1 /****************************************************************************** 2 / 3 / File: Radeon.cpp 4 / 5 / Description: ATI Radeon Graphics Chip interface. 6 / 7 / Copyright 2001, Carlos Hasan 8 / 9 *******************************************************************************/ 10 11 #include <unistd.h> 12 #include <dirent.h> 13 #include <Debug.h> 14 #include <string.h> 15 //#include "Driver.h" 16 #include "Radeon.h" 17 #include "OS.h" 18 19 static const char * const C_RADEON_REGISTER_AREA_NAME = "RadeonRegisters"; 20 static const char * const C_RADEON_MEMORY_AREA_NAME = "RadeonMemory"; 21 static const char * const C_RADEON_ROM_AREA_NAME = "RadeonROM"; 22 23 // CRadeonRect 24 CRadeonRect::CRadeonRect() 25 : fLeft(0), 26 fTop(0), 27 fRight(0), 28 fBottom(0) 29 { 30 } 31 32 CRadeonRect::CRadeonRect(int left, int top, int right, int bottom) 33 : fLeft(left), 34 fTop(top), 35 fRight(right), 36 fBottom(bottom) 37 { 38 } 39 40 int CRadeonRect::Left() const 41 { 42 return fLeft; 43 } 44 45 int CRadeonRect::Top() const 46 { 47 return fTop; 48 } 49 50 int CRadeonRect::Right() const 51 { 52 return fRight; 53 } 54 55 int CRadeonRect::Bottom() const 56 { 57 return fBottom; 58 } 59 60 int CRadeonRect::Width() const 61 { 62 return fRight - fLeft + 1; 63 } 64 65 int CRadeonRect::Height() const 66 { 67 return fBottom - fTop + 1; 68 } 69 70 void CRadeonRect::SetLeft(int value) 71 { 72 fLeft = value; 73 } 74 75 void CRadeonRect::SetTop(int value) 76 { 77 fTop = value; 78 } 79 80 void CRadeonRect::SetRight(int value) 81 { 82 fRight = value; 83 } 84 85 void CRadeonRect::SetBottom(int value) 86 { 87 fBottom = value; 88 } 89 90 void CRadeonRect::SetTo(int left, int top, int right, int bottom) 91 { 92 fLeft = left; 93 fTop = top; 94 fRight = right; 95 fBottom = bottom; 96 } 97 98 void CRadeonRect::MoveTo(int left, int top) 99 { 100 fRight += left - fLeft; 101 fBottom += top - fTop; 102 fLeft += left - fLeft; 103 fTop += top - fTop; 104 } 105 106 void CRadeonRect::ResizeTo(int width, int height) 107 { 108 fRight = fLeft + width - 1; 109 fBottom = fTop + height - 1; 110 } 111 112 113 // CRadeon 114 CRadeon::CRadeon( const char *dev_name ) 115 : fHandle(0), 116 fRegister(NULL), 117 fROM(NULL), 118 fVirtualCard(NULL), 119 fSharedInfo(NULL), 120 fRegisterArea(0), 121 fROMArea(0), 122 fVirtualCardArea(0), 123 fSharedInfoArea(0), 124 caps_video_in(0) 125 { 126 PRINT(("CRadeon::CRadeon()\n")); 127 128 if ((fHandle = open(dev_name, O_RDWR | O_CLOEXEC)) < 0) { 129 PRINT(("CRadeon::CRadeon() - Can't open kernel driver\n")); 130 return; 131 } 132 133 radeon_get_private_data gpd; 134 135 if (GetDeviceInformation(gpd) < B_OK) { 136 PRINT(("CRadeon::CRadeon() - Can't get device information\n")); 137 return; 138 } 139 140 CloneArea( 141 "Radeon virtual card", gpd.virtual_card_area, 142 &fVirtualCardArea, (void **)&fVirtualCard ); 143 CloneArea( 144 "Radeon shared info", gpd.shared_info_area, 145 &fSharedInfoArea, (void **)&fSharedInfo ); 146 147 if( fSharedInfo != NULL ) { 148 CloneArea( 149 "Radeon regs", fSharedInfo->regs_area, 150 &fRegisterArea, (void **)&fRegister ); 151 CloneArea( 152 "Radeon ROM", fSharedInfo->ROM_area, 153 &fROMArea, (void **)&fROM ); 154 } 155 156 if (fVirtualCard == NULL || fSharedInfo == NULL || 157 fROM == NULL || fRegister == NULL) 158 { 159 PRINT(("CRadeon::CRadeon() - Can't map memory apertures\n")); 160 return; 161 } 162 163 PRINT(("CRadeon::CRadeon() - ATI Radeon found\n")); 164 } 165 166 CRadeon::~CRadeon() 167 { 168 PRINT(("CRadeon::~CRadeon()\n")); 169 170 if( fVirtualCard != NULL ) 171 delete_area( fVirtualCardArea ); 172 173 if( fSharedInfo != NULL ) 174 delete_area( fSharedInfoArea ); 175 176 if (fRegister != NULL) 177 delete_area( fRegisterArea ); 178 179 if (fROM != NULL) 180 delete_area( fROMArea ); 181 182 if (fHandle >= 0) 183 close(fHandle); 184 } 185 186 status_t CRadeon::InitCheck() const 187 { 188 return 189 (fHandle >= 0 && 190 fRegister != NULL && fROM != NULL && 191 fVirtualCard != NULL && fSharedInfo != NULL) ? B_OK : B_ERROR; 192 } 193 194 uint32 CRadeon::VirtualMemoryBase() const 195 { 196 return fSharedInfo->memory[mt_local].virtual_addr_start; 197 } 198 199 int CRadeon::Register(radeon_register index) const 200 { 201 return fRegister[index >> 2]; 202 } 203 204 void CRadeon::SetRegister(radeon_register index, int value) 205 { 206 fRegister[index >> 2] = value; 207 } 208 209 int CRadeon::Register(radeon_register index, int mask) const 210 { 211 return fRegister[index >> 2] & mask; 212 } 213 214 void CRadeon::SetRegister(radeon_register index, int mask, int value) 215 { 216 #ifdef DEBUG 217 if ((value & ~mask) != 0) 218 PRINT(("CRadeon::SetRegister(0x%04x, 0x%08x, 0x%08x)\n", index, mask, value)); 219 #endif 220 221 fRegister[index >> 2] = (fRegister[index >> 2] & ~mask) | (value & mask); 222 } 223 224 int CRadeon::VIPRegister(int device, int address) 225 { 226 radeon_vip_read vr; 227 status_t res; 228 229 vr.magic = RADEON_PRIVATE_DATA_MAGIC; 230 vr.channel = device; 231 vr.address = address; 232 vr.lock = true; 233 234 res = ioctl( fHandle, RADEON_VIPREAD, &vr, sizeof( vr )); 235 236 if( res == B_OK ) 237 return vr.data; 238 else 239 return -1; 240 } 241 242 void CRadeon::SetVIPRegister(int device, int address, int value) 243 { 244 radeon_vip_write vw; 245 246 vw.magic = RADEON_PRIVATE_DATA_MAGIC; 247 vw.channel = device; 248 vw.address = address; 249 vw.data = value; 250 vw.lock = true; 251 252 ioctl( fHandle, RADEON_VIPWRITE, &vw, sizeof( vw )); 253 } 254 255 256 int CRadeon::VIPReadFifo(int device, uint32 address, uint32 count, uint8 *buffer) 257 { 258 radeon_vip_fifo_read vr; 259 status_t res; 260 261 vr.magic = RADEON_PRIVATE_DATA_MAGIC; 262 vr.channel = device; 263 vr.address = address; 264 vr.count = count; 265 vr.data = buffer; 266 vr.lock = true; 267 268 res = ioctl( fHandle, RADEON_VIPFIFOREAD, &vr, sizeof( vr )); 269 if( res == B_OK ) 270 return TRUE; 271 else 272 return FALSE; 273 274 } 275 276 int CRadeon::VIPWriteFifo(int device, uint32 address, uint32 count, uint8 *buffer) 277 { 278 radeon_vip_fifo_write vw; 279 status_t res; 280 281 vw.magic = RADEON_PRIVATE_DATA_MAGIC; 282 vw.channel = device; 283 vw.address = address; 284 vw.count = count; 285 vw.data = buffer; 286 vw.lock = true; 287 288 res = ioctl( fHandle, RADEON_VIPFIFOWRITE, &vw, sizeof( vw )); 289 290 if( res == B_OK ) 291 return TRUE; 292 else 293 return FALSE; 294 } 295 296 297 int CRadeon::FindVIPDevice( uint32 device_id ) 298 { 299 radeon_find_vip_device fvd; 300 status_t res; 301 302 fvd.magic = RADEON_PRIVATE_DATA_MAGIC; 303 fvd.device_id = device_id; 304 305 res = ioctl( fHandle, RADEON_FINDVIPDEVICE, &fvd, sizeof( fvd )); 306 307 if( res == B_OK ) 308 return fvd.channel; 309 else 310 return -1; 311 } 312 313 shared_info* CRadeon::GetSharedInfo() 314 { 315 return fSharedInfo; 316 } 317 318 void CRadeon::GetPLLParameters(int & refFreq, int & refDiv, int & minFreq, int & maxFreq, int & xclock) 319 { 320 refFreq = fSharedInfo->pll.ref_freq; 321 refDiv = fSharedInfo->pll.ref_div; 322 minFreq = fSharedInfo->pll.min_pll_freq; 323 maxFreq = fSharedInfo->pll.max_pll_freq; 324 xclock = fSharedInfo->pll.xclk; 325 } 326 327 void CRadeon::GetMMParameters(radeon_video_tuner & tuner, 328 radeon_video_decoder & video, 329 radeon_video_clock & clock, 330 int & tunerPort, 331 int & compositePort, 332 int & svideoPort) 333 { 334 335 unsigned char * fMMTable = NULL; 336 337 PRINT(("CRadeon::GetMMParameters()\n")); 338 339 if (fSharedInfo->is_atombios) { 340 uint16 hdr = fROM[0x48] + (fROM[0x49] << 8); 341 uint16 PCIR = hdr + fROM[hdr] + (fROM[hdr + 1] << 8); 342 uint16 hdr2 = fROM[PCIR - 4] + (fROM[PCIR - 3] << 8); 343 uint16 hmMedia = fROM[hdr2 + 8] + (fROM[hdr2 + 9] << 8); 344 if(fROM[hmMedia ] == 0x14 345 && fROM[hmMedia + 1] == 0x00 346 && fROM[hmMedia + 2] == 0x01 347 && fROM[hmMedia + 3] == 0x01 348 && fROM[hmMedia + 4] == '$' 349 && fROM[hmMedia + 5] == 'M' 350 && fROM[hmMedia + 6] == 'M' 351 && fROM[hmMedia + 7] == 'T') { 352 fMMTable = &fROM[hmMedia + 8]; 353 PRINT(("ATOMBIOS MM Table Signiture found\n")); 354 } else { 355 PRINT(("ATOMBIOS MM Table Not Found\n")); 356 return; 357 } 358 } else { 359 unsigned char *fVideoBIOS = fROM + fROM[0x48] + (fROM[0x49] << 8); 360 fMMTable = fROM + fVideoBIOS[0x38] + (fVideoBIOS[0x39] << 8) - 2; 361 362 if (fMMTable[0] != 0x0c) 363 { 364 PRINT(("MM_TABLE invalid size\n")); 365 return; 366 } 367 else 368 { 369 PRINT(("MM Table Found (non ATOM) \n")); 370 PRINT(("Revision %02x\n", fMMTable[0])); 371 PRINT(("Size %02x\n", fMMTable[2])); 372 fMMTable += 2; 373 } 374 } 375 376 377 // check table: 378 PRINT(( "MM_TABLE:\n")); 379 const char* names[] = { 380 "Tuner Type %02x\n", 381 "Audio Chip %02x\n", 382 "Product ID %02x\n", 383 "Tuner misc %02x\n", 384 "I2C Config %02x\n", 385 "Vid Decoder %02x\n", 386 "..Host config %02x\n", 387 "input 0 %02x\n", 388 "input 1 %02x\n", 389 "input 2 %02x\n", 390 "input 3 %02x\n", 391 "input 4 %02x\n", 392 0 393 }; 394 395 int i = 0; 396 while(names[i]) { 397 PRINT((names[i], fMMTable[i])); 398 i++; 399 } 400 401 switch (fMMTable[0] & 0x1f) { 402 case 0x00: 403 tuner = C_RADEON_NO_TUNER; 404 PRINT(("CRadeon::GetMMParameters() No Tuner\n")); 405 break; 406 case 0x01: 407 tuner = C_RADEON_FI1236_MK1_NTSC; 408 break; 409 case 0x02: 410 tuner = C_RADEON_FI1236_MK2_NTSC_JAPAN; 411 break; 412 case 0x03: 413 tuner = C_RADEON_FI1216_MK2_PAL_BG; 414 break; 415 case 0x04: 416 tuner = C_RADEON_FI1246_MK2_PAL_I; 417 break; 418 case 0x05: 419 tuner = C_RADEON_FI1216_MF_MK2_PAL_BG_SECAM_L; 420 break; 421 case 0x06: 422 tuner = C_RADEON_FI1236_MK2_NTSC; 423 break; 424 case 0x07: 425 tuner = C_RADEON_FI1256_MK2_SECAM_DK; 426 break; 427 case 0x08: 428 tuner = C_RADEON_FI1236_MK2_NTSC; 429 break; 430 case 0x09: 431 tuner = C_RADEON_FI1216_MK2_PAL_BG; 432 break; 433 case 0x0a: 434 tuner = C_RADEON_FI1246_MK2_PAL_I; 435 break; 436 case 0x0b: 437 tuner = C_RADEON_FI1216_MK2_PAL_BG_SECAM_L; 438 break; 439 case 0x0c: 440 tuner = C_RADEON_FI1236_MK2_NTSC; 441 break; 442 case 0x0d: 443 tuner = C_RADEON_TEMIC_FN5AL_PAL_IBGDK_SECAM_DK; 444 break; 445 default: 446 tuner = C_RADEON_NO_TUNER; 447 PRINT(("CRadeon::GetMMParameters() No Tuner\n")); 448 break; 449 } 450 451 switch (fMMTable[5] & 0x0f) { 452 case 0x00: 453 video = C_RADEON_NO_VIDEO; 454 PRINT(("CRadeon::GetMMParameters() No Video\n")); 455 break; 456 case 0x01: 457 video = C_RADEON_BT819; 458 break; 459 case 0x02: 460 video = C_RADEON_BT829; 461 break; 462 case 0x03: 463 video = C_RADEON_BT829A; 464 break; 465 case 0x04: 466 video = C_RADEON_SA7111; 467 break; 468 case 0x05: 469 video = C_RADEON_SA7112; 470 break; 471 case 0x06: 472 video = C_RADEON_RAGE_THEATER; 473 PRINT(("CRadeon::GetMMParameters() Rage Theater\n")); 474 break; 475 default: 476 video = C_RADEON_NO_VIDEO; 477 PRINT(("CRadeon::GetMMParameters() No Video\n")); 478 break; 479 } 480 481 switch (fMMTable[5] & 0xf0) { 482 case 0x00: 483 case 0x10: 484 case 0x20: 485 case 0x30: 486 clock = C_RADEON_NO_VIDEO_CLOCK; 487 PRINT(("CRadeon::GetMMParameters() Video No Clock\n")); 488 break; 489 case 0x40: 490 clock = C_RADEON_VIDEO_CLOCK_28_63636_MHZ; 491 break; 492 case 0x50: 493 clock = C_RADEON_VIDEO_CLOCK_29_49892_MHZ; 494 break; 495 case 0x60: 496 clock = C_RADEON_VIDEO_CLOCK_27_00000_MHZ; 497 break; 498 case 0x70: 499 clock = C_RADEON_VIDEO_CLOCK_14_31818_MHZ; 500 break; 501 default: 502 clock = C_RADEON_NO_VIDEO_CLOCK; 503 PRINT(("CRadeon::GetMMParameters() Video No Clock\n")); 504 break; 505 } 506 507 for (int port = 0; port < 5; port++) { 508 switch (fMMTable[7 + port] & 0x03) { 509 case 0x00: 510 // Unused or Invalid 511 PRINT(("CRadeon::GetMMParameters() Invalid Port\n")); 512 break; 513 case 0x01: 514 // Tuner Input 515 PRINT(("CRadeon::GetMMParameters() Tuner Port\n")); 516 tunerPort = 0; 517 break; 518 case 0x02: 519 // Front/Rear Composite Input 520 PRINT(("CRadeon::GetMMParameters() Composite Port\n")); 521 compositePort = (fMMTable[7 + port] & 0x04 ? 2 : 1); 522 break; 523 case 0x03: 524 // Front/Rear SVideo Input 525 PRINT(("CRadeon::GetMMParameters() SVideo Port\n")); 526 svideoPort = (fMMTable[7 + port] & 0x04 ? 6 : 5); 527 break; 528 } 529 } 530 } 531 532 status_t CRadeon::AllocateGraphicsMemory( 533 memory_type_e memory_type, int32 size, 534 int32 *offset, int32 *handle ) 535 { 536 radeon_alloc_mem am; 537 status_t res; 538 539 am.magic = RADEON_PRIVATE_DATA_MAGIC; 540 am.size = size; 541 am.memory_type = mt_local; 542 am.global = false; 543 544 res = ioctl( fHandle, RADEON_ALLOC_MEM, &am ); 545 546 if( res != B_OK ) 547 return res; 548 549 *handle = am.handle; 550 *offset = am.offset; 551 return B_OK; 552 } 553 554 void CRadeon::FreeGraphicsMemory( 555 memory_type_e memory_type, int32 handle ) 556 { 557 radeon_free_mem fm; 558 559 fm.magic = RADEON_PRIVATE_DATA_MAGIC; 560 fm.memory_type = memory_type; 561 fm.global = false; 562 fm.handle = handle; 563 564 ioctl( fHandle, RADEON_FREE_MEM, &fm ); 565 } 566 567 status_t CRadeon::DMACopy( 568 uint32 src, void *target, size_t size, bool lock_mem, bool contiguous ) 569 { 570 radeon_dma_copy dc; 571 572 dc.magic = RADEON_PRIVATE_DATA_MAGIC; 573 dc.src = src; 574 dc.target = target; 575 dc.size = size; 576 dc.lock_mem = lock_mem; 577 dc.contiguous = contiguous; 578 579 return ioctl( fHandle, RADEON_DMACOPY, &dc ); 580 } 581 582 status_t CRadeon::GetDeviceInformation(radeon_get_private_data & info) 583 { 584 info.magic = RADEON_PRIVATE_DATA_MAGIC; 585 586 return ioctl( fHandle, RADEON_GET_PRIVATE_DATA, &info, sizeof( info )); 587 } 588 589 status_t CRadeon::CloneArea(const char * name, area_id src_area, 590 area_id *cloned_area, void ** map) 591 { 592 int res = clone_area( name, map, B_ANY_ADDRESS, 593 B_READ_AREA | B_WRITE_AREA, src_area ); 594 595 if( res < 0 ) { 596 return res; 597 } else { 598 *cloned_area = res; 599 return B_OK; 600 } 601 } 602 603 status_t CRadeon::WaitInterrupt(int * mask, int * sequence, bigtime_t * time, bigtime_t timeout) 604 { 605 radeon_wait_for_cap_irq wvc; 606 status_t status; 607 608 wvc.magic = RADEON_PRIVATE_DATA_MAGIC; 609 wvc.timeout = timeout; 610 611 status = ioctl( fHandle, RADEON_WAIT_FOR_CAP_IRQ, &wvc ); 612 613 if( status == B_OK ) { 614 *mask = wvc.int_status; 615 *sequence = wvc.counter; 616 *time = wvc.timestamp; 617 } 618 619 return status; 620 } 621 622 #if 0 623 void CRadeon::PrintToStream() 624 { 625 // ATI ROM Signature 626 if (ROM(0) == 0x55 && ROM(1) == 0xAA) { 627 for (int offset = 0; offset < 128 - 9; offset++) { 628 if (ROM(offset + 0) == '7' && 629 ROM(offset + 1) == '6' && 630 ROM(offset + 2) == '1' && 631 ROM(offset + 3) == '2' && 632 ROM(offset + 4) == '9' && 633 ROM(offset + 5) == '5' && 634 ROM(offset + 6) == '5' && 635 ROM(offset + 7) == '2' && 636 ROM(offset + 8) == '0') 637 break; 638 } 639 } 640 641 // Video BIOS 642 unsigned char *fVideoBIOS = fROM + fROM[0x48] + (fROM[0x49] << 8); 643 644 PRINT(( 645 "----------------------------------------------------------------------\n" 646 "ATI RADEON VIDEO BIOS\n" 647 "\n" 648 "BIOS Revision: %03d.%03d.%03d%03d.%s\n" 649 "PCI Bus/Device/Function Code: 0x%04x\n" 650 "BIOS Runtime Segment Address: 0x%04x\n" 651 "I/O Base Address: 0x%04x\n" 652 "Subsystem Vendor ID: 0x%04x\n" 653 "Subsystem ID: 0x%04x\n" 654 "Post Vendor ID: 0x%04x\n" 655 "\n", 656 657 // OEM Revision (ID1.ID2.REVISION.CONFIG_FILE) 658 fVideoBIOS[2], fVideoBIOS[3], 659 fVideoBIOS[4], fVideoBIOS[5], 660 fROM + fVideoBIOS[0x10] + (fVideoBIOS[0x11] << 8), 661 662 // PCI bus, device, function code 663 fVideoBIOS[0x16] + (fVideoBIOS[0x17] << 8), 664 665 // ROM BIOS segment 666 fVideoBIOS[0x18] + (fVideoBIOS[0x19] << 8), 667 668 // I/O base address 669 fVideoBIOS[0x1a] + (fVideoBIOS[0x1b] << 8), 670 671 // Subsystem Vendor ID, Subsystem ID, Post Vendor ID 672 fVideoBIOS[0x1c] + (fVideoBIOS[0x1d] << 8), 673 fVideoBIOS[0x1e] + (fVideoBIOS[0x1f] << 8), 674 fVideoBIOS[0x20] + (fVideoBIOS[0x21] << 8) 675 )); 676 677 678 // PLL Information 679 unsigned char *fPLL = fROM + fVideoBIOS[0x30] + (fVideoBIOS[0x31] << 8); 680 681 PRINT(( 682 "----------------------------------------------------------------------\n" 683 "ATI RADEON PLL INFORMATION TABLE\n" 684 "\n" 685 "External Clock: %g MHz\n" 686 "Reference Frequency: %g MHz\n" 687 "Reference Divisor: %d\n" 688 "Min PLL Frequency: %g MHz\n" 689 "Max PLL Frequency: %g MHz\n" 690 "\n", 691 (fPLL[0x08] + (fPLL[0x09] << 8)) / 1000.0, 692 (fPLL[0x0e] + (fPLL[0x0f] << 8)) / 100.0, 693 fPLL[0x10] + (fPLL[0x11] << 8), 694 (fPLL[0x12] + (fPLL[0x13] << 8) + (fPLL[0x14] << 16) + (fPLL[0x15] << 24)) / 1000.0, 695 (fPLL[0x12] + (fPLL[0x16] << 8) + (fPLL[0x17] << 16) + (fPLL[0x18] << 24)) / 1000.0)); 696 697 698 // TV Table 699 unsigned char * fTVTable = fROM + fVideoBIOS[0x32] + (fVideoBIOS[0x33] << 8); 700 701 PRINT(( 702 "----------------------------------------------------------------------\n" 703 "ATI RADEON TV INFORMATION TABLE\n" 704 "\n" 705 "Table Signature: %c%c%c\n" 706 "Table Version: %d\n" 707 "Table Size: %d bytes\n" 708 "\n" 709 "TVOut Support: %s\n" 710 "BIOS built-in TV standard: %s\n" 711 "TVOut information: %s, %s MHz\n" 712 "\n" 713 "Run time supported TV standard:%s%s%s%s%s%s\n" 714 "Initialization time supported TV standard:%s%s%s%s%s%s\n" 715 "\n", 716 717 // Table signature, version and size 718 fTVTable[0x00],fTVTable[0x01], fTVTable[0x02], 719 fTVTable[0x03], 720 fTVTable[0x04] + ((int) fTVTable[0x05] << 8), 721 722 // TVOut support 723 fTVTable[0x06] == 'N' ? "TVOut chip not found" : "TVOut chip on board", 724 725 // BIOS built-in initialization TV standard 726 (fTVTable[0x07] & 0x0f) == 0x01 ? "NTSC" : 727 (fTVTable[0x07] & 0x0f) == 0x02 ? "PAL" : 728 (fTVTable[0x07] & 0x0f) == 0x03 ? "PAL-M" : 729 (fTVTable[0x07] & 0x0f) == 0x04 ? "PAL-60" : 730 (fTVTable[0x07] & 0x0f) == 0x05 ? "NTSC-J" : 731 (fTVTable[0x07] & 0x0f) == 0x06 ? "SCART-PAL" : "Reserved", 732 733 // TV Out information 734 (fTVTable[0x09] & 0x03) == 0x00 ? "Invalid" : 735 (fTVTable[0x09] & 0x03) == 0x01 ? "TV off, CRT on" : 736 (fTVTable[0x09] & 0x03) == 0x02 ? "TV on, CRT off" : "TV on, CRT on", 737 738 (fTVTable[0x09] & 0x0c) == 0x00 ? "29.498928713" : 739 (fTVTable[0x09] & 0x0c) == 0x04 ? "28.63636" : 740 (fTVTable[0x09] & 0x0c) == 0x08 ? "14.31818" : "27.0", 741 742 // Runtime supported TV standard 743 (fTVTable[0x0a] & 0x01) != 0 ? " NTSC" : "", 744 (fTVTable[0x0a] & 0x02) != 0 ? " PAL" : "", 745 (fTVTable[0x0a] & 0x04) != 0 ? " PAL-M" : "", 746 (fTVTable[0x0a] & 0x08) != 0 ? " PAL-60" : "", 747 (fTVTable[0x0a] & 0x10) != 0 ? " NTSC-J" : "", 748 (fTVTable[0x0a] & 0x20) != 0 ? " SCART-PAL" : "", 749 750 // Initialization time supported TV standard 751 (fTVTable[0x0b] & 0x01) != 0 ? " NTSC" : "", 752 (fTVTable[0x0b] & 0x02) != 0 ? " PAL" : "", 753 (fTVTable[0x0b] & 0x04) != 0 ? " PAL-M" : "", 754 (fTVTable[0x0b] & 0x08) != 0 ? " PAL-60" : "", 755 (fTVTable[0x0b] & 0x10) != 0 ? " NTSC-J" : "", 756 (fTVTable[0x0b] & 0x20) != 0 ? " SCART-PAL" : "" 757 )); 758 759 // Hardware Configuration Table 760 unsigned char * fHWTable = fROM + fVideoBIOS[0x36] + (fVideoBIOS[0x37] << 8); 761 762 PRINT(( 763 "----------------------------------------------------------------------\n" 764 "ATI RADEON HARDWARE CONFIGURATION TABLE\n" 765 "\n" 766 "Table Signature: %c%c%c%c\n" 767 "Table Revision: %d\n" 768 "Table Size: %d\n" 769 "\n" 770 "I2C Type: %s\n" 771 "TVOut Support: %s\n" 772 "Video Out Crystal: %s\n" 773 "ImpactTV Data Port: %s\n" 774 "\n" 775 "Video Port Capability:\n" 776 " AMC/DVS0 Video Port: %s\n" 777 " Zoom Video Port: %s\n" 778 " AMC/DVS1 Video Port: %s\n" 779 " VIP 16-bit Video Port: %s\n" 780 "\n" 781 "Host Port Configuration: %s\n" 782 "\n", 783 784 // Table Signature, Revision, Size 785 fHWTable[0x00], fHWTable[0x01], fHWTable[0x02], fHWTable[0x03], 786 fHWTable[0x04], fHWTable[0x05], 787 788 // I2C type 789 (fHWTable[0x06] & 0x0f) == 0x00 ? "Normal GP I/O (data=GP_IO2, clock=GP_IO1)" : 790 (fHWTable[0x06] & 0x0f) == 0x01 ? "ImpacTV GP I/O" : 791 (fHWTable[0x06] & 0x0f) == 0x02 ? "Dedicated I2C Pin" : 792 (fHWTable[0x06] & 0x0f) == 0x03 ? "GP I/O (data=GP_IO12, clock=GP_IO13)" : 793 (fHWTable[0x06] & 0x0f) == 0x04 ? "GP I/O (data=GPIO12, clock=GPIO10)" : 794 (fHWTable[0x06] & 0x0f) == 0x05 ? "RAGE THEATER I2C Master" : 795 (fHWTable[0x06] & 0x0f) == 0x06 ? "Rage128 MPP2 Pin" : 796 (fHWTable[0x06] & 0x0f) == 0x0f ? "No I2C Configuration" : "Reserved", 797 798 // TVOut support 799 (fHWTable[0x07] & 0x0f) == 0x00 ? "No TVOut supported" : 800 (fHWTable[0x07] & 0x0f) == 0x01 ? "ImpactTV1 supported" : 801 (fHWTable[0x07] & 0x0f) == 0x02 ? "ImpactTV2 supported" : 802 (fHWTable[0x07] & 0x0f) == 0x03 ? "Improved ImpactTV2 supported" : 803 (fHWTable[0x07] & 0x0f) == 0x04 ? "RAGE THEATER supported" : "Reserved", 804 805 // Video Out Crystal 806 (fHWTable[0x07] & 0x70) == 0x00 ? "TVOut not installed" : 807 (fHWTable[0x07] & 0x70) == 0x10 ? "28.63636 MHz" : 808 (fHWTable[0x07] & 0x70) == 0x20 ? "29.49892713 MHz" : 809 (fHWTable[0x07] & 0x70) == 0x30 ? "27.0 MHz" : 810 (fHWTable[0x07] & 0x70) == 0x40 ? "14.31818 MHz" : "Reserved", 811 812 // ImpactTV data port 813 (fHWTable[0x07] & 0x80) == 0x00 ? "MPP1" : "MPP2", 814 815 // Video Port Capability 816 (fHWTable[0x08] & 0x01) == 0x00 ? "Not Supported" : "Supported", 817 (fHWTable[0x08] & 0x02) == 0x00 ? "Not Supported" : "Supported", 818 (fHWTable[0x08] & 0x04) == 0x00 ? "Not Supported" : "Supported", 819 (fHWTable[0x08] & 0x08) == 0x00 ? "Not Supported" : "Supported", 820 821 // Host Port Configuration 822 (fHWTable[0x09] & 0x0f) == 0x00 ? "No Host Port" : 823 (fHWTable[0x09] & 0x0f) == 0x01 ? "MPP Host Port" : 824 (fHWTable[0x09] & 0x0f) == 0x02 ? "2 bit VIP Host Port" : 825 (fHWTable[0x09] & 0x0f) == 0x03 ? "4 bit VIP Host Port" : 826 (fHWTable[0x09] & 0x0f) == 0x04 ? "8 bit VIP Host Port" : "Reserved" 827 )); 828 829 // Multimedia Table 830 unsigned char * fMMTable = fROM + fVideoBIOS[0x38] + (fVideoBIOS[0x39] << 8); 831 832 PRINT(( 833 "----------------------------------------------------------------------\n" 834 "ATI RADEON MULTIMEDIA TABLE\n" 835 "\n" 836 "Table Revision: %d\n" 837 "Table Size: %d bytes\n" 838 "\n" 839 "Tuner Chip: %s\n" 840 "Tuner Input: %s\n" 841 "Tuner Voltage Regulator: %s\n" 842 "\n" 843 "Audio Chip: %s\n" 844 "FM Audio Decoder: %s\n" 845 "Audio Scrambling: %s\n" 846 "\n" 847 "Product Type: %s, Revision %d\n" 848 "Product ID: %s\n" 849 "\n" 850 "I2S Input Configuration: %s\n" 851 "I2S Output Configuration: %s\n" 852 "I2S Audio Chip: %s\n" 853 "S/PDIF Output Configuration: %s\n" 854 "\n" 855 "Video Decoder: %s\n" 856 "Video Standard/Crystal: %s\n" 857 "Video Decoder Host Config: %s\n" 858 "Hardware Teletext: %s\n" 859 "\n" 860 "Video Input:\n" 861 " 0: %s, %s (ID %d)\n" 862 " 1: %s, %s (ID %d)\n" 863 " 2: %s, %s (ID %d)\n" 864 " 3: %s, %s (ID %d)\n" 865 " 4: %s, %s (ID %d)\n" 866 "\n", 867 868 /* Hardware Table */ 869 fMMTable[-2], fMMTable[-1], 870 871 /* Tuner Type */ 872 (fMMTable[0] & 0x1f) == 0x00 ? "No Tuner" : 873 (fMMTable[0] & 0x1f) == 0x01 ? "Philips FI1236 MK1 NTSC M/N North America" : 874 (fMMTable[0] & 0x1f) == 0x02 ? "Philips FI1236 MK2 NTSC M/N Japan" : 875 876 (fMMTable[0] & 0x1f) == 0x03 ? "Philips FI1216 MK2 PAL B/G" : 877 (fMMTable[0] & 0x1f) == 0x04 ? "Philips FI1246 MK2 PAL I" : 878 (fMMTable[0] & 0x1f) == 0x05 ? "Philips FI1216 MF MK2 PAL B/G, SECAM L/L'" : 879 (fMMTable[0] & 0x1f) == 0x06 ? "Philips FI1236 MK2 NTSC M/N North America" : 880 (fMMTable[0] & 0x1f) == 0x07 ? "Philips FI1256 MK2 SECAM D/K" : 881 (fMMTable[0] & 0x1f) == 0x08 ? "Philips FM1236 MK2 NTSC M/N North America" : 882 883 (fMMTable[0] & 0x1f) == 0x09 ? "Philips FI1216 MK2 PAL B/G - External Tuner POD" : 884 (fMMTable[0] & 0x1f) == 0x0a ? "Philips FI1246 MK2 PAL I - External Tuner POD" : 885 (fMMTable[0] & 0x1f) == 0x0b ? "Philips FI1216 MF MK2 PAL B/G, SECAM L/L' - External Tuner POD" : 886 (fMMTable[0] & 0x1f) == 0x0c ? "Philips FI1236 MK2 NTSC M/N North America - External Tuner POD" : 887 888 (fMMTable[0] & 0x1f) == 0x0d ? "Temic FN5AL RF3X7595 PAL I/B/G/DK & SECAM DK" : 889 (fMMTable[0] & 0x1f) == 0x10 ? "Alps TSBH5 NTSC M/N North America" : 890 (fMMTable[0] & 0x1f) == 0x11 ? "Alps TSC?? NTSC M/N North America" : 891 (fMMTable[0] & 0x1f) == 0x12 ? "Alps TSCH5 NTSC M/N North America" : 892 893 (fMMTable[0] & 0x1f) == 0x1f ? "Unknown Tuner Type" : "Reserved", 894 895 /* Video Input for Tuner */ 896 (fMMTable[0] & 0xe0) == 0x00 ? "Video Input 0" : 897 (fMMTable[0] & 0xe0) == 0x20 ? "Video Input 1" : 898 (fMMTable[0] & 0xe0) == 0x40 ? "Video Input 2" : 899 (fMMTable[0] & 0xe0) == 0x60 ? "Video Input 3" : 900 (fMMTable[0] & 0xe0) == 0x80 ? "Video Input 4" : "Reserved", 901 902 /* Tuner Voltage */ 903 (fMMTable[3] & 0x03) == 0x00 ? "No Tuner Power down feature" : 904 (fMMTable[3] & 0x03) == 0x01 ? "Tuner Power down feature" : "Reserved", 905 906 /* Audio Chip Type */ 907 (fMMTable[1] & 0x0f) == 0x00 ? "Philips TEA5582 NTSC Stereo, no dbx, no volume" : 908 (fMMTable[1] & 0x0f) == 0x01 ? "Mono with audio mux" : 909 (fMMTable[1] & 0x0f) == 0x02 ? "Philips TDA9850 NTSC N.A. Stereo, dbx, mux, no volume" : 910 (fMMTable[1] & 0x0f) == 0x03 ? "Sony CXA2020S Japan NTSC Stereo, mux, no volume" : 911 (fMMTable[1] & 0x0f) == 0x04 ? "ITT MSP3410D Europe Stereo, volume, internal mux" : 912 (fMMTable[1] & 0x0f) == 0x05 ? "Crystal CS4236B" : 913 (fMMTable[1] & 0x0f) == 0x06 ? "Philips TDA9851 NTSC Stereo, volume, no dbx, no mux" : 914 (fMMTable[1] & 0x0f) == 0x07 ? "ITT MSP3415 (Europe)" : 915 (fMMTable[1] & 0x0f) == 0x08 ? "ITT MSP3430 (N.A.)" : 916 (fMMTable[1] & 0x0f) == 0x0f ? "No Audio Chip Installed" : "Reserved", 917 918 /* FM Audio Decoder */ 919 (fMMTable[3] & 0x30) == 0x00 ? "No FM Audio Decoder" : 920 (fMMTable[3] & 0x30) == 0x10 ? "FM Audio Decoder (Rohm BA1332F)" : "Reserved", 921 922 /* Audio Scrambling */ 923 (fMMTable[3] & 0x80) == 0x00 ? "Not Supported" : "Supported", 924 925 /* Product Type */ 926 (fMMTable[1] & 0x10) == 0x00 ? "OEM Product" : "ATI Product", 927 928 /* OEM Revision */ 929 (fMMTable[1] & 0xe0) >> 5, 930 931 /* Product ID */ 932 (fMMTable[1] & 0x10) == 0x00 ? "<OEM ID>" : 933 ( 934 fMMTable[2] == 0x00 ? "ATI Prototype Board" : 935 fMMTable[2] == 0x01 ? "ATI All in Wonder" : 936 fMMTable[2] == 0x02 ? "ATI All in Wonder Pro, no MPEG/DVD decoder" : 937 fMMTable[2] == 0x03 ? "ATI All in Wonder Pro, CD11 or similar MPEG/DVD decoder on MPP" : 938 fMMTable[2] == 0x04 ? "ATI All in Wonder Plus" : 939 fMMTable[2] == 0x05 ? "ATI Kitchener Board" : 940 fMMTable[2] == 0x06 ? "ATI Toronto Board (analog audio)" : 941 fMMTable[2] == 0x07 ? "ATI TV-Wonder" : 942 fMMTable[2] == 0x08 ? "ATI Victoria Board (Rage XL plus RAGE THEATER)" : "Reserved" 943 ), 944 945 /* I2S Input/Output Configuration */ 946 (fMMTable[4] & 0x01) == 0x00 ? "Not Supported" : "Supported", 947 (fMMTable[4] & 0x02) == 0x00 ? "Not Supported" : "Supported", 948 949 /* I2S Audio Chip */ 950 (fMMTable[4] & 0x1c) == 0x00 ? "TDA1309_32Strap" : 951 (fMMTable[4] & 0x1c) == 0x04 ? "TDA1309_64Strap" : 952 (fMMTable[4] & 0x1c) == 0x08 ? "ITT MSP3430" : 953 (fMMTable[4] & 0x1c) == 0x0c ? "ITT MSP3415" : "Reserved", 954 955 /* S/PDIF Output Config */ 956 (fMMTable[4] & 0x20) == 0x00 ? "Not Supported" : "Supported", 957 958 /* Video Decoder Type */ 959 (fMMTable[5] & 0x0f) == 0x00 ? "No Video Decoder" : 960 (fMMTable[5] & 0x0f) == 0x01 ? "Bt819" : 961 (fMMTable[5] & 0x0f) == 0x02 ? "Bt829" : 962 (fMMTable[5] & 0x0f) == 0x03 ? "Bt829A" : 963 (fMMTable[5] & 0x0f) == 0x04 ? "Philips SA7111" : 964 (fMMTable[5] & 0x0f) == 0x05 ? "Philips SA7112 or SA7112A" : 965 (fMMTable[5] & 0x0f) == 0x06 ? "RAGE THEATER" : "Reserved", 966 967 /* Video-In Standard/Crystal */ 968 (fMMTable[5] & 0xf0) == 0x00 ? "NTSC and PAL Crystals installed" : 969 (fMMTable[5] & 0xf0) == 0x10 ? "NTSC Crystal only" : 970 (fMMTable[5] & 0xf0) == 0x20 ? "PAL Crystal only" : 971 (fMMTable[5] & 0xf0) == 0x30 ? "NTSC, PAL, SECAM Ssingle crystal for Bt829 and Bt879" : 972 (fMMTable[5] & 0xf0) == 0x40 ? "28.63636 MHz Crystal" : 973 (fMMTable[5] & 0xf0) == 0x50 ? "29.49892713 MHz Crystal" : 974 (fMMTable[5] & 0xf0) == 0x60 ? "27.0 MHz Crystal" : 975 (fMMTable[5] & 0xf0) == 0x70 ? "14.31818 MHz Crystal" : "Reserved", 976 977 /* Video Decoder Host Config */ 978 (fMMTable[6] & 0x07) == 0x00 ? "I2C Device" : 979 (fMMTable[6] & 0x07) == 0x01 ? "MPP Device" : 980 (fMMTable[6] & 0x07) == 0x02 ? "2 bits VIP Device" : 981 (fMMTable[6] & 0x07) == 0x03 ? "4 bits VIP Device" : 982 (fMMTable[6] & 0x07) == 0x04 ? "8 bits VIP Device" : 983 (fMMTable[6] & 0x07) == 0x07 ? "PCI Device" : "Reserved", 984 985 /* Hardware Teletext */ 986 (fMMTable[3] & 0x0c) == 0x00 ? "No Hardware Teletext" : 987 (fMMTable[3] & 0x0c) == 0x04 ? "Philips SAA5281" : "Reserved", 988 989 /* Video Input 0 */ 990 (fMMTable[7] & 0x03) == 0x00 ? "Unused/Invalid" : 991 (fMMTable[7] & 0x03) == 0x01 ? "Tuner Input" : 992 (fMMTable[7] & 0x03) == 0x02 ? "Composite Input" : "S-Video Input", 993 (fMMTable[7] & 0x04) == 0x00 ? "Front Connector" : "Rear Connector", 994 (fMMTable[7] & 0x38) >> 3, 995 996 /* Video Input 1 */ 997 (fMMTable[8] & 0x03) == 0x00 ? "Unused/Invalid" : 998 (fMMTable[8] & 0x03) == 0x01 ? "Tuner Input" : 999 (fMMTable[8] & 0x03) == 0x02 ? "Composite Input" : "S-Video Input", 1000 (fMMTable[8] & 0x04) == 0x00 ? "Front Connector" : "Rear Connector", 1001 (fMMTable[8] & 0x38) >> 3, 1002 1003 /* Video Input 2 */ 1004 (fMMTable[9] & 0x03) == 0x00 ? "Unused/Invalid" : 1005 (fMMTable[9] & 0x03) == 0x01 ? "Tuner Input" : 1006 (fMMTable[9] & 0x03) == 0x02 ? "Composite Input" : "S-Video Input", 1007 (fMMTable[9] & 0x04) == 0x00 ? "Front Connector" : "Rear Connector", 1008 (fMMTable[9] & 0x38) >> 3, 1009 1010 /* Video Input 3 */ 1011 (fMMTable[10] & 0x03) == 0x00 ? "Unused/Invalid" : 1012 (fMMTable[10] & 0x03) == 0x01 ? "Tuner Input" : 1013 (fMMTable[10] & 0x03) == 0x02 ? "Composite Input" : "S-Video Input", 1014 (fMMTable[10] & 0x04) == 0x00 ? "Front Connector" : "Rear Connector", 1015 (fMMTable[10] & 0x38) >> 3, 1016 1017 /* Video Input 4 */ 1018 (fMMTable[11] & 0x03) == 0x00 ? "Unused/Invalid" : 1019 (fMMTable[11] & 0x03) == 0x01 ? "Tuner Input" : 1020 (fMMTable[11] & 0x03) == 0x02 ? "Composite Input" : "S-Video Input", 1021 (fMMTable[11] & 0x04) == 0x00 ? "Front Connector" : "Rear Connector", 1022 (fMMTable[11] & 0x38) >> 3 1023 )); 1024 } 1025 #endif 1026