radeon_probe.c revision 18781e08
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" 5218781e08Smrg 5318781e08Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 5418781e08Smrg#include <xf86_OSproc.h> 5518781e08Smrg#endif 5618781e08Smrg 5718781e08Smrg#ifdef XSERVER_PLATFORM_BUS 5818781e08Smrg#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, 8118781e08Smrg "Driver for ATI/AMD Radeon chipsets", 8218781e08Smrg RADEONUniqueChipsets); 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); 9918781e08Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 10018781e08Smrg if (ret) { 10118781e08Smrg if (xf86LoadKernelModule("radeonkms")) 10218781e08Smrg ret = drmCheckModesettingSupported(busIdString); 10318781e08Smrg } 10418781e08Smrg#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 13018781e08Smrg if (!radeon_kernel_mode_enabled(pScrn, pci_dev)) 13118781e08Smrg return FALSE; 132de2362d3Smrg 133de2362d3Smrg pScrn->driverVersion = RADEON_VERSION_CURRENT; 134de2362d3Smrg pScrn->driverName = RADEON_DRIVER_NAME; 135de2362d3Smrg pScrn->name = RADEON_NAME; 136de2362d3Smrg pScrn->Probe = NULL; 137de2362d3Smrg 13818781e08Smrg pScrn->PreInit = RADEONPreInit_KMS; 13918781e08Smrg pScrn->ScreenInit = RADEONScreenInit_KMS; 14018781e08Smrg pScrn->SwitchMode = RADEONSwitchMode_KMS; 14118781e08Smrg pScrn->AdjustFrame = RADEONAdjustFrame_KMS; 14218781e08Smrg pScrn->EnterVT = RADEONEnterVT_KMS; 14318781e08Smrg pScrn->LeaveVT = RADEONLeaveVT_KMS; 14418781e08Smrg pScrn->FreeScreen = RADEONFreeScreen_KMS; 14518781e08Smrg pScrn->ValidMode = RADEONValidMode; 146de2362d3Smrg 147de2362d3Smrg pEnt = xf86GetEntityInfo(entity_num); 148de2362d3Smrg 149de2362d3Smrg /* Create a RADEONEntity for all chips, even with old single head 150de2362d3Smrg * Radeon, need to use pRADEONEnt for new monitor detection routines. 151de2362d3Smrg */ 152de2362d3Smrg { 153de2362d3Smrg DevUnion *pPriv; 154de2362d3Smrg 155de2362d3Smrg xf86SetEntitySharable(entity_num); 156de2362d3Smrg 157de2362d3Smrg if (gRADEONEntityIndex == -1) 158de2362d3Smrg gRADEONEntityIndex = xf86AllocateEntityPrivateIndex(); 159de2362d3Smrg 160de2362d3Smrg pPriv = xf86GetEntityPrivate(pEnt->index, 161de2362d3Smrg gRADEONEntityIndex); 162de2362d3Smrg 163de2362d3Smrg xf86SetEntityInstanceForScreen(pScrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1); 164de2362d3Smrg 16518781e08Smrg if (!pPriv->ptr) 166de2362d3Smrg pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1); 167de2362d3Smrg } 168de2362d3Smrg 169de2362d3Smrg free(pEnt); 170de2362d3Smrg 171de2362d3Smrg return TRUE; 172de2362d3Smrg} 173de2362d3Smrg 174de2362d3Smrgstatic Bool 175de2362d3Smrgradeon_pci_probe( 176de2362d3Smrg DriverPtr pDriver, 177de2362d3Smrg int entity_num, 178de2362d3Smrg struct pci_device *device, 179de2362d3Smrg intptr_t match_data 180de2362d3Smrg) 181de2362d3Smrg{ 182de2362d3Smrg return radeon_get_scrninfo(entity_num, (void *)device); 183de2362d3Smrg} 184de2362d3Smrg 18518781e08Smrgstatic Bool 18618781e08SmrgRADEONDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data) 18718781e08Smrg{ 18818781e08Smrg xorgHWFlags *flag; 18918781e08Smrg 19018781e08Smrg switch (op) { 19118781e08Smrg case GET_REQUIRED_HW_INTERFACES: 19218781e08Smrg flag = (CARD32 *)data; 19318781e08Smrg (*flag) = 0; 19418781e08Smrg return TRUE; 19518781e08Smrg#if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,15,99,0,0) 19618781e08Smrg case SUPPORTS_SERVER_FDS: 19718781e08Smrg return TRUE; 19818781e08Smrg#endif 19918781e08Smrg default: 20018781e08Smrg return FALSE; 20118781e08Smrg } 20218781e08Smrg} 20318781e08Smrg 20418781e08Smrg#ifdef XSERVER_PLATFORM_BUS 20518781e08Smrgstatic Bool 20618781e08Smrgradeon_platform_probe(DriverPtr pDriver, 20718781e08Smrg int entity_num, int flags, 20818781e08Smrg struct xf86_platform_device *dev, 20918781e08Smrg intptr_t match_data) 21018781e08Smrg{ 21118781e08Smrg ScrnInfoPtr pScrn; 21218781e08Smrg int scr_flags = 0; 21318781e08Smrg EntityInfoPtr pEnt; 21418781e08Smrg 21518781e08Smrg if (!dev->pdev) 21618781e08Smrg return FALSE; 21718781e08Smrg 21818781e08Smrg if (flags & PLATFORM_PROBE_GPU_SCREEN) 21918781e08Smrg scr_flags = XF86_ALLOCATE_GPU_SCREEN; 22018781e08Smrg 22118781e08Smrg pScrn = xf86AllocateScreen(pDriver, scr_flags); 22218781e08Smrg if (xf86IsEntitySharable(entity_num)) 22318781e08Smrg xf86SetEntityShared(entity_num); 22418781e08Smrg xf86AddEntityToScreen(pScrn, entity_num); 22518781e08Smrg 22618781e08Smrg if (!radeon_kernel_mode_enabled(pScrn, dev->pdev)) 22718781e08Smrg return FALSE; 22818781e08Smrg 22918781e08Smrg pScrn->driverVersion = RADEON_VERSION_CURRENT; 23018781e08Smrg pScrn->driverName = RADEON_DRIVER_NAME; 23118781e08Smrg pScrn->name = RADEON_NAME; 23218781e08Smrg pScrn->Probe = NULL; 23318781e08Smrg pScrn->PreInit = RADEONPreInit_KMS; 23418781e08Smrg pScrn->ScreenInit = RADEONScreenInit_KMS; 23518781e08Smrg pScrn->SwitchMode = RADEONSwitchMode_KMS; 23618781e08Smrg pScrn->AdjustFrame = RADEONAdjustFrame_KMS; 23718781e08Smrg pScrn->EnterVT = RADEONEnterVT_KMS; 23818781e08Smrg pScrn->LeaveVT = RADEONLeaveVT_KMS; 23918781e08Smrg pScrn->FreeScreen = RADEONFreeScreen_KMS; 24018781e08Smrg pScrn->ValidMode = RADEONValidMode; 24118781e08Smrg 24218781e08Smrg pEnt = xf86GetEntityInfo(entity_num); 24318781e08Smrg 24418781e08Smrg /* Create a RADEONEntity for all chips, even with old single head 24518781e08Smrg * Radeon, need to use pRADEONEnt for new monitor detection routines. 24618781e08Smrg */ 24718781e08Smrg { 24818781e08Smrg DevUnion *pPriv; 24918781e08Smrg RADEONEntPtr pRADEONEnt; 25018781e08Smrg 25118781e08Smrg xf86SetEntitySharable(entity_num); 25218781e08Smrg 25318781e08Smrg if (gRADEONEntityIndex == -1) 25418781e08Smrg gRADEONEntityIndex = xf86AllocateEntityPrivateIndex(); 25518781e08Smrg 25618781e08Smrg pPriv = xf86GetEntityPrivate(pEnt->index, 25718781e08Smrg gRADEONEntityIndex); 25818781e08Smrg 25918781e08Smrg xf86SetEntityInstanceForScreen(pScrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1); 26018781e08Smrg 26118781e08Smrg if (!pPriv->ptr) { 26218781e08Smrg pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1); 26318781e08Smrg pRADEONEnt = pPriv->ptr; 26418781e08Smrg } else { 26518781e08Smrg pRADEONEnt = pPriv->ptr; 26618781e08Smrg } 26718781e08Smrg pRADEONEnt->platform_dev = dev; 26818781e08Smrg } 26918781e08Smrg 27018781e08Smrg free(pEnt); 27118781e08Smrg 27218781e08Smrg return TRUE; 27318781e08Smrg} 27418781e08Smrg#endif 275de2362d3Smrg 276de2362d3Smrg_X_EXPORT DriverRec RADEON = 277de2362d3Smrg{ 278de2362d3Smrg RADEON_VERSION_CURRENT, 279de2362d3Smrg RADEON_DRIVER_NAME, 280de2362d3Smrg RADEONIdentify, 281de2362d3Smrg NULL, 282de2362d3Smrg RADEONAvailableOptions, 283de2362d3Smrg NULL, 284de2362d3Smrg 0, 28518781e08Smrg RADEONDriverFunc, 286de2362d3Smrg radeon_device_match, 28718781e08Smrg radeon_pci_probe, 28818781e08Smrg#ifdef XSERVER_PLATFORM_BUS 28918781e08Smrg radeon_platform_probe 290de2362d3Smrg#endif 291de2362d3Smrg}; 292