1209ff23fSmrg/* 2209ff23fSmrg * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org 3209ff23fSmrg * 4209ff23fSmrg * Permission to use, copy, modify, distribute, and sell this software and its 5209ff23fSmrg * documentation for any purpose is hereby granted without fee, provided that 6209ff23fSmrg * the above copyright notice appear in all copies and that both that copyright 7209ff23fSmrg * notice and this permission notice appear in supporting documentation, and 8209ff23fSmrg * that the name of Marc Aurele La France not be used in advertising or 9209ff23fSmrg * publicity pertaining to distribution of the software without specific, 10209ff23fSmrg * written prior permission. Marc Aurele La France makes no representations 11209ff23fSmrg * about the suitability of this software for any purpose. It is provided 12209ff23fSmrg * "as-is" without express or implied warranty. 13209ff23fSmrg * 14209ff23fSmrg * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15209ff23fSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 16209ff23fSmrg * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17209ff23fSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18209ff23fSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19209ff23fSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20209ff23fSmrg * PERFORMANCE OF THIS SOFTWARE. 21209ff23fSmrg */ 22209ff23fSmrg 23209ff23fSmrg/*************************************************************************/ 24209ff23fSmrg 25209ff23fSmrg/* 26209ff23fSmrg * Author: Marc Aurele La France (TSI @ UQV), tsi@xfree86.org 27209ff23fSmrg * 28209ff23fSmrg * This is the ATI driver for XFree86. 29209ff23fSmrg * 30209ff23fSmrg * John Donne once said "No man is an island", and I am most certainly not an 31209ff23fSmrg * exception. Contributions, intentional or not, to this and previous versions 32209ff23fSmrg * of this driver by the following are hereby acknowledged: 33209ff23fSmrg * 34209ff23fSmrg * Thomas Roell, Per Lindqvist, Doug Evans, Rik Faith, Arthur Tateishi, 35209ff23fSmrg * Alain Hebert, Ton van Rosmalen, David Chambers, William Shubert, 36209ff23fSmrg * ATI Technologies Incorporated, Robert Wolff, David Dawes, Mark Weaver, 37209ff23fSmrg * Hans Nasten, Kevin Martin, Frederic Rienthaler, Marc Bolduc, Reuben Sumner, 38209ff23fSmrg * Benjamin T. Yang, James Fast Kane, Randall Hopper, W. Marcus Miller, 39209ff23fSmrg * Henrik Harmsen, Christian Lupien, Precision Insight Incorporated, 40209ff23fSmrg * Mark Vojkovich, Huw D M Davies, Andrew C Aitchison, Ani Joshi, 41209ff23fSmrg * Kostas Gewrgiou, Jakub Jelinek, David S. Miller, A E Lawrence, 42209ff23fSmrg * Linus Torvalds, William Blew, Ignacio Garcia Etxebarria, Patrick Chase, 43209ff23fSmrg * Vladimir Dergachev, Egbert Eich, Mike A. Harris 44209ff23fSmrg * 45209ff23fSmrg * ... and, many, many others from around the world. 46209ff23fSmrg * 47209ff23fSmrg * In addition, this work would not have been possible without the active 48209ff23fSmrg * support, both moral and otherwise, of the staff and management of Computing 49209ff23fSmrg * and Network Services at the University of Alberta, in Edmonton, Alberta, 50209ff23fSmrg * Canada. 51209ff23fSmrg * 52209ff23fSmrg * The driver is intended to support all ATI adapters since their VGA Wonder 53209ff23fSmrg * V3, including OEM counterparts. 54209ff23fSmrg */ 55209ff23fSmrg 56209ff23fSmrg#ifdef HAVE_CONFIG_H 57209ff23fSmrg#include "config.h" 58209ff23fSmrg#endif 59209ff23fSmrg 6043df4709Smrg#ifdef XSERVER_LIBPCIACCESS 61209ff23fSmrg#include <pciaccess.h> 6243df4709Smrg#endif 63209ff23fSmrg#include "atipcirename.h" 64209ff23fSmrg 65209ff23fSmrg#include "ati.h" 6640732134Srjs#include "atipciids.h" 67209ff23fSmrg#include "ativersion.h" 68209ff23fSmrg 69209ff23fSmrg/* names duplicated from version headers */ 70209ff23fSmrg#define MACH64_DRIVER_NAME "mach64" 71209ff23fSmrg#define R128_DRIVER_NAME "r128" 72209ff23fSmrg#define RADEON_DRIVER_NAME "radeon" 73209ff23fSmrg 74209ff23fSmrgenum 75209ff23fSmrg{ 76209ff23fSmrg ATI_CHIP_FAMILY_NONE = 0, 77209ff23fSmrg ATI_CHIP_FAMILY_Mach64, 78209ff23fSmrg ATI_CHIP_FAMILY_Rage128, 79209ff23fSmrg ATI_CHIP_FAMILY_Radeon 80209ff23fSmrg}; 81209ff23fSmrg 82209ff23fSmrgstatic int ATIChipID(const uint16_t); 83209ff23fSmrg 8443df4709Smrg#ifdef XSERVER_LIBPCIACCESS 8543df4709Smrg 86209ff23fSmrg/* domain defines (stolen from xserver) */ 87209ff23fSmrg#if (defined(__alpha__) || defined(__ia64__)) && defined (linux) 88209ff23fSmrg# define PCI_DOM_MASK 0x01fful 89209ff23fSmrg#else 90209ff23fSmrg# define PCI_DOM_MASK 0x0ffu 91209ff23fSmrg#endif 92209ff23fSmrg 93209ff23fSmrg#define PCI_DOM_FROM_BUS(bus) (((bus) >> 8) & (PCI_DOM_MASK)) 94209ff23fSmrg#define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu) 95209ff23fSmrg 96209ff23fSmrgstatic struct pci_device* 97209ff23fSmrgati_device_get_from_busid(int bus, int dev, int func) 98209ff23fSmrg{ 99209ff23fSmrg return pci_device_find_by_slot(PCI_DOM_FROM_BUS(bus), 100209ff23fSmrg PCI_BUS_NO_DOMAIN(bus), 101209ff23fSmrg dev, 102209ff23fSmrg func); 103209ff23fSmrg} 104209ff23fSmrg 105209ff23fSmrgstatic struct pci_device* 106209ff23fSmrgati_device_get_primary(void) 107209ff23fSmrg{ 108209ff23fSmrg struct pci_device *device = NULL; 109209ff23fSmrg struct pci_device_iterator *device_iter; 110209ff23fSmrg 111209ff23fSmrg device_iter = pci_slot_match_iterator_create(NULL); 112209ff23fSmrg 113209ff23fSmrg while ((device = pci_device_next(device_iter)) != NULL) { 114209ff23fSmrg if (xf86IsPrimaryPci(device)) 115209ff23fSmrg break; 116209ff23fSmrg } 117209ff23fSmrg 118209ff23fSmrg pci_iterator_destroy(device_iter); 119209ff23fSmrg 120209ff23fSmrg return device; 121209ff23fSmrg} 12243df4709Smrg 12343df4709Smrg#else /* XSERVER_LIBPCIACCESS */ 12443df4709Smrg 12543df4709Smrgstatic pciVideoPtr 12643df4709Smrgati_device_get_from_busid(int bus, int dev, int func) 127209ff23fSmrg{ 12843df4709Smrg pciVideoPtr pVideo = NULL; 12943df4709Smrg pciVideoPtr *xf86PciVideoInfo; 130209ff23fSmrg 13143df4709Smrg xf86PciVideoInfo = xf86GetPciVideoInfo(); 132209ff23fSmrg 13343df4709Smrg if (xf86PciVideoInfo == NULL) 13443df4709Smrg return NULL; 13543df4709Smrg 13643df4709Smrg while ((pVideo = *xf86PciVideoInfo++) != NULL) 13743df4709Smrg { 13843df4709Smrg if ((pVideo->bus == bus) && (pVideo->device == dev) && 13943df4709Smrg (pVideo->func == func)) 14043df4709Smrg break; 141209ff23fSmrg } 14243df4709Smrg 14343df4709Smrg return pVideo; 144209ff23fSmrg} 14543df4709Smrg 14643df4709Smrgstatic pciVideoPtr 14743df4709Smrgati_device_get_primary() 14843df4709Smrg{ 14943df4709Smrg pciVideoPtr pVideo = NULL; 15043df4709Smrg pciVideoPtr *xf86PciVideoInfo; 15143df4709Smrg 15243df4709Smrg xf86PciVideoInfo = xf86GetPciVideoInfo(); 15343df4709Smrg 15443df4709Smrg if (xf86PciVideoInfo == NULL) 15543df4709Smrg return NULL; 15643df4709Smrg 15743df4709Smrg while ((pVideo = *xf86PciVideoInfo++) != NULL) 15843df4709Smrg { 15943df4709Smrg if (xf86IsPrimaryPci(pVideo)) 16043df4709Smrg break; 16143df4709Smrg } 16243df4709Smrg 16343df4709Smrg return pVideo; 16443df4709Smrg} 16543df4709Smrg 16643df4709Smrg#endif /* XSERVER_LIBPCIACCESS */ 167209ff23fSmrg 168209ff23fSmrgvoid 169209ff23fSmrgati_gdev_subdriver(pointer options) 170209ff23fSmrg{ 171209ff23fSmrg int nATIGDev, nMach64GDev, nR128GDev, nRadeonGDev; 172209ff23fSmrg GDevPtr *ATIGDevs; 173209ff23fSmrg Bool load_mach64 = FALSE, load_r128 = FALSE, load_radeon = FALSE; 174209ff23fSmrg int i; 175209ff23fSmrg 176209ff23fSmrg /* let the subdrivers configure for themselves */ 177209ff23fSmrg if (xf86ServerIsOnlyDetecting()) 178209ff23fSmrg return; 179209ff23fSmrg 180209ff23fSmrg /* get Device sections with Driver "ati" */ 181209ff23fSmrg nATIGDev = xf86MatchDevice(ATI_DRIVER_NAME, &ATIGDevs); 182209ff23fSmrg nMach64GDev = xf86MatchDevice(MACH64_DRIVER_NAME, NULL); 183209ff23fSmrg nR128GDev = xf86MatchDevice(R128_DRIVER_NAME, NULL); 184209ff23fSmrg nRadeonGDev = xf86MatchDevice(RADEON_DRIVER_NAME, NULL); 185209ff23fSmrg 186209ff23fSmrg for (i = 0; i < nATIGDev; i++) { 187209ff23fSmrg GDevPtr ati_gdev = ATIGDevs[i]; 188209ff23fSmrg pciVideoPtr device = NULL; 189209ff23fSmrg int chip_family; 190209ff23fSmrg 191209ff23fSmrg /* get pci device for the Device section */ 192209ff23fSmrg if (ati_gdev->busID) { 193209ff23fSmrg int bus, dev, func; 194209ff23fSmrg 195209ff23fSmrg if (!xf86ParsePciBusString(ati_gdev->busID, &bus, &dev, &func)) 196209ff23fSmrg continue; 197209ff23fSmrg 198209ff23fSmrg device = ati_device_get_from_busid(bus, dev, func); 199209ff23fSmrg } 200209ff23fSmrg else { 201209ff23fSmrg device = ati_device_get_primary(); 202209ff23fSmrg } 203209ff23fSmrg 204209ff23fSmrg if (!device) 205209ff23fSmrg continue; 206209ff23fSmrg 207209ff23fSmrg /* check for non-ati devices and prehistoric mach32 */ 208209ff23fSmrg if ((PCI_DEV_VENDOR_ID(device) != PCI_VENDOR_ATI) || 209209ff23fSmrg (PCI_DEV_DEVICE_ID(device) == PCI_CHIP_MACH32)) 210209ff23fSmrg continue; 211209ff23fSmrg 212209ff23fSmrg /* replace Driver line in the Device section */ 213209ff23fSmrg chip_family = ATIChipID(PCI_DEV_DEVICE_ID(device)); 214209ff23fSmrg 215209ff23fSmrg if (chip_family == ATI_CHIP_FAMILY_Mach64) { 216209ff23fSmrg ati_gdev->driver = MACH64_DRIVER_NAME; 217209ff23fSmrg load_mach64 = TRUE; 218209ff23fSmrg } 219209ff23fSmrg 220209ff23fSmrg if (chip_family == ATI_CHIP_FAMILY_Rage128) { 221209ff23fSmrg ati_gdev->driver = R128_DRIVER_NAME; 222209ff23fSmrg load_r128 = TRUE; 223209ff23fSmrg } 224209ff23fSmrg 225209ff23fSmrg if (chip_family == ATI_CHIP_FAMILY_Radeon) { 226209ff23fSmrg ati_gdev->driver = RADEON_DRIVER_NAME; 227209ff23fSmrg load_radeon = TRUE; 228209ff23fSmrg } 229209ff23fSmrg } 230209ff23fSmrg 2310974d292Smrg free(ATIGDevs); 232209ff23fSmrg 233209ff23fSmrg /* load subdrivers as primary modules and only if they do not get loaded 234209ff23fSmrg * from other device sections 235209ff23fSmrg */ 236209ff23fSmrg 237209ff23fSmrg if (load_mach64 && (nMach64GDev == 0)) 238209ff23fSmrg xf86LoadOneModule(MACH64_DRIVER_NAME, options); 239209ff23fSmrg 240209ff23fSmrg if (load_r128 && (nR128GDev == 0)) 241209ff23fSmrg xf86LoadOneModule(R128_DRIVER_NAME, options); 242209ff23fSmrg 243209ff23fSmrg if (load_radeon && (nRadeonGDev == 0)) 244209ff23fSmrg xf86LoadOneModule(RADEON_DRIVER_NAME, options); 245209ff23fSmrg} 246209ff23fSmrg 247209ff23fSmrg/* 248209ff23fSmrg * ATIChipID -- 249209ff23fSmrg * 250209ff23fSmrg * This returns the ATI_CHIP_FAMILY_* value associated with a particular ChipID. 251209ff23fSmrg */ 252209ff23fSmrgstatic int 253209ff23fSmrgATIChipID(const uint16_t ChipID) 254209ff23fSmrg{ 255209ff23fSmrg switch (ChipID) 256209ff23fSmrg { 257209ff23fSmrg case PCI_CHIP_MACH64GX: 258209ff23fSmrg case PCI_CHIP_MACH64CX: 259209ff23fSmrg case PCI_CHIP_MACH64CT: 260209ff23fSmrg case PCI_CHIP_MACH64ET: 261209ff23fSmrg case PCI_CHIP_MACH64VT: 262209ff23fSmrg case PCI_CHIP_MACH64GT: 263209ff23fSmrg case PCI_CHIP_MACH64VU: 264209ff23fSmrg case PCI_CHIP_MACH64GU: 265209ff23fSmrg case PCI_CHIP_MACH64LG: 266209ff23fSmrg case PCI_CHIP_MACH64VV: 267209ff23fSmrg case PCI_CHIP_MACH64GV: 268209ff23fSmrg case PCI_CHIP_MACH64GW: 269209ff23fSmrg case PCI_CHIP_MACH64GY: 270209ff23fSmrg case PCI_CHIP_MACH64GZ: 271209ff23fSmrg case PCI_CHIP_MACH64GB: 272209ff23fSmrg case PCI_CHIP_MACH64GD: 273209ff23fSmrg case PCI_CHIP_MACH64GI: 274209ff23fSmrg case PCI_CHIP_MACH64GP: 275209ff23fSmrg case PCI_CHIP_MACH64GQ: 276209ff23fSmrg case PCI_CHIP_MACH64LB: 277209ff23fSmrg case PCI_CHIP_MACH64LD: 278209ff23fSmrg case PCI_CHIP_MACH64LI: 279209ff23fSmrg case PCI_CHIP_MACH64LP: 280209ff23fSmrg case PCI_CHIP_MACH64LQ: 281209ff23fSmrg case PCI_CHIP_MACH64GL: 282209ff23fSmrg case PCI_CHIP_MACH64GM: 283209ff23fSmrg case PCI_CHIP_MACH64GN: 284209ff23fSmrg case PCI_CHIP_MACH64GO: 285209ff23fSmrg case PCI_CHIP_MACH64GR: 286209ff23fSmrg case PCI_CHIP_MACH64GS: 287209ff23fSmrg case PCI_CHIP_MACH64LM: 288209ff23fSmrg case PCI_CHIP_MACH64LN: 289209ff23fSmrg case PCI_CHIP_MACH64LR: 290209ff23fSmrg case PCI_CHIP_MACH64LS: 291209ff23fSmrg return ATI_CHIP_FAMILY_Mach64; 292209ff23fSmrg 293209ff23fSmrg case PCI_CHIP_RAGE128RE: 294209ff23fSmrg case PCI_CHIP_RAGE128RF: 295209ff23fSmrg case PCI_CHIP_RAGE128RG: 296209ff23fSmrg case PCI_CHIP_RAGE128SK: 297209ff23fSmrg case PCI_CHIP_RAGE128SL: 298209ff23fSmrg case PCI_CHIP_RAGE128SM: 299209ff23fSmrg case PCI_CHIP_RAGE128SN: 300209ff23fSmrg case PCI_CHIP_RAGE128RK: 301209ff23fSmrg case PCI_CHIP_RAGE128RL: 302209ff23fSmrg case PCI_CHIP_RAGE128SE: 303209ff23fSmrg case PCI_CHIP_RAGE128SF: 304209ff23fSmrg case PCI_CHIP_RAGE128SG: 305209ff23fSmrg case PCI_CHIP_RAGE128SH: 306209ff23fSmrg case PCI_CHIP_RAGE128PA: 307209ff23fSmrg case PCI_CHIP_RAGE128PB: 308209ff23fSmrg case PCI_CHIP_RAGE128PC: 309209ff23fSmrg case PCI_CHIP_RAGE128PD: 310209ff23fSmrg case PCI_CHIP_RAGE128PE: 311209ff23fSmrg case PCI_CHIP_RAGE128PF: 312209ff23fSmrg case PCI_CHIP_RAGE128PG: 313209ff23fSmrg case PCI_CHIP_RAGE128PH: 314209ff23fSmrg case PCI_CHIP_RAGE128PI: 315209ff23fSmrg case PCI_CHIP_RAGE128PJ: 316209ff23fSmrg case PCI_CHIP_RAGE128PK: 317209ff23fSmrg case PCI_CHIP_RAGE128PL: 318209ff23fSmrg case PCI_CHIP_RAGE128PM: 319209ff23fSmrg case PCI_CHIP_RAGE128PN: 320209ff23fSmrg case PCI_CHIP_RAGE128PO: 321209ff23fSmrg case PCI_CHIP_RAGE128PP: 322209ff23fSmrg case PCI_CHIP_RAGE128PQ: 323209ff23fSmrg case PCI_CHIP_RAGE128PR: 324209ff23fSmrg case PCI_CHIP_RAGE128PS: 325209ff23fSmrg case PCI_CHIP_RAGE128PT: 326209ff23fSmrg case PCI_CHIP_RAGE128PU: 327209ff23fSmrg case PCI_CHIP_RAGE128PV: 328209ff23fSmrg case PCI_CHIP_RAGE128PW: 329209ff23fSmrg case PCI_CHIP_RAGE128PX: 330209ff23fSmrg case PCI_CHIP_RAGE128TF: 331209ff23fSmrg case PCI_CHIP_RAGE128TL: 332209ff23fSmrg case PCI_CHIP_RAGE128TR: 333209ff23fSmrg case PCI_CHIP_RAGE128TS: 334209ff23fSmrg case PCI_CHIP_RAGE128TT: 335209ff23fSmrg case PCI_CHIP_RAGE128TU: 336209ff23fSmrg case PCI_CHIP_RAGE128LE: 337209ff23fSmrg case PCI_CHIP_RAGE128LF: 338209ff23fSmrg#if 0 339209ff23fSmrg case PCI_CHIP_RAGE128LK: 340209ff23fSmrg case PCI_CHIP_RAGE128LL: 341209ff23fSmrg#endif 342209ff23fSmrg case PCI_CHIP_RAGE128MF: 343209ff23fSmrg case PCI_CHIP_RAGE128ML: 344209ff23fSmrg return ATI_CHIP_FAMILY_Rage128; 345209ff23fSmrg 346209ff23fSmrg default: 347209ff23fSmrg return ATI_CHIP_FAMILY_Radeon; 348209ff23fSmrg } 349209ff23fSmrg} 350