diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-03-09 23:26:27 +0000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-03-09 23:26:27 +0000 |
commit | 8033d7423267fc1b3725df6a077dd910b586daaf (patch) | |
tree | 050f5fe847ecdd66c0df0f48401afa00469fdfda /src/radeon_dri.c | |
parent | c637939d3c4ce5cdddbc5200d5ffbca4c3927050 (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.c | 260 |
1 files changed, 129 insertions, 131 deletions
diff --git a/src/radeon_dri.c b/src/radeon_dri.c index 544bca2..f9e7c9a 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) |