radeon_probe.c revision 8bf5c682
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"
518bf5c682Smrg
528bf5c682Smrg#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,19,99,1,0)
538bf5c682Smrg#include <xf86Pci.h>
548bf5c682Smrg#else
55de2362d3Smrg#include "dri.h"
568bf5c682Smrg#endif
5718781e08Smrg
5818781e08Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
5918781e08Smrg#include <xf86_OSproc.h>
6018781e08Smrg#endif
6118781e08Smrg
6218781e08Smrg#ifdef XSERVER_PLATFORM_BUS
6318781e08Smrg#include <xf86platformBus.h>
64de2362d3Smrg#endif
65de2362d3Smrg
66de2362d3Smrg#include "radeon_chipset_gen.h"
67de2362d3Smrg
68de2362d3Smrg#include "radeon_pci_chipset_gen.h"
69de2362d3Smrg
70de2362d3Smrg#include "radeon_pci_device_match_gen.h"
71de2362d3Smrg
72de2362d3Smrg_X_EXPORT int gRADEONEntityIndex = -1;
73de2362d3Smrg
74de2362d3Smrg/* Return the options for supported chipset 'n'; NULL otherwise */
75de2362d3Smrgstatic const OptionInfoRec *
76de2362d3SmrgRADEONAvailableOptions(int chipid, int busid)
77de2362d3Smrg{
78de2362d3Smrg    return RADEONOptionsWeak();
79de2362d3Smrg}
80de2362d3Smrg
81de2362d3Smrg/* Return the string name for supported chipset 'n'; NULL otherwise. */
82de2362d3Smrgstatic void
83de2362d3SmrgRADEONIdentify(int flags)
84de2362d3Smrg{
85de2362d3Smrg    xf86PrintChipsets(RADEON_NAME,
8618781e08Smrg		      "Driver for ATI/AMD Radeon chipsets",
8718781e08Smrg		      RADEONUniqueChipsets);
88de2362d3Smrg}
89de2362d3Smrg
90de2362d3Smrg
91de2362d3Smrgstatic Bool radeon_kernel_mode_enabled(ScrnInfoPtr pScrn, struct pci_device *pci_dev)
92de2362d3Smrg{
93de2362d3Smrg    char *busIdString;
94de2362d3Smrg    int ret;
95de2362d3Smrg
96de2362d3Smrg    if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
97de2362d3Smrg      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
98de2362d3Smrg		   "[KMS] No DRICreatePCIBusID symbol, no kernel modesetting.\n");
99de2362d3Smrg	return FALSE;
100de2362d3Smrg    }
101de2362d3Smrg
102de2362d3Smrg    busIdString = DRICreatePCIBusID(pci_dev);
103de2362d3Smrg    ret = drmCheckModesettingSupported(busIdString);
10418781e08Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
10518781e08Smrg    if (ret) {
10618781e08Smrg      if (xf86LoadKernelModule("radeonkms"))
10718781e08Smrg        ret = drmCheckModesettingSupported(busIdString);
10818781e08Smrg    }
10918781e08Smrg#endif
110de2362d3Smrg    free(busIdString);
111de2362d3Smrg    if (ret) {
112de2362d3Smrg      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
113de2362d3Smrg		   "[KMS] drm report modesetting isn't supported.\n");
114de2362d3Smrg	return FALSE;
115de2362d3Smrg    }
116de2362d3Smrg
117de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
118de2362d3Smrg		   "[KMS] Kernel modesetting enabled.\n");
119de2362d3Smrg    return TRUE;
120de2362d3Smrg}
121de2362d3Smrg
122de2362d3Smrgstatic Bool
123de2362d3Smrgradeon_get_scrninfo(int entity_num, void *pci_dev)
124de2362d3Smrg{
125de2362d3Smrg    ScrnInfoPtr   pScrn = NULL;
126de2362d3Smrg    EntityInfoPtr pEnt;
127de2362d3Smrg
128de2362d3Smrg    pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, RADEONPciChipsets,
129de2362d3Smrg                                NULL,
130de2362d3Smrg                                NULL, NULL, NULL, NULL);
131de2362d3Smrg
132de2362d3Smrg    if (!pScrn)
133de2362d3Smrg        return FALSE;
134de2362d3Smrg
13518781e08Smrg    if (!radeon_kernel_mode_enabled(pScrn, pci_dev))
13618781e08Smrg	return FALSE;
137de2362d3Smrg
138de2362d3Smrg    pScrn->driverVersion = RADEON_VERSION_CURRENT;
139de2362d3Smrg    pScrn->driverName    = RADEON_DRIVER_NAME;
140de2362d3Smrg    pScrn->name          = RADEON_NAME;
141de2362d3Smrg    pScrn->Probe         = NULL;
142de2362d3Smrg
14318781e08Smrg    pScrn->PreInit       = RADEONPreInit_KMS;
14418781e08Smrg    pScrn->ScreenInit    = RADEONScreenInit_KMS;
14518781e08Smrg    pScrn->SwitchMode    = RADEONSwitchMode_KMS;
14618781e08Smrg    pScrn->AdjustFrame   = RADEONAdjustFrame_KMS;
14718781e08Smrg    pScrn->EnterVT       = RADEONEnterVT_KMS;
14818781e08Smrg    pScrn->LeaveVT       = RADEONLeaveVT_KMS;
14918781e08Smrg    pScrn->FreeScreen    = RADEONFreeScreen_KMS;
15018781e08Smrg    pScrn->ValidMode     = RADEONValidMode;
151de2362d3Smrg
152de2362d3Smrg    pEnt = xf86GetEntityInfo(entity_num);
153de2362d3Smrg
154de2362d3Smrg    /* Create a RADEONEntity for all chips, even with old single head
155de2362d3Smrg     * Radeon, need to use pRADEONEnt for new monitor detection routines.
156de2362d3Smrg     */
157de2362d3Smrg    {
158de2362d3Smrg        DevUnion    *pPriv;
159de2362d3Smrg
160de2362d3Smrg        xf86SetEntitySharable(entity_num);
161de2362d3Smrg
162de2362d3Smrg        if (gRADEONEntityIndex == -1)
163de2362d3Smrg            gRADEONEntityIndex = xf86AllocateEntityPrivateIndex();
164de2362d3Smrg
165de2362d3Smrg        pPriv = xf86GetEntityPrivate(pEnt->index,
166de2362d3Smrg                                     gRADEONEntityIndex);
167de2362d3Smrg
168de2362d3Smrg	xf86SetEntityInstanceForScreen(pScrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1);
169de2362d3Smrg
17018781e08Smrg        if (!pPriv->ptr)
171de2362d3Smrg            pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1);
172de2362d3Smrg    }
173de2362d3Smrg
174de2362d3Smrg    free(pEnt);
175de2362d3Smrg
176de2362d3Smrg    return TRUE;
177de2362d3Smrg}
178de2362d3Smrg
179de2362d3Smrgstatic Bool
180de2362d3Smrgradeon_pci_probe(
181de2362d3Smrg    DriverPtr          pDriver,
182de2362d3Smrg    int                entity_num,
183de2362d3Smrg    struct pci_device *device,
184de2362d3Smrg    intptr_t           match_data
185de2362d3Smrg)
186de2362d3Smrg{
187de2362d3Smrg    return radeon_get_scrninfo(entity_num, (void *)device);
188de2362d3Smrg}
189de2362d3Smrg
19018781e08Smrgstatic Bool
19118781e08SmrgRADEONDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data)
19218781e08Smrg{
19318781e08Smrg    xorgHWFlags *flag;
19418781e08Smrg
19518781e08Smrg    switch (op) {
19618781e08Smrg	case GET_REQUIRED_HW_INTERFACES:
19718781e08Smrg	    flag = (CARD32 *)data;
19818781e08Smrg	    (*flag) = 0;
19918781e08Smrg	    return TRUE;
20018781e08Smrg#if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,15,99,0,0)
20118781e08Smrg	case SUPPORTS_SERVER_FDS:
20218781e08Smrg	    return TRUE;
20318781e08Smrg#endif
20418781e08Smrg	default:
20518781e08Smrg	    return FALSE;
20618781e08Smrg    }
20718781e08Smrg}
20818781e08Smrg
20918781e08Smrg#ifdef XSERVER_PLATFORM_BUS
21018781e08Smrgstatic Bool
21118781e08Smrgradeon_platform_probe(DriverPtr pDriver,
21218781e08Smrg		      int entity_num, int flags,
21318781e08Smrg		      struct xf86_platform_device *dev,
21418781e08Smrg		      intptr_t match_data)
21518781e08Smrg{
21618781e08Smrg    ScrnInfoPtr pScrn;
21718781e08Smrg    int scr_flags = 0;
21818781e08Smrg    EntityInfoPtr pEnt;
21918781e08Smrg
22018781e08Smrg    if (!dev->pdev)
22118781e08Smrg	return FALSE;
22218781e08Smrg
22318781e08Smrg    if (flags & PLATFORM_PROBE_GPU_SCREEN)
22418781e08Smrg	scr_flags = XF86_ALLOCATE_GPU_SCREEN;
22518781e08Smrg
22618781e08Smrg    pScrn = xf86AllocateScreen(pDriver, scr_flags);
22718781e08Smrg    if (xf86IsEntitySharable(entity_num))
22818781e08Smrg	xf86SetEntityShared(entity_num);
22918781e08Smrg    xf86AddEntityToScreen(pScrn, entity_num);
23018781e08Smrg
23118781e08Smrg    if (!radeon_kernel_mode_enabled(pScrn, dev->pdev))
23218781e08Smrg	return FALSE;
23318781e08Smrg
23418781e08Smrg    pScrn->driverVersion = RADEON_VERSION_CURRENT;
23518781e08Smrg    pScrn->driverName    = RADEON_DRIVER_NAME;
23618781e08Smrg    pScrn->name          = RADEON_NAME;
23718781e08Smrg    pScrn->Probe         = NULL;
23818781e08Smrg    pScrn->PreInit       = RADEONPreInit_KMS;
23918781e08Smrg    pScrn->ScreenInit    = RADEONScreenInit_KMS;
24018781e08Smrg    pScrn->SwitchMode    = RADEONSwitchMode_KMS;
24118781e08Smrg    pScrn->AdjustFrame   = RADEONAdjustFrame_KMS;
24218781e08Smrg    pScrn->EnterVT       = RADEONEnterVT_KMS;
24318781e08Smrg    pScrn->LeaveVT       = RADEONLeaveVT_KMS;
24418781e08Smrg    pScrn->FreeScreen    = RADEONFreeScreen_KMS;
24518781e08Smrg    pScrn->ValidMode     = RADEONValidMode;
24618781e08Smrg
24718781e08Smrg    pEnt = xf86GetEntityInfo(entity_num);
24818781e08Smrg
24918781e08Smrg    /* Create a RADEONEntity for all chips, even with old single head
25018781e08Smrg     * Radeon, need to use pRADEONEnt for new monitor detection routines.
25118781e08Smrg     */
25218781e08Smrg    {
25318781e08Smrg        DevUnion    *pPriv;
25418781e08Smrg        RADEONEntPtr pRADEONEnt;
25518781e08Smrg
25618781e08Smrg        xf86SetEntitySharable(entity_num);
25718781e08Smrg
25818781e08Smrg        if (gRADEONEntityIndex == -1)
25918781e08Smrg            gRADEONEntityIndex = xf86AllocateEntityPrivateIndex();
26018781e08Smrg
26118781e08Smrg        pPriv = xf86GetEntityPrivate(pEnt->index,
26218781e08Smrg                                     gRADEONEntityIndex);
26318781e08Smrg
26418781e08Smrg	xf86SetEntityInstanceForScreen(pScrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1);
26518781e08Smrg
26618781e08Smrg        if (!pPriv->ptr) {
26718781e08Smrg            pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1);
26818781e08Smrg            pRADEONEnt = pPriv->ptr;
26918781e08Smrg        } else {
27018781e08Smrg            pRADEONEnt = pPriv->ptr;
27118781e08Smrg        }
27218781e08Smrg        pRADEONEnt->platform_dev = dev;
27318781e08Smrg    }
27418781e08Smrg
27518781e08Smrg    free(pEnt);
27618781e08Smrg
27718781e08Smrg    return TRUE;
27818781e08Smrg}
27918781e08Smrg#endif
280de2362d3Smrg
281de2362d3Smrg_X_EXPORT DriverRec RADEON =
282de2362d3Smrg{
283de2362d3Smrg    RADEON_VERSION_CURRENT,
284de2362d3Smrg    RADEON_DRIVER_NAME,
285de2362d3Smrg    RADEONIdentify,
286de2362d3Smrg    NULL,
287de2362d3Smrg    RADEONAvailableOptions,
288de2362d3Smrg    NULL,
289de2362d3Smrg    0,
29018781e08Smrg    RADEONDriverFunc,
291de2362d3Smrg    radeon_device_match,
29218781e08Smrg    radeon_pci_probe,
29318781e08Smrg#ifdef XSERVER_PLATFORM_BUS
29418781e08Smrg    radeon_platform_probe
295de2362d3Smrg#endif
296de2362d3Smrg};
297