1/*
2 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of Marc Aurele La France not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission.  Marc Aurele La France makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as-is" without express or implied warranty.
13 *
14 * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO
16 * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23/*************************************************************************/
24
25/*
26 * Author:  Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
27 *
28 * This is the ATI driver for XFree86.
29 *
30 * John Donne once said "No man is an island", and I am most certainly not an
31 * exception.  Contributions, intentional or not, to this and previous versions
32 * of this driver by the following are hereby acknowledged:
33 *
34 * Thomas Roell, Per Lindqvist, Doug Evans, Rik Faith, Arthur Tateishi,
35 * Alain Hebert, Ton van Rosmalen, David Chambers, William Shubert,
36 * ATI Technologies Incorporated, Robert Wolff, David Dawes, Mark Weaver,
37 * Hans Nasten, Kevin Martin, Frederic Rienthaler, Marc Bolduc, Reuben Sumner,
38 * Benjamin T. Yang, James Fast Kane, Randall Hopper, W. Marcus Miller,
39 * Henrik Harmsen, Christian Lupien, Precision Insight Incorporated,
40 * Mark Vojkovich, Huw D M Davies, Andrew C Aitchison, Ani Joshi,
41 * Kostas Gewrgiou, Jakub Jelinek, David S. Miller, A E Lawrence,
42 * Linus Torvalds, William Blew, Ignacio Garcia Etxebarria, Patrick Chase,
43 * Vladimir Dergachev, Egbert Eich, Mike A. Harris
44 *
45 * ... and, many, many others from around the world.
46 *
47 * In addition, this work would not have been possible without the active
48 * support, both moral and otherwise, of the staff and management of Computing
49 * and Network Services at the University of Alberta, in Edmonton, Alberta,
50 * Canada.
51 *
52 * The driver is intended to support all ATI adapters since their VGA Wonder
53 * V3, including OEM counterparts.
54 */
55
56#ifdef HAVE_CONFIG_H
57#include "config.h"
58#endif
59
60#include <pciaccess.h>
61#include <xf86drm.h>
62#include "atipcirename.h"
63
64#include "ati.h"
65#include "atipciids.h"
66#include "ativersion.h"
67
68/* names duplicated from version headers */
69#define MACH64_DRIVER_NAME  "mach64"
70#define R128_DRIVER_NAME    "r128"
71#define RADEON_DRIVER_NAME  "radeon"
72#define AMDGPU_DRIVER_NAME  "amdgpu"
73
74enum
75{
76    ATI_CHIP_FAMILY_NONE = 0,
77    ATI_CHIP_FAMILY_Mach64,
78    ATI_CHIP_FAMILY_Rage128,
79    ATI_CHIP_FAMILY_Radeon
80};
81
82static int ATIChipID(const uint16_t);
83
84/* domain defines (stolen from xserver) */
85#if (defined(__alpha__) || defined(__ia64__)) && defined (linux)
86# define PCI_DOM_MASK 0x01fful
87#else
88# define PCI_DOM_MASK 0x0ffu
89#endif
90
91#define PCI_DOM_FROM_BUS(bus)  (((bus) >> 8) & (PCI_DOM_MASK))
92#define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu)
93
94static struct pci_device*
95ati_device_get_from_busid(int bus, int dev, int func)
96{
97    return pci_device_find_by_slot(PCI_DOM_FROM_BUS(bus),
98                                   PCI_BUS_NO_DOMAIN(bus),
99                                   dev,
100                                   func);
101}
102
103#ifndef XSERVER_PLATFORM_BUS
104static struct pci_device*
105ati_device_get_primary(void)
106{
107    struct pci_device *device = NULL;
108    struct pci_device_iterator *device_iter;
109
110    device_iter = pci_slot_match_iterator_create(NULL);
111
112    while ((device = pci_device_next(device_iter))) {
113        if (xf86IsPrimaryPci(device))
114            break;
115    }
116
117    pci_iterator_destroy(device_iter);
118
119    return device;
120}
121#else
122static struct pci_device *
123ati_device_get_indexed(int index)
124{
125    struct pci_device *device = NULL;
126    struct pci_device_iterator *device_iter;
127    int count = 0;
128
129    device_iter = pci_slot_match_iterator_create(NULL);
130
131    while ((device = pci_device_next(device_iter))) {
132        if (device->vendor_id == PCI_VENDOR_ATI) {
133            if (count == index)
134                return device;
135            count++;
136        }
137    }
138    return NULL;
139}
140#endif
141
142void
143ati_gdev_subdriver(pointer options)
144{
145    int      nATIGDev, nMach64GDev, nR128GDev, nRadeonGDev, nAmdgpuGDev;
146    GDevPtr *ATIGDevs;
147    Bool     load_mach64 = FALSE, load_r128 = FALSE, load_radeon = FALSE, load_amdgpu = FALSE;
148    int      i;
149
150    /* let the subdrivers configure for themselves */
151    if (xf86ServerIsOnlyDetecting())
152        return;
153
154    /* get Device sections with Driver "ati" */
155    nATIGDev = xf86MatchDevice(ATI_DRIVER_NAME, &ATIGDevs);
156    nMach64GDev = xf86MatchDevice(MACH64_DRIVER_NAME, NULL);
157    nR128GDev = xf86MatchDevice(R128_DRIVER_NAME, NULL);
158    nRadeonGDev = xf86MatchDevice(RADEON_DRIVER_NAME, NULL);
159    nAmdgpuGDev = xf86MatchDevice(AMDGPU_DRIVER_NAME, NULL);
160
161    for (i = 0; i < nATIGDev; i++) {
162        GDevPtr     ati_gdev = ATIGDevs[i];
163        pciVideoPtr device = NULL;
164        int         chip_family;
165
166        /* get pci device for the Device section */
167        if (ati_gdev->busID) {
168            int bus, dev, func;
169
170            if (!xf86ParsePciBusString(ati_gdev->busID, &bus, &dev, &func))
171                continue;
172
173            device = ati_device_get_from_busid(bus, dev, func);
174        }
175#ifdef XSERVER_PLATFORM_BUS
176        else
177            device = ati_device_get_indexed(i);
178#else
179        else {
180            device = ati_device_get_primary();
181        }
182#endif
183
184        if (!device)
185            continue;
186
187        /* check for non-ati devices and prehistoric mach32 */
188        if ((PCI_DEV_VENDOR_ID(device) != PCI_VENDOR_ATI) ||
189            (PCI_DEV_DEVICE_ID(device) == PCI_CHIP_MACH32))
190            continue;
191
192        /* replace Driver line in the Device section */
193        chip_family = ATIChipID(PCI_DEV_DEVICE_ID(device));
194
195        if (chip_family == ATI_CHIP_FAMILY_Mach64) {
196            ati_gdev->driver = MACH64_DRIVER_NAME;
197            load_mach64 = TRUE;
198        }
199
200        if (chip_family == ATI_CHIP_FAMILY_Rage128) {
201            ati_gdev->driver = R128_DRIVER_NAME;
202            load_r128 = TRUE;
203        }
204
205        if (chip_family == ATI_CHIP_FAMILY_Radeon) {
206            char *busid;
207
208            XNFasprintf(&busid, "pci:%04x:%02x:%02x.%d",
209                        device->domain, device->bus, device->dev,
210                        device->func);
211
212            if (busid) {
213                int fd = drmOpen(NULL, busid);
214
215                if (fd >= 0) {
216                    drmVersionPtr version = drmGetVersion(fd);
217
218                    if (version->version_major == 3) {
219                        ati_gdev->driver = AMDGPU_DRIVER_NAME;
220                        load_amdgpu = TRUE;
221                    }
222
223                    free(version);
224                    drmClose(fd);
225                }
226
227                free(busid);
228            }
229
230            if (strcmp(ati_gdev->driver, AMDGPU_DRIVER_NAME) != 0) {
231                ati_gdev->driver = RADEON_DRIVER_NAME;
232                load_radeon = TRUE;
233            }
234        }
235    }
236
237    free(ATIGDevs);
238
239    /* load subdrivers as primary modules and only if they do not get loaded
240     * from other device sections
241     */
242
243    if (load_mach64 && (nMach64GDev == 0))
244         xf86LoadOneModule(MACH64_DRIVER_NAME, options);
245
246    if (load_r128 && (nR128GDev == 0))
247         xf86LoadOneModule(R128_DRIVER_NAME, options);
248
249    if (load_radeon && (nRadeonGDev == 0))
250         xf86LoadOneModule(RADEON_DRIVER_NAME, options);
251
252    if (load_amdgpu && (nAmdgpuGDev == 0))
253         xf86LoadOneModule(AMDGPU_DRIVER_NAME, options);
254}
255
256/*
257 * ATIChipID --
258 *
259 * This returns the ATI_CHIP_FAMILY_* value associated with a particular ChipID.
260 */
261static int
262ATIChipID(const uint16_t ChipID)
263{
264    switch (ChipID)
265    {
266        case PCI_CHIP_MACH64GX:
267        case PCI_CHIP_MACH64CX:
268        case PCI_CHIP_MACH64CT:
269        case PCI_CHIP_MACH64ET:
270        case PCI_CHIP_MACH64VT:
271        case PCI_CHIP_MACH64GT:
272        case PCI_CHIP_MACH64VU:
273        case PCI_CHIP_MACH64GU:
274        case PCI_CHIP_MACH64LG:
275        case PCI_CHIP_MACH64VV:
276        case PCI_CHIP_MACH64GV:
277        case PCI_CHIP_MACH64GW:
278        case PCI_CHIP_MACH64GY:
279        case PCI_CHIP_MACH64GZ:
280        case PCI_CHIP_MACH64GB:
281        case PCI_CHIP_MACH64GD:
282        case PCI_CHIP_MACH64GI:
283        case PCI_CHIP_MACH64GP:
284        case PCI_CHIP_MACH64GQ:
285        case PCI_CHIP_MACH64LB:
286        case PCI_CHIP_MACH64LD:
287        case PCI_CHIP_MACH64LI:
288        case PCI_CHIP_MACH64LP:
289        case PCI_CHIP_MACH64LQ:
290        case PCI_CHIP_MACH64GL:
291        case PCI_CHIP_MACH64GM:
292        case PCI_CHIP_MACH64GN:
293        case PCI_CHIP_MACH64GO:
294        case PCI_CHIP_MACH64GR:
295        case PCI_CHIP_MACH64GS:
296        case PCI_CHIP_MACH64LM:
297        case PCI_CHIP_MACH64LN:
298        case PCI_CHIP_MACH64LR:
299        case PCI_CHIP_MACH64LS:
300            return ATI_CHIP_FAMILY_Mach64;
301
302        case PCI_CHIP_RAGE128RE:
303        case PCI_CHIP_RAGE128RF:
304        case PCI_CHIP_RAGE128RG:
305        case PCI_CHIP_RAGE128SK:
306        case PCI_CHIP_RAGE128SL:
307        case PCI_CHIP_RAGE128SM:
308        case PCI_CHIP_RAGE128SN:
309        case PCI_CHIP_RAGE128RK:
310        case PCI_CHIP_RAGE128RL:
311        case PCI_CHIP_RAGE128SE:
312        case PCI_CHIP_RAGE128SF:
313        case PCI_CHIP_RAGE128SG:
314        case PCI_CHIP_RAGE128SH:
315        case PCI_CHIP_RAGE128PA:
316        case PCI_CHIP_RAGE128PB:
317        case PCI_CHIP_RAGE128PC:
318        case PCI_CHIP_RAGE128PD:
319        case PCI_CHIP_RAGE128PE:
320        case PCI_CHIP_RAGE128PF:
321        case PCI_CHIP_RAGE128PG:
322        case PCI_CHIP_RAGE128PH:
323        case PCI_CHIP_RAGE128PI:
324        case PCI_CHIP_RAGE128PJ:
325        case PCI_CHIP_RAGE128PK:
326        case PCI_CHIP_RAGE128PL:
327        case PCI_CHIP_RAGE128PM:
328        case PCI_CHIP_RAGE128PN:
329        case PCI_CHIP_RAGE128PO:
330        case PCI_CHIP_RAGE128PP:
331        case PCI_CHIP_RAGE128PQ:
332        case PCI_CHIP_RAGE128PR:
333        case PCI_CHIP_RAGE128PS:
334        case PCI_CHIP_RAGE128PT:
335        case PCI_CHIP_RAGE128PU:
336        case PCI_CHIP_RAGE128PV:
337        case PCI_CHIP_RAGE128PW:
338        case PCI_CHIP_RAGE128PX:
339        case PCI_CHIP_RAGE128TF:
340        case PCI_CHIP_RAGE128TL:
341        case PCI_CHIP_RAGE128TR:
342        case PCI_CHIP_RAGE128TS:
343        case PCI_CHIP_RAGE128TT:
344        case PCI_CHIP_RAGE128TU:
345        case PCI_CHIP_RAGE128LE:
346        case PCI_CHIP_RAGE128LF:
347#if 0
348        case PCI_CHIP_RAGE128LK:
349        case PCI_CHIP_RAGE128LL:
350#endif
351        case PCI_CHIP_RAGE128MF:
352        case PCI_CHIP_RAGE128ML:
353            return ATI_CHIP_FAMILY_Rage128;
354
355        default:
356            return ATI_CHIP_FAMILY_Radeon;
357    }
358}
359