xref: /haiku/src/add-ons/accelerants/skeleton/engine/info.c (revision 2600324b57fa31cdea1627d584d314f2a579c4a8)
1 /* Read initialisation information from card */
2 /* some bits are hacks, where PINS is not known */
3 /* Author:
4    Rudolf Cornelissen 7/2003-10/2004
5 */
6 
7 #define MODULE_BIT 0x00002000
8 
9 #include "std.h"
10 
11 /* pins V5.16 and up ROM infoblock stuff */
12 typedef struct {
13 	uint16	InitScriptTablePtr;		/* ptr to list of ptrs to scripts to exec */
14 	uint16	MacroIndexTablePtr;		/* ptr to list with indexes and sizes of items in MacroTable */
15 	uint16	MacroTablePtr;			/* ptr to list with items containing multiple 32bit reg writes */
16 	uint16	ConditionTablePtr;		/* ptr to list of PCI regs and bits to tst for exec mode */
17 	uint16	IOConditionTablePtr;	/* ptr to list of ISA regs and bits to tst for exec mode */
18 	uint16	IOFlagConditionTablePtr;/* ptr to list of ISA regs and bits to tst, ref'd to a matrix, for exec mode */
19 	uint16	InitFunctionTablePtr;	/* ptr to list of startadresses of fixed ROM init routines */
20 } PinsTables;
21 
22 static void detect_panels(void);
23 static void setup_output_matrix(void);
24 static void pinsnv4_fake(void);
25 static void pinsnv5_nv5m64_fake(void);
26 static void pinsnv6_fake(void);
27 static void pinsnv10_arch_fake(void);
28 static void pinsnv20_arch_fake(void);
29 static void pinsnv30_arch_fake(void);
30 static void getRAMsize_arch_nv4(void);
31 static void getstrap_arch_nv4(void);
32 static void getRAMsize_arch_nv10_20_30_40(void);
33 static void getstrap_arch_nv10_20_30_40(void);
34 static status_t pins2_read(uint8 *rom, uint32 offset);
35 static status_t pins3_5_read(uint8 *rom, uint32 offset);
36 static status_t coldstart_card(uint8* rom, uint16 init1, uint16 init2, uint16 init_size, uint16 ram_tab);
37 static status_t coldstart_card_516_up(uint8* rom, PinsTables tabs, uint16 ram_tab);
38 static status_t exec_type1_script(uint8* rom, uint16 adress, int16* size, uint16 ram_tab);
39 static status_t exec_type2_script(uint8* rom, uint16 adress, int16* size, PinsTables tabs, uint16 ram_tab);
40 static status_t exec_type2_script_mode(uint8* rom, uint16* adress, int16* size, PinsTables tabs, uint16 ram_tab, bool* exec);
41 static void	exec_cmd_39_type2(uint8* rom, uint32 data, PinsTables tabs, bool* exec);
42 static void log_pll(uint32 reg, uint32 freq);
43 static void	setup_ram_config(uint8* rom, uint16 ram_tab);
44 static void	setup_ram_config_nv10_up(uint8* rom);
45 static void	setup_ram_config_nv28(uint8* rom);
46 static status_t translate_ISA_PCI(uint32* reg);
47 static status_t	eng_crtc_setup_fifo(void);
48 
49 /* Parse the BIOS PINS structure if there */
50 status_t parse_pins ()
51 {
52 	uint8 *rom;
53 	uint8 chksum = 0;
54 	int i;
55 	uint32 offset;
56 	status_t result = B_ERROR;
57 
58 	/* preset PINS read status to failed */
59 	si->ps.pins_status = B_ERROR;
60 
61 	/* check the validity of PINS */
62 	LOG(2,("INFO: Reading PINS info\n"));
63 	rom = (uint8 *) si->rom_mirror;
64 	/* check BIOS signature - this is defined in the PCI standard */
65 	if (rom[0]!=0x55 || rom[1]!=0xaa)
66 	{
67 		LOG(8,("INFO: BIOS signature not found\n"));
68 		return B_ERROR;
69 	}
70 	LOG(2,("INFO: BIOS signature $AA55 found OK\n"));
71 
72 	/* find the PINS struct adress */
73 	for (offset = 0; offset < 65536; offset++)
74 	{
75 		if (rom[offset    ] != 0xff) continue;
76 		if (rom[offset + 1] != 0x7f) continue;
77 		if (rom[offset + 2] != 0x4e) continue; /* N */
78 		if (rom[offset + 3] != 0x56) continue; /* V */
79 		if (rom[offset + 4] != 0x00) continue;
80 
81 		LOG(8,("INFO: PINS signature found\n"));
82 		break;
83 	}
84 
85 	if (offset > 65535)
86 	{
87 		LOG(8,("INFO: PINS signature not found\n"));
88 		return B_ERROR;
89 	}
90 
91 	/* verify PINS checksum */
92 	for (i = 0; i < 8; i++)
93 	{
94 		chksum += rom[offset + i];
95 	}
96 	if (chksum)
97 	{
98 		LOG(8,("INFO: PINS checksum error\n"));
99 		return B_ERROR;
100 	}
101 
102 	/* checkout PINS struct version */
103 	LOG(2,("INFO: PINS checksum is OK; PINS version is %d.%d\n",
104 		rom[offset + 5], rom[offset + 6]));
105 
106 	/* update the si->ps struct as far as is possible and coldstart card */
107 	//fixme: NV40 and up(?) nolonger use this system...
108 	switch (rom[offset + 5])
109 	{
110 	case 2:
111 		result = pins2_read(rom, offset);
112 		break;
113 	case 3:
114 	case 4:
115 	case 5:
116 		result = pins3_5_read(rom, offset);
117 		break;
118 	default:
119 		LOG(8,("INFO: unknown PINS version\n"));
120 		return B_ERROR;
121 		break;
122 	}
123 
124 	/* check PINS read result */
125 	if (result == B_ERROR)
126 	{
127 		LOG(8,("INFO: PINS read/decode/execute error\n"));
128 		return B_ERROR;
129 	}
130 	/* PINS scan succeeded */
131 	si->ps.pins_status = B_OK;
132 	LOG(2,("INFO: PINS scan completed succesfully\n"));
133 	return B_OK;
134 }
135 
136 static status_t pins2_read(uint8 *rom, uint32 offset)
137 {
138 	uint16 init1 = rom[offset + 18] + (rom[offset + 19] * 256);
139 	uint16 init2 = rom[offset + 20] + (rom[offset + 21] * 256);
140 	uint16 init_size = rom[offset + 22] + (rom[offset + 23] * 256) + 1;
141 	/* confirmed by comparing cards */
142 	uint16 ram_tab = init1 - 0x0010;
143 	/* fixme: PPC BIOSes (might) return NULL pointers for messages here */
144 	char* signon_msg   = &(rom[(rom[offset + 24] + (rom[offset + 25] * 256))]);
145 	char* vendor_name  = &(rom[(rom[offset + 40] + (rom[offset + 41] * 256))]);
146 	char* product_name = &(rom[(rom[offset + 42] + (rom[offset + 43] * 256))]);
147 	char* product_rev  = &(rom[(rom[offset + 44] + (rom[offset + 45] * 256))]);
148 
149 	LOG(8,("INFO: cmdlist 1: $%04x, 2: $%04x, max. size $%04x\n", init1, init2, init_size));
150 	LOG(8,("INFO: signon msg:\n%s\n", signon_msg));
151 	LOG(8,("INFO: vendor name: %s\n", vendor_name));
152 	LOG(8,("INFO: product name: %s\n", product_name));
153 	LOG(8,("INFO: product rev: %s\n", product_rev));
154 
155 	return coldstart_card(rom, init1, init2, init_size, ram_tab);
156 }
157 
158 static status_t pins3_5_read(uint8 *rom, uint32 offset)
159 {
160 	uint16 init1 = rom[offset + 18] + (rom[offset + 19] * 256);
161 	uint16 init2 = rom[offset + 20] + (rom[offset + 21] * 256);
162 	uint16 init_size = rom[offset + 22] + (rom[offset + 23] * 256) + 1;
163 	/* still confirm!! */
164 	uint16 ram_tab = init1 - 0x0010;
165 	/* fixme: PPC BIOSes (might) return NULL pointers for messages here */
166 	char* signon_msg   = &(rom[(rom[offset + 30] + (rom[offset + 31] * 256))]);
167 	char* vendor_name  = &(rom[(rom[offset + 46] + (rom[offset + 47] * 256))]);
168 	char* product_name = &(rom[(rom[offset + 48] + (rom[offset + 49] * 256))]);
169 	char* product_rev  = &(rom[(rom[offset + 50] + (rom[offset + 51] * 256))]);
170 
171 	LOG(8,("INFO: pre PINS 5.16 cmdlist 1: $%04x, 2: $%04x, max. size $%04x\n", init1, init2, init_size));
172 	LOG(8,("INFO: signon msg:\n%s\n", signon_msg));
173 	LOG(8,("INFO: vendor name: %s\n", vendor_name));
174 	LOG(8,("INFO: product name: %s\n", product_name));
175 	LOG(8,("INFO: product rev: %s\n", product_rev));
176 
177 	/* pins 5.06 and higher has VCO range info */
178 	if (((rom[offset + 5]) == 5) && ((rom[offset + 6]) >= 0x06))
179 	{
180 		/* get PLL VCO range info */
181 		uint32 fvco_max = *((uint32*)(&(rom[offset + 67])));
182 		uint32 fvco_min = *((uint32*)(&(rom[offset + 71])));
183 
184 		LOG(8,("INFO: PLL VCO range is %dkHz - %dkHz\n", fvco_min, fvco_max));
185 
186 		/* modify presets to reflect card capability */
187 		si->ps.min_system_vco = fvco_min / 1000;
188 		si->ps.max_system_vco = fvco_max / 1000;
189 		//fixme: enable and modify PLL code...
190 		//si->ps.min_pixel_vco = fvco_min / 1000;
191 		//si->ps.max_pixel_vco = fvco_max / 1000;
192 		//si->ps.min_video_vco = fvco_min / 1000;
193 		//si->ps.max_video_vco = fvco_max / 1000;
194 	}
195 
196 	//fixme: add 'parsing scripts while not actually executing' as warmstart method,
197 	//       instead of not parsing at all: this will update the driver's speeds
198 	//       as below, while logging the scripts as well (for our learning pleasure :)
199 
200 	/* pins 5.16 and higher is more extensive, and works differently from before */
201 	if (((rom[offset + 5]) == 5) && ((rom[offset + 6]) >= 0x10))
202 	{
203 		/* pins 5.16 and up have a more extensive command list table, and have more
204 		 * commands to choose from as well. */
205 		PinsTables tabs;
206 		tabs.InitScriptTablePtr = rom[offset + 75] + (rom[offset + 76] * 256);
207 		tabs.MacroIndexTablePtr = rom[offset + 77] + (rom[offset + 78] * 256);
208 		tabs.MacroTablePtr = rom[offset + 79] + (rom[offset + 80] * 256);
209 		tabs.ConditionTablePtr = rom[offset + 81] + (rom[offset + 82] * 256);
210 		tabs.IOConditionTablePtr = rom[offset + 83] + (rom[offset + 84] * 256);
211 		tabs.IOFlagConditionTablePtr = rom[offset + 85] + (rom[offset + 86] * 256);
212 		tabs.InitFunctionTablePtr = rom[offset + 87] + (rom[offset + 88] * 256);
213 
214 		LOG(8,("INFO: PINS 5.16 and later cmdlist pointers:\n"));
215 		LOG(8,("INFO: InitScriptTablePtr: $%04x\n", tabs.InitScriptTablePtr));
216 		LOG(8,("INFO: MacroIndexTablePtr: $%04x\n", tabs.MacroIndexTablePtr));
217 		LOG(8,("INFO: MacroTablePtr: $%04x\n", tabs.MacroTablePtr));
218 		LOG(8,("INFO: ConditionTablePtr: $%04x\n", tabs.ConditionTablePtr));
219 		LOG(8,("INFO: IOConditionTablePtr: $%04x\n", tabs.IOConditionTablePtr));
220 		LOG(8,("INFO: IOFlagConditionTablePtr: $%04x\n", tabs.IOFlagConditionTablePtr));
221 		LOG(8,("INFO: InitFunctionTablePtr: $%04x\n", tabs.InitFunctionTablePtr));
222 
223 		return coldstart_card_516_up(rom, tabs, ram_tab);
224 	}
225 	else
226 	{
227 		/* pre 'pins 5.16' still uses the 'old' method in which the command list
228 		 * table always has two entries. */
229 		return coldstart_card(rom, init1, init2, init_size, ram_tab);
230 	}
231 }
232 
233 static status_t coldstart_card(uint8* rom, uint16 init1, uint16 init2, uint16 init_size, uint16 ram_tab)
234 {
235 	status_t result = B_OK;
236 	int16 size = init_size;
237 
238 	LOG(8,("INFO: now executing coldstart...\n"));
239 
240 	/* select colormode CRTC registers base adresses */
241 	ENG_REG8(RG8_MISCW) = 0xcb;
242 
243 	/* unknown.. */
244 	ENG_REG8(RG8_VSE2) = 0x01;
245 
246 	/* enable access to primary head */
247 	set_crtc_owner(0);
248 	/* unlock head's registers for R/W access */
249 	CRTCW(LOCK, 0x57);
250 	CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f));
251 	/* disable RMA as it's not used */
252 	/* (RMA is the cmd register for the 32bit port in the GPU to access 32bit registers
253 	 *  and framebuffer via legacy ISA I/O space.) */
254 	CRTCW(RMA, 0x00);
255 
256 	if (si->ps.secondary_head)
257 	{
258 		/* enable access to secondary head */
259 		set_crtc_owner(1);
260 		/* unlock head's registers for R/W access */
261 		CRTC2W(LOCK, 0x57);
262 		CRTC2W(VSYNCE ,(CRTCR(VSYNCE) & 0x7f));
263 	}
264 
265 	/* turn off both displays and the hardcursors (also disables transfers) */
266 	eng_crtc_dpms(false, false, false);
267 	eng_crtc_cursor_hide();
268 	if (si->ps.secondary_head)
269 	{
270 		eng_crtc2_dpms(false, false, false);
271 		eng_crtc2_cursor_hide();
272 	}
273 
274 	/* execute BIOS coldstart script(s) */
275 	if (init1 || init2)
276 	{
277 		if (init1)
278 			if (exec_type1_script(rom, init1, &size, ram_tab) != B_OK) result = B_ERROR;
279 		if (init2 && (result == B_OK))
280 			if (exec_type1_script(rom, init2, &size, ram_tab) != B_OK) result = B_ERROR;
281 
282 		/* now enable ROM shadow or the card will remain shut-off! */
283 		CFGW(ROMSHADOW, (CFGR(ROMSHADOW) |= 0x00000001));
284 
285 		//temporary: should be called from setmode probably..
286 		eng_crtc_setup_fifo();
287 	}
288 	else
289 	{
290 		result = B_ERROR;
291 	}
292 
293 	if (result != B_OK)
294 		LOG(8,("INFO: coldstart failed.\n"));
295 	else
296 		LOG(8,("INFO: coldstart execution completed OK.\n"));
297 
298 	return result;
299 }
300 
301 static status_t coldstart_card_516_up(uint8* rom, PinsTables tabs, uint16 ram_tab)
302 {
303 	status_t result = B_OK;
304 	uint16 adress;
305 	uint32 fb_mrs1 = 0;
306 	uint32 fb_mrs2 = 0;
307 
308 	LOG(8,("INFO: now executing coldstart...\n"));
309 
310 	/* get some strapinfo(?) for NV28 framebuffer access */
311 	//fixme?: works on at least one NV28... how about other cards?
312 	if (si->ps.card_type == NV28)
313 	{
314 		fb_mrs2 = ENG_RG32(RG32_FB_MRS2);
315 		fb_mrs1 = ENG_RG32(RG32_FB_MRS1);
316 	}
317 
318 	/* select colormode CRTC registers base adresses */
319 	ENG_REG8(RG8_MISCW) = 0xcb;
320 
321 	/* unknown.. */
322 	ENG_REG8(RG8_VSE2) = 0x01;
323 
324 	/* enable access to primary head */
325 	set_crtc_owner(0);
326 	/* unlock head's registers for R/W access */
327 	CRTCW(LOCK, 0x57);
328 	CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f));
329 	/* disable RMA as it's not used */
330 	/* (RMA is the cmd register for the 32bit port in the GPU to access 32bit registers
331 	 *  and framebuffer via legacy ISA I/O space.) */
332 	CRTCW(RMA, 0x00);
333 
334 	if (si->ps.secondary_head)
335 	{
336 		/* enable access to secondary head */
337 		set_crtc_owner(1);
338 		/* unlock head's registers for R/W access */
339 		CRTC2W(LOCK, 0x57);
340 		CRTC2W(VSYNCE ,(CRTCR(VSYNCE) & 0x7f));
341 	}
342 
343 	/* turn off both displays and the hardcursors (also disables transfers) */
344 	eng_crtc_dpms(false, false, false);
345 	eng_crtc_cursor_hide();
346 	if (si->ps.secondary_head)
347 	{
348 		eng_crtc2_dpms(false, false, false);
349 		eng_crtc2_cursor_hide();
350 	}
351 
352 	/* execute all BIOS coldstart script(s) */
353 	if (tabs.InitScriptTablePtr)
354 	{
355 		/* size is nolonger used, keeping it anyway for testing purposes :) */
356 		int16 size = 32767;
357 		uint16 index = tabs.InitScriptTablePtr;
358 
359 		adress = *((uint16*)(&(rom[index])));
360 		if (!adress)
361 		{
362 			LOG(8,("INFO: no cmdlist found!\n"));
363 			result = B_ERROR;
364 		}
365 
366 		while (adress && (result == B_OK))
367 		{
368 			result = exec_type2_script(rom, adress, &size, tabs, ram_tab);
369 			/* next command script, please */
370 			index += 2;
371 			adress = *((uint16*)(&(rom[index])));
372 		}
373 
374 		/* do some NV28 specific extra stuff */
375 		//fixme: NV28 only??
376 		if (si->ps.card_type == NV28)
377 		{
378 			/* setup PTIMER */
379 			ACCW(PT_NUMERATOR, (si->ps.std_engine_clock * 20));
380 			ACCW(PT_DENOMINATR, 0x00000271);
381 
382 			/* get NV28 RAM access up and running */
383 			//fixme?: works on at least one NV28... how about other cards?
384 			ENG_RG32(RG32_FB_MRS2) = fb_mrs2;
385 			ENG_RG32(RG32_FB_MRS1) = fb_mrs1;
386 		}
387 
388 		/* now enable ROM shadow or the card will remain shut-off! */
389 		CFGW(ROMSHADOW, (CFGR(ROMSHADOW) |= 0x00000001));
390 
391 		//temporary: should be called from setmode probably..
392 		eng_crtc_setup_fifo();
393 	}
394 	else
395 	{
396 		result = B_ERROR;
397 	}
398 
399 	if (result != B_OK)
400 		LOG(8,("INFO: coldstart failed.\n"));
401 	else
402 		LOG(8,("INFO: coldstart execution completed OK.\n"));
403 
404 	return result;
405 }
406 
407 /* This routine is complete, and is used for pre-NV10 cards. It's tested on a Elsa
408  * Erazor III with TNT2 (NV05) and on a no-name TNT2-M64. Both cards coldstart
409  * perfectly. */
410 static status_t exec_type1_script(uint8* rom, uint16 adress, int16* size, uint16 ram_tab)
411 {
412 	status_t result = B_OK;
413 	bool end = false;
414 	bool exec = true;
415 	uint8 index, byte;
416 	uint32 reg, data, data2, and_out, or_in;
417 
418 	LOG(8,("\nINFO: executing type1 script at adress $%04x...\n", adress));
419 	LOG(8,("INFO: ---Executing following command(s):\n"));
420 
421 	while (!end)
422 	{
423 		LOG(8,("INFO: $%04x ($%02x); ", adress, rom[adress]));
424 
425 		switch (rom[adress])
426 		{
427 		case 0x59:
428 			*size -= 7;
429 			if (*size < 0)
430 			{
431 				LOG(8,("script size error, aborting!\n\n"));
432 				end = true;
433 				result = B_ERROR;
434 				break;
435 			}
436 
437 			/* execute */
438 			adress += 1;
439 			reg = *((uint32*)(&(rom[adress])));
440 			adress += 4;
441 			data = *((uint16*)(&(rom[adress])));
442 			adress += 2;
443 			data2 = *((uint16*)(&(rom[data])));
444 			LOG(8,("cmd 'calculate indirect and set PLL 32bit reg $%08x for %.3fMHz'\n",
445 				reg, ((float)data2)));
446 			if (exec)
447 			{
448 				float calced_clk;
449 				uint8 m, n, p;
450 				eng_dac_sys_pll_find(((float)data2), &calced_clk, &m, &n, &p, 0);
451 				ENG_RG32(reg) = ((p << 16) | (n << 8) | m);
452 			}
453 			log_pll(reg, data2);
454 			break;
455 		case 0x5a:
456 			*size -= 7;
457 			if (*size < 0)
458 			{
459 				LOG(8,("script size error, aborting!\n\n"));
460 				end = true;
461 				result = B_ERROR;
462 				break;
463 			}
464 
465 			/* execute */
466 			adress += 1;
467 			reg = *((uint32*)(&(rom[adress])));
468 			adress += 4;
469 			data = *((uint16*)(&(rom[adress])));
470 			adress += 2;
471 			data2 = *((uint32*)(&(rom[data])));
472 			LOG(8,("cmd 'WR indirect 32bit reg' $%08x = $%08x\n", reg, data2));
473 			if (exec) ENG_RG32(reg) = data2;
474 			break;
475 		case 0x63:
476 			*size -= 1;
477 			if (*size < 0)
478 			{
479 				LOG(8,("script size error, aborting!\n\n"));
480 				end = true;
481 				result = B_ERROR;
482 				break;
483 			}
484 
485 			/* execute */
486 			adress += 1;
487 			LOG(8,("cmd 'setup RAM config' (always done)\n"));
488 			/* always done */
489 			setup_ram_config(rom, ram_tab);
490 			break;
491 		case 0x65:
492 			*size -= 13;
493 			if (*size < 0)
494 			{
495 				LOG(8,("script size error, aborting!\n\n"));
496 				end = true;
497 				result = B_ERROR;
498 				break;
499 			}
500 
501 			/* execute */
502 			adress += 1;
503 			reg = *((uint32*)(&(rom[adress])));
504 			adress += 4;
505 			data = *((uint32*)(&(rom[adress])));
506 			adress += 4;
507 			data2 = *((uint32*)(&(rom[adress])));
508 			adress += 4;
509 			LOG(8,("cmd 'WR 32bit reg $%08x = $%08x, then = $%08x' (always done)\n",
510 				reg, data, data2));
511 			/* always done */
512 			ENG_RG32(reg) = data;
513 			ENG_RG32(reg) = data2;
514 			CFGW(ROMSHADOW, (CFGR(ROMSHADOW) & 0xfffffffe));
515 			break;
516 		case 0x69:
517 			*size -= 5;
518 			if (*size < 0)
519 			{
520 				LOG(8,("script size error, aborting!\n\n"));
521 				end = true;
522 				result = B_ERROR;
523 				break;
524 			}
525 
526 			/* execute */
527 			adress += 1;
528 			reg = *((uint16*)(&(rom[adress])));
529 			adress += 2;
530 			and_out = *((uint8*)(&(rom[adress])));
531 			adress += 1;
532 			or_in = *((uint8*)(&(rom[adress])));
533 			adress += 1;
534 			LOG(8,("cmd 'RD 8bit ISA reg $%04x, AND-out = $%02x, OR-in = $%02x, WR-bk'\n",
535 				reg, and_out, or_in));
536 			if (exec)
537 			{
538 				translate_ISA_PCI(&reg);
539 				byte = ENG_REG8(reg);
540 				byte &= (uint8)and_out;
541 				byte |= (uint8)or_in;
542 				ENG_REG8(reg) = byte;
543 			}
544 			break;
545 		case 0x6d:
546 			*size -= 3;
547 			if (*size < 0)
548 			{
549 				LOG(8,("script size error, aborting!\n\n"));
550 				end = true;
551 				result = B_ERROR;
552 				break;
553 			}
554 
555 			/* execute */
556 			adress += 1;
557 			data = ENG_RG32(RG32_NV4STRAPINFO);
558 			and_out = *((uint8*)(&(rom[adress])));
559 			adress += 1;
560 			byte = *((uint8*)(&(rom[adress])));
561 			adress += 1;
562 			data &= (uint32)and_out;
563 			LOG(8,("cmd 'CHK bits AND-out $%02x RAMCFG for $%02x'\n",
564 				and_out, byte));
565 			if (((uint8)data) != byte)
566 			{
567 				LOG(8,("INFO: ---No match: not executing following command(s):\n"));
568 				exec = false;
569 			}
570 			else
571 			{
572 				LOG(8,("INFO: ---Match, so this cmd has no effect.\n"));
573 			}
574 			break;
575 		case 0x6e:
576 			*size -= 13;
577 			if (*size < 0)
578 			{
579 				LOG(8,("script size error, aborting!\n\n"));
580 				end = true;
581 				result = B_ERROR;
582 				break;
583 			}
584 
585 			/* execute */
586 			adress += 1;
587 			reg = *((uint32*)(&(rom[adress])));
588 			adress += 4;
589 			and_out = *((uint32*)(&(rom[adress])));
590 			adress += 4;
591 			or_in = *((uint32*)(&(rom[adress])));
592 			adress += 4;
593 			LOG(8,("cmd 'RD 32bit reg $%08x, AND-out = $%08x, OR-in = $%08x, WR-bk'\n",
594 				reg, and_out, or_in));
595 			if (exec)
596 			{
597 				data = ENG_RG32(reg);
598 				data &= and_out;
599 				data |= or_in;
600 				ENG_RG32(reg) = data;
601 			}
602 			break;
603 		case 0x71:
604 			LOG(8,("cmd 'END', execution completed.\n\n"));
605 			end = true;
606 
607 			*size -= 1;
608 			if (*size < 0)
609 			{
610 				LOG(8,("script size error!\n\n"));
611 				result = B_ERROR;
612 			}
613 			break;
614 		case 0x72:
615 			*size -= 1;
616 			if (*size < 0)
617 			{
618 				LOG(8,("script size error!\n\n"));
619 				result = B_ERROR;
620 			}
621 
622 			/* execute */
623 			adress += 1;
624 			LOG(8,("cmd 'PGM commands'\n"));
625 			LOG(8,("INFO: ---Executing following command(s):\n"));
626 			exec = true;
627 			break;
628 		case 0x73:
629 			*size -= 9;
630 			if (*size < 0)
631 			{
632 				LOG(8,("script size error, aborting!\n\n"));
633 				end = true;
634 				result = B_ERROR;
635 				break;
636 			}
637 
638 			/* execute */
639 			adress += 1;
640 			data = ENG_RG32(RG32_NVSTRAPINFO2);
641 			and_out = *((uint32*)(&(rom[adress])));
642 			adress += 4;
643 			data2 = *((uint32*)(&(rom[adress])));
644 			adress += 4;
645 			data &= and_out;
646 			LOG(8,("cmd 'CHK bits AND-out $%08x STRAPCFG2 for $%08x'\n",
647 				and_out, data2));
648 			if (data != data2)
649 			{
650 				LOG(8,("INFO: ---No match: not executing following command(s):\n"));
651 				exec = false;
652 			}
653 			else
654 			{
655 				LOG(8,("INFO: ---Match, so this cmd has no effect.\n"));
656 			}
657 			break;
658 		case 0x74:
659 			*size -= 3;
660 			if (*size < 0)
661 			{
662 				LOG(8,("script size error, aborting!\n\n"));
663 				end = true;
664 				result = B_ERROR;
665 				break;
666 			}
667 
668 			/* execute */
669 			adress += 1;
670 			data = *((uint16*)(&(rom[adress])));
671 			adress += 2;
672 			LOG(8,("cmd 'SNOOZE for %d ($%04x) microSeconds' (always done)\n", data, data));
673 			/* always done */
674 			snooze(data);
675 			break;
676 		case 0x77:
677 			*size -= 7;
678 			if (*size < 0)
679 			{
680 				LOG(8,("script size error, aborting!\n\n"));
681 				end = true;
682 				result = B_ERROR;
683 				break;
684 			}
685 
686 			/* execute */
687 			adress += 1;
688 			reg = *((uint32*)(&(rom[adress])));
689 			adress += 4;
690 			data = *((uint16*)(&(rom[adress])));
691 			adress += 2;
692 			LOG(8,("cmd 'WR 32bit reg' $%08x = $%08x (b31-16 = '0', b15-0 = data)\n",
693 				reg, data));
694 			if (exec) ENG_RG32(reg) = data;
695 			break;
696 		case 0x78:
697 			*size -= 6;
698 			if (*size < 0)
699 			{
700 				LOG(8,("script size error, aborting!\n\n"));
701 				end = true;
702 				result = B_ERROR;
703 				break;
704 			}
705 
706 			/* execute */
707 			adress += 1;
708 			reg = *((uint16*)(&(rom[adress])));
709 			adress += 2;
710 			index = *((uint8*)(&(rom[adress])));
711 			adress += 1;
712 			and_out = *((uint8*)(&(rom[adress])));
713 			adress += 1;
714 			or_in = *((uint8*)(&(rom[adress])));
715 			adress += 1;
716 			LOG(8,("cmd 'RD idx ISA reg $%02x via $%04x, AND-out = $%02x, OR-in = $%02x, WR-bk'\n",
717 				index, reg, and_out, or_in));
718 			if (exec)
719 			{
720 				translate_ISA_PCI(&reg);
721 				ENG_REG8(reg) = index;
722 				byte = ENG_REG8(reg + 1);
723 				byte &= (uint8)and_out;
724 				byte |= (uint8)or_in;
725 				ENG_REG8(reg + 1) = byte;
726 			}
727 			break;
728 		case 0x79:
729 			*size -= 7;
730 			if (*size < 0)
731 			{
732 				LOG(8,("script size error, aborting!\n\n"));
733 				end = true;
734 				result = B_ERROR;
735 				break;
736 			}
737 
738 			/* execute */
739 			adress += 1;
740 			reg = *((uint32*)(&(rom[adress])));
741 			adress += 4;
742 			data = *((uint16*)(&(rom[adress])));
743 			adress += 2;
744 			LOG(8,("cmd 'calculate and set PLL 32bit reg $%08x for %.3fMHz'\n", reg, (data / 100.0)));
745 			if (exec)
746 			{
747 				float calced_clk;
748 				uint8 m, n, p;
749 				eng_dac_sys_pll_find((data / 100.0), &calced_clk, &m, &n, &p, 0);
750 				ENG_RG32(reg) = ((p << 16) | (n << 8) | m);
751 			}
752 			log_pll(reg, (data / 100));
753 			break;
754 		case 0x7a:
755 			*size -= 9;
756 			if (*size < 0)
757 			{
758 				LOG(8,("script size error, aborting!\n\n"));
759 				end = true;
760 				result = B_ERROR;
761 				break;
762 			}
763 
764 			/* execute */
765 			adress += 1;
766 			reg = *((uint32*)(&(rom[adress])));
767 			adress += 4;
768 			data = *((uint32*)(&(rom[adress])));
769 			adress += 4;
770 			LOG(8,("cmd 'WR 32bit reg' $%08x = $%08x\n", reg, data));
771 			if (exec) ENG_RG32(reg) = data;
772 			break;
773 		default:
774 			LOG(8,("unknown cmd, aborting!\n\n"));
775 			end = true;
776 			result = B_ERROR;
777 			break;
778 		}
779 	}
780 
781 	return result;
782 }
783 
784 static void log_pll(uint32 reg, uint32 freq)
785 {
786 	if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36))
787 		LOG(8,("INFO: ---WARNING: check/update PLL programming script code!!!\n"));
788 	switch (reg)
789 	{
790 	case RG32_MEMPLL:
791 		LOG(8,("INFO: ---Memory PLL accessed.\n"));
792 		/* update the card's specs */
793 		si->ps.std_memory_clock = freq;
794 		break;
795 	case RG32_COREPLL:
796 		LOG(8,("INFO: ---Core PLL accessed.\n"));
797 		/* update the card's specs */
798 		si->ps.std_engine_clock = freq;
799 		break;
800 	case ENDAC_PIXPLLC:
801 		LOG(8,("INFO: ---DAC1 PLL accessed.\n"));
802 		break;
803 	case ENDAC2_PIXPLLC:
804 		LOG(8,("INFO: ---DAC2 PLL accessed.\n"));
805 		break;
806 	/* unexpected cases, here for learning goals... */
807 	case RG32_MEMPLL2:
808 		LOG(8,("INFO: ---NV31/NV36 extension to memory PLL accessed only!\n"));
809 		break;
810 	case RG32_COREPLL2:
811 		LOG(8,("INFO: ---NV31/NV36 extension to core PLL accessed only!\n"));
812 		break;
813 	case ENDAC_PIXPLLC2:
814 		LOG(8,("INFO: ---NV31/NV36 extension to DAC1 PLL accessed only!\n"));
815 		break;
816 	case ENDAC2_PIXPLLC2:
817 		LOG(8,("INFO: ---NV31/NV36 extension to DAC2 PLL accessed only!\n"));
818 		break;
819 	default:
820 		LOG(8,("INFO: ---Unknown PLL accessed!\n"));
821 		break;
822 	}
823 }
824 
825 static void	setup_ram_config(uint8* rom, uint16 ram_tab)
826 {
827 	uint32 ram_cfg, data;
828 	uint8 cnt;
829 
830 	/* set MRS = 256 */
831 	ENG_RG32(RG32_PFB_DEBUG_0) &= 0xffffffef;
832 	/* read RAM config hardware(?) strap */
833 	ram_cfg = ((ENG_RG32(RG32_NVSTRAPINFO2) >> 2) & 0x0000000f);
834 	LOG(8,("INFO: ---RAM config strap is $%01x\n", ram_cfg));
835 	/* use it as a pointer in a BIOS table for prerecorded RAM configurations */
836 	ram_cfg = *((uint16*)(&(rom[(ram_tab + (ram_cfg * 2))])));
837 	/* log info */
838 	switch (ram_cfg & 0x00000003)
839 	{
840 	case 0:
841 		LOG(8,("INFO: ---32Mb RAM should be connected\n"));
842 		break;
843 	case 1:
844 		LOG(8,("INFO: ---4Mb RAM should be connected\n"));
845 		break;
846 	case 2:
847 		LOG(8,("INFO: ---8Mb RAM should be connected\n"));
848 		break;
849 	case 3:
850 		LOG(8,("INFO: ---16Mb RAM should be connected\n"));
851 		break;
852 	}
853 	if (ram_cfg & 0x00000004)
854 		LOG(8,("INFO: ---RAM should be 128bits wide\n"));
855 	else
856 		LOG(8,("INFO: ---RAM should be 64bits wide\n"));
857 	switch ((ram_cfg & 0x00000038) >> 3)
858 	{
859 	case 0:
860 		LOG(8,("INFO: ---RAM type: 8Mbit SGRAM\n"));
861 		break;
862 	case 1:
863 		LOG(8,("INFO: ---RAM type: 16Mbit SGRAM\n"));
864 		break;
865 	case 2:
866 		LOG(8,("INFO: ---RAM type: 4 banks of 16Mbit SGRAM\n"));
867 		break;
868 	case 3:
869 		LOG(8,("INFO: ---RAM type: 16Mbit SDRAM\n"));
870 		break;
871 	case 4:
872 		LOG(8,("INFO: ---RAM type: 64Mbit SDRAM\n"));
873 		break;
874 	case 5:
875 		LOG(8,("INFO: ---RAM type: 64Mbit x16 SDRAM\n"));
876 		break;
877 	}
878 	/* set RAM amount, width and type */
879 	data = (ENG_RG32(RG32_NV4STRAPINFO) & 0xffffffc0);
880 	ENG_RG32(RG32_NV4STRAPINFO) = (data | (ram_cfg & 0x0000003f));
881 	/* setup write to read delay (?) */
882 	data = (ENG_RG32(RG32_PFB_CONFIG_1) & 0xff8ffffe);
883 	data |= ((ram_cfg & 0x00000700) << 12);
884 	/* force update via b0 = 0... */
885 	ENG_RG32(RG32_PFB_CONFIG_1) = data;
886 	/* ... followed by b0 = 1(?) */
887 	ENG_RG32(RG32_PFB_CONFIG_1) = (data | 0x00000001);
888 
889 	/* do RAM width test to confirm RAM width set to be correct */
890 	/* write testpattern to first 128 bits of graphics memory... */
891 	data = 0x4e563541;
892 	for (cnt = 0; cnt < 4; cnt++)
893 		((uint32 *)si->framebuffer)[cnt] = data;
894 	/* ... if second 64 bits does not contain the testpattern we are apparantly
895 	 * set to 128bits width while we should be set to 64bits width, so correct. */
896 	if (((uint32 *)si->framebuffer)[3] != data)
897 	{
898 		LOG(8,("INFO: ---RAM width tested: width is 64bits, correcting settings.\n"));
899 		ENG_RG32(RG32_NV4STRAPINFO) &= ~0x00000004;
900 	}
901 	else
902 	{
903 		LOG(8,("INFO: ---RAM width tested: access is OK.\n"));
904 	}
905 
906 	//fixme?: do RAM size test
907 }
908 
909 /* this routine is used for NV10 and later */
910 static status_t exec_type2_script(uint8* rom, uint16 adress, int16* size, PinsTables tabs, uint16 ram_tab)
911 {
912 	bool exec = true;
913 
914 	LOG(8,("\nINFO: executing type2 script at adress $%04x...\n", adress));
915 	LOG(8,("INFO: ---Executing following command(s):\n"));
916 
917 	return exec_type2_script_mode(rom, &adress, size, tabs, ram_tab, &exec);
918 }
919 
920 /* this routine is used for NV10 and later. It's tested on a GeForce2 MX400 (NV11),
921  * GeForce4 MX440 (NV18), GeForce4 Ti4200 (NV28) and a GeForceFX 5200 (NV34).
922  * These cards coldstart perfectly. */
923 static status_t exec_type2_script_mode(uint8* rom, uint16* adress, int16* size, PinsTables tabs, uint16 ram_tab, bool* exec)
924 {
925 	status_t result = B_OK;
926 	bool end = false;
927 	uint8 index, byte, byte2, shift;
928 	uint32 reg, reg2, data, data2, and_out, and_out2, or_in, or_in2, safe32, offset32, size32;
929 
930 	while (!end)
931 	{
932 		LOG(8,("INFO: $%04x ($%02x); ", *adress, rom[*adress]));
933 
934 		/* all commands are here (verified NV11 and NV28) */
935 		switch (rom[*adress])
936 		{
937 		case 0x31: /* new */
938 			*size -= (15 + ((*((uint8*)(&(rom[(*adress + 10)])))) << 2));
939 			if (*size < 0)
940 			{
941 				LOG(8,("script size error, aborting!\n\n"));
942 				end = true;
943 				result = B_ERROR;
944 				break;
945 			}
946 
947 			/* execute */
948 			*adress += 1;
949 			reg = *((uint32*)(&(rom[*adress])));
950 			*adress += 4;
951 			and_out = *((uint32*)(&(rom[*adress])));
952 			*adress += 4;
953 			shift = *((uint8*)(&(rom[*adress])));
954 			*adress += 1;
955 			size32 = ((*((uint8*)(&(rom[*adress])))) << 2);
956 			*adress += 1;
957 			reg2 = *((uint32*)(&(rom[*adress])));
958 			*adress += 4;
959 			LOG(8,("cmd 'RD 32bit reg $%08x, AND-out = $%08x, shift-right = $%02x,\n",
960 				reg, and_out, shift));
961 			LOG(8,("INFO: (cont.) RD 32bit data from subtable with size $%04x, at offset (result << 2),\n",
962 				size32));
963 			LOG(8,("INFO: (cont.) then WR result data to 32bit reg $%08x'\n", reg2));
964 			if (*exec && reg2)
965 			{
966 				data = ENG_RG32(reg);
967 				data &= and_out;
968 				data >>= shift;
969 				data2 = *((uint32*)(&(rom[(*adress + (data << 2))])));
970 				ENG_RG32(reg2) = data2;
971 			}
972 			*adress += size32;
973 			break;
974 		case 0x32: /* new */
975 			*size -= (11 + ((*((uint8*)(&(rom[(*adress + 6)])))) << 2));
976 			if (*size < 0)
977 			{
978 				LOG(8,("script size error, aborting!\n\n"));
979 				end = true;
980 				result = B_ERROR;
981 				break;
982 			}
983 
984 			/* execute */
985 			*adress += 1;
986 			reg = *((uint16*)(&(rom[*adress])));
987 			*adress += 2;
988 			index = *((uint8*)(&(rom[*adress])));
989 			*adress += 1;
990 			and_out = *((uint8*)(&(rom[*adress])));
991 			*adress += 1;
992 			byte2 = *((uint8*)(&(rom[*adress])));
993 			*adress += 1;
994 			size32 = ((*((uint8*)(&(rom[*adress])))) << 2);
995 			*adress += 1;
996 			reg2 = *((uint32*)(&(rom[*adress])));
997 			*adress += 4;
998 			LOG(8,("cmd 'RD idx ISA reg $%02x via $%04x, AND-out = $%02x, shift-right = $%02x,\n",
999 				index, reg, and_out, byte2));
1000 			LOG(8,("INFO: (cont.) RD 32bit data from subtable with size $%04x, at offset (result << 2),\n",
1001 				size32));
1002 			LOG(8,("INFO: (cont.) then WR result data to 32bit reg $%08x'\n", reg2));
1003 			if (*exec && reg2)
1004 			{
1005 				translate_ISA_PCI(&reg);
1006 				ENG_REG8(reg) = index;
1007 				byte = ENG_REG8(reg + 1);
1008 				byte &= (uint8)and_out;
1009 				byte >>= byte2;
1010 				offset32 = (byte << 2);
1011 				data = *((uint32*)(&(rom[(*adress + offset32)])));
1012 				ENG_RG32(reg2) = data;
1013 			}
1014 			*adress += size32;
1015 			break;
1016 		case 0x33: /* new */
1017 			*size -= 2;
1018 			if (*size < 0)
1019 			{
1020 				LOG(8,("script size error, aborting!\n\n"));
1021 				end = true;
1022 				result = B_ERROR;
1023 				break;
1024 			}
1025 
1026 			/* execute */
1027 			*adress += 1;
1028 			size32 = *((uint8*)(&(rom[*adress])));
1029 			*adress += 1;
1030 			/* executed 1-256 times */
1031 			if (!size32) size32 = 256;
1032 			/* remember where to start each time */
1033 			safe32 = *adress;
1034 			LOG(8,("cmd 'execute following part of this script $%03x times' (always done)\n", size32));
1035 			for (offset32 = 0; offset32 < size32; offset32++)
1036 			{
1037 				LOG(8,("\nINFO: (#$%02x) executing part of type2 script at adress $%04x...\n",
1038 					offset32, *adress));
1039 				LOG(8,("INFO: ---Not touching 'execution' mode at this time:\n"));
1040 				*adress = safe32;
1041 				result = exec_type2_script_mode(rom, adress, size, tabs, ram_tab, exec);
1042 			}
1043 			LOG(8,("INFO: ---Continuing script:\n"));
1044 			break;
1045 		case 0x34: /* new */
1046 			*size -= (12 + ((*((uint8*)(&(rom[(*adress + 7)])))) << 1));
1047 			if (*size < 0)
1048 			{
1049 				LOG(8,("script size error, aborting!\n\n"));
1050 				end = true;
1051 				result = B_ERROR;
1052 				break;
1053 			}
1054 
1055 			/* execute */
1056 			*adress += 1;
1057 			reg = *((uint16*)(&(rom[*adress])));
1058 			*adress += 2;
1059 			index = *((uint8*)(&(rom[*adress])));
1060 			*adress += 1;
1061 			and_out = *((uint8*)(&(rom[*adress])));
1062 			*adress += 1;
1063 			shift = *((uint8*)(&(rom[*adress])));
1064 			*adress += 1;
1065 			offset32 = *((uint8*)(&(rom[*adress])));
1066 			*adress += 1;
1067 			size32 = ((*((uint8*)(&(rom[*adress])))) << 1);
1068 			*adress += 1;
1069 			reg2 = *((uint32*)(&(rom[*adress])));
1070 			*adress += 4;
1071 			LOG(8,("cmd 'RD idx ISA reg $%02x via $%04x, AND-out = $%02x, shift-right = $%02x,\n",
1072 				index, reg, and_out, shift));
1073 			LOG(8,("INFO: (cont.) RD 16bit PLL frequency to pgm from subtable with size $%04x, at offset (result << 1),\n",
1074 				size32));
1075 			LOG(8,("INFO: (cont.) RD table-index ($%02x) for cmd $39'\n",
1076 				offset32));
1077 			translate_ISA_PCI(&reg);
1078 			ENG_REG8(reg) = index;
1079 			byte = ENG_REG8(reg + 1);
1080 			byte &= (uint8)and_out;
1081 			data = (byte >> shift);
1082 			data <<= 1;
1083 			data2 = *((uint16*)(&(rom[(*adress + data)])));
1084 			if (offset32 < 0x80)
1085 			{
1086 				bool double_f = true;
1087 				LOG(8,("INFO: Do subcmd ($39); "));
1088 				exec_cmd_39_type2(rom, offset32, tabs, &double_f);
1089 				LOG(8,("INFO: (cont. cmd $34) Doubling PLL frequency to be set for cmd $34.\n"));
1090 				if (double_f) data2 <<= 1;
1091 				LOG(8,("INFO: ---Reverting to pre-subcmd ($39) 'execution' mode.\n"));
1092 			}
1093 			else
1094 			{
1095 				LOG(8,("INFO: table index is negative, not executing subcmd ($39).\n"));
1096 			}
1097 			LOG(8,("INFO: (cont.) 'calc and set PLL 32bit reg $%08x for %.3fMHz'\n",
1098 				reg2, (data2 / 100.0)));
1099 			if (*exec && reg2)
1100 			{
1101 				float calced_clk;
1102 				uint8 m, n, p;
1103 				eng_dac_sys_pll_find((data2 / 100.0), &calced_clk, &m, &n, &p, 0);
1104 				/* programming the PLL needs to be done in steps! (confirmed NV28) */
1105 				data = ENG_RG32(reg2);
1106 				ENG_RG32(reg2) = ((data & 0xffff0000) | (n << 8) | m);
1107 				data = ENG_RG32(reg2);
1108 				ENG_RG32(reg2) = ((p << 16) | (n << 8) | m);
1109 //fixme?
1110 				/* program 2nd set N and M scalers if they exist (b31=1 enables them) */
1111 //				if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36))
1112 //					DACW(PIXPLLC2, 0x80000401);
1113 			}
1114 			log_pll(reg2, (data2 / 100));
1115 			*adress += size32;
1116 			break;
1117 		case 0x35: /* new */
1118 			*size -= 2;
1119 			if (*size < 0)
1120 			{
1121 				LOG(8,("script size error, aborting!\n\n"));
1122 				end = true;
1123 				result = B_ERROR;
1124 				break;
1125 			}
1126 
1127 			/* execute */
1128 			*adress += 1;
1129 			byte = *((uint8*)(&(rom[*adress])));
1130  			*adress += 1;
1131 			offset32 = (byte << 1);
1132 			offset32 += tabs.InitFunctionTablePtr;
1133 			LOG(8,("cmd 'execute fixed VGA BIOS routine #$%02x at adress $%04x'\n",
1134 				byte, offset32));
1135 			/* note:
1136 			 * This command is BIOS/'pins' version specific. Confirmed a NV28 having NO
1137 			 * entries at all in InitFunctionTable!
1138 			 * (BIOS version 4.28.20.05.11; 'pins' version 5.21) */
1139 			//fixme: impl. if it turns out this cmd is used.. (didn't see that yet)
1140 			if (*exec)
1141 			{
1142 				//fixme: add BIOS/'pins' version dependancy...
1143 				switch(byte)
1144 				{
1145 				default:
1146 					LOG(8,("\n\nINFO: WARNING: function not implemented, skipping!\n\n"));
1147 					break;
1148 				}
1149 			}
1150 			break;
1151 		case 0x37: /* new */
1152 			*size -= 11;
1153 			if (*size < 0)
1154 			{
1155 				LOG(8,("script size error, aborting!\n\n"));
1156 				end = true;
1157 				result = B_ERROR;
1158 				break;
1159 			}
1160 
1161 			/* execute */
1162 			*adress += 1;
1163 			reg = *((uint32*)(&(rom[*adress])));
1164 			*adress += 4;
1165 			byte2 = *((uint8*)(&(rom[*adress])));
1166 			*adress += 1;
1167 			and_out = *((uint8*)(&(rom[*adress])));
1168 			*adress += 1;
1169 			reg2 = *((uint16*)(&(rom[*adress])));
1170 			*adress += 2;
1171 			index = *((uint8*)(&(rom[*adress])));
1172 			*adress += 1;
1173 			and_out2 = *((uint8*)(&(rom[*adress])));
1174 			*adress += 1;
1175 			LOG(8,("cmd 'RD 32bit reg $%08x, shift-right = $%02x, AND-out lsb = $%02x,\n",
1176 				reg, byte2, and_out));
1177 			LOG(8,("INFO: (cont.) RD 8bit ISA reg $%02x via $%04x, AND-out = $%02x, OR-in lsb result 32bit, WR-bk'\n",
1178 				index, reg2, and_out2));
1179 			if (*exec)
1180 			{
1181 				data = ENG_RG32(reg);
1182 				if (byte2 < 0x80)
1183 				{
1184 					data >>= byte2;
1185 				}
1186 				else
1187 				{
1188 					data <<= (0x0100 - byte2);
1189 				}
1190 				data &= and_out;
1191 				translate_ISA_PCI(&reg2);
1192 				ENG_REG8(reg2) = index;
1193 				byte = ENG_REG8(reg2 + 1);
1194 				byte &= (uint8)and_out2;
1195 				byte |= (uint8)data;
1196 				ENG_REG8(reg2 + 1) = byte;
1197 			}
1198 			break;
1199 		case 0x38: /* new */
1200 			*size -= 1;
1201 			if (*size < 0)
1202 			{
1203 				LOG(8,("script size error, aborting!\n\n"));
1204 				end = true;
1205 				result = B_ERROR;
1206 				break;
1207 			}
1208 
1209 			/* execute */
1210 			*adress += 1;
1211 			LOG(8,("cmd 'invert current mode'\n"));
1212 			*exec = !(*exec);
1213 			if (*exec)
1214 				LOG(8,("INFO: ---Executing following command(s):\n"));
1215 			else
1216 				LOG(8,("INFO: ---Not executing following command(s):\n"));
1217 			break;
1218 		case 0x39: /* new */
1219 			*size -= 2;
1220 			if (*size < 0)
1221 			{
1222 				LOG(8,("script size error, aborting!\n\n"));
1223 				end = true;
1224 				result = B_ERROR;
1225 				break;
1226 			}
1227 
1228 			/* execute */
1229 			*adress += 1;
1230 			data = *((uint8*)(&(rom[*adress])));
1231 			*adress += 1;
1232 			exec_cmd_39_type2(rom, data, tabs, exec);
1233 			break;
1234 		case 0x49: /* new */
1235 			size32 = *((uint8*)(&(rom[*adress + 17])));
1236 			if (!size32) size32 = 256;
1237 			*size -= (18 + (size32 << 1));
1238 			if (*size < 0)
1239 			{
1240 				LOG(8,("script size error, aborting!\n\n"));
1241 				end = true;
1242 				result = B_ERROR;
1243 				break;
1244 			}
1245 
1246 			/* execute */
1247 			*adress += 1;
1248 			reg = *((uint32*)(&(rom[*adress])));
1249 			*adress += 4;
1250 			reg2 = *((uint32*)(&(rom[*adress])));
1251 			*adress += 4;
1252 			and_out = *((uint32*)(&(rom[*adress])));
1253 			*adress += 4;
1254 			or_in = *((uint32*)(&(rom[*adress])));
1255 			*adress += 4;
1256 			size32 = *((uint8*)(&(rom[*adress])));
1257 			if (!size32) size32 = 256;
1258 			*adress += 1;
1259 			LOG(8,("cmd 'do following cmd structure $%03x time(s)':\n", size32));
1260 			for (offset32 = 0; offset32 < size32; offset32++)
1261 			{
1262 				or_in2 = *((uint8*)(&(rom[(*adress + (offset32 << 1))])));
1263 				data2 = *((uint8*)(&(rom[(*adress + (offset32 << 1) + 1)])));
1264 				LOG(8,("INFO (cont.) (#$%02x) cmd 'WR 32bit reg $%08x = $%08x, RD 32bit reg $%08x,\n",
1265 					offset32, reg2, data2, reg));
1266 				LOG(8,("INFO (cont.) AND-out $%08x, OR-in $%08x, OR-in $%08x, WR-bk'\n",
1267 					and_out, or_in, or_in2));
1268 			}
1269 			if (*exec)
1270 			{
1271 				for (index = 0; index < size32; index++)
1272 				{
1273 					or_in2 = *((uint8*)(&(rom[*adress])));
1274 					*adress += 1;
1275 					data2 = *((uint8*)(&(rom[*adress])));
1276 					*adress += 1;
1277 					ENG_RG32(reg2) = data2;
1278 					data = ENG_RG32(reg);
1279 					data &= and_out;
1280 					data |= or_in;
1281 					data |= or_in2;
1282 					ENG_RG32(reg) = data;
1283 				}
1284 			}
1285 			else
1286 			{
1287 				*adress += (size32 << 1);
1288 			}
1289 			break;
1290 		case 0x61: /* new */
1291 			*size -= 4;
1292 			if (*size < 0)
1293 			{
1294 				LOG(8,("script size error, aborting!\n\n"));
1295 				end = true;
1296 				result = B_ERROR;
1297 				break;
1298 			}
1299 
1300 			/* execute */
1301 			*adress += 1;
1302 			reg = *((uint16*)(&(rom[*adress])));
1303 			*adress += 2;
1304 			byte = *((uint8*)(&(rom[*adress])));
1305 			*adress += 1;
1306 			LOG(8,("cmd 'WR ISA reg $%04x = $%02x'\n", reg, byte));
1307 			if (*exec)
1308 			{
1309 				translate_ISA_PCI(&reg);
1310 				ENG_REG8(reg) = byte;
1311 			}
1312 			break;
1313 		case 0x62: /* new */
1314 			*size -= 5;
1315 			if (*size < 0)
1316 			{
1317 				LOG(8,("script size error, aborting!\n\n"));
1318 				end = true;
1319 				result = B_ERROR;
1320 				break;
1321 			}
1322 
1323 			/* execute */
1324 			*adress += 1;
1325 			reg = *((uint16*)(&(rom[*adress])));
1326 			*adress += 2;
1327 			index = *((uint8*)(&(rom[*adress])));
1328 			*adress += 1;
1329 			byte = *((uint8*)(&(rom[*adress])));
1330 			*adress += 1;
1331 			LOG(8,("cmd 'WR idx ISA reg $%02x via $%04x = $%02x'\n", index, reg, byte));
1332 			if (*exec)
1333 			{
1334 				translate_ISA_PCI(&reg);
1335 				ENG_REG16(reg) = ((((uint16)byte) << 8) | index);
1336 			}
1337 			break;
1338 		case 0x63: /* new setup compared to pre-NV10 version */
1339 			*size -= 1;
1340 			if (*size < 0)
1341 			{
1342 				LOG(8,("script size error, aborting!\n\n"));
1343 				end = true;
1344 				result = B_ERROR;
1345 				break;
1346 			}
1347 
1348 			/* execute */
1349 			*adress += 1;
1350 			LOG(8,("cmd 'setup RAM config' (always done)\n"));
1351 			/* always done */
1352 			switch (si->ps.card_type)
1353 			{
1354 			case NV28:
1355 				setup_ram_config_nv28(rom);
1356 				break;
1357 			default:
1358 				setup_ram_config_nv10_up(rom);
1359 				break;
1360 			}
1361 			break;
1362 		case 0x65: /* identical to type1 */
1363 			*size -= 13;
1364 			if (*size < 0)
1365 			{
1366 				LOG(8,("script size error, aborting!\n\n"));
1367 				end = true;
1368 				result = B_ERROR;
1369 				break;
1370 			}
1371 
1372 			/* execute */
1373 			*adress += 1;
1374 			reg = *((uint32*)(&(rom[*adress])));
1375 			*adress += 4;
1376 			data = *((uint32*)(&(rom[*adress])));
1377 			*adress += 4;
1378 			data2 = *((uint32*)(&(rom[*adress])));
1379 			*adress += 4;
1380 			LOG(8,("cmd 'WR 32bit reg $%08x = $%08x, then = $%08x' (always done)\n",
1381 				reg, data, data2));
1382 			/* always done */
1383 			ENG_RG32(reg) = data;
1384 			ENG_RG32(reg) = data2;
1385 			CFGW(ROMSHADOW, (CFGR(ROMSHADOW) & 0xfffffffe));
1386 			break;
1387 		case 0x69: /* identical to type1 */
1388 			*size -= 5;
1389 			if (*size < 0)
1390 			{
1391 				LOG(8,("script size error, aborting!\n\n"));
1392 				end = true;
1393 				result = B_ERROR;
1394 				break;
1395 			}
1396 
1397 			/* execute */
1398 			*adress += 1;
1399 			reg = *((uint16*)(&(rom[*adress])));
1400 			*adress += 2;
1401 			and_out = *((uint8*)(&(rom[*adress])));
1402 			*adress += 1;
1403 			or_in = *((uint8*)(&(rom[*adress])));
1404 			*adress += 1;
1405 			LOG(8,("cmd 'RD 8bit ISA reg $%04x, AND-out = $%02x, OR-in = $%02x, WR-bk'\n",
1406 				reg, and_out, or_in));
1407 			if (*exec)
1408 			{
1409 				translate_ISA_PCI(&reg);
1410 				byte = ENG_REG8(reg);
1411 				byte &= (uint8)and_out;
1412 				byte |= (uint8)or_in;
1413 				ENG_REG8(reg) = byte;
1414 			}
1415 			break;
1416 		case 0x6a: /* new */
1417 			*size -= 2;
1418 			if (*size < 0)
1419 			{
1420 				LOG(8,("script size error, aborting!\n\n"));
1421 				end = true;
1422 				result = B_ERROR;
1423 				break;
1424 			}
1425 
1426 			/* execute */
1427 			*adress += 1;
1428 			data = *((uint8*)(&(rom[*adress])));
1429 			*adress += 1;
1430 			data2 = *((uint16*)(&(rom[(tabs.InitScriptTablePtr + (data << 1))])));
1431 			LOG(8,("cmd 'jump to script #$%02x at adress $%04x'\n", data, data2));
1432 			if (*exec)
1433 			{
1434 				*adress = data2;
1435 				LOG(8,("INFO: ---Jumping; not touching 'execution' mode.\n"));
1436 			}
1437 			break;
1438 		case 0x6b: /* new */
1439 			*size -= 2;
1440 			if (*size < 0)
1441 			{
1442 				LOG(8,("script size error, aborting!\n\n"));
1443 				end = true;
1444 				result = B_ERROR;
1445 				break;
1446 			}
1447 
1448 			/* execute */
1449 			*adress += 1;
1450 			data = *((uint8*)(&(rom[*adress])));
1451 			*adress += 1;
1452 			data2 = *((uint16*)(&(rom[(tabs.InitScriptTablePtr + (data << 1))])));
1453 			LOG(8,("cmd 'gosub script #$%02x at adress $%04x'\n", data, data2));
1454 			if (*exec && data2)
1455 			{
1456 				result = exec_type2_script(rom, data2, size, tabs, ram_tab);
1457 				LOG(8,("INFO: ---Reverting to pre-gosub 'execution' mode.\n"));
1458 			}
1459 			break;
1460 		case 0x6e: /* identical to type1 */
1461 			*size -= 13;
1462 			if (*size < 0)
1463 			{
1464 				LOG(8,("script size error, aborting!\n\n"));
1465 				end = true;
1466 				result = B_ERROR;
1467 				break;
1468 			}
1469 
1470 			/* execute */
1471 			*adress += 1;
1472 			reg = *((uint32*)(&(rom[*adress])));
1473 			*adress += 4;
1474 			and_out = *((uint32*)(&(rom[*adress])));
1475 			*adress += 4;
1476 			or_in = *((uint32*)(&(rom[*adress])));
1477 			*adress += 4;
1478 			LOG(8,("cmd 'RD 32bit reg $%08x, AND-out = $%08x, OR-in = $%08x, WR-bk'\n",
1479 				reg, and_out, or_in));
1480 			if (*exec)
1481 			{
1482 				data = ENG_RG32(reg);
1483 				data &= and_out;
1484 				data |= or_in;
1485 				ENG_RG32(reg) = data;
1486 			}
1487 			break;
1488 		case 0x6f: /* new */
1489 			*size -= 2;
1490 			if (*size < 0)
1491 			{
1492 				LOG(8,("script size error, aborting!\n\n"));
1493 				end = true;
1494 				result = B_ERROR;
1495 				break;
1496 			}
1497 
1498 			/* execute */
1499 			*adress += 1;
1500 			byte = *((uint8*)(&(rom[*adress])));
1501 			*adress += 1;
1502 			data = tabs.MacroIndexTablePtr + (byte << 1);
1503 			offset32 = (*((uint8*)(&(rom[data]))) << 3);
1504 			size32 = *((uint8*)(&(rom[(data + 1)])));
1505 			offset32 += tabs.MacroTablePtr;
1506 			/* note: min 1, max 255 commands can be requested */
1507 			LOG(8,("cmd 'do $%02x time(s) a 32bit reg WR with 32bit data' (MacroIndexTable idx = $%02x):\n",
1508 				size32, byte));
1509 			safe32 = 0;
1510 			while (safe32 < size32)
1511 			{
1512 				reg2 = *((uint32*)(&(rom[(offset32 + (safe32 << 3))])));
1513 				data2 = *((uint32*)(&(rom[(offset32 + (safe32 << 3) + 4)])));
1514 				LOG(8,("INFO: (cont.) (#$%02x) cmd 'WR 32bit reg' $%08x = $%08x\n",
1515 					safe32, reg2, data2));
1516 				safe32++;
1517  			}
1518 			if (*exec)
1519 			{
1520 				safe32 = 0;
1521 				while (safe32 < size32)
1522 				{
1523 					reg2 = *((uint32*)(&(rom[(offset32 + (safe32 << 3))])));
1524 					data2 = *((uint32*)(&(rom[(offset32 + (safe32 << 3) + 4)])));
1525 					ENG_RG32(reg2) = data2;
1526 					safe32++;
1527 				}
1528 			}
1529 			break;
1530 		case 0x36: /* new */
1531 		case 0x66: /* new */
1532 		case 0x67: /* new */
1533 		case 0x68: /* new */
1534 		case 0x6c: /* new */
1535 		case 0x71: /* identical to type1 */
1536 			LOG(8,("cmd 'END', execution completed.\n\n"));
1537 			end = true;
1538 
1539 			*size -= 1;
1540 			if (*size < 0)
1541 			{
1542 				LOG(8,("script size error!\n\n"));
1543 				result = B_ERROR;
1544 			}
1545 
1546 			/* execute */
1547 			*adress += 1; /* needed to make cmd #$33 work correctly! */
1548 			break;
1549 		case 0x72: /* identical to type1 */
1550 			*size -= 1;
1551 			if (*size < 0)
1552 			{
1553 				LOG(8,("script size error!\n\n"));
1554 				result = B_ERROR;
1555 			}
1556 
1557 			/* execute */
1558 			*adress += 1;
1559 			LOG(8,("cmd 'PGM commands'\n"));
1560 			LOG(8,("INFO: ---Executing following command(s):\n"));
1561 			*exec = true;
1562 			break;
1563 		case 0x74: /* identical to type1 */
1564 			//fixme? on at least NV28 this cmd hammers the CRTC PCI-timeout register
1565 			//'data' number of times instead of snoozing.
1566 			//Couldn't see any diff in behaviour though!
1567 			*size -= 3;
1568 			if (*size < 0)
1569 			{
1570 				LOG(8,("script size error, aborting!\n\n"));
1571 				end = true;
1572 				result = B_ERROR;
1573 				break;
1574 			}
1575 
1576 			/* execute */
1577 			*adress += 1;
1578 			data = *((uint16*)(&(rom[*adress])));
1579 			*adress += 2;
1580 			LOG(8,("cmd 'SNOOZE for %d ($%04x) microSeconds' (always done)\n", data, data));
1581 			/* always done */
1582 			snooze(data);
1583 			break;
1584 		case 0x75: /* new */
1585 			*size -= 2;
1586 			if (*size < 0)
1587 			{
1588 				LOG(8,("script size error!\n\n"));
1589 				result = B_ERROR;
1590 			}
1591 
1592 			/* execute */
1593 			*adress += 1;
1594 			data = *((uint8*)(&(rom[*adress])));
1595 			*adress += 1;
1596 			data *= 12;
1597 			data += tabs.ConditionTablePtr;
1598 			reg = *((uint32*)(&(rom[data])));
1599 			and_out = *((uint32*)(&(rom[(data + 4)])));
1600 			data2 = *((uint32*)(&(rom[(data + 8)])));
1601 			data = ENG_RG32(reg);
1602 			data &= and_out;
1603 			LOG(8,("cmd 'CHK bits AND-out $%08x reg $%08x for $%08x'\n",
1604 				and_out, reg, data2));
1605 			if (data != data2)
1606 			{
1607 				LOG(8,("INFO: ---No match: not executing following command(s):\n"));
1608 				*exec = false;
1609 			}
1610 			else
1611 			{
1612 				LOG(8,("INFO: ---Match, so this cmd has no effect.\n"));
1613 			}
1614 			break;
1615 		case 0x76: /* new */
1616 			*size -= 2;
1617 			if (*size < 0)
1618 			{
1619 				LOG(8,("script size error!\n\n"));
1620 				result = B_ERROR;
1621 			}
1622 
1623 			/* execute */
1624 			*adress += 1;
1625 			data = *((uint8*)(&(rom[*adress])));
1626 			*adress += 1;
1627 			data *= 5;
1628 			data += tabs.IOConditionTablePtr;
1629 			reg = *((uint16*)(&(rom[data])));
1630 			index = *((uint8*)(&(rom[(data + 2)])));
1631 			and_out = *((uint8*)(&(rom[(data + 3)])));
1632 			byte2 = *((uint8*)(&(rom[(data + 4)])));
1633 			LOG(8,("cmd 'CHK bits AND-out $%02x idx ISA reg $%02x via $%04x for $%02x'\n",
1634 				and_out, index, reg, byte2));
1635 			translate_ISA_PCI(&reg);
1636 			ENG_REG8(reg) = index;
1637 			byte = ENG_REG8(reg + 1);
1638 			byte &= (uint8)and_out;
1639 			if (byte != byte2)
1640 			{
1641 				LOG(8,("INFO: ---No match: not executing following command(s):\n"));
1642 				*exec = false;
1643 			}
1644 			else
1645 			{
1646 				LOG(8,("INFO: ---Match, so this cmd has no effect.\n"));
1647 			}
1648 			break;
1649 		case 0x78: /* identical to type1 */
1650 			*size -= 6;
1651 			if (*size < 0)
1652 			{
1653 				LOG(8,("script size error, aborting!\n\n"));
1654 				end = true;
1655 				result = B_ERROR;
1656 				break;
1657 			}
1658 
1659 			/* execute */
1660 			*adress += 1;
1661 			reg = *((uint16*)(&(rom[*adress])));
1662 			*adress += 2;
1663 			index = *((uint8*)(&(rom[*adress])));
1664 			*adress += 1;
1665 			and_out = *((uint8*)(&(rom[*adress])));
1666 			*adress += 1;
1667 			or_in = *((uint8*)(&(rom[*adress])));
1668 			*adress += 1;
1669 			LOG(8,("cmd 'RD idx ISA reg $%02x via $%04x, AND-out = $%02x, OR-in = $%02x, WR-bk'\n",
1670 				index, reg, and_out, or_in));
1671 			if (*exec)
1672 			{
1673 				translate_ISA_PCI(&reg);
1674 				ENG_REG8(reg) = index;
1675 				byte = ENG_REG8(reg + 1);
1676 				byte &= (uint8)and_out;
1677 				byte |= (uint8)or_in;
1678 				ENG_REG8(reg + 1) = byte;
1679 			}
1680 			break;
1681 		case 0x79:
1682 			*size -= 7;
1683 			if (*size < 0)
1684 			{
1685 				LOG(8,("script size error, aborting!\n\n"));
1686 				end = true;
1687 				result = B_ERROR;
1688 				break;
1689 			}
1690 
1691 			/* execute */
1692 			*adress += 1;
1693 			reg = *((uint32*)(&(rom[*adress])));
1694 			*adress += 4;
1695 			data = *((uint16*)(&(rom[*adress])));
1696 			*adress += 2;
1697 			LOG(8,("cmd 'calculate and set PLL 32bit reg $%08x for %.3fMHz'\n", reg, (data / 100.0)));
1698 			if (*exec)
1699 			{
1700 				float calced_clk;
1701 				uint8 m, n, p;
1702 				eng_dac_sys_pll_find((data / 100.0), &calced_clk, &m, &n, &p, 0);
1703 				/* programming the PLL needs to be done in steps! (confirmed NV28) */
1704 				data2 = ENG_RG32(reg);
1705 				ENG_RG32(reg) = ((data2 & 0xffff0000) | (n << 8) | m);
1706 				data2 = ENG_RG32(reg);
1707 				ENG_RG32(reg) = ((p << 16) | (n << 8) | m);
1708 //fixme?
1709 				/* program 2nd set N and M scalers if they exist (b31=1 enables them) */
1710 //				if ((si->ps.card_type == NV31) || (si->ps.card_type == NV36))
1711 //					DACW(PIXPLLC2, 0x80000401);
1712 			}
1713 			log_pll(reg, (data / 100));
1714 			break;
1715 		case 0x7a: /* identical to type1 */
1716 			*size -= 9;
1717 			if (*size < 0)
1718 			{
1719 				LOG(8,("script size error, aborting!\n\n"));
1720 				end = true;
1721 				result = B_ERROR;
1722 				break;
1723 			}
1724 
1725 			/* execute */
1726 			*adress += 1;
1727 			reg = *((uint32*)(&(rom[*adress])));
1728 			*adress += 4;
1729 			data = *((uint32*)(&(rom[*adress])));
1730 			*adress += 4;
1731 			LOG(8,("cmd 'WR 32bit reg' $%08x = $%08x\n", reg, data));
1732 			if (*exec) ENG_RG32(reg) = data;
1733 			break;
1734 		default:
1735 			LOG(8,("unknown cmd, aborting!\n\n"));
1736 			end = true;
1737 			result = B_ERROR;
1738 			break;
1739 		}
1740 	}
1741 
1742 	return result;
1743 }
1744 
1745 static void	exec_cmd_39_type2(uint8* rom, uint32 data, PinsTables tabs, bool* exec)
1746 {
1747 	uint8 index, byte, byte2, safe, shift;
1748 	uint32 reg, and_out, and_out2, offset32;
1749 
1750 	data *= 9;
1751 	data += tabs.IOFlagConditionTablePtr;
1752 	reg = *((uint16*)(&(rom[data])));
1753 	index = *((uint8*)(&(rom[(data + 2)])));
1754 	and_out = *((uint8*)(&(rom[(data + 3)])));
1755 	shift = *((uint8*)(&(rom[(data + 4)])));
1756 	offset32 = *((uint16*)(&(rom[data + 5])));
1757 	and_out2 = *((uint8*)(&(rom[(data + 7)])));
1758 	byte2 = *((uint8*)(&(rom[(data + 8)])));
1759 	LOG(8,("cmd 'AND-out bits $%02x idx ISA reg $%02x via $%04x, shift-right = $%02x,\n",
1760 		and_out, index, reg, shift));
1761 	translate_ISA_PCI(&reg);
1762 	ENG_REG8(reg) = index;
1763 	byte = ENG_REG8(reg + 1);
1764 	byte &= (uint8)and_out;
1765 	offset32 += (byte >> shift);
1766 	safe = byte = *((uint8*)(&(rom[offset32])));
1767 	byte &= (uint8)and_out2;
1768 	LOG(8,("INFO: (cont.) use result as index in table to get data $%02x,\n",
1769 		safe));
1770 	LOG(8,("INFO: (cont.) then chk bits AND-out $%02x of data for $%02x'\n",
1771 		and_out2, byte2));
1772 	if (byte != byte2)
1773 	{
1774 		LOG(8,("INFO: ---No match: not executing following command(s):\n"));
1775 		*exec = false;
1776 	}
1777 	else
1778 	{
1779 		LOG(8,("INFO: ---Match, so this cmd has no effect.\n"));
1780 	}
1781 }
1782 
1783 static void	setup_ram_config_nv10_up(uint8* rom)
1784 {
1785 	uint32 data, dummy;
1786 	uint8 cnt = 0;
1787 	status_t stat = B_ERROR;
1788 
1789 	/* set 'refctrl is valid' */
1790 	ENG_RG32(RG32_PFB_REFCTRL) = 0x80000000;
1791 
1792 	/* check RAM for 256bits buswidth(?) */
1793 	while ((cnt < 4) && (stat != B_OK))
1794 	{
1795 		/* reset RAM bits at offset 224-255 bits four times */
1796 		((uint32 *)si->framebuffer)[0x07] = 0x00000000;
1797 		((uint32 *)si->framebuffer)[0x07] = 0x00000000;
1798 		((uint32 *)si->framebuffer)[0x07] = 0x00000000;
1799 		((uint32 *)si->framebuffer)[0x07] = 0x00000000;
1800 		/* write testpattern */
1801 		((uint32 *)si->framebuffer)[0x07] = 0x4e563131;
1802 		/* reset RAM bits at offset 480-511 bits */
1803 		((uint32 *)si->framebuffer)[0x0f] = 0x00000000;
1804 		/* check testpattern to have survived */
1805 		if (((uint32 *)si->framebuffer)[0x07] == 0x4e563131) stat = B_OK;
1806 		cnt++;
1807 	}
1808 
1809 	/* if pattern did not hold modify RAM-type setup */
1810 	if (stat != B_OK)
1811 	{
1812 		LOG(8,("INFO: ---RAM test #1 done: access errors, modified setup.\n"));
1813 		data = ENG_RG32(RG32_PFB_CONFIG_0);
1814 		if (data & 0x00000010)
1815 		{
1816 			data &= 0xffffffcf;
1817 		}
1818 		else
1819 		{
1820 			data &= 0xffffffcf;
1821 			data |= 0x00000020;
1822 		}
1823 		ENG_RG32(RG32_PFB_CONFIG_0) = data;
1824 	}
1825 	else
1826 	{
1827 		LOG(8,("INFO: ---RAM test #1 done: access is OK.\n"));
1828 	}
1829 
1830 	/* check RAM bankswitching stuff(?) */
1831 	cnt = 0;
1832 	stat = B_ERROR;
1833 	while ((cnt < 4) && (stat != B_OK))
1834 	{
1835 		/* read RAM size */
1836 		data = ENG_RG32(RG32_NV10STRAPINFO);
1837 		/* subtract 1MB */
1838 		data -= 0x00100000;
1839 		/* write testpattern at generated RAM adress */
1840 		((uint32 *)si->framebuffer)[(data >> 2)] = 0x4e564441;
1841 		/* reset first RAM adress */
1842 		((uint32 *)si->framebuffer)[0x00] = 0x00000000;
1843 		/* dummyread first RAM adress four times */
1844 		dummy = ((uint32 *)si->framebuffer)[0x00];
1845 		dummy = ((uint32 *)si->framebuffer)[0x00];
1846 		dummy = ((uint32 *)si->framebuffer)[0x00];
1847 		dummy = ((uint32 *)si->framebuffer)[0x00];
1848 		/* check testpattern to have survived */
1849 		if (((uint32 *)si->framebuffer)[(data >> 2)] == 0x4e564441) stat = B_OK;
1850 		cnt++;
1851 	}
1852 
1853 	/* if pattern did not hold modify RAM-type setup */
1854 	if (stat != B_OK)
1855 	{
1856 		LOG(8,("INFO: ---RAM test #2 done: access errors, modified setup.\n"));
1857 		ENG_RG32(RG32_PFB_CONFIG_0) &= 0xffffefff;
1858 	}
1859 	else
1860 	{
1861 		LOG(8,("INFO: ---RAM test #2 done: access is OK.\n"));
1862 	}
1863 }
1864 
1865 /* Note: this routine assumes at least 128Mb was mapped to memory (kerneldriver).
1866  * It doesn't matter if the card actually _has_ this amount of RAM or not(!) */
1867 static void	setup_ram_config_nv28(uint8* rom)
1868 {
1869 	uint32 dummy;
1870 	uint8 cnt = 0;
1871 	status_t stat = B_ERROR;
1872 
1873 	/* set 'refctrl is valid' */
1874 	ENG_RG32(RG32_PFB_REFCTRL) = 0x80000000;
1875 
1876 	/* check RAM */
1877 	while ((cnt < 4) && (stat != B_OK))
1878 	{
1879 		/* set bit 11: 'pulse' something into a new setting? */
1880 		ENG_RG32(RG32_PFB_CONFIG_0) |= 0x00000800;
1881 		/* write testpattern to RAM adress 127Mb */
1882 		((uint32 *)si->framebuffer)[0x01fc0000] = 0x4e564441;
1883 		/* reset first RAM adress */
1884 		((uint32 *)si->framebuffer)[0x00000000] = 0x00000000;
1885 		/* dummyread first RAM adress four times */
1886 		dummy = ((uint32 *)si->framebuffer)[0x00000000];
1887 		LOG(8,("INFO: (#%d) dummy1 = $%08x, ", cnt, dummy));
1888 		dummy = ((uint32 *)si->framebuffer)[0x00000000];
1889 		LOG(8,("dummy2 = $%08x, ", dummy));
1890 		dummy = ((uint32 *)si->framebuffer)[0x00000000];
1891 		LOG(8,("dummy3 = $%08x, ", dummy));
1892 		dummy = ((uint32 *)si->framebuffer)[0x00000000];
1893 		LOG(8,("dummy4 = $%08x\n", dummy));
1894 		/* check testpattern to have survived */
1895 		if (((uint32 *)si->framebuffer)[0x01fc0000] == 0x4e564441) stat = B_OK;
1896 		cnt++;
1897 	}
1898 
1899 	/* clear bit 11: set normal mode */
1900 	ENG_RG32(RG32_PFB_CONFIG_0) &= ~0x00000800;
1901 
1902 	if (stat == B_OK)
1903 		LOG(8,("INFO: ---RAM test done: access was OK within %d iteration(s).\n", cnt));
1904 	else
1905 		LOG(8,("INFO: ---RAM test done: access was still not OK after 4 iterations.\n"));
1906 }
1907 
1908 static status_t translate_ISA_PCI(uint32* reg)
1909 {
1910 	switch (*reg)
1911 	{
1912 	case 0x03c0:
1913 		*reg = RG8_ATTRDATW;
1914 		break;
1915 	case 0x03c1:
1916 		*reg = RG8_ATTRDATR;
1917 		break;
1918 	case 0x03c2:
1919 		*reg = RG8_MISCW;
1920 		break;
1921 	case 0x03c4:
1922 		*reg = RG8_SEQIND;
1923 		break;
1924 	case 0x03c5:
1925 		*reg = RG8_SEQDAT;
1926 		break;
1927 	case 0x03c6:
1928 		*reg = RG8_PALMASK;
1929 		break;
1930 	case 0x03c7:
1931 		*reg = RG8_PALINDR;
1932 		break;
1933 	case 0x03c8:
1934 		*reg = RG8_PALINDW;
1935 		break;
1936 	case 0x03c9:
1937 		*reg = RG8_PALDATA;
1938 		break;
1939 	case 0x03cc:
1940 		*reg = RG8_MISCR;
1941 		break;
1942 	case 0x03ce:
1943 		*reg = RG8_GRPHIND;
1944 		break;
1945 	case 0x03cf:
1946 		*reg = RG8_GRPHDAT;
1947 		break;
1948 	case 0x03d4:
1949 		*reg = RG8_CRTCIND;
1950 		break;
1951 	case 0x03d5:
1952 		*reg = RG8_CRTCDAT;
1953 		break;
1954 	case 0x03da:
1955 		*reg = RG8_INSTAT1;
1956 		break;
1957 	default:
1958 		LOG(8,("\n\nINFO: WARNING: ISA->PCI register adress translation failed!\n\n"));
1959 		return B_ERROR;
1960 		break;
1961 	}
1962 
1963 	return B_OK;
1964 }
1965 
1966 //fixme: move to crtc sourcefile, also setup for crtc2(?)
1967 static status_t	eng_crtc_setup_fifo()
1968 {
1969 	/* enable access to primary head */
1970 	set_crtc_owner(0);
1971 
1972 	//fixme: setup according to colordepth and RAM bus width...
1973 	/* set CRTC FIFO burst size to 256 */
1974 	CRTCW(FIFO, 0x03);
1975 
1976 	/* set CRTC FIFO low watermark to 32 */
1977 	CRTCW(FIFO_LWM, 0x20);
1978 
1979 	return B_OK;
1980 }
1981 
1982 /* (pre)set 'fixed' card specifications */
1983 void set_specs(void)
1984 {
1985 	LOG(8,("INFO: setting up card specifications\n"));
1986 
1987 	/* set failsave speeds */
1988 	switch (si->ps.card_type)
1989 	{
1990 	case NV04:
1991 		pinsnv4_fake();
1992 		break;
1993 	case NV05:
1994 	case NV05M64:
1995 		pinsnv5_nv5m64_fake();
1996 		break;
1997 	case NV06:
1998 		pinsnv6_fake();
1999 		break;
2000 	default:
2001 		switch (si->ps.card_arch)
2002 		{
2003 		case NV10A:
2004 			pinsnv10_arch_fake();
2005 			break;
2006 		case NV20A:
2007 			pinsnv20_arch_fake();
2008 			break;
2009 		case NV30A:
2010 		case NV40A:
2011 			pinsnv30_arch_fake();
2012 			break;
2013 		default:
2014 			/* 'failsafe' values... */
2015 			pinsnv10_arch_fake();
2016 			break;
2017 		}
2018 		break;
2019 	}
2020 
2021 	/* detect reference crystal frequency and dualhead */
2022 	switch (si->ps.card_arch)
2023 	{
2024 	case NV04A:
2025 		getstrap_arch_nv4();
2026 		break;
2027 	default:
2028 		getstrap_arch_nv10_20_30_40();
2029 		break;
2030 	}
2031 }
2032 
2033 /* this routine presumes the card was coldstarted by the card's BIOS for panel stuff */
2034 void fake_panel_start(void)
2035 {
2036 	LOG(8,("INFO: detecting RAM size\n"));
2037 
2038 	/* detect RAM amount */
2039 	switch (si->ps.card_arch)
2040 	{
2041 	case NV04A:
2042 		getRAMsize_arch_nv4();
2043 		break;
2044 	default:
2045 		getRAMsize_arch_nv10_20_30_40();
2046 		break;
2047 	}
2048 
2049 	/* override memory detection if requested by user */
2050 	if (si->settings.memory != 0)
2051 	{
2052 		LOG(2,("INFO: forcing memory size (specified in settings file)\n"));
2053 		si->ps.memory_size = si->settings.memory * 1024 * 1024;
2054 	}
2055 
2056 	/* find out if the card has a tvout chip */
2057 	si->ps.tvout = false;
2058 	si->ps.tvout_chip_type = NONE;
2059 //fixme ;-)
2060 /*	if (i2c_maven_probe() == B_OK)
2061 	{
2062 		si->ps.tvout = true;
2063 		si->ps.tvout_chip_bus = ???;
2064 		si->ps.tvout_chip_type = ???;
2065 	}
2066 */
2067 
2068 	LOG(8,("INFO: faking panel startup\n"));
2069 
2070 	/* find out the BIOS preprogrammed panel use status... */
2071 //	detect_panels();
2072 
2073 	/* determine and setup output devices and heads */
2074 	setup_output_matrix();
2075 
2076 	/* select other CRTC for primary head use if specified by user in settings file */
2077 	if (si->ps.secondary_head && si->settings.switchhead)
2078 	{
2079 		LOG(2,("INFO: inverting head use (specified in settings file)\n"));
2080 		si->ps.crtc2_prim = !si->ps.crtc2_prim;
2081 	}
2082 }
2083 
2084 static void detect_panels()
2085 {
2086 	/* detect if the BIOS enabled LCD's (internal panels or DVI) or TVout */
2087 
2088 	/* both external TMDS transmitters (used for LCD/DVI) and external TVencoders
2089 	 * (can) use the CRTC's in slaved mode. */
2090 	/* Note:
2091 	 * DFP's are programmed with standard VESA modelines by the card's BIOS! */
2092 	bool slaved_for_dev1 = false, slaved_for_dev2 = false;
2093 	bool tvout1 = false, tvout2 = false;
2094 
2095 	/* check primary head: */
2096 	/* enable access to primary head */
2097 	set_crtc_owner(0);
2098 
2099 	/* unlock head's registers for R/W access */
2100 	CRTCW(LOCK, 0x57);
2101 	CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f));
2102 
2103 	LOG(2,("INFO: Dumping flatpanel related CRTC registers:\n"));
2104 	/* related info PIXEL register:
2105 	 * b7: 1 = slaved mode										(all cards). */
2106 	LOG(2,("CRTC1: PIXEL register: $%02x\n", CRTCR(PIXEL)));
2107 	/* info LCD register:
2108 	 * b7: 1 = stereo view (shutter glasses use)				(all cards),
2109 	 * b5: 1 = power ext. TMDS (or something)/0 = TVout	use	(?)	(confirmed NV17, NV28),
2110 	 * b4: 1 = power ext. TMDS (or something)/0 = TVout use	(?)	(confirmed NV34),
2111 	 * b3: 1 = ??? (not panel related probably!)				(confirmed NV34),
2112 	 * b1: 1 = power ext. TMDS (or something) (?)				(confirmed NV05?, NV17),
2113 	 * b0: 1 = select panel encoder / 0 = select TVout encoder	(all cards). */
2114 	LOG(2,("CRTC1: LCD register: $%02x\n", CRTCR(LCD)));
2115 	/* info 0x59 register:
2116 	 * b0: 1 = enable ext. TMDS clock (DPMS)					(confirmed NV28, NV34). */
2117 	LOG(2,("CRTC1: register $59: $%02x\n", CRTCR(0x59)));
2118 	/* info 0x9f register:
2119 	 * b4: 0 = TVout use (?). */
2120 	LOG(2,("CRTC1: register $9f: $%02x\n", CRTCR(0x9f)));
2121 
2122 	/* detect active slave device (if any) */
2123 	slaved_for_dev1 = (CRTCR(PIXEL) & 0x80);
2124 	if (slaved_for_dev1)
2125 	{
2126 		/* if the panel isn't selected, tvout is.. */
2127 		tvout1 = !(CRTCR(LCD) & 0x01);
2128 	}
2129 
2130 	if (si->ps.secondary_head)
2131 	{
2132 		/* check secondary head: */
2133 		/* enable access to secondary head */
2134 		set_crtc_owner(1);
2135 		/* unlock head's registers for R/W access */
2136 		CRTC2W(LOCK, 0x57);
2137 		CRTC2W(VSYNCE ,(CRTC2R(VSYNCE) & 0x7f));
2138 
2139 		LOG(2,("CRTC2: PIXEL register: $%02x\n", CRTC2R(PIXEL)));
2140 		LOG(2,("CRTC2: LCD register: $%02x\n", CRTC2R(LCD)));
2141 		LOG(2,("CRTC2: register $59: $%02x\n", CRTC2R(0x59)));
2142 		LOG(2,("CRTC2: register $9f: $%02x\n", CRTC2R(0x9f)));
2143 
2144 		/* detect active slave device (if any) */
2145 		slaved_for_dev2 = (CRTC2R(PIXEL) & 0x80);
2146 		if (slaved_for_dev2)
2147 		{
2148 			/* if the panel isn't selected, tvout is.. */
2149 			tvout2 = !(CRTC2R(LCD) & 0x01);
2150 		}
2151 	}
2152 
2153 	LOG(2,("INFO: End flatpanel related CRTC registers dump.\n"));
2154 
2155 	/* do some presets */
2156 	si->ps.p1_timing.h_display = 0;
2157 	si->ps.p1_timing.v_display = 0;
2158 	si->ps.panel1_aspect = 0;
2159 	si->ps.p2_timing.h_display = 0;
2160 	si->ps.p2_timing.v_display = 0;
2161 	si->ps.panel2_aspect = 0;
2162 	si->ps.slaved_tmds1 = false;
2163 	si->ps.slaved_tmds2 = false;
2164 	si->ps.master_tmds1 = false;
2165 	si->ps.master_tmds2 = false;
2166 	si->ps.tmds1_active = false;
2167 	si->ps.tmds2_active = false;
2168 	/* determine the situation we are in... (regarding flatpanels) */
2169 	/* fixme: add VESA DDC EDID stuff one day... */
2170 	/* fixme: find out how to program those transmitters one day instead of
2171 	 * relying on the cards BIOS to do it. This adds TVout options where panels
2172 	 * are used!
2173 	 * Currently we'd loose the panel setup while not being able to restore it. */
2174 
2175 	/* note: (facts)
2176 	 * -> NV11 and NV17 laptops have LVDS panels, programmed in both sets registers;
2177 	 * -> NV34 laptops have TMDS panels, programmed in only one set of registers;
2178 	 * -> NV11, NV25 and NV34 DVI cards, so external panels (TMDS) are programmed
2179 	 *    in only one set of registers;
2180 	 * -> a register-set's FP_TG_CTRL register, bit 31 tells you if a LVDS panel is
2181 	 *    connected to the primary head (0), or to the secondary head (1) except
2182 	 *    on some NV11's if this bit is '0' there;
2183 	 * -> for LVDS panels both registersets are programmed identically by the card's
2184 	 *    BIOSes;
2185 	 * -> the programmed set of registers tells you where a TMDS (DVI) panel is
2186 	 *    connected;
2187 	 * -> On all cards a CRTC is used in slaved mode when a panel is connected,
2188 	 *    except on NV11: here master mode is (might be?) detected. */
2189 	/* note also:
2190 	 * external TMDS encoders are only used for logic-level translation: it's
2191 	 * modeline registers are not used. Instead the GPU's internal modeline registers
2192 	 * are used. The external encoder is not connected to a I2C bus (confirmed NV34). */
2193 	if (slaved_for_dev1 && !tvout1)
2194 	{
2195 		uint16 width = ((DACR(FP_HDISPEND) & 0x0000ffff) + 1);
2196 		uint16 height = ((DACR(FP_VDISPEND) & 0x0000ffff) + 1);
2197 		if ((width >= 640) && (height >= 480))
2198 		{
2199 			si->ps.slaved_tmds1 = true;
2200 			si->ps.tmds1_active = true;
2201 			si->ps.p1_timing.h_display = width;
2202 			si->ps.p1_timing.v_display = height;
2203 		}
2204 	}
2205 
2206 	if (si->ps.secondary_head && slaved_for_dev2 && !tvout2)
2207 	{
2208 		uint16 width = ((DAC2R(FP_HDISPEND) & 0x0000ffff) + 1);
2209 		uint16 height = ((DAC2R(FP_VDISPEND) & 0x0000ffff) + 1);
2210 		if ((width >= 640) && (height >= 480))
2211 		{
2212 			si->ps.slaved_tmds2 = true;
2213 			si->ps.tmds2_active = true;
2214 			si->ps.p2_timing.h_display = width;
2215 			si->ps.p2_timing.v_display = height;
2216 		}
2217 	}
2218 
2219 	if ((si->ps.card_type == NV11) &&
2220 		!si->ps.slaved_tmds1 && !tvout1)
2221 	{
2222 		uint16 width = ((DACR(FP_HDISPEND) & 0x0000ffff) + 1);
2223 		uint16 height = ((DACR(FP_VDISPEND) & 0x0000ffff) + 1);
2224 		if ((width >= 640) && (height >= 480))
2225 		{
2226 			si->ps.master_tmds1 = true;
2227 			si->ps.tmds1_active = true;
2228 			si->ps.p1_timing.h_display = width;
2229 			si->ps.p1_timing.v_display = height;
2230 		}
2231 	}
2232 
2233 	if ((si->ps.card_type == NV11) &&
2234 		si->ps.secondary_head && !si->ps.slaved_tmds2 && !tvout2)
2235 	{
2236 		uint16 width = ((DAC2R(FP_HDISPEND) & 0x0000ffff) + 1);
2237 		uint16 height = ((DAC2R(FP_VDISPEND) & 0x0000ffff) + 1);
2238 		if ((width >= 640) && (height >= 480))
2239 		{
2240 			si->ps.master_tmds2 = true;
2241 			si->ps.tmds2_active = true;
2242 			si->ps.p2_timing.h_display = width;
2243 			si->ps.p2_timing.v_display = height;
2244 		}
2245 	}
2246 
2247 	//fixme...:
2248 	//we are assuming that no DVI is used as external monitor on laptops;
2249 	//otherwise we probably get into trouble here if the checked specs match.
2250 	if (si->ps.laptop && si->ps.tmds1_active && si->ps.tmds2_active &&
2251 		((DACR(FP_TG_CTRL) & 0x80000000) == (DAC2R(FP_TG_CTRL) & 0x80000000)) &&
2252 		(si->ps.p1_timing.h_display == si->ps.p2_timing.h_display) &&
2253 		(si->ps.p1_timing.v_display == si->ps.p2_timing.v_display))
2254 	{
2255 		LOG(2,("INFO: correcting double detection of single panel!\n"));
2256 
2257 		if (si->ps.card_type == NV11)
2258 		{
2259 			/* LVDS panel is _always_ on CRTC2, so clear false primary detection */
2260 			si->ps.slaved_tmds1 = false;
2261 			si->ps.master_tmds1 = false;
2262 			si->ps.tmds1_active = false;
2263 			si->ps.p1_timing.h_display = 0;
2264 			si->ps.p1_timing.v_display = 0;
2265 		}
2266 		else
2267 		{
2268 			if (DACR(FP_TG_CTRL) & 0x80000000)
2269 			{
2270 				/* LVDS panel is on CRTC2, so clear false primary detection */
2271 				si->ps.slaved_tmds1 = false;
2272 				si->ps.master_tmds1 = false;
2273 				si->ps.tmds1_active = false;
2274 				si->ps.p1_timing.h_display = 0;
2275 				si->ps.p1_timing.v_display = 0;
2276 			}
2277 			else
2278 			{
2279 				/* LVDS panel is on CRTC1, so clear false secondary detection */
2280 				si->ps.slaved_tmds2 = false;
2281 				si->ps.master_tmds2 = false;
2282 				si->ps.tmds2_active = false;
2283 				si->ps.p2_timing.h_display = 0;
2284 				si->ps.p2_timing.v_display = 0;
2285 			}
2286 		}
2287 	}
2288 
2289 	/* fetch panel(s) modeline(s) */
2290 	if (si->ps.tmds1_active)
2291 	{
2292 		/* determine panel aspect ratio */
2293 		si->ps.panel1_aspect =
2294 			(si->ps.p1_timing.h_display / ((float)si->ps.p1_timing.v_display));
2295 		/* horizontal timing */
2296 		si->ps.p1_timing.h_sync_start = (DACR(FP_HSYNC_S) & 0x0000ffff) + 1;
2297 		si->ps.p1_timing.h_sync_end = (DACR(FP_HSYNC_E) & 0x0000ffff) + 1;
2298 		si->ps.p1_timing.h_total = (DACR(FP_HTOTAL) & 0x0000ffff) + 1;
2299 		/* vertical timing */
2300 		si->ps.p1_timing.v_sync_start = (DACR(FP_VSYNC_S) & 0x0000ffff) + 1;
2301 		si->ps.p1_timing.v_sync_end = (DACR(FP_VSYNC_E) & 0x0000ffff) + 1;
2302 		si->ps.p1_timing.v_total = (DACR(FP_VTOTAL) & 0x0000ffff) + 1;
2303 		/* sync polarity */
2304 		si->ps.p1_timing.flags = 0;
2305 		if (DACR(FP_TG_CTRL) & 0x00000001) si->ps.p1_timing.flags |= B_POSITIVE_VSYNC;
2306 		if (DACR(FP_TG_CTRL) & 0x00000010) si->ps.p1_timing.flags |= B_POSITIVE_HSYNC;
2307 		/* refreshrate:
2308 		 * fix a DVI or laptop flatpanel to 60Hz refresh! */
2309 		si->ps.p1_timing.pixel_clock =
2310 			(si->ps.p1_timing.h_total * si->ps.p1_timing.v_total * 60) / 1000;
2311 	}
2312 	if (si->ps.tmds2_active)
2313 	{
2314 		/* determine panel aspect ratio */
2315 		si->ps.panel2_aspect =
2316 			(si->ps.p2_timing.h_display / ((float)si->ps.p2_timing.v_display));
2317 		/* horizontal timing */
2318 		si->ps.p2_timing.h_sync_start = (DAC2R(FP_HSYNC_S) & 0x0000ffff) + 1;
2319 		si->ps.p2_timing.h_sync_end = (DAC2R(FP_HSYNC_E) & 0x0000ffff) + 1;
2320 		si->ps.p2_timing.h_total = (DAC2R(FP_HTOTAL) & 0x0000ffff) + 1;
2321 		/* vertical timing */
2322 		si->ps.p2_timing.v_sync_start = (DAC2R(FP_VSYNC_S) & 0x0000ffff) + 1;
2323 		si->ps.p2_timing.v_sync_end = (DAC2R(FP_VSYNC_E) & 0x0000ffff) + 1;
2324 		si->ps.p2_timing.v_total = (DAC2R(FP_VTOTAL) & 0x0000ffff) + 1;
2325 		/* sync polarity */
2326 		si->ps.p2_timing.flags = 0;
2327 		if (DAC2R(FP_TG_CTRL) & 0x00000001) si->ps.p2_timing.flags |= B_POSITIVE_VSYNC;
2328 		if (DAC2R(FP_TG_CTRL) & 0x00000010) si->ps.p2_timing.flags |= B_POSITIVE_HSYNC;
2329 		/* refreshrate:
2330 		 * fix a DVI or laptop flatpanel to 60Hz refresh! */
2331 		si->ps.p2_timing.pixel_clock =
2332 			(si->ps.p2_timing.h_total * si->ps.p2_timing.v_total * 60) / 1000;
2333 	}
2334 
2335 	/* dump some panel configuration registers... */
2336 	LOG(2,("INFO: Dumping flatpanel registers:\n"));
2337 	LOG(2,("DUALHEAD_CTRL: $%08x\n", ENG_RG32(RG32_DUALHEAD_CTRL)));
2338 	LOG(2,("DAC1: FP_HDISPEND: %d\n", DACR(FP_HDISPEND)));
2339 	LOG(2,("DAC1: FP_HTOTAL: %d\n", DACR(FP_HTOTAL)));
2340 	LOG(2,("DAC1: FP_HCRTC: %d\n", DACR(FP_HCRTC)));
2341 	LOG(2,("DAC1: FP_HSYNC_S: %d\n", DACR(FP_HSYNC_S)));
2342 	LOG(2,("DAC1: FP_HSYNC_E: %d\n", DACR(FP_HSYNC_E)));
2343 	LOG(2,("DAC1: FP_HVALID_S: %d\n", DACR(FP_HVALID_S)));
2344 	LOG(2,("DAC1: FP_HVALID_E: %d\n", DACR(FP_HVALID_E)));
2345 
2346 	LOG(2,("DAC1: FP_VDISPEND: %d\n", DACR(FP_VDISPEND)));
2347 	LOG(2,("DAC1: FP_VTOTAL: %d\n", DACR(FP_VTOTAL)));
2348 	LOG(2,("DAC1: FP_VCRTC: %d\n", DACR(FP_VCRTC)));
2349 	LOG(2,("DAC1: FP_VSYNC_S: %d\n", DACR(FP_VSYNC_S)));
2350 	LOG(2,("DAC1: FP_VSYNC_E: %d\n", DACR(FP_VSYNC_E)));
2351 	LOG(2,("DAC1: FP_VVALID_S: %d\n", DACR(FP_VVALID_S)));
2352 	LOG(2,("DAC1: FP_VVALID_E: %d\n", DACR(FP_VVALID_E)));
2353 
2354 	LOG(2,("DAC1: FP_CHKSUM: $%08x = (dec) %d\n", DACR(FP_CHKSUM),DACR(FP_CHKSUM)));
2355 	LOG(2,("DAC1: FP_TST_CTRL: $%08x\n", DACR(FP_TST_CTRL)));
2356 	LOG(2,("DAC1: FP_TG_CTRL: $%08x\n", DACR(FP_TG_CTRL)));
2357 	LOG(2,("DAC1: FP_DEBUG0: $%08x\n", DACR(FP_DEBUG0)));
2358 	LOG(2,("DAC1: FP_DEBUG1: $%08x\n", DACR(FP_DEBUG1)));
2359 	LOG(2,("DAC1: FP_DEBUG2: $%08x\n", DACR(FP_DEBUG2)));
2360 	LOG(2,("DAC1: FP_DEBUG3: $%08x\n", DACR(FP_DEBUG3)));
2361 
2362 	LOG(2,("DAC1: FUNCSEL: $%08x\n", ENG_RG32(RG32_FUNCSEL)));
2363 	LOG(2,("DAC1: PANEL_PWR: $%08x\n", ENG_RG32(RG32_PANEL_PWR)));
2364 
2365 	if(si->ps.secondary_head)
2366 	{
2367 		LOG(2,("DAC2: FP_HDISPEND: %d\n", DAC2R(FP_HDISPEND)));
2368 		LOG(2,("DAC2: FP_HTOTAL: %d\n", DAC2R(FP_HTOTAL)));
2369 		LOG(2,("DAC2: FP_HCRTC: %d\n", DAC2R(FP_HCRTC)));
2370 		LOG(2,("DAC2: FP_HSYNC_S: %d\n", DAC2R(FP_HSYNC_S)));
2371 		LOG(2,("DAC2: FP_HSYNC_E: %d\n", DAC2R(FP_HSYNC_E)));
2372 		LOG(2,("DAC2: FP_HVALID_S:%d\n", DAC2R(FP_HVALID_S)));
2373 		LOG(2,("DAC2: FP_HVALID_E: %d\n", DAC2R(FP_HVALID_E)));
2374 
2375 		LOG(2,("DAC2: FP_VDISPEND: %d\n", DAC2R(FP_VDISPEND)));
2376 		LOG(2,("DAC2: FP_VTOTAL: %d\n", DAC2R(FP_VTOTAL)));
2377 		LOG(2,("DAC2: FP_VCRTC: %d\n", DAC2R(FP_VCRTC)));
2378 		LOG(2,("DAC2: FP_VSYNC_S: %d\n", DAC2R(FP_VSYNC_S)));
2379 		LOG(2,("DAC2: FP_VSYNC_E: %d\n", DAC2R(FP_VSYNC_E)));
2380 		LOG(2,("DAC2: FP_VVALID_S: %d\n", DAC2R(FP_VVALID_S)));
2381 		LOG(2,("DAC2: FP_VVALID_E: %d\n", DAC2R(FP_VVALID_E)));
2382 
2383 		LOG(2,("DAC2: FP_CHKSUM: $%08x = (dec) %d\n", DAC2R(FP_CHKSUM),DAC2R(FP_CHKSUM)));
2384 		LOG(2,("DAC2: FP_TST_CTRL: $%08x\n", DAC2R(FP_TST_CTRL)));
2385 		LOG(2,("DAC2: FP_TG_CTRL: $%08x\n", DAC2R(FP_TG_CTRL)));
2386 		LOG(2,("DAC2: FP_DEBUG0: $%08x\n", DAC2R(FP_DEBUG0)));
2387 		LOG(2,("DAC2: FP_DEBUG1: $%08x\n", DAC2R(FP_DEBUG1)));
2388 		LOG(2,("DAC2: FP_DEBUG2: $%08x\n", DAC2R(FP_DEBUG2)));
2389 		LOG(2,("DAC2: FP_DEBUG3: $%08x\n", DAC2R(FP_DEBUG3)));
2390 
2391 		LOG(2,("DAC2: FUNCSEL: $%08x\n", ENG_RG32(RG32_2FUNCSEL)));
2392 		LOG(2,("DAC2: PANEL_PWR: $%08x\n", ENG_RG32(RG32_2PANEL_PWR)));
2393 	}
2394 	LOG(2,("INFO: End flatpanel registers dump.\n"));
2395 }
2396 
2397 static void setup_output_matrix()
2398 {
2399 	/* setup defaults: */
2400 	/* no monitors (output devices) detected */
2401 	si->ps.monitors = 0x00;
2402 	/* head 1 will be the primary head */
2403 	si->ps.crtc2_prim = false;
2404 
2405 	/* setup output devices and heads */
2406 	if (si->ps.secondary_head)
2407 	{
2408 		if (si->ps.card_type != NV11)
2409 		{
2410 			/* setup defaults: */
2411 			/* connect analog outputs straight through */
2412 			eng_general_output_select(false);
2413 
2414 			/* presetup by the card's BIOS, we can't change this (lack of info) */
2415 			if (si->ps.tmds1_active) si->ps.monitors |= 0x01;
2416 			if (si->ps.tmds2_active) si->ps.monitors |= 0x10;
2417 			/* detect analog monitors (confirmed working OK on NV18, NV28 and NV34): */
2418 			/* sense analog monitor on primary connector */
2419 			if (eng_dac_crt_connected()) si->ps.monitors |= 0x02;
2420 			/* sense analog monitor on secondary connector */
2421 			if (eng_dac2_crt_connected()) si->ps.monitors |= 0x20;
2422 
2423 			/* setup correct output and head use */
2424 			//fixme? add TVout (only, so no CRT(s) connected) support...
2425 			switch (si->ps.monitors)
2426 			{
2427 			case 0x00: /* no monitor found at all */
2428 				LOG(2,("INFO: head 1 has nothing connected;\n"));
2429 				LOG(2,("INFO: head 2 has nothing connected:\n"));
2430 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2431 				break;
2432 			case 0x01: /* digital panel on head 1, nothing on head 2 */
2433 				LOG(2,("INFO: head 1 has a digital panel;\n"));
2434 				LOG(2,("INFO: head 2 has nothing connected:\n"));
2435 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2436 				break;
2437 			case 0x02: /* analog panel or CRT on head 1, nothing on head 2 */
2438 				LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
2439 				LOG(2,("INFO: head 2 has nothing connected:\n"));
2440 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2441 				break;
2442 			case 0x03: /* both types on head 1, nothing on head 2 */
2443 				LOG(2,("INFO: head 1 has a digital panel AND an analog panel or CRT;\n"));
2444 				LOG(2,("INFO: head 2 has nothing connected:\n"));
2445 				LOG(2,("INFO: correcting...\n"));
2446 				/* cross connect analog outputs so analog panel or CRT gets head 2 */
2447 				eng_general_output_select(true);
2448 				LOG(2,("INFO: head 1 has a digital panel;\n"));
2449 				LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
2450 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2451 				break;
2452 			case 0x10: /* nothing on head 1, digital panel on head 2 */
2453 				LOG(2,("INFO: head 1 has nothing connected;\n"));
2454 				LOG(2,("INFO: head 2 has a digital panel:\n"));
2455 				LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
2456 				si->ps.crtc2_prim = true;
2457 				break;
2458 			case 0x20: /* nothing on head 1, analog panel or CRT on head 2 */
2459 				LOG(2,("INFO: head 1 has nothing connected;\n"));
2460 				LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
2461 				LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
2462 				si->ps.crtc2_prim = true;
2463 				break;
2464 			case 0x30: /* nothing on head 1, both types on head 2 */
2465 				LOG(2,("INFO: head 1 has nothing connected;\n"));
2466 				LOG(2,("INFO: head 2 has a digital panel AND an analog panel or CRT:\n"));
2467 				LOG(2,("INFO: correcting...\n"));
2468 				/* cross connect analog outputs so analog panel or CRT gets head 1 */
2469 				eng_general_output_select(true);
2470 				LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
2471 				LOG(2,("INFO: head 2 has a digital panel:\n"));
2472 				LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
2473 				si->ps.crtc2_prim = true;
2474 				break;
2475 			case 0x11: /* digital panels on both heads */
2476 				LOG(2,("INFO: head 1 has a digital panel;\n"));
2477 				LOG(2,("INFO: head 2 has a digital panel:\n"));
2478 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2479 				break;
2480 			case 0x12: /* analog panel or CRT on head 1, digital panel on head 2 */
2481 				LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
2482 				LOG(2,("INFO: head 2 has a digital panel:\n"));
2483 				LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
2484 				si->ps.crtc2_prim = true;
2485 				break;
2486 			case 0x21: /* digital panel on head 1, analog panel or CRT on head 2 */
2487 				LOG(2,("INFO: head 1 has a digital panel;\n"));
2488 				LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
2489 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2490 				break;
2491 			case 0x22: /* analog panel(s) or CRT(s) on both heads */
2492 				LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
2493 				LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
2494 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2495 				break;
2496 			default: /* more than two monitors connected to just two outputs: illegal! */
2497 				LOG(2,("INFO: illegal monitor setup ($%02x):\n", si->ps.monitors));
2498 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2499 				break;
2500 			}
2501 		}
2502 		else /* dualhead NV11 cards */
2503 		{
2504 			/* confirmed no analog output switch-options for NV11 */
2505 			LOG(2,("INFO: NV11 outputs are hardwired to be straight-through\n"));
2506 
2507 			/* presetup by the card's BIOS, we can't change this (lack of info) */
2508 			if (si->ps.tmds1_active) si->ps.monitors |= 0x01;
2509 			if (si->ps.tmds2_active) si->ps.monitors |= 0x10;
2510 			/* detect analog monitor (confirmed working OK on NV11): */
2511 			/* sense analog monitor on primary connector */
2512 			if (eng_dac_crt_connected()) si->ps.monitors |= 0x02;
2513 			/* (sense analog monitor on secondary connector is impossible on NV11) */
2514 
2515 			/* setup correct output and head use */
2516 			//fixme? add TVout (only, so no CRT(s) connected) support...
2517 			switch (si->ps.monitors)
2518 			{
2519 			case 0x00: /* no monitor found at all */
2520 				LOG(2,("INFO: head 1 has nothing connected;\n"));
2521 				LOG(2,("INFO: head 2 has nothing connected:\n"));
2522 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2523 				break;
2524 			case 0x01: /* digital panel on head 1, nothing on head 2 */
2525 				LOG(2,("INFO: head 1 has a digital panel;\n"));
2526 				LOG(2,("INFO: head 2 has nothing connected:\n"));
2527 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2528 				break;
2529 			case 0x02: /* analog panel or CRT on head 1, nothing on head 2 */
2530 				LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
2531 				LOG(2,("INFO: head 2 has nothing connected:\n"));
2532 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2533 				break;
2534 			case 0x03: /* both types on head 1, nothing on head 2 */
2535 				LOG(2,("INFO: head 1 has a digital panel AND an analog panel or CRT;\n"));
2536 				LOG(2,("INFO: head 2 has nothing connected:\n"));
2537 				LOG(2,("INFO: correction not possible...\n"));
2538 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2539 				break;
2540 			case 0x10: /* nothing on head 1, digital panel on head 2 */
2541 				LOG(2,("INFO: head 1 has nothing connected;\n"));
2542 				LOG(2,("INFO: head 2 has a digital panel:\n"));
2543 				LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
2544 				si->ps.crtc2_prim = true;
2545 				break;
2546 			case 0x11: /* digital panels on both heads */
2547 				LOG(2,("INFO: head 1 has a digital panel;\n"));
2548 				LOG(2,("INFO: head 2 has a digital panel:\n"));
2549 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2550 				break;
2551 			case 0x12: /* analog panel or CRT on head 1, digital panel on head 2 */
2552 				LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
2553 				LOG(2,("INFO: head 2 has a digital panel:\n"));
2554 				LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
2555 				si->ps.crtc2_prim = true;
2556 				break;
2557 			default: /* more than two monitors connected to just two outputs: illegal! */
2558 				LOG(2,("INFO: illegal monitor setup ($%02x):\n", si->ps.monitors));
2559 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
2560 				break;
2561 			}
2562 		}
2563 	}
2564 	else /* singlehead cards */
2565 	{
2566 		/* presetup by the card's BIOS, we can't change this (lack of info) */
2567 		if (si->ps.tmds1_active) si->ps.monitors |= 0x01;
2568 		/* detect analog monitor (confirmed working OK on all cards): */
2569 		/* sense analog monitor on primary connector */
2570 		if (eng_dac_crt_connected()) si->ps.monitors |= 0x02;
2571 
2572 		//fixme? add TVout (only, so no CRT connected) support...
2573 	}
2574 }
2575 
2576 void get_panel_modes(display_mode *p1, display_mode *p2, bool *pan1, bool *pan2)
2577 {
2578 	if (si->ps.tmds1_active)
2579 	{
2580 		/* timing ('modeline') */
2581 		p1->timing = si->ps.p1_timing;
2582 		/* setup the rest */
2583 		p1->space = B_CMAP8;
2584 		p1->virtual_width = p1->timing.h_display;
2585 		p1->virtual_height = p1->timing.v_display;
2586 		p1->h_display_start = 0;
2587 		p1->v_display_start = 0;
2588 		p1->flags = 0;
2589 		*pan1 = true;
2590 	}
2591 	else
2592 		*pan1 = false;
2593 
2594 	if (si->ps.tmds2_active)
2595 	{
2596 		/* timing ('modeline') */
2597 		p2->timing = si->ps.p2_timing;
2598 		/* setup the rest */
2599 		p2->space = B_CMAP8;
2600 		p2->virtual_width = p2->timing.h_display;
2601 		p2->virtual_height = p2->timing.v_display;
2602 		p2->h_display_start = 0;
2603 		p2->v_display_start = 0;
2604 		p2->flags = 0;
2605 		*pan2 = true;
2606 	}
2607 	else
2608 		*pan2 = false;
2609 }
2610 
2611 static void pinsnv4_fake(void)
2612 {
2613 	/* we have a standard PLL */
2614 	si->ps.ext_pll = false;
2615 	/* carefull not to take to high limits, and high should be >= 2x low. */
2616 	si->ps.max_system_vco = 256;
2617 	si->ps.min_system_vco = 128;
2618 	si->ps.max_pixel_vco = 256;
2619 	si->ps.min_pixel_vco = 128;
2620 	si->ps.max_video_vco = 0;
2621 	si->ps.min_video_vco = 0;
2622 	si->ps.max_dac1_clock = 250;
2623 	si->ps.max_dac1_clock_8 = 250;
2624 	si->ps.max_dac1_clock_16 = 250;
2625 	/* 'failsave' values */
2626 	si->ps.max_dac1_clock_24 = 220;
2627 	si->ps.max_dac1_clock_32 = 180;
2628 	si->ps.max_dac1_clock_32dh = 180;
2629 	/* secondary head */
2630 	si->ps.max_dac2_clock = 0;
2631 	si->ps.max_dac2_clock_8 = 0;
2632 	si->ps.max_dac2_clock_16 = 0;
2633 	si->ps.max_dac2_clock_24 = 0;
2634 	si->ps.max_dac2_clock_32 = 0;
2635 	/* 'failsave' values */
2636 	si->ps.max_dac2_clock_32dh = 0;
2637 	//fixme: primary & secondary_dvi should be overrule-able via skel.settings
2638 	si->ps.primary_dvi = false;
2639 	si->ps.secondary_dvi = false;
2640 	/* not used (yet) because no coldstart will be attempted (yet) */
2641 	si->ps.std_engine_clock = 90;
2642 	si->ps.std_memory_clock = 110;
2643 }
2644 
2645 static void pinsnv5_nv5m64_fake(void)
2646 {
2647 	/* we have a standard PLL */
2648 	si->ps.ext_pll = false;
2649 	/* carefull not to take to high limits, and high should be >= 2x low. */
2650 	si->ps.max_system_vco = 300;
2651 	si->ps.min_system_vco = 128;
2652 	si->ps.max_pixel_vco = 300;
2653 	si->ps.min_pixel_vco = 128;
2654 	si->ps.max_video_vco = 0;
2655 	si->ps.min_video_vco = 0;
2656 	si->ps.max_dac1_clock = 300;
2657 	si->ps.max_dac1_clock_8 = 300;
2658 	si->ps.max_dac1_clock_16 = 300;
2659 	/* 'failsave' values */
2660 	si->ps.max_dac1_clock_24 = 270;
2661 	si->ps.max_dac1_clock_32 = 230;
2662 	si->ps.max_dac1_clock_32dh = 230;
2663 	/* secondary head */
2664 	si->ps.max_dac2_clock = 0;
2665 	si->ps.max_dac2_clock_8 = 0;
2666 	si->ps.max_dac2_clock_16 = 0;
2667 	si->ps.max_dac2_clock_24 = 0;
2668 	si->ps.max_dac2_clock_32 = 0;
2669 	/* 'failsave' values */
2670 	si->ps.max_dac2_clock_32dh = 0;
2671 	//fixme: primary & secondary_dvi should be overrule-able via skel.settings
2672 	si->ps.primary_dvi = false;
2673 	si->ps.secondary_dvi = false;
2674 	/* not used (yet) because no coldstart will be attempted (yet) */
2675 	si->ps.std_engine_clock = 125;
2676 	si->ps.std_memory_clock = 150;
2677 }
2678 
2679 static void pinsnv6_fake(void)
2680 {
2681 	/* we have a standard PLL */
2682 	si->ps.ext_pll = false;
2683 	/* carefull not to take to high limits, and high should be >= 2x low. */
2684 	si->ps.max_system_vco = 300;
2685 	si->ps.min_system_vco = 128;
2686 	si->ps.max_pixel_vco = 300;
2687 	si->ps.min_pixel_vco = 128;
2688 	si->ps.max_video_vco = 0;
2689 	si->ps.min_video_vco = 0;
2690 	si->ps.max_dac1_clock = 300;
2691 	si->ps.max_dac1_clock_8 = 300;
2692 	si->ps.max_dac1_clock_16 = 300;
2693 	/* 'failsave' values */
2694 	si->ps.max_dac1_clock_24 = 270;
2695 	si->ps.max_dac1_clock_32 = 230;
2696 	si->ps.max_dac1_clock_32dh = 230;
2697 	/* secondary head */
2698 	si->ps.max_dac2_clock = 0;
2699 	si->ps.max_dac2_clock_8 = 0;
2700 	si->ps.max_dac2_clock_16 = 0;
2701 	si->ps.max_dac2_clock_24 = 0;
2702 	si->ps.max_dac2_clock_32 = 0;
2703 	/* 'failsave' values */
2704 	si->ps.max_dac2_clock_32dh = 0;
2705 	//fixme: primary & secondary_dvi should be overrule-able via skel.settings
2706 	si->ps.primary_dvi = false;
2707 	si->ps.secondary_dvi = false;
2708 	/* not used (yet) because no coldstart will be attempted (yet) */
2709 	si->ps.std_engine_clock = 100;
2710 	si->ps.std_memory_clock = 125;
2711 }
2712 
2713 static void pinsnv10_arch_fake(void)
2714 {
2715 	/* we have a standard PLL */
2716 	si->ps.ext_pll = false;
2717 	/* carefull not to take to high limits, and high should be >= 2x low. */
2718 	si->ps.max_system_vco = 350;
2719 	si->ps.min_system_vco = 128;
2720 	si->ps.max_pixel_vco = 350;
2721 	si->ps.min_pixel_vco = 128;
2722 	si->ps.max_video_vco = 350;
2723 	si->ps.min_video_vco = 128;
2724 	si->ps.max_dac1_clock = 350;
2725 	si->ps.max_dac1_clock_8 = 350;
2726 	si->ps.max_dac1_clock_16 = 350;
2727 	/* 'failsave' values */
2728 	si->ps.max_dac1_clock_24 = 320;
2729 	si->ps.max_dac1_clock_32 = 280;
2730 	si->ps.max_dac1_clock_32dh = 250;
2731 	/* secondary head */
2732 	if (si->ps.card_type < NV17)
2733 	{
2734 		/* if a GeForce2 has analog VGA dualhead capability,
2735 		 * it uses an external secondary DAC probably with limited capability. */
2736 		/* (called twinview technology) */
2737 		si->ps.max_dac2_clock = 200;
2738 		si->ps.max_dac2_clock_8 = 200;
2739 		si->ps.max_dac2_clock_16 = 200;
2740 		si->ps.max_dac2_clock_24 = 200;
2741 		si->ps.max_dac2_clock_32 = 200;
2742 		/* 'failsave' values */
2743 		si->ps.max_dac2_clock_32dh = 180;
2744 	}
2745 	else
2746 	{
2747 		/* GeForce4 cards have dual integrated DACs with identical capaability */
2748 		/* (called nview technology) */
2749 		si->ps.max_dac2_clock = 350;
2750 		si->ps.max_dac2_clock_8 = 350;
2751 		si->ps.max_dac2_clock_16 = 350;
2752 		/* 'failsave' values */
2753 		si->ps.max_dac2_clock_24 = 320;
2754 		si->ps.max_dac2_clock_32 = 280;
2755 		si->ps.max_dac2_clock_32dh = 250;
2756 	}
2757 	//fixme: primary & secondary_dvi should be overrule-able via skel.settings
2758 	si->ps.primary_dvi = false;
2759 	si->ps.secondary_dvi = false;
2760 	/* not used (yet) because no coldstart will be attempted (yet) */
2761 	si->ps.std_engine_clock = 120;
2762 	si->ps.std_memory_clock = 150;
2763 }
2764 
2765 static void pinsnv20_arch_fake(void)
2766 {
2767 	/* we have a standard PLL */
2768 	si->ps.ext_pll = false;
2769 	/* carefull not to take to high limits, and high should be >= 2x low. */
2770 	si->ps.max_system_vco = 350;
2771 	si->ps.min_system_vco = 128;
2772 	si->ps.max_pixel_vco = 350;
2773 	si->ps.min_pixel_vco = 128;
2774 	si->ps.max_video_vco = 350;
2775 	si->ps.min_video_vco = 128;
2776 	si->ps.max_dac1_clock = 350;
2777 	si->ps.max_dac1_clock_8 = 350;
2778 	si->ps.max_dac1_clock_16 = 350;
2779 	/* 'failsave' values */
2780 	si->ps.max_dac1_clock_24 = 320;
2781 	si->ps.max_dac1_clock_32 = 280;
2782 	si->ps.max_dac1_clock_32dh = 250;
2783 	/* secondary head */
2784 	/* GeForce4 cards have dual integrated DACs with identical capaability */
2785 	/* (called nview technology) */
2786 	si->ps.max_dac2_clock = 350;
2787 	si->ps.max_dac2_clock_8 = 350;
2788 	si->ps.max_dac2_clock_16 = 350;
2789 	/* 'failsave' values */
2790 	si->ps.max_dac2_clock_24 = 320;
2791 	si->ps.max_dac2_clock_32 = 280;
2792 	si->ps.max_dac2_clock_32dh = 250;
2793 	//fixme: primary & secondary_dvi should be overrule-able via skel.settings
2794 	si->ps.primary_dvi = false;
2795 	si->ps.secondary_dvi = false;
2796 	/* not used (yet) because no coldstart will be attempted (yet) */
2797 	si->ps.std_engine_clock = 175;
2798 	si->ps.std_memory_clock = 200;
2799 }
2800 
2801 static void pinsnv30_arch_fake(void)
2802 {
2803 	/* determine PLL type */
2804 	LOG(8,("INFO: NV30 architecture chip, PIXPLLC2 DAC1 = $%08x, DAC2 = $%08x\n",
2805 		DACR(PIXPLLC2), DAC2R(PIXPLLC2)));
2806 	switch (si->ps.card_type)
2807 	{
2808 	case NV31:
2809 	case NV36:
2810 	case NV40:
2811 		/* we have a extended PLL */
2812 		si->ps.ext_pll = true;
2813 		break;
2814 	default:
2815 		/* we have a standard PLL */
2816 		si->ps.ext_pll = false;
2817 		break;
2818 	}
2819 	/* carefull not to take to high limits, and high should be >= 2x low. */
2820 	si->ps.max_system_vco = 350;
2821 	si->ps.min_system_vco = 128;
2822 	si->ps.max_pixel_vco = 350;
2823 	si->ps.min_pixel_vco = 128;
2824 	si->ps.max_video_vco = 350;
2825 	si->ps.min_video_vco = 128;
2826 	si->ps.max_dac1_clock = 350;
2827 	si->ps.max_dac1_clock_8 = 350;
2828 	si->ps.max_dac1_clock_16 = 350;
2829 	/* 'failsave' values */
2830 	si->ps.max_dac1_clock_24 = 320;
2831 	si->ps.max_dac1_clock_32 = 280;
2832 	si->ps.max_dac1_clock_32dh = 250;
2833 	/* secondary head */
2834 	/* GeForceFX cards have dual integrated DACs with identical capaability */
2835 	/* (called nview technology) */
2836 	si->ps.max_dac2_clock = 350;
2837 	si->ps.max_dac2_clock_8 = 350;
2838 	si->ps.max_dac2_clock_16 = 350;
2839 	/* 'failsave' values */
2840 	si->ps.max_dac2_clock_24 = 320;
2841 	si->ps.max_dac2_clock_32 = 280;
2842 	si->ps.max_dac2_clock_32dh = 250;
2843 	//fixme: primary & secondary_dvi should be overrule-able via skel.settings
2844 	si->ps.primary_dvi = false;
2845 	si->ps.secondary_dvi = false;
2846 	/* not used (yet) because no coldstart will be attempted (yet) */
2847 	si->ps.std_engine_clock = 190;
2848 	si->ps.std_memory_clock = 190;
2849 }
2850 
2851 static void getRAMsize_arch_nv4(void)
2852 {
2853 	uint32 strapinfo = ENG_RG32(RG32_NV4STRAPINFO);
2854 
2855 	if (strapinfo & 0x00000100)
2856 	{
2857 		/* Unified memory architecture used */
2858 		si->ps.memory_size = 1024 * 1024 *
2859 			((((strapinfo & 0x0000f000) >> 12) * 2) + 2);
2860 
2861 		LOG(8,("INFO: NV4 architecture chip with UMA detected\n"));
2862 	}
2863 	else
2864 	{
2865 		/* private memory architecture used */
2866 		switch (strapinfo & 0x00000003)
2867 		{
2868 		case 0:
2869 			si->ps.memory_size = 32 * 1024 * 1024;
2870 			break;
2871 		case 1:
2872 			si->ps.memory_size = 4 * 1024 * 1024;
2873 			break;
2874 		case 2:
2875 			si->ps.memory_size = 8 * 1024 * 1024;
2876 			break;
2877 		case 3:
2878 			si->ps.memory_size = 16 * 1024 * 1024;
2879 			break;
2880 		}
2881 	}
2882 }
2883 
2884 static void getstrap_arch_nv4(void)
2885 {
2886 	uint32 strapinfo = ENG_RG32(RG32_NVSTRAPINFO2);
2887 
2888 	/* determine PLL reference crystal frequency */
2889 	if (strapinfo & 0x00000040)
2890 		si->ps.f_ref = 14.31818;
2891 	else
2892 		si->ps.f_ref = 13.50000;
2893 
2894 	/* these cards are always singlehead */
2895 	si->ps.secondary_head = false;
2896 }
2897 
2898 static void getRAMsize_arch_nv10_20_30_40(void)
2899 {
2900 	uint32 dev_manID = CFGR(DEVID);
2901 	uint32 strapinfo = ENG_RG32(RG32_NV10STRAPINFO);
2902 
2903 	switch (dev_manID)
2904 	{
2905 	case 0x01a010de: /* Nvidia GeForce2 Integrated GPU */
2906 	case 0x01f010de: /* Nvidia GeForce4 MX Integrated GPU */
2907 		/* the kerneldriver already determined the amount of RAM these cards have at
2908 		 * their disposal (UMA, values read from PCI config space in other device) */
2909 		LOG(8,("INFO: nVidia GPU with UMA detected\n"));
2910 		break;
2911 	default:
2912 		LOG(8,("INFO: (Memory detection) Strapinfo value is: $%08x\n", strapinfo));
2913 
2914 		switch ((strapinfo & 0x1ff00000) >> 20)
2915 		{
2916 		case 2:
2917 			si->ps.memory_size = 2 * 1024 * 1024;
2918 			break;
2919 		case 4:
2920 			si->ps.memory_size = 4 * 1024 * 1024;
2921 			break;
2922 		case 8:
2923 			si->ps.memory_size = 8 * 1024 * 1024;
2924 			break;
2925 		case 16:
2926 			si->ps.memory_size = 16 * 1024 * 1024;
2927 			break;
2928 		case 32:
2929 			si->ps.memory_size = 32 * 1024 * 1024;
2930 			break;
2931 		case 64:
2932 			si->ps.memory_size = 64 * 1024 * 1024;
2933 			break;
2934 		case 128:
2935 			si->ps.memory_size = 128 * 1024 * 1024;
2936 			break;
2937 		case 256:
2938 			si->ps.memory_size = 256 * 1024 * 1024;
2939 			break;
2940 		default:
2941 			si->ps.memory_size = 16 * 1024 * 1024;
2942 
2943 			LOG(8,("INFO: NV10/20/30 architecture chip with unknown RAM amount detected;\n"));
2944 			LOG(8,("INFO: Setting 16Mb\n"));
2945 			break;
2946 		}
2947 	}
2948 }
2949 
2950 static void getstrap_arch_nv10_20_30_40(void)
2951 {
2952 	uint32 dev_manID = CFGR(DEVID);
2953 	uint32 strapinfo = ENG_RG32(RG32_NVSTRAPINFO2);
2954 
2955 	/* determine PLL reference crystal frequency: three types are used... */
2956 	if (strapinfo & 0x00000040)
2957 		si->ps.f_ref = 14.31818;
2958 	else
2959 		si->ps.f_ref = 13.50000;
2960 
2961 	switch (dev_manID & 0xfff0ffff)
2962 	{
2963 	/* Nvidia cards: */
2964 	case 0x004010de:
2965 	case 0x00c010de:
2966 	case 0x00f010de:
2967 	case 0x014010de:
2968 	case 0x017010de:
2969 	case 0x018010de:
2970 	case 0x01f010de:
2971 	case 0x025010de:
2972 	case 0x028010de:
2973 	case 0x030010de:
2974 	case 0x031010de:
2975 	case 0x032010de:
2976 	case 0x033010de:
2977 	case 0x034010de:
2978 	/* Varisys cards: */
2979 	case 0x35001888:
2980 		if (strapinfo & 0x00400000) si->ps.f_ref = 27.00000;
2981 		break;
2982 	default:
2983 		break;
2984 	}
2985 
2986 	/* determine if we have a dualhead card */
2987 	switch (dev_manID & 0xfff0ffff)
2988 	{
2989 	/* Nvidia cards: */
2990 	case 0x004010de:
2991 	case 0x00c010de:
2992 	case 0x00f010de:
2993 	case 0x011010de:
2994 	case 0x014010de:
2995 	case 0x017010de:
2996 	case 0x018010de:
2997 	case 0x01f010de:
2998 	case 0x025010de:
2999 	case 0x028010de:
3000 	case 0x030010de:
3001 	case 0x031010de:
3002 	case 0x032010de:
3003 	case 0x033010de:
3004 	case 0x034010de:
3005 	/* Varisys cards: */
3006 	case 0x35001888:
3007 		si->ps.secondary_head = true;
3008 		break;
3009 	default:
3010 		si->ps.secondary_head = false;
3011 		break;
3012 	}
3013 }
3014 
3015 void dump_pins(void)
3016 {
3017 	char *msg = "";
3018 
3019 	LOG(2,("INFO: pinsdump follows:\n"));
3020 	LOG(2,("PLL type: "));
3021 	if (si->ps.ext_pll) LOG(2,("extended\n")); else LOG(2,("standard\n"));
3022 	LOG(2,("f_ref: %fMhz\n", si->ps.f_ref));
3023 	LOG(2,("max_system_vco: %dMhz\n", si->ps.max_system_vco));
3024 	LOG(2,("min_system_vco: %dMhz\n", si->ps.min_system_vco));
3025 	LOG(2,("max_pixel_vco: %dMhz\n", si->ps.max_pixel_vco));
3026 	LOG(2,("min_pixel_vco: %dMhz\n", si->ps.min_pixel_vco));
3027 	LOG(2,("max_video_vco: %dMhz\n", si->ps.max_video_vco));
3028 	LOG(2,("min_video_vco: %dMhz\n", si->ps.min_video_vco));
3029 	LOG(2,("std_engine_clock: %dMhz\n", si->ps.std_engine_clock));
3030 	LOG(2,("std_memory_clock: %dMhz\n", si->ps.std_memory_clock));
3031 	LOG(2,("max_dac1_clock: %dMhz\n", si->ps.max_dac1_clock));
3032 	LOG(2,("max_dac1_clock_8: %dMhz\n", si->ps.max_dac1_clock_8));
3033 	LOG(2,("max_dac1_clock_16: %dMhz\n", si->ps.max_dac1_clock_16));
3034 	LOG(2,("max_dac1_clock_24: %dMhz\n", si->ps.max_dac1_clock_24));
3035 	LOG(2,("max_dac1_clock_32: %dMhz\n", si->ps.max_dac1_clock_32));
3036 	LOG(2,("max_dac1_clock_32dh: %dMhz\n", si->ps.max_dac1_clock_32dh));
3037 	LOG(2,("max_dac2_clock: %dMhz\n", si->ps.max_dac2_clock));
3038 	LOG(2,("max_dac2_clock_8: %dMhz\n", si->ps.max_dac2_clock_8));
3039 	LOG(2,("max_dac2_clock_16: %dMhz\n", si->ps.max_dac2_clock_16));
3040 	LOG(2,("max_dac2_clock_24: %dMhz\n", si->ps.max_dac2_clock_24));
3041 	LOG(2,("max_dac2_clock_32: %dMhz\n", si->ps.max_dac2_clock_32));
3042 	LOG(2,("max_dac2_clock_32dh: %dMhz\n", si->ps.max_dac2_clock_32dh));
3043 	LOG(2,("secondary_head: "));
3044 	if (si->ps.secondary_head) LOG(2,("present\n")); else LOG(2,("absent\n"));
3045 	LOG(2,("tvout: "));
3046 	if (si->ps.tvout) LOG(2,("present\n")); else LOG(2,("absent\n"));
3047 	/* setup TVout logmessage text */
3048 	switch (si->ps.tvout_chip_type)
3049 	{
3050 	case NONE:
3051 		msg = "No";
3052 		break;
3053 	case CH7003:
3054 		msg = "Chrontel CH7003";
3055 		break;
3056 	case CH7004:
3057 		msg = "Chrontel CH7004";
3058 		break;
3059 	case CH7005:
3060 		msg = "Chrontel CH7005";
3061 		break;
3062 	case CH7006:
3063 		msg = "Chrontel CH7006";
3064 		break;
3065 	case CH7007:
3066 		msg = "Chrontel CH7007";
3067 		break;
3068 	case CH7008:
3069 		msg = "Chrontel CH7008";
3070 		break;
3071 	case SAA7102:
3072 		msg = "Philips SAA7102";
3073 		break;
3074 	case SAA7103:
3075 		msg = "Philips SAA7103";
3076 		break;
3077 	case SAA7104:
3078 		msg = "Philips SAA7104";
3079 		break;
3080 	case SAA7105:
3081 		msg = "Philips SAA7105";
3082 		break;
3083 	case BT868:
3084 		msg = "Brooktree/Conexant BT868";
3085 		break;
3086 	case BT869:
3087 		msg = "Brooktree/Conexant BT869";
3088 		break;
3089 	case CX25870:
3090 		msg = "Conexant CX25870";
3091 		break;
3092 	case CX25871:
3093 		msg = "Conexant CX25871";
3094 		break;
3095 	case NVIDIA:
3096 		msg = "Nvidia internal";
3097 		break;
3098 	default:
3099 		msg = "Unknown";
3100 		break;
3101 	}
3102 	LOG(2, ("%s TVout chip detected\n", msg));
3103 //	LOG(2,("primary_dvi: "));
3104 //	if (si->ps.primary_dvi) LOG(2,("present\n")); else LOG(2,("absent\n"));
3105 //	LOG(2,("secondary_dvi: "));
3106 //	if (si->ps.secondary_dvi) LOG(2,("present\n")); else LOG(2,("absent\n"));
3107 	LOG(2,("card memory_size: %3.3fMb\n", (si->ps.memory_size / (1024.0 * 1024.0))));
3108 	LOG(2,("laptop: "));
3109 	if (si->ps.laptop) LOG(2,("yes\n")); else LOG(2,("no\n"));
3110 	if (si->ps.tmds1_active)
3111 	{
3112 		LOG(2,("found DFP (digital flatpanel) on CRTC1; CRTC1 is "));
3113 		if (si->ps.slaved_tmds1) LOG(2,("slaved\n")); else LOG(2,("master\n"));
3114 		LOG(2,("panel width: %d, height: %d, aspect ratio: %1.2f\n",
3115 			si->ps.p1_timing.h_display, si->ps.p1_timing.v_display, si->ps.panel1_aspect));
3116 	}
3117 	if (si->ps.tmds2_active)
3118 	{
3119 		LOG(2,("found DFP (digital flatpanel) on CRTC2; CRTC2 is "));
3120 		if (si->ps.slaved_tmds2) LOG(2,("slaved\n")); else LOG(2,("master\n"));
3121 		LOG(2,("panel width: %d, height: %d, aspect ratio: %1.2f\n",
3122 			si->ps.p2_timing.h_display, si->ps.p2_timing.v_display, si->ps.panel2_aspect));
3123 	}
3124 	LOG(2,("monitor (output devices) setup matrix: $%02x\n", si->ps.monitors));
3125 	LOG(2,("INFO: end pinsdump.\n"));
3126 }
3127