xref: /haiku/src/add-ons/accelerants/nvidia/engine/nv_general.c (revision 67bce78b48ed6d01b5a8eef89f5694c372b7e0a1)
1 /* Authors:
2    Mark Watson 12/1999,
3    Apsed,
4    Rudolf Cornelissen 10/2002-4/2004
5 */
6 
7 #define MODULE_BIT 0x00008000
8 
9 #include "nv_std.h"
10 
11 status_t test_ram(void);
12 static status_t nvxx_general_powerup (void);
13 static status_t nv_general_bios_to_powergraphics(void);
14 
15 static void nv_dump_configuration_space (void)
16 {
17 #define DUMP_CFG(reg, type) if (si->ps.card_type >= type) do { \
18 	uint32 value = CFGR(reg); \
19 	MSG(("configuration_space 0x%02x %20s 0x%08x\n", \
20 		NVCFG_##reg, #reg, value)); \
21 } while (0)
22 	DUMP_CFG (DEVID,	0);
23 	DUMP_CFG (DEVCTRL,	0);
24 	DUMP_CFG (CLASS,	0);
25 	DUMP_CFG (HEADER,	0);
26 	DUMP_CFG (BASE1REGS,0);
27 	DUMP_CFG (BASE2FB,	0);
28 	DUMP_CFG (BASE3,	0);
29 	DUMP_CFG (BASE4,	0);
30 	DUMP_CFG (BASE5,	0);
31 	DUMP_CFG (BASE6,	0);
32 	DUMP_CFG (BASE7,	0);
33 	DUMP_CFG (SUBSYSID1,0);
34 	DUMP_CFG (ROMBASE,	0);
35 	DUMP_CFG (CFG_0,	0);
36 	DUMP_CFG (CFG_1,	0);
37 	DUMP_CFG (INTERRUPT,0);
38 	DUMP_CFG (SUBSYSID2,0);
39 	DUMP_CFG (AGPREF,	0);
40 	DUMP_CFG (AGPSTAT,	0);
41 	DUMP_CFG (AGPCMD,	0);
42 	DUMP_CFG (ROMSHADOW,0);
43 	DUMP_CFG (VGA,		0);
44 	DUMP_CFG (SCHRATCH,	0);
45 	DUMP_CFG (CFG_10,	0);
46 	DUMP_CFG (CFG_11,	0);
47 	DUMP_CFG (CFG_12,	0);
48 	DUMP_CFG (CFG_13,	0);
49 	DUMP_CFG (CFG_14,	0);
50 	DUMP_CFG (CFG_15,	0);
51 	DUMP_CFG (CFG_16,	0);
52 	DUMP_CFG (CFG_17,	0);
53 	DUMP_CFG (GF2IGPU,	0);
54 	DUMP_CFG (CFG_19,	0);
55 	DUMP_CFG (GF4MXIGPU,0);
56 	DUMP_CFG (CFG_21,	0);
57 	DUMP_CFG (CFG_22,	0);
58 	DUMP_CFG (CFG_23,	0);
59 	DUMP_CFG (CFG_24,	0);
60 	DUMP_CFG (CFG_25,	0);
61 	DUMP_CFG (CFG_26,	0);
62 	DUMP_CFG (CFG_27,	0);
63 	DUMP_CFG (CFG_28,	0);
64 	DUMP_CFG (CFG_29,	0);
65 	DUMP_CFG (CFG_30,	0);
66 	DUMP_CFG (CFG_41,	0);
67 	DUMP_CFG (CFG_42,	0);
68 	DUMP_CFG (CFG_43,	0);
69 	DUMP_CFG (CFG_44,	0);
70 	DUMP_CFG (CFG_45,	0);
71 	DUMP_CFG (CFG_46,	0);
72 	DUMP_CFG (CFG_47,	0);
73 	DUMP_CFG (CFG_48,	0);
74 	DUMP_CFG (CFG_49,	0);
75 	DUMP_CFG (CFG_50,	0);
76 #undef DUMP_CFG
77 }
78 
79 status_t nv_general_powerup()
80 {
81 	status_t status;
82 
83 	LOG(1,("POWERUP: nVidia (open)BeOS Accelerant 0.10-11 running.\n"));
84 
85 	/* preset no laptop */
86 	si->ps.laptop = false;
87 
88 	/* detect card type and power it up */
89 	switch(CFGR(DEVID))
90 	{
91 	/* Vendor Nvidia */
92 	case 0x002010de: /* Nvidia TNT1 */
93 		si->ps.card_type = NV04;
94 		si->ps.card_arch = NV04A;
95 		LOG(4,("POWERUP: Detected Nvidia TNT1 (NV04)\n"));
96 		status = nvxx_general_powerup();
97 		break;
98 	case 0x002810de: /* Nvidia TNT2 (pro) */
99 	case 0x002910de: /* Nvidia TNT2 Ultra */
100 	case 0x002a10de: /* Nvidia TNT2 */
101 	case 0x002b10de: /* Nvidia TNT2 */
102 		si->ps.card_type = NV05;
103 		si->ps.card_arch = NV04A;
104 		LOG(4,("POWERUP: Detected Nvidia TNT2 (NV05)\n"));
105 		status = nvxx_general_powerup();
106 		break;
107 	case 0x002c10de: /* Nvidia Vanta (Lt) */
108 		si->ps.card_type = NV05;
109 		si->ps.card_arch = NV04A;
110 		LOG(4,("POWERUP: Detected Nvidia Vanta (Lt) (NV05)\n"));
111 		status = nvxx_general_powerup();
112 		break;
113 	case 0x002d10de: /* Nvidia TNT2-M64 (Pro) */
114 		si->ps.card_type = NV05M64;
115 		si->ps.card_arch = NV04A;
116 		LOG(4,("POWERUP: Detected Nvidia TNT2-M64 (Pro) (NV05M64)\n"));
117 		status = nvxx_general_powerup();
118 		break;
119 	case 0x002e10de: /* Nvidia NV06 Vanta */
120 	case 0x002f10de: /* Nvidia NV06 Vanta */
121 		si->ps.card_type = NV06;
122 		si->ps.card_arch = NV04A;
123 		LOG(4,("POWERUP: Detected Nvidia Vanta (NV06)\n"));
124 		status = nvxx_general_powerup();
125 		break;
126 	case 0x00a010de: /* Nvidia Aladdin TNT2 */
127 		si->ps.card_type = NV05;
128 		si->ps.card_arch = NV04A;
129 		LOG(4,("POWERUP: Detected Nvidia Aladdin TNT2 (NV05)\n"));
130 		status = nvxx_general_powerup();
131 		break;
132 	case 0x010010de: /* Nvidia GeForce256 SDR */
133 	case 0x010110de: /* Nvidia GeForce256 DDR */
134 	case 0x010210de: /* Nvidia GeForce256 Ultra */
135 		si->ps.card_type = NV10;
136 		si->ps.card_arch = NV10A;
137 		LOG(4,("POWERUP: Detected Nvidia GeForce256 (NV10)\n"));
138 		status = nvxx_general_powerup();
139 		break;
140 	case 0x010310de: /* Nvidia Quadro */
141 		si->ps.card_type = NV10;
142 		si->ps.card_arch = NV10A;
143 		LOG(4,("POWERUP: Detected Nvidia Quadro (NV10)\n"));
144 		status = nvxx_general_powerup();
145 		break;
146 	case 0x011010de: /* Nvidia GeForce2 MX/MX400 */
147 	case 0x011110de: /* Nvidia GeForce2 MX100/MX200 DDR */
148 		si->ps.card_type = NV11;
149 		si->ps.card_arch = NV10A;
150 		LOG(4,("POWERUP: Detected Nvidia GeForce2 MX (NV11)\n"));
151 		status = nvxx_general_powerup();
152 		break;
153 	case 0x011210de: /* Nvidia GeForce2 Go */
154 		si->ps.card_type = NV11;
155 		si->ps.card_arch = NV10A;
156 		si->ps.laptop = true;
157 		LOG(4,("POWERUP: Detected Nvidia GeForce2 Go (NV11)\n"));
158 		status = nvxx_general_powerup();
159 		break;
160 	case 0x011310de: /* Nvidia Quadro2 MXR/EX/Go */
161 		si->ps.card_type = NV11;
162 		si->ps.card_arch = NV10A;
163 		LOG(4,("POWERUP: Detected Nvidia Quadro2 MXR/EX/Go (NV11)\n"));
164 		status = nvxx_general_powerup();
165 		break;
166 	case 0x015010de: /* Nvidia GeForce2 GTS/Pro */
167 	case 0x015110de: /* Nvidia GeForce2 Ti DDR */
168 	case 0x015210de: /* Nvidia GeForce2 Ultra */
169 		si->ps.card_type = NV15;
170 		si->ps.card_arch = NV10A;
171 		LOG(4,("POWERUP: Detected Nvidia GeForce2 (NV15)\n"));
172 		status = nvxx_general_powerup();
173 		break;
174 	case 0x015310de: /* Nvidia Quadro2 Pro */
175 		si->ps.card_type = NV15;
176 		si->ps.card_arch = NV10A;
177 		LOG(4,("POWERUP: Detected Nvidia Quadro2 Pro (NV15)\n"));
178 		status = nvxx_general_powerup();
179 		break;
180 	case 0x017010de: /* Nvidia GeForce4 MX 460 */
181 	case 0x017110de: /* Nvidia GeForce4 MX 440 */
182 	case 0x017210de: /* Nvidia GeForce4 MX 420 */
183 	case 0x017310de: /* Nvidia GeForce4 MX 440SE */
184 		si->ps.card_type = NV17;
185 		si->ps.card_arch = NV10A;
186 		LOG(4,("POWERUP: Detected Nvidia GeForce4 MX (NV17)\n"));
187 		status = nvxx_general_powerup();
188 		break;
189 	case 0x017410de: /* Nvidia GeForce4 440 Go */
190 	case 0x017510de: /* Nvidia GeForce4 420 Go */
191 	case 0x017610de: /* Nvidia GeForce4 420 Go 32M */
192 	case 0x017710de: /* Nvidia GeForce4 460 Go */
193 	case 0x017910de: /* Nvidia GeForce4 440 Go 64M (on PPC GeForce4 MX) */
194 		si->ps.card_type = NV17;
195 		si->ps.card_arch = NV10A;
196 		si->ps.laptop = true;
197 		LOG(4,("POWERUP: Detected Nvidia GeForce4 Go (NV17)\n"));
198 		status = nvxx_general_powerup();
199 		break;
200 	case 0x017810de: /* Nvidia Quadro4 500 XGL/550 XGL */
201 	case 0x017a10de: /* Nvidia Quadro4 200 NVS/400 NVS */
202 		si->ps.card_type = NV17;
203 		si->ps.card_arch = NV10A;
204 		LOG(4,("POWERUP: Detected Nvidia Quadro4 (NV17)\n"));
205 		status = nvxx_general_powerup();
206 		break;
207 	case 0x017c10de: /* Nvidia Quadro4 500 GoGL */
208 		si->ps.card_type = NV17;
209 		si->ps.card_arch = NV10A;
210 		si->ps.laptop = true;
211 		LOG(4,("POWERUP: Detected Nvidia Quadro4 500 GoGL (NV17)\n"));
212 		status = nvxx_general_powerup();
213 		break;
214 	case 0x017d10de: /* Nvidia GeForce4 410 Go 16M*/
215 		si->ps.card_type = NV17;
216 		si->ps.card_arch = NV10A;
217 		si->ps.laptop = true;
218 		LOG(4,("POWERUP: Detected Nvidia GeForce4 410 Go (NV17)\n"));
219 		status = nvxx_general_powerup();
220 		break;
221 	case 0x018110de: /* Nvidia GeForce4 MX 440 AGP8X */
222 	case 0x018210de: /* Nvidia GeForce4 MX 440SE AGP8X */
223 	case 0x018310de: /* Nvidia GeForce4 MX 420 AGP8X */
224 	case 0x018510de: /* Nvidia GeForce4 MX 4000 AGP8X */
225 		si->ps.card_type = NV18;
226 		si->ps.card_arch = NV10A;
227 		LOG(4,("POWERUP: Detected Nvidia GeForce4 MX AGP8X (NV18)\n"));
228 		status = nvxx_general_powerup();
229 		break;
230 	case 0x018610de: /* Nvidia GeForce4 448 Go */
231 	case 0x018710de: /* Nvidia GeForce4 488 Go */
232 		si->ps.card_type = NV18;
233 		si->ps.card_arch = NV10A;
234 		si->ps.laptop = true;
235 		LOG(4,("POWERUP: Detected Nvidia GeForce4 Go (NV18)\n"));
236 		status = nvxx_general_powerup();
237 		break;
238 	case 0x018810de: /* Nvidia Quadro4 580 XGL */
239 		si->ps.card_type = NV18;
240 		si->ps.card_arch = NV10A;
241 		LOG(4,("POWERUP: Detected Nvidia Quadro4 (NV18)\n"));
242 		status = nvxx_general_powerup();
243 		break;
244 	case 0x018910de: /* Nvidia GeForce4 MX AGP8X */
245 		si->ps.card_type = NV18;
246 		si->ps.card_arch = NV10A;
247 		LOG(4,("POWERUP: Detected Nvidia GeForce4 MX AGP8X (NV18)\n"));
248 		status = nvxx_general_powerup();
249 		break;
250 	case 0x018a10de: /* Nvidia Quadro4 280 NVS AGP8X */
251 	case 0x018b10de: /* Nvidia Quadro4 380 XGL */
252 		si->ps.card_type = NV18;
253 		si->ps.card_arch = NV10A;
254 		LOG(4,("POWERUP: Detected Nvidia Quadro4 (NV18)\n"));
255 		status = nvxx_general_powerup();
256 		break;
257 	case 0x01a010de: /* Nvidia GeForce2 Integrated GPU */
258 		si->ps.card_type = NV11;
259 		si->ps.card_arch = NV10A;
260 		LOG(4,("POWERUP: Detected Nvidia GeForce2 Integrated GPU (CRUSH, NV11)\n"));
261 		status = nvxx_general_powerup();
262 		break;
263 	case 0x01f010de: /* Nvidia GeForce4 MX Integrated GPU */
264 		si->ps.card_type = NV17;
265 		si->ps.card_arch = NV10A;
266 		LOG(4,("POWERUP: Detected Nvidia GeForce4 MX Integrated GPU (NFORCE2, NV17)\n"));
267 		status = nvxx_general_powerup();
268 		break;
269 	case 0x020010de: /* Nvidia GeForce3 */
270 	case 0x020110de: /* Nvidia GeForce3 Ti 200 */
271 	case 0x020210de: /* Nvidia GeForce3 Ti 500 */
272 		si->ps.card_type = NV20;
273 		si->ps.card_arch = NV20A;
274 		LOG(4,("POWERUP: Detected Nvidia GeForce3 (NV20)\n"));
275 		status = nvxx_general_powerup();
276 		break;
277 	case 0x020310de: /* Nvidia Quadro DCC */
278 		si->ps.card_type = NV20;
279 		si->ps.card_arch = NV20A;
280 		LOG(4,("POWERUP: Detected Nvidia Quadro DCC (NV20)\n"));
281 		status = nvxx_general_powerup();
282 		break;
283 	case 0x025010de: /* Nvidia GeForce4 Ti 4600 */
284 	case 0x025110de: /* Nvidia GeForce4 Ti 4400 */
285 	case 0x025210de: /* Nvidia GeForce4 Ti 4600 */
286 	case 0x025310de: /* Nvidia GeForce4 Ti 4200 */
287 		si->ps.card_type = NV25;
288 		si->ps.card_arch = NV20A;
289 		LOG(4,("POWERUP: Detected Nvidia GeForce4 Ti (NV25)\n"));
290 		status = nvxx_general_powerup();
291 		break;
292 	case 0x025810de: /* Nvidia Quadro4 900 XGL */
293 	case 0x025910de: /* Nvidia Quadro4 750 XGL */
294 	case 0x025b10de: /* Nvidia Quadro4 700 XGL */
295 		si->ps.card_type = NV25;
296 		si->ps.card_arch = NV20A;
297 		LOG(4,("POWERUP: Detected Nvidia Quadro4 XGL (NV25)\n"));
298 		status = nvxx_general_powerup();
299 		break;
300 	case 0x028010de: /* Nvidia GeForce4 Ti 4800 AGP8X */
301 	case 0x028110de: /* Nvidia GeForce4 Ti 4200 AGP8X */
302 		si->ps.card_type = NV28;
303 		si->ps.card_arch = NV20A;
304 		LOG(4,("POWERUP: Detected Nvidia GeForce4 Ti AGP8X (NV28)\n"));
305 		status = nvxx_general_powerup();
306 		break;
307 	case 0x028210de: /* Nvidia GeForce4 Ti 4800SE */
308 		si->ps.card_type = NV28;
309 		si->ps.card_arch = NV20A;
310 		LOG(4,("POWERUP: Detected Nvidia GeForce4 Ti 4800SE (NV28)\n"));
311 		status = nvxx_general_powerup();
312 		break;
313 	case 0x028610de: /* Nvidia GeForce4 4200 Go */
314 		si->ps.card_type = NV28;
315 		si->ps.card_arch = NV20A;
316 		si->ps.laptop = true;
317 		LOG(4,("POWERUP: Detected Nvidia GeForce4 4200 Go (NV28)\n"));
318 		status = nvxx_general_powerup();
319 		break;
320 	case 0x028810de: /* Nvidia Quadro4 980 XGL */
321 	case 0x028910de: /* Nvidia Quadro4 780 XGL */
322 		si->ps.card_type = NV28;
323 		si->ps.card_arch = NV20A;
324 		LOG(4,("POWERUP: Detected Nvidia Quadro4 XGL (NV28)\n"));
325 		status = nvxx_general_powerup();
326 		break;
327 	case 0x028c10de: /* Nvidia Quadro4 700 GoGL */
328 		si->ps.card_type = NV28;
329 		si->ps.card_arch = NV20A;
330 		si->ps.laptop = true;
331 		LOG(4,("POWERUP: Detected Nvidia Quadro4 700 GoGL (NV28)\n"));
332 		status = nvxx_general_powerup();
333 		break;
334 	case 0x02a010de: /* Nvidia GeForce3 Integrated GPU */
335 		si->ps.card_type = NV20;
336 		si->ps.card_arch = NV20A;
337 		LOG(4,("POWERUP: Detected Nvidia GeForce3 Integrated GPU (XBOX, NV20)\n"));
338 		status = nvxx_general_powerup();
339 		break;
340 	case 0x030110de: /* Nvidia GeForce FX 5800 Ultra */
341 	case 0x030210de: /* Nvidia GeForce FX 5800 */
342 		si->ps.card_type = NV30;
343 		si->ps.card_arch = NV30A;
344 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5800 (NV30)\n"));
345 		status = nvxx_general_powerup();
346 		break;
347 	case 0x030810de: /* Nvidia Quadro FX 2000 */
348 	case 0x030910de: /* Nvidia Quadro FX 1000 */
349 		si->ps.card_type = NV30;
350 		si->ps.card_arch = NV30A;
351 		LOG(4,("POWERUP: Detected Nvidia Quadro FX (NV30)\n"));
352 		status = nvxx_general_powerup();
353 		break;
354 	case 0x031110de: /* Nvidia GeForce FX 5600 Ultra */
355 	case 0x031210de: /* Nvidia GeForce FX 5600 */
356 		si->ps.card_type = NV31;
357 		si->ps.card_arch = NV30A;
358 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5600 (NV31)\n"));
359 		status = nvxx_general_powerup();
360 		break;
361 	case 0x031310de: /* Nvidia unknown FX */
362 		si->ps.card_type = NV31;
363 		si->ps.card_arch = NV30A;
364 		LOG(4,("POWERUP: Detected Nvidia unknown FX (NV31)\n"));
365 		status = nvxx_general_powerup();
366 		break;
367 	case 0x031410de: /* Nvidia GeForce FX 5600XT */
368 		si->ps.card_type = NV31;
369 		si->ps.card_arch = NV30A;
370 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5600XT (NV31)\n"));
371 		status = nvxx_general_powerup();
372 		break;
373 	case 0x031610de: /* Nvidia unknown FX Go */
374 	case 0x031710de: /* Nvidia unknown FX Go */
375 		si->ps.card_type = NV31;
376 		si->ps.card_arch = NV30A;
377 		si->ps.laptop = true;
378 		LOG(4,("POWERUP: Detected Nvidia unknown FX Go (NV31)\n"));
379 		status = nvxx_general_powerup();
380 		break;
381 	case 0x031a10de: /* Nvidia GeForce FX 5600 Go */
382 		si->ps.card_type = NV31;
383 		si->ps.card_arch = NV30A;
384 		si->ps.laptop = true;
385 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5600 Go (NV31)\n"));
386 		status = nvxx_general_powerup();
387 		break;
388 	case 0x031b10de: /* Nvidia GeForce FX 5650 Go */
389 		si->ps.card_type = NV31;
390 		si->ps.card_arch = NV30A;
391 		si->ps.laptop = true;
392 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5650 Go (NV31)\n"));
393 		status = nvxx_general_powerup();
394 		break;
395 	case 0x031c10de: /* Nvidia Quadro FX 700 Go */
396 		si->ps.card_type = NV31;
397 		si->ps.card_arch = NV30A;
398 		si->ps.laptop = true;
399 		LOG(4,("POWERUP: Detected Nvidia Quadro FX 700 Go (NV31)\n"));
400 		status = nvxx_general_powerup();
401 		break;
402 	case 0x031d10de: /* Nvidia unknown FX Go */
403 	case 0x031e10de: /* Nvidia unknown FX Go */
404 	case 0x031f10de: /* Nvidia unknown FX Go */
405 		si->ps.card_type = NV31;
406 		si->ps.card_arch = NV30A;
407 		si->ps.laptop = true;
408 		LOG(4,("POWERUP: Detected Nvidia unknown FX Go (NV31)\n"));
409 		status = nvxx_general_powerup();
410 		break;
411 	case 0x032110de: /* Nvidia GeForce FX 5200 Ultra */
412 	case 0x032210de: /* Nvidia GeForce FX 5200 */
413 	case 0x032310de: /* Nvidia GeForce FX 5200SE */
414 		si->ps.card_type = NV34;
415 		si->ps.card_arch = NV30A;
416 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5200 (NV34)\n"));
417 		status = nvxx_general_powerup();
418 		break;
419 	case 0x032410de: /* Nvidia GeForce FX 5200 Go */
420 		si->ps.card_type = NV34;
421 		si->ps.card_arch = NV30A;
422 		si->ps.laptop = true;
423 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5200 Go (NV34)\n"));
424 		status = nvxx_general_powerup();
425 		break;
426 	case 0x032510de: /* Nvidia GeForce FX 5250 Go */
427 		si->ps.card_type = NV34;
428 		si->ps.card_arch = NV30A;
429 		si->ps.laptop = true;
430 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5250 Go (NV34)\n"));
431 		status = nvxx_general_powerup();
432 		break;
433 	case 0x032610de: /* Nvidia GeForce FX 5500 */
434 		si->ps.card_type = NV34;
435 		si->ps.card_arch = NV30A;
436 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5500 (NV34)\n"));
437 		status = nvxx_general_powerup();
438 		break;
439 	case 0x032810de: /* Nvidia GeForce FX 5200 Go 32M/64M */
440 		si->ps.card_type = NV34;
441 		si->ps.card_arch = NV30A;
442 		si->ps.laptop = true;
443 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5200 Go (NV34)\n"));
444 		status = nvxx_general_powerup();
445 		break;
446 	case 0x032910de: /* Nvidia GeForce FX 5200 (PPC) */
447 		si->ps.card_type = NV34;
448 		si->ps.card_arch = NV30A;
449 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5200 (NV34)\n"));
450 		status = nvxx_general_powerup();
451 		break;
452 	case 0x032a10de: /* Nvidia Quadro NVS 280 PCI */
453 		si->ps.card_type = NV34;
454 		si->ps.card_arch = NV30A;
455 		LOG(4,("POWERUP: Detected Nvidia Quadro NVS 280 PCI (NV34)\n"));
456 		status = nvxx_general_powerup();
457 		break;
458 	case 0x032b10de: /* Nvidia Quadro FX 500 */
459 		si->ps.card_type = NV34;
460 		si->ps.card_arch = NV30A;
461 		LOG(4,("POWERUP: Detected Nvidia Quadro FX 500 (NV34)\n"));
462 		status = nvxx_general_powerup();
463 		break;
464 	case 0x032c10de: /* Nvidia GeForce FX 5300 Go */
465 	case 0x032d10de: /* Nvidia GeForce FX 5100 Go */
466 		si->ps.card_type = NV34;
467 		si->ps.card_arch = NV30A;
468 		si->ps.laptop = true;
469 		LOG(4,("POWERUP: Detected Nvidia GeForce FX Go (NV34)\n"));
470 		status = nvxx_general_powerup();
471 		break;
472 	case 0x032e10de: /* Nvidia unknown FX Go */
473 	case 0x032f10de: /* Nvidia unknown FX Go */
474 		si->ps.card_type = NV34;
475 		si->ps.card_arch = NV30A;
476 		si->ps.laptop = true;
477 		LOG(4,("POWERUP: Detected Nvidia unknown FX Go (NV34)\n"));
478 		status = nvxx_general_powerup();
479 		break;
480 	case 0x033010de: /* Nvidia GeForce FX 5900 Ultra */
481 	case 0x033110de: /* Nvidia GeForce FX 5900 */
482 		si->ps.card_type = NV35;
483 		si->ps.card_arch = NV30A;
484 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5900 (NV35)\n"));
485 		status = nvxx_general_powerup();
486 		break;
487 	case 0x033210de: /* Nvidia GeForce FX 5900 XT */
488 		si->ps.card_type = NV35;
489 		si->ps.card_arch = NV30A;
490 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5900 XT (NV35)\n"));
491 		status = nvxx_general_powerup();
492 		break;
493 	case 0x033310de: /* Nvidia GeForce FX 5950 Ultra */
494 		si->ps.card_type = NV38;
495 		si->ps.card_arch = NV30A;
496 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5950 Ultra (NV38)\n"));
497 		status = nvxx_general_powerup();
498 		break;
499 	case 0x033410de: /* Nvidia unknown FX Go(?) */
500 		si->ps.card_type = NV38;
501 		si->ps.card_arch = NV30A;
502 		si->ps.laptop = true;
503 		LOG(4,("POWERUP: Detected Nvidia unknown FX Go(?) (NV38(?))\n"));
504 		status = nvxx_general_powerup();
505 		break;
506 	case 0x033810de: /* Nvidia Quadro FX 3000 */
507 		si->ps.card_type = NV35;
508 		si->ps.card_arch = NV30A;
509 		LOG(4,("POWERUP: Detected Nvidia Quadro FX 3000 (NV35)\n"));
510 		status = nvxx_general_powerup();
511 		break;
512 	case 0x034110de: /* Nvidia GeForce FX 5700 Ultra */
513 	case 0x034210de: /* Nvidia GeForce FX 5700 */
514 	case 0x034310de: /* Nvidia GeForce FX 5700LE */
515 	case 0x034410de: /* Nvidia GeForce FX 5700VE */
516 		si->ps.card_type = NV36;
517 		si->ps.card_arch = NV30A;
518 		LOG(4,("POWERUP: Detected Nvidia GeForce FX 5700 (NV36)\n"));
519 		status = nvxx_general_powerup();
520 		break;
521 	case 0x034e10de: /* Nvidia Quadro FX 1100 */
522 		si->ps.card_type = NV36;
523 		si->ps.card_arch = NV30A;
524 		LOG(4,("POWERUP: Detected Nvidia Quadro FX 1100 (NV36)\n"));
525 		status = nvxx_general_powerup();
526 		break;
527 	case 0x034f10de: /* Nvidia unknown FX */
528 		si->ps.card_type = NV36;
529 		si->ps.card_arch = NV30A;
530 		LOG(4,("POWERUP: Detected Nvidia unknown FX (NV36(?))\n"));
531 		status = nvxx_general_powerup();
532 		break;
533 	/* Vendor Elsa GmbH */
534 	case 0x0c601048: /* Elsa Gladiac Geforce2 MX */
535 		si->ps.card_type = NV11;
536 		si->ps.card_arch = NV10A;
537 		LOG(4,("POWERUP: Detected Elsa Gladiac Geforce2 MX (NV11)\n"));
538 		status = nvxx_general_powerup();
539 		break;
540 	/* Vendor Nvidia STB/SGS-Thompson */
541 	case 0x002012d2: /* Nvidia STB/SGS-Thompson TNT1 */
542 		si->ps.card_type = NV04;
543 		si->ps.card_arch = NV04A;
544 		LOG(4,("POWERUP: Detected Nvidia STB/SGS-Thompson TNT1 (NV04)\n"));
545 		status = nvxx_general_powerup();
546 		break;
547 	case 0x002812d2: /* Nvidia STB/SGS-Thompson TNT2 (pro) */
548 	case 0x002912d2: /* Nvidia STB/SGS-Thompson TNT2 Ultra */
549 	case 0x002a12d2: /* Nvidia STB/SGS-Thompson TNT2 */
550 	case 0x002b12d2: /* Nvidia STB/SGS-Thompson TNT2 */
551 		si->ps.card_type = NV05;
552 		si->ps.card_arch = NV04A;
553 		LOG(4,("POWERUP: Detected Nvidia STB/SGS-Thompson TNT2 (NV05)\n"));
554 		status = nvxx_general_powerup();
555 		break;
556 	case 0x002c12d2: /* Nvidia STB/SGS-Thompson Vanta (Lt) */
557 		si->ps.card_type = NV05;
558 		si->ps.card_arch = NV04A;
559 		LOG(4,("POWERUP: Detected Nvidia STB/SGS-Thompson Vanta (Lt) (NV05)\n"));
560 		status = nvxx_general_powerup();
561 		break;
562 	case 0x002d12d2: /* Nvidia STB/SGS-Thompson TNT2-M64 (Pro) */
563 		si->ps.card_type = NV05M64;
564 		si->ps.card_arch = NV04A;
565 		LOG(4,("POWERUP: Detected Nvidia STB/SGS-Thompson TNT2-M64 (Pro) (NV05M64)\n"));
566 		status = nvxx_general_powerup();
567 		break;
568 	case 0x002e12d2: /* Nvidia STB/SGS-Thompson NV06 Vanta */
569 	case 0x002f12d2: /* Nvidia STB/SGS-Thompson NV06 Vanta */
570 		si->ps.card_type = NV06;
571 		si->ps.card_arch = NV04A;
572 		LOG(4,("POWERUP: Detected Nvidia STB/SGS-Thompson Vanta (NV06)\n"));
573 		status = nvxx_general_powerup();
574 		break;
575 	case 0x00a012d2: /* Nvidia STB/SGS-Thompson Aladdin TNT2 */
576 		si->ps.card_type = NV05;
577 		si->ps.card_arch = NV04A;
578 		LOG(4,("POWERUP: Detected Nvidia STB/SGS-Thompson Aladdin TNT2 (NV05)\n"));
579 		status = nvxx_general_powerup();
580 		break;
581 	/* Vendor Varisys Limited */
582 	case 0x35031888: /* Varisys GeForce4 MX440 */
583 		si->ps.card_type = NV17;
584 		si->ps.card_arch = NV10A;
585 		LOG(4,("POWERUP: Detected Varisys GeForce4 MX440 (NV17)\n"));
586 		status = nvxx_general_powerup();
587 		break;
588 	case 0x35051888: /* Varisys GeForce4 Ti 4200 */
589 		si->ps.card_type = NV25;
590 		si->ps.card_arch = NV20A;
591 		LOG(4,("POWERUP: Detected Varisys GeForce4 Ti 4200 (NV25)\n"));
592 		status = nvxx_general_powerup();
593 		break;
594 	default:
595 		LOG(8,("POWERUP: Failed to detect valid card 0x%08x\n",CFGR(DEVID)));
596 		return B_ERROR;
597 	}
598 
599 	/* override memory detection if requested by user */
600 	if (si->settings.memory != 0)
601 		si->ps.memory_size = si->settings.memory;
602 
603 	return status;
604 }
605 
606 status_t test_ram()
607 {
608 	uint32 value, offset;
609 	status_t result = B_OK;
610 
611 	/* make sure we don't corrupt the hardware cursor by using fbc.frame_buffer. */
612 	if (si->fbc.frame_buffer == NULL)
613 	{
614 		LOG(8,("INIT: test_ram detected NULL pointer.\n"));
615 		return B_ERROR;
616 	}
617 
618 	for (offset = 0, value = 0x55aa55aa; offset < 256; offset++)
619 	{
620 		/* write testpattern to cardRAM */
621 		((uint32 *)si->fbc.frame_buffer)[offset] = value;
622 		/* toggle testpattern */
623 		value = 0xffffffff - value;
624 	}
625 
626 	for (offset = 0, value = 0x55aa55aa; offset < 256; offset++)
627 	{
628 		/* readback and verify testpattern from cardRAM */
629 		if (((uint32 *)si->fbc.frame_buffer)[offset] != value) result = B_ERROR;
630 		/* toggle testpattern */
631 		value = 0xffffffff - value;
632 	}
633 	return result;
634 }
635 
636 /* NOTE:
637  * This routine *has* to be done *after* SetDispplayMode has been executed,
638  * or test results will not be representative!
639  * (CAS latency is dependant on NV setup on some (DRAM) boards) */
640 status_t nv_set_cas_latency()
641 {
642 	status_t result = B_ERROR;
643 	uint8 latency = 0;
644 
645 	/* check current RAM access to see if we need to change anything */
646 	if (test_ram() == B_OK)
647 	{
648 		LOG(4,("INIT: RAM access OK.\n"));
649 		return B_OK;
650 	}
651 
652 	/* check if we read PINS at starttime so we have valid registersettings at our disposal */
653 	if (si->ps.pins_status != B_OK)
654 	{
655 		LOG(4,("INIT: RAM access errors; not fixable: PINS was not read from cardBIOS.\n"));
656 		return B_ERROR;
657 	}
658 
659 	/* OK. We might have a problem, try to fix it now.. */
660 	LOG(4,("INIT: RAM access errors; tuning CAS latency if prudent...\n"));
661 
662 	switch(si->ps.card_type)
663 	{
664 	case G550:
665 			if (0)//!si->ps.sdram)
666 			{
667 				LOG(4,("INIT: G100 SGRAM CAS tuning not permitted, aborting.\n"));
668 				return B_OK;
669 			}
670 			/* SDRAM card */
671 			for (latency = 4; latency >= 2; latency-- )
672 			{
673 				/* MCTLWTST is a write-only register! */
674 //				ACCW(MCTLWTST, ((si->ps.mctlwtst_reg & 0xfffffffc) | (latency - 2)));
675 				result = test_ram();
676 				if (result == B_OK) break;
677 			}
678 			break;
679 	default:
680 			/* fixme: Millenium2 and others if needed */
681 			LOG(4,("INIT: RAM CAS tuning not implemented for this card, aborting.\n"));
682 			return B_OK;
683 			break;
684 	}
685 	if (result == B_OK)
686 		LOG(4,("INIT: RAM access OK. CAS latency set to %d cycles.\n", latency));
687 	else
688 		LOG(4,("INIT: RAM access not fixable. CAS latency set to %d cycles.\n", latency));
689 
690 	return result;
691 }
692 
693 static status_t nvxx_general_powerup()
694 {
695 	status_t result;
696 
697 	LOG(4, ("INIT: NV powerup\n"));
698 	if (si->settings.logmask & 0x80000000) nv_dump_configuration_space();
699 
700 	/* initialize the shared_info PINS struct */
701 	result = parse_pins();
702 	if (result != B_OK) fake_pins();
703 
704 	/* log the PINS struct settings */
705 	dump_pins();
706 
707 	/* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */
708 //temp:
709 return nv_general_bios_to_powergraphics();
710 	if (si->settings.usebios || (result != B_OK)) return nv_general_bios_to_powergraphics();
711 
712 	/*power up the PLLs,LUT,DAC*/
713 	LOG(2,("INIT: PLL/LUT/DAC powerup\n"));
714 	/* turn off both displays and the hardcursor (also disables transfers) */
715 	nv_crtc_dpms(false, false, false);
716 	nv_crtc_cursor_hide();
717 	/* G200 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals!
718 	 * (this would create electrical shortcuts,
719 	 * resulting in extra chip heat and distortions visible on screen */
720 	/* set voltage reference - using DAC reference block partly */
721 //	DXIW(VREFCTRL,0x03);
722 	/* wait for 100ms for voltage reference to stabilize */
723 	delay(100000);
724 	/* power up the SYSPLL */
725 //	CFGW(OPTION,CFGR(OPTION)|0x20);
726 	/* power up the PIXPLL */
727 //	DXIW(PIXCLKCTRL,0x08);
728 
729 	/* disable pixelclock oscillations before switching on CLUT */
730 //	DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) | 0x04));
731 	/* disable 15bit mode CLUT-overlay function */
732 //	DXIW(GENCTRL, DXIR(GENCTRL & 0xfd));
733 	/* CRTC2->MAFC, 8-bit DAC, CLUT enabled, enable DAC */
734 //	DXIW(MISCCTRL,0x1b);
735 	snooze(250);
736 	/* re-enable pixelclock oscillations */
737 //	DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) & 0xfb));
738 
739 	/* setup i2c bus */
740 	i2c_init();
741 
742 	/*make sure card is in powergraphics mode*/
743 //	VGAW_I(CRTCEXT,3,0x80);
744 
745 	/*set the system clocks to powergraphics speed*/
746 	LOG(2,("INIT: Setting system PLL to powergraphics speeds\n"));
747 	g400_dac_set_sys_pll();
748 
749 	/* 'official' RAM initialisation */
750 	LOG(2,("INIT: RAM init\n"));
751 	/* disable hardware plane write mask if SDRAM card */
752 //	if (si->ps.sdram) CFGW(OPTION,(CFGR(OPTION) & 0xffffbfff));
753 	/* disable plane write mask (needed for SDRAM): actual change needed to get it sent to RAM */
754 //	ACCW(PLNWT,0x00000000);
755 //	ACCW(PLNWT,0xffffffff);
756 	/* program memory control waitstates */
757 //	ACCW(MCTLWTST,si->ps.mctlwtst_reg);
758 	/* set memory configuration including:
759 	 * - SDRAM / SGRAM special functions select. */
760 //	CFGW(OPTION,(CFGR(OPTION)&0xFFFF83FF) | ((si->ps.v3_mem_type & 0x07) << 10));
761 //	if (!si->ps.sdram) CFGW(OPTION,(CFGR(OPTION) | (0x01 << 14)));
762 	/* set memory buffer type */
763 //	CFGW(OPTION2,(CFGR(OPTION2)&0xFFFFCFFF)|((si->ps.v3_option2_reg & 0x03) << 12));
764 	/* set mode register opcode and streamer flow control */
765 //	ACCW(MEMRDBK,(ACCR(MEMRDBK)&0x0000FFFF)|(si->ps.memrdbk_reg & 0xffff0000));
766 	/* set RAM read tap delays */
767 //	ACCW(MEMRDBK,(ACCR(MEMRDBK)&0xFFFF0000)|(si->ps.memrdbk_reg & 0x0000ffff));
768 	/* wait 200uS minimum */
769 	snooze(250);
770 
771 	/* reset memory (MACCESS is a write only register!) */
772 //	ACCW(MACCESS, 0x00000000);
773 	/* perform actual RAM reset */
774 //	ACCW(MACCESS, 0x00008000);
775 	snooze(250);
776 	/* start memory refresh */
777 //	CFGW(OPTION,(CFGR(OPTION)&0xffe07fff) | (si->ps.option_reg & 0x001f8000));
778 	/* set memory control waitstate again AFTER the RAM reset */
779 //	ACCW(MCTLWTST,si->ps.mctlwtst_reg);
780 	/* end 'official' RAM initialisation. */
781 
782 	/* Bus parameters: enable retries, use advanced read */
783 //	CFGW(OPTION,(CFGR(OPTION)|(1<<22)|(0<<29)));
784 
785 	/*enable writing to crtc registers*/
786 //	VGAW_I(CRTC,0x11,0);
787 
788 	/* turn on display one */
789 	nv_crtc_dpms(true , true, true);
790 
791 	return B_OK;
792 }
793 
794 status_t nv_general_output_select(bool cross)
795 {
796 	/* make sure this call is warranted */
797 	if (si->ps.secondary_head)
798 	{
799 		/* NV11 cards can't switch heads */
800 		if (si->ps.card_type != NV11)
801 		{
802 			if (cross)
803 			{
804 				LOG(4,("INIT: switching outputs to be cross-connected\n"));
805 
806 				/* enable head 2 on connector 1 */
807 				/* (b8 = select CRTC (head) for output,
808 				 *  b4 = enable DVI???,
809 				 *  b0 = enable CRT) */
810 				DACW(OUTPUT, 0x00000101);
811 				/* enable head 1 on connector 2 */
812 				DAC2W(OUTPUT, 0x00000001);
813 			}
814 			else
815 			{
816 				LOG(4,("INIT: switching outputs to be straight-through\n"));
817 
818 				/* enable head 1 on connector 1 */
819 				DACW(OUTPUT, 0x00000001);
820 				/* enable head 2 on connector 2 */
821 				DAC2W(OUTPUT, 0x00000101);
822 			}
823 		}
824 		else
825 		{
826 			LOG(4,("INIT: NV11 outputs are hardwired to be straight-through\n"));
827 		}
828 		return B_OK;
829 	}
830 	else
831 	{
832 		return B_ERROR;
833 	}
834 }
835 
836 /* basic change of card state from VGA to enhanced mode:
837  * Should work from VGA BIOS POST init state. */
838 static
839 status_t nv_general_bios_to_powergraphics()
840 {
841 	LOG(2, ("INIT: Skipping card coldstart!\n"));
842 
843 	/* let acc engine make power off/power on cycle to start 'fresh' */
844 	NV_REG32(NV32_PWRUPCTRL) = 0x13110011;
845 	snooze(1000);
846 
847 	/* power-up all nvidia hardware function blocks */
848 	/* bit 28: OVERLAY ENGINE (BES),
849 	 * bit 25: CRTC2, (> NV04A)
850 	 * bit 24: CRTC1,
851 	 * bit 20: framebuffer,
852 	 * bit 16: PPMI,
853 	 * bit 12: PGRAPH,
854 	 * bit  8: PFIFO,
855 	 * bit  4: PMEDIA,
856 	 * bit  0: TVOUT. (> NV04A) */
857 	NV_REG32(NV32_PWRUPCTRL) = 0x13111111;
858 
859 	/* select colormode CRTC registers base adresses */
860 	NV_REG8(NV8_MISCW) = 0xcb;
861 
862 	/* unlock card registers for R/W access */
863 	if (si->ps.secondary_head) CRTCW(OWNER, 0x00);
864 	CRTCW(LOCK, 0x57);
865 	CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f));
866 	if (si->ps.secondary_head)
867 	{
868 		CRTC2W(OWNER, 0x03);
869 		CRTC2W(LOCK, 0x57);
870 		CRTC2W(VSYNCE ,(CRTCR(VSYNCE) & 0x7f));
871 	}
872 
873 	/* turn off both displays and the hardcursors (also disables transfers) */
874 	nv_crtc_dpms(false, false, false);
875 	nv_crtc_cursor_hide();
876 	if (si->ps.secondary_head)
877 	{
878 		nv_crtc2_dpms(false, false, false);
879 		nv_crtc2_cursor_hide();
880 	}
881 
882 	if (si->ps.secondary_head)
883 	{
884 		/* switch overlay engine to CRTC1 */
885 		/* bit 12: overlay engine,
886 		 * bit  8: TVout chip (fixme: or bit 4?),
887 		 * bit  4: DDC channel (fixme: or bit 8?) */
888 		NV_REG32(NV32_2FUNCSEL) &= ~0x00001000;
889 		NV_REG32(NV32_FUNCSEL) |= 0x00001000;
890 	}
891 	si->overlay.crtc = 0;
892 
893 	/* enable 'enhanced' mode on primary head: */
894 	/* enable access to primary head */
895 	if (si->ps.secondary_head) CRTCW(OWNER, 0x00);
896 	/* note: 'BUFFER' is a non-standard register in behaviour(!) on most
897 	 * NV11's like the GeForce2 MX200, while the MX400 and non-NV11 cards
898 	 * behave normally.
899 	 * Also readback is not nessesarily what was written before!
900 	 *
901 	 * Double-write action needed on those strange NV11 cards: */
902 	/* RESET: don't doublebuffer CRTC access: set programmed values immediately... */
903 	CRTCW(BUFFER, 0xff);
904 	/* ... and keep fine pitched CRTC granularity on > NV4 cards (b2 = 0) */
905 	CRTCW(BUFFER, 0xfb);
906 	/* select VGA mode (old VGA register) */
907 	CRTCW(MODECTL, 0xc3);
908 	/* select graphics mode (old VGA register) */
909 	SEQW(MEMMODE, 0x0e);
910 	/* select 8 dots character clocks (old VGA register) */
911 	SEQW(CLKMODE, 0x21);
912 	/* select VGA mode (old VGA register) */
913 	GRPHW(MODE, 0x00);
914 	/* select graphics mode (old VGA register) */
915 	GRPHW(MISC, 0x01);
916 	/* select graphics mode (old VGA register) */
917 	ATBW(MODECTL, 0x01);
918 	/* enable 'enhanced mode', enable Vsync & Hsync,
919 	 * set DAC palette to 8-bit width, disable large screen */
920 	CRTCW(REPAINT1, 0x04);
921 
922 	/* enable 'enhanced' mode on secondary head: */
923 	if (si->ps.secondary_head)
924 	{
925 		/* enable access to secondary head (is SEQ2, GRPH2, CRTC2, ATB2, etc!!) */
926 		CRTC2W(OWNER, 0x03);
927 		/* select colormode CRTC2 registers base adresses */
928 		NV_REG8(NV8_MISCW) = 0xcb;
929 		/* note: 'BUFFER' is a non-standard register in behaviour(!) on most
930 		 * NV11's like the GeForce2 MX200, while the MX400 and non-NV11 cards
931 		 * behave normally.
932 		 * Also readback is not nessesarily what was written before!
933 		 *
934 		 * Double-write action needed on those strange NV11 cards: */
935 		/* RESET: don't doublebuffer CRTC2 access: set programmed values immediately... */
936 		CRTC2W(BUFFER, 0xff);
937 		/* ... and keep fine pitched CRTC2 granularity (b2 = 0) */
938 		CRTC2W(BUFFER, 0xfb);
939 		/* select VGA mode (old VGA register) */
940 		CRTC2W(MODECTL, 0xc3);
941 		/* select graphics mode (old VGA register) */
942 		SEQW(MEMMODE, 0x0e);
943 		/* select 8 dots character clocks (old VGA register) */
944 		SEQW(CLKMODE, 0x21);
945 		/* select VGA mode (old VGA register) */
946 		GRPHW(MODE, 0x00);
947 		/* select graphics mode (old VGA register) */
948 		GRPHW(MISC, 0x01);
949 		/* select graphics mode (old VGA register) */
950 		ATB2W(MODECTL, 0x01);
951 		/* enable 'enhanced mode', enable Vsync & Hsync,
952 		 * set DAC palette to 8-bit width, disable large screen */
953 		CRTC2W(REPAINT1, 0x04);
954 	}
955 
956 	/* enable palettes */
957 	DACW(GENCTRL, 0x00100100);
958 	if (si->ps.secondary_head) DAC2W(GENCTRL, 0x00100100);
959 
960 	/* enable programmable PLLs */
961 	DACW(PLLSEL, 0x10000700);
962 	if (si->ps.secondary_head) DACW(PLLSEL, (DACR(PLLSEL) | 0x20000800));
963 
964 	/* turn on DAC and make sure detection testsignal routing is disabled
965 	 * (b16 = disable DAC,
966 	 *  b12 = enable testsignal output */
967 	DACW(TSTCTRL, (DACR(TSTCTRL) & 0xfffeefff));
968 	/* turn on DAC2 if it exists
969 	 * (NOTE: testsignal function block resides in DAC1 only (!)) */
970 	if (si->ps.secondary_head) DAC2W(TSTCTRL, (DAC2R(TSTCTRL) & 0xfffeefff));
971 
972 	/* turn screen one on */
973 	nv_crtc_dpms(true, true, true);
974 
975 	return B_OK;
976 }
977 
978 /* Check if mode virtual_size adheres to the cards _maximum_ contraints, and modify
979  * virtual_size to the nearest valid maximum for the mode on the card if not so.
980  * Also: check if virtual_width adheres to the cards granularity constraints, and
981  * create mode slopspace if not so.
982  * We use acc or crtc granularity constraints based on the 'worst case' scenario.
983  *
984  * Mode slopspace is reflected in fbc->bytes_per_row BTW. */
985 status_t nv_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row, bool *acc_mode)
986 {
987 	uint32 video_pitch;
988 	uint32 acc_mask, crtc_mask;
989 	uint32 max_crtc_width, max_acc_width;
990 	uint8 depth = 8;
991 
992 	/* determine pixel multiple based on 2D/3D engine constraints */
993 	switch (si->ps.card_arch)
994 	{
995 	default:
996 		/* confirmed for:
997 		 * TNT1, TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForceFX 5200 */
998 		switch (target->space)
999 		{
1000 			case B_CMAP8: acc_mask = 0x0f; depth =  8; break;
1001 			case B_RGB15: acc_mask = 0x07; depth = 16; break;
1002 			case B_RGB16: acc_mask = 0x07; depth = 16; break;
1003 			case B_RGB24: acc_mask = 0x0f; depth = 24; break;
1004 			case B_RGB32: acc_mask = 0x03; depth = 32; break;
1005 			default:
1006 				LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
1007 				return B_ERROR;
1008 		}
1009 		/* NV31 (confirmed GeForceFX 5600) has NV20A granularity!
1010 		 * So let it fall through... */
1011 		if (si->ps.card_type != NV31) break;
1012 	case NV20A:
1013 		/* confirmed for:
1014 		 * GeForce4 Ti4200 */
1015 		switch (target->space)
1016 		{
1017 			case B_CMAP8: acc_mask = 0x3f; depth =  8; break;
1018 			case B_RGB15: acc_mask = 0x1f; depth = 16; break;
1019 			case B_RGB16: acc_mask = 0x1f; depth = 16; break;
1020 			case B_RGB24: acc_mask = 0x3f; depth = 24; break;
1021 			case B_RGB32: acc_mask = 0x0f; depth = 32; break;
1022 			default:
1023 				LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
1024 				return B_ERROR;
1025 		}
1026 		break;
1027 	}
1028 
1029 	/* determine pixel multiple based on CRTC memory pitch constraints:
1030 	 * -> all NV cards have same granularity constraints on CRTC1 and CRTC2,
1031 	 *    provided that the CRTC1 and CRTC2 BUFFER register b2 = 0;
1032 	 *
1033 	 * (Note: Don't mix this up with CRTC timing contraints! Those are
1034 	 *        multiples of 8 for horizontal, 1 for vertical timing.) */
1035 	if (0)
1036 	{
1037 		/* confirmed for:
1038 		 * TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForce4 Ti4200,
1039 		 * GeForceFX 5200: if the CRTC1 (and CRTC2) BUFFER register b2 = 1 */
1040 		switch (target->space)
1041 		{
1042 			case B_CMAP8: crtc_mask = 0x1f; break;
1043 			case B_RGB15: crtc_mask = 0x0f; break;
1044 			case B_RGB16: crtc_mask = 0x0f; break;
1045 			case B_RGB24: crtc_mask = 0x1f; break;
1046 			case B_RGB32: crtc_mask = 0x07; break;
1047 			default:
1048 				LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
1049 				return B_ERROR;
1050 		}
1051 	}
1052 	else
1053 	{
1054 		/* confirmed for:
1055 		 * TNT1 always;
1056 		 * TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForce4 Ti4200,
1057 		 * GeForceFX 5200: if the CRTC1 (and CRTC2) BUFFER register b2 = 0 */
1058 		/* NOTE:
1059 		 * Unfortunately older cards have a hardware fault that prevents use.
1060 		 * We need doubled granularity on those to prevent the single top line
1061 		 * from shifting to the left!
1062 		 * This is confirmed for TNT2, GeForce2 MX200, GeForce2 MX400.
1063 		 * Confirmed OK are:
1064 		 * GeForce4 MX440, GeForce4 Ti4200, GeForceFX 5200. */
1065 		switch (target->space)
1066 		{
1067 			case B_CMAP8: crtc_mask = 0x0f; break; /* 0x07 */
1068 			case B_RGB15: crtc_mask = 0x07; break; /* 0x03 */
1069 			case B_RGB16: crtc_mask = 0x07; break; /* 0x03 */
1070 			case B_RGB24: crtc_mask = 0x0f; break; /* 0x07 */
1071 			case B_RGB32: crtc_mask = 0x03; break; /* 0x01 */
1072 			default:
1073 				LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
1074 				return B_ERROR;
1075 		}
1076 	}
1077 
1078 	/* set virtual_width limit for accelerated modes */
1079 	switch (si->ps.card_arch)
1080 	{
1081 	case NV04A:
1082 		/* confirmed for:
1083 		 * TNT1, TNT2, TNT2-M64 */
1084 		switch(target->space)
1085 		{
1086 			case B_CMAP8: max_acc_width = 8176; break;
1087 			case B_RGB15: max_acc_width = 4088; break;
1088 			case B_RGB16: max_acc_width = 4088; break;
1089 			case B_RGB24: max_acc_width = 2720; break;
1090 			case B_RGB32: max_acc_width = 2044; break;
1091 			default:
1092 				LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
1093 				return B_ERROR;
1094 		}
1095 		break;
1096 	default:
1097 		/* confirmed for:
1098 		 * GeForce2 MX400, GeForce4 MX440, GeForceFX 5200 */
1099 		switch(target->space)
1100 		{
1101 			case B_CMAP8: max_acc_width = 16368; break;
1102 			case B_RGB15: max_acc_width =  8184; break;
1103 			case B_RGB16: max_acc_width =  8184; break;
1104 			case B_RGB24: max_acc_width =  5456; break;
1105 			case B_RGB32: max_acc_width =  4092; break;
1106 			default:
1107 				LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
1108 				return B_ERROR;
1109 		}
1110 		/* NV31 (confirmed GeForceFX 5600) has NV20A granularity!
1111 		 * So let it fall through... */
1112 		if (si->ps.card_type != NV31) break;
1113 	case NV20A:
1114 		/* confirmed for:
1115 		 * GeForce4 Ti4200 */
1116 		switch(target->space)
1117 		{
1118 			case B_CMAP8: max_acc_width = 16320; break;
1119 			case B_RGB15: max_acc_width =  8160; break;
1120 			case B_RGB16: max_acc_width =  8160; break;
1121 			case B_RGB24: max_acc_width =  5440; break;
1122 			case B_RGB32: max_acc_width =  4080; break;
1123 			default:
1124 				LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
1125 				return B_ERROR;
1126 		}
1127 		break;
1128 	}
1129 
1130 	/* set virtual_width limit for unaccelerated modes */
1131 	if (0)
1132 	{
1133 		/* confirmed for:
1134 		 * TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForce4 Ti4200,
1135 		 * GeForceFX 5200: if the CRTC1 (and CRTC2) BUFFER register b2 = 1 */
1136 		switch(target->space)
1137 		{
1138 			case B_CMAP8: max_crtc_width = 16352; break;
1139 			case B_RGB15: max_crtc_width =  8176; break;
1140 			case B_RGB16: max_crtc_width =  8176; break;
1141 			case B_RGB24: max_crtc_width =  5440; break;
1142 			case B_RGB32: max_crtc_width =  4088; break;
1143 			default:
1144 				LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
1145 				return B_ERROR;
1146 		}
1147 	}
1148 	else
1149 	{
1150 		/* confirmed for:
1151 		 * TNT1 always;
1152 		 * TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForce4 Ti4200,
1153 		 * GeForceFX 5200: if the CRTC1 (and CRTC2) BUFFER register b2 = 0 */
1154 		/* NOTE:
1155 		 * Unfortunately older cards have a hardware fault that prevents use.
1156 		 * We need doubled granularity on those to prevent the single top line
1157 		 * from shifting to the left!
1158 		 * This is confirmed for TNT2, GeForce2 MX200, GeForce2 MX400.
1159 		 * Confirmed OK are:
1160 		 * GeForce4 MX440, GeForce4 Ti4200, GeForceFX 5200. */
1161 		switch(target->space)
1162 		{
1163 			case B_CMAP8: max_crtc_width = 16368; break; /* 16376 */
1164 			case B_RGB15: max_crtc_width =  8184; break; /*  8188 */
1165 			case B_RGB16: max_crtc_width =  8184; break; /*  8188 */
1166 			case B_RGB24: max_crtc_width =  5456; break; /*  5456 */
1167 			case B_RGB32: max_crtc_width =  4092; break; /*  4094 */
1168 			default:
1169 				LOG(8,("INIT: unknown color space: 0x%08x\n", target->space));
1170 				return B_ERROR;
1171 		}
1172 	}
1173 
1174 	/* check for acc capability, and adjust mode to adhere to hardware constraints */
1175 	if (max_acc_width <= max_crtc_width)
1176 	{
1177 		/* check if we can setup this mode with acceleration */
1178 		*acc_mode = true;
1179 		/* virtual_width */
1180 		if (target->virtual_width > max_acc_width) *acc_mode = false;
1181 		/* virtual_height */
1182 		/* (NV cards can even do more than this(?)...
1183 		 *  but 4096 is confirmed on all cards at max. accelerated width.) */
1184 		if (target->virtual_height > 4096) *acc_mode = false;
1185 
1186 		/* now check virtual_size based on CRTC constraints */
1187 		if (target->virtual_width > max_crtc_width) target->virtual_width = max_crtc_width;
1188 		/* virtual_height: The only constraint here is the cards memory size which is
1189 		 * checked later on in ProposeMode: virtual_height is adjusted then if needed.
1190 		 * 'Limiting here' to the variable size that's at least available (uint16). */
1191 		if (target->virtual_height > 65535) target->virtual_height = 65535;
1192 
1193 		/* OK, now we know that virtual_width is valid, and it's needing no slopspace if
1194 		 * it was confined above, so we can finally calculate safely if we need slopspace
1195 		 * for this mode... */
1196 		if (*acc_mode)
1197 		{
1198 			/* the mode needs to adhere to the largest granularity imposed... */
1199 			if (acc_mask < crtc_mask)
1200 				video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask);
1201 			else
1202 				video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask);
1203 		}
1204 		else /* unaccelerated mode */
1205 			video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask);
1206 	}
1207 	else /* max_acc_width > max_crtc_width */
1208 	{
1209 		/* check if we can setup this mode with acceleration */
1210 		*acc_mode = true;
1211 		/* (we already know virtual_width will be no problem) */
1212 		/* virtual_height */
1213 		/* (NV cards can even do more than this(?)...
1214 		 *  but 4096 is confirmed on all cards at max. accelerated width.) */
1215 		if (target->virtual_height > 4096) *acc_mode = false;
1216 
1217 		/* now check virtual_size based on CRTC constraints */
1218 		if (*acc_mode)
1219 		{
1220 			/* note that max_crtc_width already adheres to crtc_mask */
1221 			if (target->virtual_width > (max_crtc_width & ~acc_mask))
1222 					target->virtual_width = (max_crtc_width & ~acc_mask);
1223 		}
1224 		else /* unaccelerated mode */
1225 		{
1226 			if (target->virtual_width > max_crtc_width)
1227 					target->virtual_width = max_crtc_width;
1228 		}
1229 		/* virtual_height: The only constraint here is the cards memory size which is
1230 		 * checked later on in ProposeMode: virtual_height is adjusted then if needed.
1231 		 * 'Limiting here' to the variable size that's at least available (uint16). */
1232 		if (target->virtual_height > 65535) target->virtual_height = 65535;
1233 
1234 		/* OK, now we know that virtual_width is valid, and it's needing no slopspace if
1235 		 * it was confined above, so we can finally calculate safely if we need slopspace
1236 		 * for this mode... */
1237 		if (*acc_mode)
1238 		{
1239 			/* the mode needs to adhere to the largest granularity imposed... */
1240 			if (acc_mask < crtc_mask)
1241 				video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask);
1242 			else
1243 				video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask);
1244 		}
1245 		else /* unaccelerated mode */
1246 			video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask);
1247 	}
1248 
1249 	LOG(2,("INIT: memory pitch will be set to %d pixels for colorspace 0x%08x\n",
1250 														video_pitch, target->space));
1251 	if (target->virtual_width != video_pitch)
1252 		LOG(2,("INIT: effective mode slopspace is %d pixels\n",
1253 											(video_pitch - target->virtual_width)));
1254 
1255 	/* now calculate bytes_per_row for this mode */
1256 	*bytes_per_row = video_pitch * (depth >> 3);
1257 
1258 	return B_OK;
1259 }
1260