1/* Read initialisation information from card */
2/* some bits are hacks, where PINS is not known */
3/* Authors:
4   Mark Watson 2/2000,
5   Rudolf Cornelissen 10/2002-5/2006
6*/
7
8#define MODULE_BIT 0x00002000
9
10#include "mga_std.h"
11
12/* Parse the BIOS PINS structure if there */
13status_t parse_pins ()
14{
15	uint8 pins_len = 0;
16	uint8 *rom;
17	uint8 *pins;
18	uint8 chksum = 0;
19	int i;
20	status_t result = B_ERROR;
21
22	/* preset PINS read status to failed */
23	si->ps.pins_status = B_ERROR;
24
25	/* check the validity of PINS */
26	LOG(2,("INFO: Reading PINS info\n"));
27	rom = (uint8 *) si->rom_mirror;
28	/* check BIOS signature */
29	if (rom[0]!=0x55 || rom[1]!=0xaa)
30	{
31		LOG(8,("INFO: BIOS signature not found\n"));
32		return B_ERROR;
33	}
34	LOG(2,("INFO: BIOS signature $AA55 found OK\n"));
35	/* check for a valid PINS struct adress */
36	pins = rom + (rom[0x7FFC]|(rom[0x7FFD]<<8));
37	if ((pins - rom) > 0x7F80)
38	{
39		LOG(8,("INFO: invalid PINS adress\n"));
40		return B_ERROR;
41	}
42	/* checkout new PINS struct version if there */
43	if ((pins[0] == 0x2E) && (pins[1] == 0x41))
44	{
45		pins_len = pins[2];
46		if (pins_len < 3 || pins_len > 128)
47		{
48			LOG(8,("INFO: invalid PINS size\n"));
49			return B_ERROR;
50		}
51
52		/* calculate PINS checksum */
53		for (i = 0; i < pins_len; i++)
54		{
55			chksum += pins[i];
56		}
57		if (chksum)
58		{
59			LOG(8,("INFO: PINS checksum error\n"));
60			return B_ERROR;
61		}
62		LOG(2,("INFO: new PINS, version %u.%u, length %u\n", pins[5], pins[4], pins[2]));
63		/* fill out the si->ps struct if possible */
64		switch (pins[5])
65		{
66			case 2:
67				result = pins2_read(pins, pins_len);
68				break;
69			case 3:
70				result = pins3_read(pins, pins_len);
71				break;
72			case 4:
73				result = pins4_read(pins, pins_len);
74				break;
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	/* checkout old 64 byte PINS struct version if there */
85	else if ((pins[0] == 0x40) && (pins[1] == 0x00))
86	{
87		pins_len = 0x40;
88		/* this PINS version has no checksum */
89
90		LOG(2,("INFO: old PINS found\n"));
91		/* fill out the si->ps struct */
92		result = pins1_read(pins, pins_len);
93	}
94	/* no valid PINS signature found */
95	else
96	{
97		LOG(8,("INFO: no PINS signature found\n"));
98		return B_ERROR;
99	}
100	/* check PINS read result */
101	if (result == B_ERROR)
102	{
103		LOG(8,("INFO: PINS read/decode error\n"));
104		return B_ERROR;
105	}
106	/* PINS scan succeeded */
107	si->ps.pins_status = B_OK;
108	LOG(2,("INFO: PINS scan completed succesfully\n"));
109	return B_OK;
110}
111
112status_t pins1_read(uint8 *pins, uint8 length)
113{
114	if (length != 64)
115	{
116		LOG(8,("INFO: wrong PINS length, expected 64, got %d\n", length));
117		return B_ERROR;
118	}
119
120//reset all for test:
121//float:
122	si->ps.f_ref = 0;
123//uint32:
124	si->ps.max_system_vco = 0;
125	si->ps.min_system_vco = 0;
126	si->ps.min_pixel_vco = 0;
127	si->ps.min_video_vco = 0;
128	si->ps.std_engine_clock_dh = 0;
129	si->ps.max_dac1_clock_32 = 0;
130	si->ps.max_dac1_clock_32dh = 0;
131	si->ps.memory_size = 0;
132	si->ps.mctlwtst_reg = 0;
133	si->ps.memrdbk_reg = 0;
134	si->ps.option2_reg = 0;
135	si->ps.option3_reg = 0;
136	si->ps.option4_reg = 0;
137//uint8:
138	si->ps.v3_option2_reg = 0;
139	si->ps.v3_clk_div = 0;
140	si->ps.v3_mem_type = 0;
141//uint16:
142	si->ps.v5_mem_type = 0;
143//bools:
144	si->ps.secondary_head = false;
145	si->ps.tvout = false;
146	si->ps.primary_dvi = false;
147	si->ps.secondary_dvi = false;
148	si->ps.sdram = true;
149
150//experimental: checkout!
151	si->ps.max_dac1_clock_32 = pins[22];//ramdac
152	si->ps.max_pixel_vco = (pins[25] << 8) | pins[24];//PCLK
153	si->ps.std_engine_clock = (pins[29] << 8) | pins[28];
154	if ((uint32)((pins[31] << 8) | pins[30]) < si->ps.std_engine_clock)
155		si->ps.std_engine_clock = (pins[31] << 8) | pins[30];
156	if ((uint32)((pins[33] << 8) | pins[32]) < si->ps.std_engine_clock)
157		si->ps.std_engine_clock = (pins[33] << 8) | pins[32];
158
159//temp. test to see some vals..
160	si->ps.max_video_vco = (pins[27] << 8) | pins[26];//LCLK
161	//feature flags:
162	si->ps.option_reg = (pins[53] << 24) | (pins[52] << 16) | (pins[51] << 8) | pins [50];
163
164	si->ps.max_dac2_clock = (pins[35] << 8) | pins[34];//clkmod
165	si->ps.max_dac2_clock_8 = (pins[37] << 8) | pins[36];//testclk
166	si->ps.max_dac2_clock_16 = (pins[39] << 8) | pins[38];//vgafreq1
167	si->ps.max_dac2_clock_24 = (pins[41] << 8) | pins[40];//vgafreq2
168	si->ps.max_dac2_clock_32 = (pins[55] << 8) | pins[54];//vga clock
169	si->ps.max_dac2_clock_32dh = pins[58];//vid ctrl
170
171	si->ps.max_dac1_clock = (pins[29] << 8) | pins[28];//clkbase
172	si->ps.max_dac1_clock_8 = (pins[31] << 8) | pins[30];//4mb
173	si->ps.max_dac1_clock_16 = (pins[33] << 8) | pins[32];//8mb
174	si->ps.max_dac1_clock_24 = pins[23];//ramdac type
175
176//test! Don't actually use the reported settings for now...
177	return B_OK;
178}
179
180status_t pins2_read(uint8 *pins, uint8 length)
181{
182	if (length != 64)
183	{
184		LOG(8,("INFO: wrong PINS length, expected 64, got %d\n", length));
185		return B_ERROR;
186	}
187
188	LOG(2,("INFO: PINS version 2 details not yet known\n"));
189	return B_ERROR;
190}
191
192/* pins v3 is used by G100 and G200. */
193status_t pins3_read(uint8 *pins, uint8 length)
194{
195	/* used to calculate RAM refreshrate */
196	float mclk_period;
197	uint32 rfhcnt;
198
199	if (length != 64)
200	{
201		LOG(8,("INFO: wrong PINS length, expected 64, got %d\n", length));
202		return B_ERROR;
203	}
204
205	/* fill out the shared info si->ps struct */
206	si->ps.max_pixel_vco = pins[36] + 100;
207
208	si->ps.max_dac1_clock_8 = pins[37] + 100;
209	si->ps.max_dac1_clock_16 = pins[38] + 100;
210	si->ps.max_dac1_clock_24 = pins[39] + 100;
211	si->ps.max_dac1_clock_32 = pins[40] + 100;
212
213	si->ps.std_engine_clock = pins[44];
214	if (pins [45] < si->ps.std_engine_clock) si->ps.std_engine_clock = pins[45];
215	if (pins [46] < si->ps.std_engine_clock) si->ps.std_engine_clock = pins[46];
216	if (pins [47] < si->ps.std_engine_clock) si->ps.std_engine_clock = pins[47];
217	if ((si->ps.card_type == G200) && (pins[58] & 0x04))
218	{
219		/* G200 can work without divisor */
220		si->ps.std_engine_clock *= 1;
221	}
222	else
223	{
224		if (pins[52] & 0x01)
225			si->ps.std_engine_clock *= 3;
226		else
227			si->ps.std_engine_clock *= 2;
228	}
229
230	if (pins[52] & 0x20) si->ps.f_ref = 14.31818;
231	else si->ps.f_ref = 27.00000;
232
233	/* G100 and G200 support 2-16Mb RAM */
234	si->ps.memory_size = 2 << ((pins[55] & 0xc0) >> 6);
235	/* more memory specifics */
236	si->ps.mctlwtst_reg = (pins[51] << 24) | (pins[50] << 16) | (pins[49] << 8) | pins [48];
237	si->ps.memrdbk_reg =
238		(pins[56] & 0x0f) | ((pins[56] & 0xf0) << 1) | ((pins[57] & 0x03) << 22) | ((pins[57] & 0xf0) << 21);
239	/* Mark did this as one step in the above stuff, which must be wrong:
240	((pins[p3_memrd+1]&0x03)>>2)<<16; //FIXME - ROR */
241
242	si->ps.v3_clk_div = pins[52];
243	si->ps.v3_mem_type = pins[54];
244	si->ps.v3_option2_reg = pins[58];
245
246	/* for cards using this version of PINS both functions are in maven */
247	si->ps.tvout = !(pins[59] & 0x01);
248	/* beware of TVout add-on boards: test for the MAVEN ourself! */
249	if (i2c_maven_probe() == B_OK)
250	{
251		si->ps.tvout = true;
252	}
253
254	/* G200 and earlier cards are always singlehead cards */
255	si->ps.secondary_head = false;
256	if (si->ps.card_type >= G400) si->ps.secondary_head = !(pins[59] & 0x01);
257
258	/* setup via gathered info from pins */
259	si->ps.option_reg = 0;
260	/* calculate refresh timer info-bits for 15uS interval (or shorter). See G100/G200 specs */
261	/* calculate std memory clock period (nS) */
262	if ((si->ps.card_type == G200) && (pins[58] & 0x08))
263	{
264		/* G200 can work without Mclk divisor */
265		mclk_period = 1000.0 / si->ps.std_engine_clock;
266	}
267	else
268	{
269		if (pins[52] & 0x02)
270			/* this factor is only used on G200, not on G100 */
271			mclk_period = 3000.0 / si->ps.std_engine_clock;
272		else
273			mclk_period = 2000.0 / si->ps.std_engine_clock;
274	}
275	/* calculate needed setting, 'round-down' result! */
276	rfhcnt = (uint32)(((15000 / mclk_period) - 1) / 64);
277	/* check for register limit */
278	if (rfhcnt > 0x3f) rfhcnt = 0x3f;
279	/* add to option register */
280	si->ps.option_reg |= (rfhcnt << 15);
281	/* the rest of the OPTION info for pins v3 comes via 'v3_clk_div' and 'v3_mem_type'. */
282
283	/* assuming the only possible panellink will be on the first head */
284	si->ps.primary_dvi = !(pins[59] & 0x40);
285	/* logical consequence of the above */
286	si->ps.secondary_dvi = false;
287
288	/* indirect logical consequences, see also G100 and G200 specs */
289	si->ps.max_system_vco = si->ps.max_pixel_vco;
290	si->ps.max_dac1_clock = si->ps.max_dac1_clock_8;
291	si->ps.max_dac1_clock_32dh = si->ps.max_dac1_clock_32;
292	si->ps.std_engine_clock_dh = si->ps.std_engine_clock;
293	si->ps.sdram = (si->ps.v3_clk_div & 0x10);
294	/* not supported: */
295	si->ps.max_dac2_clock_8 = 0;
296	si->ps.max_dac2_clock_24 = 0;
297	/* see G100, G200 and G400 specs */
298	si->ps.min_system_vco = 50;
299	si->ps.min_pixel_vco = 50;
300	/* fixme: ehhh, no specs: confirm/tune these by testing?! */
301	si->ps.max_video_vco = si->ps.max_pixel_vco;
302	si->ps.min_video_vco = 50;
303	/* assuming G100, G200 MAVEN has same specs as G400 MAVEN */
304	si->ps.max_dac2_clock = 136;
305	si->ps.max_dac2_clock_16 = 136;
306	si->ps.max_dac2_clock_32dh = 136;
307	si->ps.max_dac2_clock_32 = 136;
308
309	/* not used here: */
310	si->ps.option2_reg = 0;
311	si->ps.option3_reg = 0;
312	si->ps.option4_reg = 0;
313	si->ps.v5_mem_type = 0;
314	return B_OK;
315}
316
317/* pins v4 is used by G400 and G400MAX */
318status_t pins4_read(uint8 *pins, uint8 length)
319{
320	/* used to calculate RAM refreshrate */
321	float mclk_period;
322	uint32 rfhcnt;
323
324	if (length != 128)
325	{
326		LOG(8,("INFO: wrong PINS length, expected 128, got %d\n", length));
327		return B_ERROR;
328	}
329
330	/* fill out the shared info si->ps struct */
331	if (pins[39] == 0xff) si->ps.max_pixel_vco = 230;
332	else si->ps.max_pixel_vco = 4 * pins[39];
333
334	if (pins[38] == 0xff) si->ps.max_system_vco = si->ps.max_pixel_vco;
335	else si->ps.max_system_vco = 4 * pins[38];
336
337	if (pins[40] == 0xff) si->ps.max_dac1_clock_8 = si->ps.max_pixel_vco;
338	else si->ps.max_dac1_clock_8 = 4 * pins[40];
339
340	if (pins[41] == 0xff) si->ps.max_dac1_clock_16 = si->ps.max_dac1_clock_8;
341	else si->ps.max_dac1_clock_16 = 4 * pins[41];
342
343	if (pins[42] == 0xff) si->ps.max_dac1_clock_24 = si->ps.max_dac1_clock_16;
344	else si->ps.max_dac1_clock_24 = 4 * pins[42];
345
346	if (pins[43] == 0xff) si->ps.max_dac1_clock_32 = si->ps.max_dac1_clock_24;
347	else si->ps.max_dac1_clock_32 = 4 * pins[43];
348
349	if (pins[44] == 0xff) si->ps.max_dac2_clock_16 = si->ps.max_pixel_vco;
350	else si->ps.max_dac2_clock_16 = 4 * pins[44];
351
352	if (pins[45] == 0xff) si->ps.max_dac2_clock_32 = si->ps.max_dac2_clock_16;
353	else si->ps.max_dac2_clock_32 = 4 * pins[45];
354
355	/* verified against windows driver: */
356	si->ps.std_engine_clock = 2 * pins[65];
357
358	if (pins[92] & 0x01) si->ps.f_ref = 14.31818;
359	else si->ps.f_ref = 27.00000;
360
361	si->ps.memory_size = 4 << ((pins[92] >> 2) & 0x03);
362	/* more memory specifics */
363	si->ps.mctlwtst_reg = (pins[74] << 24) | (pins[73] << 16) | (pins[72] << 8) | pins [71];
364	si->ps.option3_reg = (pins[70] << 24) | (pins[69] << 16) | (pins[68] << 8) | pins [67];
365	/* mrsopcod field, msb is always zero.. */
366	si->ps.memrdbk_reg =
367		(pins[86] & 0x0f) | ((pins[86] & 0xf0) << 1) | ((pins[87] & 0x03) << 22) | ((pins[87] & 0xf0) << 21);
368	si->ps.sdram = (pins[92] & 0x10);
369
370	/* setup via gathered info from pins */
371	si->ps.option_reg = ((pins[53] & 0x38) << 7) | ((pins[53] & 0x40) << 22) | ((pins[53] & 0x80) << 15);
372	/* calculate refresh timer info-bits for 15uS interval (or shorter). See G400 specs;
373	 * the 15uS value was confirmed by Mark Watson for both G400 and G400MAX */
374	/* calculate std memory clock period (nS) */
375	switch ((si->ps.option3_reg & 0x0000e000) >> 13)
376	{
377	case 0:
378		mclk_period = 3000.0 / (si->ps.std_engine_clock * 1);
379		break;
380	case 1:
381		mclk_period = 5000.0 / (si->ps.std_engine_clock * 2);
382		break;
383	case 2:
384		mclk_period = 9000.0 / (si->ps.std_engine_clock * 4);
385		break;
386	case 3:
387		mclk_period = 2000.0 / (si->ps.std_engine_clock * 1);
388		break;
389	case 4:
390		mclk_period = 3000.0 / (si->ps.std_engine_clock * 2);
391		break;
392	case 5:
393		mclk_period = 1000.0 / (si->ps.std_engine_clock * 1);
394		break;
395	default:
396		/* we choose the lowest refreshcount that could be needed (so assuming slowest clocked memory) */
397		mclk_period = 3000.0 / (si->ps.std_engine_clock * 1);
398		LOG(8,("INFO: undefined/unknown memory clock divider select, using failsafe for refresh\n"));
399		break;
400	}
401	/* calculate needed setting, 'round-down' result! */
402	rfhcnt = (uint32)(((15000 / mclk_period) - 1) / 64);
403	/* check for register limit */
404	if (rfhcnt > 0x3f) rfhcnt = 0x3f;
405	/* add to option register */
406	si->ps.option_reg |= (rfhcnt << 15);
407
408	/* for cards using this version of PINS both functions are in maven */
409	si->ps.tvout = !(pins[91] & 0x01);
410	/* beware of TVout add-on boards: test for the MAVEN ourself! */
411	if (i2c_maven_probe() == B_OK)
412	{
413		si->ps.tvout = true;
414	}
415
416	/* G200 and earlier cards are always singlehead cards */
417	si->ps.secondary_head = false;
418	if (si->ps.card_type >= G400) si->ps.secondary_head = !(pins[91] & 0x01);
419
420	/* assuming the only possible panellink will be on the first head */
421	si->ps.primary_dvi = !(pins[91] & 0x40);
422	/* logical consequence of the above */
423	si->ps.secondary_dvi = false;
424
425	/* indirect logical consequences, see also G100, G200 and G400 specs */
426	si->ps.max_dac1_clock = si->ps.max_dac1_clock_8;
427	si->ps.max_dac2_clock = si->ps.max_dac2_clock_16;
428	si->ps.max_dac1_clock_32dh = si->ps.max_dac1_clock_32;
429	si->ps.max_dac2_clock_32dh = si->ps.max_dac2_clock_32;
430	si->ps.std_engine_clock_dh = si->ps.std_engine_clock;
431	/* not supported: */
432	si->ps.max_dac2_clock_8 = 0;
433	si->ps.max_dac2_clock_24 = 0;
434	/* see G100, G200 and G400 specs */
435	si->ps.min_system_vco = 50;
436	si->ps.min_pixel_vco = 50;
437	/* fixme: ehhh, no specs: confirm/tune these by testing?! */
438	si->ps.max_video_vco = si->ps.max_pixel_vco;
439	si->ps.min_video_vco = 50;
440
441	/* not used here: */
442	si->ps.option2_reg = 0;
443	si->ps.option4_reg = 0;
444	si->ps.v3_option2_reg = 0;
445	si->ps.v3_clk_div = 0;
446	si->ps.v3_mem_type = 0;
447	si->ps.v5_mem_type = 0;
448
449	/* check for a G400MAX card */
450	/* fixme: use the PCI configspace ID method if it exists... */
451	if (si->ps.max_dac1_clock > 300)
452	{
453		si->ps.card_type = G400MAX;
454		LOG(2,("INFO: G400MAX detected\n"));
455	}
456	return B_OK;
457}
458
459/* pins v5 is used by G450 and G550 */
460status_t pins5_read(uint8 *pins, uint8 length)
461{
462	unsigned int m_factor = 6;
463
464	if (length != 128)
465	{
466		LOG(8,("INFO: wrong PINS length, expected 128, got %d\n", length));
467		return B_ERROR;
468	}
469
470	/* fill out the shared info si->ps struct */
471	if (pins[4] == 0x01) m_factor = 8;
472	if (pins[4] >= 0x02) m_factor = 10;
473
474	si->ps.max_system_vco = m_factor * pins[36];
475	si->ps.max_video_vco = m_factor * pins[37];
476	si->ps.max_pixel_vco = m_factor * pins[38];
477	si->ps.min_system_vco = m_factor * pins[121];
478	si->ps.min_video_vco = m_factor * pins[122];
479	si->ps.min_pixel_vco = m_factor * pins[123];
480
481	if (pins[39] == 0xff) si->ps.max_dac1_clock_8 = si->ps.max_pixel_vco;
482	else si->ps.max_dac1_clock_8 = 4 * pins[39];
483
484	if (pins[40] == 0xff) si->ps.max_dac1_clock_16 = si->ps.max_dac1_clock_8;
485	else si->ps.max_dac1_clock_16 = 4 * pins[40];
486
487	if (pins[41] == 0xff) si->ps.max_dac1_clock_24 = si->ps.max_dac1_clock_16;
488	else si->ps.max_dac1_clock_24 = 4 * pins[41];
489
490	if (pins[42] == 0xff) si->ps.max_dac1_clock_32 = si->ps.max_dac1_clock_24;
491	else si->ps.max_dac1_clock_32 = 4 * pins[42];
492
493	if (pins[124] == 0xff) si->ps.max_dac1_clock_32dh = si->ps.max_dac1_clock_32;
494	else si->ps.max_dac1_clock_32dh = 4 * pins[124];
495
496	if (pins[43] == 0xff) si->ps.max_dac2_clock_16 = si->ps.max_video_vco;
497	else si->ps.max_dac2_clock_16 = 4 * pins[43];
498
499	if (pins[44] == 0xff) si->ps.max_dac2_clock_32 = si->ps.max_dac2_clock_16;
500	else si->ps.max_dac2_clock_32 = 4 * pins[44];
501
502	if (pins[125] == 0xff) si->ps.max_dac2_clock_32dh = si->ps.max_dac2_clock_32;
503	else si->ps.max_dac2_clock_32dh = 4 * pins[125];
504
505	if (pins[118] == 0xff) si->ps.max_dac1_clock = si->ps.max_dac1_clock_8;
506	else si->ps.max_dac1_clock = 4 * pins[118];
507
508	if (pins[119] == 0xff) si->ps.max_dac2_clock = si->ps.max_dac1_clock;
509	else si->ps.max_dac2_clock = 4 * pins[119];
510
511	si->ps.std_engine_clock = 4 * pins[74];
512	si->ps.std_engine_clock_dh = 4 * pins[92];
513
514	si->ps.memory_size = ((pins[114] & 0x03) + 1) * 8;
515	if ((pins[114] & 0x07) > 3)
516	{
517		LOG(8,("INFO: unknown RAM size, defaulting to 8Mb\n"));
518		si->ps.memory_size = 8;
519	}
520
521	if (pins[110] & 0x01) si->ps.f_ref = 14.31818;
522	else si->ps.f_ref = 27.00000;
523
524	/* make sure SGRAM functions only get enabled if SGRAM mounted */
525	if ((pins[114] & 0x18) == 0x08) si->ps.sdram = false;
526	else si->ps.sdram = true;
527	/* more memory specifics */
528	si->ps.v5_mem_type = (pins[115] << 8) | pins [114];
529
530	/* various registers */
531	si->ps.option_reg = (pins[51] << 24) | (pins[50] << 16) | (pins[49] << 8) | pins [48];
532	si->ps.option2_reg = (pins[55] << 24) | (pins[54] << 16) | (pins[53] << 8) | pins [52];
533	si->ps.option3_reg = (pins[79] << 24) | (pins[78] << 16) | (pins[77] << 8) | pins [76];
534	si->ps.option4_reg = (pins[87] << 24) | (pins[86] << 16) | (pins[85] << 8) | pins [84];
535	si->ps.mctlwtst_reg = (pins[83] << 24) | (pins[82] << 16) | (pins[81] << 8) | pins [80];
536	si->ps.memrdbk_reg = (pins[91] << 24) | (pins[90] << 16) | (pins[89] << 8) | pins [88];
537
538	/* both the secondary head and MAVEN are on die, (so) no add-on boards exist */
539	si->ps.secondary_head = (pins[117] & 0x70);
540	si->ps.tvout = (pins[117] & 0x40);
541
542	si->ps.primary_dvi = (pins[117] & 0x02);
543	si->ps.secondary_dvi = (pins[117] & 0x20);
544
545	/* not supported: */
546	si->ps.max_dac2_clock_8 = 0;
547	si->ps.max_dac2_clock_24 = 0;
548
549	/* not used here: */
550	si->ps.v3_option2_reg = 0;
551	si->ps.v3_clk_div = 0;
552	si->ps.v3_mem_type = 0;
553	return B_OK;
554}
555
556/* fake_pins presumes the card was coldstarted by it's BIOS */
557void fake_pins(void)
558{
559	LOG(8,("INFO: faking PINS\n"));
560
561	switch (si->ps.card_type)
562	{
563		case MIL1:
564			pinsmil1_fake();
565			break;
566		case MIL2:
567			pinsmil2_fake();
568			break;
569		case G100:
570			pinsg100_fake();
571			break;
572		case G200:
573			pinsg200_fake();
574			break;
575		case G400:
576			pinsg400_fake();
577			break;
578		case G400MAX:
579			pinsg400max_fake();
580			break;
581		case G450:
582			pinsg450_fake();
583			break;
584		case G550:
585			pinsg550_fake();
586			break;
587	}
588
589	/* find out if the card has a maven */
590	si->ps.tvout = false;
591	si->ps.secondary_head = false;
592	/* only do I2C probe if the card has a chance */
593	if (si->ps.card_type >= G100)
594	{
595		if (i2c_maven_probe() == B_OK)
596		{
597			si->ps.tvout = true;
598			/* G200 and earlier cards are always singlehead cards */
599			if (si->ps.card_type >= G400) si->ps.secondary_head = true;
600		}
601	}
602
603	/* not used because no coldstart will be attempted */
604	si->ps.std_engine_clock = 0;
605	si->ps.std_engine_clock_dh = 0;
606	si->ps.mctlwtst_reg = 0;
607	si->ps.memrdbk_reg = 0;
608	si->ps.option_reg = 0;
609	si->ps.option2_reg = 0;
610	si->ps.option3_reg = 0;
611	si->ps.option4_reg = 0;
612	si->ps.v3_option2_reg = 0;
613	si->ps.v3_clk_div = 0;
614	si->ps.v3_mem_type = 0;
615	si->ps.v5_mem_type = 0;
616}
617
618void pinsmil1_fake(void)
619{
620	/* 'worst case' scenario defaults, overrule-able via mga.settings if needed */
621
622	si->ps.f_ref = 14.31818;
623	/* see MIL1 specs */
624	si->ps.max_system_vco = 220;
625	si->ps.min_system_vco = 110;
626	si->ps.max_pixel_vco = 220;
627	si->ps.min_pixel_vco = 110;
628	/* no specs, assuming these */
629	si->ps.max_video_vco = 0;
630	si->ps.min_video_vco = 0;
631	/* see MIL1 specs */
632	si->ps.max_dac1_clock = 220;
633	si->ps.max_dac1_clock_8 = 220;
634	si->ps.max_dac1_clock_16 = 200;
635	/* 'failsave' values */
636	si->ps.max_dac1_clock_24 = 180;
637	si->ps.max_dac1_clock_32 = 136;
638	si->ps.max_dac1_clock_32dh = 0;
639	/* see specs */
640	si->ps.max_dac2_clock = 0;
641	si->ps.max_dac2_clock_8 = 0;
642	si->ps.max_dac2_clock_16 = 0;
643	si->ps.max_dac2_clock_24 = 0;
644	si->ps.max_dac2_clock_32 = 0;
645	/* 'failsave' value */
646	si->ps.max_dac2_clock_32dh = 0;
647	si->ps.primary_dvi = false;
648	si->ps.secondary_dvi = false;
649	/*  presume 2Mb RAM mounted */
650	//fixme: see if we can get this from OPTION or so...
651	si->ps.memory_size = 2;
652	//fixme: should be overrule-able via mga.settings for MIL1.
653	//fail-safe mode for now:
654	si->ps.sdram = true;
655}
656
657void pinsmil2_fake(void)
658{
659	/* 'worst case' scenario defaults, overrule-able via mga.settings if needed */
660
661	si->ps.f_ref = 14.31818;
662	/* see MIL2 specs */
663	si->ps.max_system_vco = 220;
664	si->ps.min_system_vco = 110;
665	si->ps.max_pixel_vco = 220;
666	si->ps.min_pixel_vco = 110;
667	/* no specs, assuming these */
668	si->ps.max_video_vco = 0;
669	si->ps.min_video_vco = 0;
670	/* see MIL2 specs */
671	si->ps.max_dac1_clock = 220;
672	si->ps.max_dac1_clock_8 = 220;
673	si->ps.max_dac1_clock_16 = 200;
674	/* 'failsave' values */
675	si->ps.max_dac1_clock_24 = 180;
676	si->ps.max_dac1_clock_32 = 136;
677	si->ps.max_dac1_clock_32dh = 0;
678	/* see specs */
679	si->ps.max_dac2_clock = 0;
680	si->ps.max_dac2_clock_8 = 0;
681	si->ps.max_dac2_clock_16 = 0;
682	si->ps.max_dac2_clock_24 = 0;
683	si->ps.max_dac2_clock_32 = 0;
684	/* 'failsave' value */
685	si->ps.max_dac2_clock_32dh = 0;
686	si->ps.primary_dvi = false;
687	si->ps.secondary_dvi = false;
688	/*  presume 4Mb RAM mounted */
689	//fixme: see if we can get this from OPTION or so...
690	si->ps.memory_size = 4;
691	//fixme: should be overrule-able via mga.settings for MIL2.
692	//fail-safe mode for now:
693	si->ps.sdram = true;
694}
695
696void pinsg100_fake(void)
697{
698	/* 'worst case' scenario defaults, overrule-able via mga.settings if needed */
699
700	//fixme: should be overrule-able via mga.settings.
701	si->ps.f_ref = 27.000;
702	/* see G100 specs */
703	si->ps.max_system_vco = 230;
704	si->ps.min_system_vco = 50;
705	si->ps.max_pixel_vco = 230;
706	si->ps.min_pixel_vco = 50;
707	/* no specs, assuming these */
708	si->ps.max_video_vco = 230;
709	si->ps.min_video_vco = 50;
710	/* see G100 specs */
711	si->ps.max_dac1_clock = 230;
712	si->ps.max_dac1_clock_8 = 230;
713	si->ps.max_dac1_clock_16 = 230;
714	/* 'failsave' values */
715	si->ps.max_dac1_clock_24 = 180;
716	si->ps.max_dac1_clock_32 = 136;
717	si->ps.max_dac1_clock_32dh = 136;
718	/* see specs */
719	si->ps.max_dac2_clock = 136;
720	si->ps.max_dac2_clock_8 = 0;
721	si->ps.max_dac2_clock_16 = 136;
722	si->ps.max_dac2_clock_24 = 0;
723	si->ps.max_dac2_clock_32 = 136;
724	/* 'failsave' value */
725	si->ps.max_dac2_clock_32dh = 136;
726	/* assuming the only possible panellink will be on the first head */
727	//fixme: primary_dvi should be overrule-able via mga.settings for G100.
728	si->ps.primary_dvi = false;
729	si->ps.secondary_dvi = false;
730	/*  presume 2Mb RAM mounted */
731	si->ps.memory_size = 2;
732	//fixme: should be overrule-able via mga.settings for G100.
733	//fail-safe mode for now:
734	si->ps.sdram = true;
735}
736
737void pinsg200_fake(void)
738{
739	/* 'worst case' scenario defaults, overrule-able via mga.settings if needed */
740
741	//fixme: should be overrule-able via mga.settings.
742	si->ps.f_ref = 27.000;
743	/* see G200 specs */
744	si->ps.max_system_vco = 250;
745	si->ps.min_system_vco = 50;
746	si->ps.max_pixel_vco = 250;
747	si->ps.min_pixel_vco = 50;
748	/* no specs, assuming these */
749	si->ps.max_video_vco = 250;
750	si->ps.min_video_vco = 50;
751	/* see G200 specs */
752	si->ps.max_dac1_clock = 250;
753	si->ps.max_dac1_clock_8 = 250;
754	si->ps.max_dac1_clock_16 = 250;
755	/* 'failsave' values */
756	si->ps.max_dac1_clock_24 = 180;
757	si->ps.max_dac1_clock_32 = 136;
758	si->ps.max_dac1_clock_32dh = 136;
759	/* see specs */
760	si->ps.max_dac2_clock = 136;
761	si->ps.max_dac2_clock_8 = 0;
762	si->ps.max_dac2_clock_16 = 136;
763	si->ps.max_dac2_clock_24 = 0;
764	si->ps.max_dac2_clock_32 = 136;
765	/* 'failsave' value */
766	si->ps.max_dac2_clock_32dh = 136;
767	/* assuming the only possible panellink will be on the first head */
768	//fixme: primary_dvi should be overrule-able via mga.settings for G100.
769	si->ps.primary_dvi = false;
770	si->ps.secondary_dvi = false;
771	/*  presume 2Mb RAM mounted */
772	si->ps.memory_size = 2;
773	/* ask the G200 what type of RAM it has been set to by it's BIOS */
774	si->ps.sdram = !(CFGR(OPTION) & 0x00004000);
775}
776
777void pinsg400_fake(void)
778{
779	/* 'worst case' scenario defaults, overrule-able via mga.settings if needed */
780
781	//fixme: should be overrule-able via mga.settings.
782	si->ps.f_ref = 27.000;
783	/* see G400 specs */
784	si->ps.max_system_vco = 300;
785	si->ps.min_system_vco = 50;
786	si->ps.max_pixel_vco = 300;
787	si->ps.min_pixel_vco = 50;
788	/* no specs, assuming these */
789	si->ps.max_video_vco = 300;
790	si->ps.min_video_vco = 50;
791	/* see G400 specs */
792	si->ps.max_dac1_clock = 300;
793	si->ps.max_dac1_clock_8 = 300;
794	si->ps.max_dac1_clock_16 = 300;
795	/* 'failsave' values */
796	si->ps.max_dac1_clock_24 = 230;
797	si->ps.max_dac1_clock_32 = 180;
798	si->ps.max_dac1_clock_32dh = 136;
799	/* see specs */
800	si->ps.max_dac2_clock = 136;
801	si->ps.max_dac2_clock_8 = 0;
802	si->ps.max_dac2_clock_16 = 136;
803	si->ps.max_dac2_clock_24 = 0;
804	si->ps.max_dac2_clock_32 = 136;
805	/* 'failsave' value */
806	si->ps.max_dac2_clock_32dh = 136;
807	/* assuming the only possible panellink will be on the first head */
808	//fixme: primary_dvi should be overrule-able via mga.settings for G400.
809	si->ps.primary_dvi = false;
810	si->ps.secondary_dvi = false;
811	/*  presume 4Mb RAM mounted */
812	si->ps.memory_size = 4;
813	/* ask the G400 what type of RAM it has been set to by it's BIOS */
814	si->ps.sdram = !(CFGR(OPTION) & 0x00004000);
815}
816
817/* this routine is currently unused, because G400MAX is detected via pins! */
818void pinsg400max_fake(void)
819{
820	/* 'worst case' scenario defaults, overrule-able via mga.settings if needed */
821
822	//fixme: should be overrule-able via mga.settings.
823	si->ps.f_ref = 27.000;
824	/* see G400MAX specs */
825	si->ps.max_system_vco = 360;
826	si->ps.min_system_vco = 50;
827	si->ps.max_pixel_vco = 360;
828	si->ps.min_pixel_vco = 50;
829	/* no specs, assuming these */
830	si->ps.max_video_vco = 360;
831	si->ps.min_video_vco = 50;
832	/* see G400MAX specs */
833	si->ps.max_dac1_clock = 360;
834	si->ps.max_dac1_clock_8 = 360;
835	si->ps.max_dac1_clock_16 = 360;
836	/* 'failsave' values */
837	si->ps.max_dac1_clock_24 = 280;
838	si->ps.max_dac1_clock_32 = 230;
839	si->ps.max_dac1_clock_32dh = 136;
840	/* see specs */
841	si->ps.max_dac2_clock = 136;
842	si->ps.max_dac2_clock_8 = 0;
843	si->ps.max_dac2_clock_16 = 136;
844	si->ps.max_dac2_clock_24 = 0;
845	si->ps.max_dac2_clock_32 = 136;
846	/* 'failsave' value */
847	si->ps.max_dac2_clock_32dh = 136;
848	/* assuming the only possible panellink will be on the first head */
849	//fixme: primary_dvi should be overrule-able via mga.settings for G400MAX.
850	si->ps.primary_dvi = false;
851	si->ps.secondary_dvi = false;
852	/*  presume 4Mb RAM mounted */
853	si->ps.memory_size = 4;
854	/* ask the G400MAX what type of RAM it has been set to by it's BIOS */
855	si->ps.sdram = !(CFGR(OPTION) & 0x00004000);
856}
857
858void pinsg450_fake(void)
859{
860	/* 'worst case' scenario defaults, overrule-able via mga.settings if needed */
861
862	//fixme: should be overrule-able via mga.settings.
863	si->ps.f_ref = 27.000;
864	/* see G450 pins readouts for max ranges, then use a bit smaller ones */
865	/* carefull not to take to high lower limits, and high should be >= 2x low. */
866	si->ps.max_system_vco = 640;
867	si->ps.min_system_vco = 320;
868	si->ps.max_pixel_vco = 640;
869	si->ps.min_pixel_vco = 320;
870	si->ps.max_video_vco = 640;
871	si->ps.min_video_vco = 320;
872	si->ps.max_dac1_clock = 360;
873	si->ps.max_dac1_clock_8 = 360;
874	si->ps.max_dac1_clock_16 = 360;
875	/* 'failsave' values */
876	si->ps.max_dac1_clock_24 = 280;
877	si->ps.max_dac1_clock_32 = 230;
878	si->ps.max_dac1_clock_32dh = 180;
879	/* see G450 pins readouts */
880	si->ps.max_dac2_clock = 232;
881	si->ps.max_dac2_clock_8 = 0;
882	si->ps.max_dac2_clock_16 = 232;
883	si->ps.max_dac2_clock_24 = 0;
884	si->ps.max_dac2_clock_32 = 232;
885	/* 'failsave' values */
886	si->ps.max_dac2_clock_32dh = 180;
887	//fixme: primary & secondary_dvi should be overrule-able via mga.settings for G450.
888	si->ps.primary_dvi = false;
889	si->ps.secondary_dvi = false;
890	/*  presume 8Mb RAM mounted */
891	si->ps.memory_size = 8;
892	/* ask the G450 what type of RAM it has been set to by it's BIOS */
893//todo:
894//	si->ps.sdram = !(CFGR(OPTION) & 0x00004000);
895//fail-safe mode for now:
896	si->ps.sdram = true;
897}
898
899void pinsg550_fake(void)
900{
901	/* 'worst case' scenario defaults, overrule-able via mga.settings if needed */
902
903	//fixme: should be overrule-able via mga.settings.
904	si->ps.f_ref = 27.000;
905	/* see G550 pins readouts for max ranges, then use a bit smaller ones */
906	/* carefull not to take to high lower limits, and high should be >= 2x low. */
907	si->ps.max_system_vco = 768;
908	si->ps.min_system_vco = 384;
909	si->ps.max_pixel_vco = 960;
910	si->ps.min_pixel_vco = 320;
911	si->ps.max_video_vco = 960;
912	si->ps.min_video_vco = 320;
913	si->ps.max_dac1_clock = 360;
914	si->ps.max_dac1_clock_8 = 360;
915	si->ps.max_dac1_clock_16 = 360;
916	/* 'failsave' values */
917	si->ps.max_dac1_clock_24 = 280;
918	si->ps.max_dac1_clock_32 = 230;
919	si->ps.max_dac1_clock_32dh = 180;
920	/* see G550 pins readouts */
921	si->ps.max_dac2_clock = 232;
922	si->ps.max_dac2_clock_8 = 0;
923	si->ps.max_dac2_clock_16 = 232;
924	si->ps.max_dac2_clock_24 = 0;
925	si->ps.max_dac2_clock_32 = 232;
926	/* 'failsave' values */
927	si->ps.max_dac2_clock_32dh = 180;
928	//fixme: primary & secondary_dvi should be overrule-able via mga.settings for G550.
929	si->ps.primary_dvi = false;
930	si->ps.secondary_dvi = false;
931	/*  presume 8Mb RAM mounted */
932	si->ps.memory_size = 8;
933	/* ask the G550 what type of RAM it has been set to by it's BIOS */
934//todo:
935//	si->ps.sdram = !(CFGR(OPTION) & 0x00004000);
936//fail-safe mode for now:
937	si->ps.sdram = true;
938}
939
940void dump_pins(void)
941{
942	LOG(2,("INFO: pinsdump follows:\n"));
943	LOG(2,("f_ref: %fMhz\n", si->ps.f_ref));
944	LOG(2,("max_system_vco: %dMhz\n", si->ps.max_system_vco));
945	LOG(2,("min_system_vco: %dMhz\n", si->ps.min_system_vco));
946	LOG(2,("max_pixel_vco: %dMhz\n", si->ps.max_pixel_vco));
947	LOG(2,("min_pixel_vco: %dMhz\n", si->ps.min_pixel_vco));
948	LOG(2,("max_video_vco: %dMhz\n", si->ps.max_video_vco));
949	LOG(2,("min_video_vco: %dMhz\n", si->ps.min_video_vco));
950	LOG(2,("std_engine_clock: %dMhz\n", si->ps.std_engine_clock));
951	LOG(2,("std_engine_clock_dh: %dMhz\n", si->ps.std_engine_clock_dh));
952	LOG(2,("max_dac1_clock: %dMhz\n", si->ps.max_dac1_clock));
953	LOG(2,("max_dac1_clock_8: %dMhz\n", si->ps.max_dac1_clock_8));
954	LOG(2,("max_dac1_clock_16: %dMhz\n", si->ps.max_dac1_clock_16));
955	LOG(2,("max_dac1_clock_24: %dMhz\n", si->ps.max_dac1_clock_24));
956	LOG(2,("max_dac1_clock_32: %dMhz\n", si->ps.max_dac1_clock_32));
957	LOG(2,("max_dac1_clock_32dh: %dMhz\n", si->ps.max_dac1_clock_32dh));
958	LOG(2,("max_dac2_clock: %dMhz\n", si->ps.max_dac2_clock));
959	LOG(2,("max_dac2_clock_8: %dMhz\n", si->ps.max_dac2_clock_8));
960	LOG(2,("max_dac2_clock_16: %dMhz\n", si->ps.max_dac2_clock_16));
961	LOG(2,("max_dac2_clock_24: %dMhz\n", si->ps.max_dac2_clock_24));
962	LOG(2,("max_dac2_clock_32: %dMhz\n", si->ps.max_dac2_clock_32));
963	LOG(2,("max_dac2_clock_32dh: %dMhz\n", si->ps.max_dac2_clock_32dh));
964	LOG(2,("secondary_head: "));
965	if (si->ps.secondary_head) LOG(2,("present\n")); else LOG(2,("absent\n"));
966	LOG(2,("tvout: "));
967	if (si->ps.tvout) LOG(2,("present\n")); else LOG(2,("absent\n"));
968	//fixme: probably only valid for pre-G400 cards...(?)
969	if ((si->ps.tvout) && (si->ps.card_type < G450))
970	{
971		if (si->ps.card_type < G400)
972			LOG(2,("MGA_TVO version: "));
973		else
974			LOG(2,("MAVEN version: "));
975		if ((MAVR(VERSION)) < 20)
976			LOG(2,("rev. B\n"));
977		else
978			LOG(2,("rev. C\n"));
979	}
980	LOG(2,("primary_dvi: "));
981	if (si->ps.primary_dvi) LOG(2,("present\n")); else LOG(2,("absent\n"));
982	LOG(2,("secondary_dvi: "));
983	if (si->ps.secondary_dvi) LOG(2,("present\n")); else LOG(2,("absent\n"));
984	LOG(2,("card memory_size: %dMb\n", si->ps.memory_size));
985	LOG(2,("mctlwtst register: $%08x\n", si->ps.mctlwtst_reg));
986	LOG(2,("memrdbk register: $%08x\n", si->ps.memrdbk_reg));
987	LOG(2,("option register: $%08x\n", si->ps.option_reg));
988	LOG(2,("option2 register: $%08x\n", si->ps.option2_reg));
989	LOG(2,("option3 register: $%08x\n", si->ps.option3_reg));
990	LOG(2,("option4 register: $%08x\n", si->ps.option4_reg));
991	LOG(2,("v3_option2_reg: $%02x\n", si->ps.v3_option2_reg));
992	LOG(2,("v3_clock_div: $%02x\n", si->ps.v3_clk_div));
993	LOG(2,("v3_mem_type: $%02x\n", si->ps.v3_mem_type));
994	LOG(2,("v5_mem_type: $%04x\n", si->ps.v5_mem_type));
995	LOG(2,("sdram: "));
996	if (si->ps.sdram) LOG(2,("SDRAM card\n")); else LOG(2,("SGRAM card\n"));
997	LOG(2,("INFO: end pinsdump.\n"));
998}
999