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