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