summaryrefslogtreecommitdiff
path: root/src/radeon_dri.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-03-09 23:26:27 +0000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-03-09 23:26:27 +0000
commit8033d7423267fc1b3725df6a077dd910b586daaf (patch)
tree050f5fe847ecdd66c0df0f48401afa00469fdfda /src/radeon_dri.c
parentc637939d3c4ce5cdddbc5200d5ffbca4c3927050 (diff)
More memory map fixes !!! This time, we add a way to get the DRM kernel
module version early, in order to properly limit the framebuffer size when a module that doesn't support the new map is loaded. That will improve backward compatibility. I also made the minimum required kernel module version 1.3 which hopefully shouldn't be a problem for anybody, and cleaned up the ordering in which we test for DRM version to enable features
Diffstat (limited to 'src/radeon_dri.c')
-rw-r--r--src/radeon_dri.c260
1 files changed, 129 insertions, 131 deletions
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 544bca24..f9e7c9a3 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -1092,7 +1092,7 @@ static void RADEONDRIGartHeapInit(RADEONInfoPtr info, ScreenPtr pScreen)
drmRadeonMemInitHeap drmHeap;
/* Start up the simple memory manager for GART space */
- if (info->drmMinor >= 6) {
+ if (info->pKernelDRMVersion->version_minor >= 6) {
drmHeap.region = RADEON_MEM_REGION_GART;
drmHeap.start = 0;
drmHeap.size = info->gartTexMapSize;
@@ -1109,7 +1109,7 @@ static void RADEONDRIGartHeapInit(RADEONInfoPtr info, ScreenPtr pScreen)
} else {
xf86DrvMsg(pScreen->myNum, X_INFO,
"[drm] Kernel module too old (1.%d) for GART heap manager\n",
- info->drmMinor);
+ info->pKernelDRMVersion->version_minor);
}
}
@@ -1193,19 +1193,14 @@ static void RADEONDRICPInit(ScrnInfoPtr pScrn)
}
-/* Initialize the screen-specific data structures for the DRI and the
- * Radeon. This is the main entry point to the device-specific
- * initialization code. It calls device-independent DRI functions to
- * create the DRI data structures and initialize the DRI state.
- */
-Bool RADEONDRIScreenInit(ScreenPtr pScreen)
+/* Get the DRM version and do some basic useability checks of DRI */
+Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn)
{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
- DRIInfoPtr pDRIInfo;
- RADEONDRIPtr pRADEONDRI;
- int major, minor, patch;
- drmVersionPtr version;
+ int major, minor, patch, fd;
+ int req_minor, req_patch;
+ char *busId;
+ drmVersionPtr libVersion;
/* Check that the GLX, DRI, and DRM modules have been loaded by testing
* for known symbols in each module.
@@ -1213,16 +1208,17 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE;
if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE;
if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[dri] RADEONDRIScreenInit failed (libdri.a too old)\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] RADEONDRIGetVersion failed (libdri.a too old)\n"
+ "[dri] Disabling DRI.\n");
return FALSE;
}
/* Check the DRI version */
DRIQueryVersion(&major, &minor, &patch);
if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[dri] RADEONDRIScreenInit failed because of a version "
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] RADEONDRIGetVersion failed because of a version "
"mismatch.\n"
"[dri] libdri version is %d.%d.%d but version %d.%d.x is "
"needed.\n"
@@ -1232,6 +1228,118 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
return FALSE;
}
+ /* Check the lib version */
+ if (xf86LoaderCheckSymbol("drmGetLibVersion"))
+ info->pLibDRMVersion = drmGetLibVersion(info->drmFD);
+ if (info->pLibDRMVersion == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] RADEONDRIGetVersion failed because libDRM is really "
+ "way to old to even get a version number out of it.\n"
+ "[dri] Disabling DRI.\n");
+ return FALSE;
+ }
+ if (info->pLibDRMVersion->version_major != 1 ||
+ info->pLibDRMVersion->version_minor < 2) {
+ /* incompatible drm library version */
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] RADEONDRIGetVersion failed because of a "
+ "version mismatch.\n"
+ "[dri] libdrm.a module version is %d.%d.%d but "
+ "version 1.2.x is needed.\n"
+ "[dri] Disabling DRI.\n",
+ info->pLibDRMVersion->version_major,
+ info->pLibDRMVersion->version_minor,
+ info->pLibDRMVersion->version_patchlevel);
+ drmFreeVersion(info->pLibDRMVersion);
+ info->pLibDRMVersion = NULL;
+ return FALSE;
+ }
+
+ /* Create a bus Id */
+ if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
+ busId = DRICreatePCIBusID(info->PciInfo);
+ } else {
+ busId = xalloc(64);
+ sprintf(busId,
+ "PCI:%d:%d:%d",
+ info->PciInfo->bus,
+ info->PciInfo->device,
+ info->PciInfo->func);
+ }
+
+ /* Low level DRM open */
+ fd = drmOpen(RADEON_DRIVER_NAME, busId);
+ xfree(busId);
+ if (fd < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] RADEONDRIGetVersion failed to open the DRM\n"
+ "[dri] Disabling DRI.\n");
+ return FALSE;
+ }
+
+ /* Get DRM version & close DRM */
+ info->pKernelDRMVersion = drmGetVersion(fd);
+ drmClose(fd);
+ if (info->pKernelDRMVersion == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] RADEONDRIGetVersion failed to get the DRM version\n"
+ "[dri] Disabling DRI.\n");
+ return FALSE;
+ }
+
+ /* Now check if we qualify */
+ if (info->IsIGP) {
+ req_minor = 10;
+ req_patch = 0;
+ } else if (info->ChipFamily >= CHIP_FAMILY_R300) {
+ req_minor = 17;
+ req_patch = 0;
+ } else if (info->ChipFamily >= CHIP_FAMILY_R200) {
+ req_minor = 5;
+ req_patch = 0;
+ } else {
+ req_minor = 3;
+ req_patch = 0;
+ }
+
+ /* We don't, bummer ! */
+ if (info->pKernelDRMVersion->version_major != 1 ||
+ info->pKernelDRMVersion->version_minor < req_minor ||
+ (info->pKernelDRMVersion->version_minor == req_minor &&
+ info->pKernelDRMVersion->version_patchlevel < req_patch)) {
+ /* Incompatible drm version */
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] RADEONDRIGetVersion failed because of a version "
+ "mismatch.\n"
+ "[dri] radeon.o kernel module version is %d.%d.%d "
+ "but version 1.%d.%d or newer is needed.\n"
+ "[dri] Disabling DRI.\n",
+ info->pKernelDRMVersion->version_major,
+ info->pKernelDRMVersion->version_minor,
+ info->pKernelDRMVersion->version_patchlevel,
+ req_minor,
+ req_patch);
+ drmFreeVersion(info->pKernelDRMVersion);
+ info->pKernelDRMVersion = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Initialize the screen-specific data structures for the DRI and the
+ * Radeon. This is the main entry point to the device-specific
+ * initialization code. It calls device-independent DRI functions to
+ * create the DRI data structures and initialize the DRI state.
+ */
+Bool RADEONDRIScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ DRIInfoPtr pDRIInfo;
+ RADEONDRIPtr pRADEONDRI;
+ drmVersionPtr version;
+
switch (info->CurrentLayout.pixel_code) {
case 8:
case 15:
@@ -1350,117 +1458,6 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
pDRIInfo = NULL;
return FALSE;
}
-
- /* Check the DRM lib version.
- * drmGetLibVersion was not supported in version 1.0, so check for
- * symbol first to avoid possible crash or hang.
- */
- if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
- version = drmGetLibVersion(info->drmFD);
- } else {
- /* drmlib version 1.0.0 didn't have the drmGetLibVersion
- * entry point. Fake it by allocating a version record
- * via drmGetVersion and changing it to version 1.0.0.
- */
- version = drmGetVersion(info->drmFD);
- version->version_major = 1;
- version->version_minor = 0;
- version->version_patchlevel = 0;
- }
-
- if (version) {
- if (version->version_major != 1 ||
- version->version_minor < 1) {
- /* incompatible drm library version */
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[dri] RADEONDRIScreenInit failed because of a "
- "version mismatch.\n"
- "[dri] libdrm.a module version is %d.%d.%d but "
- "version 1.1.x is needed.\n"
- "[dri] Disabling DRI.\n",
- version->version_major,
- version->version_minor,
- version->version_patchlevel);
- drmFreeVersion(version);
- RADEONDRICloseScreen(pScreen);
- return FALSE;
- }
- drmFreeVersion(version);
- }
-
- /* Check the radeon DRM version */
- version = drmGetVersion(info->drmFD);
- if (version) {
- int req_minor, req_patch;
-
- if (info->IsIGP) {
- req_minor = 10;
- req_patch = 0;
- } else if (info->ChipFamily >= CHIP_FAMILY_R300) {
- req_minor = 17;
- req_patch = 0;
- } else if (info->ChipFamily >= CHIP_FAMILY_R200) {
- req_minor = 5;
- req_patch = 0;
- } else {
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
- req_minor = 1;
- req_patch = 0;
-#else
- req_minor = 2;
- req_patch = 1;
-#endif
- }
-
- if (version->version_major != 1 ||
- version->version_minor < req_minor ||
- (version->version_minor == req_minor &&
- version->version_patchlevel < req_patch)) {
- /* Incompatible drm version */
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[dri] RADEONDRIScreenInit failed because of a version "
- "mismatch.\n"
- "[dri] radeon.o kernel module version is %d.%d.%d "
- "but version 1.%d.%d or newer is needed.\n"
- "[dri] Disabling DRI.\n",
- version->version_major,
- version->version_minor,
- version->version_patchlevel,
- req_minor,
- req_patch);
- drmFreeVersion(version);
- RADEONDRICloseScreen(pScreen);
- return FALSE;
- }
-
- if (version->version_minor < 3) {
- xf86DrvMsg(pScreen->myNum, X_WARNING,
- "[dri] Some DRI features disabled because of version "
- "mismatch.\n"
- "[dri] radeon.o kernel module version is %d.%d.%d but "
- "1.3.1 or later is preferred.\n",
- version->version_major,
- version->version_minor,
- version->version_patchlevel);
- }
- info->drmMinor = version->version_minor;
-
- if (info->allowColorTiling && version->version_minor < 14) {
- xf86DrvMsg(pScreen->myNum, X_WARNING,
- "[dri] color tiling disabled because of version "
- "mismatch.\n"
- "[dri] radeon.o kernel module version is %d.%d.%d but "
- "1.14.0 or later is required for color tiling.\n",
- version->version_major,
- version->version_minor,
- version->version_patchlevel);
- info->allowColorTiling = FALSE;
- info->tilingEnabled = FALSE;
- pDRIInfo->ddxDriverMajorVersion = RADEON_VERSION_MAJOR;
- }
- drmFreeVersion(version);
- }
-
/* Initialize AGP */
if (info->cardType==CARD_AGP && !RADEONDRIAgpInit(info, pScreen)) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
@@ -1613,7 +1610,7 @@ void RADEONDRIInitPageFlip(ScreenPtr pScreen)
/* Have shadowfb run only while there is 3d active. This must happen late,
* after XAAInit has been called
*/
- if (!info->useEXA /* && info->drmMinor >= 3 */) {
+ if (!info->useEXA) {
if (!ShadowFBInit( pScreen, RADEONDRIRefreshArea )) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"ShadowFB init failed, Page Flipping disabled\n");
@@ -1638,7 +1635,7 @@ void RADEONDRIResume(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
- if (info->drmMinor >= 9) {
+ if (info->pKernelDRMVersion->version_minor >= 9) {
xf86DrvMsg(pScreen->myNum, X_INFO,
"[RESUME] Attempting to re-init Radeon hardware.\n");
} else {
@@ -2008,7 +2005,8 @@ void RADEONDRIAllocatePCIGARTTable(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
- if (info->cardType!=CARD_PCIE || info->drmMinor<19)
+ if (info->cardType != CARD_PCIE ||
+ info->pKernelDRMVersion->version_minor < 19)
return;
if (info->FbSecureSize==0)