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