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