1 /* 2 Copyright 2007-2009 Haiku, Inc. All rights reserved. 3 Distributed under the terms of the MIT license. 4 5 Authors: 6 Gerald Zajac 2007-2009 7 */ 8 9 #include <KernelExport.h> 10 #include <PCI.h> 11 #include <malloc.h> 12 #include <stdio.h> 13 #include <string.h> 14 #include <graphic_driver.h> 15 #include <boot_item.h> 16 #include <arch/x86/vm86.h> 17 18 #include "DriverInterface.h" 19 20 21 #undef TRACE 22 23 //#define ENABLE_DEBUG_TRACE 24 #ifdef ENABLE_DEBUG_TRACE 25 # define TRACE(x...) dprintf("ati: " x) 26 #else 27 # define TRACE(x...) ; 28 #endif 29 30 31 #define ATI_ACCELERANT_NAME "ati.accelerant" 32 33 #define ROUND_TO_PAGE_SIZE(x) (((x) + (B_PAGE_SIZE) - 1) & ~((B_PAGE_SIZE) - 1)) 34 35 #define VESA_MODES_BOOT_INFO "vesa_modes/v1" 36 37 #define SKD_HANDLER_INSTALLED 0x80000000 38 #define MAX_DEVICES 4 39 #define DEVICE_FORMAT "%04X_%04X_%02X%02X%02X" 40 41 #define M64_BIOS_SIZE 0x10000 // 64KB 42 #define R128_BIOS_SIZE 0x10000 // 64KB 43 44 int32 api_version = B_CUR_DRIVER_API_VERSION; // revision of driver API we support 45 46 #define VENDOR_ID 0x1002 // ATI vendor ID 47 48 // Mach64 register definitions. 49 #define M64_CLOCK_INTERNAL 4 50 #define M64_CONFIG_CHIP_ID 0x0CE0 // offset in register area 51 #define M64_CFG_CHIP_TYPE 0x0000FFFF 52 53 54 struct ChipInfo { 55 uint16 chipID; // PCI device id of the chip 56 ChipType chipType; // assigned chip type identifier 57 const char* chipName; // user recognizable name for chip (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, size); 203 } 204 205 206 static inline void 207 SetPCI(pci_info& info, uint8 offset, uint8 size, uint32 value) 208 { 209 gPCI->write_pci_config(info.bus, info.device, info.function, offset, size, value); 210 } 211 212 213 // Functions for dealing with Vertical Blanking Interrupts. Currently, I do 214 // not know the commands to handle these operations; thus, these functions 215 // currently do nothing. 216 217 static bool 218 InterruptIsVBI() 219 { 220 // return true only if a vertical blanking interrupt has occured 221 return false; 222 } 223 224 225 static void 226 ClearVBI() 227 { 228 } 229 230 static void 231 EnableVBI() 232 { 233 } 234 235 static void 236 DisableVBI() 237 { 238 } 239 240 241 242 static status_t 243 GetEdidFromBIOS(edid1_raw& edidRaw) 244 { 245 // Get the EDID info from the video BIOS, and return B_OK if successful. 246 247 #define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4) 248 #define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf) 249 250 vm86_state vmState; 251 252 status_t status = vm86_prepare(&vmState, 0x2000); 253 if (status != B_OK) { 254 TRACE("GetEdidFromBIOS(); vm86_prepare() failed, status: 0x%lx\n", status); 255 return status; 256 } 257 258 vmState.regs.eax = 0x4f15; 259 vmState.regs.ebx = 0; // 0 = report DDC service 260 vmState.regs.ecx = 0; 261 vmState.regs.es = 0; 262 vmState.regs.edi = 0; 263 264 status = vm86_do_int(&vmState, 0x10); 265 if (status == B_OK) { 266 // AH contains the error code, and AL determines wether or not the 267 // function is supported. 268 if (vmState.regs.eax != 0x4f) 269 status = B_NOT_SUPPORTED; 270 271 // Test if DDC is supported by the monitor. 272 if ((vmState.regs.ebx & 3) == 0) 273 status = B_NOT_SUPPORTED; 274 } 275 276 if (status == B_OK) { 277 // According to the author of the vm86 functions, the address of any 278 // object to receive data must be >= 0x1000 and within the ram size 279 // specified in the second argument of the vm86_prepare() call above. 280 // Thus, the address of the struct to receive the EDID info is set to 281 // 0x1000. 282 283 edid1_raw* edid = (edid1_raw*)0x1000; 284 285 vmState.regs.eax = 0x4f15; 286 vmState.regs.ebx = 1; // 1 = read EDID 287 vmState.regs.ecx = 0; 288 vmState.regs.edx = 0; 289 vmState.regs.es = ADDRESS_SEGMENT(edid); 290 vmState.regs.edi = ADDRESS_OFFSET(edid); 291 292 status = vm86_do_int(&vmState, 0x10); 293 if (status == B_OK) { 294 if (vmState.regs.eax != 0x4f) { 295 status = B_NOT_SUPPORTED; 296 } else { 297 // Copy the EDID info to the caller's location, and compute the 298 // checksum of the EDID info while copying. 299 300 uint8 sum = 0; 301 uint8 allOr = 0; 302 uint8* dest = (uint8*)&edidRaw; 303 uint8* src = (uint8*)edid; 304 305 for (uint32 j = 0; j < sizeof(edidRaw); j++) { 306 sum += *src; 307 allOr |= *src; 308 *dest++ = *src++; 309 } 310 311 if (allOr == 0) { 312 TRACE("GetEdidFromBIOS(); EDID info contains only zeros\n"); 313 status = B_ERROR; 314 } else if (sum != 0) { 315 TRACE("GetEdidFromBIOS(); Checksum error in EDID info\n"); 316 status = B_ERROR; 317 } 318 } 319 } 320 } 321 322 vm86_cleanup(&vmState); 323 324 return status; 325 } 326 327 328 static status_t 329 SetVesaDisplayMode(uint16 mode) 330 { 331 // Set the VESA display mode, and return B_OK if successful. 332 333 #define SET_MODE_MASK 0x01ff 334 #define SET_MODE_LINEAR_BUFFER (1 << 14) 335 336 vm86_state vmState; 337 338 status_t status = vm86_prepare(&vmState, 0x2000); 339 if (status != B_OK) { 340 TRACE("SetVesaDisplayMode(); vm86_prepare() failed, status: 0x%lx\n", status); 341 return status; 342 } 343 344 vmState.regs.eax = 0x4f02; 345 vmState.regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER; 346 347 status = vm86_do_int(&vmState, 0x10); 348 if (status != B_OK) { 349 TRACE("SetVesaDisplayMode(0x%x): vm86_do_int failed\n", mode); 350 } 351 352 if (status == B_OK && (vmState.regs.eax & 0xffff) != 0x4f) { 353 TRACE("SetVesaDisplayMode(0x%x): BIOS returned 0x%04lx\n", mode, 354 vmState.regs.eax & 0xffff); 355 status = B_ERROR; 356 } 357 358 vm86_cleanup(&vmState); 359 360 return status; 361 } 362 363 364 365 // Macros for accessing BIOS info. 366 367 #define BIOS8(v) (romAddr[v]) 368 #define BIOS16(v) (romAddr[v] | \ 369 (romAddr[(v) + 1] << 8)) 370 #define BIOS32(v) (romAddr[v] | \ 371 (romAddr[(v) + 1] << 8) | \ 372 (romAddr[(v) + 2] << 16) | \ 373 (romAddr[(v) + 3] << 24)) 374 375 376 static status_t 377 Mach64_GetBiosParameters(DeviceInfo& di, uint8& clockType) 378 { 379 // Get some clock parameters from the video BIOS, and if Mobility chip, 380 // also get the LCD panel width & height. 381 382 // In case mapping the ROM area fails or other error occurs, set default 383 // values for the parameters which will be obtained from the BIOS ROM. 384 385 clockType = M64_CLOCK_INTERNAL; 386 387 SharedInfo& si = *(di.sharedInfo); 388 M64_Params& params = si.m64Params; 389 params.clockNumberToProgram = 3; 390 391 si.panelX = 0; 392 si.panelY = 0; 393 394 // Map the ROM area. The Mach64 chips do not assign a ROM address in the 395 // PCI info; thus, access the ROM via the ISA legacy memory map. 396 397 uint8* romAddr; 398 area_id romArea = map_physical_memory("ATI Mach64 ROM", 399 0x000c0000, 400 M64_BIOS_SIZE, 401 B_ANY_KERNEL_ADDRESS, 402 B_READ_AREA, 403 (void**)&(romAddr)); 404 405 if (romArea < 0) { 406 TRACE("Mach64_GetBiosParameters(), ROM mapping error: %ld\n", romArea); 407 return romArea; // ROM mapping failed; return error code 408 } 409 410 // Check if we have the BIOS signature (might fail on laptops..). 411 412 if (BIOS8(0) != 0x55 || BIOS8(1) != 0xaa) { 413 TRACE("Mach64_GetBiosParameters(), ROM does not contain BIOS signature\n"); 414 delete_area(romArea); 415 return B_ERROR; 416 } 417 418 // Get clock info from BIOS. 419 420 uint32 romTable = BIOS16(0x48); 421 uint32 clockTable = BIOS16(romTable + 16); 422 clockType = BIOS8(clockTable); 423 params.clockNumberToProgram = BIOS8(clockTable + 6); 424 params.maxPixelClock = BIOS16(clockTable + 4) * 10; 425 params.refFreq = BIOS16(clockTable + 8); 426 params.refDivider = BIOS16(clockTable + 10); 427 428 // If Mobility chip, get the LCD panel width & height. 429 430 if (si.chipType == MACH64_MOBILITY) { 431 uint32 lcdTable = BIOS16(0x78); 432 if (BIOS32(lcdTable) == 0x544d5224) { // is LCD table signature correct? 433 uint32 lcdPanelInfo = BIOS16(lcdTable + 10); 434 si.panelX = BIOS16(lcdPanelInfo + 25); 435 si.panelY = BIOS16(lcdPanelInfo + 27); 436 TRACE("Mobility LCD Panel size: %dx%d\n", si.panelX, si.panelY); 437 } else { 438 TRACE("Mobility LCD table signature 0x%x in BIOS is incorrect\n", 439 BIOS32(lcdTable)); 440 } 441 } 442 443 delete_area(romArea); 444 445 return B_OK; 446 } 447 448 449 450 static status_t 451 Rage128_GetBiosParameters(DeviceInfo& di) 452 { 453 // Get the PLL parameters from the video BIOS, and if Mobility chips, also 454 // get the LCD panel width & height and a few other related parameters. 455 456 // In case mapping the ROM area fails or other error occurs, set default 457 // values for the parameters which will be obtained from the BIOS ROM. 458 // The default PLL parameters values probably will not work for all chips. 459 // For example, reference freq can be 29.50MHz, 28.63MHz, or 14.32MHz. 460 461 SharedInfo& si = *(di.sharedInfo); 462 R128_PLLParams& pll = si.r128PLLParams; 463 pll.reference_freq = 2950; 464 pll.reference_div = 65; 465 pll.min_pll_freq = 12500; 466 pll.max_pll_freq = 25000; 467 pll.xclk = 10300; 468 469 si.panelX = 0; 470 si.panelY = 0; 471 si.panelPowerDelay = 1; 472 473 // Map the ROM area. The Rage128 chips do not assign a ROM address in the 474 // PCI info; thus, access the ROM via the ISA legacy memory map. 475 476 uint8* romAddr; 477 area_id romArea = map_physical_memory("ATI Rage128 ROM", 478 0x000c0000, 479 R128_BIOS_SIZE, 480 B_ANY_KERNEL_ADDRESS, 481 B_READ_AREA, 482 (void**)&(romAddr)); 483 484 if (romArea < 0) { 485 TRACE("Rage128_GetBiosParameters(), ROM mapping error: %ld\n", romArea); 486 return romArea; // ROM mapping failed; return error code 487 } 488 489 // Check if we got the BIOS signature (might fail on laptops..). 490 491 if (BIOS8(0) != 0x55 || BIOS8(1) != 0xaa) { 492 TRACE("Rage128_GetBiosParameters(), ROM does not contain BIOS signature\n"); 493 delete_area(romArea); 494 return B_ERROR; 495 } 496 497 // Get the PLL values from the mapped ROM area. 498 499 uint16 biosHeader = BIOS16(0x48); 500 uint16 pllInfoBlock = BIOS16(biosHeader + 0x30); 501 502 pll.reference_freq = BIOS16(pllInfoBlock + 0x0e); 503 pll.reference_div = BIOS16(pllInfoBlock + 0x10); 504 pll.min_pll_freq = BIOS32(pllInfoBlock + 0x12); 505 pll.max_pll_freq = BIOS32(pllInfoBlock + 0x16); 506 pll.xclk = BIOS16(pllInfoBlock + 0x08); 507 508 TRACE("PLL parameters: rf=%d rd=%d min=%ld max=%ld; xclk=%d\n", pll.reference_freq, 509 pll.reference_div, pll.min_pll_freq, pll.max_pll_freq, pll.xclk); 510 511 // If Mobility chip, get the LCD panel width & height and a few other 512 // related parameters. 513 514 if (si.chipType == RAGE128_MOBILITY) { 515 // There should be direct access to the start of the FP info table, but 516 // until we find out where that offset is stored, we must search for 517 // the ATI signature string: "M3 ". 518 519 int i; 520 for (i = 4; i < R128_BIOS_SIZE - 8; i++) { 521 if (BIOS8(i) == 'M' && 522 BIOS8(i + 1) == '3' && 523 BIOS8(i + 2) == ' ' && 524 BIOS8(i + 3) == ' ' && 525 BIOS8(i + 4) == ' ' && 526 BIOS8(i + 5) == ' ' && 527 BIOS8(i + 6) == ' ' && 528 BIOS8(i + 7) == ' ') { 529 int fpHeader = i - 2; 530 531 // Assume that only one panel is attached and supported. 532 533 for (i = fpHeader + 20; i < fpHeader + 84; i += 2) { 534 if (BIOS16(i) != 0) { 535 int fpStart = BIOS16(i); 536 si.panelX = BIOS16(fpStart + 25); 537 si.panelY = BIOS16(fpStart + 27); 538 si.panelPowerDelay = BIOS8(fpStart + 56); 539 TRACE("LCD Panel size: %dx%d Panel type: 0x%x power delay: %d\n", 540 si.panelX, si.panelY, BIOS16(fpStart + 29), si.panelPowerDelay); 541 break; 542 } 543 } 544 545 break; 546 } 547 } 548 } 549 550 delete_area(romArea); 551 552 return B_OK; 553 } 554 555 556 static status_t 557 MapDevice(DeviceInfo& di) 558 { 559 SharedInfo& si = *(di.sharedInfo); 560 pci_info& pciInfo = di.pciInfo; 561 562 // Enable memory mapped IO and bus master. 563 564 SetPCI(pciInfo, PCI_command, 2, GetPCI(pciInfo, PCI_command, 2) 565 | PCI_command_io | PCI_command_memory | PCI_command_master); 566 567 // Map the video memory. 568 569 uint32 videoRamAddr = pciInfo.u.h0.base_registers[0]; 570 uint32 videoRamSize = pciInfo.u.h0.base_register_sizes[0]; 571 si.videoMemPCI = (void *)videoRamAddr; 572 char frameBufferAreaName[] = "ATI frame buffer"; 573 574 si.videoMemArea = map_physical_memory( 575 frameBufferAreaName, 576 videoRamAddr, 577 videoRamSize, 578 B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC, 579 B_READ_AREA + B_WRITE_AREA, 580 &(si.videoMemAddr)); 581 582 if (si.videoMemArea < 0) { 583 // Try to map this time without write combining. 584 si.videoMemArea = map_physical_memory( 585 frameBufferAreaName, 586 videoRamAddr, 587 videoRamSize, 588 B_ANY_KERNEL_BLOCK_ADDRESS, 589 B_READ_AREA + B_WRITE_AREA, 590 &(si.videoMemAddr)); 591 } 592 593 if (si.videoMemArea < 0) 594 return si.videoMemArea; 595 596 // Map the MMIO register area. 597 598 uint32 regsBase = pciInfo.u.h0.base_registers[2]; 599 uint32 regAreaSize = pciInfo.u.h0.base_register_sizes[2]; 600 601 // If the register area address or size is not in the PCI info, it should 602 // be at the end of the video memory. Check if it is there. 603 604 if (MACH64_FAMILY(si.chipType) && (regsBase == 0 || regAreaSize == 0)) { 605 uint32 regsOffset = 0x7ff000; // offset to regs area in video memory 606 uint32 regs = uint32(si.videoMemAddr) + regsOffset; 607 uint32 chipInfo = *((vuint32*)(regs + M64_CONFIG_CHIP_ID)); 608 609 if (si.deviceID != (chipInfo & M64_CFG_CHIP_TYPE)) { 610 // Register area not found; delete any other areas that were 611 // created. 612 delete_area(si.videoMemArea); 613 si.videoMemArea = -1; 614 TRACE("Mach64 register area not found\n"); 615 return B_ERROR; 616 } 617 618 // Adjust params for creating register area below. 619 620 regsBase = videoRamAddr + regsOffset; 621 regAreaSize = 0x1000; 622 TRACE("Register address is at end of frame buffer memory at 0x%lx\n", regsBase); 623 } 624 625 si.regsArea = map_physical_memory("ATI mmio registers", 626 regsBase, 627 regAreaSize, 628 B_ANY_KERNEL_ADDRESS, 629 0, // neither read nor write, to hide it from user space apps 630 (void**)(&(di.regs))); 631 632 // If there was an error, delete other areas. 633 if (si.regsArea < 0) { 634 delete_area(si.videoMemArea); 635 si.videoMemArea = -1; 636 } 637 638 return si.regsArea; 639 } 640 641 642 static void 643 UnmapDevice(DeviceInfo& di) 644 { 645 SharedInfo& si = *(di.sharedInfo); 646 647 if (si.regsArea >= 0) 648 delete_area(si.regsArea); 649 if (si.videoMemArea >= 0) 650 delete_area(si.videoMemArea); 651 652 si.regsArea = si.videoMemArea = -1; 653 si.videoMemAddr = NULL; 654 di.regs = NULL; 655 } 656 657 658 static int32 659 InterruptHandler(void* data) 660 { 661 int32 handled = B_UNHANDLED_INTERRUPT; 662 DeviceInfo& di = *((DeviceInfo*)data); 663 int32* flags = &(di.flags); 664 665 // Is someone already handling an interrupt for this device? 666 if (atomic_or(flags, SKD_HANDLER_INSTALLED) & SKD_HANDLER_INSTALLED) 667 return B_UNHANDLED_INTERRUPT; 668 669 if (InterruptIsVBI()) { // was interrupt a VBI? 670 ClearVBI(); // clear interrupt 671 672 handled = B_HANDLED_INTERRUPT; 673 674 // Release vertical blanking semaphore. 675 sem_id& sem = di.sharedInfo->vertBlankSem; 676 677 if (sem >= 0) { 678 int32 blocked; 679 if ((get_sem_count(sem, &blocked) == B_OK) && (blocked < 0)) { 680 release_sem_etc(sem, -blocked, B_DO_NOT_RESCHEDULE); 681 handled = B_INVOKE_SCHEDULER; 682 } 683 } 684 } 685 686 atomic_and(flags, ~SKD_HANDLER_INSTALLED); // note we're not in handler anymore 687 688 return handled; 689 } 690 691 692 static void 693 InitInterruptHandler(DeviceInfo& di) 694 { 695 SharedInfo& si = *(di.sharedInfo); 696 697 DisableVBI(); // disable & clear any pending interrupts 698 si.bInterruptAssigned = false; // indicate interrupt not assigned yet 699 700 // Create a semaphore for vertical blank management. 701 si.vertBlankSem = create_sem(0, di.name); 702 if (si.vertBlankSem < 0) 703 return; 704 705 // Change the owner of the semaphores to the calling team (usually the 706 // app_server). This is required because apps can't aquire kernel 707 // semaphores. 708 709 thread_id threadID = find_thread(NULL); 710 thread_info threadInfo; 711 status_t status = get_thread_info(threadID, &threadInfo); 712 if (status == B_OK) 713 status = set_sem_owner(si.vertBlankSem, threadInfo.team); 714 715 // If there is a valid interrupt assigned, set up interrupts. 716 717 if (status == B_OK && di.pciInfo.u.h0.interrupt_pin != 0x00 718 && di.pciInfo.u.h0.interrupt_line != 0xff) { 719 // We have a interrupt line to use. 720 721 status = install_io_interrupt_handler(di.pciInfo.u.h0.interrupt_line, 722 InterruptHandler, (void*)(&di), 0); 723 724 if (status == B_OK) 725 si.bInterruptAssigned = true; // we can use interrupt related functions 726 } 727 728 if (status != B_OK) { 729 // Interrupt does not exist; thus delete semaphore as it won't be used. 730 delete_sem(si.vertBlankSem); 731 si.vertBlankSem = -1; 732 } 733 } 734 735 736 static status_t 737 InitDevice(DeviceInfo& di) 738 { 739 // Perform initialization and mapping of the device, and return B_OK if 740 // sucessful; else, return error code. 741 742 // Get the table of VESA modes that the chip supports. Note that we will 743 // need this table only for chips that are currently connected to a laptop 744 // display or a monitor connected via a DVI interface. 745 746 size_t vesaModeTableSize = 0; 747 VesaMode* vesaModes = (VesaMode*)get_boot_item(VESA_MODES_BOOT_INFO, 748 &vesaModeTableSize); 749 750 size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7; 751 752 // Create the area for shared info with NO user-space read or write 753 // permissions, to prevent accidental damage. 754 755 di.sharedArea = create_area("ATI shared info", 756 (void**) &(di.sharedInfo), 757 B_ANY_KERNEL_ADDRESS, 758 ROUND_TO_PAGE_SIZE(sharedSize + vesaModeTableSize), 759 B_FULL_LOCK, 0); 760 if (di.sharedArea < 0) 761 return di.sharedArea; // return error code 762 763 SharedInfo& si = *(di.sharedInfo); 764 765 memset(&si, 0, sharedSize); 766 767 if (vesaModes != NULL) { 768 si.vesaModeTableOffset = sharedSize; 769 si.vesaModeCount = vesaModeTableSize / sizeof(VesaMode); 770 771 memcpy((uint8*)&si + si.vesaModeTableOffset, vesaModes, vesaModeTableSize); 772 } 773 774 pci_info& pciInfo = di.pciInfo; 775 776 si.vendorID = pciInfo.vendor_id; 777 si.deviceID = pciInfo.device_id; 778 si.revision = pciInfo.revision; 779 si.chipType = di.pChipInfo->chipType; 780 strcpy(si.chipName, di.pChipInfo->chipName); 781 782 TRACE("Chip revision: 0x%x\n", si.revision); 783 784 // 264GT has two chip versions. If version is non-zero, chip is 264GTB. 785 786 if (si.chipType == MACH64_264GT && si.revision & 0x7) 787 si.chipType = MACH64_264GTB; 788 789 // 264VT has two chip versions. If version is non-zero, chip is 264VTB. 790 791 if (si.chipType == MACH64_264VT && si.revision & 0x7) 792 si.chipType = MACH64_264VTB; 793 794 status_t status = MapDevice(di); 795 796 // If device mapped without any error, get the bios parameters from the 797 // chip's BIOS ROM. 798 799 if (status >= 0) { 800 if (MACH64_FAMILY(si.chipType)) { 801 uint8 clockType; 802 Mach64_GetBiosParameters(di, clockType); 803 804 // All chips supported by this driver should have an internal clock. 805 // If the clock is not an internal clock, the video chip is not 806 // supported. 807 808 if (clockType != M64_CLOCK_INTERNAL) { 809 TRACE("Video chip clock type %d not supported\n", clockType); 810 status = B_UNSUPPORTED; 811 } 812 } 813 else if (RAGE128_FAMILY(si.chipType)) 814 Rage128_GetBiosParameters(di); 815 } 816 817 if (status < 0) { 818 delete_area(di.sharedArea); 819 di.sharedArea = -1; 820 di.sharedInfo = NULL; 821 return status; // return error code 822 } 823 824 InitInterruptHandler(di); 825 826 TRACE("Interrupt assigned: %s\n", si.bInterruptAssigned ? "yes" : "no"); 827 return B_OK; 828 } 829 830 831 static const ChipInfo* 832 GetNextSupportedDevice(uint32& pciIndex, pci_info& pciInfo) 833 { 834 // Search the PCI devices for a device that is supported by this driver. 835 // The search starts at the device specified by argument pciIndex, and 836 // continues until a supported device is found or there are no more devices 837 // to examine. Argument pciIndex is incremented after each device is 838 // examined. 839 840 // If a supported device is found, return a pointer to the struct containing 841 // the chip info; else return NULL. 842 843 while (gPCI->get_nth_pci_info(pciIndex, &pciInfo) == B_OK) { 844 845 if (pciInfo.vendor_id == VENDOR_ID) { 846 847 // Search the table of supported devices to find a chip/device that 848 // matches device ID of the current PCI device. 849 850 const ChipInfo* pDevice = chipTable; 851 852 while (pDevice->chipID != 0) { // end of table? 853 if (pDevice->chipID == pciInfo.device_id) { 854 // Matching device/chip found. If chip is 264VT, reject it 855 // if its version is zero since the mode can not be set on 856 // that chip. 857 858 if (pDevice->chipType == MACH64_264VT 859 && (pciInfo.revision & 0x7) == 0) 860 break; 861 862 return pDevice; // matching device/chip found 863 } 864 865 pDevice++; 866 } 867 } 868 869 pciIndex++; 870 } 871 872 return NULL; // no supported device found 873 } 874 875 876 877 // #pragma mark - Kernel Interface 878 879 880 status_t 881 init_hardware(void) 882 { 883 // Return B_OK if a device supported by this driver is found; otherwise, 884 // return B_ERROR so the driver will be unloaded. 885 886 if (get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI) != B_OK) 887 return B_ERROR; // unable to access PCI bus 888 889 // Check pci devices for a device supported by this driver. 890 891 uint32 pciIndex = 0; 892 pci_info pciInfo; 893 const ChipInfo* pDevice = GetNextSupportedDevice(pciIndex, pciInfo); 894 895 TRACE("init_hardware() - %s\n", pDevice == NULL ? "no supported devices" : "device supported"); 896 897 put_module(B_PCI_MODULE_NAME); // put away the module manager 898 899 return (pDevice == NULL ? B_ERROR : B_OK); 900 } 901 902 903 status_t init_driver(void) 904 { 905 // Get handle for the pci bus. 906 907 if (get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI) != B_OK) 908 return B_ERROR; 909 910 status_t status = gLock.Init("ATI driver lock"); 911 if (status < B_OK) 912 return status; 913 914 // Get info about all the devices supported by this driver. 915 916 uint32 pciIndex = 0; 917 uint32 count = 0; 918 919 while (count < MAX_DEVICES) { 920 DeviceInfo& di = gDeviceInfo[count]; 921 922 const ChipInfo* pDevice = GetNextSupportedDevice(pciIndex, di.pciInfo); 923 if (pDevice == NULL) 924 break; // all supported devices have been obtained 925 926 // Compose device name. 927 sprintf(di.name, "graphics/" DEVICE_FORMAT, 928 di.pciInfo.vendor_id, di.pciInfo.device_id, 929 di.pciInfo.bus, di.pciInfo.device, di.pciInfo.function); 930 TRACE("init_driver() match found; name: %s\n", di.name); 931 932 gDeviceNames[count] = di.name; 933 di.openCount = 0; // mark driver as available for R/W open 934 di.sharedArea = -1; // indicate shared area not yet created 935 di.sharedInfo = NULL; 936 di.pChipInfo = pDevice; 937 count++; 938 pciIndex++; 939 } 940 941 gDeviceNames[count] = NULL; // terminate list with null pointer 942 943 TRACE("init_driver() %ld supported devices\n", count); 944 945 return B_OK; 946 } 947 948 949 void 950 uninit_driver(void) 951 { 952 // Free the driver data. 953 954 gLock.Delete(); 955 put_module(B_PCI_MODULE_NAME); // put the pci module away 956 } 957 958 959 const char** 960 publish_devices(void) 961 { 962 return (const char**)gDeviceNames; // return list of supported devices 963 } 964 965 966 device_hooks* 967 find_device(const char* name) 968 { 969 int i = 0; 970 while (gDeviceNames[i] != NULL) { 971 if (strcmp(name, gDeviceNames[i]) == 0) 972 return &gDeviceHooks; 973 i++; 974 } 975 976 return NULL; 977 } 978 979 980 981 // #pragma mark - Device Hooks 982 983 984 static status_t 985 device_open(const char* name, uint32 /*flags*/, void** cookie) 986 { 987 status_t status = B_OK; 988 989 TRACE("device_open() - name: %s\n", name); 990 991 // Find the device name in the list of devices. 992 993 int32 i = 0; 994 while (gDeviceNames[i] != NULL && (strcmp(name, gDeviceNames[i]) != 0)) 995 i++; 996 997 if (gDeviceNames[i] == NULL) 998 return B_BAD_VALUE; // device name not found in list of devices 999 1000 DeviceInfo& di = gDeviceInfo[i]; 1001 1002 gLock.Acquire(); // make sure no one else has write access to common data 1003 1004 if (di.openCount == 0) 1005 status = InitDevice(di); 1006 1007 gLock.Release(); 1008 1009 if (status == B_OK) { 1010 di.openCount++; // mark device open 1011 *cookie = &di; // send cookie to opener 1012 } 1013 1014 TRACE("device_open() returning 0x%lx, open count: %ld\n", status, di.openCount); 1015 return status; 1016 } 1017 1018 1019 static status_t 1020 device_read(void* dev, off_t pos, void* buf, size_t* len) 1021 { 1022 // Following 3 lines of code are here to eliminate "unused parameter" warnings. 1023 (void)dev; 1024 (void)pos; 1025 (void)buf; 1026 1027 *len = 0; 1028 return B_NOT_ALLOWED; 1029 } 1030 1031 1032 static status_t 1033 device_write(void* dev, off_t pos, const void* buf, size_t* len) 1034 { 1035 // Following 3 lines of code are here to eliminate "unused parameter" warnings. 1036 (void)dev; 1037 (void)pos; 1038 (void)buf; 1039 1040 *len = 0; 1041 return B_NOT_ALLOWED; 1042 } 1043 1044 1045 static status_t 1046 device_close(void* dev) 1047 { 1048 (void)dev; // avoid compiler warning for unused arg 1049 1050 return B_NO_ERROR; 1051 } 1052 1053 1054 static status_t 1055 device_free(void* dev) 1056 { 1057 DeviceInfo& di = *((DeviceInfo*)dev); 1058 SharedInfo& si = *(di.sharedInfo); 1059 pci_info& pciInfo = di.pciInfo; 1060 1061 TRACE("enter device_free()\n"); 1062 1063 gLock.Acquire(); // lock driver 1064 1065 // If opened multiple times, merely decrement the open count and exit. 1066 1067 if (di.openCount <= 1) { 1068 DisableVBI(); // disable & clear any pending interrupts 1069 1070 if (si.bInterruptAssigned) { 1071 remove_io_interrupt_handler(pciInfo.u.h0.interrupt_line, InterruptHandler, &di); 1072 } 1073 1074 // Delete the semaphores, ignoring any errors because the owning team may have died. 1075 if (si.vertBlankSem >= 0) 1076 delete_sem(si.vertBlankSem); 1077 si.vertBlankSem = -1; 1078 1079 UnmapDevice(di); // free regs and frame buffer areas 1080 1081 delete_area(di.sharedArea); 1082 di.sharedArea = -1; 1083 di.sharedInfo = NULL; 1084 } 1085 1086 if (di.openCount > 0) 1087 di.openCount--; // mark device available 1088 1089 gLock.Release(); // unlock driver 1090 1091 TRACE("exit device_free() openCount: %ld\n", di.openCount); 1092 return B_OK; 1093 } 1094 1095 1096 static status_t 1097 device_ioctl(void* dev, uint32 msg, void* buffer, size_t bufferLength) 1098 { 1099 DeviceInfo& di = *((DeviceInfo*)dev); 1100 1101 // TRACE("device_ioctl(); ioctl: %lu, buffer: 0x%08lx, bufLen: %lu\n", msg, (uint32)buffer, bufferLength); 1102 1103 switch (msg) { 1104 case B_GET_ACCELERANT_SIGNATURE: 1105 strcpy((char*)buffer, ATI_ACCELERANT_NAME); 1106 return B_OK; 1107 1108 case ATI_DEVICE_NAME: 1109 strncpy((char*)buffer, di.name, B_OS_NAME_LENGTH); 1110 ((char*)buffer)[B_OS_NAME_LENGTH -1] = '\0'; 1111 return B_OK; 1112 1113 case ATI_GET_SHARED_DATA: 1114 if (bufferLength != sizeof(area_id)) 1115 return B_BAD_DATA; 1116 1117 *((area_id*)buffer) = di.sharedArea; 1118 return B_OK; 1119 1120 case ATI_GET_EDID: 1121 { 1122 if (bufferLength != sizeof(edid1_raw)) 1123 return B_BAD_DATA; 1124 1125 edid1_raw rawEdid; 1126 status_t status = GetEdidFromBIOS(rawEdid); 1127 if (status == B_OK) 1128 user_memcpy((edid1_raw*)buffer, &rawEdid, sizeof(rawEdid)); 1129 return status; 1130 } 1131 1132 case ATI_SET_VESA_DISPLAY_MODE: 1133 if (bufferLength != sizeof(uint16)) 1134 return B_BAD_DATA; 1135 1136 return SetVesaDisplayMode(*((uint16*)buffer)); 1137 1138 case ATI_RUN_INTERRUPTS: 1139 if (bufferLength != sizeof(bool)) 1140 return B_BAD_DATA; 1141 1142 if (*((bool*)buffer)) 1143 EnableVBI(); 1144 else 1145 DisableVBI(); 1146 1147 return B_OK; 1148 } 1149 1150 return B_DEV_INVALID_IOCTL; 1151 } 1152