xenocara/driver/xf86-video-ati/src/radeon_probe.c
jsg 5d95bbee18 update to xf86-video-ati 7.10.0
tested by matthieu@ and myself on a wide range of radeons
2018-02-20 04:49:19 +00:00

297 lines
7.8 KiB
C

/*
* Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
* VA Linux Systems Inc., Fremont, California.
*
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation on the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
* THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <stdlib.h>
/*
* Authors:
* Kevin E. Martin <martin@xfree86.org>
* Rickard E. Faith <faith@valinux.com>
* KMS support - Dave Airlie <airlied@redhat.com>
*/
#include "radeon_probe.h"
#include "radeon_version.h"
#include "atipciids.h"
#include "atipcirename.h"
#include "xf86.h"
#include "xf86drmMode.h"
#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,19,99,1,0)
#include <xf86Pci.h>
#else
#include "dri.h"
#endif
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <xf86_OSproc.h>
#endif
#ifdef XSERVER_PLATFORM_BUS
#include <xf86platformBus.h>
#endif
#include "radeon_chipset_gen.h"
#include "radeon_pci_chipset_gen.h"
#include "radeon_pci_device_match_gen.h"
_X_EXPORT int gRADEONEntityIndex = -1;
/* Return the options for supported chipset 'n'; NULL otherwise */
static const OptionInfoRec *
RADEONAvailableOptions(int chipid, int busid)
{
return RADEONOptionsWeak();
}
/* Return the string name for supported chipset 'n'; NULL otherwise. */
static void
RADEONIdentify(int flags)
{
xf86PrintChipsets(RADEON_NAME,
"Driver for ATI/AMD Radeon chipsets",
RADEONUniqueChipsets);
}
static Bool radeon_kernel_mode_enabled(ScrnInfoPtr pScrn, struct pci_device *pci_dev)
{
char *busIdString;
int ret;
if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
"[KMS] No DRICreatePCIBusID symbol, no kernel modesetting.\n");
return FALSE;
}
busIdString = DRICreatePCIBusID(pci_dev);
ret = drmCheckModesettingSupported(busIdString);
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
if (ret) {
if (xf86LoadKernelModule("radeonkms"))
ret = drmCheckModesettingSupported(busIdString);
}
#endif
free(busIdString);
if (ret) {
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
"[KMS] drm report modesetting isn't supported.\n");
return FALSE;
}
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
"[KMS] Kernel modesetting enabled.\n");
return TRUE;
}
static Bool
radeon_get_scrninfo(int entity_num, void *pci_dev)
{
ScrnInfoPtr pScrn = NULL;
EntityInfoPtr pEnt;
pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, RADEONPciChipsets,
NULL,
NULL, NULL, NULL, NULL);
if (!pScrn)
return FALSE;
if (!radeon_kernel_mode_enabled(pScrn, pci_dev))
return FALSE;
pScrn->driverVersion = RADEON_VERSION_CURRENT;
pScrn->driverName = RADEON_DRIVER_NAME;
pScrn->name = RADEON_NAME;
pScrn->Probe = NULL;
pScrn->PreInit = RADEONPreInit_KMS;
pScrn->ScreenInit = RADEONScreenInit_KMS;
pScrn->SwitchMode = RADEONSwitchMode_KMS;
pScrn->AdjustFrame = RADEONAdjustFrame_KMS;
pScrn->EnterVT = RADEONEnterVT_KMS;
pScrn->LeaveVT = RADEONLeaveVT_KMS;
pScrn->FreeScreen = RADEONFreeScreen_KMS;
pScrn->ValidMode = RADEONValidMode;
pEnt = xf86GetEntityInfo(entity_num);
/* Create a RADEONEntity for all chips, even with old single head
* Radeon, need to use pRADEONEnt for new monitor detection routines.
*/
{
DevUnion *pPriv;
xf86SetEntitySharable(entity_num);
if (gRADEONEntityIndex == -1)
gRADEONEntityIndex = xf86AllocateEntityPrivateIndex();
pPriv = xf86GetEntityPrivate(pEnt->index,
gRADEONEntityIndex);
xf86SetEntityInstanceForScreen(pScrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1);
if (!pPriv->ptr)
pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1);
}
free(pEnt);
return TRUE;
}
static Bool
radeon_pci_probe(
DriverPtr pDriver,
int entity_num,
struct pci_device *device,
intptr_t match_data
)
{
return radeon_get_scrninfo(entity_num, (void *)device);
}
static Bool
RADEONDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data)
{
xorgHWFlags *flag;
switch (op) {
case GET_REQUIRED_HW_INTERFACES:
flag = (CARD32 *)data;
(*flag) = 0;
return TRUE;
#if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,15,99,0,0)
case SUPPORTS_SERVER_FDS:
return TRUE;
#endif
default:
return FALSE;
}
}
#ifdef XSERVER_PLATFORM_BUS
static Bool
radeon_platform_probe(DriverPtr pDriver,
int entity_num, int flags,
struct xf86_platform_device *dev,
intptr_t match_data)
{
ScrnInfoPtr pScrn;
int scr_flags = 0;
EntityInfoPtr pEnt;
if (!dev->pdev)
return FALSE;
if (flags & PLATFORM_PROBE_GPU_SCREEN)
scr_flags = XF86_ALLOCATE_GPU_SCREEN;
pScrn = xf86AllocateScreen(pDriver, scr_flags);
if (xf86IsEntitySharable(entity_num))
xf86SetEntityShared(entity_num);
xf86AddEntityToScreen(pScrn, entity_num);
if (!radeon_kernel_mode_enabled(pScrn, dev->pdev))
return FALSE;
pScrn->driverVersion = RADEON_VERSION_CURRENT;
pScrn->driverName = RADEON_DRIVER_NAME;
pScrn->name = RADEON_NAME;
pScrn->Probe = NULL;
pScrn->PreInit = RADEONPreInit_KMS;
pScrn->ScreenInit = RADEONScreenInit_KMS;
pScrn->SwitchMode = RADEONSwitchMode_KMS;
pScrn->AdjustFrame = RADEONAdjustFrame_KMS;
pScrn->EnterVT = RADEONEnterVT_KMS;
pScrn->LeaveVT = RADEONLeaveVT_KMS;
pScrn->FreeScreen = RADEONFreeScreen_KMS;
pScrn->ValidMode = RADEONValidMode;
pEnt = xf86GetEntityInfo(entity_num);
/* Create a RADEONEntity for all chips, even with old single head
* Radeon, need to use pRADEONEnt for new monitor detection routines.
*/
{
DevUnion *pPriv;
RADEONEntPtr pRADEONEnt;
xf86SetEntitySharable(entity_num);
if (gRADEONEntityIndex == -1)
gRADEONEntityIndex = xf86AllocateEntityPrivateIndex();
pPriv = xf86GetEntityPrivate(pEnt->index,
gRADEONEntityIndex);
xf86SetEntityInstanceForScreen(pScrn, pEnt->index, xf86GetNumEntityInstances(pEnt->index) - 1);
if (!pPriv->ptr) {
pPriv->ptr = xnfcalloc(sizeof(RADEONEntRec), 1);
pRADEONEnt = pPriv->ptr;
} else {
pRADEONEnt = pPriv->ptr;
}
pRADEONEnt->platform_dev = dev;
}
free(pEnt);
return TRUE;
}
#endif
_X_EXPORT DriverRec RADEON =
{
RADEON_VERSION_CURRENT,
RADEON_DRIVER_NAME,
RADEONIdentify,
NULL,
RADEONAvailableOptions,
NULL,
0,
RADEONDriverFunc,
radeon_device_match,
radeon_pci_probe,
#ifdef XSERVER_PLATFORM_BUS
radeon_platform_probe
#endif
};