• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 Red Hat Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: Ben Skeggs
23  */
24 
25 #include <subdev/bios.h>
26 #include <subdev/bios/pll.h>
27 #include <subdev/bios/rammap.h>
28 #include <subdev/bios/timing.h>
29 #include <subdev/ltc.h>
30 
31 #include <subdev/clock.h>
32 #include <subdev/clock/pll.h>
33 
34 #include <core/option.h>
35 
36 #include "ramfuc.h"
37 
38 #include "nvc0.h"
39 
40 struct nvc0_ramfuc {
41 	struct ramfuc base;
42 
43 	struct ramfuc_reg r_0x10fe20;
44 	struct ramfuc_reg r_0x10fe24;
45 	struct ramfuc_reg r_0x137320;
46 	struct ramfuc_reg r_0x137330;
47 
48 	struct ramfuc_reg r_0x132000;
49 	struct ramfuc_reg r_0x132004;
50 	struct ramfuc_reg r_0x132100;
51 
52 	struct ramfuc_reg r_0x137390;
53 
54 	struct ramfuc_reg r_0x10f290;
55 	struct ramfuc_reg r_0x10f294;
56 	struct ramfuc_reg r_0x10f298;
57 	struct ramfuc_reg r_0x10f29c;
58 	struct ramfuc_reg r_0x10f2a0;
59 
60 	struct ramfuc_reg r_0x10f300;
61 	struct ramfuc_reg r_0x10f338;
62 	struct ramfuc_reg r_0x10f340;
63 	struct ramfuc_reg r_0x10f344;
64 	struct ramfuc_reg r_0x10f348;
65 
66 	struct ramfuc_reg r_0x10f910;
67 	struct ramfuc_reg r_0x10f914;
68 
69 	struct ramfuc_reg r_0x100b0c;
70 	struct ramfuc_reg r_0x10f050;
71 	struct ramfuc_reg r_0x10f090;
72 	struct ramfuc_reg r_0x10f200;
73 	struct ramfuc_reg r_0x10f210;
74 	struct ramfuc_reg r_0x10f310;
75 	struct ramfuc_reg r_0x10f314;
76 	struct ramfuc_reg r_0x10f610;
77 	struct ramfuc_reg r_0x10f614;
78 	struct ramfuc_reg r_0x10f800;
79 	struct ramfuc_reg r_0x10f808;
80 	struct ramfuc_reg r_0x10f824;
81 	struct ramfuc_reg r_0x10f830;
82 	struct ramfuc_reg r_0x10f988;
83 	struct ramfuc_reg r_0x10f98c;
84 	struct ramfuc_reg r_0x10f990;
85 	struct ramfuc_reg r_0x10f998;
86 	struct ramfuc_reg r_0x10f9b0;
87 	struct ramfuc_reg r_0x10f9b4;
88 	struct ramfuc_reg r_0x10fb04;
89 	struct ramfuc_reg r_0x10fb08;
90 	struct ramfuc_reg r_0x137300;
91 	struct ramfuc_reg r_0x137310;
92 	struct ramfuc_reg r_0x137360;
93 	struct ramfuc_reg r_0x1373ec;
94 	struct ramfuc_reg r_0x1373f0;
95 	struct ramfuc_reg r_0x1373f8;
96 
97 	struct ramfuc_reg r_0x61c140;
98 	struct ramfuc_reg r_0x611200;
99 
100 	struct ramfuc_reg r_0x13d8f4;
101 };
102 
103 struct nvc0_ram {
104 	struct nouveau_ram base;
105 	struct nvc0_ramfuc fuc;
106 	struct nvbios_pll refpll;
107 	struct nvbios_pll mempll;
108 };
109 
110 static void
nvc0_ram_train(struct nvc0_ramfuc * fuc,u32 magic)111 nvc0_ram_train(struct nvc0_ramfuc *fuc, u32 magic)
112 {
113 	struct nvc0_ram *ram = container_of(fuc, typeof(*ram), fuc);
114 	struct nouveau_fb *pfb = nouveau_fb(ram);
115 	u32 part = nv_rd32(pfb, 0x022438), i;
116 	u32 mask = nv_rd32(pfb, 0x022554);
117 	u32 addr = 0x110974;
118 
119 	ram_wr32(fuc, 0x10f910, magic);
120 	ram_wr32(fuc, 0x10f914, magic);
121 
122 	for (i = 0; (magic & 0x80000000) && i < part; addr += 0x1000, i++) {
123 		if (mask & (1 << i))
124 			continue;
125 		ram_wait(fuc, addr, 0x0000000f, 0x00000000, 500000);
126 	}
127 }
128 
129 static int
nvc0_ram_calc(struct nouveau_fb * pfb,u32 freq)130 nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
131 {
132 	struct nouveau_clock *clk = nouveau_clock(pfb);
133 	struct nouveau_bios *bios = nouveau_bios(pfb);
134 	struct nvc0_ram *ram = (void *)pfb->ram;
135 	struct nvc0_ramfuc *fuc = &ram->fuc;
136 	struct nvbios_ramcfg cfg;
137 	u8  ver, cnt, len, strap;
138 	struct {
139 		u32 data;
140 		u8  size;
141 	} rammap, ramcfg, timing;
142 	int ref, div, out;
143 	int from, mode;
144 	int N1, M1, P;
145 	int ret;
146 
147 	/* lookup memory config data relevant to the target frequency */
148 	rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size,
149 				     &cnt, &ramcfg.size, &cfg);
150 	if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) {
151 		nv_error(pfb, "invalid/missing rammap entry\n");
152 		return -EINVAL;
153 	}
154 
155 	/* locate specific data set for the attached memory */
156 	strap = nvbios_ramcfg_index(nv_subdev(pfb));
157 	if (strap >= cnt) {
158 		nv_error(pfb, "invalid ramcfg strap\n");
159 		return -EINVAL;
160 	}
161 
162 	ramcfg.data = rammap.data + rammap.size + (strap * ramcfg.size);
163 	if (!ramcfg.data || ver != 0x10 || ramcfg.size < 0x0e) {
164 		nv_error(pfb, "invalid/missing ramcfg entry\n");
165 		return -EINVAL;
166 	}
167 
168 	/* lookup memory timings, if bios says they're present */
169 	strap = nv_ro08(bios, ramcfg.data + 0x01);
170 	if (strap != 0xff) {
171 		timing.data = nvbios_timingEe(bios, strap, &ver, &timing.size,
172 					     &cnt, &len);
173 		if (!timing.data || ver != 0x10 || timing.size < 0x19) {
174 			nv_error(pfb, "invalid/missing timing entry\n");
175 			return -EINVAL;
176 		}
177 	} else {
178 		timing.data = 0;
179 	}
180 
181 	ret = ram_init(fuc, pfb);
182 	if (ret)
183 		return ret;
184 
185 	/* determine current mclk configuration */
186 	from = !!(ram_rd32(fuc, 0x1373f0) & 0x00000002); /*XXX: ok? */
187 
188 	/* determine target mclk configuration */
189 	if (!(ram_rd32(fuc, 0x137300) & 0x00000100))
190 		ref = clk->read(clk, nv_clk_src_sppll0);
191 	else
192 		ref = clk->read(clk, nv_clk_src_sppll1);
193 	div = max(min((ref * 2) / freq, (u32)65), (u32)2) - 2;
194 	out = (ref * 2) / (div + 2);
195 	mode = freq != out;
196 
197 	ram_mask(fuc, 0x137360, 0x00000002, 0x00000000);
198 
199 	if ((ram_rd32(fuc, 0x132000) & 0x00000002) || 0 /*XXX*/) {
200 		ram_nuke(fuc, 0x132000);
201 		ram_mask(fuc, 0x132000, 0x00000002, 0x00000002);
202 		ram_mask(fuc, 0x132000, 0x00000002, 0x00000000);
203 	}
204 
205 	if (mode == 1) {
206 		ram_nuke(fuc, 0x10fe20);
207 		ram_mask(fuc, 0x10fe20, 0x00000002, 0x00000002);
208 		ram_mask(fuc, 0x10fe20, 0x00000002, 0x00000000);
209 	}
210 
211 // 0x00020034 // 0x0000000a
212 	ram_wr32(fuc, 0x132100, 0x00000001);
213 
214 	if (mode == 1 && from == 0) {
215 		/* calculate refpll */
216 		ret = nva3_pll_calc(nv_subdev(pfb), &ram->refpll,
217 				    ram->mempll.refclk, &N1, NULL, &M1, &P);
218 		if (ret <= 0) {
219 			nv_error(pfb, "unable to calc refpll\n");
220 			return ret ? ret : -ERANGE;
221 		}
222 
223 		ram_wr32(fuc, 0x10fe20, 0x20010000);
224 		ram_wr32(fuc, 0x137320, 0x00000003);
225 		ram_wr32(fuc, 0x137330, 0x81200006);
226 		ram_wr32(fuc, 0x10fe24, (P << 16) | (N1 << 8) | M1);
227 		ram_wr32(fuc, 0x10fe20, 0x20010001);
228 		ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000);
229 
230 		/* calculate mempll */
231 		ret = nva3_pll_calc(nv_subdev(pfb), &ram->mempll, freq,
232 				   &N1, NULL, &M1, &P);
233 		if (ret <= 0) {
234 			nv_error(pfb, "unable to calc refpll\n");
235 			return ret ? ret : -ERANGE;
236 		}
237 
238 		ram_wr32(fuc, 0x10fe20, 0x20010005);
239 		ram_wr32(fuc, 0x132004, (P << 16) | (N1 << 8) | M1);
240 		ram_wr32(fuc, 0x132000, 0x18010101);
241 		ram_wait(fuc, 0x137390, 0x00000002, 0x00000002, 64000);
242 	} else
243 	if (mode == 0) {
244 		ram_wr32(fuc, 0x137300, 0x00000003);
245 	}
246 
247 	if (from == 0) {
248 		ram_nuke(fuc, 0x10fb04);
249 		ram_mask(fuc, 0x10fb04, 0x0000ffff, 0x00000000);
250 		ram_nuke(fuc, 0x10fb08);
251 		ram_mask(fuc, 0x10fb08, 0x0000ffff, 0x00000000);
252 		ram_wr32(fuc, 0x10f988, 0x2004ff00);
253 		ram_wr32(fuc, 0x10f98c, 0x003fc040);
254 		ram_wr32(fuc, 0x10f990, 0x20012001);
255 		ram_wr32(fuc, 0x10f998, 0x00011a00);
256 		ram_wr32(fuc, 0x13d8f4, 0x00000000);
257 	} else {
258 		ram_wr32(fuc, 0x10f988, 0x20010000);
259 		ram_wr32(fuc, 0x10f98c, 0x00000000);
260 		ram_wr32(fuc, 0x10f990, 0x20012001);
261 		ram_wr32(fuc, 0x10f998, 0x00010a00);
262 	}
263 
264 	if (from == 0) {
265 // 0x00020039 // 0x000000ba
266 	}
267 
268 // 0x0002003a // 0x00000002
269 	ram_wr32(fuc, 0x100b0c, 0x00080012);
270 // 0x00030014 // 0x00000000 // 0x02b5f070
271 // 0x00030014 // 0x00010000 // 0x02b5f070
272 	ram_wr32(fuc, 0x611200, 0x00003300);
273 // 0x00020034 // 0x0000000a
274 // 0x00030020 // 0x00000001 // 0x00000000
275 
276 	ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
277 	ram_wr32(fuc, 0x10f210, 0x00000000);
278 	ram_nsec(fuc, 1000);
279 	if (mode == 0)
280 		nvc0_ram_train(fuc, 0x000c1001);
281 	ram_wr32(fuc, 0x10f310, 0x00000001);
282 	ram_nsec(fuc, 1000);
283 	ram_wr32(fuc, 0x10f090, 0x00000061);
284 	ram_wr32(fuc, 0x10f090, 0xc000007f);
285 	ram_nsec(fuc, 1000);
286 
287 	if (from == 0) {
288 		ram_wr32(fuc, 0x10f824, 0x00007fd4);
289 	} else {
290 		ram_wr32(fuc, 0x1373ec, 0x00020404);
291 	}
292 
293 	if (mode == 0) {
294 		ram_mask(fuc, 0x10f808, 0x00080000, 0x00000000);
295 		ram_mask(fuc, 0x10f200, 0x00008000, 0x00008000);
296 		ram_wr32(fuc, 0x10f830, 0x41500010);
297 		ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000);
298 		ram_mask(fuc, 0x132100, 0x00000100, 0x00000100);
299 		ram_wr32(fuc, 0x10f050, 0xff000090);
300 		ram_wr32(fuc, 0x1373ec, 0x00020f0f);
301 		ram_wr32(fuc, 0x1373f0, 0x00000003);
302 		ram_wr32(fuc, 0x137310, 0x81201616);
303 		ram_wr32(fuc, 0x132100, 0x00000001);
304 // 0x00020039 // 0x000000ba
305 		ram_wr32(fuc, 0x10f830, 0x00300017);
306 		ram_wr32(fuc, 0x1373f0, 0x00000001);
307 		ram_wr32(fuc, 0x10f824, 0x00007e77);
308 		ram_wr32(fuc, 0x132000, 0x18030001);
309 		ram_wr32(fuc, 0x10f090, 0x4000007e);
310 		ram_nsec(fuc, 2000);
311 		ram_wr32(fuc, 0x10f314, 0x00000001);
312 		ram_wr32(fuc, 0x10f210, 0x80000000);
313 		ram_wr32(fuc, 0x10f338, 0x00300220);
314 		ram_wr32(fuc, 0x10f300, 0x0000011d);
315 		ram_nsec(fuc, 1000);
316 		ram_wr32(fuc, 0x10f290, 0x02060505);
317 		ram_wr32(fuc, 0x10f294, 0x34208288);
318 		ram_wr32(fuc, 0x10f298, 0x44050411);
319 		ram_wr32(fuc, 0x10f29c, 0x0000114c);
320 		ram_wr32(fuc, 0x10f2a0, 0x42e10069);
321 		ram_wr32(fuc, 0x10f614, 0x40044f77);
322 		ram_wr32(fuc, 0x10f610, 0x40044f77);
323 		ram_wr32(fuc, 0x10f344, 0x00600009);
324 		ram_nsec(fuc, 1000);
325 		ram_wr32(fuc, 0x10f348, 0x00700008);
326 		ram_wr32(fuc, 0x61c140, 0x19240000);
327 		ram_wr32(fuc, 0x10f830, 0x00300017);
328 		nvc0_ram_train(fuc, 0x80021001);
329 		nvc0_ram_train(fuc, 0x80081001);
330 		ram_wr32(fuc, 0x10f340, 0x00500004);
331 		ram_nsec(fuc, 1000);
332 		ram_wr32(fuc, 0x10f830, 0x01300017);
333 		ram_wr32(fuc, 0x10f830, 0x00300017);
334 // 0x00030020 // 0x00000000 // 0x00000000
335 // 0x00020034 // 0x0000000b
336 		ram_wr32(fuc, 0x100b0c, 0x00080028);
337 		ram_wr32(fuc, 0x611200, 0x00003330);
338 	} else {
339 		ram_wr32(fuc, 0x10f800, 0x00001800);
340 		ram_wr32(fuc, 0x13d8f4, 0x00000000);
341 		ram_wr32(fuc, 0x1373ec, 0x00020404);
342 		ram_wr32(fuc, 0x1373f0, 0x00000003);
343 		ram_wr32(fuc, 0x10f830, 0x40700010);
344 		ram_wr32(fuc, 0x10f830, 0x40500010);
345 		ram_wr32(fuc, 0x13d8f4, 0x00000000);
346 		ram_wr32(fuc, 0x1373f8, 0x00000000);
347 		ram_wr32(fuc, 0x132100, 0x00000101);
348 		ram_wr32(fuc, 0x137310, 0x89201616);
349 		ram_wr32(fuc, 0x10f050, 0xff000090);
350 		ram_wr32(fuc, 0x1373ec, 0x00030404);
351 		ram_wr32(fuc, 0x1373f0, 0x00000002);
352 	// 0x00020039 // 0x00000011
353 		ram_wr32(fuc, 0x132100, 0x00000001);
354 		ram_wr32(fuc, 0x1373f8, 0x00002000);
355 		ram_nsec(fuc, 2000);
356 		ram_wr32(fuc, 0x10f808, 0x7aaa0050);
357 		ram_wr32(fuc, 0x10f830, 0x00500010);
358 		ram_wr32(fuc, 0x10f200, 0x00ce1000);
359 		ram_wr32(fuc, 0x10f090, 0x4000007e);
360 		ram_nsec(fuc, 2000);
361 		ram_wr32(fuc, 0x10f314, 0x00000001);
362 		ram_wr32(fuc, 0x10f210, 0x80000000);
363 		ram_wr32(fuc, 0x10f338, 0x00300200);
364 		ram_wr32(fuc, 0x10f300, 0x0000084d);
365 		ram_nsec(fuc, 1000);
366 		ram_wr32(fuc, 0x10f290, 0x0b343825);
367 		ram_wr32(fuc, 0x10f294, 0x3483028e);
368 		ram_wr32(fuc, 0x10f298, 0x440c0600);
369 		ram_wr32(fuc, 0x10f29c, 0x0000214c);
370 		ram_wr32(fuc, 0x10f2a0, 0x42e20069);
371 		ram_wr32(fuc, 0x10f200, 0x00ce0000);
372 		ram_wr32(fuc, 0x10f614, 0x60044e77);
373 		ram_wr32(fuc, 0x10f610, 0x60044e77);
374 		ram_wr32(fuc, 0x10f340, 0x00500000);
375 		ram_nsec(fuc, 1000);
376 		ram_wr32(fuc, 0x10f344, 0x00600228);
377 		ram_nsec(fuc, 1000);
378 		ram_wr32(fuc, 0x10f348, 0x00700000);
379 		ram_wr32(fuc, 0x13d8f4, 0x00000000);
380 		ram_wr32(fuc, 0x61c140, 0x09a40000);
381 
382 		nvc0_ram_train(fuc, 0x800e1008);
383 
384 		ram_nsec(fuc, 1000);
385 		ram_wr32(fuc, 0x10f800, 0x00001804);
386 	// 0x00030020 // 0x00000000 // 0x00000000
387 	// 0x00020034 // 0x0000000b
388 		ram_wr32(fuc, 0x13d8f4, 0x00000000);
389 		ram_wr32(fuc, 0x100b0c, 0x00080028);
390 		ram_wr32(fuc, 0x611200, 0x00003330);
391 		ram_nsec(fuc, 100000);
392 		ram_wr32(fuc, 0x10f9b0, 0x05313f41);
393 		ram_wr32(fuc, 0x10f9b4, 0x00002f50);
394 
395 		nvc0_ram_train(fuc, 0x010c1001);
396 	}
397 
398 	ram_mask(fuc, 0x10f200, 0x00000800, 0x00000800);
399 // 0x00020016 // 0x00000000
400 
401 	if (mode == 0)
402 		ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
403 	return 0;
404 }
405 
406 static int
nvc0_ram_prog(struct nouveau_fb * pfb)407 nvc0_ram_prog(struct nouveau_fb *pfb)
408 {
409 	struct nouveau_device *device = nv_device(pfb);
410 	struct nvc0_ram *ram = (void *)pfb->ram;
411 	struct nvc0_ramfuc *fuc = &ram->fuc;
412 	ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", true));
413 	return 0;
414 }
415 
416 static void
nvc0_ram_tidy(struct nouveau_fb * pfb)417 nvc0_ram_tidy(struct nouveau_fb *pfb)
418 {
419 	struct nvc0_ram *ram = (void *)pfb->ram;
420 	struct nvc0_ramfuc *fuc = &ram->fuc;
421 	ram_exec(fuc, false);
422 }
423 
424 extern const u8 nvc0_pte_storage_type_map[256];
425 
426 void
nvc0_ram_put(struct nouveau_fb * pfb,struct nouveau_mem ** pmem)427 nvc0_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
428 {
429 	struct nouveau_ltc *ltc = nouveau_ltc(pfb);
430 	struct nouveau_mem *mem = *pmem;
431 
432 	*pmem = NULL;
433 	if (unlikely(mem == NULL))
434 		return;
435 
436 	mutex_lock(&pfb->base.mutex);
437 	if (mem->tag)
438 		ltc->tags_free(ltc, &mem->tag);
439 	__nv50_ram_put(pfb, mem);
440 	mutex_unlock(&pfb->base.mutex);
441 
442 	kfree(mem);
443 }
444 
445 int
nvc0_ram_get(struct nouveau_fb * pfb,u64 size,u32 align,u32 ncmin,u32 memtype,struct nouveau_mem ** pmem)446 nvc0_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
447 	     u32 memtype, struct nouveau_mem **pmem)
448 {
449 	struct nouveau_mm *mm = &pfb->vram;
450 	struct nouveau_mm_node *r;
451 	struct nouveau_mem *mem;
452 	int type = (memtype & 0x0ff);
453 	int back = (memtype & 0x800);
454 	const bool comp = nvc0_pte_storage_type_map[type] != type;
455 	int ret;
456 
457 	size  >>= 12;
458 	align >>= 12;
459 	ncmin >>= 12;
460 	if (!ncmin)
461 		ncmin = size;
462 
463 	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
464 	if (!mem)
465 		return -ENOMEM;
466 
467 	INIT_LIST_HEAD(&mem->regions);
468 	mem->size = size;
469 
470 	mutex_lock(&pfb->base.mutex);
471 	if (comp) {
472 		struct nouveau_ltc *ltc = nouveau_ltc(pfb);
473 
474 		/* compression only works with lpages */
475 		if (align == (1 << (17 - 12))) {
476 			int n = size >> 5;
477 			ltc->tags_alloc(ltc, n, &mem->tag);
478 		}
479 
480 		if (unlikely(!mem->tag))
481 			type = nvc0_pte_storage_type_map[type];
482 	}
483 	mem->memtype = type;
484 
485 	do {
486 		if (back)
487 			ret = nouveau_mm_tail(mm, 0, 1, size, ncmin, align, &r);
488 		else
489 			ret = nouveau_mm_head(mm, 0, 1, size, ncmin, align, &r);
490 		if (ret) {
491 			mutex_unlock(&pfb->base.mutex);
492 			pfb->ram->put(pfb, &mem);
493 			return ret;
494 		}
495 
496 		list_add_tail(&r->rl_entry, &mem->regions);
497 		size -= r->length;
498 	} while (size);
499 	mutex_unlock(&pfb->base.mutex);
500 
501 	r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
502 	mem->offset = (u64)r->offset << 12;
503 	*pmem = mem;
504 	return 0;
505 }
506 
507 int
nvc0_ram_create_(struct nouveau_object * parent,struct nouveau_object * engine,struct nouveau_oclass * oclass,u32 maskaddr,int size,void ** pobject)508 nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
509 		 struct nouveau_oclass *oclass, u32 maskaddr, int size,
510 		 void **pobject)
511 {
512 	struct nouveau_fb *pfb = nouveau_fb(parent);
513 	struct nouveau_bios *bios = nouveau_bios(pfb);
514 	struct nouveau_ram *ram;
515 	const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
516 	const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
517 	u32 parts = nv_rd32(pfb, 0x022438);
518 	u32 pmask = nv_rd32(pfb, maskaddr);
519 	u32 bsize = nv_rd32(pfb, 0x10f20c);
520 	u32 offset, length;
521 	bool uniform = true;
522 	int ret, part;
523 
524 	ret = nouveau_ram_create_(parent, engine, oclass, size, pobject);
525 	ram = *pobject;
526 	if (ret)
527 		return ret;
528 
529 	nv_debug(pfb, "0x100800: 0x%08x\n", nv_rd32(pfb, 0x100800));
530 	nv_debug(pfb, "parts 0x%08x mask 0x%08x\n", parts, pmask);
531 
532 	ram->type = nouveau_fb_bios_memtype(bios);
533 	ram->ranks = (nv_rd32(pfb, 0x10f200) & 0x00000004) ? 2 : 1;
534 
535 	/* read amount of vram attached to each memory controller */
536 	for (part = 0; part < parts; part++) {
537 		if (!(pmask & (1 << part))) {
538 			u32 psize = nv_rd32(pfb, 0x11020c + (part * 0x1000));
539 			if (psize != bsize) {
540 				if (psize < bsize)
541 					bsize = psize;
542 				uniform = false;
543 			}
544 
545 			nv_debug(pfb, "%d: mem_amount 0x%08x\n", part, psize);
546 			ram->size += (u64)psize << 20;
547 		}
548 	}
549 
550 	/* if all controllers have the same amount attached, there's no holes */
551 	if (uniform) {
552 		offset = rsvd_head;
553 		length = (ram->size >> 12) - rsvd_head - rsvd_tail;
554 		ret = nouveau_mm_init(&pfb->vram, offset, length, 1);
555 	} else {
556 		/* otherwise, address lowest common amount from 0GiB */
557 		ret = nouveau_mm_init(&pfb->vram, rsvd_head,
558 				      (bsize << 8) * parts - rsvd_head, 1);
559 		if (ret)
560 			return ret;
561 
562 		/* and the rest starting from (8GiB + common_size) */
563 		offset = (0x0200000000ULL >> 12) + (bsize << 8);
564 		length = (ram->size >> 12) - ((bsize * parts) << 8) - rsvd_tail;
565 
566 		ret = nouveau_mm_init(&pfb->vram, offset, length, 1);
567 		if (ret)
568 			nouveau_mm_fini(&pfb->vram);
569 	}
570 
571 	if (ret)
572 		return ret;
573 
574 	ram->get = nvc0_ram_get;
575 	ram->put = nvc0_ram_put;
576 	return 0;
577 }
578 
579 static int
nvc0_ram_init(struct nouveau_object * object)580 nvc0_ram_init(struct nouveau_object *object)
581 {
582 	struct nouveau_fb *pfb = (void *)object->parent;
583 	struct nvc0_ram   *ram = (void *)object;
584 	int ret, i;
585 
586 	ret = nouveau_ram_init(&ram->base);
587 	if (ret)
588 		return ret;
589 
590 	/* prepare for ddr link training, and load training patterns */
591 	switch (ram->base.type) {
592 	case NV_MEM_TYPE_GDDR5: {
593 		static const u8  train0[] = {
594 			0x00, 0xff, 0x55, 0xaa, 0x33, 0xcc,
595 			0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
596 		};
597 		static const u32 train1[] = {
598 			0x00000000, 0xffffffff,
599 			0x55555555, 0xaaaaaaaa,
600 			0x33333333, 0xcccccccc,
601 			0xf0f0f0f0, 0x0f0f0f0f,
602 			0x00ff00ff, 0xff00ff00,
603 			0x0000ffff, 0xffff0000,
604 		};
605 
606 		for (i = 0; i < 0x30; i++) {
607 			nv_wr32(pfb, 0x10f968, 0x00000000 | (i << 8));
608 			nv_wr32(pfb, 0x10f96c, 0x00000000 | (i << 8));
609 			nv_wr32(pfb, 0x10f920, 0x00000100 | train0[i % 12]);
610 			nv_wr32(pfb, 0x10f924, 0x00000100 | train0[i % 12]);
611 			nv_wr32(pfb, 0x10f918,              train1[i % 12]);
612 			nv_wr32(pfb, 0x10f91c,              train1[i % 12]);
613 			nv_wr32(pfb, 0x10f920, 0x00000000 | train0[i % 12]);
614 			nv_wr32(pfb, 0x10f924, 0x00000000 | train0[i % 12]);
615 			nv_wr32(pfb, 0x10f918,              train1[i % 12]);
616 			nv_wr32(pfb, 0x10f91c,              train1[i % 12]);
617 		}
618 	}	break;
619 	default:
620 		break;
621 	}
622 
623 	return 0;
624 }
625 
626 static int
nvc0_ram_ctor(struct nouveau_object * parent,struct nouveau_object * engine,struct nouveau_oclass * oclass,void * data,u32 size,struct nouveau_object ** pobject)627 nvc0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
628 	      struct nouveau_oclass *oclass, void *data, u32 size,
629 	      struct nouveau_object **pobject)
630 {
631 	struct nouveau_bios *bios = nouveau_bios(parent);
632 	struct nvc0_ram *ram;
633 	int ret;
634 
635 	ret = nvc0_ram_create(parent, engine, oclass, 0x022554, &ram);
636 	*pobject = nv_object(ram);
637 	if (ret)
638 		return ret;
639 
640 	ret = nvbios_pll_parse(bios, 0x0c, &ram->refpll);
641 	if (ret) {
642 		nv_error(ram, "mclk refpll data not found\n");
643 		return ret;
644 	}
645 
646 	ret = nvbios_pll_parse(bios, 0x04, &ram->mempll);
647 	if (ret) {
648 		nv_error(ram, "mclk pll data not found\n");
649 		return ret;
650 	}
651 
652 	switch (ram->base.type) {
653 	case NV_MEM_TYPE_GDDR5:
654 		ram->base.calc = nvc0_ram_calc;
655 		ram->base.prog = nvc0_ram_prog;
656 		ram->base.tidy = nvc0_ram_tidy;
657 		break;
658 	default:
659 		nv_warn(ram, "reclocking of this ram type unsupported\n");
660 		return 0;
661 	}
662 
663 	ram->fuc.r_0x10fe20 = ramfuc_reg(0x10fe20);
664 	ram->fuc.r_0x10fe24 = ramfuc_reg(0x10fe24);
665 	ram->fuc.r_0x137320 = ramfuc_reg(0x137320);
666 	ram->fuc.r_0x137330 = ramfuc_reg(0x137330);
667 
668 	ram->fuc.r_0x132000 = ramfuc_reg(0x132000);
669 	ram->fuc.r_0x132004 = ramfuc_reg(0x132004);
670 	ram->fuc.r_0x132100 = ramfuc_reg(0x132100);
671 
672 	ram->fuc.r_0x137390 = ramfuc_reg(0x137390);
673 
674 	ram->fuc.r_0x10f290 = ramfuc_reg(0x10f290);
675 	ram->fuc.r_0x10f294 = ramfuc_reg(0x10f294);
676 	ram->fuc.r_0x10f298 = ramfuc_reg(0x10f298);
677 	ram->fuc.r_0x10f29c = ramfuc_reg(0x10f29c);
678 	ram->fuc.r_0x10f2a0 = ramfuc_reg(0x10f2a0);
679 
680 	ram->fuc.r_0x10f300 = ramfuc_reg(0x10f300);
681 	ram->fuc.r_0x10f338 = ramfuc_reg(0x10f338);
682 	ram->fuc.r_0x10f340 = ramfuc_reg(0x10f340);
683 	ram->fuc.r_0x10f344 = ramfuc_reg(0x10f344);
684 	ram->fuc.r_0x10f348 = ramfuc_reg(0x10f348);
685 
686 	ram->fuc.r_0x10f910 = ramfuc_reg(0x10f910);
687 	ram->fuc.r_0x10f914 = ramfuc_reg(0x10f914);
688 
689 	ram->fuc.r_0x100b0c = ramfuc_reg(0x100b0c);
690 	ram->fuc.r_0x10f050 = ramfuc_reg(0x10f050);
691 	ram->fuc.r_0x10f090 = ramfuc_reg(0x10f090);
692 	ram->fuc.r_0x10f200 = ramfuc_reg(0x10f200);
693 	ram->fuc.r_0x10f210 = ramfuc_reg(0x10f210);
694 	ram->fuc.r_0x10f310 = ramfuc_reg(0x10f310);
695 	ram->fuc.r_0x10f314 = ramfuc_reg(0x10f314);
696 	ram->fuc.r_0x10f610 = ramfuc_reg(0x10f610);
697 	ram->fuc.r_0x10f614 = ramfuc_reg(0x10f614);
698 	ram->fuc.r_0x10f800 = ramfuc_reg(0x10f800);
699 	ram->fuc.r_0x10f808 = ramfuc_reg(0x10f808);
700 	ram->fuc.r_0x10f824 = ramfuc_reg(0x10f824);
701 	ram->fuc.r_0x10f830 = ramfuc_reg(0x10f830);
702 	ram->fuc.r_0x10f988 = ramfuc_reg(0x10f988);
703 	ram->fuc.r_0x10f98c = ramfuc_reg(0x10f98c);
704 	ram->fuc.r_0x10f990 = ramfuc_reg(0x10f990);
705 	ram->fuc.r_0x10f998 = ramfuc_reg(0x10f998);
706 	ram->fuc.r_0x10f9b0 = ramfuc_reg(0x10f9b0);
707 	ram->fuc.r_0x10f9b4 = ramfuc_reg(0x10f9b4);
708 	ram->fuc.r_0x10fb04 = ramfuc_reg(0x10fb04);
709 	ram->fuc.r_0x10fb08 = ramfuc_reg(0x10fb08);
710 	ram->fuc.r_0x137310 = ramfuc_reg(0x137300);
711 	ram->fuc.r_0x137310 = ramfuc_reg(0x137310);
712 	ram->fuc.r_0x137360 = ramfuc_reg(0x137360);
713 	ram->fuc.r_0x1373ec = ramfuc_reg(0x1373ec);
714 	ram->fuc.r_0x1373f0 = ramfuc_reg(0x1373f0);
715 	ram->fuc.r_0x1373f8 = ramfuc_reg(0x1373f8);
716 
717 	ram->fuc.r_0x61c140 = ramfuc_reg(0x61c140);
718 	ram->fuc.r_0x611200 = ramfuc_reg(0x611200);
719 
720 	ram->fuc.r_0x13d8f4 = ramfuc_reg(0x13d8f4);
721 	return 0;
722 }
723 
724 struct nouveau_oclass
725 nvc0_ram_oclass = {
726 	.handle = 0,
727 	.ofuncs = &(struct nouveau_ofuncs) {
728 		.ctor = nvc0_ram_ctor,
729 		.dtor = _nouveau_ram_dtor,
730 		.init = nvc0_ram_init,
731 		.fini = _nouveau_ram_fini,
732 	}
733 };
734