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 52#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,19,99,1,0) 53#include <xf86Pci.h> 54#else 55#include "dri.h" 56#endif 57 58#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 59#include <xf86_OSproc.h> 60#endif 61 62#ifdef XSERVER_PLATFORM_BUS 63#include <xf86platformBus.h> 64#endif 65 66#include "radeon_chipset_gen.h" 67 68#include "radeon_pci_chipset_gen.h" 69 70#include "radeon_pci_device_match_gen.h" 71 72_X_EXPORT int gRADEONEntityIndex = -1; 73 74/* Return the options for supported chipset 'n'; NULL otherwise */ 75static const OptionInfoRec * 76RADEONAvailableOptions(int chipid, int busid) 77{ 78 return RADEONOptionsWeak(); 79} 80 81/* Return the string name for supported chipset 'n'; NULL otherwise. */ 82static void 83RADEONIdentify(int flags) 84{ 85 xf86PrintChipsets(RADEON_NAME, 86 "Driver for ATI/AMD Radeon chipsets", 87 RADEONUniqueChipsets); 88} 89 90 91static Bool radeon_kernel_mode_enabled(ScrnInfoPtr pScrn, struct pci_device *pci_dev) 92{ 93 char *busIdString; 94 int ret; 95 96 if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) { 97 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, 98 "[KMS] No DRICreatePCIBusID symbol, no kernel modesetting.\n"); 99 return FALSE; 100 } 101 102 busIdString = DRICreatePCIBusID(pci_dev); 103 ret = drmCheckModesettingSupported(busIdString); 104#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 105 if (ret) { 106 if (xf86LoadKernelModule("radeonkms")) 107 ret = drmCheckModesettingSupported(busIdString); 108 } 109#endif 110 free(busIdString); 111 if (ret) { 112 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, 113 "[KMS] drm report modesetting isn't supported.\n"); 114 return FALSE; 115 } 116 117 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, 118 "[KMS] Kernel modesetting enabled.\n"); 119 return TRUE; 120} 121 122static Bool 123radeon_get_scrninfo(int entity_num, void *pci_dev) 124{ 125 ScrnInfoPtr pScrn = NULL; 126 EntityInfoPtr pEnt; 127 128 pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, RADEONPciChipsets, 129 NULL, 130 NULL, NULL, NULL, NULL); 131 132 if (!pScrn) 133 return FALSE; 134 135 if (!radeon_kernel_mode_enabled(pScrn, pci_dev)) 136 return FALSE; 137 138 pScrn->driverVersion = RADEON_VERSION_CURRENT; 139 pScrn->driverName = RADEON_DRIVER_NAME; 140 pScrn->name = RADEON_NAME; 141 pScrn->Probe = NULL; 142 143 pScrn->PreInit = RADEONPreInit_KMS; 144 pScrn->ScreenInit = RADEONScreenInit_KMS; 145 pScrn->SwitchMode = RADEONSwitchMode_KMS; 146 pScrn->AdjustFrame = RADEONAdjustFrame_KMS; 147 pScrn->EnterVT = RADEONEnterVT_KMS; 148 pScrn->LeaveVT = RADEONLeaveVT_KMS; 149 pScrn->FreeScreen = RADEONFreeScreen_KMS; 150 pScrn->ValidMode = RADEONValidMode; 151 152 pEnt = xf86GetEntityInfo(entity_num); 153 154 /* Create a RADEONEntity for all chips, even with old single head 155 * Radeon, need to use pRADEONEnt for new monitor detection routines. 156 */ 157 { 158 DevUnion *pPriv; 159 160 xf86SetEntitySharable(entity_num); 161 162 if (gRADEONEntityIndex == -1) 163 gRADEONEntityIndex = xf86AllocateEntityPrivateIndex(); 164 165 pPriv = xf86GetEntityPrivate(pEnt->index, 166 gRADEONEntityIndex); 167 168 xf86SetEntityInstanceForScreen(pScrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1); 169 170 if (!pPriv->ptr) 171 pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1); 172 } 173 174 free(pEnt); 175 176 return TRUE; 177} 178 179static Bool 180radeon_pci_probe( 181 DriverPtr pDriver, 182 int entity_num, 183 struct pci_device *device, 184 intptr_t match_data 185) 186{ 187 return radeon_get_scrninfo(entity_num, (void *)device); 188} 189 190static Bool 191RADEONDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data) 192{ 193 xorgHWFlags *flag; 194 195 switch (op) { 196 case GET_REQUIRED_HW_INTERFACES: 197 flag = (CARD32 *)data; 198 (*flag) = 0; 199 return TRUE; 200#if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,15,99,0,0) 201 case SUPPORTS_SERVER_FDS: 202 return TRUE; 203#endif 204 default: 205 return FALSE; 206 } 207} 208 209#ifdef XSERVER_PLATFORM_BUS 210static Bool 211radeon_platform_probe(DriverPtr pDriver, 212 int entity_num, int flags, 213 struct xf86_platform_device *dev, 214 intptr_t match_data) 215{ 216 ScrnInfoPtr pScrn; 217 int scr_flags = 0; 218 EntityInfoPtr pEnt; 219 220 if (!dev->pdev) 221 return FALSE; 222 223 if (flags & PLATFORM_PROBE_GPU_SCREEN) 224 scr_flags = XF86_ALLOCATE_GPU_SCREEN; 225 226 pScrn = xf86AllocateScreen(pDriver, scr_flags); 227 if (xf86IsEntitySharable(entity_num)) 228 xf86SetEntityShared(entity_num); 229 xf86AddEntityToScreen(pScrn, entity_num); 230 231 if (!radeon_kernel_mode_enabled(pScrn, dev->pdev)) 232 return FALSE; 233 234 pScrn->driverVersion = RADEON_VERSION_CURRENT; 235 pScrn->driverName = RADEON_DRIVER_NAME; 236 pScrn->name = RADEON_NAME; 237 pScrn->Probe = NULL; 238 pScrn->PreInit = RADEONPreInit_KMS; 239 pScrn->ScreenInit = RADEONScreenInit_KMS; 240 pScrn->SwitchMode = RADEONSwitchMode_KMS; 241 pScrn->AdjustFrame = RADEONAdjustFrame_KMS; 242 pScrn->EnterVT = RADEONEnterVT_KMS; 243 pScrn->LeaveVT = RADEONLeaveVT_KMS; 244 pScrn->FreeScreen = RADEONFreeScreen_KMS; 245 pScrn->ValidMode = RADEONValidMode; 246 247 pEnt = xf86GetEntityInfo(entity_num); 248 249 /* Create a RADEONEntity for all chips, even with old single head 250 * Radeon, need to use pRADEONEnt for new monitor detection routines. 251 */ 252 { 253 DevUnion *pPriv; 254 RADEONEntPtr pRADEONEnt; 255 256 xf86SetEntitySharable(entity_num); 257 258 if (gRADEONEntityIndex == -1) 259 gRADEONEntityIndex = xf86AllocateEntityPrivateIndex(); 260 261 pPriv = xf86GetEntityPrivate(pEnt->index, 262 gRADEONEntityIndex); 263 264 xf86SetEntityInstanceForScreen(pScrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1); 265 266 if (!pPriv->ptr) { 267 pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1); 268 pRADEONEnt = pPriv->ptr; 269 } else { 270 pRADEONEnt = pPriv->ptr; 271 } 272 pRADEONEnt->platform_dev = dev; 273 } 274 275 free(pEnt); 276 277 return TRUE; 278} 279#endif 280 281DriverRec RADEON = 282{ 283 RADEON_VERSION_CURRENT, 284 RADEON_DRIVER_NAME, 285 RADEONIdentify, 286 NULL, 287 RADEONAvailableOptions, 288 NULL, 289 0, 290 RADEONDriverFunc, 291 radeon_device_match, 292 radeon_pci_probe, 293#ifdef XSERVER_PLATFORM_BUS 294 radeon_platform_probe 295#endif 296}; 297