1 /* 2 Copyright (c) 2002, Thomas Kurschel 3 4 5 Part of Radeon kernel driver 6 7 BIOS detection and retrieval of vital data 8 9 Most of this data should be gathered directly, 10 especially monitor detection should be done on 11 demand so not all monitors need to be connected 12 during boot 13 */ 14 15 #include "radeon_driver.h" 16 #include "mmio.h" 17 #include "bios_regs.h" 18 #include "config_regs.h" 19 #include "memcntrl_regs.h" 20 #include "buscntrl_regs.h" 21 #include "fp_regs.h" 22 #include "crtc_regs.h" 23 #include "ddc_regs.h" 24 #include "radeon_bios.h" 25 #include "utils.h" 26 27 #include <stdio.h> 28 #include <string.h> 29 30 #define get_pci(o, s) (*pci_bus->read_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s)) 31 32 #define RADEON_BIOS8(v) (di->rom.rom_ptr[v]) 33 #define RADEON_BIOS16(v) ((di->rom.rom_ptr[v]) | \ 34 (di->rom.rom_ptr[(v) + 1] << 8)) 35 #define RADEON_BIOS32(v) ((di->rom.rom_ptr[v]) | \ 36 (di->rom.rom_ptr[(v) + 1] << 8) | \ 37 (di->rom.rom_ptr[(v) + 2] << 16) | \ 38 (di->rom.rom_ptr[(v) + 3] << 24)) 39 40 static const char ati_rom_sig[] = "761295520"; 41 42 static const tmds_pll_info default_tmds_pll[14][4] = 43 { 44 {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // r100 45 {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // rv100 46 {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, // rs100 47 {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // rv200 48 {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // rs200 49 {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, // r200 50 {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, // rv250 51 {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, // rs300 52 {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, // rv280 53 {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, // r300 54 {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, // r350 55 {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, // rv350 56 {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, // rv380 57 {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, // r420 58 }; 59 60 61 // find address of ROM; 62 // this code is really nasty as maintaining the radeon signatures 63 // is almost impossible (the signatures provided by ATI are always out-dated); 64 // further, if there is more then one card built into the computer, we 65 // may detect the wrong BIOS! 66 // we have two possible solutions: 67 // 1. use the PCI location as stored in BIOS 68 // 2. verify the IO-base address as stored in BIOS 69 // I have no clue how these values are _written_ into the BIOS, and 70 // unfortunately, every BIOS does the detection in a different way, 71 // so I'm not sure which is the _right_ way of doing it 72 static char *Radeon_FindRom( rom_info *ri ) 73 { 74 uint32 segstart; 75 uint8 *rom_base; 76 char *rom; 77 int i; 78 79 for( segstart = 0x000c0000; segstart < 0x000f0000; segstart += 0x00001000 ) { 80 bool found = false; 81 82 // find ROM 83 rom_base = ri->bios_ptr + segstart - 0xc0000; 84 85 if( rom_base[0] != 0x55 || rom_base[1] != 0xaa ) 86 continue; 87 88 // find signature of ATI 89 rom = rom_base; 90 91 found = false; 92 93 for( i = 0; i < 128 - strlen( ati_rom_sig ); i++ ) { 94 if( ati_rom_sig[0] == rom_base[i] ) { 95 if( strncmp(ati_rom_sig, rom_base + i, strlen( ati_rom_sig )) == 0 ) { 96 found = true; 97 break; 98 } 99 } 100 } 101 102 if( !found ) 103 continue; 104 105 // EK don't bother looking for signiture now, due to lack of consistancy. 106 107 SHOW_INFO( 2, "found ROM @0x%lx", segstart ); 108 return rom_base; 109 } 110 111 SHOW_INFO0( 2, "no ROM found" ); 112 return NULL; 113 } 114 115 116 // PLL info is stored in ROM, probably it's too easy to replace it 117 // and thus they produce cards with different timings 118 static void Radeon_GetPLLInfo( device_info *di ) 119 { 120 uint8 *bios_header; 121 uint8 *tmp; 122 PLL_BLOCK pll, *pll_info; 123 124 bios_header = di->rom.rom_ptr + *(uint16 *)(di->rom.rom_ptr + 0x48); 125 pll_info = (PLL_BLOCK *)(di->rom.rom_ptr + *(uint16 *)(bios_header + 0x30)); 126 127 // determine type of ROM 128 129 tmp = bios_header + 4; 130 131 if (( *tmp == 'A' 132 && *(tmp+1) == 'T' 133 && *(tmp+2) == 'O' 134 && *(tmp+3) == 'M' 135 ) 136 || 137 ( *tmp == 'M' 138 && *(tmp+1) == 'O' 139 && *(tmp+2) == 'T' 140 && *(tmp+3) == 'A' 141 )) 142 { 143 int bios_header, master_data_start, pll_start; 144 di->is_atombios = true; 145 146 bios_header = RADEON_BIOS16(0x48); 147 master_data_start = RADEON_BIOS16(bios_header + 32); 148 pll_start = RADEON_BIOS16(master_data_start + 12); 149 150 di->pll.ref_div = 0; 151 di->pll.max_pll_freq = RADEON_BIOS16(pll_start + 32); 152 di->pll.xclk = RADEON_BIOS16(pll_start + 72); 153 di->pll.min_pll_freq = RADEON_BIOS16(pll_start + 78); 154 di->pll.ref_freq = RADEON_BIOS16(pll_start + 82); 155 156 SHOW_INFO( 2, "TESTING ref_clk=%ld, ref_div=%ld, xclk=%ld, min_freq=%ld, max_freq=%ld from ATOM Bios", 157 di->pll.ref_freq, di->pll.ref_div, di->pll.xclk, 158 di->pll.min_pll_freq, di->pll.max_pll_freq ); 159 160 // Unused by beos driver so it appears... 161 // info->sclk = RADEON_BIOS32(pll_info_block + 8) / 100.0; 162 // info->mclk = RADEON_BIOS32(pll_info_block + 12) / 100.0; 163 // if (info->sclk == 0) info->sclk = 200; 164 // if (info->mclk == 0) info->mclk = 200; 165 166 } 167 else 168 { 169 di->is_atombios = false; 170 171 memcpy( &pll, pll_info, sizeof( pll )); 172 173 di->pll.xclk = (uint32)pll.XCLK; 174 di->pll.ref_freq = (uint32)pll.PCLK_ref_freq; 175 di->pll.ref_div = (uint32)pll.PCLK_ref_divider; 176 di->pll.min_pll_freq = pll.PCLK_min_freq; 177 di->pll.max_pll_freq = pll.PCLK_max_freq; 178 179 SHOW_INFO( 2, "ref_clk=%ld, ref_div=%ld, xclk=%ld, min_freq=%ld, max_freq=%ld from Legacy BIOS", 180 di->pll.ref_freq, di->pll.ref_div, di->pll.xclk, 181 di->pll.min_pll_freq, di->pll.max_pll_freq ); 182 183 } 184 185 } 186 187 /* 188 const char *Mon2Str[] = { 189 "N/C", 190 "CRT", 191 "CRT", 192 "Laptop flatpanel", 193 "DVI (flatpanel)", 194 "secondary DVI (flatpanel) - unsupported", 195 "Composite TV", 196 "S-Video out" 197 };*/ 198 199 /* 200 // ask BIOS what kind of monitor is connected to each port 201 static void Radeon_GetMonType( device_info *di ) 202 { 203 unsigned int tmp; 204 205 SHOW_FLOW0( 3, "" ); 206 207 di->disp_type[0] = di->disp_type[1] = dt_none; 208 209 if (di->has_crtc2) { 210 tmp = INREG( di->regs, RADEON_BIOS_4_SCRATCH ); 211 212 // ordering of "if"s is important as multiple 213 // devices can be concurrently connected to one port 214 // (like both a CRT and a TV) 215 216 // primary port 217 // having flat-panel support is most important 218 if (tmp & 0x08) 219 di->disp_type[0] = dt_dvi; 220 else if (tmp & 0x4) 221 di->disp_type[0] = dt_lvds; 222 else if (tmp & 0x200) 223 di->disp_type[0] = dt_tv_crt; 224 else if (tmp & 0x10) 225 di->disp_type[0] = dt_ctv; 226 else if (tmp & 0x20) 227 di->disp_type[0] = dt_stv; 228 229 // secondary port 230 // having TV-Out support is more important then CRT support 231 // (CRT gets signal anyway) 232 if (tmp & 0x1000) 233 di->disp_type[1] = dt_ctv; 234 else if (tmp & 0x2000) 235 di->disp_type[1] = dt_stv; 236 else if (tmp & 0x2) 237 di->disp_type[1] = dt_crt; 238 else if (tmp & 0x800) 239 di->disp_type[1] = dt_dvi_ext; 240 else if (tmp & 0x400) 241 // this is unlikely - I only know about one LVDS unit 242 di->disp_type[1] = dt_lvds; 243 } else { 244 // regular Radeon 245 // TBD: no TV-Out detection 246 di->disp_type[0] = dt_none; 247 248 tmp = INREG( di->regs, RADEON_FP_GEN_CNTL); 249 250 if( tmp & RADEON_FP_EN_TMDS ) 251 di->disp_type[0] = dt_dvi; 252 else 253 di->disp_type[0] = dt_crt; 254 } 255 256 SHOW_INFO( 1, "BIOS reports %s on primary and %s on secondary port", 257 Mon2Str[di->disp_type[0]], Mon2Str[di->disp_type[1]]); 258 259 // remove unsupported devices 260 if( di->disp_type[0] >= dt_dvi_ext ) 261 di->disp_type[0] = dt_none; 262 if( di->disp_type[1] >= dt_dvi_ext ) 263 di->disp_type[1] = dt_none; 264 265 // HACK: overlays can only be shown on first CRTC; 266 // if there's nothing on first port, connect 267 // second port to first CRTC (proper signal routing 268 // is hopefully done by BIOS) 269 if( di->has_crtc2 ) { 270 if( di->disp_type[0] == dt_none && di->disp_type[1] == dt_crt ) { 271 di->disp_type[0] = dt_crt; 272 di->disp_type[1] = dt_none; 273 } 274 } 275 276 SHOW_INFO( 1, "Effective routing: %s on primary and %s on secondary port", 277 Mon2Str[di->disp_type[0]], Mon2Str[di->disp_type[1]]); 278 } 279 */ 280 281 282 static bool Radeon_GetConnectorInfoFromBIOS ( device_info* di ) 283 { 284 285 ptr_disp_entity ptr_entity = &di->routing; 286 int i = 0, j, tmp, tmp0=0, tmp1=0; 287 288 int bios_header, master_data_start; 289 290 bios_header = RADEON_BIOS16(0x48); 291 292 if (di->is_atombios) 293 { 294 master_data_start = RADEON_BIOS16( bios_header + 32 ); 295 tmp = RADEON_BIOS16( master_data_start + 22); 296 if (tmp) { 297 int crtc = 0, id[2]; 298 tmp1 = RADEON_BIOS16( tmp + 4 ); 299 for (i=0; i<8; i++) { 300 if(tmp1 & (1<<i)) { 301 uint16 portinfo = RADEON_BIOS16( tmp + 6 + i * 2 ); 302 if (crtc < 2) { 303 if ((i == 2) || (i == 6)) continue; /* ignore TV here */ 304 305 if ( crtc == 1 ) { 306 /* sharing same port with id[0] */ 307 if ((( portinfo >> 8) & 0xf) == id[0] ) { 308 if (i == 3) 309 ptr_entity->port_info[0].tmds_type = tmds_int; 310 else if (i == 7) 311 ptr_entity->port_info[0].tmds_type = tmds_ext; 312 313 if (ptr_entity->port_info[0].dac_type == dac_unknown) 314 ptr_entity->port_info[0].dac_type = (portinfo & 0xf) - 1; 315 continue; 316 } 317 } 318 319 id[crtc] = (portinfo>>8) & 0xf; 320 ptr_entity->port_info[crtc].dac_type = (portinfo & 0xf) - 1; 321 ptr_entity->port_info[crtc].connector_type = (portinfo>>4) & 0xf; 322 if (i == 3) 323 ptr_entity->port_info[crtc].tmds_type = tmds_int; 324 else if (i == 7) 325 ptr_entity->port_info[crtc].tmds_type = tmds_ext; 326 327 tmp0 = RADEON_BIOS16( master_data_start + 24); 328 if( tmp0 && id[crtc] ) { 329 switch (RADEON_BIOS16(tmp0 + 4 + 27 * id[crtc]) * 4) 330 { 331 case RADEON_GPIO_MONID: 332 ptr_entity->port_info[crtc].ddc_type = ddc_monid; 333 break; 334 case RADEON_GPIO_DVI_DDC: 335 ptr_entity->port_info[crtc].ddc_type = ddc_dvi; 336 break; 337 case RADEON_GPIO_VGA_DDC: 338 ptr_entity->port_info[crtc].ddc_type = ddc_vga; 339 break; 340 case RADEON_GPIO_CRT2_DDC: 341 ptr_entity->port_info[crtc].ddc_type = ddc_crt2; 342 break; 343 default: 344 ptr_entity->port_info[crtc].ddc_type = ddc_none_detected; 345 break; 346 } 347 348 } else { 349 ptr_entity->port_info[crtc].ddc_type = ddc_none_detected; 350 } 351 crtc++; 352 } else { 353 /* we have already had two CRTCs assigned. the rest may share the same 354 * port with the existing connector, fill in them accordingly. 355 */ 356 for ( j = 0; j < 2; j++ ) { 357 if ((( portinfo >> 8 ) & 0xf ) == id[j] ) { 358 if ( i == 3 ) 359 ptr_entity->port_info[j].tmds_type = tmds_int; 360 else if (i == 7) 361 ptr_entity->port_info[j].tmds_type = tmds_ext; 362 363 if ( ptr_entity->port_info[j].dac_type == dac_unknown ) 364 ptr_entity->port_info[j].dac_type = ( portinfo & 0xf ) - 1; 365 } 366 } 367 } 368 } 369 } 370 371 for (i=0; i<2; i++) { 372 SHOW_INFO( 2, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d", 373 i, ptr_entity->port_info[i].ddc_type, ptr_entity->port_info[i].dac_type, 374 ptr_entity->port_info[i].tmds_type, ptr_entity->port_info[i].connector_type); 375 } 376 } else { 377 SHOW_INFO0( 4 , "No Device Info Table found!"); 378 return FALSE; 379 } 380 } else { 381 /* Some laptops only have one connector (VGA) listed in the connector table, 382 * we need to add LVDS in as a non-DDC display. 383 * Note, we can't assume the listed VGA will be filled in PortInfo[0], 384 * when walking through connector table. connector_found has following meaning: 385 * 0 -- nothing found, 386 * 1 -- only PortInfo[0] filled, 387 * 2 -- only PortInfo[1] filled, 388 * 3 -- both are filled. 389 */ 390 int connector_found = 0; 391 392 if ((tmp = RADEON_BIOS16( bios_header + 0x50 ))) { 393 for ( i = 1; i < 4; i++ ) { 394 395 if (!(RADEON_BIOS16( tmp + i * 2 ))) 396 break; /* end of table */ 397 398 tmp0 = RADEON_BIOS16( tmp + i * 2 ); 399 if ((( tmp0 >> 12 ) & 0x0f ) == 0 ) 400 continue; /* no connector */ 401 if (connector_found > 0) { 402 if (ptr_entity->port_info[tmp1].ddc_type == (( tmp0 >> 8 ) & 0x0f )) 403 continue; /* same connector */ 404 } 405 406 /* internal ddc_dvi port will get assigned to portinfo[0], or if there is no ddc_dvi (like in some igps). */ 407 tmp1 = (((( tmp0 >> 8 ) & 0xf ) == ddc_dvi ) || ( tmp1 == 1 )) ? 0 : 1; /* determine port info index */ 408 409 ptr_entity->port_info[tmp1].ddc_type = (tmp0 >> 8) & 0x0f; 410 if (ptr_entity->port_info[tmp1].ddc_type > ddc_crt2) 411 ptr_entity->port_info[tmp1].ddc_type = ddc_none_detected; 412 ptr_entity->port_info[tmp1].dac_type = (tmp0 & 0x01) ? dac_tvdac : dac_primary; 413 ptr_entity->port_info[tmp1].connector_type = (tmp0 >> 12) & 0x0f; 414 if (ptr_entity->port_info[tmp1].connector_type > connector_unsupported) 415 ptr_entity->port_info[tmp1].connector_type = connector_unsupported; 416 ptr_entity->port_info[tmp1].tmds_type = ((tmp0 >> 4) & 0x01) ? tmds_ext : tmds_int; 417 418 /* some sanity checks */ 419 if (((ptr_entity->port_info[tmp1].connector_type != connector_dvi_d) && 420 (ptr_entity->port_info[tmp1].connector_type != connector_dvi_i)) && 421 ptr_entity->port_info[tmp1].tmds_type == tmds_int) 422 ptr_entity->port_info[tmp1].tmds_type = tmds_unknown; 423 424 connector_found += (tmp1 + 1); 425 } 426 } else { 427 SHOW_INFO0(4, "No Connector Info Table found!"); 428 return FALSE; 429 } 430 431 if (di->is_mobility) 432 { 433 /* For the cases where only one VGA connector is found, 434 we assume LVDS is not listed in the connector table, 435 add it in here as the first port. 436 */ 437 if ((connector_found < 3) && (ptr_entity->port_info[tmp1].connector_type == connector_crt)) { 438 if (connector_found == 1) { 439 memcpy (&ptr_entity->port_info[1], 440 &ptr_entity->port_info[0], 441 sizeof (ptr_entity->port_info[0])); 442 } 443 ptr_entity->port_info[0].dac_type = dac_tvdac; 444 ptr_entity->port_info[0].tmds_type = tmds_unknown; 445 ptr_entity->port_info[0].ddc_type = ddc_none_detected; 446 ptr_entity->port_info[0].connector_type = connector_proprietary; 447 448 SHOW_INFO0( 4 , "lvds port is not in connector table, added in."); 449 if (connector_found == 0) 450 connector_found = 1; 451 else 452 connector_found = 3; 453 } 454 455 if ((tmp = RADEON_BIOS16( bios_header + 0x42 ))) { 456 if ((tmp0 = RADEON_BIOS16( tmp + 0x15 ))) { 457 if ((tmp1 = RADEON_BIOS16( tmp0 + 2 ) & 0x07)) { 458 ptr_entity->port_info[0].ddc_type = tmp1; 459 if (ptr_entity->port_info[0].ddc_type > ddc_crt2) { 460 SHOW_INFO( 4, "unknown ddctype %d found", 461 ptr_entity->port_info[0].ddc_type); 462 ptr_entity->port_info[0].ddc_type = ddc_none_detected; 463 } 464 SHOW_INFO0( 4, "lcd ddc info table found!"); 465 } 466 } 467 } 468 } else if (connector_found == 2) { 469 memcpy (&ptr_entity->port_info[0], 470 &ptr_entity->port_info[1], 471 sizeof (ptr_entity->port_info[0])); 472 ptr_entity->port_info[1].dac_type = dac_unknown; 473 ptr_entity->port_info[1].tmds_type = tmds_unknown; 474 ptr_entity->port_info[1].ddc_type = ddc_none_detected; 475 ptr_entity->port_info[1].connector_type = connector_none; 476 connector_found = 1; 477 } 478 479 if (connector_found == 0) { 480 SHOW_INFO0( 4, "no connector found in connector info table."); 481 } else { 482 SHOW_INFO( 2, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d", 483 0, ptr_entity->port_info[0].ddc_type, ptr_entity->port_info[0].dac_type, 484 ptr_entity->port_info[0].tmds_type, ptr_entity->port_info[0].connector_type); 485 486 } 487 if (connector_found == 3) { 488 SHOW_INFO( 2, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d", 489 1, ptr_entity->port_info[1].ddc_type, ptr_entity->port_info[1].dac_type, 490 ptr_entity->port_info[1].tmds_type, ptr_entity->port_info[1].connector_type); 491 } 492 493 } 494 return TRUE; 495 } 496 497 498 // get flat panel info (does only make sense for Laptops 499 // with integrated display, but looking for it doesn't hurt, 500 // who knows which strange kind of combination is out there?) 501 static bool Radeon_GetBIOSDFPInfo( device_info *di ) 502 { 503 uint16 bios_header; 504 uint16 fpi_offset; 505 FPI_BLOCK fpi; 506 char panel_name[30]; 507 int i; 508 509 uint16 tmp; 510 511 bios_header = RADEON_BIOS16( 0x48 ); 512 513 if (di->is_atombios) 514 { 515 int master_data_start; 516 master_data_start = RADEON_BIOS16( bios_header + 32 ); 517 518 tmp = RADEON_BIOS16( master_data_start + 16 ); 519 if( tmp ) 520 { 521 522 di->fp_info.panel_xres = RADEON_BIOS16( tmp + 6 ); 523 di->fp_info.panel_yres = RADEON_BIOS16( tmp + 10 ); 524 di->fp_info.dot_clock = RADEON_BIOS16( tmp + 4 ) * 10; 525 di->fp_info.h_blank = RADEON_BIOS16( tmp + 8 ); 526 di->fp_info.h_over_plus = RADEON_BIOS16( tmp + 14 ); 527 di->fp_info.h_sync_width = RADEON_BIOS16( tmp + 16 ); 528 di->fp_info.v_blank = RADEON_BIOS16( tmp + 12 ); 529 di->fp_info.v_over_plus = RADEON_BIOS16( tmp + 18 ); 530 di->fp_info.h_sync_width = RADEON_BIOS16( tmp + 20 ); 531 di->fp_info.panel_pwr_delay = RADEON_BIOS16( tmp + 40 ); 532 533 SHOW_INFO( 2, "Panel Info from ATOMBIOS:\n" 534 "XRes: %d, YRes: %d, DotClock: %d\n" 535 "HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n" 536 "VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n" 537 "PanelPowerDelay: %d\n", 538 di->fp_info.panel_xres, di->fp_info.panel_yres, di->fp_info.dot_clock, 539 di->fp_info.h_blank, di->fp_info.h_over_plus, di->fp_info.h_sync_width, 540 di->fp_info.v_blank, di->fp_info.v_over_plus, di->fp_info.h_sync_width, 541 di->fp_info.panel_pwr_delay ); 542 543 } 544 else 545 { 546 di->fp_info.panel_pwr_delay = 200; 547 SHOW_ERROR0( 2, "No Panel Info Table found in BIOS" ); 548 return false; 549 } 550 } // is_atombios 551 else 552 { 553 554 fpi_offset = RADEON_BIOS16(bios_header + 0x40); 555 556 if( !fpi_offset ) { 557 di->fp_info.panel_pwr_delay = 200; 558 SHOW_ERROR0( 2, "No Panel Info Table found in BIOS" ); 559 return false; 560 } 561 562 memcpy( &fpi, di->rom.rom_ptr + fpi_offset, sizeof( fpi )); 563 564 memcpy( panel_name, &fpi.name, sizeof( fpi.name ) ); 565 panel_name[sizeof( fpi.name )] = 0; 566 567 SHOW_INFO( 2, "Panel ID string: %s", panel_name ); 568 569 di->fp_info.panel_xres = fpi.panel_xres; 570 di->fp_info.panel_yres = fpi.panel_yres; 571 572 SHOW_INFO( 2, "Panel Size from BIOS: %dx%d", 573 di->fp_info.panel_xres, di->fp_info.panel_yres); 574 575 di->fp_info.panel_pwr_delay = fpi.panel_pwr_delay; 576 if( di->fp_info.panel_pwr_delay > 2000 || di->fp_info.panel_pwr_delay < 0 ) 577 di->fp_info.panel_pwr_delay = 2000; 578 579 di->fp_info.ref_div = fpi.ref_div; 580 di->fp_info.post_div = fpi.post_div; 581 di->fp_info.feedback_div = fpi.feedback_div; 582 583 di->fp_info.fixed_dividers = 584 di->fp_info.ref_div != 0 && di->fp_info.feedback_div > 3; 585 586 587 // there might be multiple supported resolutions stored; 588 // we are looking for native resolution 589 for( i = 0; i < 20; ++i ) { 590 uint16 fpi_timing_ofs; 591 FPI_TIMING_BLOCK fpi_timing; 592 593 fpi_timing_ofs = fpi.fpi_timing_ofs[i]; 594 595 if( fpi_timing_ofs == 0 ) 596 break; 597 598 memcpy( &fpi_timing, di->rom.rom_ptr + fpi_timing_ofs, sizeof( fpi_timing )); 599 600 if( fpi_timing.panel_xres != di->fp_info.panel_xres || 601 fpi_timing.panel_yres != di->fp_info.panel_yres ) 602 continue; 603 604 di->fp_info.h_blank = (fpi_timing.h_total - fpi_timing.h_display) * 8; 605 // TBD: seems like upper four bits of hsync_start contain garbage 606 di->fp_info.h_over_plus = ((fpi_timing.h_sync_start & 0xfff) - fpi_timing.h_display - 1) * 8; 607 di->fp_info.h_sync_width = fpi_timing.h_sync_width * 8; 608 di->fp_info.v_blank = fpi_timing.v_total - fpi_timing.v_display; 609 di->fp_info.v_over_plus = (fpi_timing.v_sync & 0x7ff) - fpi_timing.v_display; 610 di->fp_info.v_sync_width = (fpi_timing.v_sync & 0xf800) >> 11; 611 di->fp_info.dot_clock = fpi_timing.dot_clock * 10; 612 return true; 613 } 614 } // not is_atombios 615 616 SHOW_ERROR0( 2, "Radeon: couldn't get Panel Timing from BIOS" ); 617 return false; 618 } 619 620 621 // try to reverse engineer DFP specification from 622 // timing currently set up in graphics cards registers 623 // (effectively, we hope that BIOS has set it up correctly 624 // and noone has messed registers up yet; let's pray) 625 static void Radeon_RevEnvDFPSize( device_info *di ) 626 { 627 vuint8 *regs = di->regs; 628 629 di->fp_info.panel_yres = 630 ((INREG( regs, RADEON_FP_VERT_STRETCH ) & RADEON_VERT_PANEL_SIZE) 631 >> RADEON_VERT_PANEL_SIZE_SHIFT) + 1; 632 633 di->fp_info.panel_xres = 634 (((INREG( regs, RADEON_FP_HORZ_STRETCH ) & RADEON_HORZ_PANEL_SIZE) 635 >> RADEON_HORZ_PANEL_SIZE_SHIFT) + 1) * 8; 636 637 SHOW_INFO( 2, "detected panel size from registers: %dx%d", 638 di->fp_info.panel_xres, di->fp_info.panel_yres); 639 } 640 641 642 // once more for getting precise timing 643 static void Radeon_RevEnvDFPTiming( device_info *di ) 644 { 645 vuint8 *regs = di->regs; 646 uint32 r; 647 uint16 a, b; 648 649 650 r = INREG( regs, RADEON_FP_CRTC_H_TOTAL_DISP ); 651 // the magic "4" was found by trial and error and probably stems from fudge (see crtc.c) 652 a = (r & RADEON_FP_CRTC_H_TOTAL_MASK)/* + 4*/; 653 b = (r & RADEON_FP_CRTC_H_DISP_MASK) >> RADEON_FP_CRTC_H_DISP_SHIFT; 654 di->fp_info.h_blank = (a - b) * 8; 655 656 SHOW_FLOW( 2, "h_total=%d, h_disp=%d", a * 8, b * 8 ); 657 658 r = INREG( regs, RADEON_FP_H_SYNC_STRT_WID ); 659 di->fp_info.h_over_plus = 660 ((r & RADEON_FP_H_SYNC_STRT_CHAR_MASK) 661 >> RADEON_FP_H_SYNC_STRT_CHAR_SHIFT) - b/* - 1*/; 662 di->fp_info.h_over_plus *= 8; 663 di->fp_info.h_sync_width = 664 ((r & RADEON_FP_H_SYNC_WID_MASK) 665 >> RADEON_FP_H_SYNC_WID_SHIFT); 666 // TBD: this seems to be wrong 667 // (my BIOS tells 112, this calculation leads to 24!) 668 di->fp_info.h_sync_width *= 8; 669 670 r = INREG( regs, RADEON_FP_CRTC_V_TOTAL_DISP ); 671 a = (r & RADEON_FP_CRTC_V_TOTAL_MASK)/* + 1*/; 672 b = (r & RADEON_FP_CRTC_V_DISP_MASK) >> RADEON_FP_CRTC_V_DISP_SHIFT; 673 di->fp_info.v_blank = a - b; 674 675 SHOW_FLOW( 2, "v_total=%d, v_disp=%d", a, b ); 676 677 r = INREG( regs, RADEON_FP_V_SYNC_STRT_WID ); 678 di->fp_info.v_over_plus = (r & RADEON_FP_V_SYNC_STRT_MASK) - b; 679 di->fp_info.v_sync_width = ((r & RADEON_FP_V_SYNC_WID_MASK) 680 >> RADEON_FP_V_SYNC_WID_SHIFT)/* + 1*/; 681 682 // standard CRTC 683 r = INREG( regs, RADEON_CRTC_H_TOTAL_DISP ); 684 a = (r & RADEON_CRTC_H_TOTAL); 685 b = (r & RADEON_CRTC_H_DISP) >> RADEON_CRTC_H_DISP_SHIFT; 686 di->fp_info.h_blank = (a - b) * 8; 687 688 SHOW_FLOW( 2, "h_total=%d, h_disp=%d", a * 8, b * 8 ); 689 690 r = INREG( regs, RADEON_CRTC_H_SYNC_STRT_WID ); 691 di->fp_info.h_over_plus = 692 ((r & RADEON_CRTC_H_SYNC_STRT_CHAR) 693 >> RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) - b; 694 di->fp_info.h_over_plus *= 8; 695 di->fp_info.h_sync_width = 696 ((r & RADEON_CRTC_H_SYNC_WID) 697 >> RADEON_CRTC_H_SYNC_WID_SHIFT); 698 di->fp_info.h_sync_width *= 8; 699 700 r = INREG( regs, RADEON_CRTC_V_TOTAL_DISP ); 701 a = (r & RADEON_CRTC_V_TOTAL); 702 b = (r & RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT; 703 di->fp_info.v_blank = a - b; 704 705 SHOW_FLOW( 2, "v_total=%d, v_disp=%d", a, b ); 706 707 r = INREG( regs, RADEON_CRTC_V_SYNC_STRT_WID ); 708 di->fp_info.v_over_plus = (r & RADEON_CRTC_V_SYNC_STRT) - b; 709 di->fp_info.v_sync_width = ((r & RADEON_CRTC_V_SYNC_WID) 710 >> RADEON_CRTC_V_SYNC_WID_SHIFT); 711 } 712 713 //snaffled from X.org hope it works... 714 static void Radeon_GetTMDSInfoFromBios( device_info *di ) 715 { 716 uint32 tmp, maxfreq; 717 uint32 found = FALSE; 718 int i, n; 719 uint16 bios_header; 720 721 bios_header = RADEON_BIOS16( 0x48 ); 722 723 for (i = 0; i < 4; i++) { 724 di->tmds_pll[i].value = 0; 725 di->tmds_pll[i].freq = 0; 726 } 727 728 if (di->is_atombios) 729 { 730 int master_data_start; 731 master_data_start = RADEON_BIOS16( bios_header + 32 ); 732 733 if((tmp = RADEON_BIOS16 (master_data_start + 18))) { 734 735 maxfreq = RADEON_BIOS16(tmp + 4); 736 737 for (i = 0; i < 4; i++) { 738 di->tmds_pll[i].freq = RADEON_BIOS16(tmp + i * 6 + 6); 739 // This assumes each field in TMDS_PLL has 6 bit as in R300/R420 740 di->tmds_pll[i].value = ((RADEON_BIOS8(tmp + i * 6 + 8) & 0x3f) | 741 ((RADEON_BIOS8(tmp + i * 6 + 10) & 0x3f) << 6) | 742 ((RADEON_BIOS8(tmp + i * 6 + 9) & 0xf) << 12) | 743 ((RADEON_BIOS8(tmp + i * 6 + 11) & 0xf) << 16)); 744 SHOW_ERROR( 2, "TMDS PLL from BIOS: %ld %lx", 745 di->tmds_pll[i].freq, di->tmds_pll[i].value); 746 747 if (maxfreq == di->tmds_pll[i].freq) { 748 di->tmds_pll[i].freq = 0xffffffff; 749 break; 750 } 751 } 752 found = TRUE; 753 } 754 } else { 755 756 tmp = RADEON_BIOS16(bios_header + 0x34); 757 if (tmp) { 758 SHOW_ERROR( 2, "DFP table revision: %d", RADEON_BIOS8(tmp)); 759 if (RADEON_BIOS8(tmp) == 3) { 760 n = RADEON_BIOS8(tmp + 5) + 1; 761 if (n > 4) 762 n = 4; 763 for (i = 0; i < n; i++) { 764 di->tmds_pll[i].value = RADEON_BIOS32(tmp + i * 10 + 0x08); 765 di->tmds_pll[i].freq = RADEON_BIOS16(tmp + i * 10 + 0x10); 766 } 767 found = TRUE; 768 } else if (RADEON_BIOS8(tmp) == 4) { 769 int stride = 0; 770 n = RADEON_BIOS8(tmp + 5) + 1; 771 if (n > 4) 772 n = 4; 773 for (i = 0; i < n; i++) { 774 di->tmds_pll[i].value = RADEON_BIOS32(tmp + stride + 0x08); 775 di->tmds_pll[i].freq = RADEON_BIOS16(tmp + stride + 0x10); 776 if (i == 0) 777 stride += 10; 778 else 779 stride += 6; 780 } 781 found = TRUE; 782 } 783 784 // revision 4 has some problem as it appears in RV280, 785 // comment it off for now, use default instead 786 /* 787 else if (RADEON_BIOS8(tmp) == 4) { 788 int stride = 0; 789 n = RADEON_BIOS8(tmp + 5) + 1; 790 if (n > 4) n = 4; 791 for (i = 0; i < n; i++) { 792 di->tmds_pll[i].value = RADEON_BIOS32(tmp + stride + 0x08); 793 di->tmds_pll[i].freq = RADEON_BIOS16(tmp + stride + 0x10); 794 if (i == 0) 795 stride += 10; 796 else 797 stride += 6; 798 } 799 found = TRUE; 800 } 801 */ 802 803 } 804 } 805 806 if (found == FALSE) { 807 for (i = 0; i < 4; i++) { 808 di->tmds_pll[i].value = default_tmds_pll[di->asic][i].value; 809 di->tmds_pll[i].freq = default_tmds_pll[di->asic][i].freq; 810 SHOW_ERROR( 2, "TMDS PLL from DEFAULTS: %ld %lx", 811 di->tmds_pll[i].freq, di->tmds_pll[i].value); 812 } 813 } 814 } 815 816 /* 817 // get everything in terms of monitors connected to the card 818 static void Radeon_GetBIOSMon( device_info *di ) 819 { 820 Radeon_GetMonType( di ); 821 822 // reset all Flat Panel Info; 823 // it gets filled out step by step, and this way we know what's still missing 824 memset( &di->fp_info, 0, sizeof( di->fp_info )); 825 826 // we assume that the only fp port is combined with standard port 0 827 di->fp_info.disp_type = di->disp_type[0]; 828 829 if( di->is_mobility ) { 830 // there is a flat panel - get info about it 831 Radeon_GetBIOSDFPInfo( di ); 832 833 // if BIOS doesn't know, ask the registers 834 if( di->fp_info.panel_xres == 0 || di->fp_info.panel_yres == 0) 835 Radeon_RevEnvDFPSize( di ); 836 837 if( di->fp_info.h_blank == 0 || di->fp_info.v_blank == 0) 838 Radeon_RevEnvDFPTiming( di ); 839 840 SHOW_INFO( 2, "h_disp=%d, h_blank=%d, h_over_plus=%d, h_sync_width=%d", 841 di->fp_info.panel_xres, di->fp_info.h_blank, di->fp_info.h_over_plus, di->fp_info.h_sync_width ); 842 SHOW_INFO( 2, "v_disp=%d, v_blank=%d, v_over_plus=%d, v_sync_width=%d", 843 di->fp_info.panel_yres, di->fp_info.v_blank, di->fp_info.v_over_plus, di->fp_info.v_sync_width ); 844 SHOW_INFO( 2, "pixel_clock=%d", di->fp_info.dot_clock ); 845 } 846 } 847 */ 848 849 // get info about Laptop flat panel 850 static void Radeon_GetFPData( device_info *di ) 851 { 852 // reset all Flat Panel Info; 853 // it gets filled out step by step, and this way we know what's still missing 854 memset( &di->fp_info, 0, sizeof( di->fp_info )); 855 856 // we only use BIOS for Laptop flat panels 857 if( !di->is_mobility ) 858 return; 859 860 // ask BIOS about flat panel spec 861 Radeon_GetBIOSDFPInfo( di ); 862 863 // if BIOS doesn't know, ask the registers 864 if( di->fp_info.panel_xres == 0 || di->fp_info.panel_yres == 0) 865 Radeon_RevEnvDFPSize( di ); 866 867 if( di->fp_info.h_blank == 0 || di->fp_info.v_blank == 0) 868 Radeon_RevEnvDFPTiming( di ); 869 870 SHOW_INFO( 2, "h_disp=%d, h_blank=%d, h_over_plus=%d, h_sync_width=%d", 871 di->fp_info.panel_xres, di->fp_info.h_blank, di->fp_info.h_over_plus, di->fp_info.h_sync_width ); 872 SHOW_INFO( 2, "v_disp=%d, v_blank=%d, v_over_plus=%d, v_sync_width=%d", 873 di->fp_info.panel_yres, di->fp_info.v_blank, di->fp_info.v_over_plus, di->fp_info.v_sync_width ); 874 SHOW_INFO( 2, "pixel_clock=%d", di->fp_info.dot_clock ); 875 } 876 877 878 // Depending on card genertation, chipset bugs, etc... the amount of vram 879 // accessible to the CPU can vary. This function is our best shot at figuring 880 // it out. Returns a value in KB. 881 static uint32 RADEON_GetAccessibleVRAM( device_info *di ) 882 { 883 vuint8 *regs = di->regs; 884 pci_info *pcii = &(di->pcii); 885 886 uint32 aper_size = INREG( regs, RADEON_CONFIG_APER_SIZE ); 887 888 // Set HDP_APER_CNTL only on cards that are known not to be broken, 889 // that is has the 2nd generation multifunction PCI interface 890 if (di->asic == rt_rv280 || 891 di->asic == rt_rv350 || 892 di->asic == rt_rv380 || 893 di->asic == rt_r420 ) { 894 OUTREGP( regs, RADEON_HOST_PATH_CNTL, RADEON_HDP_APER_CNTL, 895 ~RADEON_HDP_APER_CNTL); 896 SHOW_INFO0( 0, "Generation 2 PCI interface, using max accessible memory"); 897 return aper_size * 2; 898 } 899 900 // Older cards have all sorts of funny issues to deal with. First 901 // check if it's a multifunction card by reading the PCI config 902 // header type... Limit those to one aperture size 903 if (get_pci(PCI_header_type, 1) & 0x80) { 904 SHOW_INFO0( 0, "Generation 1 PCI interface in multifunction mode" 905 ", accessible memory limited to one aperture\n"); 906 return aper_size; 907 } 908 909 // Single function older card. We read HDP_APER_CNTL to see how the BIOS 910 // have set it up. We don't write this as it's broken on some ASICs but 911 // we expect the BIOS to have done the right thing (might be too optimistic...) 912 if (INREG( regs, RADEON_HOST_PATH_CNTL ) & RADEON_HDP_APER_CNTL ) 913 return aper_size * 2; 914 915 return aper_size; 916 } 917 918 919 // detect amount of graphics memory 920 static void Radeon_DetectRAM( device_info *di ) 921 { 922 vuint8 *regs = di->regs; 923 uint32 accessible, bar_size, tmp = 0; 924 925 if( di->is_igp ) { 926 uint32 tom; 927 928 tom = INREG( regs, RADEON_NB_TOM ); 929 di->local_mem_size = ((tom >> 16) + 1 - (tom & 0xffff)) << 16; 930 OUTREG( regs, RADEON_CONFIG_MEMSIZE, di->local_mem_size * 1024); 931 } else { 932 di->local_mem_size = INREG( regs, RADEON_CONFIG_MEMSIZE ) & RADEON_CONFIG_MEMSIZE_MASK; 933 } 934 935 // some production boards of m6 will return 0 if it's 8 MB 936 if( di->local_mem_size == 0 ) { 937 di->local_mem_size = 8 * 1024 *1024; 938 OUTREG( regs, RADEON_CONFIG_MEMSIZE, di->local_mem_size); 939 } 940 941 942 // Get usable Vram, after asic bugs, configuration screw ups etc 943 accessible = RADEON_GetAccessibleVRAM( di ); 944 945 // Crop it to the size of the PCI BAR 946 bar_size = di->pcii.u.h0.base_register_sizes[0]; 947 if (bar_size == 0) 948 bar_size = 0x200000; 949 if (accessible > bar_size) 950 accessible = bar_size; 951 952 SHOW_INFO( 0, "Detected total video RAM=%ldK, accessible=%ldK (PCI BAR=%ldK)" 953 , di->local_mem_size/1024, accessible/1024, bar_size/1024); 954 if (di->local_mem_size > accessible) 955 di->local_mem_size = accessible; 956 957 // detect ram bus width only used by dynamic clocks for now. 958 tmp = INREG( regs, RADEON_MEM_CNTL ); 959 if (IS_DI_R300_VARIANT) { 960 tmp &= R300_MEM_NUM_CHANNELS_MASK; 961 switch (tmp) { 962 case 0: di->ram.width = 64; break; 963 case 1: di->ram.width = 128; break; 964 case 2: di->ram.width = 256; break; 965 default: di->ram.width = 128; break; 966 } 967 } else if ( (di->asic >= rt_rv100) || 968 (di->asic >= rt_rs100) || 969 (di->asic >= rt_rs200)) { 970 if (tmp & RV100_HALF_MODE) 971 di->ram.width = 32; 972 else 973 di->ram.width = 64; 974 } else { 975 if (tmp & RADEON_MEM_NUM_CHANNELS_MASK) 976 di->ram.width = 128; 977 else 978 di->ram.width = 64; 979 } 980 981 if (di->is_igp || (di->asic >= rt_r300)) 982 { 983 uint32 mem_type = INREG( regs, RADEON_MEM_SDRAM_MODE_REG ) & RADEON_MEM_CFG_TYPE_MASK; 984 if ( mem_type == RADEON_MEM_CFG_SDR) { 985 // SDR SGRAM (2:1) 986 strcpy(di->ram_type, "SDR SGRAM"); 987 di->ram.ml = 4; 988 di->ram.MB = 4; 989 di->ram.Trcd = 1; 990 di->ram.Trp = 2; 991 di->ram.Twr = 1; 992 di->ram.CL = 2; 993 di->ram.loop_latency = 16; 994 di->ram.Rloop = 16; 995 di->ram.Tr2w = 0; 996 } else { // RADEON_MEM_CFG_DDR 997 // DDR SGRAM 998 strcpy(di->ram_type, "DDR SGRAM"); 999 di->ram.ml = 4; 1000 di->ram.MB = 4; 1001 di->ram.Trcd = 3; 1002 di->ram.Trp = 3; 1003 di->ram.Twr = 2; 1004 di->ram.CL = 3; 1005 di->ram.Tr2w = 1; 1006 di->ram.loop_latency = 16; 1007 di->ram.Rloop = 16; 1008 } 1009 } 1010 1011 SHOW_INFO( 1, "%ld MB %s found on %d wide bus", 1012 di->local_mem_size / 1024 / 1024, di->ram_type, di->ram.width); 1013 1014 /* if( di->local_mem_size > 64 * 1024 * 1024 ) { 1015 di->local_mem_size = 64 * 1024 * 1024; 1016 1017 SHOW_INFO0( 1, "restricted to 64 MB" ); 1018 }*/ 1019 } 1020 1021 1022 // map and verify card's BIOS to see whether this really is a Radeon 1023 // (as we need BIOS for further info we have to make sure we use the right one) 1024 status_t Radeon_MapBIOS( pci_info *pcii, rom_info *ri ) 1025 { 1026 char buffer[100]; 1027 1028 sprintf(buffer, "%04X_%04X_%02X%02X%02X bios", 1029 pcii->vendor_id, pcii->device_id, 1030 pcii->bus, pcii->device, pcii->function); 1031 1032 // we only scan BIOS at legacy location in first MB; 1033 // using the PCI location would improve detection, especially 1034 // if multiple graphics cards are installed 1035 // BUT: BeOS uses the first graphics card it finds (sorted by 1036 // device name), thus you couldn't choose in BIOS which card 1037 // to use; checking the legacy location ensures that the card is 1038 // only detected if it's the primary card 1039 ri->phys_address = 0xc0000; 1040 ri->size = 0x40000; 1041 1042 ri->bios_area = map_physical_memory( buffer, ri->phys_address, 1043 ri->size, B_ANY_KERNEL_ADDRESS, B_READ_AREA, (void **)&ri->bios_ptr ); 1044 if( ri->bios_area < 0 ) 1045 return ri->bios_area; 1046 1047 ri->rom_ptr = Radeon_FindRom( ri ); 1048 1049 // on success, adjust physical address to found ROM 1050 if( ri->rom_ptr != NULL ) 1051 ri->phys_address += ri->rom_ptr - ri->bios_ptr; 1052 1053 return ri->rom_ptr != NULL ? B_OK : B_ERROR; 1054 } 1055 1056 1057 // unmap card's BIOS 1058 void Radeon_UnmapBIOS( rom_info *ri ) 1059 { 1060 delete_area( ri->bios_area ); 1061 1062 ri->bios_ptr = ri->rom_ptr = NULL; 1063 } 1064 1065 1066 // get everything valuable from BIOS (BIOS must be mapped) 1067 status_t Radeon_ReadBIOSData( device_info *di ) 1068 { 1069 shared_info dummy_si; 1070 status_t result = B_OK; 1071 1072 // give Radeon_MapDevice something to play with 1073 di->si = &dummy_si; 1074 1075 // don't map frame buffer - we don't know its proper size yet! 1076 result = Radeon_MapDevice( di, true ); 1077 if( result < 0 ) 1078 goto err1; 1079 1080 Radeon_GetPLLInfo( di ); 1081 1082 // setup defaults 1083 di->routing.port_info[0].mon_type = mt_unknown; 1084 di->routing.port_info[0].ddc_type = ddc_none_detected; 1085 di->routing.port_info[0].dac_type = dac_unknown; 1086 di->routing.port_info[0].tmds_type = tmds_unknown; 1087 di->routing.port_info[0].connector_type = connector_none; 1088 1089 di->routing.port_info[1].mon_type = mt_unknown; 1090 di->routing.port_info[1].ddc_type = ddc_none_detected; 1091 di->routing.port_info[1].dac_type = dac_unknown; 1092 di->routing.port_info[1].tmds_type = tmds_unknown; 1093 di->routing.port_info[1].connector_type = connector_none; 1094 1095 if ( !Radeon_GetConnectorInfoFromBIOS( di ) ) 1096 { 1097 di->routing.port_info[0].mon_type = mt_unknown; 1098 di->routing.port_info[0].ddc_type = ddc_none_detected; 1099 di->routing.port_info[0].dac_type = dac_tvdac; 1100 di->routing.port_info[0].tmds_type = tmds_unknown; 1101 di->routing.port_info[0].connector_type = connector_proprietary; 1102 1103 di->routing.port_info[1].mon_type = mt_unknown; 1104 di->routing.port_info[1].ddc_type = ddc_none_detected; 1105 di->routing.port_info[1].dac_type = dac_primary; 1106 di->routing.port_info[1].tmds_type = tmds_ext; 1107 di->routing.port_info[1].connector_type = connector_crt; 1108 1109 } 1110 Radeon_GetFPData( di ); 1111 Radeon_GetTMDSInfoFromBios( di ); 1112 Radeon_DetectRAM( di ); 1113 1114 Radeon_UnmapDevice( di ); 1115 1116 err1: 1117 di->si = NULL; 1118 1119 return result; 1120 } 1121