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 */ 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 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 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. */ 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 */ 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 */ 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 */ 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 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 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 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 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 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! */ 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 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 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 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