xref: /haiku/src/add-ons/accelerants/nvidia/engine/nv_info.c (revision 9eb55bc1d104b8fda80898f8b25c94d8000c8255)
1 /* Read initialisation information from card */
2 /* some bits are hacks, where PINS is not known */
3 /* Author:
4    Rudolf Cornelissen 7/2003-1/2004
5 */
6 
7 #define MODULE_BIT 0x00002000
8 
9 #include "nv_std.h"
10 
11 static void pinsnv4_fake(void);
12 static void pinsnv5_nv5m64_fake(void);
13 static void pinsnv6_fake(void);
14 static void pinsnv10_arch_fake(void);
15 static void pinsnv20_arch_fake(void);
16 static void pinsnv30_arch_fake(void);
17 static void getstrap_arch_nv4(void);
18 static void getstrap_arch_nv10_20_30(void);
19 static status_t pins5_read(uint8 *pins, uint8 length);
20 
21 /* Parse the BIOS PINS structure if there */
22 status_t parse_pins ()
23 {
24 	uint8 pins_len = 0;
25 	uint8 *rom;
26 	uint8 *pins;
27 	uint8 chksum = 0;
28 	int i;
29 	status_t result = B_ERROR;
30 
31 	/* preset PINS read status to failed */
32 	si->ps.pins_status = B_ERROR;
33 
34 	/* check the validity of PINS */
35 	LOG(2,("INFO: Reading PINS info\n"));
36 	rom = (uint8 *) si->rom_mirror;
37 	/* check BIOS signature */
38 	if (rom[0]!=0x55 || rom[1]!=0xaa)
39 	{
40 		LOG(8,("INFO: BIOS signiture not found\n"));
41 		return B_ERROR;
42 	}
43 	LOG(2,("INFO: BIOS signiture $AA55 found OK\n"));
44 	/* check for a valid PINS struct adress */
45 	pins = rom + (rom[0x7FFC]|(rom[0x7FFD]<<8));
46 	if ((pins - rom) > 0x7F80)
47 	{
48 		LOG(8,("INFO: invalid PINS adress\n"));
49 		return B_ERROR;
50 	}
51 	/* checkout new PINS struct version if there */
52 	if ((pins[0] == 0x2E) && (pins[1] == 0x41))
53 	{
54 		pins_len = pins[2];
55 		if (pins_len < 3 || pins_len > 128)
56 		{
57 			LOG(8,("INFO: invalid PINS size\n"));
58 			return B_ERROR;
59 		}
60 
61 		/* calculate PINS checksum */
62 		for (i = 0; i < pins_len; i++)
63 		{
64 			chksum += pins[i];
65 		}
66 		if (chksum)
67 		{
68 			LOG(8,("INFO: PINS checksum error\n"));
69 			return B_ERROR;
70 		}
71 		LOG(2,("INFO: new PINS, version %u.%u, length %u\n", pins[5], pins[4], pins[2]));
72 		/* fill out the si->ps struct if possible */
73 		switch (pins[5])
74 		{
75 			case 5:
76 				result = pins5_read(pins, pins_len);
77 				break;
78 			default:
79 				LOG(8,("INFO: unknown PINS version\n"));
80 				return B_ERROR;
81 				break;
82 		}
83 	}
84 	/* no valid PINS signature found */
85 	else
86 	{
87 		LOG(8,("INFO: no PINS signature found\n"));
88 		return B_ERROR;
89 	}
90 	/* check PINS read result */
91 	if (result == B_ERROR)
92 	{
93 		LOG(8,("INFO: PINS read/decode error\n"));
94 		return B_ERROR;
95 	}
96 	/* PINS scan succeeded */
97 	si->ps.pins_status = B_OK;
98 	LOG(2,("INFO: PINS scan completed succesfully\n"));
99 	return B_OK;
100 }
101 
102 /* pins v5 is used by G450 and G550 */
103 static status_t pins5_read(uint8 *pins, uint8 length)
104 {
105 	unsigned int m_factor = 6;
106 
107 	if (length != 128)
108 	{
109 		LOG(8,("INFO: wrong PINS length, expected 128, got %d\n", length));
110 		return B_ERROR;
111 	}
112 
113 	/* fill out the shared info si->ps struct */
114 	if (pins[4] == 0x01) m_factor = 8;
115 	if (pins[4] >= 0x02) m_factor = 10;
116 
117 	si->ps.max_system_vco = m_factor * pins[36];
118 	si->ps.max_video_vco = m_factor * pins[37];
119 	si->ps.max_pixel_vco = m_factor * pins[38];
120 	si->ps.min_system_vco = m_factor * pins[121];
121 	si->ps.min_video_vco = m_factor * pins[122];
122 	si->ps.min_pixel_vco = m_factor * pins[123];
123 
124 	if (pins[39] == 0xff) si->ps.max_dac1_clock_8 = si->ps.max_pixel_vco;
125 	else si->ps.max_dac1_clock_8 = 4 * pins[39];
126 
127 	if (pins[40] == 0xff) si->ps.max_dac1_clock_16 = si->ps.max_dac1_clock_8;
128 	else si->ps.max_dac1_clock_16 = 4 * pins[40];
129 
130 	if (pins[41] == 0xff) si->ps.max_dac1_clock_24 = si->ps.max_dac1_clock_16;
131 	else si->ps.max_dac1_clock_24 = 4 * pins[41];
132 
133 	if (pins[42] == 0xff) si->ps.max_dac1_clock_32 = si->ps.max_dac1_clock_24;
134 	else si->ps.max_dac1_clock_32 = 4 * pins[42];
135 
136 	if (pins[124] == 0xff) si->ps.max_dac1_clock_32dh = si->ps.max_dac1_clock_32;
137 	else si->ps.max_dac1_clock_32dh = 4 * pins[124];
138 
139 	if (pins[43] == 0xff) si->ps.max_dac2_clock_16 = si->ps.max_video_vco;
140 	else si->ps.max_dac2_clock_16 = 4 * pins[43];
141 
142 	if (pins[44] == 0xff) si->ps.max_dac2_clock_32 = si->ps.max_dac2_clock_16;
143 	else si->ps.max_dac2_clock_32 = 4 * pins[44];
144 
145 	if (pins[125] == 0xff) si->ps.max_dac2_clock_32dh = si->ps.max_dac2_clock_32;
146 	else si->ps.max_dac2_clock_32dh = 4 * pins[125];
147 
148 	if (pins[118] == 0xff) si->ps.max_dac1_clock = si->ps.max_dac1_clock_8;
149 	else si->ps.max_dac1_clock = 4 * pins[118];
150 
151 	if (pins[119] == 0xff) si->ps.max_dac2_clock = si->ps.max_dac1_clock;
152 	else si->ps.max_dac2_clock = 4 * pins[119];
153 
154 	si->ps.std_engine_clock = 4 * pins[74];
155 	si->ps.std_memory_clock = 4 * pins[92];
156 
157 	si->ps.memory_size = ((pins[114] & 0x03) + 1) * 8;
158 	if ((pins[114] & 0x07) > 3)
159 	{
160 		LOG(8,("INFO: unknown RAM size, defaulting to 8Mb\n"));
161 		si->ps.memory_size = 8;
162 	}
163 
164 	if (pins[110] & 0x01) si->ps.f_ref = 14.31818;
165 	else si->ps.f_ref = 27.00000;
166 
167 	/* make sure SGRAM functions only get enabled if SGRAM mounted */
168 	if ((pins[114] & 0x18) == 0x08) si->ps.sdram = false;
169 	else si->ps.sdram = true;
170 
171 	/* various registers */
172 	si->ps.secondary_head = (pins[117] & 0x70);
173 	si->ps.tvout = (pins[117] & 0x40);
174 	si->ps.primary_dvi = (pins[117] & 0x02);
175 	si->ps.secondary_dvi = (pins[117] & 0x20);
176 
177 	/* not supported: */
178 	si->ps.max_dac2_clock_8 = 0;
179 	si->ps.max_dac2_clock_24 = 0;
180 
181 	return B_OK;
182 }
183 
184 /* fake_pins presumes the card was coldstarted by it's BIOS */
185 void fake_pins(void)
186 {
187 	LOG(8,("INFO: faking PINS\n"));
188 
189 	/* set failsave speeds */
190 	switch (si->ps.card_type)
191 	{
192 	case NV04:
193 		pinsnv4_fake();
194 		break;
195 	case NV05:
196 	case NV05M64:
197 		pinsnv5_nv5m64_fake();
198 		break;
199 	case NV06:
200 		pinsnv6_fake();
201 		break;
202 	default:
203 		switch (si->ps.card_arch)
204 		{
205 		case NV10A:
206 			pinsnv10_arch_fake();
207 			break;
208 		case NV20A:
209 			pinsnv20_arch_fake();
210 			break;
211 		case NV30A:
212 			pinsnv30_arch_fake();
213 			break;
214 		default:
215 			/* 'failsafe' values... */
216 			pinsnv10_arch_fake();
217 			break;
218 		}
219 		break;
220 	}
221 
222 	/* detect RAM amount, reference crystal frequency and dualhead */
223 	switch (si->ps.card_arch)
224 	{
225 	case NV04A:
226 		getstrap_arch_nv4();
227 		break;
228 	default:
229 		getstrap_arch_nv10_20_30();
230 		break;
231 	}
232 
233 	/* find out if the card has a tvout chip */
234 	si->ps.tvout = false;
235 	si->ps.tvout_chip_type = NONE;
236 //fixme ;-)
237 /*	if (i2c_maven_probe() == B_OK)
238 	{
239 		si->ps.tvout = true;
240 		si->ps.tvout_chip_bus = ???;
241 		si->ps.tvout_chip_type = ???;
242 	}
243 */
244 }
245 
246 static void pinsnv4_fake(void)
247 {
248 	/* carefull not to take to high limits, and high should be >= 2x low. */
249 	si->ps.max_system_vco = 256;
250 	si->ps.min_system_vco = 128;
251 	si->ps.max_pixel_vco = 256;
252 	si->ps.min_pixel_vco = 128;
253 	si->ps.max_video_vco = 0;
254 	si->ps.min_video_vco = 0;
255 	si->ps.max_dac1_clock = 250;
256 	si->ps.max_dac1_clock_8 = 250;
257 	si->ps.max_dac1_clock_16 = 250;
258 	/* 'failsave' values */
259 	si->ps.max_dac1_clock_24 = 220;
260 	si->ps.max_dac1_clock_32 = 180;
261 	si->ps.max_dac1_clock_32dh = 180;
262 	/* secondary head */
263 	si->ps.max_dac2_clock = 0;
264 	si->ps.max_dac2_clock_8 = 0;
265 	si->ps.max_dac2_clock_16 = 0;
266 	si->ps.max_dac2_clock_24 = 0;
267 	si->ps.max_dac2_clock_32 = 0;
268 	/* 'failsave' values */
269 	si->ps.max_dac2_clock_32dh = 0;
270 	//fixme: primary & secondary_dvi should be overrule-able via nv.settings
271 	si->ps.primary_dvi = false;
272 	si->ps.secondary_dvi = false;
273 //fixme: is this needed for nv acc?
274 //fail-safe mode for now:
275 	si->ps.sdram = true;
276 
277 	/* not used (yet) because no coldstart will be attempted (yet) */
278 	si->ps.std_engine_clock = 90;
279 	si->ps.std_memory_clock = 110;
280 }
281 
282 static void pinsnv5_nv5m64_fake(void)
283 {
284 	/* carefull not to take to high limits, and high should be >= 2x low. */
285 	si->ps.max_system_vco = 300;
286 	si->ps.min_system_vco = 128;
287 	si->ps.max_pixel_vco = 300;
288 	si->ps.min_pixel_vco = 128;
289 	si->ps.max_video_vco = 0;
290 	si->ps.min_video_vco = 0;
291 	si->ps.max_dac1_clock = 300;
292 	si->ps.max_dac1_clock_8 = 300;
293 	si->ps.max_dac1_clock_16 = 300;
294 	/* 'failsave' values */
295 	si->ps.max_dac1_clock_24 = 270;
296 	si->ps.max_dac1_clock_32 = 230;
297 	si->ps.max_dac1_clock_32dh = 230;
298 	/* secondary head */
299 	si->ps.max_dac2_clock = 0;
300 	si->ps.max_dac2_clock_8 = 0;
301 	si->ps.max_dac2_clock_16 = 0;
302 	si->ps.max_dac2_clock_24 = 0;
303 	si->ps.max_dac2_clock_32 = 0;
304 	/* 'failsave' values */
305 	si->ps.max_dac2_clock_32dh = 0;
306 	//fixme: primary & secondary_dvi should be overrule-able via nv.settings
307 	si->ps.primary_dvi = false;
308 	si->ps.secondary_dvi = false;
309 //fixme: is this needed for nv acc?
310 //fail-safe mode for now:
311 	si->ps.sdram = true;
312 
313 	/* not used (yet) because no coldstart will be attempted (yet) */
314 	si->ps.std_engine_clock = 125;
315 	si->ps.std_memory_clock = 150;
316 }
317 
318 static void pinsnv6_fake(void)
319 {
320 	/* carefull not to take to high limits, and high should be >= 2x low. */
321 	si->ps.max_system_vco = 300;
322 	si->ps.min_system_vco = 128;
323 	si->ps.max_pixel_vco = 300;
324 	si->ps.min_pixel_vco = 128;
325 	si->ps.max_video_vco = 0;
326 	si->ps.min_video_vco = 0;
327 	si->ps.max_dac1_clock = 300;
328 	si->ps.max_dac1_clock_8 = 300;
329 	si->ps.max_dac1_clock_16 = 300;
330 	/* 'failsave' values */
331 	si->ps.max_dac1_clock_24 = 270;
332 	si->ps.max_dac1_clock_32 = 230;
333 	si->ps.max_dac1_clock_32dh = 230;
334 	/* secondary head */
335 	si->ps.max_dac2_clock = 0;
336 	si->ps.max_dac2_clock_8 = 0;
337 	si->ps.max_dac2_clock_16 = 0;
338 	si->ps.max_dac2_clock_24 = 0;
339 	si->ps.max_dac2_clock_32 = 0;
340 	/* 'failsave' values */
341 	si->ps.max_dac2_clock_32dh = 0;
342 	//fixme: primary & secondary_dvi should be overrule-able via nv.settings
343 	si->ps.primary_dvi = false;
344 	si->ps.secondary_dvi = false;
345 //fixme: is this needed for nv acc?
346 //fail-safe mode for now:
347 	si->ps.sdram = true;
348 
349 	/* not used (yet) because no coldstart will be attempted (yet) */
350 	si->ps.std_engine_clock = 100;
351 	si->ps.std_memory_clock = 125;
352 }
353 
354 static void pinsnv10_arch_fake(void)
355 {
356 	/* carefull not to take to high limits, and high should be >= 2x low. */
357 	si->ps.max_system_vco = 350;
358 	si->ps.min_system_vco = 128;
359 	si->ps.max_pixel_vco = 350;
360 	si->ps.min_pixel_vco = 128;
361 	si->ps.max_video_vco = 350;
362 	si->ps.min_video_vco = 128;
363 	si->ps.max_dac1_clock = 350;
364 	si->ps.max_dac1_clock_8 = 350;
365 	si->ps.max_dac1_clock_16 = 350;
366 	/* 'failsave' values */
367 	si->ps.max_dac1_clock_24 = 320;
368 	si->ps.max_dac1_clock_32 = 280;
369 	si->ps.max_dac1_clock_32dh = 250;
370 	/* secondary head */
371 	//fixme? assuming...
372 	si->ps.max_dac2_clock = 200;
373 	si->ps.max_dac2_clock_8 = 200;
374 	si->ps.max_dac2_clock_16 = 200;
375 	si->ps.max_dac2_clock_24 = 200;
376 	si->ps.max_dac2_clock_32 = 200;
377 	/* 'failsave' values */
378 	si->ps.max_dac2_clock_32dh = 180;
379 	//fixme: primary & secondary_dvi should be overrule-able via nv.settings
380 	si->ps.primary_dvi = false;
381 	si->ps.secondary_dvi = false;
382 //fixme: is this needed for nv acc?
383 //fail-safe mode for now:
384 	si->ps.sdram = true;
385 
386 	/* not used (yet) because no coldstart will be attempted (yet) */
387 	si->ps.std_engine_clock = 120;
388 	si->ps.std_memory_clock = 150;
389 }
390 
391 static void pinsnv20_arch_fake(void)
392 {
393 	/* carefull not to take to high limits, and high should be >= 2x low. */
394 	si->ps.max_system_vco = 350;
395 	si->ps.min_system_vco = 128;
396 	si->ps.max_pixel_vco = 350;
397 	si->ps.min_pixel_vco = 128;
398 	si->ps.max_video_vco = 350;
399 	si->ps.min_video_vco = 128;
400 	si->ps.max_dac1_clock = 350;
401 	si->ps.max_dac1_clock_8 = 350;
402 	si->ps.max_dac1_clock_16 = 350;
403 	/* 'failsave' values */
404 	si->ps.max_dac1_clock_24 = 320;
405 	si->ps.max_dac1_clock_32 = 280;
406 	si->ps.max_dac1_clock_32dh = 250;
407 	/* secondary head */
408 	//fixme? assuming...
409 	si->ps.max_dac2_clock = 200;
410 	si->ps.max_dac2_clock_8 = 200;
411 	si->ps.max_dac2_clock_16 = 200;
412 	si->ps.max_dac2_clock_24 = 200;
413 	si->ps.max_dac2_clock_32 = 200;
414 	/* 'failsave' values */
415 	si->ps.max_dac2_clock_32dh = 180;
416 	//fixme: primary & secondary_dvi should be overrule-able via nv.settings
417 	si->ps.primary_dvi = false;
418 	si->ps.secondary_dvi = false;
419 //fixme: is this needed for nv acc?
420 //fail-safe mode for now:
421 	si->ps.sdram = true;
422 
423 	/* not used (yet) because no coldstart will be attempted (yet) */
424 	si->ps.std_engine_clock = 175;
425 	si->ps.std_memory_clock = 200;
426 }
427 
428 static void pinsnv30_arch_fake(void)
429 {
430 	/* carefull not to take to high limits, and high should be >= 2x low. */
431 	si->ps.max_system_vco = 350;
432 	si->ps.min_system_vco = 128;
433 	si->ps.max_pixel_vco = 350;
434 	si->ps.min_pixel_vco = 128;
435 	si->ps.max_video_vco = 350;
436 	si->ps.min_video_vco = 128;
437 	si->ps.max_dac1_clock = 350;
438 	si->ps.max_dac1_clock_8 = 350;
439 	si->ps.max_dac1_clock_16 = 350;
440 	/* 'failsave' values */
441 	si->ps.max_dac1_clock_24 = 320;
442 	si->ps.max_dac1_clock_32 = 280;
443 	si->ps.max_dac1_clock_32dh = 250;
444 	/* secondary head */
445 	//fixme? assuming...
446 	si->ps.max_dac2_clock = 200;
447 	si->ps.max_dac2_clock_8 = 200;
448 	si->ps.max_dac2_clock_16 = 200;
449 	si->ps.max_dac2_clock_24 = 200;
450 	si->ps.max_dac2_clock_32 = 200;
451 	/* 'failsave' values */
452 	si->ps.max_dac2_clock_32dh = 180;
453 	//fixme: primary & secondary_dvi should be overrule-able via nv.settings
454 	si->ps.primary_dvi = false;
455 	si->ps.secondary_dvi = false;
456 //fixme: is this needed for nv acc?
457 //fail-safe mode for now:
458 	si->ps.sdram = true;
459 
460 	/* not used (yet) because no coldstart will be attempted (yet) */
461 	si->ps.std_engine_clock = 190;
462 	si->ps.std_memory_clock = 190;
463 }
464 
465 static void getstrap_arch_nv4(void)
466 {
467 	uint32 strapinfo = NV_REG32(NV32_NV4STRAPINFO);
468 
469 	if (strapinfo & 0x00000100)
470 	{
471 		/* Unified memory architecture used */
472 		si->ps.memory_size =
473 			((((strapinfo & 0x0000f000) >> 12) * 2) + 2);
474 
475 		LOG(8,("INFO: NV4 architecture chip with UMA detected\n"));
476 	}
477 	else
478 	{
479 		/* private memory architecture used */
480 		switch (strapinfo & 0x00000003)
481 		{
482 		case 0:
483 			si->ps.memory_size = 32;
484 			break;
485 		case 1:
486 			si->ps.memory_size = 4;
487 			break;
488 		case 2:
489 			si->ps.memory_size = 8;
490 			break;
491 		case 3:
492 			si->ps.memory_size = 16;
493 			break;
494 		}
495 	}
496 
497 	strapinfo = NV_REG32(NV32_NVSTRAPINFO2);
498 
499 	/* determine PLL reference crystal frequency */
500 	if (strapinfo & 0x00000040)
501 		si->ps.f_ref = 14.31818;
502 	else
503 		si->ps.f_ref = 13.50000;
504 
505 	/* these cards are always singlehead */
506 	si->ps.secondary_head = false;
507 }
508 
509 static void getstrap_arch_nv10_20_30(void)
510 {
511 	uint32 dev_manID = CFGR(DEVID);
512 	uint32 strapinfo = NV_REG32(NV32_NV10STRAPINFO);
513 
514 	switch (dev_manID)
515 	{
516 	case 0x01a010de: /* Nvidia GeForce2 Integrated GPU */
517 		//fixme: need kerneldriver function to readout other device PCI config space!?!
518 		//linux: int amt = pciReadLong(pciTag(0, 0, 1), 0x7C);
519 		si->ps.memory_size = (((CFGR(GF2IGPU) & 0x000007c0) >> 6) + 1);
520 		break;
521 	case 0x01f010de: /* Nvidia GeForce4 MX Integrated GPU */
522 		//fixme: need kerneldriver function to readout other device PCI config space!?!
523 		//linux: int amt = pciReadLong(pciTag(0, 0, 1), 0x84);
524 		si->ps.memory_size = (((CFGR(GF4MXIGPU) & 0x000007f0) >> 4) + 1);
525 		break;
526 	default:
527 		LOG(8,("INFO: (Memory detection) Strapinfo value is: $%08x\n", strapinfo));
528 
529 		switch ((strapinfo & 0x1ff00000) >> 20)
530 		{
531 		case 2:
532 			si->ps.memory_size = 2;
533 			break;
534 		case 4:
535 			si->ps.memory_size = 4;
536 			break;
537 		case 8:
538 			si->ps.memory_size = 8;
539 			break;
540 		case 16:
541 			si->ps.memory_size = 16;
542 			break;
543 		case 32:
544 			si->ps.memory_size = 32;
545 			break;
546 		case 64:
547 			si->ps.memory_size = 64;
548 			break;
549 		case 128:
550 			si->ps.memory_size = 128;
551 			break;
552 		case 256:
553 			si->ps.memory_size = 256;
554 			break;
555 		default:
556 			si->ps.memory_size = 16;
557 
558 			LOG(8,("INFO: NV10/20/30 architecture chip with unknown RAM amount detected;\n"));
559 			LOG(8,("INFO: Setting 16Mb\n"));
560 			break;
561 		}
562 	}
563 
564 	strapinfo = NV_REG32(NV32_NVSTRAPINFO2);
565 
566 	/* determine PLL reference crystal frequency: three types are used... */
567 	if (strapinfo & 0x00000040)
568 		si->ps.f_ref = 14.31818;
569 	else
570 		si->ps.f_ref = 13.50000;
571 
572 	switch (dev_manID & 0xfff0ffff)
573 	{
574 	/* Nvidia cards: */
575 	case 0x017010de:
576 	case 0x018010de:
577 	case 0x01f010de:
578 	case 0x025010de:
579 	case 0x028010de:
580 	case 0x030010de:
581 	case 0x031010de:
582 	case 0x032010de:
583 	case 0x033010de:
584 	case 0x034010de:
585 	/* Varisys cards: */
586 	case 0x35001888:
587 		if (strapinfo & 0x00400000) si->ps.f_ref = 27.00000;
588 		break;
589 	default:
590 		break;
591 	}
592 
593 	/* determine if we have a dualhead card */
594 	switch (dev_manID & 0xfff0ffff)
595 	{
596 	/* Nvidia cards: */
597 	case 0x011010de:
598 	case 0x017010de:
599 	case 0x018010de:
600 	case 0x01f010de:
601 	case 0x025010de:
602 	case 0x028010de:
603 	case 0x030010de:
604 	case 0x031010de:
605 	case 0x032010de:
606 	case 0x033010de:
607 	case 0x034010de:
608 	/* Varisys cards: */
609 	case 0x35001888:
610 		si->ps.secondary_head = true;
611 		break;
612 	default:
613 		si->ps.secondary_head = false;
614 		break;
615 	}
616 }
617 
618 void dump_pins(void)
619 {
620 	char *msg = "";
621 
622 	LOG(2,("INFO: pinsdump follows:\n"));
623 	LOG(2,("f_ref: %fMhz\n", si->ps.f_ref));
624 	LOG(2,("max_system_vco: %dMhz\n", si->ps.max_system_vco));
625 	LOG(2,("min_system_vco: %dMhz\n", si->ps.min_system_vco));
626 	LOG(2,("max_pixel_vco: %dMhz\n", si->ps.max_pixel_vco));
627 	LOG(2,("min_pixel_vco: %dMhz\n", si->ps.min_pixel_vco));
628 	LOG(2,("max_video_vco: %dMhz\n", si->ps.max_video_vco));
629 	LOG(2,("min_video_vco: %dMhz\n", si->ps.min_video_vco));
630 	LOG(2,("std_engine_clock: %dMhz\n", si->ps.std_engine_clock));
631 	LOG(2,("std_memory_clock: %dMhz\n", si->ps.std_memory_clock));
632 	LOG(2,("max_dac1_clock: %dMhz\n", si->ps.max_dac1_clock));
633 	LOG(2,("max_dac1_clock_8: %dMhz\n", si->ps.max_dac1_clock_8));
634 	LOG(2,("max_dac1_clock_16: %dMhz\n", si->ps.max_dac1_clock_16));
635 	LOG(2,("max_dac1_clock_24: %dMhz\n", si->ps.max_dac1_clock_24));
636 	LOG(2,("max_dac1_clock_32: %dMhz\n", si->ps.max_dac1_clock_32));
637 	LOG(2,("max_dac1_clock_32dh: %dMhz\n", si->ps.max_dac1_clock_32dh));
638 	LOG(2,("max_dac2_clock: %dMhz\n", si->ps.max_dac2_clock));
639 	LOG(2,("max_dac2_clock_8: %dMhz\n", si->ps.max_dac2_clock_8));
640 	LOG(2,("max_dac2_clock_16: %dMhz\n", si->ps.max_dac2_clock_16));
641 	LOG(2,("max_dac2_clock_24: %dMhz\n", si->ps.max_dac2_clock_24));
642 	LOG(2,("max_dac2_clock_32: %dMhz\n", si->ps.max_dac2_clock_32));
643 	LOG(2,("max_dac2_clock_32dh: %dMhz\n", si->ps.max_dac2_clock_32dh));
644 	LOG(2,("secondary_head: "));
645 	if (si->ps.secondary_head) LOG(2,("present\n")); else LOG(2,("absent\n"));
646 	LOG(2,("tvout: "));
647 	if (si->ps.tvout) LOG(2,("present\n")); else LOG(2,("absent\n"));
648 	/* setup TVout logmessage text */
649 	switch (si->ps.tvout_chip_type)
650 	{
651 	case NONE:
652 		msg = "No";
653 		break;
654 	case CH7003:
655 		msg = "Chrontel CH7003";
656 		break;
657 	case CH7004:
658 		msg = "Chrontel CH7004";
659 		break;
660 	case CH7005:
661 		msg = "Chrontel CH7005";
662 		break;
663 	case CH7006:
664 		msg = "Chrontel CH7006";
665 		break;
666 	case CH7007:
667 		msg = "Chrontel CH7007";
668 		break;
669 	case SAA7102:
670 		msg = "Philips SAA7102";
671 		break;
672 	case SAA7104:
673 		msg = "Philips SAA7104";
674 		break;
675 	case SAA7108:
676 		msg = "Philips SAA7108";
677 		break;
678 	case SAA7114:
679 		msg = "Philips SAA7114";
680 		break;
681 	case BT868:
682 		msg = "Brooktree/Conexant BT868";
683 		break;
684 	case BT869:
685 		msg = "Brooktree/Conexant BT869";
686 		break;
687 	case CX25870:
688 		msg = "Conexant CX25870";
689 		break;
690 	case CX25871:
691 		msg = "Conexant CX25871";
692 		break;
693 	case NVIDIA:
694 		msg = "Nvidia internal";
695 		break;
696 	default:
697 		msg = "Unknown";
698 		break;
699 	}
700 	LOG(2, ("%s TVout chip detected\n", msg));
701 	LOG(2,("primary_dvi: "));
702 	if (si->ps.primary_dvi) LOG(2,("present\n")); else LOG(2,("absent\n"));
703 	LOG(2,("secondary_dvi: "));
704 	if (si->ps.secondary_dvi) LOG(2,("present\n")); else LOG(2,("absent\n"));
705 	LOG(2,("card memory_size: %dMb\n", si->ps.memory_size));
706 	LOG(2,("sdram: "));
707 	if (si->ps.sdram) LOG(2,("SDRAM card\n")); else LOG(2,("SGRAM card\n"));
708 	LOG(2,("laptop: "));
709 	if (si->ps.laptop) LOG(2,("yes\n")); else LOG(2,("no\n"));
710 	LOG(2,("INFO: end pinsdump.\n"));
711 }
712