radeon_probe.c revision de2362d3
1de2362d3Smrg/*
2de2362d3Smrg * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
3de2362d3Smrg *                VA Linux Systems Inc., Fremont, California.
4de2362d3Smrg *
5de2362d3Smrg * All Rights Reserved.
6de2362d3Smrg *
7de2362d3Smrg * Permission is hereby granted, free of charge, to any person obtaining
8de2362d3Smrg * a copy of this software and associated documentation files (the
9de2362d3Smrg * "Software"), to deal in the Software without restriction, including
10de2362d3Smrg * without limitation on the rights to use, copy, modify, merge,
11de2362d3Smrg * publish, distribute, sublicense, and/or sell copies of the Software,
12de2362d3Smrg * and to permit persons to whom the Software is furnished to do so,
13de2362d3Smrg * subject to the following conditions:
14de2362d3Smrg *
15de2362d3Smrg * The above copyright notice and this permission notice (including the
16de2362d3Smrg * next paragraph) shall be included in all copies or substantial
17de2362d3Smrg * portions of the Software.
18de2362d3Smrg *
19de2362d3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20de2362d3Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21de2362d3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22de2362d3Smrg * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
23de2362d3Smrg * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24de2362d3Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25de2362d3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26de2362d3Smrg * DEALINGS IN THE SOFTWARE.
27de2362d3Smrg */
28de2362d3Smrg
29de2362d3Smrg#ifdef HAVE_CONFIG_H
30de2362d3Smrg#include "config.h"
31de2362d3Smrg#endif
32de2362d3Smrg
33de2362d3Smrg#include <string.h>
34de2362d3Smrg#include <stdlib.h>
35de2362d3Smrg
36de2362d3Smrg/*
37de2362d3Smrg * Authors:
38de2362d3Smrg *   Kevin E. Martin <martin@xfree86.org>
39de2362d3Smrg *   Rickard E. Faith <faith@valinux.com>
40de2362d3Smrg * KMS support - Dave Airlie <airlied@redhat.com>
41de2362d3Smrg */
42de2362d3Smrg
43de2362d3Smrg#include "radeon_probe.h"
44de2362d3Smrg#include "radeon_version.h"
45de2362d3Smrg#include "atipciids.h"
46de2362d3Smrg#include "atipcirename.h"
47de2362d3Smrg
48de2362d3Smrg#include "xf86.h"
49de2362d3Smrg
50de2362d3Smrg#include "xf86drmMode.h"
51de2362d3Smrg#include "dri.h"
52de2362d3Smrg
53de2362d3Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
54de2362d3Smrg#include <xf86_OSproc.h>
55de2362d3Smrg#endif
56de2362d3Smrg
57de2362d3Smrg#ifdef XSERVER_PLATFORM_BUS
58de2362d3Smrg#include <xf86platformBus.h>
59de2362d3Smrg#endif
60de2362d3Smrg
61de2362d3Smrg#include "radeon_chipset_gen.h"
62de2362d3Smrg
63de2362d3Smrg#include "radeon_pci_chipset_gen.h"
64de2362d3Smrg
65de2362d3Smrg#include "radeon_pci_device_match_gen.h"
66de2362d3Smrg
67de2362d3Smrg_X_EXPORT int gRADEONEntityIndex = -1;
68de2362d3Smrg
69de2362d3Smrg/* Return the options for supported chipset 'n'; NULL otherwise */
70de2362d3Smrgstatic const OptionInfoRec *
71de2362d3SmrgRADEONAvailableOptions(int chipid, int busid)
72de2362d3Smrg{
73de2362d3Smrg    return RADEONOptionsWeak();
74de2362d3Smrg}
75de2362d3Smrg
76de2362d3Smrg/* Return the string name for supported chipset 'n'; NULL otherwise. */
77de2362d3Smrgstatic void
78de2362d3SmrgRADEONIdentify(int flags)
79de2362d3Smrg{
80de2362d3Smrg    xf86PrintChipsets(RADEON_NAME,
81de2362d3Smrg		      "Driver for ATI Radeon chipsets",
82de2362d3Smrg		      RADEONChipsets);
83de2362d3Smrg}
84de2362d3Smrg
85de2362d3Smrg
86de2362d3Smrgstatic Bool radeon_kernel_mode_enabled(ScrnInfoPtr pScrn, struct pci_device *pci_dev)
87de2362d3Smrg{
88de2362d3Smrg    char *busIdString;
89de2362d3Smrg    int ret;
90de2362d3Smrg
91de2362d3Smrg    if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
92de2362d3Smrg      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
93de2362d3Smrg		   "[KMS] No DRICreatePCIBusID symbol, no kernel modesetting.\n");
94de2362d3Smrg	return FALSE;
95de2362d3Smrg    }
96de2362d3Smrg
97de2362d3Smrg    busIdString = DRICreatePCIBusID(pci_dev);
98de2362d3Smrg    ret = drmCheckModesettingSupported(busIdString);
99de2362d3Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
100de2362d3Smrg    if (ret) {
101de2362d3Smrg      if (xf86LoadKernelModule("radeonkms"))
102de2362d3Smrg        ret = drmCheckModesettingSupported(busIdString);
103de2362d3Smrg    }
104de2362d3Smrg#endif
105de2362d3Smrg    free(busIdString);
106de2362d3Smrg    if (ret) {
107de2362d3Smrg      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
108de2362d3Smrg		   "[KMS] drm report modesetting isn't supported.\n");
109de2362d3Smrg	return FALSE;
110de2362d3Smrg    }
111de2362d3Smrg
112de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
113de2362d3Smrg		   "[KMS] Kernel modesetting enabled.\n");
114de2362d3Smrg    return TRUE;
115de2362d3Smrg}
116de2362d3Smrg
117de2362d3Smrgstatic Bool
118de2362d3Smrgradeon_get_scrninfo(int entity_num, void *pci_dev)
119de2362d3Smrg{
120de2362d3Smrg    ScrnInfoPtr   pScrn = NULL;
121de2362d3Smrg    EntityInfoPtr pEnt;
122de2362d3Smrg
123de2362d3Smrg    pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, RADEONPciChipsets,
124de2362d3Smrg                                NULL,
125de2362d3Smrg                                NULL, NULL, NULL, NULL);
126de2362d3Smrg
127de2362d3Smrg    if (!pScrn)
128de2362d3Smrg        return FALSE;
129de2362d3Smrg
130de2362d3Smrg    if (pci_dev) {
131de2362d3Smrg      if (!radeon_kernel_mode_enabled(pScrn, pci_dev)) {
132de2362d3Smrg	return FALSE;
133de2362d3Smrg      }
134de2362d3Smrg    }
135de2362d3Smrg
136de2362d3Smrg    pScrn->driverVersion = RADEON_VERSION_CURRENT;
137de2362d3Smrg    pScrn->driverName    = RADEON_DRIVER_NAME;
138de2362d3Smrg    pScrn->name          = RADEON_NAME;
139de2362d3Smrg    pScrn->Probe         = NULL;
140de2362d3Smrg
141de2362d3Smrg    pScrn->PreInit       = RADEONPreInit_KMS;
142de2362d3Smrg    pScrn->ScreenInit    = RADEONScreenInit_KMS;
143de2362d3Smrg    pScrn->SwitchMode    = RADEONSwitchMode_KMS;
144de2362d3Smrg    pScrn->AdjustFrame   = RADEONAdjustFrame_KMS;
145de2362d3Smrg    pScrn->EnterVT       = RADEONEnterVT_KMS;
146de2362d3Smrg    pScrn->LeaveVT       = RADEONLeaveVT_KMS;
147de2362d3Smrg    pScrn->FreeScreen    = RADEONFreeScreen_KMS;
148de2362d3Smrg    pScrn->ValidMode     = RADEONValidMode;
149de2362d3Smrg
150de2362d3Smrg    pEnt = xf86GetEntityInfo(entity_num);
151de2362d3Smrg
152de2362d3Smrg    /* Create a RADEONEntity for all chips, even with old single head
153de2362d3Smrg     * Radeon, need to use pRADEONEnt for new monitor detection routines.
154de2362d3Smrg     */
155de2362d3Smrg    {
156de2362d3Smrg        DevUnion    *pPriv;
157de2362d3Smrg        RADEONEntPtr pRADEONEnt;
158de2362d3Smrg
159de2362d3Smrg        xf86SetEntitySharable(entity_num);
160de2362d3Smrg
161de2362d3Smrg        if (gRADEONEntityIndex == -1)
162de2362d3Smrg            gRADEONEntityIndex = xf86AllocateEntityPrivateIndex();
163de2362d3Smrg
164de2362d3Smrg        pPriv = xf86GetEntityPrivate(pEnt->index,
165de2362d3Smrg                                     gRADEONEntityIndex);
166de2362d3Smrg
167de2362d3Smrg	xf86SetEntityInstanceForScreen(pScrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1);
168de2362d3Smrg
169de2362d3Smrg        if (!pPriv->ptr) {
170de2362d3Smrg            pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1);
171de2362d3Smrg            pRADEONEnt = pPriv->ptr;
172de2362d3Smrg            pRADEONEnt->HasSecondary = FALSE;
173de2362d3Smrg        } else {
174de2362d3Smrg            pRADEONEnt = pPriv->ptr;
175de2362d3Smrg            pRADEONEnt->HasSecondary = TRUE;
176de2362d3Smrg        }
177de2362d3Smrg    }
178de2362d3Smrg
179de2362d3Smrg    free(pEnt);
180de2362d3Smrg
181de2362d3Smrg    return TRUE;
182de2362d3Smrg}
183de2362d3Smrg
184de2362d3Smrgstatic Bool
185de2362d3Smrgradeon_pci_probe(
186de2362d3Smrg    DriverPtr          pDriver,
187de2362d3Smrg    int                entity_num,
188de2362d3Smrg    struct pci_device *device,
189de2362d3Smrg    intptr_t           match_data
190de2362d3Smrg)
191de2362d3Smrg{
192de2362d3Smrg    return radeon_get_scrninfo(entity_num, (void *)device);
193de2362d3Smrg}
194de2362d3Smrg
195de2362d3Smrgstatic Bool
196de2362d3SmrgRADEONDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data)
197de2362d3Smrg{
198de2362d3Smrg    xorgHWFlags *flag;
199de2362d3Smrg
200de2362d3Smrg    switch (op) {
201de2362d3Smrg	case GET_REQUIRED_HW_INTERFACES:
202de2362d3Smrg	    flag = (CARD32 *)data;
203de2362d3Smrg	    (*flag) = 0;
204de2362d3Smrg	    return TRUE;
205de2362d3Smrg#if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,15,99,0,0)
206de2362d3Smrg	case SUPPORTS_SERVER_FDS:
207de2362d3Smrg	    return TRUE;
208de2362d3Smrg#endif
209de2362d3Smrg	default:
210de2362d3Smrg	    return FALSE;
211de2362d3Smrg    }
212de2362d3Smrg}
213de2362d3Smrg
214de2362d3Smrg#ifdef XSERVER_PLATFORM_BUS
215de2362d3Smrgstatic Bool
216de2362d3Smrgradeon_platform_probe(DriverPtr pDriver,
217de2362d3Smrg		      int entity_num, int flags,
218de2362d3Smrg		      struct xf86_platform_device *dev,
219de2362d3Smrg		      intptr_t match_data)
220de2362d3Smrg{
221de2362d3Smrg    ScrnInfoPtr pScrn;
222de2362d3Smrg    int scr_flags = 0;
223de2362d3Smrg    EntityInfoPtr pEnt;
224de2362d3Smrg
225de2362d3Smrg    if (!dev->pdev)
226de2362d3Smrg	return FALSE;
227de2362d3Smrg
228de2362d3Smrg    if (flags & PLATFORM_PROBE_GPU_SCREEN)
229de2362d3Smrg	scr_flags = XF86_ALLOCATE_GPU_SCREEN;
230de2362d3Smrg
231de2362d3Smrg    pScrn = xf86AllocateScreen(pDriver, scr_flags);
232de2362d3Smrg    if (xf86IsEntitySharable(entity_num))
233de2362d3Smrg	xf86SetEntityShared(entity_num);
234de2362d3Smrg    xf86AddEntityToScreen(pScrn, entity_num);
235de2362d3Smrg
236de2362d3Smrg    if (!radeon_kernel_mode_enabled(pScrn, dev->pdev))
237de2362d3Smrg	return FALSE;
238de2362d3Smrg
239de2362d3Smrg    pScrn->driverVersion = RADEON_VERSION_CURRENT;
240de2362d3Smrg    pScrn->driverName    = RADEON_DRIVER_NAME;
241de2362d3Smrg    pScrn->name          = RADEON_NAME;
242de2362d3Smrg    pScrn->Probe         = NULL;
243de2362d3Smrg    pScrn->PreInit       = RADEONPreInit_KMS;
244de2362d3Smrg    pScrn->ScreenInit    = RADEONScreenInit_KMS;
245de2362d3Smrg    pScrn->SwitchMode    = RADEONSwitchMode_KMS;
246de2362d3Smrg    pScrn->AdjustFrame   = RADEONAdjustFrame_KMS;
247de2362d3Smrg    pScrn->EnterVT       = RADEONEnterVT_KMS;
248de2362d3Smrg    pScrn->LeaveVT       = RADEONLeaveVT_KMS;
249de2362d3Smrg    pScrn->FreeScreen    = RADEONFreeScreen_KMS;
250de2362d3Smrg    pScrn->ValidMode     = RADEONValidMode;
251de2362d3Smrg
252de2362d3Smrg    pEnt = xf86GetEntityInfo(entity_num);
253de2362d3Smrg
254de2362d3Smrg    /* Create a RADEONEntity for all chips, even with old single head
255de2362d3Smrg     * Radeon, need to use pRADEONEnt for new monitor detection routines.
256de2362d3Smrg     */
257de2362d3Smrg    {
258de2362d3Smrg        DevUnion    *pPriv;
259de2362d3Smrg        RADEONEntPtr pRADEONEnt;
260de2362d3Smrg
261de2362d3Smrg        xf86SetEntitySharable(entity_num);
262de2362d3Smrg
263de2362d3Smrg        if (gRADEONEntityIndex == -1)
264de2362d3Smrg            gRADEONEntityIndex = xf86AllocateEntityPrivateIndex();
265de2362d3Smrg
266de2362d3Smrg        pPriv = xf86GetEntityPrivate(pEnt->index,
267de2362d3Smrg                                     gRADEONEntityIndex);
268de2362d3Smrg
269de2362d3Smrg	xf86SetEntityInstanceForScreen(pScrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1);
270de2362d3Smrg
271de2362d3Smrg        if (!pPriv->ptr) {
272de2362d3Smrg            pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1);
273de2362d3Smrg            pRADEONEnt = pPriv->ptr;
274de2362d3Smrg            pRADEONEnt->HasSecondary = FALSE;
275de2362d3Smrg        } else {
276de2362d3Smrg            pRADEONEnt = pPriv->ptr;
277de2362d3Smrg            pRADEONEnt->HasSecondary = TRUE;
278de2362d3Smrg        }
279de2362d3Smrg        pRADEONEnt->platform_dev = dev;
280de2362d3Smrg    }
281de2362d3Smrg
282de2362d3Smrg    free(pEnt);
283de2362d3Smrg
284de2362d3Smrg    return TRUE;
285de2362d3Smrg}
286de2362d3Smrg#endif
287de2362d3Smrg
288de2362d3Smrg_X_EXPORT DriverRec RADEON =
289de2362d3Smrg{
290de2362d3Smrg    RADEON_VERSION_CURRENT,
291de2362d3Smrg    RADEON_DRIVER_NAME,
292de2362d3Smrg    RADEONIdentify,
293de2362d3Smrg    NULL,
294de2362d3Smrg    RADEONAvailableOptions,
295de2362d3Smrg    NULL,
296de2362d3Smrg    0,
297de2362d3Smrg    RADEONDriverFunc,
298de2362d3Smrg    radeon_device_match,
299de2362d3Smrg    radeon_pci_probe,
300de2362d3Smrg#ifdef XSERVER_PLATFORM_BUS
301de2362d3Smrg    radeon_platform_probe
302de2362d3Smrg#endif
303de2362d3Smrg};
304