1 /* 2 Copyright 2007-2011 Haiku, Inc. All rights reserved. 3 Distributed under the terms of the MIT license. 4 5 Authors: 6 Gerald Zajac 7 */ 8 9 #include <KernelExport.h> 10 #include <PCI.h> 11 #include <drivers/bios.h> 12 #include <malloc.h> 13 #include <stdio.h> 14 #include <string.h> 15 #include <graphic_driver.h> 16 #include <boot_item.h> 17 18 #include "DriverInterface.h" 19 20 21 #undef TRACE 22 23 #ifdef ENABLE_DEBUG_TRACE 24 # define TRACE(x...) dprintf("ati: " x) 25 #else 26 # define TRACE(x...) ; 27 #endif 28 29 30 #define ATI_ACCELERANT_NAME "ati.accelerant" 31 32 #define ROUND_TO_PAGE_SIZE(x) (((x) + (B_PAGE_SIZE) - 1) & ~((B_PAGE_SIZE) - 1)) 33 34 #define VESA_MODES_BOOT_INFO "vesa_modes/v1" 35 36 #define SKD_HANDLER_INSTALLED 0x80000000 37 #define MAX_DEVICES 4 38 #define DEVICE_FORMAT "%04X_%04X_%02X%02X%02X" 39 40 #define M64_BIOS_SIZE 0x10000 // 64KB 41 #define R128_BIOS_SIZE 0x10000 // 64KB 42 43 int32 api_version = B_CUR_DRIVER_API_VERSION; // revision of driver API used 44 45 #define VENDOR_ID 0x1002 // ATI vendor ID 46 47 // Mach64 register definitions. 48 #define M64_CLOCK_INTERNAL 4 49 #define M64_CONFIG_CHIP_ID 0x0CE0 // offset in register area 50 #define M64_CFG_CHIP_TYPE 0x0000FFFF 51 52 53 struct ChipInfo { 54 uint16 chipID; // PCI device id of the chip 55 ChipType chipType; // assigned chip type identifier 56 const char* chipName; // user recognizable name for chip 57 // (must be < 32 chars) 58 }; 59 60 61 // Names for chip types. 62 63 static char sRage128_GL[] = "RAGE 128 GL"; 64 static char sRage128_VR[] = "RAGE 128 VR"; 65 static char sRage128_Pro_GL[] = "RAGE 128 PRO GL"; 66 static char sRage128_Pro_VR[] = "RAGE 128 PRO VR"; 67 static char sRage128_Pro_Ultra[] = "RAGE 128 PRO Ultra"; 68 69 // This table maps a PCI device ID to a chip type identifier and the chip name. 70 // The table is split into two groups of chips, the Mach64 and Rage128 chips, 71 // with each group ordered by the chip ID. 72 73 static const ChipInfo chipTable[] = { 74 { 0x4742, MACH64_264GTPRO, "3D RAGE PRO, AGP" }, // GB 75 { 0x4744, MACH64_264GTPRO, "3D RAGE PRO, AGP" }, // GD 76 { 0x4749, MACH64_264GTPRO, "3D RAGE PRO, PCI" }, // GI 77 { 0x474C, MACH64_264XL, "3D RAGE XC, PCI" }, // GL 78 { 0x474D, MACH64_264XL, "3D RAGE XL, AGP" }, // GM 79 { 0x474E, MACH64_264XL, "3D RAGE XC, AGP" }, // GN 80 { 0x474F, MACH64_264XL, "3D RAGE XL, PCI" }, // GO 81 { 0x4750, MACH64_264GTPRO, "3D RAGE PRO, PCI" }, // GP 82 { 0x4751, MACH64_264GTPRO, "3D RAGE PRO, PCI" }, // GQ 83 { 0x4752, MACH64_264XL, "3D RAGE XL, PCI" }, // GR 84 { 0x4753, MACH64_264XL, "3D RAGE XC, PCI" }, // GS 85 { 0x4754, MACH64_264GT, "3D RAGE II" }, // GT 86 { 0x4755, MACH64_264GTDVD, "3D RAGE II+" }, // GU 87 { 0x4756, MACH64_264GT2C, "3D RAGE IIC, PCI" }, // GV 88 { 0x4757, MACH64_264GT2C, "3D RAGE IIC, AGP" }, // GW 89 { 0x4759, MACH64_264GT2C, "3D RAGE IIC, PCI" }, // GY 90 { 0x475A, MACH64_264GT2C, "3D RAGE IIC, AGP" }, // GZ 91 { 0x4C42, MACH64_264LTPRO, "3D RAGE LT PRO, AGP" }, // LB 92 { 0x4C44, MACH64_264LTPRO, "3D RAGE LT PRO, AGP" }, // LD 93 { 0x4C47, MACH64_264LT, "3D RAGE LT" }, // LG 94 { 0x4C49, MACH64_264LTPRO, "3D RAGE LT PRO, PCI" }, // LI 95 { 0x4C4D, MACH64_MOBILITY, "3D RAGE Mobility, AGP" }, // LM 96 { 0x4C4E, MACH64_MOBILITY, "3D RAGE Mobility, AGP" }, // LN 97 { 0x4C50, MACH64_264LTPRO, "3D RAGE LT PRO, PCI" }, // LP 98 { 0x4C51, MACH64_264LTPRO, "3D RAGE LT PRO, PCI" }, // LQ 99 { 0x4C52, MACH64_MOBILITY, "3D RAGE Mobility, PCI" }, // LR 100 { 0x4C53, MACH64_MOBILITY, "3D RAGE Mobility, PCI" }, // LS 101 { 0x5654, MACH64_264VT, "264VT2" }, // VT 102 { 0x5655, MACH64_264VT3, "264VT3" }, // VU 103 { 0x5656, MACH64_264VT4, "264VT4" }, // VV 104 105 { 0x4C45, RAGE128_MOBILITY, "RAGE 128 Mobility 3" }, // LE 106 { 0x4C46, RAGE128_MOBILITY, "RAGE 128 Mobility 3" }, // LF 107 { 0x4D46, RAGE128_MOBILITY, "RAGE 128 Mobility 4" }, // MF 108 { 0x4D4C, RAGE128_MOBILITY, "RAGE 128 Mobility 4" }, // ML 109 { 0x5041, RAGE128_PRO_GL, sRage128_Pro_GL }, // PA 110 { 0x5042, RAGE128_PRO_GL, sRage128_Pro_GL }, // PB 111 { 0x5043, RAGE128_PRO_GL, sRage128_Pro_GL }, // PC 112 { 0x5044, RAGE128_PRO_GL, sRage128_Pro_GL }, // PD 113 { 0x5045, RAGE128_PRO_GL, sRage128_Pro_GL }, // PE 114 { 0x5046, RAGE128_PRO_GL, sRage128_Pro_GL }, // PF 115 { 0x5047, RAGE128_PRO_VR, sRage128_Pro_VR }, // PG 116 { 0x5048, RAGE128_PRO_VR, sRage128_Pro_VR }, // PH 117 { 0x5049, RAGE128_PRO_VR, sRage128_Pro_VR }, // PI 118 { 0x504A, RAGE128_PRO_VR, sRage128_Pro_VR }, // PJ 119 { 0x504B, RAGE128_PRO_VR, sRage128_Pro_VR }, // PK 120 { 0x504C, RAGE128_PRO_VR, sRage128_Pro_VR }, // PL 121 { 0x504D, RAGE128_PRO_VR, sRage128_Pro_VR }, // PM 122 { 0x504E, RAGE128_PRO_VR, sRage128_Pro_VR }, // PN 123 { 0x504F, RAGE128_PRO_VR, sRage128_Pro_VR }, // PO 124 { 0x5050, RAGE128_PRO_VR, sRage128_Pro_VR }, // PP 125 { 0x5051, RAGE128_PRO_VR, sRage128_Pro_VR }, // PQ 126 { 0x5052, RAGE128_PRO_VR, sRage128_Pro_VR }, // PR 127 { 0x5053, RAGE128_PRO_VR, sRage128_Pro_VR }, // PS 128 { 0x5054, RAGE128_PRO_VR, sRage128_Pro_VR }, // PT 129 { 0x5055, RAGE128_PRO_VR, sRage128_Pro_VR }, // PU 130 { 0x5056, RAGE128_PRO_VR, sRage128_Pro_VR }, // PV 131 { 0x5057, RAGE128_PRO_VR, sRage128_Pro_VR }, // PW 132 { 0x5058, RAGE128_PRO_VR, sRage128_Pro_VR }, // PX 133 { 0x5245, RAGE128_GL, sRage128_GL }, // RE 134 { 0x5246, RAGE128_GL, sRage128_GL }, // RF 135 { 0x5247, RAGE128_GL, sRage128_GL }, // RG 136 { 0x524B, RAGE128_VR, sRage128_VR }, // RK 137 { 0x524C, RAGE128_VR, sRage128_VR }, // RL 138 { 0x5345, RAGE128_VR, sRage128_VR }, // SE 139 { 0x5346, RAGE128_VR, sRage128_VR }, // SF 140 { 0x5347, RAGE128_VR, sRage128_VR }, // SG 141 { 0x5348, RAGE128_VR, sRage128_VR }, // SH 142 { 0x534B, RAGE128_GL, sRage128_GL }, // SK 143 { 0x534C, RAGE128_GL, sRage128_GL }, // SL 144 { 0x534D, RAGE128_GL, sRage128_GL }, // SM 145 { 0x534E, RAGE128_GL, sRage128_GL }, // SN 146 { 0x5446, RAGE128_PRO_ULTRA, sRage128_Pro_Ultra }, // TF 147 { 0x544C, RAGE128_PRO_ULTRA, sRage128_Pro_Ultra }, // TL 148 { 0x5452, RAGE128_PRO_ULTRA, sRage128_Pro_Ultra }, // TR 149 { 0x5453, RAGE128_PRO_ULTRA, sRage128_Pro_Ultra }, // TS 150 { 0x5454, RAGE128_PRO_ULTRA, sRage128_Pro_Ultra }, // TT 151 { 0x5455, RAGE128_PRO_ULTRA, sRage128_Pro_Ultra }, // TU 152 { 0, ATI_NONE, NULL } 153 }; 154 155 156 struct DeviceInfo { 157 uint32 openCount; // count of how many times device has been opened 158 int32 flags; 159 area_id sharedArea; // area shared between driver and all accelerants 160 SharedInfo* sharedInfo; // pointer to shared info area memory 161 vuint8* regs; // pointer to memory mapped registers 162 const ChipInfo* pChipInfo; // info about the selected chip 163 pci_info pciInfo; // copy of pci info for this device 164 char name[B_OS_NAME_LENGTH]; // name of device 165 }; 166 167 168 static Benaphore gLock; 169 static DeviceInfo gDeviceInfo[MAX_DEVICES]; 170 static char* gDeviceNames[MAX_DEVICES + 1]; 171 static pci_module_info* gPCI; 172 173 174 // Prototypes for device hook functions. 175 176 static status_t device_open(const char* name, uint32 flags, void** cookie); 177 static status_t device_close(void* dev); 178 static status_t device_free(void* dev); 179 static status_t device_read(void* dev, off_t pos, void* buf, size_t* len); 180 static status_t device_write(void* dev, off_t pos, const void* buf, size_t* len); 181 static status_t device_ioctl(void* dev, uint32 msg, void* buf, size_t len); 182 183 static device_hooks gDeviceHooks = 184 { 185 device_open, 186 device_close, 187 device_free, 188 device_ioctl, 189 device_read, 190 device_write, 191 NULL, 192 NULL, 193 NULL, 194 NULL 195 }; 196 197 198 199 static inline uint32 200 GetPCI(pci_info& info, uint8 offset, uint8 size) 201 { 202 return gPCI->read_pci_config(info.bus, info.device, info.function, offset, 203 size); 204 } 205 206 207 static inline void 208 SetPCI(pci_info& info, uint8 offset, uint8 size, uint32 value) 209 { 210 gPCI->write_pci_config(info.bus, info.device, info.function, offset, size, 211 value); 212 } 213 214 215 // Functions for dealing with Vertical Blanking Interrupts. Currently, I do 216 // not know the commands to handle these operations; thus, these functions 217 // currently do nothing. 218 219 static bool 220 InterruptIsVBI() 221 { 222 // return true only if a vertical blanking interrupt has occured 223 return false; 224 } 225 226 227 static void 228 ClearVBI() 229 { 230 } 231 232 static void 233 EnableVBI() 234 { 235 } 236 237 static void 238 DisableVBI() 239 { 240 } 241 242 243 244 static status_t 245 GetEdidFromBIOS(edid1_raw& edidRaw) 246 { 247 // Get the EDID info from the video BIOS, and return B_OK if successful. 248 249 #define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4) 250 #define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf) 251 252 bios_module_info* biosModule; 253 status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule); 254 if (status != B_OK) { 255 TRACE("GetEdidFromBIOS(): failed to get BIOS module: 0x%" B_PRIx32 "\n", 256 status); 257 return status; 258 } 259 260 bios_state* state; 261 status = biosModule->prepare(&state); 262 if (status != B_OK) { 263 TRACE("GetEdidFromBIOS(): bios_prepare() failed: 0x%" B_PRIx32 "\n", 264 status); 265 put_module(B_BIOS_MODULE_NAME); 266 return status; 267 } 268 269 bios_regs regs = {}; 270 regs.eax = 0x4f15; 271 regs.ebx = 0; // 0 = report DDC service 272 regs.ecx = 0; 273 regs.es = 0; 274 regs.edi = 0; 275 276 status = biosModule->interrupt(state, 0x10, ®s); 277 if (status == B_OK) { 278 // AH contains the error code, and AL determines whether or not the 279 // function is supported. 280 if (regs.eax != 0x4f) 281 status = B_NOT_SUPPORTED; 282 283 // Test if DDC is supported by the monitor. 284 if ((regs.ebx & 3) == 0) 285 status = B_NOT_SUPPORTED; 286 } 287 288 if (status == B_OK) { 289 edid1_raw* edid = (edid1_raw*)biosModule->allocate_mem(state, 290 sizeof(edid1_raw)); 291 if (edid == NULL) { 292 status = B_NO_MEMORY; 293 goto out; 294 } 295 296 regs.eax = 0x4f15; 297 regs.ebx = 1; // 1 = read EDID 298 regs.ecx = 0; 299 regs.edx = 0; 300 regs.es = ADDRESS_SEGMENT(edid); 301 regs.edi = ADDRESS_OFFSET(edid); 302 303 status = biosModule->interrupt(state, 0x10, ®s); 304 if (status == B_OK) { 305 if (regs.eax != 0x4f) { 306 status = B_NOT_SUPPORTED; 307 } else { 308 // Copy the EDID info to the caller's location, and compute the 309 // checksum of the EDID info while copying. 310 311 uint8 sum = 0; 312 uint8 allOr = 0; 313 uint8* dest = (uint8*)&edidRaw; 314 uint8* src = (uint8*)edid; 315 316 for (uint32 j = 0; j < sizeof(edidRaw); j++) { 317 sum += *src; 318 allOr |= *src; 319 *dest++ = *src++; 320 } 321 322 if (allOr == 0) { 323 TRACE("GetEdidFromBIOS(); EDID info contains only zeros\n"); 324 status = B_ERROR; 325 } else if (sum != 0) { 326 TRACE("GetEdidFromBIOS(); Checksum error in EDID info\n"); 327 status = B_ERROR; 328 } 329 } 330 } 331 } 332 333 out: 334 biosModule->finish(state); 335 put_module(B_BIOS_MODULE_NAME); 336 return status; 337 } 338 339 340 static status_t 341 SetVesaDisplayMode(uint16 mode) 342 { 343 // Set the VESA display mode, and return B_OK if successful. 344 345 #define SET_MODE_MASK 0x01ff 346 #define SET_MODE_LINEAR_BUFFER (1 << 14) 347 348 bios_module_info* biosModule; 349 status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule); 350 if (status != B_OK) { 351 TRACE("SetVesaDisplayMode(0x%x): failed to get BIOS module: 0x%" B_PRIx32 352 "\n", mode, status); 353 return status; 354 } 355 356 bios_state* state; 357 status = biosModule->prepare(&state); 358 if (status != B_OK) { 359 TRACE("SetVesaDisplayMode(0x%x): bios_prepare() failed: 0x%" B_PRIx32 360 "\n", mode, status); 361 put_module(B_BIOS_MODULE_NAME); 362 return status; 363 } 364 365 bios_regs regs = {}; 366 regs.eax = 0x4f02; 367 regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER; 368 369 status = biosModule->interrupt(state, 0x10, ®s); 370 if (status != B_OK) { 371 TRACE("SetVesaDisplayMode(0x%x): BIOS interrupt failed\n", mode); 372 } 373 374 if (status == B_OK && (regs.eax & 0xffff) != 0x4f) { 375 TRACE("SetVesaDisplayMode(0x%x): BIOS returned 0x%04" B_PRIx32 "\n", 376 mode, regs.eax & 0xffff); 377 status = B_ERROR; 378 } 379 380 biosModule->finish(state); 381 put_module(B_BIOS_MODULE_NAME); 382 return status; 383 } 384 385 386 387 // Macros for accessing BIOS info. 388 389 #define BIOS8(v) (romAddr[v]) 390 #define BIOS16(v) (romAddr[v] | \ 391 (romAddr[(v) + 1] << 8)) 392 #define BIOS32(v) (romAddr[v] | \ 393 (romAddr[(v) + 1] << 8) | \ 394 (romAddr[(v) + 2] << 16) | \ 395 (romAddr[(v) + 3] << 24)) 396 397 398 static status_t 399 Mach64_GetBiosParameters(DeviceInfo& di, uint8& clockType) 400 { 401 // Get some clock parameters from the video BIOS, and if Mobility chip, 402 // also get the LCD panel width & height. 403 404 // In case mapping the ROM area fails or other error occurs, set default 405 // values for the parameters which will be obtained from the BIOS ROM. 406 407 clockType = M64_CLOCK_INTERNAL; 408 409 SharedInfo& si = *(di.sharedInfo); 410 M64_Params& params = si.m64Params; 411 params.clockNumberToProgram = 3; 412 413 si.panelX = 0; 414 si.panelY = 0; 415 416 // Map the ROM area. The Mach64 chips do not assign a ROM address in the 417 // PCI info; thus, access the ROM via the ISA legacy memory map. 418 419 uint8* romAddr; 420 area_id romArea = map_physical_memory("ATI Mach64 ROM", 421 #if defined(__x86__) || defined(__x86_64__) 422 0x000c0000, 423 #else 424 di.pciInfo.u.h0.rom_base, 425 #endif 426 M64_BIOS_SIZE, 427 B_ANY_KERNEL_ADDRESS, 428 B_KERNEL_READ_AREA, 429 (void**)&(romAddr)); 430 431 if (romArea < 0) { 432 TRACE("Mach64_GetBiosParameters(), ROM mapping error: %" B_PRId32 "\n", 433 romArea); 434 return romArea; // ROM mapping failed; return error code 435 } 436 437 // Check if we have the BIOS signature (might fail on laptops..). 438 439 if (BIOS8(0) != 0x55 || BIOS8(1) != 0xaa) { 440 TRACE("Mach64_GetBiosParameters(), ROM does not contain BIOS signature\n"); 441 delete_area(romArea); 442 return B_ERROR; 443 } 444 445 // Get clock info from BIOS. 446 447 uint32 romTable = BIOS16(0x48); 448 uint32 clockTable = BIOS16(romTable + 16); 449 clockType = BIOS8(clockTable); 450 params.clockNumberToProgram = BIOS8(clockTable + 6); 451 params.maxPixelClock = BIOS16(clockTable + 4) * 10; 452 params.refFreq = BIOS16(clockTable + 8); 453 params.refDivider = BIOS16(clockTable + 10); 454 455 // If Mobility chip, get the LCD panel width & height. 456 457 if (si.chipType == MACH64_MOBILITY) { 458 uint32 lcdTable = BIOS16(0x78); 459 if (BIOS32(lcdTable) == 0x544d5224) { // is LCD table signature correct? 460 uint32 lcdPanelInfo = BIOS16(lcdTable + 10); 461 si.panelX = BIOS16(lcdPanelInfo + 25); 462 si.panelY = BIOS16(lcdPanelInfo + 27); 463 TRACE("Mobility LCD Panel size: %dx%d\n", si.panelX, si.panelY); 464 } else { 465 TRACE("Mobility LCD table signature 0x%x in BIOS is incorrect\n", 466 BIOS32(lcdTable)); 467 } 468 } 469 470 delete_area(romArea); 471 472 return B_OK; 473 } 474 475 476 477 static status_t 478 Rage128_GetBiosParameters(DeviceInfo& di) 479 { 480 // Get the PLL parameters from the video BIOS, and if Mobility chips, also 481 // get the LCD panel width & height and a few other related parameters. 482 483 // In case mapping the ROM area fails or other error occurs, set default 484 // values for the parameters which will be obtained from the BIOS ROM. 485 // The default PLL parameters values probably will not work for all chips. 486 // For example, reference freq can be 29.50MHz, 28.63MHz, or 14.32MHz. 487 488 SharedInfo& si = *(di.sharedInfo); 489 R128_PLLParams& pll = si.r128PLLParams; 490 pll.reference_freq = 2950; 491 pll.reference_div = 65; 492 pll.min_pll_freq = 12500; 493 pll.max_pll_freq = 25000; 494 pll.xclk = 10300; 495 496 si.panelX = 0; 497 si.panelY = 0; 498 si.panelPowerDelay = 1; 499 500 // Map the ROM area. The Rage128 chips do not assign a ROM address in the 501 // PCI info; thus, access the ROM via the ISA legacy memory map. 502 503 uint8* romAddr; 504 area_id romArea = map_physical_memory("ATI Rage128 ROM", 505 #if defined(__x86__) || defined(__x86_64__) 506 0x000c0000, 507 #else 508 di.pciInfo.u.h0.rom_base, 509 #endif 510 R128_BIOS_SIZE, 511 B_ANY_KERNEL_ADDRESS, 512 B_KERNEL_READ_AREA, 513 (void**)&(romAddr)); 514 515 if (romArea < 0) { 516 TRACE("Rage128_GetBiosParameters(), ROM mapping error: %" B_PRId32 517 "\n", romArea); 518 return romArea; // ROM mapping failed; return error code 519 } 520 521 // Check if we got the BIOS signature (might fail on laptops..). 522 523 if (BIOS8(0) != 0x55 || BIOS8(1) != 0xaa) { 524 TRACE("Rage128_GetBiosParameters(), ROM does not contain BIOS signature\n"); 525 delete_area(romArea); 526 return B_ERROR; 527 } 528 529 // Get the PLL values from the mapped ROM area. 530 531 uint16 biosHeader = BIOS16(0x48); 532 uint16 pllInfoBlock = BIOS16(biosHeader + 0x30); 533 534 pll.reference_freq = BIOS16(pllInfoBlock + 0x0e); 535 pll.reference_div = BIOS16(pllInfoBlock + 0x10); 536 pll.min_pll_freq = BIOS32(pllInfoBlock + 0x12); 537 pll.max_pll_freq = BIOS32(pllInfoBlock + 0x16); 538 pll.xclk = BIOS16(pllInfoBlock + 0x08); 539 540 TRACE("PLL parameters: rf=%d rd=%d min=%" B_PRId32 " max=%" B_PRId32 541 "; xclk=%d\n", 542 pll.reference_freq, pll.reference_div, pll.min_pll_freq, 543 pll.max_pll_freq, pll.xclk); 544 545 // If Mobility chip, get the LCD panel width & height and a few other 546 // related parameters. 547 548 if (si.chipType == RAGE128_MOBILITY) { 549 // There should be direct access to the start of the FP info table, but 550 // until we find out where that offset is stored, we must search for 551 // the ATI signature string: "M3 ". 552 553 int i; 554 for (i = 4; i < R128_BIOS_SIZE - 8; i++) { 555 if (BIOS8(i) == 'M' && 556 BIOS8(i + 1) == '3' && 557 BIOS8(i + 2) == ' ' && 558 BIOS8(i + 3) == ' ' && 559 BIOS8(i + 4) == ' ' && 560 BIOS8(i + 5) == ' ' && 561 BIOS8(i + 6) == ' ' && 562 BIOS8(i + 7) == ' ') { 563 int fpHeader = i - 2; 564 565 // Assume that only one panel is attached and supported. 566 567 for (i = fpHeader + 20; i < fpHeader + 84; i += 2) { 568 if (BIOS16(i) != 0) { 569 int fpStart = BIOS16(i); 570 si.panelX = BIOS16(fpStart + 25); 571 si.panelY = BIOS16(fpStart + 27); 572 si.panelPowerDelay = BIOS8(fpStart + 56); 573 TRACE("LCD Panel size: %dx%d Panel type: 0x%x power delay: %d\n", 574 si.panelX, si.panelY, BIOS16(fpStart + 29), 575 si.panelPowerDelay); 576 break; 577 } 578 } 579 580 break; 581 } 582 } 583 } 584 585 delete_area(romArea); 586 587 return B_OK; 588 } 589 590 591 static status_t 592 MapDevice(DeviceInfo& di) 593 { 594 SharedInfo& si = *(di.sharedInfo); 595 pci_info& pciInfo = di.pciInfo; 596 597 // Enable memory mapped IO and bus master. 598 599 SetPCI(pciInfo, PCI_command, 2, GetPCI(pciInfo, PCI_command, 2) 600 | PCI_command_io | PCI_command_memory | PCI_command_master); 601 602 // Enable ROM decoding 603 604 if (di.pciInfo.u.h0.rom_size > 0) { 605 SetPCI(pciInfo, PCI_rom_base, 4, 606 GetPCI(pciInfo, PCI_rom_base, 4) | 0x00000001); 607 } 608 609 // Map the video memory. 610 611 phys_addr_t videoRamAddr = pciInfo.u.h0.base_registers[0]; 612 uint32 videoRamSize = pciInfo.u.h0.base_register_sizes[0]; 613 si.videoMemPCI = videoRamAddr; 614 char frameBufferAreaName[] = "ATI frame buffer"; 615 616 si.videoMemArea = map_physical_memory( 617 frameBufferAreaName, 618 videoRamAddr, 619 videoRamSize, 620 B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC, 621 B_READ_AREA + B_WRITE_AREA, 622 (void**)&(si.videoMemAddr)); 623 624 if (si.videoMemArea < 0) { 625 // Try to map this time without write combining. 626 si.videoMemArea = map_physical_memory( 627 frameBufferAreaName, 628 videoRamAddr, 629 videoRamSize, 630 B_ANY_KERNEL_BLOCK_ADDRESS, 631 B_READ_AREA + B_WRITE_AREA, 632 (void**)&(si.videoMemAddr)); 633 } 634 635 if (si.videoMemArea < 0) 636 return si.videoMemArea; 637 638 // Map the MMIO register area. 639 640 phys_addr_t regsBase = pciInfo.u.h0.base_registers[2]; 641 uint32 regAreaSize = pciInfo.u.h0.base_register_sizes[2]; 642 643 // If the register area address or size is not in the PCI info, it should 644 // be at the end of the video memory. Check if it is there. 645 646 if (MACH64_FAMILY(si.chipType) && (regsBase == 0 || regAreaSize == 0)) { 647 uint32 regsOffset = 0x7ff000; // offset to regs area in video memory 648 addr_t regs = addr_t(si.videoMemAddr) + regsOffset; 649 uint32 chipInfo = *((vuint32*)(regs + M64_CONFIG_CHIP_ID)); 650 651 if (si.deviceID != (chipInfo & M64_CFG_CHIP_TYPE)) { 652 // Register area not found; delete any other areas that were 653 // created. 654 delete_area(si.videoMemArea); 655 si.videoMemArea = -1; 656 TRACE("Mach64 register area not found\n"); 657 return B_ERROR; 658 } 659 660 // Adjust params for creating register area below. 661 662 regsBase = videoRamAddr + regsOffset; 663 regAreaSize = 0x1000; 664 TRACE("Register address is at end of frame buffer memory at 0x%" 665 B_PRIxPHYSADDR "\n", regsBase); 666 } 667 668 si.regsArea = map_physical_memory("ATI mmio registers", 669 regsBase, 670 regAreaSize, 671 B_ANY_KERNEL_ADDRESS, 672 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_CLONEABLE_AREA, 673 (void**)&di.regs); 674 675 // If there was an error, delete other areas. 676 if (si.regsArea < 0) { 677 delete_area(si.videoMemArea); 678 si.videoMemArea = -1; 679 } 680 681 return si.regsArea; 682 } 683 684 685 static void 686 UnmapDevice(DeviceInfo& di) 687 { 688 SharedInfo& si = *(di.sharedInfo); 689 690 if (si.regsArea >= 0) 691 delete_area(si.regsArea); 692 if (si.videoMemArea >= 0) 693 delete_area(si.videoMemArea); 694 695 si.regsArea = si.videoMemArea = -1; 696 si.videoMemAddr = (addr_t)NULL; 697 di.regs = NULL; 698 } 699 700 701 static int32 702 InterruptHandler(void* data) 703 { 704 int32 handled = B_UNHANDLED_INTERRUPT; 705 DeviceInfo& di = *((DeviceInfo*)data); 706 int32* flags = &(di.flags); 707 708 // Is someone already handling an interrupt for this device? 709 if (atomic_or(flags, SKD_HANDLER_INSTALLED) & SKD_HANDLER_INSTALLED) 710 return B_UNHANDLED_INTERRUPT; 711 712 if (InterruptIsVBI()) { // was interrupt a VBI? 713 ClearVBI(); // clear interrupt 714 715 handled = B_HANDLED_INTERRUPT; 716 717 // Release vertical blanking semaphore. 718 sem_id& sem = di.sharedInfo->vertBlankSem; 719 720 if (sem >= 0) { 721 int32 blocked; 722 if ((get_sem_count(sem, &blocked) == B_OK) && (blocked < 0)) { 723 release_sem_etc(sem, -blocked, B_DO_NOT_RESCHEDULE); 724 handled = B_INVOKE_SCHEDULER; 725 } 726 } 727 } 728 729 atomic_and(flags, ~SKD_HANDLER_INSTALLED); // note we're not in handler anymore 730 731 return handled; 732 } 733 734 735 static void 736 InitInterruptHandler(DeviceInfo& di) 737 { 738 SharedInfo& si = *(di.sharedInfo); 739 740 DisableVBI(); // disable & clear any pending interrupts 741 si.bInterruptAssigned = false; // indicate interrupt not assigned yet 742 743 // Create a semaphore for vertical blank management. 744 si.vertBlankSem = create_sem(0, di.name); 745 if (si.vertBlankSem < 0) 746 return; 747 748 // Change the owner of the semaphores to the calling team (usually the 749 // app_server). This is required because apps can't aquire kernel 750 // semaphores. 751 752 thread_id threadID = find_thread(NULL); 753 thread_info threadInfo; 754 status_t status = get_thread_info(threadID, &threadInfo); 755 if (status == B_OK) 756 status = set_sem_owner(si.vertBlankSem, threadInfo.team); 757 758 // If there is a valid interrupt assigned, set up interrupts. 759 760 if (status == B_OK && di.pciInfo.u.h0.interrupt_pin != 0x00 761 && di.pciInfo.u.h0.interrupt_line != 0xff) { 762 // We have a interrupt line to use. 763 764 status = install_io_interrupt_handler(di.pciInfo.u.h0.interrupt_line, 765 InterruptHandler, (void*)(&di), 0); 766 767 if (status == B_OK) 768 si.bInterruptAssigned = true; // we can use interrupt related functions 769 } 770 771 if (status != B_OK) { 772 // Interrupt does not exist; thus delete semaphore as it won't be used. 773 delete_sem(si.vertBlankSem); 774 si.vertBlankSem = -1; 775 } 776 } 777 778 779 static status_t 780 InitDevice(DeviceInfo& di) 781 { 782 // Perform initialization and mapping of the device, and return B_OK if 783 // sucessful; else, return error code. 784 785 // Get the table of VESA modes that the chip supports. Note that we will 786 // need this table only for chips that are currently connected to a laptop 787 // display or a monitor connected via a DVI interface. 788 789 size_t vesaModeTableSize = 0; 790 VesaMode* vesaModes = (VesaMode*)get_boot_item(VESA_MODES_BOOT_INFO, 791 &vesaModeTableSize); 792 793 size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7; 794 795 // Create the area for shared info with NO user-space read or write 796 // permissions, to prevent accidental damage. 797 798 di.sharedArea = create_area("ATI shared info", 799 (void**) &(di.sharedInfo), 800 B_ANY_KERNEL_ADDRESS, 801 ROUND_TO_PAGE_SIZE(sharedSize + vesaModeTableSize), 802 B_FULL_LOCK, 803 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_CLONEABLE_AREA); 804 if (di.sharedArea < 0) 805 return di.sharedArea; // return error code 806 807 SharedInfo& si = *(di.sharedInfo); 808 809 memset(&si, 0, sharedSize); 810 811 if (vesaModes != NULL) { 812 si.vesaModeTableOffset = sharedSize; 813 si.vesaModeCount = vesaModeTableSize / sizeof(VesaMode); 814 815 memcpy((uint8*)&si + si.vesaModeTableOffset, vesaModes, 816 vesaModeTableSize); 817 } 818 819 pci_info& pciInfo = di.pciInfo; 820 821 si.vendorID = pciInfo.vendor_id; 822 si.deviceID = pciInfo.device_id; 823 si.revision = pciInfo.revision; 824 si.chipType = di.pChipInfo->chipType; 825 strcpy(si.chipName, di.pChipInfo->chipName); 826 827 TRACE("Chip revision: 0x%x\n", si.revision); 828 829 // 264GT has two chip versions. If version is non-zero, chip is 264GTB. 830 831 if (si.chipType == MACH64_264GT && si.revision & 0x7) 832 si.chipType = MACH64_264GTB; 833 834 // 264VT has two chip versions. If version is non-zero, chip is 264VTB. 835 836 if (si.chipType == MACH64_264VT && si.revision & 0x7) 837 si.chipType = MACH64_264VTB; 838 839 status_t status = MapDevice(di); 840 841 // If device mapped without any error, get the bios parameters from the 842 // chip's BIOS ROM. 843 844 if (status >= 0) { 845 if (MACH64_FAMILY(si.chipType)) { 846 uint8 clockType; 847 Mach64_GetBiosParameters(di, clockType); 848 849 // All chips supported by this driver should have an internal clock. 850 // If the clock is not an internal clock, the video chip is not 851 // supported. 852 853 if (clockType != M64_CLOCK_INTERNAL) { 854 TRACE("Video chip clock type %d not supported\n", clockType); 855 status = B_UNSUPPORTED; 856 } 857 } 858 else if (RAGE128_FAMILY(si.chipType)) 859 Rage128_GetBiosParameters(di); 860 } 861 862 if (status < 0) { 863 delete_area(di.sharedArea); 864 di.sharedArea = -1; 865 di.sharedInfo = NULL; 866 return status; // return error code 867 } 868 869 InitInterruptHandler(di); 870 871 TRACE("Interrupt assigned: %s\n", si.bInterruptAssigned ? "yes" : "no"); 872 return B_OK; 873 } 874 875 876 static const ChipInfo* 877 GetNextSupportedDevice(uint32& pciIndex, pci_info& pciInfo) 878 { 879 // Search the PCI devices for a device that is supported by this driver. 880 // The search starts at the device specified by argument pciIndex, and 881 // continues until a supported device is found or there are no more devices 882 // to examine. Argument pciIndex is incremented after each device is 883 // examined. 884 885 // If a supported device is found, return a pointer to the struct containing 886 // the chip info; else return NULL. 887 888 while (gPCI->get_nth_pci_info(pciIndex, &pciInfo) == B_OK) { 889 890 if (pciInfo.vendor_id == VENDOR_ID) { 891 892 // Search the table of supported devices to find a chip/device that 893 // matches device ID of the current PCI device. 894 895 const ChipInfo* pDevice = chipTable; 896 897 while (pDevice->chipID != 0) { // end of table? 898 if (pDevice->chipID == pciInfo.device_id) { 899 // Matching device/chip found. If chip is 264VT, reject it 900 // if its version is zero since the mode can not be set on 901 // that chip. 902 903 if (pDevice->chipType == MACH64_264VT 904 && (pciInfo.revision & 0x7) == 0) 905 break; 906 907 return pDevice; // matching device/chip found 908 } 909 910 pDevice++; 911 } 912 } 913 914 pciIndex++; 915 } 916 917 return NULL; // no supported device found 918 } 919 920 921 922 // #pragma mark - Kernel Interface 923 924 925 status_t 926 init_hardware(void) 927 { 928 // Return B_OK if a device supported by this driver is found; otherwise, 929 // return B_ERROR so the driver will be unloaded. 930 931 if (get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI) != B_OK) 932 return B_ERROR; // unable to access PCI bus 933 934 // Check pci devices for a device supported by this driver. 935 936 uint32 pciIndex = 0; 937 pci_info pciInfo; 938 const ChipInfo* pDevice = GetNextSupportedDevice(pciIndex, pciInfo); 939 940 TRACE("init_hardware() - %s\n", 941 pDevice == NULL ? "no supported devices" : "device supported"); 942 943 put_module(B_PCI_MODULE_NAME); // put away the module manager 944 945 return (pDevice == NULL ? B_ERROR : B_OK); 946 } 947 948 949 status_t 950 init_driver(void) 951 { 952 // Get handle for the pci bus. 953 954 if (get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI) != B_OK) 955 return B_ERROR; 956 957 status_t status = gLock.Init("ATI driver lock"); 958 if (status < B_OK) 959 return status; 960 961 // Get info about all the devices supported by this driver. 962 963 uint32 pciIndex = 0; 964 uint32 count = 0; 965 966 while (count < MAX_DEVICES) { 967 DeviceInfo& di = gDeviceInfo[count]; 968 969 const ChipInfo* pDevice = GetNextSupportedDevice(pciIndex, di.pciInfo); 970 if (pDevice == NULL) 971 break; // all supported devices have been obtained 972 973 // Compose device name. 974 sprintf(di.name, "graphics/" DEVICE_FORMAT, 975 di.pciInfo.vendor_id, di.pciInfo.device_id, 976 di.pciInfo.bus, di.pciInfo.device, di.pciInfo.function); 977 TRACE("init_driver() match found; name: %s\n", di.name); 978 979 gDeviceNames[count] = di.name; 980 di.openCount = 0; // mark driver as available for R/W open 981 di.sharedArea = -1; // indicate shared area not yet created 982 di.sharedInfo = NULL; 983 di.pChipInfo = pDevice; 984 count++; 985 pciIndex++; 986 } 987 988 gDeviceNames[count] = NULL; // terminate list with null pointer 989 990 TRACE("init_driver() %" B_PRIu32 " supported devices\n", count); 991 992 return B_OK; 993 } 994 995 996 void 997 uninit_driver(void) 998 { 999 // Free the driver data. 1000 1001 gLock.Delete(); 1002 put_module(B_PCI_MODULE_NAME); // put the pci module away 1003 } 1004 1005 1006 const char** 1007 publish_devices(void) 1008 { 1009 return (const char**)gDeviceNames; // return list of supported devices 1010 } 1011 1012 1013 device_hooks* 1014 find_device(const char* name) 1015 { 1016 int i = 0; 1017 while (gDeviceNames[i] != NULL) { 1018 if (strcmp(name, gDeviceNames[i]) == 0) 1019 return &gDeviceHooks; 1020 i++; 1021 } 1022 1023 return NULL; 1024 } 1025 1026 1027 1028 // #pragma mark - Device Hooks 1029 1030 1031 static status_t 1032 device_open(const char* name, uint32 /*flags*/, void** cookie) 1033 { 1034 status_t status = B_OK; 1035 1036 TRACE("device_open() - name: %s\n", name); 1037 1038 // Find the device name in the list of devices. 1039 1040 int32 i = 0; 1041 while (gDeviceNames[i] != NULL && (strcmp(name, gDeviceNames[i]) != 0)) 1042 i++; 1043 1044 if (gDeviceNames[i] == NULL) 1045 return B_BAD_VALUE; // device name not found in list of devices 1046 1047 DeviceInfo& di = gDeviceInfo[i]; 1048 1049 gLock.Acquire(); // make sure no one else has write access to common data 1050 1051 if (di.openCount == 0) 1052 status = InitDevice(di); 1053 1054 gLock.Release(); 1055 1056 if (status == B_OK) { 1057 di.openCount++; // mark device open 1058 *cookie = &di; // send cookie to opener 1059 } 1060 1061 TRACE("device_open() returning 0x%" B_PRIx32 ", open count: %" B_PRIu32 "\n", status, 1062 di.openCount); 1063 return status; 1064 } 1065 1066 1067 static status_t 1068 device_read(void* dev, off_t pos, void* buf, size_t* len) 1069 { 1070 // Following 3 lines of code are here to eliminate "unused parameter" 1071 // warnings. 1072 (void)dev; 1073 (void)pos; 1074 (void)buf; 1075 1076 *len = 0; 1077 return B_NOT_ALLOWED; 1078 } 1079 1080 1081 static status_t 1082 device_write(void* dev, off_t pos, const void* buf, size_t* len) 1083 { 1084 // Following 3 lines of code are here to eliminate "unused parameter" 1085 // warnings. 1086 (void)dev; 1087 (void)pos; 1088 (void)buf; 1089 1090 *len = 0; 1091 return B_NOT_ALLOWED; 1092 } 1093 1094 1095 static status_t 1096 device_close(void* dev) 1097 { 1098 (void)dev; // avoid compiler warning for unused arg 1099 1100 return B_NO_ERROR; 1101 } 1102 1103 1104 static status_t 1105 device_free(void* dev) 1106 { 1107 DeviceInfo& di = *((DeviceInfo*)dev); 1108 SharedInfo& si = *(di.sharedInfo); 1109 pci_info& pciInfo = di.pciInfo; 1110 1111 TRACE("enter device_free()\n"); 1112 1113 gLock.Acquire(); // lock driver 1114 1115 // If opened multiple times, merely decrement the open count and exit. 1116 1117 if (di.openCount <= 1) { 1118 DisableVBI(); // disable & clear any pending interrupts 1119 1120 if (si.bInterruptAssigned) { 1121 remove_io_interrupt_handler(pciInfo.u.h0.interrupt_line, 1122 InterruptHandler, &di); 1123 } 1124 1125 // Delete the semaphores, ignoring any errors because the owning team 1126 // may have died. 1127 if (si.vertBlankSem >= 0) 1128 delete_sem(si.vertBlankSem); 1129 si.vertBlankSem = -1; 1130 1131 UnmapDevice(di); // free regs and frame buffer areas 1132 1133 delete_area(di.sharedArea); 1134 di.sharedArea = -1; 1135 di.sharedInfo = NULL; 1136 } 1137 1138 if (di.openCount > 0) 1139 di.openCount--; // mark device available 1140 1141 gLock.Release(); // unlock driver 1142 1143 TRACE("exit device_free() openCount: %" B_PRIu32 "\n", di.openCount); 1144 return B_OK; 1145 } 1146 1147 1148 static status_t 1149 device_ioctl(void* dev, uint32 msg, void* buffer, size_t bufferLength) 1150 { 1151 DeviceInfo& di = *((DeviceInfo*)dev); 1152 1153 TRACE("device_ioctl(); ioctl: %" B_PRIu32 ", buffer: %#08" B_PRIxADDR 1154 ", bufLen: %" B_PRIuSIZE "\n", msg, (addr_t)buffer, bufferLength); 1155 1156 switch (msg) { 1157 case B_GET_ACCELERANT_SIGNATURE: 1158 { 1159 status_t status = user_strlcpy((char*)buffer, ATI_ACCELERANT_NAME, 1160 bufferLength); 1161 if (status < B_OK) 1162 return status; 1163 1164 return B_OK; 1165 } 1166 1167 case ATI_DEVICE_NAME: 1168 { 1169 status_t status = user_strlcpy((char*)buffer, di.name, 1170 B_OS_NAME_LENGTH); 1171 if (status < B_OK) 1172 return status; 1173 1174 return B_OK; 1175 } 1176 1177 case ATI_GET_SHARED_DATA: 1178 if (bufferLength != sizeof(area_id)) 1179 return B_BAD_DATA; 1180 1181 return user_memcpy(buffer, &di.sharedArea, sizeof(area_id)); 1182 1183 case ATI_GET_EDID: 1184 { 1185 if (bufferLength != sizeof(edid1_raw)) 1186 return B_BAD_DATA; 1187 1188 edid1_raw rawEdid; 1189 status_t status = GetEdidFromBIOS(rawEdid); 1190 if (status != B_OK) 1191 return status; 1192 1193 return user_memcpy((edid1_raw*)buffer, &rawEdid, sizeof(rawEdid)); 1194 } 1195 1196 case ATI_SET_VESA_DISPLAY_MODE: 1197 { 1198 if (bufferLength != sizeof(uint16)) 1199 return B_BAD_DATA; 1200 1201 uint16 value; 1202 status_t status = user_memcpy(&value, buffer, sizeof(uint16)); 1203 if (status < B_OK) 1204 return status; 1205 1206 return SetVesaDisplayMode(value); 1207 } 1208 1209 case ATI_RUN_INTERRUPTS: 1210 { 1211 if (bufferLength != sizeof(bool)) 1212 return B_BAD_DATA; 1213 1214 bool value; 1215 status_t res = user_memcpy(&value, buffer, sizeof(bool)); 1216 if (res < B_OK) 1217 return res; 1218 1219 if (value) 1220 EnableVBI(); 1221 else 1222 DisableVBI(); 1223 1224 return B_OK; 1225 } 1226 } 1227 1228 return B_DEV_INVALID_IOCTL; 1229 } 1230