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 */
parse_pins()13 status_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
pins1_read(uint8 * pins,uint8 length)112 status_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
pins2_read(uint8 * pins,uint8 length)180 status_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. */
pins3_read(uint8 * pins,uint8 length)193 status_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 */
pins4_read(uint8 * pins,uint8 length)318 status_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 */
pins5_read(uint8 * pins,uint8 length)460 status_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 */
fake_pins(void)557 void 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
pinsmil1_fake(void)618 void 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
pinsmil2_fake(void)657 void 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
pinsg100_fake(void)696 void 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
pinsg200_fake(void)737 void 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
pinsg400_fake(void)777 void 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! */
pinsg400max_fake(void)818 void 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
pinsg450_fake(void)858 void 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
pinsg550_fake(void)899 void 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
dump_pins(void)940 void 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