xref: /haiku/src/add-ons/accelerants/nvidia/engine/nv_info.c (revision 67bce78b48ed6d01b5a8eef89f5694c372b7e0a1)
1 /* Read initialisation information from card */
2 /* some bits are hacks, where PINS is not known */
3 /* Author:
4    Rudolf Cornelissen 7/2003-4/2004
5 */
6 
7 #define MODULE_BIT 0x00002000
8 
9 #include "nv_std.h"
10 
11 static void detect_panels(void);
12 static void pinsnv4_fake(void);
13 static void pinsnv5_nv5m64_fake(void);
14 static void pinsnv6_fake(void);
15 static void pinsnv10_arch_fake(void);
16 static void pinsnv20_arch_fake(void);
17 static void pinsnv30_arch_fake(void);
18 static void getstrap_arch_nv4(void);
19 static void getstrap_arch_nv10_20_30(void);
20 static status_t pins5_read(uint8 *pins, uint8 length);
21 
22 /* Parse the BIOS PINS structure if there */
23 status_t parse_pins ()
24 {
25 	uint8 pins_len = 0;
26 	uint8 *rom;
27 	uint8 *pins;
28 	uint8 chksum = 0;
29 	int i;
30 	status_t result = B_ERROR;
31 
32 	/* preset PINS read status to failed */
33 	si->ps.pins_status = B_ERROR;
34 
35 	/* check the validity of PINS */
36 	LOG(2,("INFO: Reading PINS info\n"));
37 	rom = (uint8 *) si->rom_mirror;
38 	/* check BIOS signature */
39 	if (rom[0]!=0x55 || rom[1]!=0xaa)
40 	{
41 		LOG(8,("INFO: BIOS signiture not found\n"));
42 		return B_ERROR;
43 	}
44 	LOG(2,("INFO: BIOS signiture $AA55 found OK\n"));
45 	/* check for a valid PINS struct adress */
46 	pins = rom + (rom[0x7FFC]|(rom[0x7FFD]<<8));
47 	if ((pins - rom) > 0x7F80)
48 	{
49 		LOG(8,("INFO: invalid PINS adress\n"));
50 		return B_ERROR;
51 	}
52 	/* checkout new PINS struct version if there */
53 	if ((pins[0] == 0x2E) && (pins[1] == 0x41))
54 	{
55 		pins_len = pins[2];
56 		if (pins_len < 3 || pins_len > 128)
57 		{
58 			LOG(8,("INFO: invalid PINS size\n"));
59 			return B_ERROR;
60 		}
61 
62 		/* calculate PINS checksum */
63 		for (i = 0; i < pins_len; i++)
64 		{
65 			chksum += pins[i];
66 		}
67 		if (chksum)
68 		{
69 			LOG(8,("INFO: PINS checksum error\n"));
70 			return B_ERROR;
71 		}
72 		LOG(2,("INFO: new PINS, version %u.%u, length %u\n", pins[5], pins[4], pins[2]));
73 		/* fill out the si->ps struct if possible */
74 		switch (pins[5])
75 		{
76 			case 5:
77 				result = pins5_read(pins, pins_len);
78 				break;
79 			default:
80 				LOG(8,("INFO: unknown PINS version\n"));
81 				return B_ERROR;
82 				break;
83 		}
84 	}
85 	/* no valid PINS signature found */
86 	else
87 	{
88 		LOG(8,("INFO: no PINS signature found\n"));
89 		return B_ERROR;
90 	}
91 	/* check PINS read result */
92 	if (result == B_ERROR)
93 	{
94 		LOG(8,("INFO: PINS read/decode error\n"));
95 		return B_ERROR;
96 	}
97 	/* PINS scan succeeded */
98 	si->ps.pins_status = B_OK;
99 	LOG(2,("INFO: PINS scan completed succesfully\n"));
100 	return B_OK;
101 }
102 
103 /* pins v5 is used by G450 and G550 */
104 static status_t pins5_read(uint8 *pins, uint8 length)
105 {
106 	unsigned int m_factor = 6;
107 
108 	if (length != 128)
109 	{
110 		LOG(8,("INFO: wrong PINS length, expected 128, got %d\n", length));
111 		return B_ERROR;
112 	}
113 
114 	/* fill out the shared info si->ps struct */
115 	if (pins[4] == 0x01) m_factor = 8;
116 	if (pins[4] >= 0x02) m_factor = 10;
117 
118 	si->ps.max_system_vco = m_factor * pins[36];
119 	si->ps.max_video_vco = m_factor * pins[37];
120 	si->ps.max_pixel_vco = m_factor * pins[38];
121 	si->ps.min_system_vco = m_factor * pins[121];
122 	si->ps.min_video_vco = m_factor * pins[122];
123 	si->ps.min_pixel_vco = m_factor * pins[123];
124 
125 	if (pins[39] == 0xff) si->ps.max_dac1_clock_8 = si->ps.max_pixel_vco;
126 	else si->ps.max_dac1_clock_8 = 4 * pins[39];
127 
128 	if (pins[40] == 0xff) si->ps.max_dac1_clock_16 = si->ps.max_dac1_clock_8;
129 	else si->ps.max_dac1_clock_16 = 4 * pins[40];
130 
131 	if (pins[41] == 0xff) si->ps.max_dac1_clock_24 = si->ps.max_dac1_clock_16;
132 	else si->ps.max_dac1_clock_24 = 4 * pins[41];
133 
134 	if (pins[42] == 0xff) si->ps.max_dac1_clock_32 = si->ps.max_dac1_clock_24;
135 	else si->ps.max_dac1_clock_32 = 4 * pins[42];
136 
137 	if (pins[124] == 0xff) si->ps.max_dac1_clock_32dh = si->ps.max_dac1_clock_32;
138 	else si->ps.max_dac1_clock_32dh = 4 * pins[124];
139 
140 	if (pins[43] == 0xff) si->ps.max_dac2_clock_16 = si->ps.max_video_vco;
141 	else si->ps.max_dac2_clock_16 = 4 * pins[43];
142 
143 	if (pins[44] == 0xff) si->ps.max_dac2_clock_32 = si->ps.max_dac2_clock_16;
144 	else si->ps.max_dac2_clock_32 = 4 * pins[44];
145 
146 	if (pins[125] == 0xff) si->ps.max_dac2_clock_32dh = si->ps.max_dac2_clock_32;
147 	else si->ps.max_dac2_clock_32dh = 4 * pins[125];
148 
149 	if (pins[118] == 0xff) si->ps.max_dac1_clock = si->ps.max_dac1_clock_8;
150 	else si->ps.max_dac1_clock = 4 * pins[118];
151 
152 	if (pins[119] == 0xff) si->ps.max_dac2_clock = si->ps.max_dac1_clock;
153 	else si->ps.max_dac2_clock = 4 * pins[119];
154 
155 	si->ps.std_engine_clock = 4 * pins[74];
156 	si->ps.std_memory_clock = 4 * pins[92];
157 
158 	si->ps.memory_size = ((pins[114] & 0x03) + 1) * 8;
159 	if ((pins[114] & 0x07) > 3)
160 	{
161 		LOG(8,("INFO: unknown RAM size, defaulting to 8Mb\n"));
162 		si->ps.memory_size = 8;
163 	}
164 
165 	if (pins[110] & 0x01) si->ps.f_ref = 14.31818;
166 	else si->ps.f_ref = 27.00000;
167 
168 	/* make sure SGRAM functions only get enabled if SGRAM mounted */
169 //	if ((pins[114] & 0x18) == 0x08) si->ps.sdram = false;
170 //	else si->ps.sdram = true;
171 
172 	/* various registers */
173 	si->ps.secondary_head = (pins[117] & 0x70);
174 	si->ps.tvout = (pins[117] & 0x40);
175 	si->ps.primary_dvi = (pins[117] & 0x02);
176 	si->ps.secondary_dvi = (pins[117] & 0x20);
177 
178 	/* not supported: */
179 	si->ps.max_dac2_clock_8 = 0;
180 	si->ps.max_dac2_clock_24 = 0;
181 
182 	return B_OK;
183 }
184 
185 /* fake_pins presumes the card was coldstarted by it's BIOS */
186 void fake_pins(void)
187 {
188 	LOG(8,("INFO: faking PINS\n"));
189 
190 	/* set failsave speeds */
191 	switch (si->ps.card_type)
192 	{
193 	case NV04:
194 		pinsnv4_fake();
195 		break;
196 	case NV05:
197 	case NV05M64:
198 		pinsnv5_nv5m64_fake();
199 		break;
200 	case NV06:
201 		pinsnv6_fake();
202 		break;
203 	default:
204 		switch (si->ps.card_arch)
205 		{
206 		case NV10A:
207 			pinsnv10_arch_fake();
208 			break;
209 		case NV20A:
210 			pinsnv20_arch_fake();
211 			break;
212 		case NV30A:
213 			pinsnv30_arch_fake();
214 			break;
215 		default:
216 			/* 'failsafe' values... */
217 			pinsnv10_arch_fake();
218 			break;
219 		}
220 		break;
221 	}
222 
223 	/* detect RAM amount, reference crystal frequency and dualhead */
224 	switch (si->ps.card_arch)
225 	{
226 	case NV04A:
227 		getstrap_arch_nv4();
228 		break;
229 	default:
230 		getstrap_arch_nv10_20_30();
231 		break;
232 	}
233 
234 	/* find out if the card has a tvout chip */
235 	si->ps.tvout = false;
236 	si->ps.tvout_chip_type = NONE;
237 //fixme ;-)
238 /*	if (i2c_maven_probe() == B_OK)
239 	{
240 		si->ps.tvout = true;
241 		si->ps.tvout_chip_bus = ???;
242 		si->ps.tvout_chip_type = ???;
243 	}
244 */
245 
246 	/* find out the BIOS preprogrammed panel use status... */
247 	detect_panels();
248 }
249 
250 static void detect_panels()
251 {
252 	/* detect if the BIOS enabled LCD's (internal panels or DVI) or TVout */
253 
254 	/* both external TMDS transmitters (used for LCD/DVI) and external TVencoders
255 	 * can use the CRTC's in slaved mode. */
256 	/* Note:
257 	 * Apparantly a panel on CRTC1 uses the CRTC in slaved mode, while a panel
258 	 * on CRTC2 uses the CRTC in master mode. */
259 	/* Note also:
260 	 * DFP's are programmed with standard VESA modelines by the card's BIOS! */
261 	bool slaved_for_dev1 = false, slaved_for_dev2 = false;
262 	bool tvout1 = false, tvout2 = false;
263 
264 	/* check primary head: */
265 	/* enable access to CRTC1 on dualhead cards */
266 	if (si->ps.secondary_head) CRTCW(OWNER, 0x00);
267 
268 	/* unlock CRTC1 */
269 	CRTCW(LOCK, 0x57);
270 	CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f));
271 	/* detect active slave device (if any) */
272 	slaved_for_dev1 = (CRTCR(PIXEL) & 0x80);
273 	if (slaved_for_dev1)
274 	{
275 		/* if the panel isn't selected, tvout is.. */
276 		tvout1 = !(CRTCR(LCD) & 0x01);
277 	}
278 
279 	if (si->ps.secondary_head)
280 	{
281 		/* check secondary head: */
282 		/* enable access to CRTC2 */
283 		CRTCW(OWNER, 0x03);
284 		/* unlock CRTC2 */
285 		CRTCW(LOCK, 0x57);
286 		CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f));
287 		/* detect active slave device (if any) */
288 		slaved_for_dev2 = (CRTCR(PIXEL) & 0x80);
289 		if (slaved_for_dev2)
290 		{
291 			/* if the panel isn't selected, tvout is.. */
292 			tvout2 = !(CRTCR(LCD) & 0x01);
293 		}
294 	}
295 
296 	/* do some presets */
297 	si->ps.panel1_width = 0;
298 	si->ps.panel1_height = 0;
299 	si->ps.panel1_aspect = 0;
300 	si->ps.panel2_width = 0;
301 	si->ps.panel2_height = 0;
302 	si->ps.panel2_aspect = 0;
303 	si->ps.slaved_tmds1 = false;
304 	si->ps.slaved_tmds2 = false;
305 	si->ps.master_tmds1 = false;
306 	si->ps.master_tmds2 = false;
307 	si->ps.tmds1_active = false;
308 	si->ps.tmds2_active = false;
309 	/* determine the situation we are in... (regarding flatpanels) */
310 	/* fixme: add VESA DDC EDID stuff one day... */
311 	/* fixme: find out how to program those transmitters one day instead of
312 	 * relying on the cards BIOS to do it. This adds TVout options where panels
313 	 * are used!
314 	 * Currently we'd loose the panel setup while not being able to restore it. */
315 
316 	/* note: (facts)
317 	 * -> NV11 and NV17 laptops have LVDS panels, programmed in both sets registers;
318 	 * -> NV34 laptops have TMDS panels, programmed in only one set of registers;
319 	 * -> NV11, NV25 and NV34 DVI cards, so external panels (TMDS) are programmed
320 	 *    in only one set of registers;
321 	 * -> a register-set's FP_TG_CTRL register, bit 31 tells you if a LVDS panel is
322 	 *    connected to the primary head (0), or to the secondary head (1);
323 	 * -> for LVDS panels both registersets are programmed identically by the card's
324 	 *    BIOSes;
325 	 * -> the programmed set of registers tells you where a TMDS (DVI) panel is
326 	 *    connected. */
327 	if (slaved_for_dev1 && !tvout1)
328 	{
329 		uint16 width = ((DACR(FP_HDISPEND) & 0x0000ffff) + 1);
330 		uint16 height = ((DACR(FP_VDISPEND) & 0x0000ffff) + 1);
331 		if ((width >= 640) && (height >= 480))
332 		{
333 			si->ps.slaved_tmds1 = true;
334 			si->ps.tmds1_active = true;
335 			si->ps.panel1_width = width;
336 			si->ps.panel1_height = height;
337 		}
338 	}
339 
340 	if (si->ps.secondary_head && slaved_for_dev2 && !tvout2)
341 	{
342 		uint16 width = ((DAC2R(FP_HDISPEND) & 0x0000ffff) + 1);
343 		uint16 height = ((DAC2R(FP_VDISPEND) & 0x0000ffff) + 1);
344 		if ((width >= 640) && (height >= 480))
345 		{
346 			si->ps.slaved_tmds2 = true;
347 			si->ps.tmds2_active = true;
348 			si->ps.panel2_width = width;
349 			si->ps.panel2_height = height;
350 		}
351 	}
352 
353 	if (!si->ps.slaved_tmds1 && !tvout1)
354 	{
355 		uint16 width = ((DACR(FP_HDISPEND) & 0x0000ffff) + 1);
356 		uint16 height = ((DACR(FP_VDISPEND) & 0x0000ffff) + 1);
357 		if ((width >= 640) && (height >= 480))
358 		{
359 			si->ps.master_tmds1 = true;
360 			si->ps.tmds1_active = true;
361 			si->ps.panel1_width = width;
362 			si->ps.panel1_height = height;
363 		}
364 	}
365 
366 	if (si->ps.secondary_head && !si->ps.slaved_tmds2 && !tvout2)
367 	{
368 		uint16 width = ((DAC2R(FP_HDISPEND) & 0x0000ffff) + 1);
369 		uint16 height = ((DAC2R(FP_VDISPEND) & 0x0000ffff) + 1);
370 		if ((width >= 640) && (height >= 480))
371 		{
372 			si->ps.master_tmds2 = true;
373 			si->ps.tmds2_active = true;
374 			si->ps.panel2_width = width;
375 			si->ps.panel2_height = height;
376 		}
377 	}
378 
379 	//fixme...:
380 	//we are assuming that no DVI is used as external monitor on laptops;
381 	//otherwise we probably get into trouble here if the checked specs match.
382 	if (si->ps.laptop && si->ps.tmds1_active && si->ps.tmds2_active &&
383 		((DACR(FP_TG_CTRL) & 0x80000000) == (DAC2R(FP_TG_CTRL) & 0x80000000)) &&
384 		(si->ps.panel1_width == si->ps.panel2_width) &&
385 		(si->ps.panel1_height == si->ps.panel2_height))
386 	{
387 		if (DACR(FP_TG_CTRL) & 0x80000000)
388 		{
389 			/* LVDS panel is on CRTC2, so clear false primary detection */
390 			si->ps.slaved_tmds1 = false;
391 			si->ps.master_tmds1 = false;
392 			si->ps.tmds1_active = false;
393 			si->ps.panel1_width = 0;
394 			si->ps.panel1_height = 0;
395 		}
396 		else
397 		{
398 			/* LVDS panel is on CRTC1, so clear false secondary detection */
399 			si->ps.slaved_tmds2 = false;
400 			si->ps.master_tmds2 = false;
401 			si->ps.tmds2_active = false;
402 			si->ps.panel2_width = 0;
403 			si->ps.panel2_height = 0;
404 		}
405 	}
406 
407 	/* determine panel(s) aspect ratio(s) */
408 	if (si->ps.tmds1_active)
409 		si->ps.panel1_aspect = (si->ps.panel1_width / ((float)si->ps.panel1_height));
410 	if (si->ps.tmds2_active)
411 		si->ps.panel2_aspect = (si->ps.panel2_width / ((float)si->ps.panel2_height));
412 
413 	/* dump some panel configuration registers... */
414 	LOG(2,("INFO: Dumping flatpanel registers:\n"));
415 	LOG(2,("DAC1: FP_HDISPEND: %d\n", DACR(FP_HDISPEND)));
416 	LOG(2,("DAC1: FP_HTOTAL: %d\n", DACR(FP_HTOTAL)));
417 	LOG(2,("DAC1: FP_HCRTC: %d\n", DACR(FP_HCRTC)));
418 	LOG(2,("DAC1: FP_HSYNC_S: %d\n", DACR(FP_HSYNC_S)));
419 	LOG(2,("DAC1: FP_HSYNC_E: %d\n", DACR(FP_HSYNC_E)));
420 	LOG(2,("DAC1: FP_HVALID_S: %d\n", DACR(FP_HVALID_S)));
421 	LOG(2,("DAC1: FP_HVALID_E: %d\n", DACR(FP_HVALID_E)));
422 
423 	LOG(2,("DAC1: FP_VDISPEND: %d\n", DACR(FP_VDISPEND)));
424 	LOG(2,("DAC1: FP_VTOTAL: %d\n", DACR(FP_VTOTAL)));
425 	LOG(2,("DAC1: FP_VCRTC: %d\n", DACR(FP_VCRTC)));
426 	LOG(2,("DAC1: FP_VSYNC_S: %d\n", DACR(FP_VSYNC_S)));
427 	LOG(2,("DAC1: FP_VSYNC_E: %d\n", DACR(FP_VSYNC_E)));
428 	LOG(2,("DAC1: FP_VVALID_S: %d\n", DACR(FP_VVALID_S)));
429 	LOG(2,("DAC1: FP_VVALID_E: %d\n", DACR(FP_VVALID_E)));
430 
431 	LOG(2,("DAC1: FP_CHKSUM: $%08x = (dec) %d\n", DACR(FP_CHKSUM),DACR(FP_CHKSUM)));
432 	LOG(2,("DAC1: FP_TST_CTRL: $%08x\n", DACR(FP_TST_CTRL)));
433 	LOG(2,("DAC1: FP_TG_CTRL: $%08x\n", DACR(FP_TG_CTRL)));
434 	LOG(2,("DAC1: FP_DEBUG0: $%08x\n", DACR(FP_DEBUG0)));
435 	LOG(2,("DAC1: FP_DEBUG1: $%08x\n", DACR(FP_DEBUG1)));
436 	LOG(2,("DAC1: FP_DEBUG2: $%08x\n", DACR(FP_DEBUG2)));
437 	LOG(2,("DAC1: FP_DEBUG3: $%08x\n", DACR(FP_DEBUG3)));
438 
439 	LOG(2,("DAC1: FUNCSEL: $%08x\n", NV_REG32(NV32_FUNCSEL)));
440 
441 	if(si->ps.secondary_head)
442 	{
443 		LOG(2,("DAC2: FP_HDISPEND: %d\n", DAC2R(FP_HDISPEND)));
444 		LOG(2,("DAC2: FP_HTOTAL: %d\n", DAC2R(FP_HTOTAL)));
445 		LOG(2,("DAC2: FP_HCRTC: %d\n", DAC2R(FP_HCRTC)));
446 		LOG(2,("DAC2: FP_HSYNC_S: %d\n", DAC2R(FP_HSYNC_S)));
447 		LOG(2,("DAC2: FP_HSYNC_E: %d\n", DAC2R(FP_HSYNC_E)));
448 		LOG(2,("DAC2: FP_HVALID_S:%d\n", DAC2R(FP_HVALID_S)));
449 		LOG(2,("DAC2: FP_HVALID_E: %d\n", DAC2R(FP_HVALID_E)));
450 
451 		LOG(2,("DAC2: FP_VDISPEND: %d\n", DAC2R(FP_VDISPEND)));
452 		LOG(2,("DAC2: FP_VTOTAL: %d\n", DAC2R(FP_VTOTAL)));
453 		LOG(2,("DAC2: FP_VCRTC: %d\n", DAC2R(FP_VCRTC)));
454 		LOG(2,("DAC2: FP_VSYNC_S: %d\n", DAC2R(FP_VSYNC_S)));
455 		LOG(2,("DAC2: FP_VSYNC_E: %d\n", DAC2R(FP_VSYNC_E)));
456 		LOG(2,("DAC2: FP_VVALID_S: %d\n", DAC2R(FP_VVALID_S)));
457 		LOG(2,("DAC2: FP_VVALID_E: %d\n", DAC2R(FP_VVALID_E)));
458 
459 		LOG(2,("DAC2: FP_CHKSUM: $%08x = (dec) %d\n", DAC2R(FP_CHKSUM),DAC2R(FP_CHKSUM)));
460 		LOG(2,("DAC2: FP_TST_CTRL: $%08x\n", DAC2R(FP_TST_CTRL)));
461 		LOG(2,("DAC2: FP_TG_CTRL: $%08x\n", DAC2R(FP_TG_CTRL)));
462 		LOG(2,("DAC2: FP_DEBUG0: $%08x\n", DAC2R(FP_DEBUG0)));
463 		LOG(2,("DAC2: FP_DEBUG1: $%08x\n", DAC2R(FP_DEBUG1)));
464 		LOG(2,("DAC2: FP_DEBUG2: $%08x\n", DAC2R(FP_DEBUG2)));
465 		LOG(2,("DAC2: FP_DEBUG3: $%08x\n", DAC2R(FP_DEBUG3)));
466 
467 		LOG(2,("DAC2: FUNCSEL: $%08x\n", NV_REG32(NV32_2FUNCSEL)));
468 	}
469 	LOG(2,("INFO: End flatpanel registers dump.\n"));
470 }
471 
472 void get_panel_modelines(display_mode *p1, display_mode *p2, bool *pan1, bool *pan2)
473 {
474 	if (si->ps.tmds1_active)
475 	{
476 		/* horizontal timing */
477 		p1->timing.h_display = (DACR(FP_HDISPEND) & 0x0000ffff) + 1;
478 		p1->timing.h_sync_start = (DACR(FP_HSYNC_S) & 0x0000ffff) + 1;
479 		p1->timing.h_sync_end = (DACR(FP_HSYNC_E) & 0x0000ffff) + 1;
480 		p1->timing.h_total = (DACR(FP_HTOTAL) & 0x0000ffff) + 1;
481 		/* vertical timing */
482 		p1->timing.v_display = (DACR(FP_VDISPEND) & 0x0000ffff) + 1;
483 		p1->timing.v_sync_start = (DACR(FP_VSYNC_S) & 0x0000ffff) + 1;
484 		p1->timing.v_sync_end = (DACR(FP_VSYNC_E) & 0x0000ffff) + 1;
485 		p1->timing.v_total = (DACR(FP_VTOTAL) & 0x0000ffff) + 1;
486 		/* sync polarity */
487 		p1->timing.flags = 0;
488 		if (DACR(FP_TG_CTRL) & 0x00000001) p1->timing.flags |= B_POSITIVE_VSYNC;
489 		if (DACR(FP_TG_CTRL) & 0x00000010) p1->timing.flags |= B_POSITIVE_HSYNC;
490 		/* refreshrate */
491 		p1->timing.pixel_clock = (p1->timing.h_total * p1->timing.v_total * 60) / 1000;
492 		/* setup the rest */
493 		p1->space = B_CMAP8;
494 		p1->virtual_width = p1->timing.h_display;
495 		p1->virtual_height = p1->timing.v_display;
496 		p1->h_display_start = 0;
497 		p1->v_display_start = 0;
498 		p1->flags = 0;
499 		*pan1 = TRUE;
500 	}
501 	else
502 		*pan1 = FALSE;
503 
504 	if (si->ps.tmds2_active)
505 	{
506 		/* horizontal timing */
507 		p2->timing.h_display = (DAC2R(FP_HDISPEND) & 0x0000ffff) + 1;
508 		p2->timing.h_sync_start = (DAC2R(FP_HSYNC_S) & 0x0000ffff) + 1;
509 		p2->timing.h_sync_end = (DAC2R(FP_HSYNC_E) & 0x0000ffff) + 1;
510 		p2->timing.h_total = (DAC2R(FP_HTOTAL) & 0x0000ffff) + 1;
511 		/* vertical timing */
512 		p2->timing.v_display = (DAC2R(FP_VDISPEND) & 0x0000ffff) + 1;
513 		p2->timing.v_sync_start = (DAC2R(FP_VSYNC_S) & 0x0000ffff) + 1;
514 		p2->timing.v_sync_end = (DAC2R(FP_VSYNC_E) & 0x0000ffff) + 1;
515 		p2->timing.v_total = (DAC2R(FP_VTOTAL) & 0x0000ffff) + 1;
516 		/* sync polarity */
517 		p2->timing.flags = 0;
518 		if (DAC2R(FP_TG_CTRL) & 0x00000001) p2->timing.flags |= B_POSITIVE_VSYNC;
519 		if (DAC2R(FP_TG_CTRL) & 0x00000010) p2->timing.flags |= B_POSITIVE_HSYNC;
520 		/* refreshrate */
521 		p2->timing.pixel_clock = (p2->timing.h_total * p2->timing.v_total * 60) / 1000;
522 		/* setup the rest */
523 		p2->space = B_CMAP8;
524 		p2->virtual_width = p2->timing.h_display;
525 		p2->virtual_height = p2->timing.v_display;
526 		p2->h_display_start = 0;
527 		p2->v_display_start = 0;
528 		p2->flags = 0;
529 		*pan2 = TRUE;
530 	}
531 	else
532 		*pan2 = FALSE;
533 }
534 
535 static void pinsnv4_fake(void)
536 {
537 	/* carefull not to take to high limits, and high should be >= 2x low. */
538 	si->ps.max_system_vco = 256;
539 	si->ps.min_system_vco = 128;
540 	si->ps.max_pixel_vco = 256;
541 	si->ps.min_pixel_vco = 128;
542 	si->ps.max_video_vco = 0;
543 	si->ps.min_video_vco = 0;
544 	si->ps.max_dac1_clock = 250;
545 	si->ps.max_dac1_clock_8 = 250;
546 	si->ps.max_dac1_clock_16 = 250;
547 	/* 'failsave' values */
548 	si->ps.max_dac1_clock_24 = 220;
549 	si->ps.max_dac1_clock_32 = 180;
550 	si->ps.max_dac1_clock_32dh = 180;
551 	/* secondary head */
552 	si->ps.max_dac2_clock = 0;
553 	si->ps.max_dac2_clock_8 = 0;
554 	si->ps.max_dac2_clock_16 = 0;
555 	si->ps.max_dac2_clock_24 = 0;
556 	si->ps.max_dac2_clock_32 = 0;
557 	/* 'failsave' values */
558 	si->ps.max_dac2_clock_32dh = 0;
559 	//fixme: primary & secondary_dvi should be overrule-able via nv.settings
560 	si->ps.primary_dvi = false;
561 	si->ps.secondary_dvi = false;
562 	/* not used (yet) because no coldstart will be attempted (yet) */
563 	si->ps.std_engine_clock = 90;
564 	si->ps.std_memory_clock = 110;
565 }
566 
567 static void pinsnv5_nv5m64_fake(void)
568 {
569 	/* carefull not to take to high limits, and high should be >= 2x low. */
570 	si->ps.max_system_vco = 300;
571 	si->ps.min_system_vco = 128;
572 	si->ps.max_pixel_vco = 300;
573 	si->ps.min_pixel_vco = 128;
574 	si->ps.max_video_vco = 0;
575 	si->ps.min_video_vco = 0;
576 	si->ps.max_dac1_clock = 300;
577 	si->ps.max_dac1_clock_8 = 300;
578 	si->ps.max_dac1_clock_16 = 300;
579 	/* 'failsave' values */
580 	si->ps.max_dac1_clock_24 = 270;
581 	si->ps.max_dac1_clock_32 = 230;
582 	si->ps.max_dac1_clock_32dh = 230;
583 	/* secondary head */
584 	si->ps.max_dac2_clock = 0;
585 	si->ps.max_dac2_clock_8 = 0;
586 	si->ps.max_dac2_clock_16 = 0;
587 	si->ps.max_dac2_clock_24 = 0;
588 	si->ps.max_dac2_clock_32 = 0;
589 	/* 'failsave' values */
590 	si->ps.max_dac2_clock_32dh = 0;
591 	//fixme: primary & secondary_dvi should be overrule-able via nv.settings
592 	si->ps.primary_dvi = false;
593 	si->ps.secondary_dvi = false;
594 	/* not used (yet) because no coldstart will be attempted (yet) */
595 	si->ps.std_engine_clock = 125;
596 	si->ps.std_memory_clock = 150;
597 }
598 
599 static void pinsnv6_fake(void)
600 {
601 	/* carefull not to take to high limits, and high should be >= 2x low. */
602 	si->ps.max_system_vco = 300;
603 	si->ps.min_system_vco = 128;
604 	si->ps.max_pixel_vco = 300;
605 	si->ps.min_pixel_vco = 128;
606 	si->ps.max_video_vco = 0;
607 	si->ps.min_video_vco = 0;
608 	si->ps.max_dac1_clock = 300;
609 	si->ps.max_dac1_clock_8 = 300;
610 	si->ps.max_dac1_clock_16 = 300;
611 	/* 'failsave' values */
612 	si->ps.max_dac1_clock_24 = 270;
613 	si->ps.max_dac1_clock_32 = 230;
614 	si->ps.max_dac1_clock_32dh = 230;
615 	/* secondary head */
616 	si->ps.max_dac2_clock = 0;
617 	si->ps.max_dac2_clock_8 = 0;
618 	si->ps.max_dac2_clock_16 = 0;
619 	si->ps.max_dac2_clock_24 = 0;
620 	si->ps.max_dac2_clock_32 = 0;
621 	/* 'failsave' values */
622 	si->ps.max_dac2_clock_32dh = 0;
623 	//fixme: primary & secondary_dvi should be overrule-able via nv.settings
624 	si->ps.primary_dvi = false;
625 	si->ps.secondary_dvi = false;
626 	/* not used (yet) because no coldstart will be attempted (yet) */
627 	si->ps.std_engine_clock = 100;
628 	si->ps.std_memory_clock = 125;
629 }
630 
631 static void pinsnv10_arch_fake(void)
632 {
633 	/* carefull not to take to high limits, and high should be >= 2x low. */
634 	si->ps.max_system_vco = 350;
635 	si->ps.min_system_vco = 128;
636 	si->ps.max_pixel_vco = 350;
637 	si->ps.min_pixel_vco = 128;
638 	si->ps.max_video_vco = 350;
639 	si->ps.min_video_vco = 128;
640 	si->ps.max_dac1_clock = 350;
641 	si->ps.max_dac1_clock_8 = 350;
642 	si->ps.max_dac1_clock_16 = 350;
643 	/* 'failsave' values */
644 	si->ps.max_dac1_clock_24 = 320;
645 	si->ps.max_dac1_clock_32 = 280;
646 	si->ps.max_dac1_clock_32dh = 250;
647 	/* secondary head */
648 	//fixme? assuming...
649 	si->ps.max_dac2_clock = 200;
650 	si->ps.max_dac2_clock_8 = 200;
651 	si->ps.max_dac2_clock_16 = 200;
652 	si->ps.max_dac2_clock_24 = 200;
653 	si->ps.max_dac2_clock_32 = 200;
654 	/* 'failsave' values */
655 	si->ps.max_dac2_clock_32dh = 180;
656 	//fixme: primary & secondary_dvi should be overrule-able via nv.settings
657 	si->ps.primary_dvi = false;
658 	si->ps.secondary_dvi = false;
659 	/* not used (yet) because no coldstart will be attempted (yet) */
660 	si->ps.std_engine_clock = 120;
661 	si->ps.std_memory_clock = 150;
662 }
663 
664 static void pinsnv20_arch_fake(void)
665 {
666 	/* carefull not to take to high limits, and high should be >= 2x low. */
667 	si->ps.max_system_vco = 350;
668 	si->ps.min_system_vco = 128;
669 	si->ps.max_pixel_vco = 350;
670 	si->ps.min_pixel_vco = 128;
671 	si->ps.max_video_vco = 350;
672 	si->ps.min_video_vco = 128;
673 	si->ps.max_dac1_clock = 350;
674 	si->ps.max_dac1_clock_8 = 350;
675 	si->ps.max_dac1_clock_16 = 350;
676 	/* 'failsave' values */
677 	si->ps.max_dac1_clock_24 = 320;
678 	si->ps.max_dac1_clock_32 = 280;
679 	si->ps.max_dac1_clock_32dh = 250;
680 	/* secondary head */
681 	//fixme? assuming...
682 	si->ps.max_dac2_clock = 200;
683 	si->ps.max_dac2_clock_8 = 200;
684 	si->ps.max_dac2_clock_16 = 200;
685 	si->ps.max_dac2_clock_24 = 200;
686 	si->ps.max_dac2_clock_32 = 200;
687 	/* 'failsave' values */
688 	si->ps.max_dac2_clock_32dh = 180;
689 	//fixme: primary & secondary_dvi should be overrule-able via nv.settings
690 	si->ps.primary_dvi = false;
691 	si->ps.secondary_dvi = false;
692 	/* not used (yet) because no coldstart will be attempted (yet) */
693 	si->ps.std_engine_clock = 175;
694 	si->ps.std_memory_clock = 200;
695 }
696 
697 static void pinsnv30_arch_fake(void)
698 {
699 	/* carefull not to take to high limits, and high should be >= 2x low. */
700 	si->ps.max_system_vco = 350;
701 	si->ps.min_system_vco = 128;
702 	si->ps.max_pixel_vco = 350;
703 	si->ps.min_pixel_vco = 128;
704 	si->ps.max_video_vco = 350;
705 	si->ps.min_video_vco = 128;
706 	si->ps.max_dac1_clock = 350;
707 	si->ps.max_dac1_clock_8 = 350;
708 	si->ps.max_dac1_clock_16 = 350;
709 	/* 'failsave' values */
710 	si->ps.max_dac1_clock_24 = 320;
711 	si->ps.max_dac1_clock_32 = 280;
712 	si->ps.max_dac1_clock_32dh = 250;
713 	/* secondary head */
714 	//fixme? assuming...
715 	si->ps.max_dac2_clock = 200;
716 	si->ps.max_dac2_clock_8 = 200;
717 	si->ps.max_dac2_clock_16 = 200;
718 	si->ps.max_dac2_clock_24 = 200;
719 	si->ps.max_dac2_clock_32 = 200;
720 	/* 'failsave' values */
721 	si->ps.max_dac2_clock_32dh = 180;
722 	//fixme: primary & secondary_dvi should be overrule-able via nv.settings
723 	si->ps.primary_dvi = false;
724 	si->ps.secondary_dvi = false;
725 	/* not used (yet) because no coldstart will be attempted (yet) */
726 	si->ps.std_engine_clock = 190;
727 	si->ps.std_memory_clock = 190;
728 }
729 
730 static void getstrap_arch_nv4(void)
731 {
732 	uint32 strapinfo = NV_REG32(NV32_NV4STRAPINFO);
733 
734 	if (strapinfo & 0x00000100)
735 	{
736 		/* Unified memory architecture used */
737 		si->ps.memory_size =
738 			((((strapinfo & 0x0000f000) >> 12) * 2) + 2);
739 
740 		LOG(8,("INFO: NV4 architecture chip with UMA detected\n"));
741 	}
742 	else
743 	{
744 		/* private memory architecture used */
745 		switch (strapinfo & 0x00000003)
746 		{
747 		case 0:
748 			si->ps.memory_size = 32;
749 			break;
750 		case 1:
751 			si->ps.memory_size = 4;
752 			break;
753 		case 2:
754 			si->ps.memory_size = 8;
755 			break;
756 		case 3:
757 			si->ps.memory_size = 16;
758 			break;
759 		}
760 	}
761 
762 	strapinfo = NV_REG32(NV32_NVSTRAPINFO2);
763 
764 	/* determine PLL reference crystal frequency */
765 	if (strapinfo & 0x00000040)
766 		si->ps.f_ref = 14.31818;
767 	else
768 		si->ps.f_ref = 13.50000;
769 
770 	/* these cards are always singlehead */
771 	si->ps.secondary_head = false;
772 }
773 
774 static void getstrap_arch_nv10_20_30(void)
775 {
776 	uint32 dev_manID = CFGR(DEVID);
777 	uint32 strapinfo = NV_REG32(NV32_NV10STRAPINFO);
778 
779 	switch (dev_manID)
780 	{
781 	case 0x01a010de: /* Nvidia GeForce2 Integrated GPU */
782 		//fixme: need kerneldriver function to readout other device PCI config space!?!
783 		//linux: int amt = pciReadLong(pciTag(0, 0, 1), 0x7C);
784 		si->ps.memory_size = (((CFGR(GF2IGPU) & 0x000007c0) >> 6) + 1);
785 		break;
786 	case 0x01f010de: /* Nvidia GeForce4 MX Integrated GPU */
787 		//fixme: need kerneldriver function to readout other device PCI config space!?!
788 		//linux: int amt = pciReadLong(pciTag(0, 0, 1), 0x84);
789 		si->ps.memory_size = (((CFGR(GF4MXIGPU) & 0x000007f0) >> 4) + 1);
790 		break;
791 	default:
792 		LOG(8,("INFO: (Memory detection) Strapinfo value is: $%08x\n", strapinfo));
793 
794 		switch ((strapinfo & 0x1ff00000) >> 20)
795 		{
796 		case 2:
797 			si->ps.memory_size = 2;
798 			break;
799 		case 4:
800 			si->ps.memory_size = 4;
801 			break;
802 		case 8:
803 			si->ps.memory_size = 8;
804 			break;
805 		case 16:
806 			si->ps.memory_size = 16;
807 			break;
808 		case 32:
809 			si->ps.memory_size = 32;
810 			break;
811 		case 64:
812 			si->ps.memory_size = 64;
813 			break;
814 		case 128:
815 			si->ps.memory_size = 128;
816 			break;
817 		case 256:
818 			si->ps.memory_size = 256;
819 			break;
820 		default:
821 			si->ps.memory_size = 16;
822 
823 			LOG(8,("INFO: NV10/20/30 architecture chip with unknown RAM amount detected;\n"));
824 			LOG(8,("INFO: Setting 16Mb\n"));
825 			break;
826 		}
827 	}
828 
829 	strapinfo = NV_REG32(NV32_NVSTRAPINFO2);
830 
831 	/* determine PLL reference crystal frequency: three types are used... */
832 	if (strapinfo & 0x00000040)
833 		si->ps.f_ref = 14.31818;
834 	else
835 		si->ps.f_ref = 13.50000;
836 
837 	switch (dev_manID & 0xfff0ffff)
838 	{
839 	/* Nvidia cards: */
840 	case 0x017010de:
841 	case 0x018010de:
842 	case 0x01f010de:
843 	case 0x025010de:
844 	case 0x028010de:
845 	case 0x030010de:
846 	case 0x031010de:
847 	case 0x032010de:
848 	case 0x033010de:
849 	case 0x034010de:
850 	/* Varisys cards: */
851 	case 0x35001888:
852 		if (strapinfo & 0x00400000) si->ps.f_ref = 27.00000;
853 		break;
854 	default:
855 		break;
856 	}
857 
858 	/* determine if we have a dualhead card */
859 	switch (dev_manID & 0xfff0ffff)
860 	{
861 	/* Nvidia cards: */
862 	case 0x011010de:
863 	case 0x017010de:
864 	case 0x018010de:
865 	case 0x01f010de:
866 	case 0x025010de:
867 	case 0x028010de:
868 	case 0x030010de:
869 	case 0x031010de:
870 	case 0x032010de:
871 	case 0x033010de:
872 	case 0x034010de:
873 	/* Varisys cards: */
874 	case 0x35001888:
875 		si->ps.secondary_head = true;
876 		break;
877 	default:
878 		si->ps.secondary_head = false;
879 		break;
880 	}
881 }
882 
883 void dump_pins(void)
884 {
885 	char *msg = "";
886 
887 	LOG(2,("INFO: pinsdump follows:\n"));
888 	LOG(2,("f_ref: %fMhz\n", si->ps.f_ref));
889 	LOG(2,("max_system_vco: %dMhz\n", si->ps.max_system_vco));
890 	LOG(2,("min_system_vco: %dMhz\n", si->ps.min_system_vco));
891 	LOG(2,("max_pixel_vco: %dMhz\n", si->ps.max_pixel_vco));
892 	LOG(2,("min_pixel_vco: %dMhz\n", si->ps.min_pixel_vco));
893 	LOG(2,("max_video_vco: %dMhz\n", si->ps.max_video_vco));
894 	LOG(2,("min_video_vco: %dMhz\n", si->ps.min_video_vco));
895 	LOG(2,("std_engine_clock: %dMhz\n", si->ps.std_engine_clock));
896 	LOG(2,("std_memory_clock: %dMhz\n", si->ps.std_memory_clock));
897 	LOG(2,("max_dac1_clock: %dMhz\n", si->ps.max_dac1_clock));
898 	LOG(2,("max_dac1_clock_8: %dMhz\n", si->ps.max_dac1_clock_8));
899 	LOG(2,("max_dac1_clock_16: %dMhz\n", si->ps.max_dac1_clock_16));
900 	LOG(2,("max_dac1_clock_24: %dMhz\n", si->ps.max_dac1_clock_24));
901 	LOG(2,("max_dac1_clock_32: %dMhz\n", si->ps.max_dac1_clock_32));
902 	LOG(2,("max_dac1_clock_32dh: %dMhz\n", si->ps.max_dac1_clock_32dh));
903 	LOG(2,("max_dac2_clock: %dMhz\n", si->ps.max_dac2_clock));
904 	LOG(2,("max_dac2_clock_8: %dMhz\n", si->ps.max_dac2_clock_8));
905 	LOG(2,("max_dac2_clock_16: %dMhz\n", si->ps.max_dac2_clock_16));
906 	LOG(2,("max_dac2_clock_24: %dMhz\n", si->ps.max_dac2_clock_24));
907 	LOG(2,("max_dac2_clock_32: %dMhz\n", si->ps.max_dac2_clock_32));
908 	LOG(2,("max_dac2_clock_32dh: %dMhz\n", si->ps.max_dac2_clock_32dh));
909 	LOG(2,("secondary_head: "));
910 	if (si->ps.secondary_head) LOG(2,("present\n")); else LOG(2,("absent\n"));
911 	LOG(2,("tvout: "));
912 	if (si->ps.tvout) LOG(2,("present\n")); else LOG(2,("absent\n"));
913 	/* setup TVout logmessage text */
914 	switch (si->ps.tvout_chip_type)
915 	{
916 	case NONE:
917 		msg = "No";
918 		break;
919 	case CH7003:
920 		msg = "Chrontel CH7003";
921 		break;
922 	case CH7004:
923 		msg = "Chrontel CH7004";
924 		break;
925 	case CH7005:
926 		msg = "Chrontel CH7005";
927 		break;
928 	case CH7006:
929 		msg = "Chrontel CH7006";
930 		break;
931 	case CH7007:
932 		msg = "Chrontel CH7007";
933 		break;
934 	case CH7008:
935 		msg = "Chrontel CH7008";
936 		break;
937 	case SAA7102:
938 		msg = "Philips SAA7102";
939 		break;
940 	case SAA7103:
941 		msg = "Philips SAA7103";
942 		break;
943 	case SAA7104:
944 		msg = "Philips SAA7104";
945 		break;
946 	case SAA7105:
947 		msg = "Philips SAA7105";
948 		break;
949 	case BT868:
950 		msg = "Brooktree/Conexant BT868";
951 		break;
952 	case BT869:
953 		msg = "Brooktree/Conexant BT869";
954 		break;
955 	case CX25870:
956 		msg = "Conexant CX25870";
957 		break;
958 	case CX25871:
959 		msg = "Conexant CX25871";
960 		break;
961 	case NVIDIA:
962 		msg = "Nvidia internal";
963 		break;
964 	default:
965 		msg = "Unknown";
966 		break;
967 	}
968 	LOG(2, ("%s TVout chip detected\n", msg));
969 //	LOG(2,("primary_dvi: "));
970 //	if (si->ps.primary_dvi) LOG(2,("present\n")); else LOG(2,("absent\n"));
971 //	LOG(2,("secondary_dvi: "));
972 //	if (si->ps.secondary_dvi) LOG(2,("present\n")); else LOG(2,("absent\n"));
973 	LOG(2,("card memory_size: %dMb\n", si->ps.memory_size));
974 	LOG(2,("laptop: "));
975 	if (si->ps.laptop) LOG(2,("yes\n")); else LOG(2,("no\n"));
976 	if (si->ps.tmds1_active)
977 	{
978 		LOG(2,("found DFP (digital flatpanel) on CRTC1; CRTC1 is "));
979 		if (si->ps.slaved_tmds1) LOG(2,("slaved\n")); else LOG(2,("master\n"));
980 		LOG(2,("panel width: %d, height: %d, aspect ratio: %1.2f\n",
981 			si->ps.panel1_width, si->ps.panel1_height, si->ps.panel1_aspect));
982 	}
983 	if (si->ps.tmds2_active)
984 	{
985 		LOG(2,("found DFP (digital flatpanel) on CRTC2; CRTC2 is "));
986 		if (si->ps.slaved_tmds2) LOG(2,("slaved\n")); else LOG(2,("master\n"));
987 		LOG(2,("panel width: %d, height: %d, aspect ratio: %1.2f\n",
988 			si->ps.panel2_width, si->ps.panel2_height, si->ps.panel2_aspect));
989 	}
990 	LOG(2,("INFO: end pinsdump.\n"));
991 }
992