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