ati.c revision 209ff23f
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 60209ff23fSmrg#ifdef XSERVER_LIBPCIACCESS 61209ff23fSmrg#include <pciaccess.h> 62209ff23fSmrg#endif 63209ff23fSmrg#include "atipcirename.h" 64209ff23fSmrg 65209ff23fSmrg#include "ati.h" 66209ff23fSmrg#include "ativersion.h" 67209ff23fSmrg 68209ff23fSmrg/* names duplicated from version headers */ 69209ff23fSmrg#define MACH64_DRIVER_NAME "mach64" 70209ff23fSmrg#define R128_DRIVER_NAME "r128" 71209ff23fSmrg#define RADEON_DRIVER_NAME "radeon" 72209ff23fSmrg 73209ff23fSmrgenum 74209ff23fSmrg{ 75209ff23fSmrg ATI_CHIP_FAMILY_NONE = 0, 76209ff23fSmrg ATI_CHIP_FAMILY_Mach64, 77209ff23fSmrg ATI_CHIP_FAMILY_Rage128, 78209ff23fSmrg ATI_CHIP_FAMILY_Radeon 79209ff23fSmrg}; 80209ff23fSmrg 81209ff23fSmrgstatic int ATIChipID(const uint16_t); 82209ff23fSmrg 83209ff23fSmrg#ifdef XSERVER_LIBPCIACCESS 84209ff23fSmrg 85209ff23fSmrg/* domain defines (stolen from xserver) */ 86209ff23fSmrg#if (defined(__alpha__) || defined(__ia64__)) && defined (linux) 87209ff23fSmrg# define PCI_DOM_MASK 0x01fful 88209ff23fSmrg#else 89209ff23fSmrg# define PCI_DOM_MASK 0x0ffu 90209ff23fSmrg#endif 91209ff23fSmrg 92209ff23fSmrg#define PCI_DOM_FROM_BUS(bus) (((bus) >> 8) & (PCI_DOM_MASK)) 93209ff23fSmrg#define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu) 94209ff23fSmrg 95209ff23fSmrgstatic struct pci_device* 96209ff23fSmrgati_device_get_from_busid(int bus, int dev, int func) 97209ff23fSmrg{ 98209ff23fSmrg return pci_device_find_by_slot(PCI_DOM_FROM_BUS(bus), 99209ff23fSmrg PCI_BUS_NO_DOMAIN(bus), 100209ff23fSmrg dev, 101209ff23fSmrg func); 102209ff23fSmrg} 103209ff23fSmrg 104209ff23fSmrgstatic struct pci_device* 105209ff23fSmrgati_device_get_primary(void) 106209ff23fSmrg{ 107209ff23fSmrg struct pci_device *device = NULL; 108209ff23fSmrg struct pci_device_iterator *device_iter; 109209ff23fSmrg 110209ff23fSmrg device_iter = pci_slot_match_iterator_create(NULL); 111209ff23fSmrg 112209ff23fSmrg while ((device = pci_device_next(device_iter)) != NULL) { 113209ff23fSmrg if (xf86IsPrimaryPci(device)) 114209ff23fSmrg break; 115209ff23fSmrg } 116209ff23fSmrg 117209ff23fSmrg pci_iterator_destroy(device_iter); 118209ff23fSmrg 119209ff23fSmrg return device; 120209ff23fSmrg} 121209ff23fSmrg 122209ff23fSmrg#else /* XSERVER_LIBPCIACCESS */ 123209ff23fSmrg 124209ff23fSmrgstatic pciVideoPtr 125209ff23fSmrgati_device_get_from_busid(int bus, int dev, int func) 126209ff23fSmrg{ 127209ff23fSmrg pciVideoPtr pVideo = NULL; 128209ff23fSmrg pciVideoPtr *xf86PciVideoInfo; 129209ff23fSmrg 130209ff23fSmrg xf86PciVideoInfo = xf86GetPciVideoInfo(); 131209ff23fSmrg 132209ff23fSmrg if (xf86PciVideoInfo == NULL) 133209ff23fSmrg return NULL; 134209ff23fSmrg 135209ff23fSmrg while ((pVideo = *xf86PciVideoInfo++) != NULL) 136209ff23fSmrg { 137209ff23fSmrg if ((pVideo->bus == bus) && (pVideo->device == dev) && 138209ff23fSmrg (pVideo->func == func)) 139209ff23fSmrg break; 140209ff23fSmrg } 141209ff23fSmrg 142209ff23fSmrg return pVideo; 143209ff23fSmrg} 144209ff23fSmrg 145209ff23fSmrgstatic pciVideoPtr 146209ff23fSmrgati_device_get_primary() 147209ff23fSmrg{ 148209ff23fSmrg pciVideoPtr pVideo = NULL; 149209ff23fSmrg pciVideoPtr *xf86PciVideoInfo; 150209ff23fSmrg 151209ff23fSmrg xf86PciVideoInfo = xf86GetPciVideoInfo(); 152209ff23fSmrg 153209ff23fSmrg if (xf86PciVideoInfo == NULL) 154209ff23fSmrg return NULL; 155209ff23fSmrg 156209ff23fSmrg while ((pVideo = *xf86PciVideoInfo++) != NULL) 157209ff23fSmrg { 158209ff23fSmrg if (xf86IsPrimaryPci(pVideo)) 159209ff23fSmrg break; 160209ff23fSmrg } 161209ff23fSmrg 162209ff23fSmrg return pVideo; 163209ff23fSmrg} 164209ff23fSmrg 165209ff23fSmrg#endif /* XSERVER_LIBPCIACCESS */ 166209ff23fSmrg 167209ff23fSmrgvoid 168209ff23fSmrgati_gdev_subdriver(pointer options) 169209ff23fSmrg{ 170209ff23fSmrg int nATIGDev, nMach64GDev, nR128GDev, nRadeonGDev; 171209ff23fSmrg GDevPtr *ATIGDevs; 172209ff23fSmrg Bool load_mach64 = FALSE, load_r128 = FALSE, load_radeon = FALSE; 173209ff23fSmrg int i; 174209ff23fSmrg 175209ff23fSmrg /* let the subdrivers configure for themselves */ 176209ff23fSmrg if (xf86ServerIsOnlyDetecting()) 177209ff23fSmrg return; 178209ff23fSmrg 179209ff23fSmrg /* get Device sections with Driver "ati" */ 180209ff23fSmrg nATIGDev = xf86MatchDevice(ATI_DRIVER_NAME, &ATIGDevs); 181209ff23fSmrg nMach64GDev = xf86MatchDevice(MACH64_DRIVER_NAME, NULL); 182209ff23fSmrg nR128GDev = xf86MatchDevice(R128_DRIVER_NAME, NULL); 183209ff23fSmrg nRadeonGDev = xf86MatchDevice(RADEON_DRIVER_NAME, NULL); 184209ff23fSmrg 185209ff23fSmrg for (i = 0; i < nATIGDev; i++) { 186209ff23fSmrg GDevPtr ati_gdev = ATIGDevs[i]; 187209ff23fSmrg pciVideoPtr device = NULL; 188209ff23fSmrg int chip_family; 189209ff23fSmrg 190209ff23fSmrg /* get pci device for the Device section */ 191209ff23fSmrg if (ati_gdev->busID) { 192209ff23fSmrg int bus, dev, func; 193209ff23fSmrg 194209ff23fSmrg if (!xf86ParsePciBusString(ati_gdev->busID, &bus, &dev, &func)) 195209ff23fSmrg continue; 196209ff23fSmrg 197209ff23fSmrg device = ati_device_get_from_busid(bus, dev, func); 198209ff23fSmrg } 199209ff23fSmrg else { 200209ff23fSmrg device = ati_device_get_primary(); 201209ff23fSmrg } 202209ff23fSmrg 203209ff23fSmrg if (!device) 204209ff23fSmrg continue; 205209ff23fSmrg 206209ff23fSmrg /* check for non-ati devices and prehistoric mach32 */ 207209ff23fSmrg if ((PCI_DEV_VENDOR_ID(device) != PCI_VENDOR_ATI) || 208209ff23fSmrg (PCI_DEV_DEVICE_ID(device) == PCI_CHIP_MACH32)) 209209ff23fSmrg continue; 210209ff23fSmrg 211209ff23fSmrg /* replace Driver line in the Device section */ 212209ff23fSmrg chip_family = ATIChipID(PCI_DEV_DEVICE_ID(device)); 213209ff23fSmrg 214209ff23fSmrg if (chip_family == ATI_CHIP_FAMILY_Mach64) { 215209ff23fSmrg ati_gdev->driver = MACH64_DRIVER_NAME; 216209ff23fSmrg load_mach64 = TRUE; 217209ff23fSmrg } 218209ff23fSmrg 219209ff23fSmrg if (chip_family == ATI_CHIP_FAMILY_Rage128) { 220209ff23fSmrg ati_gdev->driver = R128_DRIVER_NAME; 221209ff23fSmrg load_r128 = TRUE; 222209ff23fSmrg } 223209ff23fSmrg 224209ff23fSmrg if (chip_family == ATI_CHIP_FAMILY_Radeon) { 225209ff23fSmrg ati_gdev->driver = RADEON_DRIVER_NAME; 226209ff23fSmrg load_radeon = TRUE; 227209ff23fSmrg } 228209ff23fSmrg } 229209ff23fSmrg 230209ff23fSmrg xfree(ATIGDevs); 231209ff23fSmrg 232209ff23fSmrg /* load subdrivers as primary modules and only if they do not get loaded 233209ff23fSmrg * from other device sections 234209ff23fSmrg */ 235209ff23fSmrg 236209ff23fSmrg if (load_mach64 && (nMach64GDev == 0)) 237209ff23fSmrg xf86LoadOneModule(MACH64_DRIVER_NAME, options); 238209ff23fSmrg 239209ff23fSmrg if (load_r128 && (nR128GDev == 0)) 240209ff23fSmrg xf86LoadOneModule(R128_DRIVER_NAME, options); 241209ff23fSmrg 242209ff23fSmrg if (load_radeon && (nRadeonGDev == 0)) 243209ff23fSmrg xf86LoadOneModule(RADEON_DRIVER_NAME, options); 244209ff23fSmrg} 245209ff23fSmrg 246209ff23fSmrg/* 247209ff23fSmrg * ATIChipID -- 248209ff23fSmrg * 249209ff23fSmrg * This returns the ATI_CHIP_FAMILY_* value associated with a particular ChipID. 250209ff23fSmrg */ 251209ff23fSmrgstatic int 252209ff23fSmrgATIChipID(const uint16_t ChipID) 253209ff23fSmrg{ 254209ff23fSmrg switch (ChipID) 255209ff23fSmrg { 256209ff23fSmrg case PCI_CHIP_MACH64GX: 257209ff23fSmrg case PCI_CHIP_MACH64CX: 258209ff23fSmrg case PCI_CHIP_MACH64CT: 259209ff23fSmrg case PCI_CHIP_MACH64ET: 260209ff23fSmrg case PCI_CHIP_MACH64VT: 261209ff23fSmrg case PCI_CHIP_MACH64GT: 262209ff23fSmrg case PCI_CHIP_MACH64VU: 263209ff23fSmrg case PCI_CHIP_MACH64GU: 264209ff23fSmrg case PCI_CHIP_MACH64LG: 265209ff23fSmrg case PCI_CHIP_MACH64VV: 266209ff23fSmrg case PCI_CHIP_MACH64GV: 267209ff23fSmrg case PCI_CHIP_MACH64GW: 268209ff23fSmrg case PCI_CHIP_MACH64GY: 269209ff23fSmrg case PCI_CHIP_MACH64GZ: 270209ff23fSmrg case PCI_CHIP_MACH64GB: 271209ff23fSmrg case PCI_CHIP_MACH64GD: 272209ff23fSmrg case PCI_CHIP_MACH64GI: 273209ff23fSmrg case PCI_CHIP_MACH64GP: 274209ff23fSmrg case PCI_CHIP_MACH64GQ: 275209ff23fSmrg case PCI_CHIP_MACH64LB: 276209ff23fSmrg case PCI_CHIP_MACH64LD: 277209ff23fSmrg case PCI_CHIP_MACH64LI: 278209ff23fSmrg case PCI_CHIP_MACH64LP: 279209ff23fSmrg case PCI_CHIP_MACH64LQ: 280209ff23fSmrg case PCI_CHIP_MACH64GL: 281209ff23fSmrg case PCI_CHIP_MACH64GM: 282209ff23fSmrg case PCI_CHIP_MACH64GN: 283209ff23fSmrg case PCI_CHIP_MACH64GO: 284209ff23fSmrg case PCI_CHIP_MACH64GR: 285209ff23fSmrg case PCI_CHIP_MACH64GS: 286209ff23fSmrg case PCI_CHIP_MACH64LM: 287209ff23fSmrg case PCI_CHIP_MACH64LN: 288209ff23fSmrg case PCI_CHIP_MACH64LR: 289209ff23fSmrg case PCI_CHIP_MACH64LS: 290209ff23fSmrg return ATI_CHIP_FAMILY_Mach64; 291209ff23fSmrg 292209ff23fSmrg case PCI_CHIP_RAGE128RE: 293209ff23fSmrg case PCI_CHIP_RAGE128RF: 294209ff23fSmrg case PCI_CHIP_RAGE128RG: 295209ff23fSmrg case PCI_CHIP_RAGE128SK: 296209ff23fSmrg case PCI_CHIP_RAGE128SL: 297209ff23fSmrg case PCI_CHIP_RAGE128SM: 298209ff23fSmrg case PCI_CHIP_RAGE128SN: 299209ff23fSmrg case PCI_CHIP_RAGE128RK: 300209ff23fSmrg case PCI_CHIP_RAGE128RL: 301209ff23fSmrg case PCI_CHIP_RAGE128SE: 302209ff23fSmrg case PCI_CHIP_RAGE128SF: 303209ff23fSmrg case PCI_CHIP_RAGE128SG: 304209ff23fSmrg case PCI_CHIP_RAGE128SH: 305209ff23fSmrg case PCI_CHIP_RAGE128PA: 306209ff23fSmrg case PCI_CHIP_RAGE128PB: 307209ff23fSmrg case PCI_CHIP_RAGE128PC: 308209ff23fSmrg case PCI_CHIP_RAGE128PD: 309209ff23fSmrg case PCI_CHIP_RAGE128PE: 310209ff23fSmrg case PCI_CHIP_RAGE128PF: 311209ff23fSmrg case PCI_CHIP_RAGE128PG: 312209ff23fSmrg case PCI_CHIP_RAGE128PH: 313209ff23fSmrg case PCI_CHIP_RAGE128PI: 314209ff23fSmrg case PCI_CHIP_RAGE128PJ: 315209ff23fSmrg case PCI_CHIP_RAGE128PK: 316209ff23fSmrg case PCI_CHIP_RAGE128PL: 317209ff23fSmrg case PCI_CHIP_RAGE128PM: 318209ff23fSmrg case PCI_CHIP_RAGE128PN: 319209ff23fSmrg case PCI_CHIP_RAGE128PO: 320209ff23fSmrg case PCI_CHIP_RAGE128PP: 321209ff23fSmrg case PCI_CHIP_RAGE128PQ: 322209ff23fSmrg case PCI_CHIP_RAGE128PR: 323209ff23fSmrg case PCI_CHIP_RAGE128PS: 324209ff23fSmrg case PCI_CHIP_RAGE128PT: 325209ff23fSmrg case PCI_CHIP_RAGE128PU: 326209ff23fSmrg case PCI_CHIP_RAGE128PV: 327209ff23fSmrg case PCI_CHIP_RAGE128PW: 328209ff23fSmrg case PCI_CHIP_RAGE128PX: 329209ff23fSmrg case PCI_CHIP_RAGE128TF: 330209ff23fSmrg case PCI_CHIP_RAGE128TL: 331209ff23fSmrg case PCI_CHIP_RAGE128TR: 332209ff23fSmrg case PCI_CHIP_RAGE128TS: 333209ff23fSmrg case PCI_CHIP_RAGE128TT: 334209ff23fSmrg case PCI_CHIP_RAGE128TU: 335209ff23fSmrg case PCI_CHIP_RAGE128LE: 336209ff23fSmrg case PCI_CHIP_RAGE128LF: 337209ff23fSmrg#if 0 338209ff23fSmrg case PCI_CHIP_RAGE128LK: 339209ff23fSmrg case PCI_CHIP_RAGE128LL: 340209ff23fSmrg#endif 341209ff23fSmrg case PCI_CHIP_RAGE128MF: 342209ff23fSmrg case PCI_CHIP_RAGE128ML: 343209ff23fSmrg return ATI_CHIP_FAMILY_Rage128; 344209ff23fSmrg 345209ff23fSmrg default: 346209ff23fSmrg return ATI_CHIP_FAMILY_Radeon; 347209ff23fSmrg } 348209ff23fSmrg} 349