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