xref: /haiku/src/add-ons/accelerants/via/engine/info.c (revision 3ede6fca8a77d976ac3554cb7ba509f4cb31e5f9)
1 /* Read initialisation information from card */
2 /* some bits are hacks, where PINS is not known */
3 /* Author:
4    Rudolf Cornelissen 7/2003-7/2005
5 */
6 
7 #define MODULE_BIT 0x00002000
8 
9 #include "std.h"
10 
11 static void detect_panels(void);
12 static void setup_output_matrix(void);
13 static void pins_cle266_fake(void);
14 static void pinsnv5_nv5m64_fake(void);
15 static void pinsnv6_fake(void);
16 static void pinsnv10_arch_fake(void);
17 static void pinsnv20_arch_fake(void);
18 static void pinsnv30_arch_fake(void);
19 static void getRAMsize(void);
20 static void getstrap_arch_nv4(void);
21 static void getstrap_arch_nv10_20_30_40(void);
22 static status_t	eng_crtc_setup_fifo(void);
23 
24 /* Parse the BIOS PINS structure if there */
25 status_t parse_pins ()
26 {
27 	uint8 *rom;
28 	status_t result = B_ERROR;
29 
30 	/* preset PINS read status to failed */
31 	si->ps.pins_status = B_ERROR;
32 
33 	/* check the validity of PINS */
34 	LOG(2,("INFO: Reading PINS info\n"));
35 	rom = (uint8 *) si->rom_mirror;
36 	/* check BIOS signature - this is defined in the PCI standard */
37 	if (rom[0]!=0x55 || rom[1]!=0xaa)
38 	{
39 		LOG(8,("INFO: BIOS signature not found\n"));
40 		return B_ERROR;
41 	}
42 	LOG(2,("INFO: BIOS signature $AA55 found OK\n"));
43 
44 	/* find the PINS struct adress */
45 	//fixme...
46 
47 	/* check PINS read result */
48 	if (result == B_ERROR)
49 	{
50 		LOG(8,("INFO: PINS read/decode/execute error\n"));
51 		return B_ERROR;
52 	}
53 	/* PINS scan succeeded */
54 	si->ps.pins_status = B_OK;
55 	LOG(2,("INFO: PINS scan completed succesfully\n"));
56 	return B_OK;
57 }
58 
59 //fixme: move to crtc sourcefile, also setup for crtc2(?)
60 static status_t	eng_crtc_setup_fifo()
61 {
62 	/* enable access to primary head */
63 	set_crtc_owner(0);
64 
65 	//fixme: setup according to colordepth and RAM bus width...
66 	/* set CRTC FIFO burst size to 256 */
67 	CRTCW(FIFO, 0x03);
68 
69 	/* set CRTC FIFO low watermark to 32 */
70 	CRTCW(FIFO_LWM, 0x20);
71 
72 	return B_OK;
73 }
74 
75 /* (pre)set 'fixed' card specifications */
76 void set_specs(void)
77 {
78 	LOG(8,("INFO: setting up card specifications\n"));
79 
80 	/* set failsave speeds */
81 	switch (si->ps.card_type)
82 	{
83 	case CLE266:
84 		pins_cle266_fake();
85 		break;
86 	case NV05:
87 	case NV05M64:
88 		pinsnv5_nv5m64_fake();
89 		break;
90 	case NV06:
91 		pinsnv6_fake();
92 		break;
93 	default:
94 		switch (si->ps.card_arch)
95 		{
96 		case NV10A:
97 			pinsnv10_arch_fake();
98 			break;
99 		case NV20A:
100 			pinsnv20_arch_fake();
101 			break;
102 		case NV30A:
103 		case NV40A:
104 			pinsnv30_arch_fake();
105 			break;
106 		default:
107 			/* 'failsafe' values... */
108 			pinsnv10_arch_fake();
109 			break;
110 		}
111 		break;
112 	}
113 
114 	/* detect reference crystal frequency and dualhead */
115 	switch (si->ps.card_arch)
116 	{
117 	case NV04A:
118 		getstrap_arch_nv4();
119 		break;
120 	default:
121 		getstrap_arch_nv10_20_30_40();
122 		break;
123 	}
124 }
125 
126 /* this routine presumes the card was coldstarted by the card's BIOS for panel stuff */
127 void fake_panel_start(void)
128 {
129 	LOG(8,("INFO: detecting RAM size\n"));
130 
131 	/* detect RAM amount */
132 	getRAMsize();
133 
134 	/* override memory detection if requested by user */
135 	if (si->settings.memory != 0)
136 	{
137 		LOG(2,("INFO: forcing memory size (specified in settings file)\n"));
138 		si->ps.memory_size = si->settings.memory * 1024 * 1024;
139 	}
140 
141 	/* find out if the card has a tvout chip */
142 	si->ps.tvout = false;
143 	si->ps.tvout_chip_type = NONE;
144 //fixme ;-)
145 /*	if (i2c_maven_probe() == B_OK)
146 	{
147 		si->ps.tvout = true;
148 		si->ps.tvout_chip_bus = ???;
149 		si->ps.tvout_chip_type = ???;
150 	}
151 */
152 
153 	LOG(8,("INFO: faking panel startup\n"));
154 
155 	/* find out the BIOS preprogrammed panel use status... */
156 //	detect_panels();
157 
158 	/* determine and setup output devices and heads */
159 	setup_output_matrix();
160 
161 	/* select other CRTC for primary head use if specified by user in settings file */
162 	if (si->ps.secondary_head && si->settings.switchhead)
163 	{
164 		LOG(2,("INFO: inverting head use (specified in settings file)\n"));
165 		si->ps.crtc2_prim = !si->ps.crtc2_prim;
166 	}
167 }
168 
169 static void detect_panels()
170 {
171 	/* detect if the BIOS enabled LCD's (internal panels or DVI) or TVout */
172 
173 	/* both external TMDS transmitters (used for LCD/DVI) and external TVencoders
174 	 * (can) use the CRTC's in slaved mode. */
175 	/* Note:
176 	 * DFP's are programmed with standard VESA modelines by the card's BIOS! */
177 	bool slaved_for_dev1 = false, slaved_for_dev2 = false;
178 	bool tvout1 = false, tvout2 = false;
179 
180 	/* check primary head: */
181 	/* enable access to primary head */
182 	set_crtc_owner(0);
183 
184 	/* unlock head's registers for R/W access */
185 	CRTCW(LOCK, 0x57);
186 	CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f));
187 
188 	LOG(2,("INFO: Dumping flatpanel related CRTC registers:\n"));
189 	/* related info PIXEL register:
190 	 * b7: 1 = slaved mode										(all cards). */
191 	LOG(2,("CRTC1: PIXEL register: $%02x\n", CRTCR(PIXEL)));
192 	/* info LCD register:
193 	 * b7: 1 = stereo view (shutter glasses use)				(all cards),
194 	 * b5: 1 = power ext. TMDS (or something)/0 = TVout	use	(?)	(confirmed NV17, NV28),
195 	 * b4: 1 = power ext. TMDS (or something)/0 = TVout use	(?)	(confirmed NV34),
196 	 * b3: 1 = ??? (not panel related probably!)				(confirmed NV34),
197 	 * b1: 1 = power ext. TMDS (or something) (?)				(confirmed NV05?, NV17),
198 	 * b0: 1 = select panel encoder / 0 = select TVout encoder	(all cards). */
199 	LOG(2,("CRTC1: LCD register: $%02x\n", CRTCR(LCD)));
200 	/* info 0x59 register:
201 	 * b0: 1 = enable ext. TMDS clock (DPMS)					(confirmed NV28, NV34). */
202 	LOG(2,("CRTC1: register $59: $%02x\n", CRTCR(0x59)));
203 	/* info 0x9f register:
204 	 * b4: 0 = TVout use (?). */
205 	LOG(2,("CRTC1: register $9f: $%02x\n", CRTCR(0x9f)));
206 
207 	/* detect active slave device (if any) */
208 	slaved_for_dev1 = (CRTCR(PIXEL) & 0x80);
209 	if (slaved_for_dev1)
210 	{
211 		/* if the panel isn't selected, tvout is.. */
212 		tvout1 = !(CRTCR(LCD) & 0x01);
213 	}
214 
215 	if (si->ps.secondary_head)
216 	{
217 		/* check secondary head: */
218 		/* enable access to secondary head */
219 		set_crtc_owner(1);
220 		/* unlock head's registers for R/W access */
221 		CRTC2W(LOCK, 0x57);
222 		CRTC2W(VSYNCE ,(CRTC2R(VSYNCE) & 0x7f));
223 
224 		LOG(2,("CRTC2: PIXEL register: $%02x\n", CRTC2R(PIXEL)));
225 		LOG(2,("CRTC2: LCD register: $%02x\n", CRTC2R(LCD)));
226 		LOG(2,("CRTC2: register $59: $%02x\n", CRTC2R(0x59)));
227 		LOG(2,("CRTC2: register $9f: $%02x\n", CRTC2R(0x9f)));
228 
229 		/* detect active slave device (if any) */
230 		slaved_for_dev2 = (CRTC2R(PIXEL) & 0x80);
231 		if (slaved_for_dev2)
232 		{
233 			/* if the panel isn't selected, tvout is.. */
234 			tvout2 = !(CRTC2R(LCD) & 0x01);
235 		}
236 	}
237 
238 	LOG(2,("INFO: End flatpanel related CRTC registers dump.\n"));
239 
240 	/* do some presets */
241 	si->ps.p1_timing.h_display = 0;
242 	si->ps.p1_timing.v_display = 0;
243 	si->ps.panel1_aspect = 0;
244 	si->ps.p2_timing.h_display = 0;
245 	si->ps.p2_timing.v_display = 0;
246 	si->ps.panel2_aspect = 0;
247 	si->ps.slaved_tmds1 = false;
248 	si->ps.slaved_tmds2 = false;
249 	si->ps.master_tmds1 = false;
250 	si->ps.master_tmds2 = false;
251 	si->ps.tmds1_active = false;
252 	si->ps.tmds2_active = false;
253 	/* determine the situation we are in... (regarding flatpanels) */
254 	/* fixme: add VESA DDC EDID stuff one day... */
255 	/* fixme: find out how to program those transmitters one day instead of
256 	 * relying on the cards BIOS to do it. This adds TVout options where panels
257 	 * are used!
258 	 * Currently we'd loose the panel setup while not being able to restore it. */
259 
260 	/* note: (facts)
261 	 * -> NV11 and NV17 laptops have LVDS panels, programmed in both sets registers;
262 	 * -> NV34 laptops have TMDS panels, programmed in only one set of registers;
263 	 * -> NV11, NV25 and NV34 DVI cards, so external panels (TMDS) are programmed
264 	 *    in only one set of registers;
265 	 * -> a register-set's FP_TG_CTRL register, bit 31 tells you if a LVDS panel is
266 	 *    connected to the primary head (0), or to the secondary head (1) except
267 	 *    on some NV11's if this bit is '0' there;
268 	 * -> for LVDS panels both registersets are programmed identically by the card's
269 	 *    BIOSes;
270 	 * -> the programmed set of registers tells you where a TMDS (DVI) panel is
271 	 *    connected;
272 	 * -> On all cards a CRTC is used in slaved mode when a panel is connected,
273 	 *    except on NV11: here master mode is (might be?) detected. */
274 	/* note also:
275 	 * external TMDS encoders are only used for logic-level translation: it's
276 	 * modeline registers are not used. Instead the GPU's internal modeline registers
277 	 * are used. The external encoder is not connected to a I2C bus (confirmed NV34). */
278 	if (slaved_for_dev1 && !tvout1)
279 	{
280 		uint16 width = ((DACR(FP_HDISPEND) & 0x0000ffff) + 1);
281 		uint16 height = ((DACR(FP_VDISPEND) & 0x0000ffff) + 1);
282 		if ((width >= 640) && (height >= 480))
283 		{
284 			si->ps.slaved_tmds1 = true;
285 			si->ps.tmds1_active = true;
286 			si->ps.p1_timing.h_display = width;
287 			si->ps.p1_timing.v_display = height;
288 		}
289 	}
290 
291 	if (si->ps.secondary_head && slaved_for_dev2 && !tvout2)
292 	{
293 		uint16 width = ((DAC2R(FP_HDISPEND) & 0x0000ffff) + 1);
294 		uint16 height = ((DAC2R(FP_VDISPEND) & 0x0000ffff) + 1);
295 		if ((width >= 640) && (height >= 480))
296 		{
297 			si->ps.slaved_tmds2 = true;
298 			si->ps.tmds2_active = true;
299 			si->ps.p2_timing.h_display = width;
300 			si->ps.p2_timing.v_display = height;
301 		}
302 	}
303 
304 	if ((si->ps.card_type == NV11) &&
305 		!si->ps.slaved_tmds1 && !tvout1)
306 	{
307 		uint16 width = ((DACR(FP_HDISPEND) & 0x0000ffff) + 1);
308 		uint16 height = ((DACR(FP_VDISPEND) & 0x0000ffff) + 1);
309 		if ((width >= 640) && (height >= 480))
310 		{
311 			si->ps.master_tmds1 = true;
312 			si->ps.tmds1_active = true;
313 			si->ps.p1_timing.h_display = width;
314 			si->ps.p1_timing.v_display = height;
315 		}
316 	}
317 
318 	if ((si->ps.card_type == NV11) &&
319 		si->ps.secondary_head && !si->ps.slaved_tmds2 && !tvout2)
320 	{
321 		uint16 width = ((DAC2R(FP_HDISPEND) & 0x0000ffff) + 1);
322 		uint16 height = ((DAC2R(FP_VDISPEND) & 0x0000ffff) + 1);
323 		if ((width >= 640) && (height >= 480))
324 		{
325 			si->ps.master_tmds2 = true;
326 			si->ps.tmds2_active = true;
327 			si->ps.p2_timing.h_display = width;
328 			si->ps.p2_timing.v_display = height;
329 		}
330 	}
331 
332 	//fixme...:
333 	//we are assuming that no DVI is used as external monitor on laptops;
334 	//otherwise we probably get into trouble here if the checked specs match.
335 	if (si->ps.laptop && si->ps.tmds1_active && si->ps.tmds2_active &&
336 		((DACR(FP_TG_CTRL) & 0x80000000) == (DAC2R(FP_TG_CTRL) & 0x80000000)) &&
337 		(si->ps.p1_timing.h_display == si->ps.p2_timing.h_display) &&
338 		(si->ps.p1_timing.v_display == si->ps.p2_timing.v_display))
339 	{
340 		LOG(2,("INFO: correcting double detection of single panel!\n"));
341 
342 		if (si->ps.card_type == NV11)
343 		{
344 			/* LVDS panel is _always_ on CRTC2, so clear false primary detection */
345 			si->ps.slaved_tmds1 = false;
346 			si->ps.master_tmds1 = false;
347 			si->ps.tmds1_active = false;
348 			si->ps.p1_timing.h_display = 0;
349 			si->ps.p1_timing.v_display = 0;
350 		}
351 		else
352 		{
353 			if (DACR(FP_TG_CTRL) & 0x80000000)
354 			{
355 				/* LVDS panel is on CRTC2, so clear false primary detection */
356 				si->ps.slaved_tmds1 = false;
357 				si->ps.master_tmds1 = false;
358 				si->ps.tmds1_active = false;
359 				si->ps.p1_timing.h_display = 0;
360 				si->ps.p1_timing.v_display = 0;
361 			}
362 			else
363 			{
364 				/* LVDS panel is on CRTC1, so clear false secondary detection */
365 				si->ps.slaved_tmds2 = false;
366 				si->ps.master_tmds2 = false;
367 				si->ps.tmds2_active = false;
368 				si->ps.p2_timing.h_display = 0;
369 				si->ps.p2_timing.v_display = 0;
370 			}
371 		}
372 	}
373 
374 	/* fetch panel(s) modeline(s) */
375 	if (si->ps.tmds1_active)
376 	{
377 		/* determine panel aspect ratio */
378 		si->ps.panel1_aspect =
379 			(si->ps.p1_timing.h_display / ((float)si->ps.p1_timing.v_display));
380 		/* horizontal timing */
381 		si->ps.p1_timing.h_sync_start = (DACR(FP_HSYNC_S) & 0x0000ffff) + 1;
382 		si->ps.p1_timing.h_sync_end = (DACR(FP_HSYNC_E) & 0x0000ffff) + 1;
383 		si->ps.p1_timing.h_total = (DACR(FP_HTOTAL) & 0x0000ffff) + 1;
384 		/* vertical timing */
385 		si->ps.p1_timing.v_sync_start = (DACR(FP_VSYNC_S) & 0x0000ffff) + 1;
386 		si->ps.p1_timing.v_sync_end = (DACR(FP_VSYNC_E) & 0x0000ffff) + 1;
387 		si->ps.p1_timing.v_total = (DACR(FP_VTOTAL) & 0x0000ffff) + 1;
388 		/* sync polarity */
389 		si->ps.p1_timing.flags = 0;
390 		if (DACR(FP_TG_CTRL) & 0x00000001) si->ps.p1_timing.flags |= B_POSITIVE_VSYNC;
391 		if (DACR(FP_TG_CTRL) & 0x00000010) si->ps.p1_timing.flags |= B_POSITIVE_HSYNC;
392 		/* refreshrate:
393 		 * fix a DVI or laptop flatpanel to 60Hz refresh! */
394 		si->ps.p1_timing.pixel_clock =
395 			(si->ps.p1_timing.h_total * si->ps.p1_timing.v_total * 60) / 1000;
396 	}
397 	if (si->ps.tmds2_active)
398 	{
399 		/* determine panel aspect ratio */
400 		si->ps.panel2_aspect =
401 			(si->ps.p2_timing.h_display / ((float)si->ps.p2_timing.v_display));
402 		/* horizontal timing */
403 		si->ps.p2_timing.h_sync_start = (DAC2R(FP_HSYNC_S) & 0x0000ffff) + 1;
404 		si->ps.p2_timing.h_sync_end = (DAC2R(FP_HSYNC_E) & 0x0000ffff) + 1;
405 		si->ps.p2_timing.h_total = (DAC2R(FP_HTOTAL) & 0x0000ffff) + 1;
406 		/* vertical timing */
407 		si->ps.p2_timing.v_sync_start = (DAC2R(FP_VSYNC_S) & 0x0000ffff) + 1;
408 		si->ps.p2_timing.v_sync_end = (DAC2R(FP_VSYNC_E) & 0x0000ffff) + 1;
409 		si->ps.p2_timing.v_total = (DAC2R(FP_VTOTAL) & 0x0000ffff) + 1;
410 		/* sync polarity */
411 		si->ps.p2_timing.flags = 0;
412 		if (DAC2R(FP_TG_CTRL) & 0x00000001) si->ps.p2_timing.flags |= B_POSITIVE_VSYNC;
413 		if (DAC2R(FP_TG_CTRL) & 0x00000010) si->ps.p2_timing.flags |= B_POSITIVE_HSYNC;
414 		/* refreshrate:
415 		 * fix a DVI or laptop flatpanel to 60Hz refresh! */
416 		si->ps.p2_timing.pixel_clock =
417 			(si->ps.p2_timing.h_total * si->ps.p2_timing.v_total * 60) / 1000;
418 	}
419 
420 	/* dump some panel configuration registers... */
421 	LOG(2,("INFO: Dumping flatpanel registers:\n"));
422 	LOG(2,("DUALHEAD_CTRL: $%08x\n", ENG_REG32(RG32_DUALHEAD_CTRL)));
423 	LOG(2,("DAC1: FP_HDISPEND: %d\n", DACR(FP_HDISPEND)));
424 	LOG(2,("DAC1: FP_HTOTAL: %d\n", DACR(FP_HTOTAL)));
425 	LOG(2,("DAC1: FP_HCRTC: %d\n", DACR(FP_HCRTC)));
426 	LOG(2,("DAC1: FP_HSYNC_S: %d\n", DACR(FP_HSYNC_S)));
427 	LOG(2,("DAC1: FP_HSYNC_E: %d\n", DACR(FP_HSYNC_E)));
428 	LOG(2,("DAC1: FP_HVALID_S: %d\n", DACR(FP_HVALID_S)));
429 	LOG(2,("DAC1: FP_HVALID_E: %d\n", DACR(FP_HVALID_E)));
430 
431 	LOG(2,("DAC1: FP_VDISPEND: %d\n", DACR(FP_VDISPEND)));
432 	LOG(2,("DAC1: FP_VTOTAL: %d\n", DACR(FP_VTOTAL)));
433 	LOG(2,("DAC1: FP_VCRTC: %d\n", DACR(FP_VCRTC)));
434 	LOG(2,("DAC1: FP_VSYNC_S: %d\n", DACR(FP_VSYNC_S)));
435 	LOG(2,("DAC1: FP_VSYNC_E: %d\n", DACR(FP_VSYNC_E)));
436 	LOG(2,("DAC1: FP_VVALID_S: %d\n", DACR(FP_VVALID_S)));
437 	LOG(2,("DAC1: FP_VVALID_E: %d\n", DACR(FP_VVALID_E)));
438 
439 	LOG(2,("DAC1: FP_CHKSUM: $%08x = (dec) %d\n", DACR(FP_CHKSUM),DACR(FP_CHKSUM)));
440 	LOG(2,("DAC1: FP_TST_CTRL: $%08x\n", DACR(FP_TST_CTRL)));
441 	LOG(2,("DAC1: FP_TG_CTRL: $%08x\n", DACR(FP_TG_CTRL)));
442 	LOG(2,("DAC1: FP_DEBUG0: $%08x\n", DACR(FP_DEBUG0)));
443 	LOG(2,("DAC1: FP_DEBUG1: $%08x\n", DACR(FP_DEBUG1)));
444 	LOG(2,("DAC1: FP_DEBUG2: $%08x\n", DACR(FP_DEBUG2)));
445 	LOG(2,("DAC1: FP_DEBUG3: $%08x\n", DACR(FP_DEBUG3)));
446 
447 	LOG(2,("DAC1: FUNCSEL: $%08x\n", ENG_REG32(RG32_FUNCSEL)));
448 	LOG(2,("DAC1: PANEL_PWR: $%08x\n", ENG_REG32(RG32_PANEL_PWR)));
449 
450 	if(si->ps.secondary_head)
451 	{
452 		LOG(2,("DAC2: FP_HDISPEND: %d\n", DAC2R(FP_HDISPEND)));
453 		LOG(2,("DAC2: FP_HTOTAL: %d\n", DAC2R(FP_HTOTAL)));
454 		LOG(2,("DAC2: FP_HCRTC: %d\n", DAC2R(FP_HCRTC)));
455 		LOG(2,("DAC2: FP_HSYNC_S: %d\n", DAC2R(FP_HSYNC_S)));
456 		LOG(2,("DAC2: FP_HSYNC_E: %d\n", DAC2R(FP_HSYNC_E)));
457 		LOG(2,("DAC2: FP_HVALID_S:%d\n", DAC2R(FP_HVALID_S)));
458 		LOG(2,("DAC2: FP_HVALID_E: %d\n", DAC2R(FP_HVALID_E)));
459 
460 		LOG(2,("DAC2: FP_VDISPEND: %d\n", DAC2R(FP_VDISPEND)));
461 		LOG(2,("DAC2: FP_VTOTAL: %d\n", DAC2R(FP_VTOTAL)));
462 		LOG(2,("DAC2: FP_VCRTC: %d\n", DAC2R(FP_VCRTC)));
463 		LOG(2,("DAC2: FP_VSYNC_S: %d\n", DAC2R(FP_VSYNC_S)));
464 		LOG(2,("DAC2: FP_VSYNC_E: %d\n", DAC2R(FP_VSYNC_E)));
465 		LOG(2,("DAC2: FP_VVALID_S: %d\n", DAC2R(FP_VVALID_S)));
466 		LOG(2,("DAC2: FP_VVALID_E: %d\n", DAC2R(FP_VVALID_E)));
467 
468 		LOG(2,("DAC2: FP_CHKSUM: $%08x = (dec) %d\n", DAC2R(FP_CHKSUM),DAC2R(FP_CHKSUM)));
469 		LOG(2,("DAC2: FP_TST_CTRL: $%08x\n", DAC2R(FP_TST_CTRL)));
470 		LOG(2,("DAC2: FP_TG_CTRL: $%08x\n", DAC2R(FP_TG_CTRL)));
471 		LOG(2,("DAC2: FP_DEBUG0: $%08x\n", DAC2R(FP_DEBUG0)));
472 		LOG(2,("DAC2: FP_DEBUG1: $%08x\n", DAC2R(FP_DEBUG1)));
473 		LOG(2,("DAC2: FP_DEBUG2: $%08x\n", DAC2R(FP_DEBUG2)));
474 		LOG(2,("DAC2: FP_DEBUG3: $%08x\n", DAC2R(FP_DEBUG3)));
475 
476 		LOG(2,("DAC2: FUNCSEL: $%08x\n", ENG_REG32(RG32_2FUNCSEL)));
477 		LOG(2,("DAC2: PANEL_PWR: $%08x\n", ENG_REG32(RG32_2PANEL_PWR)));
478 	}
479 	LOG(2,("INFO: End flatpanel registers dump.\n"));
480 }
481 
482 static void setup_output_matrix()
483 {
484 	/* setup defaults: */
485 	/* no monitors (output devices) detected */
486 	si->ps.monitors = 0x00;
487 	/* head 1 will be the primary head */
488 	si->ps.crtc2_prim = false;
489 
490 	/* setup output devices and heads */
491 	if (0)//si->ps.secondary_head)
492 	{
493 		if (si->ps.card_type != NV11)
494 		{
495 			/* setup defaults: */
496 			/* connect analog outputs straight through */
497 			eng_general_output_select(false);
498 
499 			/* presetup by the card's BIOS, we can't change this (lack of info) */
500 			if (si->ps.tmds1_active) si->ps.monitors |= 0x01;
501 			if (si->ps.tmds2_active) si->ps.monitors |= 0x10;
502 			/* detect analog monitors (confirmed working OK on NV18, NV28 and NV34): */
503 			/* sense analog monitor on primary connector */
504 			if (eng_dac_crt_connected()) si->ps.monitors |= 0x02;
505 			/* sense analog monitor on secondary connector */
506 			if (eng_dac2_crt_connected()) si->ps.monitors |= 0x20;
507 
508 			/* setup correct output and head use */
509 			//fixme? add TVout (only, so no CRT(s) connected) support...
510 			switch (si->ps.monitors)
511 			{
512 			case 0x00: /* no monitor found at all */
513 				LOG(2,("INFO: head 1 has nothing connected;\n"));
514 				LOG(2,("INFO: head 2 has nothing connected:\n"));
515 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
516 				break;
517 			case 0x01: /* digital panel on head 1, nothing on head 2 */
518 				LOG(2,("INFO: head 1 has a digital panel;\n"));
519 				LOG(2,("INFO: head 2 has nothing connected:\n"));
520 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
521 				break;
522 			case 0x02: /* analog panel or CRT on head 1, nothing on head 2 */
523 				LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
524 				LOG(2,("INFO: head 2 has nothing connected:\n"));
525 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
526 				break;
527 			case 0x03: /* both types on head 1, nothing on head 2 */
528 				LOG(2,("INFO: head 1 has a digital panel AND an analog panel or CRT;\n"));
529 				LOG(2,("INFO: head 2 has nothing connected:\n"));
530 				LOG(2,("INFO: correcting...\n"));
531 				/* cross connect analog outputs so analog panel or CRT gets head 2 */
532 				eng_general_output_select(true);
533 				LOG(2,("INFO: head 1 has a digital panel;\n"));
534 				LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
535 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
536 				break;
537 			case 0x10: /* nothing on head 1, digital panel on head 2 */
538 				LOG(2,("INFO: head 1 has nothing connected;\n"));
539 				LOG(2,("INFO: head 2 has a digital panel:\n"));
540 				LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
541 				si->ps.crtc2_prim = true;
542 				break;
543 			case 0x20: /* nothing on head 1, analog panel or CRT on head 2 */
544 				LOG(2,("INFO: head 1 has nothing connected;\n"));
545 				LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
546 				LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
547 				si->ps.crtc2_prim = true;
548 				break;
549 			case 0x30: /* nothing on head 1, both types on head 2 */
550 				LOG(2,("INFO: head 1 has nothing connected;\n"));
551 				LOG(2,("INFO: head 2 has a digital panel AND an analog panel or CRT:\n"));
552 				LOG(2,("INFO: correcting...\n"));
553 				/* cross connect analog outputs so analog panel or CRT gets head 1 */
554 				eng_general_output_select(true);
555 				LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
556 				LOG(2,("INFO: head 2 has a digital panel:\n"));
557 				LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
558 				si->ps.crtc2_prim = true;
559 				break;
560 			case 0x11: /* digital panels on both heads */
561 				LOG(2,("INFO: head 1 has a digital panel;\n"));
562 				LOG(2,("INFO: head 2 has a digital panel:\n"));
563 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
564 				break;
565 			case 0x12: /* analog panel or CRT on head 1, digital panel on head 2 */
566 				LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
567 				LOG(2,("INFO: head 2 has a digital panel:\n"));
568 				LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
569 				si->ps.crtc2_prim = true;
570 				break;
571 			case 0x21: /* digital panel on head 1, analog panel or CRT on head 2 */
572 				LOG(2,("INFO: head 1 has a digital panel;\n"));
573 				LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
574 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
575 				break;
576 			case 0x22: /* analog panel(s) or CRT(s) on both heads */
577 				LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
578 				LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
579 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
580 				break;
581 			default: /* more than two monitors connected to just two outputs: illegal! */
582 				LOG(2,("INFO: illegal monitor setup ($%02x):\n", si->ps.monitors));
583 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
584 				break;
585 			}
586 		}
587 		else /* dualhead NV11 cards */
588 		{
589 			/* confirmed no analog output switch-options for NV11 */
590 			LOG(2,("INFO: NV11 outputs are hardwired to be straight-through\n"));
591 
592 			/* presetup by the card's BIOS, we can't change this (lack of info) */
593 			if (si->ps.tmds1_active) si->ps.monitors |= 0x01;
594 			if (si->ps.tmds2_active) si->ps.monitors |= 0x10;
595 			/* detect analog monitor (confirmed working OK on NV11): */
596 			/* sense analog monitor on primary connector */
597 			if (eng_dac_crt_connected()) si->ps.monitors |= 0x02;
598 			/* (sense analog monitor on secondary connector is impossible on NV11) */
599 
600 			/* setup correct output and head use */
601 			//fixme? add TVout (only, so no CRT(s) connected) support...
602 			switch (si->ps.monitors)
603 			{
604 			case 0x00: /* no monitor found at all */
605 				LOG(2,("INFO: head 1 has nothing connected;\n"));
606 				LOG(2,("INFO: head 2 has nothing connected:\n"));
607 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
608 				break;
609 			case 0x01: /* digital panel on head 1, nothing on head 2 */
610 				LOG(2,("INFO: head 1 has a digital panel;\n"));
611 				LOG(2,("INFO: head 2 has nothing connected:\n"));
612 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
613 				break;
614 			case 0x02: /* analog panel or CRT on head 1, nothing on head 2 */
615 				LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
616 				LOG(2,("INFO: head 2 has nothing connected:\n"));
617 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
618 				break;
619 			case 0x03: /* both types on head 1, nothing on head 2 */
620 				LOG(2,("INFO: head 1 has a digital panel AND an analog panel or CRT;\n"));
621 				LOG(2,("INFO: head 2 has nothing connected:\n"));
622 				LOG(2,("INFO: correction not possible...\n"));
623 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
624 				break;
625 			case 0x10: /* nothing on head 1, digital panel on head 2 */
626 				LOG(2,("INFO: head 1 has nothing connected;\n"));
627 				LOG(2,("INFO: head 2 has a digital panel:\n"));
628 				LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
629 				si->ps.crtc2_prim = true;
630 				break;
631 			case 0x11: /* digital panels on both heads */
632 				LOG(2,("INFO: head 1 has a digital panel;\n"));
633 				LOG(2,("INFO: head 2 has a digital panel:\n"));
634 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
635 				break;
636 			case 0x12: /* analog panel or CRT on head 1, digital panel on head 2 */
637 				LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
638 				LOG(2,("INFO: head 2 has a digital panel:\n"));
639 				LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
640 				si->ps.crtc2_prim = true;
641 				break;
642 			default: /* more than two monitors connected to just two outputs: illegal! */
643 				LOG(2,("INFO: illegal monitor setup ($%02x):\n", si->ps.monitors));
644 				LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
645 				break;
646 			}
647 		}
648 	}
649 	else /* singlehead cards */
650 	{
651 		/* presetup by the card's BIOS, we can't change this (lack of info) */
652 		if (si->ps.tmds1_active) si->ps.monitors |= 0x01;
653 		/* detect analog monitor (confirmed working OK on all cards): */
654 		/* sense analog monitor on primary connector */
655 		if (eng_dac_crt_connected()) si->ps.monitors |= 0x02;
656 
657 		//fixme? add TVout (only, so no CRT connected) support...
658 	}
659 }
660 
661 void get_panel_modes(display_mode *p1, display_mode *p2, bool *pan1, bool *pan2)
662 {
663 	if (si->ps.tmds1_active)
664 	{
665 		/* timing ('modeline') */
666 		p1->timing = si->ps.p1_timing;
667 		/* setup the rest */
668 		p1->space = B_CMAP8;
669 		p1->virtual_width = p1->timing.h_display;
670 		p1->virtual_height = p1->timing.v_display;
671 		p1->h_display_start = 0;
672 		p1->v_display_start = 0;
673 		p1->flags = 0;
674 		*pan1 = true;
675 	}
676 	else
677 		*pan1 = false;
678 
679 	if (si->ps.tmds2_active)
680 	{
681 		/* timing ('modeline') */
682 		p2->timing = si->ps.p2_timing;
683 		/* setup the rest */
684 		p2->space = B_CMAP8;
685 		p2->virtual_width = p2->timing.h_display;
686 		p2->virtual_height = p2->timing.v_display;
687 		p2->h_display_start = 0;
688 		p2->v_display_start = 0;
689 		p2->flags = 0;
690 		*pan2 = true;
691 	}
692 	else
693 		*pan2 = false;
694 }
695 
696 static void pins_cle266_fake(void)
697 {
698 	/* we have a standard PLL */
699 	si->ps.ext_pll = false;
700 	/* carefull not to take to high limits, and high should be >= 2x low. */
701 	si->ps.max_system_vco = 230;
702 	si->ps.min_system_vco = 20;
703 	si->ps.max_pixel_vco = 230;
704 	si->ps.min_pixel_vco = 20;
705 	si->ps.max_video_vco = 0;
706 	si->ps.min_video_vco = 0;
707 	si->ps.max_dac1_clock = 230;
708 	si->ps.max_dac1_clock_8 = 230;
709 	si->ps.max_dac1_clock_16 = 230;
710 	/* 'failsave' values */
711 	si->ps.max_dac1_clock_24 = 200;
712 	si->ps.max_dac1_clock_32 = 180;
713 	si->ps.max_dac1_clock_32dh = 180;
714 	/* secondary head */
715 	si->ps.max_dac2_clock = 0;
716 	si->ps.max_dac2_clock_8 = 0;
717 	si->ps.max_dac2_clock_16 = 0;
718 	si->ps.max_dac2_clock_24 = 0;
719 	si->ps.max_dac2_clock_32 = 0;
720 	/* 'failsave' values */
721 	si->ps.max_dac2_clock_32dh = 0;
722 	//fixme: primary & secondary_dvi should be overrule-able via skel.settings
723 	si->ps.primary_dvi = false;
724 	si->ps.secondary_dvi = false;
725 	/* not used (yet) because no coldstart will be attempted (yet) */
726 	si->ps.std_engine_clock = 90;
727 	si->ps.std_memory_clock = 110;
728 }
729 
730 static void pinsnv5_nv5m64_fake(void)
731 {
732 	/* we have a standard PLL */
733 	si->ps.ext_pll = false;
734 	/* carefull not to take to high limits, and high should be >= 2x low. */
735 	si->ps.max_system_vco = 300;
736 	si->ps.min_system_vco = 128;
737 	si->ps.max_pixel_vco = 300;
738 	si->ps.min_pixel_vco = 128;
739 	si->ps.max_video_vco = 0;
740 	si->ps.min_video_vco = 0;
741 	si->ps.max_dac1_clock = 300;
742 	si->ps.max_dac1_clock_8 = 300;
743 	si->ps.max_dac1_clock_16 = 300;
744 	/* 'failsave' values */
745 	si->ps.max_dac1_clock_24 = 270;
746 	si->ps.max_dac1_clock_32 = 230;
747 	si->ps.max_dac1_clock_32dh = 230;
748 	/* secondary head */
749 	si->ps.max_dac2_clock = 0;
750 	si->ps.max_dac2_clock_8 = 0;
751 	si->ps.max_dac2_clock_16 = 0;
752 	si->ps.max_dac2_clock_24 = 0;
753 	si->ps.max_dac2_clock_32 = 0;
754 	/* 'failsave' values */
755 	si->ps.max_dac2_clock_32dh = 0;
756 	//fixme: primary & secondary_dvi should be overrule-able via skel.settings
757 	si->ps.primary_dvi = false;
758 	si->ps.secondary_dvi = false;
759 	/* not used (yet) because no coldstart will be attempted (yet) */
760 	si->ps.std_engine_clock = 125;
761 	si->ps.std_memory_clock = 150;
762 }
763 
764 static void pinsnv6_fake(void)
765 {
766 	/* we have a standard PLL */
767 	si->ps.ext_pll = false;
768 	/* carefull not to take to high limits, and high should be >= 2x low. */
769 	si->ps.max_system_vco = 300;
770 	si->ps.min_system_vco = 128;
771 	si->ps.max_pixel_vco = 300;
772 	si->ps.min_pixel_vco = 128;
773 	si->ps.max_video_vco = 0;
774 	si->ps.min_video_vco = 0;
775 	si->ps.max_dac1_clock = 300;
776 	si->ps.max_dac1_clock_8 = 300;
777 	si->ps.max_dac1_clock_16 = 300;
778 	/* 'failsave' values */
779 	si->ps.max_dac1_clock_24 = 270;
780 	si->ps.max_dac1_clock_32 = 230;
781 	si->ps.max_dac1_clock_32dh = 230;
782 	/* secondary head */
783 	si->ps.max_dac2_clock = 0;
784 	si->ps.max_dac2_clock_8 = 0;
785 	si->ps.max_dac2_clock_16 = 0;
786 	si->ps.max_dac2_clock_24 = 0;
787 	si->ps.max_dac2_clock_32 = 0;
788 	/* 'failsave' values */
789 	si->ps.max_dac2_clock_32dh = 0;
790 	//fixme: primary & secondary_dvi should be overrule-able via skel.settings
791 	si->ps.primary_dvi = false;
792 	si->ps.secondary_dvi = false;
793 	/* not used (yet) because no coldstart will be attempted (yet) */
794 	si->ps.std_engine_clock = 100;
795 	si->ps.std_memory_clock = 125;
796 }
797 
798 static void pinsnv10_arch_fake(void)
799 {
800 	/* we have a standard PLL */
801 	si->ps.ext_pll = false;
802 	/* carefull not to take to high limits, and high should be >= 2x low. */
803 	si->ps.max_system_vco = 350;
804 	si->ps.min_system_vco = 128;
805 	si->ps.max_pixel_vco = 350;
806 	si->ps.min_pixel_vco = 128;
807 	si->ps.max_video_vco = 350;
808 	si->ps.min_video_vco = 128;
809 	si->ps.max_dac1_clock = 350;
810 	si->ps.max_dac1_clock_8 = 350;
811 	si->ps.max_dac1_clock_16 = 350;
812 	/* 'failsave' values */
813 	si->ps.max_dac1_clock_24 = 320;
814 	si->ps.max_dac1_clock_32 = 280;
815 	si->ps.max_dac1_clock_32dh = 250;
816 	/* secondary head */
817 	if (si->ps.card_type < NV17)
818 	{
819 		/* if a GeForce2 has analog VGA dualhead capability,
820 		 * it uses an external secondary DAC probably with limited capability. */
821 		/* (called twinview technology) */
822 		si->ps.max_dac2_clock = 200;
823 		si->ps.max_dac2_clock_8 = 200;
824 		si->ps.max_dac2_clock_16 = 200;
825 		si->ps.max_dac2_clock_24 = 200;
826 		si->ps.max_dac2_clock_32 = 200;
827 		/* 'failsave' values */
828 		si->ps.max_dac2_clock_32dh = 180;
829 	}
830 	else
831 	{
832 		/* GeForce4 cards have dual integrated DACs with identical capaability */
833 		/* (called nview technology) */
834 		si->ps.max_dac2_clock = 350;
835 		si->ps.max_dac2_clock_8 = 350;
836 		si->ps.max_dac2_clock_16 = 350;
837 		/* 'failsave' values */
838 		si->ps.max_dac2_clock_24 = 320;
839 		si->ps.max_dac2_clock_32 = 280;
840 		si->ps.max_dac2_clock_32dh = 250;
841 	}
842 	//fixme: primary & secondary_dvi should be overrule-able via skel.settings
843 	si->ps.primary_dvi = false;
844 	si->ps.secondary_dvi = false;
845 	/* not used (yet) because no coldstart will be attempted (yet) */
846 	si->ps.std_engine_clock = 120;
847 	si->ps.std_memory_clock = 150;
848 }
849 
850 static void pinsnv20_arch_fake(void)
851 {
852 	/* we have a standard PLL */
853 	si->ps.ext_pll = false;
854 	/* carefull not to take to high limits, and high should be >= 2x low. */
855 	si->ps.max_system_vco = 350;
856 	si->ps.min_system_vco = 128;
857 	si->ps.max_pixel_vco = 350;
858 	si->ps.min_pixel_vco = 128;
859 	si->ps.max_video_vco = 350;
860 	si->ps.min_video_vco = 128;
861 	si->ps.max_dac1_clock = 350;
862 	si->ps.max_dac1_clock_8 = 350;
863 	si->ps.max_dac1_clock_16 = 350;
864 	/* 'failsave' values */
865 	si->ps.max_dac1_clock_24 = 320;
866 	si->ps.max_dac1_clock_32 = 280;
867 	si->ps.max_dac1_clock_32dh = 250;
868 	/* secondary head */
869 	/* GeForce4 cards have dual integrated DACs with identical capaability */
870 	/* (called nview technology) */
871 	si->ps.max_dac2_clock = 350;
872 	si->ps.max_dac2_clock_8 = 350;
873 	si->ps.max_dac2_clock_16 = 350;
874 	/* 'failsave' values */
875 	si->ps.max_dac2_clock_24 = 320;
876 	si->ps.max_dac2_clock_32 = 280;
877 	si->ps.max_dac2_clock_32dh = 250;
878 	//fixme: primary & secondary_dvi should be overrule-able via skel.settings
879 	si->ps.primary_dvi = false;
880 	si->ps.secondary_dvi = false;
881 	/* not used (yet) because no coldstart will be attempted (yet) */
882 	si->ps.std_engine_clock = 175;
883 	si->ps.std_memory_clock = 200;
884 }
885 
886 static void pinsnv30_arch_fake(void)
887 {
888 	/* determine PLL type */
889 	LOG(8,("INFO: NV30 architecture chip, PIXPLLC2 DAC1 = $%08x, DAC2 = $%08x\n",
890 		DACR(PIXPLLC2), DAC2R(PIXPLLC2)));
891 	switch (si->ps.card_type)
892 	{
893 	case NV31:
894 	case NV36:
895 	case NV40:
896 		/* we have a extended PLL */
897 		si->ps.ext_pll = true;
898 		break;
899 	default:
900 		/* we have a standard PLL */
901 		si->ps.ext_pll = false;
902 		break;
903 	}
904 	/* carefull not to take to high limits, and high should be >= 2x low. */
905 	si->ps.max_system_vco = 350;
906 	si->ps.min_system_vco = 128;
907 	si->ps.max_pixel_vco = 350;
908 	si->ps.min_pixel_vco = 128;
909 	si->ps.max_video_vco = 350;
910 	si->ps.min_video_vco = 128;
911 	si->ps.max_dac1_clock = 350;
912 	si->ps.max_dac1_clock_8 = 350;
913 	si->ps.max_dac1_clock_16 = 350;
914 	/* 'failsave' values */
915 	si->ps.max_dac1_clock_24 = 320;
916 	si->ps.max_dac1_clock_32 = 280;
917 	si->ps.max_dac1_clock_32dh = 250;
918 	/* secondary head */
919 	/* GeForceFX cards have dual integrated DACs with identical capaability */
920 	/* (called nview technology) */
921 	si->ps.max_dac2_clock = 350;
922 	si->ps.max_dac2_clock_8 = 350;
923 	si->ps.max_dac2_clock_16 = 350;
924 	/* 'failsave' values */
925 	si->ps.max_dac2_clock_24 = 320;
926 	si->ps.max_dac2_clock_32 = 280;
927 	si->ps.max_dac2_clock_32dh = 250;
928 	//fixme: primary & secondary_dvi should be overrule-able via skel.settings
929 	si->ps.primary_dvi = false;
930 	si->ps.secondary_dvi = false;
931 	/* not used (yet) because no coldstart will be attempted (yet) */
932 	si->ps.std_engine_clock = 190;
933 	si->ps.std_memory_clock = 190;
934 }
935 
936 static void getRAMsize(void)
937 {
938 	uint8 ram_size = 0;
939 
940 	if (si->ps.card_type == CLE266)
941 	{
942 		ram_size = SEQR(MSIZE_CLE266);
943 	}
944 	else
945 	{
946 		ram_size = SEQR(MSIZE_OTHER);
947 	}
948 
949 	if ((ram_size > 16) && (ram_size <= 128))
950 	{
951 		/* 9.0 - 64.5Mb in 0.5Mb steps */
952 		si->ps.memory_size = (ram_size + 1) * 512 * 1024;
953 	}
954 	else
955 	{
956 		if ((ram_size > 0) && (ram_size <= 16))
957 		{
958 			/* 4 - 64Mb in 4Mb steps */
959 			si->ps.memory_size = ram_size * 4 * 1024 * 1024;
960 		}
961 		else
962 		{
963 			LOG(8,("INFO: unable to detect RAMsize (read $%02x), assuming 16Mb\n"));
964 			si->ps.memory_size = 16 * 1024 * 1024;
965 		}
966 	}
967 }
968 
969 static void getstrap_arch_nv4(void)
970 {
971 	uint32 strapinfo = ENG_REG32(RG32_NVSTRAPINFO2);
972 
973 	/* determine PLL reference crystal frequency */
974 	if (strapinfo & 0x00000040)
975 		si->ps.f_ref = 14.31818;
976 	else
977 		si->ps.f_ref = 13.50000;
978 
979 	/* these cards are always singlehead */
980 	si->ps.secondary_head = false;
981 }
982 
983 static void getstrap_arch_nv10_20_30_40(void)
984 {
985 	uint32 dev_manID = CFGR(DEVID);
986 	uint32 strapinfo = ENG_REG32(RG32_NVSTRAPINFO2);
987 
988 	/* determine PLL reference crystal frequency: three types are used... */
989 	if (strapinfo & 0x00000040)
990 		si->ps.f_ref = 14.31818;
991 	else
992 		si->ps.f_ref = 13.50000;
993 
994 	switch (dev_manID & 0xfff0ffff)
995 	{
996 	/* Nvidia cards: */
997 	case 0x004010de:
998 	case 0x00c010de:
999 	case 0x00f010de:
1000 	case 0x014010de:
1001 	case 0x017010de:
1002 	case 0x018010de:
1003 	case 0x01f010de:
1004 	case 0x025010de:
1005 	case 0x028010de:
1006 	case 0x030010de:
1007 	case 0x031010de:
1008 	case 0x032010de:
1009 	case 0x033010de:
1010 	case 0x034010de:
1011 	/* Varisys cards: */
1012 	case 0x35001888:
1013 		if (strapinfo & 0x00400000) si->ps.f_ref = 27.00000;
1014 		break;
1015 	default:
1016 		break;
1017 	}
1018 
1019 	/* determine if we have a dualhead card */
1020 	switch (dev_manID & 0xfff0ffff)
1021 	{
1022 	/* Nvidia cards: */
1023 	case 0x004010de:
1024 	case 0x00c010de:
1025 	case 0x00f010de:
1026 	case 0x011010de:
1027 	case 0x014010de:
1028 	case 0x017010de:
1029 	case 0x018010de:
1030 	case 0x01f010de:
1031 	case 0x025010de:
1032 	case 0x028010de:
1033 	case 0x030010de:
1034 	case 0x031010de:
1035 	case 0x032010de:
1036 	case 0x033010de:
1037 	case 0x034010de:
1038 	/* Varisys cards: */
1039 	case 0x35001888:
1040 		si->ps.secondary_head = true;
1041 		break;
1042 	default:
1043 		si->ps.secondary_head = false;
1044 		break;
1045 	}
1046 }
1047 
1048 void dump_pins(void)
1049 {
1050 	char *msg = "";
1051 
1052 	LOG(2,("INFO: pinsdump follows:\n"));
1053 	LOG(2,("PLL type: "));
1054 	if (si->ps.ext_pll) LOG(2,("extended\n")); else LOG(2,("standard\n"));
1055 	LOG(2,("f_ref: %fMhz\n", si->ps.f_ref));
1056 	LOG(2,("max_system_vco: %dMhz\n", si->ps.max_system_vco));
1057 	LOG(2,("min_system_vco: %dMhz\n", si->ps.min_system_vco));
1058 	LOG(2,("max_pixel_vco: %dMhz\n", si->ps.max_pixel_vco));
1059 	LOG(2,("min_pixel_vco: %dMhz\n", si->ps.min_pixel_vco));
1060 	LOG(2,("max_video_vco: %dMhz\n", si->ps.max_video_vco));
1061 	LOG(2,("min_video_vco: %dMhz\n", si->ps.min_video_vco));
1062 	LOG(2,("std_engine_clock: %dMhz\n", si->ps.std_engine_clock));
1063 	LOG(2,("std_memory_clock: %dMhz\n", si->ps.std_memory_clock));
1064 	LOG(2,("max_dac1_clock: %dMhz\n", si->ps.max_dac1_clock));
1065 	LOG(2,("max_dac1_clock_8: %dMhz\n", si->ps.max_dac1_clock_8));
1066 	LOG(2,("max_dac1_clock_16: %dMhz\n", si->ps.max_dac1_clock_16));
1067 	LOG(2,("max_dac1_clock_24: %dMhz\n", si->ps.max_dac1_clock_24));
1068 	LOG(2,("max_dac1_clock_32: %dMhz\n", si->ps.max_dac1_clock_32));
1069 	LOG(2,("max_dac1_clock_32dh: %dMhz\n", si->ps.max_dac1_clock_32dh));
1070 	LOG(2,("max_dac2_clock: %dMhz\n", si->ps.max_dac2_clock));
1071 	LOG(2,("max_dac2_clock_8: %dMhz\n", si->ps.max_dac2_clock_8));
1072 	LOG(2,("max_dac2_clock_16: %dMhz\n", si->ps.max_dac2_clock_16));
1073 	LOG(2,("max_dac2_clock_24: %dMhz\n", si->ps.max_dac2_clock_24));
1074 	LOG(2,("max_dac2_clock_32: %dMhz\n", si->ps.max_dac2_clock_32));
1075 	LOG(2,("max_dac2_clock_32dh: %dMhz\n", si->ps.max_dac2_clock_32dh));
1076 	LOG(2,("secondary_head: "));
1077 	if (si->ps.secondary_head) LOG(2,("present\n")); else LOG(2,("absent\n"));
1078 	LOG(2,("tvout: "));
1079 	if (si->ps.tvout) LOG(2,("present\n")); else LOG(2,("absent\n"));
1080 	/* setup TVout logmessage text */
1081 	switch (si->ps.tvout_chip_type)
1082 	{
1083 	case NONE:
1084 		msg = "No";
1085 		break;
1086 	case CH7003:
1087 		msg = "Chrontel CH7003";
1088 		break;
1089 	case CH7004:
1090 		msg = "Chrontel CH7004";
1091 		break;
1092 	case CH7005:
1093 		msg = "Chrontel CH7005";
1094 		break;
1095 	case CH7006:
1096 		msg = "Chrontel CH7006";
1097 		break;
1098 	case CH7007:
1099 		msg = "Chrontel CH7007";
1100 		break;
1101 	case CH7008:
1102 		msg = "Chrontel CH7008";
1103 		break;
1104 	case SAA7102:
1105 		msg = "Philips SAA7102";
1106 		break;
1107 	case SAA7103:
1108 		msg = "Philips SAA7103";
1109 		break;
1110 	case SAA7104:
1111 		msg = "Philips SAA7104";
1112 		break;
1113 	case SAA7105:
1114 		msg = "Philips SAA7105";
1115 		break;
1116 	case BT868:
1117 		msg = "Brooktree/Conexant BT868";
1118 		break;
1119 	case BT869:
1120 		msg = "Brooktree/Conexant BT869";
1121 		break;
1122 	case CX25870:
1123 		msg = "Conexant CX25870";
1124 		break;
1125 	case CX25871:
1126 		msg = "Conexant CX25871";
1127 		break;
1128 	case NVIDIA:
1129 		msg = "Nvidia internal";
1130 		break;
1131 	default:
1132 		msg = "Unknown";
1133 		break;
1134 	}
1135 	LOG(2, ("%s TVout chip detected\n", msg));
1136 //	LOG(2,("primary_dvi: "));
1137 //	if (si->ps.primary_dvi) LOG(2,("present\n")); else LOG(2,("absent\n"));
1138 //	LOG(2,("secondary_dvi: "));
1139 //	if (si->ps.secondary_dvi) LOG(2,("present\n")); else LOG(2,("absent\n"));
1140 	LOG(2,("card memory_size: %3.3fMb\n", (si->ps.memory_size / (1024.0 * 1024.0))));
1141 	LOG(2,("laptop: "));
1142 	if (si->ps.laptop) LOG(2,("yes\n")); else LOG(2,("no\n"));
1143 	if (si->ps.tmds1_active)
1144 	{
1145 		LOG(2,("found DFP (digital flatpanel) on CRTC1; CRTC1 is "));
1146 		if (si->ps.slaved_tmds1) LOG(2,("slaved\n")); else LOG(2,("master\n"));
1147 		LOG(2,("panel width: %d, height: %d, aspect ratio: %1.2f\n",
1148 			si->ps.p1_timing.h_display, si->ps.p1_timing.v_display, si->ps.panel1_aspect));
1149 	}
1150 	if (si->ps.tmds2_active)
1151 	{
1152 		LOG(2,("found DFP (digital flatpanel) on CRTC2; CRTC2 is "));
1153 		if (si->ps.slaved_tmds2) LOG(2,("slaved\n")); else LOG(2,("master\n"));
1154 		LOG(2,("panel width: %d, height: %d, aspect ratio: %1.2f\n",
1155 			si->ps.p2_timing.h_display, si->ps.p2_timing.v_display, si->ps.panel2_aspect));
1156 	}
1157 	LOG(2,("monitor (output devices) setup matrix: $%02x\n", si->ps.monitors));
1158 	LOG(2,("INFO: end pinsdump.\n"));
1159 }
1160