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 28139413783SmrgDriverRec 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