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