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