From 18c707a8c13ac5fffdd30d55e6f5926a68b367df Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 25 Jul 2007 10:11:16 -0700 Subject: [PATCH 01/26] When TTM is available, use it instead of manual AGP allocations when possible. This is a step towards being able to expose buffer objects through the screen private to DRI clients, instead of having them have to use the fake buffer object type. This fails in two ways. First, the kernel memory manager is not currently suitable for doing the physical allocations we need, so we still use AGP for those. Additionally, the DRI lock can't be initialized early enough for us, so these buffer object allocations fail. This will be fixed by improving the DRM interface. --- man/intel.man | 5 +- src/i830.h | 8 +- src/i830_accel.c | 6 ++ src/i830_dri.c | 106 ++++++++++------------- src/i830_driver.c | 215 +++++++++++++--------------------------------- src/i830_memory.c | 200 ++++++++++++++++++++++++++++++++++-------- 6 files changed, 283 insertions(+), 257 deletions(-) diff --git a/man/intel.man b/man/intel.man index 33dc319e..c682d550 100644 --- a/man/intel.man +++ b/man/intel.man @@ -128,9 +128,8 @@ Default: XVideo is enabled for configurations where it is supported. Enable support for the legacy i915_dri.so 3D driver. This will, among other things, make the 2D driver tell libGL to load the 3D driver i915_dri.so instead of the newer i915tex_dri.so. -This option is only used for chipsets in the range i830-i945. -Default for i830-i945 series: Enabled for i915 drm versions < 1.7.0. Otherwise -disabled. +This option is only used for chipsets in the range i830-i945. +Default for i830-i945 series: Enabled. Default for i810: The option is not used. Default for i965: The option is always true. .TP diff --git a/src/i830.h b/src/i830.h index aa2b240c..6e1f88a2 100644 --- a/src/i830.h +++ b/src/i830.h @@ -158,6 +158,9 @@ struct _i830_memory { i830_memory *prev; /** @} */ +#ifdef XF86DRI_MM + drmBO bo; +#endif }; typedef struct { @@ -328,8 +331,7 @@ typedef struct _I830Rec { int TexGranularity; int drmMinor; - int mmModeFlags; - int mmSize; + Bool allocate_classic_textures; unsigned int back_tiled; unsigned int third_tiled; @@ -635,6 +637,7 @@ extern void I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, Bool i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size); +void i830_allocator_fini(ScrnInfoPtr pScrn); void i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix); void i830_reset_allocations(ScrnInfoPtr pScrn); @@ -744,6 +747,7 @@ extern const int I830CopyROP[16]; /* Flags for memory allocation function */ #define NEED_PHYSICAL_ADDR 0x00000001 #define ALIGN_BOTH_ENDS 0x00000002 +#define NEED_NON_STOLEN 0x00000004 /* Chipset registers for VIDEO BIOS memory RW access */ #define _855_DRAM_RW_CONTROL 0x58 diff --git a/src/i830_accel.c b/src/i830_accel.c index 5cbad44e..4d9ea790 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -254,6 +254,12 @@ I830RefreshRing(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); + /* If we're reaching RefreshRing as a result of grabbing the DRI lock + * before we've set up the ringbuffer, don't bother. + */ + if (pI830->LpRing->mem == NULL) + return; + pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); diff --git a/src/i830_dri.c b/src/i830_dri.c index ca1190cf..0d511d22 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -546,16 +546,12 @@ I830DRIScreenInit(ScreenPtr pScreen) pDRIInfo->ddxDriverMajorVersion = I830_MAJOR_VERSION; pDRIInfo->ddxDriverMinorVersion = I830_MINOR_VERSION; pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL; -#if 1 /* Remove this soon - see bug 5714 */ - pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr + - pI830->front_buffer->offset; - pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth * - pScrn->virtualY * pI830->cpp); -#else - /* For rotation we map a 0 length framebuffer as we remap ourselves later */ - pDRIInfo->frameBufferSize = 0; -#endif - pDRIInfo->frameBufferStride = pScrn->displayWidth * pI830->cpp; + /* Supply a dummy mapping info required by DRI setup. See bug #5714 for + * progress on removing this requirement. + */ + pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr; + pDRIInfo->frameBufferSize = GTT_PAGE_SIZE; + pDRIInfo->frameBufferStride = 1; pDRIInfo->ddxDrawableTableEntry = I830_MAX_DRAWABLES; if (SAREA_MAX_DRAWABLES < I830_MAX_DRAWABLES) @@ -637,11 +633,11 @@ I830DRIScreenInit(ScreenPtr pScreen) return FALSE; } -#if 0 /* disabled now, see frameBufferSize above being set to 0 */ - /* for this driver, get rid of the front buffer mapping now */ + /* Now, nuke dri.c's frontbuffer map setup. */ +#if 0 if (xf86LoaderCheckSymbol("DRIGetScreenPrivate")) { - DRIScreenPrivPtr pDRIPriv - = (DRIScreenPrivPtr) DRIGetScreenPrivate(pScreen); + DRIScreenPrivPtr pDRIPriv = + (DRIScreenPrivPtr) DRIGetScreenPrivate(pScreen); if (pDRIPriv && pDRIPriv->drmFD && pDRIPriv->hFrameBuffer) { xf86DrvMsg(pScreen->myNum, X_ERROR, @@ -652,11 +648,25 @@ I830DRIScreenInit(ScreenPtr pScreen) "[intel] done removing original screen mapping\n"); } } - else { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[intel] DRIGetScreenPrivate not found!!!!\n"); - } #endif + { + int tmp; + unsigned int fb_handle; + void *ptmp; + + /* With the compat method, it will continue to report + * the wrong map out of GetDeviceInfo, but we don't have any consumers + * of the frontbuffer handle from there. + */ + DRIGetDeviceInfo(pScreen, &fb_handle, &tmp, &tmp, &tmp, &tmp, &ptmp); + drmRmMap(pI830->drmSubFD, fb_handle); + + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Removed DRI frontbuffer mapping in compatibility mode.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "DRIGetDeviceInfo will report incorrect frontbuffer " + "handle.\n"); + } /* Check the i915 DRM versioning */ { @@ -724,27 +734,6 @@ I830DRIScreenInit(ScreenPtr pScreen) return FALSE; } pI830->drmMinor = version->version_minor; - if (version->version_minor < 7) { - if (pI830->mmModeFlags & I830_KERNEL_MM) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Unable to use TTM-based memory manager with DRM version %d.%d\n", - version->version_major, version->version_minor); - pI830->mmModeFlags &= ~I830_KERNEL_MM; - - i830_free_memory(pScrn, pI830->memory_manager); - pI830->memory_manager = NULL; - - if (!(pI830->mmModeFlags & I830_KERNEL_TEX)) { - pI830->mmModeFlags |= I830_KERNEL_TEX; - - if (!i830_allocate_texture_memory(pScrn)) { - I830DRICloseScreen(pScreen); - drmFreeVersion(version); - return FALSE; - } - } - } - } #ifdef DAMAGE if (pI830->allowPageFlip && pI830->drmMinor < 9) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, @@ -762,7 +751,7 @@ I830DRIScreenInit(ScreenPtr pScreen) */ if ((pDRIInfo->clientDriverName == I830ClientDriverName) && - (pI830->mmModeFlags & I830_KERNEL_TEX)) { + (pI830->allocate_classic_textures)) { pDRIInfo->clientDriverName = I830LegacyClientDriverName; } @@ -780,26 +769,21 @@ I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea) pScrn->virtualY * pI830->cpp); #endif - /* The I965G isn't ready for the front buffer mapping to be moved around, - * because of issues with rmmap, it seems. - */ - if (!IS_I965G(pI830)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "[drm] Mapping front buffer\n"); - if (drmAddMap(pI830->drmSubFD, - (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), - sarea->front_size, - DRM_AGP, - 0, - (drmAddress) &sarea->front_handle) < 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); - DRICloseScreen(pScreen); - return FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Front Buffer = 0x%08x\n", - (int)sarea->front_handle); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[drm] Mapping front buffer\n"); + if (drmAddMap(pI830->drmSubFD, + (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), + sarea->front_size, + DRM_AGP, + 0, + (drmAddress) &sarea->front_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); + DRICloseScreen(pScreen); + return FALSE; } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Front Buffer = 0x%08x\n", + (int)sarea->front_handle); if (drmAddMap(pI830->drmSubFD, (drm_handle_t)(sarea->back_offset + pI830->LinearAddr), @@ -841,7 +825,7 @@ I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Depth Buffer = 0x%08x\n", (int)sarea->depth_handle); - if (pI830->mmModeFlags & I830_KERNEL_TEX) { + if (pI830->allocate_classic_textures) { if (drmAddMap(pI830->drmSubFD, (drm_handle_t)sarea->tex_offset + pI830->LinearAddr, sarea->tex_size, DRM_AGP, 0, @@ -1710,7 +1694,7 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) success = I830DRIMapScreenRegions(pScrn, sarea); - if (success && (pI830->mmModeFlags & I830_KERNEL_TEX)) + if (success && pI830->allocate_classic_textures) I830InitTextureHeap(pScrn, sarea); return success; diff --git a/src/i830_driver.c b/src/i830_driver.c index 9bb12c6b..20c6c682 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -290,7 +290,6 @@ typedef enum { OPTION_TILING, #ifdef XF86DRI_MM OPTION_INTELTEXPOOL, - OPTION_INTELMMSIZE, #endif OPTION_TRIPLEBUFFER, } I830Opts; @@ -313,7 +312,6 @@ static OptionInfoRec I830Options[] = { {OPTION_TILING, "Tiling", OPTV_BOOLEAN, {0}, TRUE}, #ifdef XF86DRI_MM {OPTION_INTELTEXPOOL,"Legacy3D", OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_INTELMMSIZE, "AperTexSize", OPTV_INTEGER, {0}, FALSE}, #endif {OPTION_TRIPLEBUFFER, "TripleBuffer", OPTV_BOOLEAN, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} @@ -1319,50 +1317,22 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->directRenderingDisabled = TRUE; } - pI830->mmModeFlags = 0; - if (!pI830->directRenderingDisabled) { - pI830->mmModeFlags = I830_KERNEL_TEX; -#ifdef XF86DRI_MM - Bool tmp = FALSE; - - if (!IS_I965G(pI830)) - pI830->mmModeFlags |= I830_KERNEL_MM; -#endif + pI830->allocate_classic_textures = TRUE; from = X_PROBED; #ifdef XF86DRI_MM - if (xf86GetOptValBool(pI830->Options, - OPTION_INTELTEXPOOL, &tmp)) { - from = X_CONFIG; - if (tmp) { - pI830->mmModeFlags |= I830_KERNEL_TEX; - pI830->mmModeFlags &= ~I830_KERNEL_MM; - } else { - pI830->mmModeFlags &= ~I830_KERNEL_TEX; - pI830->mmModeFlags |= I830_KERNEL_MM; - } - } -#endif + if (!IS_I965G(pI830)) { + Bool tmp; - xf86DrvMsg(pScrn->scrnIndex, from, - "Will %stry to allocate texture pool " - "for old Mesa 3D driver.\n", - (pI830->mmModeFlags & I830_KERNEL_TEX) ? - "" : "not "); - -#ifdef XF86DRI_MM - pI830->mmSize = I830_MM_MAXSIZE; - from = X_INFO; - if (xf86GetOptValInteger(pI830->Options, OPTION_INTELMMSIZE, - &(pI830->mmSize))) { - from = X_CONFIG; + if (xf86GetOptValBool(pI830->Options, + OPTION_INTELTEXPOOL, &tmp)) { + from = X_CONFIG; + if (!tmp) + pI830->allocate_classic_textures = FALSE; + } } - xf86DrvMsg(pScrn->scrnIndex, from, - "Will try to reserve %d kiB of AGP aperture space\n" - "\tfor the DRM memory manager.\n", - pI830->mmSize); #endif } } @@ -2128,12 +2098,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) int i; Bool allocation_done = FALSE; MessageType from; -#ifdef XF86DRI - Bool driDisabled; -#ifdef XF86DRI_MM - unsigned long savedMMSize; -#endif -#endif pScrn = xf86Screens[pScreen->myNum]; pI830 = I830PTR(pScrn); @@ -2227,6 +2191,23 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->videoRam &= ~3; } +#ifdef XF86DRI + /* Check for appropriate bpp and module support to initialize DRI. */ + if (!I830CheckDRIAvailable(pScrn)) { + pI830->directRenderingDisabled = TRUE; + } + + /* If DRI hasn't been explicitly disabled, try to initialize it. + * It will be used by the memory allocator. + */ + if (!pI830->directRenderingDisabled) + pI830->directRenderingEnabled = I830DRIScreenInit(pScreen); + else + pI830->directRenderingEnabled = FALSE; +#else + pI830->directRenderingEnabled = FALSE; +#endif + /* Set up our video memory allocator for the chosen videoRam */ if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -2321,12 +2302,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) * for it, and if there's also enough to allow tiling to be enabled. */ - if (!I830CheckDRIAvailable(pScrn)) { - pI830->directRenderingDisabled = TRUE; -#ifdef XF86DRI_MM - pI830->mmSize = 0; -#endif - } #ifdef I830_XV /* @@ -2336,7 +2311,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->XvEnabled = !pI830->XvDisabled; #endif - if (!pI830->directRenderingDisabled) { + if (pI830->directRenderingEnabled) { int savedDisplayWidth = pScrn->displayWidth; Bool tiled = FALSE; @@ -2366,25 +2341,18 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } - /* Attempt several rounds of allocation to get 2d and 3d memory to fit: + /* Attempt two rounds of allocation to get 2d and 3d memory to fit: * - * 0: tiled, large memory manager - * 1: tiled, small memory manager - * 2: untiled, large - * 3: untiled, small + * 0: untiled + * 1: tiled */ -#ifdef XF86DRI_MM - savedMMSize = pI830->mmSize; -#define MM_TURNS 4 -#else #define MM_TURNS 2 -#endif for (i = 0; i < MM_TURNS; i++) { - if (!tiled && i < 2) + if (!tiled && i == 0) continue; - if (i >= MM_TURNS/2) { + if (i >= 1) { /* For further allocations, disable tiling */ pI830->tiling = FALSE; pScrn->displayWidth = savedDisplayWidth; @@ -2395,26 +2363,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->allowPageFlip = FALSE; } -#ifdef XF86DRI_MM - if (i & 1) { - /* For this allocation, switch to a smaller DRI memory manager - * size. - */ - pI830->mmSize = I830_MM_MINPAGES * GTT_PAGE_SIZE / KB(1); - } else { - pI830->mmSize = savedMMSize; - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Attempting memory allocation with %s buffers and \n" - "\t %s DRI memory manager reservation:\n", - (i & 2) ? "untiled" : "tiled", - (i & 1) ? "small" : "large"); -#else - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Attempting memory allocation with %s buffers:\n", + "Attempting memory allocation with %s buffers.\n", (i & 1) ? "untiled" : "tiled"); -#endif if (i830_allocate_2d_memory(pScrn) && i830_allocate_3d_memory(pScrn)) @@ -2436,10 +2387,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (i == MM_TURNS) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Not enough video memory. Disabling DRI.\n"); -#ifdef XF86DRI_MM - pI830->mmSize = 0; -#endif - pI830->directRenderingDisabled = TRUE; + pI830->directRenderingEnabled = FALSE; } } #endif @@ -2461,7 +2409,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support DRI with frame buffer width > 2048.\n"); pI830->tiling = FALSE; - pI830->directRenderingDisabled = TRUE; + pI830->directRenderingEnabled = FALSE; } pScrn->displayWidth = pScrn->displayWidth; @@ -2562,11 +2510,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif #ifdef XF86DRI - /* - * pI830->directRenderingDisabled is set once in PreInit. Reinitialise - * pI830->directRenderingEnabled based on it each generation. - */ - pI830->directRenderingEnabled = !pI830->directRenderingDisabled; /* * Setup DRI after visuals have been established, but before fbScreenInit * is called. fbScreenInit will eventually call into the drivers @@ -2578,26 +2521,21 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DRI is disabled because it " "needs HW cursor, 2D accel and AGPGART.\n"); pI830->directRenderingEnabled = FALSE; - i830_free_3d_memory(pScrn); } } - driDisabled = !pI830->directRenderingEnabled; - if (pI830->directRenderingEnabled) - pI830->directRenderingEnabled = I830DRIScreenInit(pScreen); + pI830->directRenderingEnabled = I830DRIDoMappings(pScreen); - if (!pI830->directRenderingEnabled) { + /* If we failed for any reason, free DRI memory. */ + if (!pI830->directRenderingEnabled) i830_free_3d_memory(pScrn); - } #else pI830->directRenderingEnabled = FALSE; #endif #ifdef XF86DRI - if (pI830->directRenderingEnabled) - pI830->directRenderingEnabled = I830DRIDoMappings(pScreen); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page Flipping %sabled\n", pI830->allowPageFlip ? "en" : "dis"); @@ -2717,9 +2655,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif #ifdef XF86DRI - if (pI830->directRenderingEnabled) { + if (pI830->directRenderingEnabled) pI830->directRenderingEnabled = I830DRIFinishScreenInit(pScreen); - } #endif /* Setup 3D engine, needed for rotation too */ @@ -2730,7 +2667,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->directRenderingOpen = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Enabled\n"); } else { - if (driDisabled) + if (pI830->directRenderingDisabled) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Disabled\n"); else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Failed\n"); @@ -2771,37 +2708,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->closing = FALSE; pI830->suspended = FALSE; -#ifdef XF86DRI_MM - if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM)) - { - if (pI830->memory_manager == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Too little AGP aperture space for DRM memory manager.\n" - "\tPlease increase AGP aperture size from BIOS configuration screen.\n" - "\tDisabling DRI.\n"); - pI830->directRenderingOpen = FALSE; - I830DRICloseScreen(pScreen); - pI830->directRenderingEnabled = FALSE; - } else { - unsigned long aperEnd = ROUND_DOWN_TO(pI830->memory_manager->offset + - pI830->memory_manager->size, - GTT_PAGE_SIZE) / GTT_PAGE_SIZE; - unsigned long aperStart = ROUND_TO(pI830->memory_manager->offset, - GTT_PAGE_SIZE) / GTT_PAGE_SIZE; - - if (drmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart, - DRM_BO_MEM_TT)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Could not initialize the DRM memory manager.\n"); - - pI830->directRenderingOpen = FALSE; - I830DRICloseScreen(pScreen); - pI830->directRenderingEnabled = FALSE; - } - } - } -#endif /* XF86DRI_MM */ - return TRUE; } @@ -2862,7 +2768,7 @@ I830LeaveVT(int scrnIndex, int flags) if (pI830->directRenderingOpen) { DRILock(screenInfo.screens[pScrn->scrnIndex], 0); #ifdef XF86DRI_MM - if (pI830->mmModeFlags & I830_KERNEL_MM) { + if (pI830->memory_manager != NULL) { drmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT); } #endif /* XF86DRI_MM */ @@ -2967,7 +2873,7 @@ I830EnterVT(int scrnIndex, int flags) sarea->texList[i].age = sarea->texAge; #ifdef XF86DRI_MM - if (pI830->mmModeFlags & I830_KERNEL_MM) { + if (pI830->memory_manager != NULL) { drmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT); } #endif /* XF86DRI_MM */ @@ -3014,26 +2920,6 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) #endif pI830->closing = TRUE; -#ifdef XF86DRI - if (pI830->directRenderingOpen) { -#ifdef DAMAGE - if (pI830->pDamage) { - PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); - - DamageUnregister(&pPix->drawable, pI830->pDamage); - DamageDestroy(pI830->pDamage); - pI830->pDamage = NULL; - } -#endif -#ifdef XF86DRI_MM - if (pI830->mmModeFlags & I830_KERNEL_MM) { - drmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT); - } -#endif /* XF86DRI_MM */ - pI830->directRenderingOpen = FALSE; - I830DRICloseScreen(pScreen); - } -#endif if (pScrn->vtSema == TRUE) { I830LeaveVT(scrnIndex, 0); @@ -3068,7 +2954,22 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) #endif xf86_cursors_fini (pScreen); - i830_reset_allocations(pScrn); + i830_allocator_fini(pScrn); +#ifdef XF86DRI + if (pI830->directRenderingOpen) { +#ifdef DAMAGE + if (pI830->pDamage) { + PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); + + DamageUnregister(&pPix->drawable, pI830->pDamage); + DamageDestroy(pI830->pDamage); + pI830->pDamage = NULL; + } +#endif + pI830->directRenderingOpen = FALSE; + I830DRICloseScreen(pScreen); + } +#endif if (I830IsPrimary(pScrn)) { xf86GARTCloseScreen(scrnIndex); diff --git a/src/i830_memory.c b/src/i830_memory.c index b38a5dfe..d4e9bff0 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -114,6 +114,9 @@ enum tile_format { TILING_YMAJOR }; +static i830_memory * +i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, + long size, unsigned long alignment, int flags); static void i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, unsigned int pitch, unsigned int size, enum tile_format tile_format); @@ -182,10 +185,22 @@ i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem) { +#ifdef XF86DRI_MM + I830Ptr pI830 = I830PTR(pScrn); +#endif + if (mem == NULL) return; - /* Disconnect from the list of allocations */ +#ifdef XF86DRI_MM + if (mem->bo.size != 0) { + drmBOUnReference(pI830->drmSubFD, &mem->bo); + xfree(mem->name); + xfree(mem); + return; + } +#endif + /* Disconnect from the list of allocations */ if (mem->prev != NULL) mem->prev->next = mem->next; if (mem->next != NULL) @@ -237,7 +252,6 @@ i830_reset_allocations(ScrnInfoPtr pScrn) pI830->third_buffer = NULL; pI830->depth_buffer = NULL; pI830->textures = NULL; - pI830->memory_manager = NULL; #endif pI830->LpRing->mem = NULL; @@ -260,21 +274,24 @@ i830_free_3d_memory(ScrnInfoPtr pScrn) pI830->depth_buffer = NULL; i830_free_memory(pScrn, pI830->textures); pI830->textures = NULL; - i830_free_memory(pScrn, pI830->memory_manager); - pI830->memory_manager = NULL; #endif } /** * Initialize's the driver's video memory allocator to allocate in the * given range. + * + * This sets up the kernel memory manager to manage as much of the memory + * as we think it can, while leaving enough to us to fulfill our non-TTM + * static allocations. Some of these exist because of the need for physical + * addresses to reference. */ Bool -i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, - unsigned long size) +i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size) { I830Ptr pI830 = I830PTR(pScrn); i830_memory *start, *end; + int ret; start = xcalloc(1, sizeof(*start)); if (start == NULL) @@ -311,9 +328,82 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, pI830->memory_list = start; +#ifdef XF86DRI_MM + /* Now that we have our manager set up, initialize the kernel MM if + * possible, covering almost all of the aperture. + */ + if (pI830->directRenderingEnabled && pI830->drmMinor >= 7) { + int mmsize; + + /* Take over all of the graphics aperture minus enough to for + * physical-address allocations of cursor/overlay registers. + */ + mmsize = size; + if (!OVERLAY_NOPHYSICAL(pI830) && !IS_I965G(pI830)) { + mmsize -= ROUND_TO(OVERLAY_SIZE, GTT_PAGE_SIZE); + if (pI830->CursorNeedsPhysical) { + mmsize -= 2 * (ROUND_TO(HWCURSOR_SIZE, GTT_PAGE_SIZE) + + ROUND_TO(HWCURSOR_SIZE_ARGB, GTT_PAGE_SIZE)); + } + } + if (pI830->fb_compression) + mmsize -= MB(6); + /* Can't do TTM on stolen memory */ + mmsize -= pI830->stolen_size; + + /* Create the aperture allocation */ + pI830->memory_manager = + i830_allocate_aperture(pScrn, "DRI memory manager", + mmsize, GTT_PAGE_SIZE, + ALIGN_BOTH_ENDS | NEED_NON_STOLEN); + + if (pI830->memory_manager != NULL) { + /* Tell the kernel to manage it */ + ret = drmMMInit(pI830->drmSubFD, + pI830->memory_manager->offset / GTT_PAGE_SIZE, + pI830->memory_manager->size / GTT_PAGE_SIZE, + DRM_BO_MEM_TT); + if (ret != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to initialize kernel memory manager\n"); + i830_free_memory(pScrn, pI830->memory_manager); + pI830->memory_manager = NULL; + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate space for kernel memory manager\n"); + i830_free_memory(pScrn, pI830->memory_manager); + pI830->memory_manager = NULL; + } + } +#endif /* XF86DRI_MM */ + return TRUE; } +void +i830_allocator_fini(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + /* Free most of the allocations */ + i830_reset_allocations(pScrn); + +#ifdef XF86DRI_MM + /* The memory manager is more special */ + if (pI830->memory_manager) { + drmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT); + i830_free_memory(pScrn, pI830->memory_manager); + pI830->memory_manager = NULL; + } +#endif /* XF86DRI_MM */ + + /* Free the start/end markers */ + free(pI830->memory_list->next); + free(pI830->memory_list); + pI830->memory_list = NULL; +} + /** * Reads a GTT entry for the memory at the given offset and returns the * physical address. @@ -447,6 +537,9 @@ i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, mem->offset = ROUND_TO(pI830->stolen_size, alignment); } } + if ((flags & NEED_NON_STOLEN) && mem->offset < pI830->stolen_size) { + mem->offset = ROUND_TO(pI830->stolen_size, alignment); + } mem->end = mem->offset + size; if (flags & ALIGN_BOTH_ENDS) @@ -515,25 +608,80 @@ i830_allocate_agp_memory(ScrnInfoPtr pScrn, i830_memory *mem, int flags) return TRUE; } +#ifdef XF86DRI_MM +static i830_memory * +i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name, + unsigned long size, unsigned long align, int flags) +{ + I830Ptr pI830 = I830PTR(pScrn); + i830_memory *mem; + unsigned long hint, mask; + int ret; + + assert((flags & NEED_PHYSICAL_ADDR) == 0); + + /* Only allocate page-sized increments. */ + size = ALIGN(size, GTT_PAGE_SIZE); + align = ROUND_TO(align, GTT_PAGE_SIZE); + + mem = xcalloc(1, sizeof(*mem)); + if (mem == NULL) + return NULL; + + mem->name = xstrdup(name); + if (name == NULL) { + xfree(mem); + return NULL; + } + + mask = DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MAPPABLE | + DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE; + hint = DRM_BO_HINT_DONT_FENCE | DRM_BO_HINT_DONT_BLOCK | + DRM_BO_HINT_ALLOW_UNFENCED_MAP; + + I830DRILock(pScrn); + ret = drmBOCreate(pI830->drmSubFD, 0, size, align / GTT_PAGE_SIZE, NULL, + drm_bo_type_dc, mask, hint, &mem->bo); + I830DRIUnlock(pScrn); + if (ret) { + xfree(mem->name); + xfree(mem); + return NULL; + } + + mem->offset = mem->bo.offset; + mem->end = mem->bo.start + size; + mem->size = size; + + return mem; +} +#endif /* XF86DRI_MM */ /* Allocates video memory at the given size and alignment. * * The memory will be bound automatically when the driver is in control of the - * VT. + * VT. When the kernel memory manager is available and compatible with flags + * (that is, flags doesn't say that the allocation must include a physical + * address), that will be used for the allocation. */ static i830_memory * i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, unsigned long size, unsigned long alignment, int flags) { + I830Ptr pI830 = I830PTR(pScrn); i830_memory *mem; - mem = i830_allocate_aperture(pScrn, name, size, alignment, flags); - if (mem == NULL) - return NULL; + if (pI830->memory_manager && !(flags & NEED_PHYSICAL_ADDR)) { + return i830_allocate_memory_bo(pScrn, name, size, alignment, flags); + } else { + mem = i830_allocate_aperture(pScrn, name, size, alignment, flags); + if (mem == NULL) + return NULL; - if (!i830_allocate_agp_memory(pScrn, mem, flags)) { - i830_free_memory(pScrn, mem); - return NULL; + if (!i830_allocate_agp_memory(pScrn, mem, flags)) { + i830_free_memory(pScrn, mem); + return NULL; + } } return mem; @@ -588,7 +736,7 @@ i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name, aper_align = alignment; fence_divide = 1; - mem = i830_allocate_aperture(pScrn, name, aper_size, aper_align, flags); + mem = i830_allocate_memory(pScrn, name, aper_size, aper_align, flags); if (mem == NULL && !IS_I965G(pI830)) { /* For the older hardware with stricter fencing limits, if we * couldn't allocate with the large alignment, try relaxing the @@ -604,8 +752,8 @@ i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name, break; } - mem = i830_allocate_aperture(pScrn, name, aper_size, - aper_align / fence_divide, flags); + mem = i830_allocate_memory(pScrn, name, aper_size, + aper_align / fence_divide, flags); } } @@ -623,12 +771,6 @@ i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name, return NULL; } - /* Allocate any necessary AGP memory to back this allocation */ - if (!i830_allocate_agp_memory(pScrn, mem, flags)) { - i830_free_memory(pScrn, mem); - return NULL; - } - /* Set up the fence registers. */ for (i = 0; i < fence_divide; i++) { i830_set_fence(pScrn, pI830->next_fence++, @@ -1341,17 +1483,7 @@ i830_allocate_texture_memory(ScrnInfoPtr pScrn) unsigned long size; int i; - if (pI830->mmModeFlags & I830_KERNEL_MM) { - pI830->memory_manager = - i830_allocate_aperture(pScrn, "DRI memory manager", - pI830->mmSize * KB(1), GTT_PAGE_SIZE, - ALIGN_BOTH_ENDS); - /* XXX: try memory manager size backoff here? */ - if (pI830->memory_manager == NULL) - return FALSE; - } - - if (pI830->mmModeFlags & I830_KERNEL_TEX) { + if (pI830->allocate_classic_textures) { /* XXX: auto-sizing */ size = MB(32); i = myLog2(size / I830_NR_TEX_REGIONS); @@ -1368,7 +1500,7 @@ i830_allocate_texture_memory(ScrnInfoPtr pScrn) size / 1024); return FALSE; } - pI830->textures = i830_allocate_memory(pScrn, "textures", size, + pI830->textures = i830_allocate_memory(pScrn, "classic textures", size, GTT_PAGE_SIZE, 0); if (pI830->textures == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, From 1a585d03972394cb97dec2462937b0104bdf4de2 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 26 Jul 2007 10:46:35 -0700 Subject: [PATCH 02/26] Use new drmBOSetPin interface instead of NO_EVICT/NO_MOVE buffers. To do this, we have to deal with buffer offsets being set at EnterVT time instead of screen init time. We've wanted to move this direction for a long time, but there are repercussions. The EXA offscreen memory manager has to be disabled, because it can't be moved. That will be replaced by BO-backed pixmaps soon. Also unresolved is whether our moving front/back/depth/texture buffers will break the classic-mode DRI driver. This code doesn't actually work yet. --- src/i830.h | 8 +++- src/i830_driver.c | 28 +++++++++---- src/i830_exa.c | 9 ++++- src/i830_memory.c | 101 +++++++++++++++++++++++++++++++++++++++------- 4 files changed, 122 insertions(+), 24 deletions(-) diff --git a/src/i830.h b/src/i830.h index 6e1f88a2..14de7f0e 100644 --- a/src/i830.h +++ b/src/i830.h @@ -286,7 +286,13 @@ typedef struct _I830Rec { /* These are set in PreInit and never changed. */ long FbMapSize; - i830_memory *memory_list; /**< Linked list of video memory allocations */ + /** + * Linked list of video memory allocations. The head and tail are + * dummy entries that bound the allocation area. + */ + i830_memory *memory_list; + /** Linked list of buffer object memory allocations */ + i830_memory *bo_list; long stolen_size; /**< bytes of pre-bound stolen memory */ int gtt_acquired; /**< whether we currently own the AGP */ diff --git a/src/i830_driver.c b/src/i830_driver.c index 20c6c682..929a5410 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2403,8 +2403,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) I830UnmapMMIO(pScrn); - i830_describe_allocations(pScrn, 1, ""); - if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support DRI with frame buffer width > 2048.\n"); @@ -2632,6 +2630,14 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing SW Cursor!\n"); +#ifdef XF86DRI + /* Must be called before EnterVT, so we can acquire the DRI lock when + * binding our memory. + */ + if (pI830->directRenderingEnabled) + pI830->directRenderingEnabled = I830DRIFinishScreenInit(pScreen); +#endif + if (!I830EnterVT(scrnIndex, 0)) return FALSE; @@ -2654,11 +2660,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) I830InitVideo(pScreen); #endif -#ifdef XF86DRI - if (pI830->directRenderingEnabled) - pI830->directRenderingEnabled = I830DRIFinishScreenInit(pScreen); -#endif - /* Setup 3D engine, needed for rotation too */ IntelEmitInvarientState(pScrn); @@ -2802,6 +2803,7 @@ static Bool I830EnterVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + ScreenPtr pScreen = pScrn->pScreen; I830Ptr pI830 = I830PTR(pScrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); int o; @@ -2823,6 +2825,18 @@ I830EnterVT(int scrnIndex, int flags) if (!i830_bind_all_memory(pScrn)) return FALSE; + i830_describe_allocations(pScrn, 1, ""); + + /* Update buffer locations, which may have changed as a result of + * i830_bind_all_memory(). + */ + pScrn->fbOffset = pI830->front_buffer->offset; + if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen), + -1, -1, -1, -1, -1, + (pointer)(pI830->FbBase + + pScrn->fbOffset))) + FatalError("Couldn't adjust screen pixmap\n"); + if (i830_check_error_state(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Existing errors found in hardware state.\n"); diff --git a/src/i830_exa.c b/src/i830_exa.c index fed4067b..e801d50d 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -405,9 +405,14 @@ I830EXAInit(ScreenPtr pScreen) pI830->EXADriverPtr->exa_major = 2; pI830->EXADriverPtr->exa_minor = 1; pI830->EXADriverPtr->memoryBase = pI830->FbBase; - pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset; - pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset + + if (pI830->exa_offscreen) { + pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset; + pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset + pI830->exa_offscreen->size; + } else { + pI830->EXADriverPtr->offScreenBase = pI830->FbMapSize; + pI830->EXADriverPtr->memorySize = pI830->FbMapSize; + } pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS; DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n", diff --git a/src/i830_memory.c b/src/i830_memory.c index d4e9bff0..80e3536e 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -155,10 +155,25 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) { I830Ptr pI830 = I830PTR(pScrn); - if (mem == NULL || mem->key == -1 || mem->bound || !pI830->gtt_acquired) + if (mem == NULL || mem->bound || !pI830->gtt_acquired) return TRUE; - if (xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) { +#ifdef XF86DRI_MM + if (mem->bo.size != 0) { + int ret; + + ret = drmBOSetPin(pI830->drmSubFD, &mem->bo, 1); + mem->offset = mem->bo.offset; + mem->end = mem->offset + mem->size; + if (ret) + return FALSE; + else + return TRUE; + } +#endif + + if (mem->key == -1 || + xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) { mem->bound = TRUE; return TRUE; } else { @@ -171,10 +186,23 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) static Bool i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) { - if (mem == NULL || mem->key == -1 || !mem->bound) + if (mem == NULL || !mem->bound) return TRUE; - if (xf86UnbindGARTMemory(pScrn->scrnIndex, mem->key)) { +#ifdef XF86DRI_MM + if (mem->bo.size != 0) { + I830Ptr pI830 = I830PTR(pScrn); + int ret; + + ret = drmBOSetPin(pI830->drmSubFD, &mem->bo, 0); + if (ret) + return FALSE; + else + return TRUE; + } +#endif + + if (mem->key == -1 || xf86UnbindGARTMemory(pScrn->scrnIndex, mem->key)) { mem->bound = FALSE; return TRUE; } else { @@ -195,6 +223,12 @@ i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem) #ifdef XF86DRI_MM if (mem->bo.size != 0) { drmBOUnReference(pI830->drmSubFD, &mem->bo); + if (pI830->bo_list == mem) + pI830->bo_list = mem->next; + if (mem->next) + mem->next->prev = NULL; + if (mem->prev) + mem->prev->next = NULL; xfree(mem->name); xfree(mem); return; @@ -615,7 +649,7 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name, { I830Ptr pI830 = I830PTR(pScrn); i830_memory *mem; - unsigned long hint, mask; + unsigned long mask; int ret; assert((flags & NEED_PHYSICAL_ADDR) == 0); @@ -635,14 +669,10 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name, } mask = DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MAPPABLE | - DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE; - hint = DRM_BO_HINT_DONT_FENCE | DRM_BO_HINT_DONT_BLOCK | - DRM_BO_HINT_ALLOW_UNFENCED_MAP; + DRM_BO_FLAG_MEM_TT; - I830DRILock(pScrn); ret = drmBOCreate(pI830->drmSubFD, 0, size, align / GTT_PAGE_SIZE, NULL, - drm_bo_type_dc, mask, hint, &mem->bo); - I830DRIUnlock(pScrn); + drm_bo_type_dc, mask, 0, &mem->bo); if (ret) { xfree(mem->name); xfree(mem); @@ -653,6 +683,13 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name, mem->end = mem->bo.start + size; mem->size = size; + /* Insert new allocation into the list */ + mem->prev = NULL; + mem->next = pI830->bo_list; + if (pI830->bo_list != NULL) + pI830->bo_list->prev = mem; + pI830->bo_list = mem; + return mem; } #endif /* XF86DRI_MM */ @@ -711,6 +748,12 @@ i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name, if (tile_format == TILING_NONE) return i830_allocate_memory(pScrn, name, size, alignment, flags); + /* XXX: for now, refuse to tile with buffer object allocations, + * until we can move the set_fence (and failure recovery) into EnterVT. + */ + if (pI830->memory_manager != NULL) + return NULL; + /* Only allocate page-sized increments. */ size = ALIGN(size, GTT_PAGE_SIZE); @@ -811,7 +854,7 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) } xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sMemory allocation layout:\n", prefix); + "%sFixed memory allocation layout:\n", prefix); for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) { @@ -831,7 +874,7 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) } else { xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, "%s0x%08lx-0x%08lx: %s " - "(%ld kB, 0x%16llx physical)\n", + "(%ld kB, 0x%016llx physical)\n", prefix, mem->offset, mem->end - 1, mem->name, mem->size / 1024, mem->bus_addr); @@ -841,6 +884,25 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) "%s0x%08lx: end of aperture\n", prefix, pI830->FbMapSize); +#ifdef XF86DRI_MM + if (pI830->memory_manager) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sBO memory allocation layout:\n", prefix); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s0x%08lx: start of memory manager\n", + prefix, pI830->memory_manager->offset); + for (mem = pI830->bo_list; mem != NULL; mem = mem->next) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s0x%08lx-0x%08lx: %s (%ld kB)\n", prefix, + mem->offset, mem->end - 1, mem->name, + mem->size / 1024); + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s0x%08lx: end of memory manager\n", + prefix, pI830->memory_manager->end); + } +#endif /* XF86DRI_MM */ + if (pI830->front_buffer != NULL) { i830_describe_tiling(pScrn, verbosity, prefix, pI830->front_buffer, pI830->front_tiled); @@ -1305,7 +1367,12 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) #ifdef I830_USE_EXA if (pI830->useEXA) { - if (pI830->exa_offscreen == NULL) { + /* With the kernel memory manager, the exa offscreen allocation would + * change locations at EnterVT, which EXA is unprepared for. The + * performance of EXA offscreen memory management was low enough + * that just not using it is reasonable. + */ + if (pI830->exa_offscreen == NULL && pI830->memory_manager == NULL) { /* Default EXA to having 3 screens worth of offscreen memory space * (for pixmaps), plus a double-buffered, 1920x1088 video's worth. * @@ -1799,6 +1866,10 @@ i830_bind_all_memory(ScrnInfoPtr pScrn) FatalError("Couldn't bind memory for %s\n", mem->name); } } + for (mem = pI830->bo_list; mem != NULL; mem = mem->next) { + if (!i830_bind_memory(pScrn, mem)) + FatalError("Couldn't bind memory for BO %s\n", mem->name); + } } return TRUE; @@ -1821,6 +1892,8 @@ i830_unbind_all_memory(ScrnInfoPtr pScrn) { i830_unbind_memory(pScrn, mem); } + for (mem = pI830->bo_list; mem != NULL; mem = mem->next) + i830_unbind_memory(pScrn, mem); pI830->gtt_acquired = FALSE; From 2b1ec0f51479c1d7e5e62803c68feca29375519d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 27 Jul 2007 10:00:35 -0700 Subject: [PATCH 03/26] Use the dontMapFramebuffer option available with DRIINFO 5.4. If not available, AIGLX init will fail. While here, simplify DRIINFO tests since we refuse to init with a version queried less than the version we compiled against, anyway. --- src/i830_dri.c | 106 +++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 56 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index 0d511d22..0ffafca4 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -124,11 +124,20 @@ static void I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, static void I830DRITransitionTo2d(ScreenPtr pScreen); static void I830DRITransitionTo3d(ScreenPtr pScreen); -static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen); -static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen); #if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 || \ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1)) #define DRI_SUPPORTS_CLIP_NOTIFY 1 +#else +#define DRI_SUPPORTS_CLIP_NOTIFY 0 +static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen); +static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen); +#endif + +#if (DRIINFO_MAJOR_VERSION > 5 || \ + (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 4)) +#define DRI_DRIVER_FRAMEBUFFER_MAP 1 +#else +#define DRI_DRIVER_FRAMEBUFFER_MAP 0 #endif #ifdef DRI_SUPPORTS_CLIP_NOTIFY @@ -491,7 +500,8 @@ I830CheckDRIAvailable(ScrnInfoPtr pScrn) int major, minor, patch; DRIQueryVersion(&major, &minor, &patch); - if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) { + if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION || + major < 5) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] %s failed because of a version mismatch.\n" "[dri] libDRI version is %d.%d.%d but version %d.%d.x is needed.\n" @@ -546,12 +556,6 @@ I830DRIScreenInit(ScreenPtr pScreen) pDRIInfo->ddxDriverMajorVersion = I830_MAJOR_VERSION; pDRIInfo->ddxDriverMinorVersion = I830_MINOR_VERSION; pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL; - /* Supply a dummy mapping info required by DRI setup. See bug #5714 for - * progress on removing this requirement. - */ - pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr; - pDRIInfo->frameBufferSize = GTT_PAGE_SIZE; - pDRIInfo->frameBufferStride = 1; pDRIInfo->ddxDrawableTableEntry = I830_MAX_DRAWABLES; if (SAREA_MAX_DRAWABLES < I830_MAX_DRAWABLES) @@ -587,40 +591,38 @@ I830DRIScreenInit(ScreenPtr pScreen) pDRIInfo->MoveBuffers = I830DRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; - { -#if DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1 - int major, minor, patch; - - DRIQueryVersion(&major, &minor, &patch); - -#if DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3 - if (minor >= 3) -#endif #if DRIINFO_MAJOR_VERSION > 5 || \ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3) - pDRIInfo->texOffsetStart = I830TexOffsetStart; + pDRIInfo->texOffsetStart = I830TexOffsetStart; #endif -#if DRI_SUPPORTS_CLIP_NOTIFY && DRIINFO_MAJOR_VERSION == 5 - if (minor >= 1) -#endif #if DRI_SUPPORTS_CLIP_NOTIFY - pDRIInfo->ClipNotify = I830DRIClipNotify; + pDRIInfo->ClipNotify = I830DRIClipNotify; +#endif + +#if DRI_DRIVER_FRAMEBUFFER_MAP + /* DRI version is high enough that we can get the DRI code to not + * try to manage the framebuffer. + */ + pDRIInfo->frameBufferPhysicalAddress = 0; + pDRIInfo->frameBufferSize = 0; + pDRIInfo->frameBufferStride = 0; + pDRIInfo->dontMapFrameBuffer = TRUE; +#else + /* Supply a dummy mapping info required by DRI setup. + */ + pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr; + pDRIInfo->frameBufferSize = GTT_PAGE_SIZE; + pDRIInfo->frameBufferStride = 1; #endif -#endif /* DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1 */ - } pDRIInfo->TransitionTo2d = I830DRITransitionTo2d; pDRIInfo->TransitionTo3d = I830DRITransitionTo3d; -#if DRIINFO_MAJOR_VERSION > 5 || \ - (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1) - if (!pDRIInfo->ClipNotify) +#if !DRI_SUPPORTS_CLIP_NOTIFY + pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d; + pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d; #endif - { - pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d; - pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d; - } /* do driver-independent DRI screen initialization here */ if (!DRIScreenInit(pScreen, pDRIInfo, &pI830->drmSubFD)) { @@ -633,30 +635,14 @@ I830DRIScreenInit(ScreenPtr pScreen) return FALSE; } - /* Now, nuke dri.c's frontbuffer map setup. */ -#if 0 - if (xf86LoaderCheckSymbol("DRIGetScreenPrivate")) { - DRIScreenPrivPtr pDRIPriv = - (DRIScreenPrivPtr) DRIGetScreenPrivate(pScreen); - - if (pDRIPriv && pDRIPriv->drmFD && pDRIPriv->hFrameBuffer) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[intel] removing original screen mapping\n"); - drmRmMap(pDRIPriv->drmFD, pDRIPriv->hFrameBuffer); - pDRIPriv->hFrameBuffer = 0; - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[intel] done removing original screen mapping\n"); - } - } -#endif - { + /* Now, nuke dri.c's dummy frontbuffer map setup if we did that. */ + if (pDRIInfo->frameBufferSize != 0) { int tmp; unsigned int fb_handle; void *ptmp; /* With the compat method, it will continue to report - * the wrong map out of GetDeviceInfo, but we don't have any consumers - * of the frontbuffer handle from there. + * the wrong map out of GetDeviceInfo, which will break AIGLX. */ DRIGetDeviceInfo(pScreen, &fb_handle, &tmp, &tmp, &tmp, &tmp, &ptmp); drmRmMap(pI830->drmSubFD, fb_handle); @@ -763,11 +749,12 @@ I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea) { ScreenPtr pScreen = pScrn->pScreen; I830Ptr pI830 = I830PTR(pScrn); + drm_handle_t front_handle; -#if 1 /* Remove this soon - see bug 5714 */ - pI830->pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth * - pScrn->virtualY * pI830->cpp); -#endif + pI830->pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr; + pI830->pDRIInfo->frameBufferStride = pScrn->displayWidth * pI830->cpp; + pI830->pDRIInfo->frameBufferSize = + ROUND_TO_PAGE(pI830->pDRIInfo->frameBufferStride * pScrn->virtualY); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Mapping front buffer\n"); @@ -776,12 +763,17 @@ I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea) sarea->front_size, DRM_AGP, 0, - (drmAddress) &sarea->front_handle) < 0) { + &front_handle) < 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); DRICloseScreen(pScreen); return FALSE; } + sarea->front_handle = front_handle; +#if DRI_DRIVER_FRAMEBUFFER_MAP + pI830->pDRIInfo->hFrameBuffer = front_handle; +#endif + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Front Buffer = 0x%08x\n", (int)sarea->front_handle); @@ -1530,6 +1522,7 @@ I830DRISetPfMask(ScreenPtr pScreen, int pfMask) pSAREAPriv->pf_active = 0; } +#if !DRI_SUPPORTS_CLIP_NOTIFY static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen) { @@ -1550,6 +1543,7 @@ I830DRITransitionMultiToSingle3d(ScreenPtr pScreen) */ I830DRISetPfMask(pScreen, pI830->allowPageFlip ? 0x3 : 0); } +#endif /* !DRI_SUPPORTS_CLIP_NOTIFY */ static void I830DRITransitionTo3d(ScreenPtr pScreen) From d7b5b595ad29ae0ac3adbd3a176be3fe7ffa6474 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 27 Jul 2007 12:48:08 -0700 Subject: [PATCH 04/26] Delay the first screen pixmap update to CreateScreenResources. The return value of GetScreenPixmap before CreateScreenResources is not, in fact, a pixmap. --- src/i830_driver.c | 57 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 929a5410..676b4cb9 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -712,6 +712,50 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, } } +static void +i830UpdateFrontOffset(ScrnInfoPtr pScrn) +{ + ScreenPtr pScreen = pScrn->pScreen; + I830Ptr pI830 = I830PTR(pScrn); + + /* If we are still in ScreenInit, there is no screen pixmap to be updated + * yet. We'll fix it up at CreateScreenResources. + */ + if (pI830->starting) + return; + + /* Update buffer locations, which may have changed as a result of + * i830_bind_all_memory(). + */ + pScrn->fbOffset = pI830->front_buffer->offset; + if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen), + -1, -1, -1, -1, -1, + (pointer)(pI830->FbBase + + pScrn->fbOffset))) + FatalError("Couldn't adjust screen pixmap\n"); +} + +/** + * Adjust the screen pixmap for the current location of the front buffer. + * This is done at EnterVT when buffers are bound as long as the resources + * have already been created, but the first EnterVT happens before + * CreateScreenResources. + */ +static Bool +i830CreateScreenResources(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + + pScreen->CreateScreenResources = pI830->CreateScreenResources; + if (!(*pScreen->CreateScreenResources)(pScreen)) + return FALSE; + + i830UpdateFrontOffset(pScrn); + + return TRUE; +} + int i830_output_clones (ScrnInfoPtr pScrn, int type_mask) { @@ -2680,6 +2724,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScreen->SaveScreen = xf86SaveScreen; pI830->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = I830CloseScreen; + pI830->CreateScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = i830CreateScreenResources; if (!xf86CrtcScreenInit (pScreen)) return FALSE; @@ -2803,7 +2849,6 @@ static Bool I830EnterVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - ScreenPtr pScreen = pScrn->pScreen; I830Ptr pI830 = I830PTR(pScrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); int o; @@ -2827,15 +2872,7 @@ I830EnterVT(int scrnIndex, int flags) i830_describe_allocations(pScrn, 1, ""); - /* Update buffer locations, which may have changed as a result of - * i830_bind_all_memory(). - */ - pScrn->fbOffset = pI830->front_buffer->offset; - if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen), - -1, -1, -1, -1, -1, - (pointer)(pI830->FbBase + - pScrn->fbOffset))) - FatalError("Couldn't adjust screen pixmap\n"); + i830UpdateFrontOffset(pScrn); if (i830_check_error_state(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, From 857b4a7bcb69ca43b866b4283fe075abbafb1d22 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 27 Jul 2007 18:03:12 -0700 Subject: [PATCH 05/26] Pin some buffer objects at creation time, which can't be moved yet. A number of other interfaces of ours don't allow buffer offsets to be updated after screeninit. This attempts to catalog why for each one, so that they can be fixed one by one. This happens to restore the EXA offscreen allocator for now, as a fixed-offset object. --- src/i830.h | 2 + src/i830_driver.c | 9 ++ src/i830_memory.c | 210 +++++++++++++++++++++++++++++++++------------- 3 files changed, 161 insertions(+), 60 deletions(-) diff --git a/src/i830.h b/src/i830.h index 14de7f0e..730d6bcc 100644 --- a/src/i830.h +++ b/src/i830.h @@ -160,6 +160,7 @@ struct _i830_memory { #ifdef XF86DRI_MM drmBO bo; + Bool lifetime_fixed_offset; #endif }; @@ -754,6 +755,7 @@ extern const int I830CopyROP[16]; #define NEED_PHYSICAL_ADDR 0x00000001 #define ALIGN_BOTH_ENDS 0x00000002 #define NEED_NON_STOLEN 0x00000004 +#define NEED_LIFETIME_FIXED 0x00000008 /* Chipset registers for VIDEO BIOS memory RW access */ #define _855_DRAM_RW_CONTROL 0x58 diff --git a/src/i830_driver.c b/src/i830_driver.c index 676b4cb9..c86840a1 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -712,6 +712,10 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, } } +#if 0 +/* This code ended up unused, but will be at least a reference when we let the + * front buffer move. + */ static void i830UpdateFrontOffset(ScrnInfoPtr pScrn) { @@ -755,6 +759,7 @@ i830CreateScreenResources(ScreenPtr pScreen) return TRUE; } +#endif int i830_output_clones (ScrnInfoPtr pScrn, int type_mask) @@ -2724,8 +2729,10 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScreen->SaveScreen = xf86SaveScreen; pI830->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = I830CloseScreen; +#if 0 pI830->CreateScreenResources = pScreen->CreateScreenResources; pScreen->CreateScreenResources = i830CreateScreenResources; +#endif if (!xf86CrtcScreenInit (pScreen)) return FALSE; @@ -2872,7 +2879,9 @@ I830EnterVT(int scrnIndex, int flags) i830_describe_allocations(pScrn, 1, ""); +#if 0 i830UpdateFrontOffset(pScrn); +#endif if (i830_check_error_state(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, diff --git a/src/i830_memory.c b/src/i830_memory.c index 80e3536e..e4d5d3da 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -108,6 +108,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) +/* Our hardware status area is just a single page */ +#define HWSTATUS_PAGE_SIZE GTT_PAGE_SIZE + enum tile_format { TILING_NONE, TILING_XMAJOR, @@ -155,23 +158,29 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) { I830Ptr pI830 = I830PTR(pScrn); - if (mem == NULL || mem->bound || !pI830->gtt_acquired) + if (mem == NULL || mem->bound) return TRUE; #ifdef XF86DRI_MM if (mem->bo.size != 0) { + I830Ptr pI830 = I830PTR(pScrn); int ret; ret = drmBOSetPin(pI830->drmSubFD, &mem->bo, 1); - mem->offset = mem->bo.offset; - mem->end = mem->offset + mem->size; - if (ret) - return FALSE; - else + if (ret == 0) { + mem->bound = TRUE; + mem->offset = mem->bo.offset; + mem->end = mem->bo.offset + mem->size; return TRUE; + } else { + return FALSE; + } } #endif + if (!pI830->gtt_acquired) + return TRUE; + if (mem->key == -1 || xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) { mem->bound = TRUE; @@ -195,10 +204,15 @@ i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) int ret; ret = drmBOSetPin(pI830->drmSubFD, &mem->bo, 0); - if (ret) - return FALSE; - else + if (ret == 0) { + mem->bound = FALSE; + /* Give buffer obviously wrong offset/end until it's re-pinned. */ + mem->offset = -1; + mem->end = -1; return TRUE; + } else { + return FALSE; + } } #endif @@ -213,15 +227,16 @@ i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem) { -#ifdef XF86DRI_MM - I830Ptr pI830 = I830PTR(pScrn); -#endif - if (mem == NULL) return; + /* Free any AGP memory. */ + i830_unbind_memory(pScrn, mem); + #ifdef XF86DRI_MM if (mem->bo.size != 0) { + I830Ptr pI830 = I830PTR(pScrn); + drmBOUnReference(pI830->drmSubFD, &mem->bo); if (pI830->bo_list == mem) pI830->bo_list = mem->next; @@ -240,9 +255,6 @@ i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem) if (mem->next != NULL) mem->next->prev = mem->prev; - /* Free any AGP memory. */ - i830_unbind_memory(pScrn, mem); - if (mem->key != -1) { xf86DeallocateGARTMemory(pScrn->scrnIndex, mem->key); mem->key = -1; @@ -326,6 +338,9 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size) I830Ptr pI830 = I830PTR(pScrn); i830_memory *start, *end; int ret; +#ifdef XF86DRI_MM + int dri_major, dri_minor, dri_patch; +#endif start = xcalloc(1, sizeof(*start)); if (start == NULL) @@ -363,16 +378,23 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size) pI830->memory_list = start; #ifdef XF86DRI_MM + DRIQueryVersion(&dri_major, &dri_minor, &dri_patch); + /* Now that we have our manager set up, initialize the kernel MM if - * possible, covering almost all of the aperture. + * possible, covering almost all of the aperture. We need libdri interface + * 5.4 or newer so we can rely on the lock being held after DRIScreenInit, + * rather than after DRIFinishScreenInit. */ - if (pI830->directRenderingEnabled && pI830->drmMinor >= 7) { + if (pI830->directRenderingEnabled && pI830->drmMinor >= 7 && + (dri_major > 5 || (dri_major == 5 && dri_minor >= 4))) + { int mmsize; /* Take over all of the graphics aperture minus enough to for * physical-address allocations of cursor/overlay registers. */ mmsize = size; + /* Overlay is always set up as fixed, currently. */ if (!OVERLAY_NOPHYSICAL(pI830) && !IS_I965G(pI830)) { mmsize -= ROUND_TO(OVERLAY_SIZE, GTT_PAGE_SIZE); if (pI830->CursorNeedsPhysical) { @@ -678,10 +700,19 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name, xfree(mem); return NULL; } - - mem->offset = mem->bo.offset; - mem->end = mem->bo.start + size; + /* Give buffer obviously wrong offset/end until it's pinned. */ + mem->offset = -1; + mem->end = -1; mem->size = size; + if (flags & NEED_LIFETIME_FIXED) { + if (!i830_bind_memory(pScrn, mem)) { + drmBOUnReference(pI830->drmSubFD, &mem->bo); + xfree(mem->name); + xfree(mem); + return NULL; + } + mem->lifetime_fixed_offset = TRUE; + } /* Insert new allocation into the list */ mem->prev = NULL; @@ -700,6 +731,17 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name, * VT. When the kernel memory manager is available and compatible with flags * (that is, flags doesn't say that the allocation must include a physical * address), that will be used for the allocation. + * + * flags: + * - NEED_PHYSICAL_ADDR: Allocates the memory physically contiguous, and return + * the bus address for that memory. + * - ALIGN_BOTH_ENDS: after choosing the alignment, align the end offset to + * @alignment as well. + * - NEED_NON-STOLEN: don't allow any part of the memory allocation to lie + * within stolen memory + * - NEED_LIFETIME_FIXED: don't allow the buffer object to move throughout + * the entire Screen lifetime. This means not using buffer objects, which + * get their offsets chosen at each EnterVT time. */ static i830_memory * i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, @@ -748,10 +790,10 @@ i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name, if (tile_format == TILING_NONE) return i830_allocate_memory(pScrn, name, size, alignment, flags); - /* XXX: for now, refuse to tile with buffer object allocations, - * until we can move the set_fence (and failure recovery) into EnterVT. + /* XXX: for now, refuse to tile with movable buffer object allocations, + * until we can move the set_fence (and failure recovery) into bind time. */ - if (pI830->memory_manager != NULL) + if (pI830->memory_manager != NULL && !(flags & NEED_LIFETIME_FIXED)) return NULL; /* Only allocate page-sized increments. */ @@ -892,10 +934,16 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) "%s0x%08lx: start of memory manager\n", prefix, pI830->memory_manager->offset); for (mem = pI830->bo_list; mem != NULL; mem = mem->next) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s0x%08lx-0x%08lx: %s (%ld kB)\n", prefix, - mem->offset, mem->end - 1, mem->name, - mem->size / 1024); + if (mem->bound) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s0x%08lx-0x%08lx: %s (%ld kB)\n", prefix, + mem->offset, mem->end - 1, mem->name, + mem->size / 1024); + } else { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sunpinned : %s (%ld kB)\n", prefix, + mem->name, mem->size / 1024); + } } xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, "%s0x%08lx: end of memory manager\n", @@ -931,9 +979,13 @@ i830_allocate_ringbuffer(ScrnInfoPtr pScrn) if (pI830->noAccel || pI830->LpRing->mem != NULL) return TRUE; + /* We don't have any mechanism in the DRM yet to alert it that we've moved + * the ringbuffer since init time, so allocate it fixed for its lifetime. + */ pI830->LpRing->mem = i830_allocate_memory(pScrn, "ring buffer", PRIMARY_RINGBUFFER_SIZE, - GTT_PAGE_SIZE, 0); + GTT_PAGE_SIZE, + NEED_LIFETIME_FIXED); if (pI830->LpRing->mem == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate Ring Buffer space\n"); @@ -953,7 +1005,7 @@ static Bool i830_allocate_overlay(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - int flags = NEED_PHYSICAL_ADDR; + int flags = NEED_PHYSICAL_ADDR | NEED_LIFETIME_FIXED; /* Only allocate if overlay is going to be enabled. */ if (!pI830->XvEnabled) @@ -963,6 +1015,10 @@ i830_allocate_overlay(ScrnInfoPtr pScrn) flags = 0; if (!IS_I965G(pI830)) { + /* XXX: The lifetime fixed offset for overlay register is bogus, and we + * should just tell i830_video.c about the new location at EnterVT + * time. + */ pI830->overlay_regs = i830_allocate_memory(pScrn, "overlay registers", OVERLAY_SIZE, GTT_PAGE_SIZE, flags); @@ -1030,7 +1086,7 @@ IsTileable(ScrnInfoPtr pScrn, int pitch) */ static i830_memory * i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, - Bool secondary, int flags) + Bool secondary) { unsigned int pitch = pScrn->displayWidth * pI830->cpp; unsigned long minspace, avail; @@ -1038,8 +1094,15 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, int align; long size, fb_height; char *name; + int flags; i830_memory *front_buffer = NULL; + /* The front buffer is currently marked as NEED_LIFETIME_FIXED because + * DRIDoMappings is the only caller of the rm/add map functions, + * and it's only called at startup. This should be easily fixable. + */ + flags = NEED_LIFETIME_FIXED; + /* Clear everything first. */ memset(FbMemBox, 0, sizeof(*FbMemBox)); @@ -1107,7 +1170,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, name = secondary ? "secondary front buffer" : "front buffer"; - /* Attempt to allocate it tiled first if we have page flipping on. */ + /* Attempt to allocate it tiled first if possible. */ if (pI830->tiling && IsTileable(pScrn, pitch)) { /* XXX: probably not the case on 965 */ if (IS_I9XX(pI830)) @@ -1116,7 +1179,8 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, align = KB(512); front_buffer = i830_allocate_memory_tiled(pScrn, name, size, pitch, align, - 0, TILING_XMAJOR); + flags, + TILING_XMAJOR); pI830->front_tiled = FENCE_XMAJOR; } @@ -1149,7 +1213,7 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) /* Try to allocate one big blob for our cursor memory. This works * around a limitation in the FreeBSD AGP driver that allows only one - * physical allocation larger than a page, and could allos us + * physical allocation larger than a page, and could allow us * to pack the cursors smaller. */ size = xf86_config->num_crtc * (HWCURSOR_SIZE + HWCURSOR_SIZE_ARGB); @@ -1356,23 +1420,18 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) pI830->front_buffer_2 = i830_allocate_framebuffer(pI830Ent->pScrn_2, pI8302, - &pI830->FbMemBox2, TRUE, 0); + &pI830->FbMemBox2, TRUE); if (pI830->front_buffer_2 == NULL) return FALSE; } pI830->front_buffer = - i830_allocate_framebuffer(pScrn, pI830, &pI830->FbMemBox, FALSE, 0); + i830_allocate_framebuffer(pScrn, pI830, &pI830->FbMemBox, FALSE); if (pI830->front_buffer == NULL) return FALSE; #ifdef I830_USE_EXA if (pI830->useEXA) { - /* With the kernel memory manager, the exa offscreen allocation would - * change locations at EnterVT, which EXA is unprepared for. The - * performance of EXA offscreen memory management was low enough - * that just not using it is reasonable. - */ - if (pI830->exa_offscreen == NULL && pI830->memory_manager == NULL) { + if (pI830->exa_offscreen == NULL) { /* Default EXA to having 3 screens worth of offscreen memory space * (for pixmaps), plus a double-buffered, 1920x1088 video's worth. * @@ -1384,8 +1443,13 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) size += 1920 * 1088 * 2 * 2; size = ROUND_TO_PAGE(size); - pI830->exa_offscreen = i830_allocate_memory(pScrn, "exa offscreen", - size, 1, 0); + /* EXA has no way to tell it that the offscreen memory manager has + * moved its base and all the contents with it, so we have to have + * it locked in place for the whole driver instance. + */ + pI830->exa_offscreen = + i830_allocate_memory(pScrn, "exa offscreen", + size, 1, NEED_LIFETIME_FIXED); if (pI830->exa_offscreen == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate EXA offscreen memory."); @@ -1396,14 +1460,18 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) #endif /* I830_USE_EXA */ if (!pI830->noAccel && !pI830->useEXA) { + /* The lifetime fixed offset of xaa scratch is probably not required, + * but we do some setup using it at XAAInit() time. And XAA may not + * end up being supported with TTM anyway. + */ pI830->xaa_scratch = i830_allocate_memory(pScrn, "xaa scratch", MAX_SCRATCH_BUFFER_SIZE, - GTT_PAGE_SIZE, 0); + GTT_PAGE_SIZE, NEED_LIFETIME_FIXED); if (pI830->xaa_scratch == NULL) { pI830->xaa_scratch = i830_allocate_memory(pScrn, "xaa scratch", MIN_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE, - 0); + NEED_LIFETIME_FIXED); if (pI830->xaa_scratch == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate scratch buffer space\n"); @@ -1418,12 +1486,12 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) pI830->xaa_scratch_2 = i830_allocate_memory(pScrn, "xaa scratch 2", MAX_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE, - 0); + NEED_LIFETIME_FIXED); if (pI830->xaa_scratch_2 == NULL) { pI830->xaa_scratch_2 = i830_allocate_memory(pScrn, "xaa scratch 2", MIN_SCRATCH_BUFFER_SIZE, - GTT_PAGE_SIZE, 0); + GTT_PAGE_SIZE, NEED_LIFETIME_FIXED); if (pI830->xaa_scratch_2 == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate secondary scratch " @@ -1470,15 +1538,18 @@ i830_allocate_backbuffer(ScrnInfoPtr pScrn, i830_memory **buffer, size = ROUND_TO_PAGE(pitch * ALIGN(height, 16)); *buffer = i830_allocate_memory_tiled(pScrn, name, size, pitch, GTT_PAGE_SIZE, ALIGN_BOTH_ENDS, - TILING_XMAJOR); + TILING_XMAJOR | + NEED_LIFETIME_FIXED); *tiled = FENCE_XMAJOR; } - /* Otherwise, just allocate it linear */ + /* Otherwise, just allocate it linear. The offset must stay constant + * currently because we don't ever update the DRI maps after screen init. + */ if (*buffer == NULL) { size = ROUND_TO_PAGE(pitch * height); *buffer = i830_allocate_memory(pScrn, name, size, GTT_PAGE_SIZE, - ALIGN_BOTH_ENDS); + ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED); *tiled = FENCE_LINEAR; } @@ -1519,18 +1590,21 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn) pI830->depth_buffer = i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch, - GTT_PAGE_SIZE, ALIGN_BOTH_ENDS, + GTT_PAGE_SIZE, + ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED, tile_format); pI830->depth_tiled = (tile_format == TILING_YMAJOR) ? FENCE_YMAJOR : FENCE_XMAJOR; } - /* Otherwise, allocate it linear. */ + /* Otherwise, allocate it linear. The offset must stay constant + * currently because we don't ever update the DRI maps after screen init. + */ if (pI830->depth_buffer == NULL) { size = ROUND_TO_PAGE(pitch * height); pI830->depth_buffer = i830_allocate_memory(pScrn, "depth buffer", size, GTT_PAGE_SIZE, - 0); + NEED_LIFETIME_FIXED); pI830->depth_tiled = FENCE_LINEAR; } @@ -1567,8 +1641,12 @@ i830_allocate_texture_memory(ScrnInfoPtr pScrn) size / 1024); return FALSE; } + /* The offset must stay constant currently because we don't ever update + * the DRI maps after screen init. + */ pI830->textures = i830_allocate_memory(pScrn, "classic textures", size, - GTT_PAGE_SIZE, 0); + GTT_PAGE_SIZE, + NEED_LIFETIME_FIXED); if (pI830->textures == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate texture space.\n"); @@ -1582,11 +1660,14 @@ i830_allocate_texture_memory(ScrnInfoPtr pScrn) static Bool i830_allocate_hwstatus(ScrnInfoPtr pScrn) { -#define HWSTATUS_PAGE_SIZE (4*1024) I830Ptr pI830 = I830PTR(pScrn); + /* The current DRM will leak the HWS mapping if we update the address + * after init (at best), so allocate it fixed for its lifetime + * (i.e. not through buffer objects). + */ pI830->hw_status = i830_allocate_memory(pScrn, "G33 hw status", - HWSTATUS_PAGE_SIZE, GTT_PAGE_SIZE, 0); + HWSTATUS_PAGE_SIZE, GTT_PAGE_SIZE, NEED_LIFETIME_FIXED); if (pI830->hw_status == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate hw status page for G33.\n"); @@ -1866,10 +1947,12 @@ i830_bind_all_memory(ScrnInfoPtr pScrn) FatalError("Couldn't bind memory for %s\n", mem->name); } } +#ifdef XF86DRI_MM for (mem = pI830->bo_list; mem != NULL; mem = mem->next) { - if (!i830_bind_memory(pScrn, mem)) + if (!mem->lifetime_fixed_offset && !i830_bind_memory(pScrn, mem)) FatalError("Couldn't bind memory for BO %s\n", mem->name); } +#endif } return TRUE; @@ -1892,8 +1975,15 @@ i830_unbind_all_memory(ScrnInfoPtr pScrn) { i830_unbind_memory(pScrn, mem); } - for (mem = pI830->bo_list; mem != NULL; mem = mem->next) - i830_unbind_memory(pScrn, mem); +#ifdef XF86DRI_MM + for (mem = pI830->bo_list; mem != NULL; mem = mem->next) { + /* Don't unpin objects which require that their offsets never + * change. + */ + if (!mem->lifetime_fixed_offset) + i830_unbind_memory(pScrn, mem); + } +#endif pI830->gtt_acquired = FALSE; From 79d9a309b19e22561e000a47b732c67479c2e6d4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 2 Aug 2007 15:50:42 -0700 Subject: [PATCH 06/26] Mark DRI buffers as shareable, and pass their buffer handles through the SAREA. --- src/i830.h | 1 + src/i830_common.h | 9 +++++++++ src/i830_dri.c | 16 ++++++++++++++++ src/i830_dri.h | 2 +- src/i830_memory.c | 23 ++++++++++++++++------- 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/i830.h b/src/i830.h index 730d6bcc..ccbae4fe 100644 --- a/src/i830.h +++ b/src/i830.h @@ -756,6 +756,7 @@ extern const int I830CopyROP[16]; #define ALIGN_BOTH_ENDS 0x00000002 #define NEED_NON_STOLEN 0x00000004 #define NEED_LIFETIME_FIXED 0x00000008 +#define ALLOW_SHARING 0x00000010 /* Chipset registers for VIDEO BIOS memory RW access */ #define _855_DRAM_RW_CONTROL 0x58 diff --git a/src/i830_common.h b/src/i830_common.h index 9c8616cd..1ca26422 100644 --- a/src/i830_common.h +++ b/src/i830_common.h @@ -138,6 +138,15 @@ typedef struct { int third_offset; int third_size; unsigned int third_tiled; + + /* buffer object handles for the static buffers. May change + * over the lifetime of the client, though it doesn't in our current + * implementation. + */ + unsigned int front_bo_handle; + unsigned int back_bo_handle; + unsigned int third_bo_handle; + unsigned int depth_bo_handle; } drmI830Sarea; /* Flags for perf_boxes diff --git a/src/i830_dri.c b/src/i830_dri.c index 0ffafca4..f97edd77 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -1664,6 +1664,7 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) sarea->third_offset = 0; sarea->third_size = 0; } + sarea->depth_offset = pI830->depth_buffer->offset; sarea->depth_size = pI830->depth_buffer->size; if (pI830->textures != NULL) { @@ -1678,6 +1679,21 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) sarea->virtualX = pScrn->virtualX; sarea->virtualY = pScrn->virtualY; + sarea->front_bo_handle = -1; + sarea->back_bo_handle = -1; + sarea->third_bo_handle = -1; + sarea->depth_bo_handle = -1; +#ifdef XF86DRI_MM + if (pI830->front_buffer->bo.size) + sarea->front_bo_handle = pI830->front_buffer->bo.handle; + if (pI830->back_buffer->bo.size) + sarea->back_bo_handle = pI830->back_buffer->bo.handle; + if (pI830->third_buffer != NULL && pI830->third_buffer->bo.size) + sarea->third_bo_handle = pI830->third_buffer->bo.handle; + if (pI830->depth_buffer->bo.size) + sarea->depth_bo_handle = pI830->depth_buffer->bo.handle; +#endif + /* The rotation is now handled entirely by the X Server, so just leave the * DRI unaware. */ diff --git a/src/i830_dri.h b/src/i830_dri.h index a2cf78ec..b6a83662 100644 --- a/src/i830_dri.h +++ b/src/i830_dri.h @@ -9,7 +9,7 @@ #define I830_MAX_DRAWABLES 256 #define I830_MAJOR_VERSION 1 -#define I830_MINOR_VERSION 8 +#define I830_MINOR_VERSION 9 #define I830_PATCHLEVEL 0 #define I830_REG_SIZE 0x80000 diff --git a/src/i830_memory.c b/src/i830_memory.c index e4d5d3da..96a4d67f 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -692,6 +692,8 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name, mask = DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MAPPABLE | DRM_BO_FLAG_MEM_TT; + if (flags & ALLOW_SHARING) + mask |= DRM_BO_FLAG_SHAREABLE; ret = drmBOCreate(pI830->drmSubFD, 0, size, align / GTT_PAGE_SIZE, NULL, drm_bo_type_dc, mask, 0, &mem->bo); @@ -1101,7 +1103,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, * DRIDoMappings is the only caller of the rm/add map functions, * and it's only called at startup. This should be easily fixable. */ - flags = NEED_LIFETIME_FIXED; + flags = NEED_LIFETIME_FIXED | ALLOW_SHARING; /* Clear everything first. */ memset(FbMemBox, 0, sizeof(*FbMemBox)); @@ -1537,9 +1539,11 @@ i830_allocate_backbuffer(ScrnInfoPtr pScrn, i830_memory **buffer, { size = ROUND_TO_PAGE(pitch * ALIGN(height, 16)); *buffer = i830_allocate_memory_tiled(pScrn, name, size, pitch, - GTT_PAGE_SIZE, ALIGN_BOTH_ENDS, - TILING_XMAJOR | - NEED_LIFETIME_FIXED); + GTT_PAGE_SIZE, + ALIGN_BOTH_ENDS | + NEED_LIFETIME_FIXED | + ALLOW_SHARING, + TILING_XMAJOR); *tiled = FENCE_XMAJOR; } @@ -1549,7 +1553,9 @@ i830_allocate_backbuffer(ScrnInfoPtr pScrn, i830_memory **buffer, if (*buffer == NULL) { size = ROUND_TO_PAGE(pitch * height); *buffer = i830_allocate_memory(pScrn, name, size, GTT_PAGE_SIZE, - ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED); + ALIGN_BOTH_ENDS | + NEED_LIFETIME_FIXED | + ALLOW_SHARING); *tiled = FENCE_LINEAR; } @@ -1591,7 +1597,9 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn) pI830->depth_buffer = i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch, GTT_PAGE_SIZE, - ALIGN_BOTH_ENDS | NEED_LIFETIME_FIXED, + ALIGN_BOTH_ENDS | + NEED_LIFETIME_FIXED | + ALLOW_SHARING, tile_format); pI830->depth_tiled = (tile_format == TILING_YMAJOR) ? FENCE_YMAJOR : FENCE_XMAJOR; @@ -1604,7 +1612,7 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn) size = ROUND_TO_PAGE(pitch * height); pI830->depth_buffer = i830_allocate_memory(pScrn, "depth buffer", size, GTT_PAGE_SIZE, - NEED_LIFETIME_FIXED); + ALLOW_SHARING | NEED_LIFETIME_FIXED); pI830->depth_tiled = FENCE_LINEAR; } @@ -1646,6 +1654,7 @@ i830_allocate_texture_memory(ScrnInfoPtr pScrn) */ pI830->textures = i830_allocate_memory(pScrn, "classic textures", size, GTT_PAGE_SIZE, + ALLOW_SHARING | NEED_LIFETIME_FIXED); if (pI830->textures == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, From c3438356d6b7b63ad9d0086efb084be8e048980e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 16 Aug 2007 11:34:02 -0700 Subject: [PATCH 07/26] Add tiling information to BO layout description. --- src/i830_memory.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index 23288588..902ca2dd 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -926,15 +926,22 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) "%s0x%08lx: start of memory manager\n", prefix, pI830->memory_manager->offset); for (mem = pI830->bo_list; mem != NULL; mem = mem->next) { + char *tile_suffix = ""; + + if (mem->tiling == TILE_XMAJOR) + tile_suffix = " X tiled"; + else if (mem->tiling == TILE_YMAJOR) + tile_suffix = " Y tiled"; + if (mem->bound) { xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s0x%08lx-0x%08lx: %s (%ld kB)\n", prefix, + "%s0x%08lx-0x%08lx: %s (%ld kB)%s\n", prefix, mem->offset, mem->end - 1, mem->name, - mem->size / 1024); + mem->size / 1024, tile_suffix); } else { xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sunpinned : %s (%ld kB)\n", prefix, - mem->name, mem->size / 1024); + "%sunpinned : %s (%ld kB)%s\n", prefix, + mem->name, mem->size / 1024, tile_suffix); } } xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, From b73235f40497cfb10792ba191d4f6eac3a5df009 Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Thu, 20 Sep 2007 11:28:52 +0800 Subject: [PATCH 08/26] Fix pixmap offset Use consistent interface for counting pixmap offset. --- src/i830_exa.c | 4 +--- src/i830_video.c | 7 ++++--- src/i915_video.c | 4 ++-- src/i965_video.c | 5 ++--- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/i830_exa.c b/src/i830_exa.c index 273c6260..88503829 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -112,9 +112,7 @@ i830_pixmap_tiled(PixmapPtr pPixmap) I830Ptr pI830 = I830PTR(pScrn); unsigned long offset; - /* Don't use exaGetPixmapOffset becuase we might be called from XAA code. */ - offset = (long)pPixmap->devPrivate.ptr - - (long)pI830->FbBase; + offset = intel_get_pixmap_offset(pPixmap); if (offset == pI830->front_buffer->offset && pI830->front_buffer->tiling != TILE_NONE) { diff --git a/src/i830_video.c b/src/i830_video.c index 2128eb88..beec03ea 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -2402,9 +2402,10 @@ I830PutImage(ScrnInfoPtr pScrn, } #endif - if (((char *)pPixmap->devPrivate.ptr < (char *)pI830->FbBase) || - ((char *)pPixmap->devPrivate.ptr >= (char *)pI830->FbBase + - pI830->FbMapSize)) { + if (!pI830->useEXA && + (((char *)pPixmap->devPrivate.ptr < (char *)pI830->FbBase) || + ((char *)pPixmap->devPrivate.ptr >= (char *)pI830->FbBase + + pI830->FbMapSize))) { /* If the pixmap wasn't in framebuffer, then we have no way in XAA to * force it there. So, we simply refuse to draw and fail. */ diff --git a/src/i915_video.c b/src/i915_video.c index a6447b1c..00494a7b 100644 --- a/src/i915_video.c +++ b/src/i915_video.c @@ -127,8 +127,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, /* front buffer, pitch, offset */ OUT_RING(_3DSTATE_BUF_INFO_CMD); OUT_RING(BUF_3D_ID_COLOR_BACK | BUF_3D_USE_FENCE | - BUF_3D_PITCH(pPixmap->devKind)); - OUT_RING(BUF_3D_ADDR((long)pPixmap->devPrivate.ptr - (long)pI830->FbBase)); + BUF_3D_PITCH(intel_get_pixmap_pitch(pPixmap))); + OUT_RING(BUF_3D_ADDR(intel_get_pixmap_offset(pPixmap))); ADVANCE_LP_RING(); if (!planar) { diff --git a/src/i965_video.c b/src/i965_video.c index 6ed7f01a..03572703 100644 --- a/src/i965_video.c +++ b/src/i965_video.c @@ -371,13 +371,12 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, dest_surf_state->ss0.mipmap_layout_mode = 0; dest_surf_state->ss0.render_cache_read_mode = 0; - dest_surf_state->ss1.base_addr = (long)pPixmap->devPrivate.ptr - - (long)pI830->FbBase; + dest_surf_state->ss1.base_addr = intel_get_pixmap_offset(pPixmap); dest_surf_state->ss2.height = pScrn->virtualY - 1; dest_surf_state->ss2.width = pScrn->virtualX - 1; dest_surf_state->ss2.mip_count = 0; dest_surf_state->ss2.render_target_rotation = 0; - dest_surf_state->ss3.pitch = pPixmap->devKind - 1; + dest_surf_state->ss3.pitch = intel_get_pixmap_pitch(pPixmap) - 1; dest_surf_state->ss3.tiled_surface = i830_pixmap_tiled(pPixmap); dest_surf_state->ss3.tile_walk = 0; /* TileX */ From ca67fa767dc762dac369e84b27a7ef15673d527c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Sep 2007 11:12:22 -0700 Subject: [PATCH 09/26] Remove logic for supporting i915tex_dri.so vs. i915_dri.so. There can be only one. --- src/i830_dri.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index bff885eb..6fe75e53 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -102,11 +102,6 @@ typedef struct drm_i915_flip { #include "dristruct.h" -static char I830KernelDriverName[] = "i915"; -static char I830ClientDriverName[] = "i915tex"; -static char I965ClientDriverName[] = "i965"; -static char I830LegacyClientDriverName[] = "i915"; - static Bool I830InitVisualConfigs(ScreenPtr pScreen); static Bool I830CreateContext(ScreenPtr pScreen, VisualPtr visual, drm_context_t hwContext, void *pVisualConfigPriv, @@ -538,11 +533,11 @@ I830DRIScreenInit(ScreenPtr pScreen) pI830->pDRIInfo = pDRIInfo; pI830->LockHeld = 0; - pDRIInfo->drmDriverName = I830KernelDriverName; + pDRIInfo->drmDriverName = "i915"; if (IS_I965G(pI830)) - pDRIInfo->clientDriverName = I965ClientDriverName; - else - pDRIInfo->clientDriverName = I830ClientDriverName; + pDRIInfo->clientDriverName = "i965"; + else + pDRIInfo->clientDriverName = "i915"; if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { pDRIInfo->busIdString = DRICreatePCIBusID(pI830->PciInfo); @@ -719,9 +714,15 @@ I830DRIScreenInit(ScreenPtr pScreen) drmFreeVersion(version); return FALSE; } - if (strncmp(version->name, I830KernelDriverName, strlen(I830KernelDriverName))) { - xf86DrvMsg(pScreen->myNum, X_WARNING, - "i830 Kernel module detected, Use the i915 Kernel module instead, aborting DRI init.\n"); + /* Check whether the kernel module attached to the device isn't the + * one we expected (meaning it's the old i830 module). + */ + if (strncmp(version->name, pDRIInfo->drmDriverName, + strlen(pDRIInfo->drmDriverName))) + { + xf86DrvMsg(pScreen->myNum, X_WARNING, + "Detected i830 kernel module. The i915 kernel module " + "is required for DRI. Aborting.\n"); I830DRICloseScreen(pScreen); drmFreeVersion(version); return FALSE; @@ -739,15 +740,6 @@ I830DRIScreenInit(ScreenPtr pScreen) } } - /* - * Backwards compatibility - */ - - if ((pDRIInfo->clientDriverName == I830ClientDriverName) && - (pI830->allocate_classic_textures)) { - pDRIInfo->clientDriverName = I830LegacyClientDriverName; - } - return TRUE; } From bbf69c7446aa9748dacecccfe0b63d803f865b00 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Thu, 27 Sep 2007 17:37:19 +0800 Subject: [PATCH 10/26] Pin cursor, overlay(no physical) and exa state buffers And cursor mem counting for dri mem manager is not relate to overlay. --- src/i830_memory.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index 42e88a69..7ae23322 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -392,10 +392,10 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size) /* Overlay is always set up as fixed, currently. */ if (!OVERLAY_NOPHYSICAL(pI830) && !IS_I965G(pI830)) { mmsize -= ROUND_TO(OVERLAY_SIZE, GTT_PAGE_SIZE); - if (pI830->CursorNeedsPhysical) { - mmsize -= 2 * (ROUND_TO(HWCURSOR_SIZE, GTT_PAGE_SIZE) + - ROUND_TO(HWCURSOR_SIZE_ARGB, GTT_PAGE_SIZE)); - } + } + if (pI830->CursorNeedsPhysical) { + mmsize -= 2 * (ROUND_TO(HWCURSOR_SIZE, GTT_PAGE_SIZE) + + ROUND_TO(HWCURSOR_SIZE_ARGB, GTT_PAGE_SIZE)); } if (pI830->fb_compression) mmsize -= MB(6); @@ -992,7 +992,7 @@ i830_allocate_overlay(ScrnInfoPtr pScrn) return TRUE; if (OVERLAY_NOPHYSICAL(pI830)) - flags = 0; + flags &= ~NEED_PHYSICAL_ADDR; if (!IS_I965G(pI830)) { /* XXX: The lifetime fixed offset for overlay register is bogus, and we @@ -1193,7 +1193,7 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0; + int flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : NEED_LIFETIME_FIXED; int i; long size; @@ -1381,7 +1381,7 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) if (IS_I965G(pI830) && !pI830->noAccel && pI830->exa_965_state == NULL) { pI830->exa_965_state = i830_allocate_memory(pScrn, "exa G965 state buffer", - EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, 0); + EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, NEED_LIFETIME_FIXED); if (pI830->exa_965_state == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate exa state buffer for 965.\n"); From f3d92ab474de11babe507b0e3c15aca146b6cb66 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 28 Sep 2007 10:17:55 -0400 Subject: [PATCH 11/26] Dell XPS 1330 has no TV out --- src/i830_quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/i830_quirks.c b/src/i830_quirks.c index 28b8ff93..66675453 100644 --- a/src/i830_quirks.c +++ b/src/i830_quirks.c @@ -64,6 +64,8 @@ static i830_quirk i830_quirk_list[] = { /* Dell Latitude X1 */ { PCI_CHIP_I945_GM, 0x1028, 0x01a3, quirk_ignore_tv }, + /* Dell XPS 1330 */ + { PCI_CHIP_I965_GM, 0x1028, 0x0209, quirk_ignore_tv }, /* Lenovo X60s has no TV output */ { PCI_CHIP_I945_GM, 0x17aa, 0x201a, quirk_ignore_tv }, From 1845e7c6e9caf7a9ad7f46a8fbfa321ddec69a1e Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 28 Sep 2007 10:12:11 -0700 Subject: [PATCH 12/26] Go back to using old drm_i915_flip_t field name This field shouldn't have been renamed in the first place. Go back to using the old name so that the tree is backward and forward compatible again. --- src/i830_dri.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index 6fe75e53..4cddf3ba 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -91,7 +91,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRM_VBLANK_FLIP 0x8000000 typedef struct drm_i915_flip { - int planes; + int pipes; } drm_i915_flip_t; #undef DRM_IOCTL_I915_FLIP @@ -1256,20 +1256,20 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, #ifdef DAMAGE /* Try flipping back to the front page if necessary */ if (sPriv && !sPriv->pf_enabled && sPriv->pf_current_page != 0) { - drm_i915_flip_t flip = { .planes = 0 }; + drm_i915_flip_t flip = { .pipes = 0 }; if (sPriv->pf_current_page & (0x3 << 2)) { sPriv->pf_current_page = sPriv->pf_current_page & 0x3; sPriv->pf_current_page |= (sPriv->third_handle ? 2 : 1) << 2; - flip.planes |= 0x2; + flip.pipes |= 0x2; } if (sPriv->pf_current_page & 0x3) { sPriv->pf_current_page = sPriv->pf_current_page & (0x3 << 2); sPriv->pf_current_page |= sPriv->third_handle ? 2 : 1; - flip.planes |= 0x1; + flip.pipes |= 0x1; } drmCommandWrite(pI830->drmSubFD, DRM_I915_FLIP, &flip, sizeof(flip)); From 0e5574e842eeaac75271ccd50027d3e54c57722d Mon Sep 17 00:00:00 2001 From: Regis Prevot Date: Sat, 29 Sep 2007 16:21:08 +0200 Subject: [PATCH 13/26] Ignore detection of TV output on Panasonic CF-Y7 --- src/i830_quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/i830_quirks.c b/src/i830_quirks.c index 66675453..8e4ec975 100644 --- a/src/i830_quirks.c +++ b/src/i830_quirks.c @@ -76,6 +76,8 @@ static i830_quirk i830_quirk_list[] = { /* Panasonic Toughbook CF-Y4 has no TV output */ { PCI_CHIP_I915_GM, 0x10f7, 0x8338, quirk_ignore_tv }, + /* Panasonic Toughbook CF-Y7 has no TV output */ + { PCI_CHIP_I965_GM, 0x10f7, 0x8338, quirk_ignore_tv }, { 0, 0, 0, NULL }, }; From 994ee6721d9f1650ad37e21198b86848352b73af Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 1 Oct 2007 12:01:16 -0700 Subject: [PATCH 14/26] Disable TV/VGA output on the CH7017/7018 devices. We don't support those outputs on this chip yet, so turn them off if the BIOS had set them on. --- src/ch7017/ch7017.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ch7017/ch7017.c b/src/ch7017/ch7017.c index 8e3a6ef4..4c9b4c61 100644 --- a/src/ch7017/ch7017.c +++ b/src/ch7017/ch7017.c @@ -55,6 +55,7 @@ struct ch7017_priv { CARD8 save_lvds_control_2; CARD8 save_outputs_enable; CARD8 save_lvds_power_down; + CARD8 save_power_management; }; static void @@ -224,12 +225,20 @@ ch7017_dpms(I2CDevPtr d, int mode) ch7017_read(priv, CH7017_LVDS_POWER_DOWN, &val); + /* Turn off TV/VGA, and never turn it on since we don't support it. */ + ch7017_write(priv, CH7017_POWER_MANAGEMENT, + CH7017_DAC0_POWER_DOWN | + CH7017_DAC1_POWER_DOWN | + CH7017_DAC2_POWER_DOWN | + CH7017_DAC3_POWER_DOWN | + CH7017_TV_POWER_DOWN_EN); + if (mode == DPMSModeOn) { /* Turn on the LVDS */ ch7017_write(priv, CH7017_LVDS_POWER_DOWN, val & ~CH7017_LVDS_POWER_DOWN_EN); } else { - /* Turn on the LVDS */ + /* Turn off the LVDS */ ch7017_write(priv, CH7017_LVDS_POWER_DOWN, val | CH7017_LVDS_POWER_DOWN_EN); } @@ -273,6 +282,7 @@ ch7017_save(I2CDevPtr d) ch7017_read(priv, CH7017_LVDS_CONTROL_2, &priv->save_lvds_control_2); ch7017_read(priv, CH7017_OUTPUTS_ENABLE, &priv->save_outputs_enable); ch7017_read(priv, CH7017_LVDS_POWER_DOWN, &priv->save_lvds_power_down); + ch7017_read(priv, CH7017_POWER_MANAGEMENT, &priv->save_power_management); } static void @@ -290,6 +300,7 @@ ch7017_restore(I2CDevPtr d) ch7017_write(priv, CH7017_LVDS_CONTROL_2, priv->save_lvds_control_2); ch7017_write(priv, CH7017_OUTPUTS_ENABLE, priv->save_outputs_enable); ch7017_write(priv, CH7017_LVDS_POWER_DOWN, priv->save_lvds_power_down); + ch7017_write(priv, CH7017_POWER_MANAGEMENT, priv->save_power_management); } I830I2CVidOutputRec ch7017_methods = { From 6dd8228a386334d05836353672aae9f8c456e435 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 1 Oct 2007 12:07:22 -0700 Subject: [PATCH 15/26] Enable CH7017/7018 DVO driver by default. On hardware containing one of these chips (generally single pipe with an LVDS connected), it's probably better to try to enable it and fail in some cases than to not probe the output at all. --- src/i830_dvo.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/i830_dvo.c b/src/i830_dvo.c index cb461d79..8ba38bdb 100644 --- a/src/i830_dvo.c +++ b/src/i830_dvo.c @@ -55,12 +55,10 @@ static const char *ivch_symbols[] = { NULL }; -#if 0 static const char *ch7017_symbols[] = { "ch7017_methods", NULL }; -#endif /* driver list */ struct _I830DVODriver i830_dvo_drivers[] = @@ -97,10 +95,14 @@ struct _I830DVODriver i830_dvo_drivers[] = .address = (TFP410_ADDR_1<<1), .symbols = TFP410Symbols }, - /* - { I830_OUTPUT_DVO_LVDS, "ch7017", "ch7017_methods", - 0xea, ch7017_symbols, NULL, NULL, NULL } - */ + { + .type = I830_OUTPUT_DVO_LVDS, + .modulename = "ch7017", + .fntablename = "ch7017_methods", + .dvo_reg = DVOA, + .address = 0xea, + .symbols = ch7017_symbols, + } }; #define I830_NUM_DVO_DRIVERS (sizeof(i830_dvo_drivers)/sizeof(struct _I830DVODriver)) From 29d3188ee9676f697f6fcb859c7f680f5df30318 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 1 Oct 2007 13:45:09 -0700 Subject: [PATCH 16/26] Suppress I2C failure error messages during DVO device detection. Otherwise, errors would be printed for every chip probed which wasn't present on the system. --- src/ch7xxx/ch7xxx.c | 27 ++++++++++++++++++--------- src/ivch/ivch.c | 20 ++++++++++++++------ src/sil164/sil164.c | 18 ++++++++++++------ src/sil164/sil164_reg.h | 1 + src/tfp410/tfp410.c | 18 ++++++++++++------ src/tfp410/tfp410_reg.h | 2 ++ 6 files changed, 59 insertions(+), 27 deletions(-) diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index 3ef9612a..3c58165d 100644 --- a/src/ch7xxx/ch7xxx.c +++ b/src/ch7xxx/ch7xxx.c @@ -67,6 +67,8 @@ struct ch7xxx_reg_state { struct ch7xxx_priv { I2CDevRec d; + Bool quiet; + struct ch7xxx_reg_state SavedReg; struct ch7xxx_reg_state ModeReg; CARD8 save_TCTL, save_TPCP, save_TPD, save_TPVT; @@ -92,9 +94,11 @@ static Bool ch7xxx_read(struct ch7xxx_priv *dev_priv, int addr, unsigned char *ch) { if (!xf86I2CReadByte(&dev_priv->d, addr, ch)) { - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, - X_ERROR, "Unable to read from %s Slave %d.\n", - dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); + if (!dev_priv->quiet) { + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, + X_ERROR, "Unable to read from %s Slave %d.\n", + dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); + } return FALSE; } @@ -106,9 +110,11 @@ static Bool ch7xxx_write(struct ch7xxx_priv *dev_priv, int addr, unsigned char ch) { if (!xf86I2CWriteByte(&dev_priv->d, addr, ch)) { - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, - "Unable to write to %s Slave %d.\n", - dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); + if (!dev_priv->quiet) { + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, + "Unable to write to %s Slave %d.\n", + dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); + } return FALSE; } @@ -136,6 +142,7 @@ ch7xxx_init(I2CBusPtr b, I2CSlaveAddr addr) dev_priv->d.ByteTimeout = b->ByteTimeout; dev_priv->d.DriverPrivate.ptr = dev_priv; + dev_priv->quiet = TRUE; if (!ch7xxx_read(dev_priv, CH7xxx_REG_VID, &vendor)) goto out; @@ -159,9 +166,11 @@ ch7xxx_init(I2CBusPtr b, I2CSlaveAddr addr) dev_priv->d.SlaveAddr); goto out; } - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_INFO, - "Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n", - name, vendor, device); + dev_priv->quiet = FALSE; + + xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_INFO, + "Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n", + name, vendor, device); if (!xf86I2CDevInit(&dev_priv->d)) { goto out; diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c index bd11dd42..ac57ff3a 100644 --- a/src/ivch/ivch.c +++ b/src/ivch/ivch.c @@ -48,6 +48,7 @@ struct ivch_priv { I2CDevRec d; xf86OutputPtr output; + Bool quiet; CARD16 width; CARD16 height; @@ -105,9 +106,11 @@ ivch_read(struct ivch_priv *priv, int addr, CARD16 *data) return TRUE; fail: - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR, - "ivch: Unable to read register 0x%02x from %s:%02x.\n", - addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr); + if (!priv->quiet) { + xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR, + "ivch: Unable to read register 0x%02x from %s:%02x.\n", + addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr); + } b->I2CStop(&priv->d); return FALSE; @@ -140,9 +143,12 @@ ivch_write(struct ivch_priv *priv, int addr, CARD16 data) fail: b->I2CStop(&priv->d); - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR, - "Unable to write register 0x%02x to %s:%d.\n", - addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr); + + if (!priv->quiet) { + xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR, + "Unable to write register 0x%02x to %s:%d.\n", + addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr); + } return FALSE; } @@ -167,9 +173,11 @@ ivch_init(I2CBusPtr b, I2CSlaveAddr addr) priv->d.AcknTimeout = b->AcknTimeout; priv->d.ByteTimeout = b->ByteTimeout; priv->d.DriverPrivate.ptr = priv; + priv->quiet = TRUE; if (!ivch_read(priv, VR00, &temp)) goto out; + priv->quiet = FALSE; /* Since the identification bits are probably zeroes, which doesn't seem * very unique, check that the value in the base address field matches diff --git a/src/sil164/sil164.c b/src/sil164/sil164.c index 60a03e22..c774a56c 100644 --- a/src/sil164/sil164.c +++ b/src/sil164/sil164.c @@ -49,9 +49,11 @@ static Bool sil164ReadByte(SIL164Ptr sil, int addr, CARD8 *ch) { if (!xf86I2CReadByte(&(sil->d), addr, ch)) { - xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, - "Unable to read from %s Slave %d.\n", - sil->d.pI2CBus->BusName, sil->d.SlaveAddr); + if (!sil->quiet) { + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, + "Unable to read from %s Slave %d.\n", + sil->d.pI2CBus->BusName, sil->d.SlaveAddr); + } return FALSE; } return TRUE; @@ -61,9 +63,11 @@ static Bool sil164WriteByte(SIL164Ptr sil, int addr, CARD8 ch) { if (!xf86I2CWriteByte(&(sil->d), addr, ch)) { - xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, - "Unable to write to %s Slave %d.\n", - sil->d.pI2CBus->BusName, sil->d.SlaveAddr); + if (!sil->quiet) { + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, + "Unable to write to %s Slave %d.\n", + sil->d.pI2CBus->BusName, sil->d.SlaveAddr); + } return FALSE; } return TRUE; @@ -91,6 +95,7 @@ sil164_init(I2CBusPtr b, I2CSlaveAddr addr) sil->d.AcknTimeout = b->AcknTimeout; sil->d.ByteTimeout = b->ByteTimeout; sil->d.DriverPrivate.ptr = sil; + sil->quiet = TRUE; if (!sil164ReadByte(sil, SIL164_VID_LO, &ch)) goto out; @@ -111,6 +116,7 @@ sil164_init(I2CBusPtr b, I2CSlaveAddr addr) ch, sil->d.pI2CBus->BusName, sil->d.SlaveAddr); goto out; } + sil->quiet = FALSE; if (!xf86I2CDevInit(&(sil->d))) { goto out; diff --git a/src/sil164/sil164_reg.h b/src/sil164/sil164_reg.h index ebfcb8c7..734e55dd 100644 --- a/src/sil164/sil164_reg.h +++ b/src/sil164/sil164_reg.h @@ -65,6 +65,7 @@ typedef struct _Sil164SaveRec { typedef struct { I2CDevRec d; + Bool quiet; SIL164SaveRec SavedReg; SIL164SaveRec ModeReg; } SIL164Rec, *SIL164Ptr; diff --git a/src/tfp410/tfp410.c b/src/tfp410/tfp410.c index fecb64c8..bc0ad749 100644 --- a/src/tfp410/tfp410.c +++ b/src/tfp410/tfp410.c @@ -48,9 +48,11 @@ static Bool tfp410ReadByte(TFP410Ptr tfp, int addr, CARD8 *ch) { if (!xf86I2CReadByte(&(tfp->d), addr, ch)) { - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR, - "Unable to read from %s Slave %d.\n", - tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr); + if (!tfp->quiet) { + xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR, + "Unable to read from %s Slave %d.\n", + tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr); + } return FALSE; } return TRUE; @@ -60,9 +62,11 @@ static Bool tfp410WriteByte(TFP410Ptr tfp, int addr, CARD8 ch) { if (!xf86I2CWriteByte(&(tfp->d), addr, ch)) { - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR, - "Unable to write to %s Slave %d.\n", - tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr); + if (!tfp->quiet) { + xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR, + "Unable to write to %s Slave %d.\n", + tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr); + } return FALSE; } return TRUE; @@ -103,6 +107,7 @@ tfp410_init(I2CBusPtr b, I2CSlaveAddr addr) tfp->d.AcknTimeout = b->AcknTimeout; tfp->d.ByteTimeout = b->ByteTimeout; tfp->d.DriverPrivate.ptr = tfp; + tfp->quiet = TRUE; if ((id = tfp410GetID(tfp, TFP410_VID_LO)) != TFP410_VID) { xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR, @@ -117,6 +122,7 @@ tfp410_init(I2CBusPtr b, I2CSlaveAddr addr) id, tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr); goto out; } + tfp->quiet = FALSE; if (!xf86I2CDevInit(&(tfp->d))) { goto out; diff --git a/src/tfp410/tfp410_reg.h b/src/tfp410/tfp410_reg.h index 45afa9b0..c555b977 100644 --- a/src/tfp410/tfp410_reg.h +++ b/src/tfp410/tfp410_reg.h @@ -95,6 +95,8 @@ typedef struct _TFP410SaveRec { typedef struct { I2CDevRec d; + Bool quiet; + TFP410SaveRec SavedReg; TFP410SaveRec ModeReg; } TFP410Rec, *TFP410Ptr; From 1b83e5e589105d05c1b78032fa47eecee478cb99 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 1 Oct 2007 14:32:28 -0700 Subject: [PATCH 17/26] Remove more DVO probing noise. --- src/ch7017/ch7017.c | 2 -- src/sil164/sil164.c | 2 -- src/tfp410/tfp410.c | 10 +++++----- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/ch7017/ch7017.c b/src/ch7017/ch7017.c index 4c9b4c61..ceb8a2a1 100644 --- a/src/ch7017/ch7017.c +++ b/src/ch7017/ch7017.c @@ -94,8 +94,6 @@ ch7017_init(I2CBusPtr b, I2CSlaveAddr addr) struct ch7017_priv *priv; CARD8 val; - xf86DrvMsg(b->scrnIndex, X_INFO, "detecting ch7017\n"); - priv = xcalloc(1, sizeof(struct ch7017_priv)); if (priv == NULL) return NULL; diff --git a/src/sil164/sil164.c b/src/sil164/sil164.c index c774a56c..12fe8e2e 100644 --- a/src/sil164/sil164.c +++ b/src/sil164/sil164.c @@ -81,8 +81,6 @@ sil164_init(I2CBusPtr b, I2CSlaveAddr addr) SIL164Ptr sil; unsigned char ch; - xf86DrvMsg(b->scrnIndex, X_ERROR, "detecting sil164\n"); - sil = xcalloc(1, sizeof(SIL164Rec)); if (sil == NULL) return NULL; diff --git a/src/tfp410/tfp410.c b/src/tfp410/tfp410.c index bc0ad749..b79fd2a8 100644 --- a/src/tfp410/tfp410.c +++ b/src/tfp410/tfp410.c @@ -93,8 +93,6 @@ tfp410_init(I2CBusPtr b, I2CSlaveAddr addr) TFP410Ptr tfp; int id; - xf86DrvMsg(b->scrnIndex, X_INFO, "detecting tfp410\n"); - tfp = xcalloc(1, sizeof(TFP410Rec)); if (tfp == NULL) return NULL; @@ -110,9 +108,11 @@ tfp410_init(I2CBusPtr b, I2CSlaveAddr addr) tfp->quiet = TRUE; if ((id = tfp410GetID(tfp, TFP410_VID_LO)) != TFP410_VID) { - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR, - "tfp410 not detected got VID %X: from %s Slave %d.\n", - id, tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr); + if (id != 0xffffffff) { + xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR, + "tfp410 not detected got VID %X: from %s Slave %d.\n", + id, tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr); + } goto out; } From 219354af212c7b68c20df689692c55331e36a705 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 1 Oct 2007 16:09:13 -0700 Subject: [PATCH 18/26] Restore building of pciaccess-based tools even if the server doesn't use it. --- configure.ac | 8 +++++++- src/Makefile.am | 2 +- src/bios_reader/Makefile.am | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 1c7ad04f..e5a7cf6e 100644 --- a/configure.ac +++ b/configure.ac @@ -116,9 +116,15 @@ CFLAGS="$save_CFLAGS" if test x$XSERVER_LIBPCIACCESS = xyes; then PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0]) +else + PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.5.0], + have_libpciaccess=yes, + have_libpciaccess=no) fi - +have_libpciaccess=no AM_CONDITIONAL(XSERVER_LIBPCIACCESS, test "x$XSERVER_LIBPCIACCESS" = xyes) +AM_CONDITIONAL(LIBPCIACCESS, + test "x$XSERVER_LIBPCIACCESS" = xyes -o "x$have_libpciaccess" = xyes) AM_CONDITIONAL(XMODES, test "x$XMODES" = xno) if test "x$XSERVER_SOURCE" = x; then diff --git a/src/Makefile.am b/src/Makefile.am index 13cbf913..118d4b13 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,7 +18,7 @@ # 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. -if XSERVER_LIBPCIACCESS +if LIBPCIACCESS REGDUMPER = reg_dumper endif diff --git a/src/bios_reader/Makefile.am b/src/bios_reader/Makefile.am index a4adecb1..76ad15f7 100644 --- a/src/bios_reader/Makefile.am +++ b/src/bios_reader/Makefile.am @@ -2,7 +2,7 @@ AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @XMODES_CFLAGS@ noinst_PROGRAMS = bios_reader $(BIOS_DUMPER) -if XSERVER_LIBPCIACCESS +if LIBPCIACCESS BIOS_DUMPER = bios_dumper bios_dumper_SOURCES = bios_dumper.c From 263d48ad93a0fb7100729d0c6e0443797c20c80a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 1 Oct 2007 16:23:30 -0700 Subject: [PATCH 19/26] Fix probing of the sample CH7017 device I found by allowing GPIO overrides. It may be that the LVDS chips need to be DVOA and GPIOB only on mobility devices with them, and DVOC/GPIOE on non-mobility like this 845. But until more examples are found, just make this one device probe. --- src/i830.h | 1 + src/i830_dvo.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/i830.h b/src/i830.h index b1f1f68f..0a4b4a7b 100644 --- a/src/i830.h +++ b/src/i830.h @@ -221,6 +221,7 @@ struct _I830DVODriver { char *modulename; char *fntablename; unsigned int dvo_reg; + uint32_t gpio; int address; const char **symbols; I830I2CVidOutputRec *vid_rec; diff --git a/src/i830_dvo.c b/src/i830_dvo.c index 8ba38bdb..e6ff6af6 100644 --- a/src/i830_dvo.c +++ b/src/i830_dvo.c @@ -99,9 +99,10 @@ struct _I830DVODriver i830_dvo_drivers[] = .type = I830_OUTPUT_DVO_LVDS, .modulename = "ch7017", .fntablename = "ch7017_methods", - .dvo_reg = DVOA, + .dvo_reg = DVOC, .address = 0xea, .symbols = ch7017_symbols, + .gpio = GPIOE, } }; @@ -430,7 +431,12 @@ i830_dvo_init(ScrnInfoPtr pScrn) ret_ptr = NULL; drv->vid_rec = LoaderSymbol(drv->fntablename); - if (drv->type == I830_OUTPUT_DVO_LVDS) + /* Allow the I2C driver info to specify the GPIO to be used in + * special cases, but otherwise default to what's defined in the spec. + */ + if (drv->gpio != 0) + gpio = drv->gpio; + else if (drv->type == I830_OUTPUT_DVO_LVDS) gpio = GPIOB; else gpio = GPIOE; From 04e936935f0b0045600241424f1d04a6721a2432 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 1 Oct 2007 17:29:35 -0700 Subject: [PATCH 20/26] Bring the CH7017 driver closer to spec. This is also closer to what my hardware is programmed with, except for some very confusing off-by-one bugs in an unexpected direction. --- src/ch7017/ch7017.c | 52 ++++++++++++++++++++++++----------------- src/ch7017/ch7017_reg.h | 13 ++++++++++- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/ch7017/ch7017.c b/src/ch7017/ch7017.c index ceb8a2a1..f8e2b311 100644 --- a/src/ch7017/ch7017.c +++ b/src/ch7017/ch7017.c @@ -50,6 +50,7 @@ struct ch7017_priv { CARD8 save_hapi; CARD8 save_vali; CARD8 save_valo; + CARD8 save_ailo; CARD8 save_lvds_pll_vco; CARD8 save_feedback_div; CARD8 save_lvds_control_2; @@ -157,31 +158,34 @@ ch7017_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode) ch7017_dump_regs(d); /* LVDS PLL settings from page 75 of 7017-7017ds.pdf*/ - if (mode->Clock < 50000) { - lvds_pll_feedback_div = 45; - lvds_pll_vco_control = (2 << 4) | (3 << 0); - outputs_enable = (0 << 0); /* XXX: enables */ + if (mode->Clock < 100000) { + outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_LOW; + lvds_pll_feedback_div = CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED | + (2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) | + (13 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT); + lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED | + (2 << CH7017_LVDS_PLL_VCO_SHIFT) | + (3 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT); lvds_control_2 = (1 << CH7017_LOOP_FILTER_SHIFT) | (0 << CH7017_PHASE_DETECTOR_SHIFT); - } else if (mode->Clock < 100000) { - lvds_pll_feedback_div = 45; - lvds_pll_vco_control = (2 << 4) | (3 << 0); - outputs_enable = (0 << 0); /* XXX: enables */ - lvds_control_2 = (1 << CH7017_LOOP_FILTER_SHIFT) | - (0 << CH7017_PHASE_DETECTOR_SHIFT); - } else if (mode->Clock < 160000) { + } else { + outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_HIGH; + lvds_pll_feedback_div = CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED | + (2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) | + (3 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT); lvds_pll_feedback_div = 35; - outputs_enable = (3 << 0); /* XXX: enables */ lvds_control_2 = (3 << CH7017_LOOP_FILTER_SHIFT) | (0 << CH7017_PHASE_DETECTOR_SHIFT); - if (1) { /* XXX: dual panel */ - lvds_pll_vco_control = (2 << 4) | (13 << 0); + if (1) { /* XXX: dual channel panel detection. Assume yes for now. */ + outputs_enable |= CH7017_LVDS_CHANNEL_B; + lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED | + (2 << CH7017_LVDS_PLL_VCO_SHIFT) | + (13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT); } else { - lvds_pll_vco_control = (1 << 4) | (13 << 0); + lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED | + (1 << CH7017_LVDS_PLL_VCO_SHIFT) | + (13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT); } - } else { - FatalError("Invalid mode clock (%.1fMHz)\n", - (float)mode->Clock / 1000.0); } horizontal_active_pixel_input = mode->HDisplay & 0x00ff; @@ -189,10 +193,11 @@ ch7017_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode) vertical_active_line_output = mode->VDisplay & 0x00ff; horizontal_active_pixel_output = mode->HDisplay & 0x00ff; - active_input_line_output = ((mode->HDisplay & 0x0700) >> 9) | - ((mode->VDisplay & 0x0700) >> 8); + active_input_line_output = ((mode->HDisplay & 0x0700) >> 8) | + (((mode->VDisplay & 0x0700) >> 8) << 3); - lvds_power_down = (mode->HDisplay & 0x0f00) >> 8; + lvds_power_down = CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED | + (mode->HDisplay & 0x0700) >> 8; ch7017_dpms(d, DPMSModeOff); ch7017_write(priv, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, @@ -201,6 +206,8 @@ ch7017_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode) horizontal_active_pixel_output); ch7017_write(priv, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT, vertical_active_line_output); + ch7017_write(priv, CH7017_ACTIVE_INPUT_LINE_OUTPUT, + active_input_line_output); ch7017_write(priv, CH7017_LVDS_PLL_VCO_CONTROL, lvds_pll_vco_control); ch7017_write(priv, CH7017_LVDS_PLL_FEEDBACK_DIV, lvds_pll_feedback_div); ch7017_write(priv, CH7017_LVDS_CONTROL_2, lvds_control_2); @@ -261,6 +268,7 @@ do { \ DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT); DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT); DUMP(CH7017_VERTICAL_ACTIVE_LINE_OUTPUT); + DUMP(CH7017_ACTIVE_INPUT_LINE_OUTPUT); DUMP(CH7017_LVDS_PLL_VCO_CONTROL); DUMP(CH7017_LVDS_PLL_FEEDBACK_DIV); DUMP(CH7017_LVDS_CONTROL_2); @@ -275,6 +283,7 @@ ch7017_save(I2CDevPtr d) ch7017_read(priv, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, &priv->save_hapi); ch7017_read(priv, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT, &priv->save_valo); + ch7017_read(priv, CH7017_ACTIVE_INPUT_LINE_OUTPUT, &priv->save_ailo); ch7017_read(priv, CH7017_LVDS_PLL_VCO_CONTROL, &priv->save_lvds_pll_vco); ch7017_read(priv, CH7017_LVDS_PLL_FEEDBACK_DIV, &priv->save_feedback_div); ch7017_read(priv, CH7017_LVDS_CONTROL_2, &priv->save_lvds_control_2); @@ -293,6 +302,7 @@ ch7017_restore(I2CDevPtr d) ch7017_write(priv, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, priv->save_hapi); ch7017_write(priv, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT, priv->save_valo); + ch7017_write(priv, CH7017_ACTIVE_INPUT_LINE_OUTPUT, priv->save_ailo); ch7017_write(priv, CH7017_LVDS_PLL_VCO_CONTROL, priv->save_lvds_pll_vco); ch7017_write(priv, CH7017_LVDS_PLL_FEEDBACK_DIV, priv->save_feedback_div); ch7017_write(priv, CH7017_LVDS_CONTROL_2, priv->save_lvds_control_2); diff --git a/src/ch7017/ch7017_reg.h b/src/ch7017/ch7017_reg.h index 89f81cc3..3344c4e6 100644 --- a/src/ch7017/ch7017_reg.h +++ b/src/ch7017/ch7017_reg.h @@ -99,11 +99,12 @@ #define CH7017_LVDS_POWER_DOWN 0x63 /** High bits of horizontal active pixel output */ -#define CH7017_LVDS_HAP_HIGH_MASK (0xf << 0) +#define CH7017_LVDS_HAP_HIGH_MASK (0x7 << 0) /** Enables the LVDS power down state transition */ #define CH7017_LVDS_POWER_DOWN_EN (1 << 6) /** Enables the LVDS upscaler */ #define CH7017_LVDS_UPSCALER_EN (1 << 7) +#define CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED 0x08 #define CH7017_LVDS_ENCODING 0x64 #define CH7017_LVDS_DITHER_2D (1 << 2) @@ -127,10 +128,20 @@ #define CH7017_GPIO_DRIVER_TYPE 0x6c #define CH7017_GPIO_DATA 0x6d #define CH7017_GPIO_DIRECTION_CONTROL 0x6e + #define CH7017_LVDS_PLL_FEEDBACK_DIV 0x71 +# define CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT 4 +# define CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT 0 +# define CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED 0x80 + #define CH7017_LVDS_PLL_VCO_CONTROL 0x72 +# define CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED 0x80 +# define CH7017_LVDS_PLL_VCO_SHIFT 4 +# define CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT 0 #define CH7017_OUTPUTS_ENABLE 0x73 +# define CH7017_CHARGE_PUMP_LOW 0x0 +# define CH7017_CHARGE_PUMP_HIGH 0x3 # define CH7017_LVDS_CHANNEL_A (1 << 3) # define CH7017_LVDS_CHANNEL_B (1 << 4) # define CH7017_TV_DAC_A (1 << 5) From bf33c4e2d91172efd08690fadda7b3743dd3de62 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 5 Oct 2007 12:40:37 -0700 Subject: [PATCH 21/26] Fix formatting of error message. --- src/i830_memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index 7ae23322..c850033b 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -1434,7 +1434,7 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) size, 1, NEED_LIFETIME_FIXED); if (pI830->exa_offscreen == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to allocate EXA offscreen memory."); + "Failed to allocate EXA offscreen memory.\n"); return FALSE; } } From 7db9d706a1bc9da7afc4823cee92b23e96ae55b8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 5 Oct 2007 12:40:48 -0700 Subject: [PATCH 22/26] Warning cleanup. --- src/i830_driver.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index dc271700..0d55609f 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2270,7 +2270,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) Bool allocation_done = FALSE; MessageType from; #ifdef XF86DRI - Bool driDisabled; xf86CrtcConfigPtr config; #endif From dfa22df8ce7713b491c4766ce6ce652db91b5f90 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 5 Oct 2007 12:53:07 -0700 Subject: [PATCH 23/26] Don't leak buffer object allocations in i830_reset_allocations(). --- src/i830_memory.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/i830_memory.c b/src/i830_memory.c index c850033b..d2aa3270 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -272,6 +272,14 @@ i830_reset_allocations(ScrnInfoPtr pScrn) while (pI830->memory_list->next->next != NULL) i830_free_memory(pScrn, pI830->memory_list->next); + /* Free any allocations in buffer objects */ +#ifdef XF86DRI_MM + if (pI830->memory_manager) { + while (pI830->bo_list != NULL) + i830_free_memory(pScrn, pI830->bo_list); + } +#endif + /* Null out the pointers for all the allocations we just freed. This is * kind of gross, but at least it's just one place now. */ From 1cc6bec4628a4ca04a68919a84148a1e6312072f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 4 Oct 2007 14:23:48 -0700 Subject: [PATCH 24/26] Revert setting of exa_965_state as LIFETIME_FIXED. The current offset is used every time in render setup. --- src/i830_memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index d2aa3270..7671b5b7 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -1389,7 +1389,7 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) if (IS_I965G(pI830) && !pI830->noAccel && pI830->exa_965_state == NULL) { pI830->exa_965_state = i830_allocate_memory(pScrn, "exa G965 state buffer", - EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, NEED_LIFETIME_FIXED); + EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, 0); if (pI830->exa_965_state == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate exa state buffer for 965.\n"); From c9d6e90c2523096c45d330552f471e6bf1752704 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 4 Oct 2007 14:27:07 -0700 Subject: [PATCH 25/26] Don't set overlay registers LIFETIME_FIXED. It always uses the current offset. --- src/i830_memory.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index 7671b5b7..23d5e0c7 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -993,20 +993,16 @@ static Bool i830_allocate_overlay(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - int flags = NEED_PHYSICAL_ADDR | NEED_LIFETIME_FIXED; + int flags = 0; /* Only allocate if overlay is going to be enabled. */ if (!pI830->XvEnabled) return TRUE; - if (OVERLAY_NOPHYSICAL(pI830)) - flags &= ~NEED_PHYSICAL_ADDR; + if (!OVERLAY_NOPHYSICAL(pI830)) + flags |= NEED_PHYSICAL_ADDR; if (!IS_I965G(pI830)) { - /* XXX: The lifetime fixed offset for overlay register is bogus, and we - * should just tell i830_video.c about the new location at EnterVT - * time. - */ pI830->overlay_regs = i830_allocate_memory(pScrn, "overlay registers", OVERLAY_SIZE, GTT_PAGE_SIZE, flags); From 9e770bf69edaa8944048049e11266dbe1ef145e5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 4 Oct 2007 14:31:37 -0700 Subject: [PATCH 26/26] Replace setting of LIFETIME_FIXED on cursors with just updating the offsets. --- src/i830.h | 1 + src/i830_cursor.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++- src/i830_memory.c | 47 +++----------------------------------- 3 files changed, 61 insertions(+), 45 deletions(-) diff --git a/src/i830.h b/src/i830.h index 0a4b4a7b..a04f9370 100644 --- a/src/i830.h +++ b/src/i830.h @@ -583,6 +583,7 @@ extern void IntelEmitInvarientState(ScrnInfoPtr pScrn); extern void I830EmitInvarientState(ScrnInfoPtr pScrn); extern void I915EmitInvarientState(ScrnInfoPtr pScrn); extern void I830SelectBuffer(ScrnInfoPtr pScrn, int buffer); +void i830_update_cursor_offsets(ScrnInfoPtr pScrn); /* CRTC-based cursor functions */ void diff --git a/src/i830_cursor.c b/src/i830_cursor.c index 667b0a6c..52eb2661 100644 --- a/src/i830_cursor.c +++ b/src/i830_cursor.c @@ -1,4 +1,4 @@ -/* -*- c-basic-offset: 3 -*- */ +/* -*- c-basic-offset: 4 -*- */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -275,3 +275,59 @@ i830_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) OUTREG(pal0 + 8, fg & 0x00ffffff); OUTREG(pal0 + 12, bg & 0x00ffffff); } + +void +i830_update_cursor_offsets (ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + if (pI830->cursor_mem) { + unsigned long cursor_offset_base = pI830->cursor_mem->offset; + unsigned long cursor_addr_base, offset = 0; + + /* Single memory buffer for cursors */ + if (pI830->CursorNeedsPhysical) { + /* On any hardware that requires physical addresses for cursors, + * the PTEs don't support memory above 4GB, so we can safely + * ignore the top 32 bits of cursor_mem->bus_addr. + */ + cursor_addr_base = (unsigned long)pI830->cursor_mem->bus_addr; + } else + cursor_addr_base = pI830->cursor_mem->offset; + + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + + intel_crtc->cursor_argb_addr = cursor_addr_base + offset; + intel_crtc->cursor_argb_offset = cursor_offset_base + offset; + offset += HWCURSOR_SIZE_ARGB; + + intel_crtc->cursor_addr = cursor_addr_base + offset; + intel_crtc->cursor_offset = cursor_offset_base + offset; + offset += HWCURSOR_SIZE; + } + } else { + /* Separate allocations per cursor */ + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + + if (pI830->CursorNeedsPhysical) { + intel_crtc->cursor_addr = + pI830->cursor_mem_classic[i]->bus_addr; + intel_crtc->cursor_argb_addr = + pI830->cursor_mem_argb[i]->bus_addr; + } else { + intel_crtc->cursor_addr = + pI830->cursor_mem_classic[i]->offset; + intel_crtc->cursor_argb_addr = + pI830->cursor_mem_argb[i]->offset; + } + intel_crtc->cursor_offset = pI830->cursor_mem_classic[i]->offset; + intel_crtc->cursor_argb_offset = pI830->cursor_mem_argb[i]->offset; + } + } +} diff --git a/src/i830_memory.c b/src/i830_memory.c index 23d5e0c7..cdb7c47d 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -1197,7 +1197,7 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : NEED_LIFETIME_FIXED; + int flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0; int i; long size; @@ -1211,35 +1211,8 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) pI830->cursor_mem = i830_allocate_memory(pScrn, "HW cursors", size, GTT_PAGE_SIZE, flags); - if (pI830->cursor_mem != NULL) { - unsigned long cursor_offset_base = pI830->cursor_mem->offset; - unsigned long cursor_addr_base, offset = 0; - - if (pI830->CursorNeedsPhysical) { - /* On any hardware that requires physical addresses for cursors, - * the PTEs don't support memory above 4GB, so we can safely - * ignore the top 32 bits of cursor_mem->bus_addr. - */ - cursor_addr_base = (unsigned long)pI830->cursor_mem->bus_addr; - } else - cursor_addr_base = pI830->cursor_mem->offset; - - /* Set up the offsets for our cursors in each CRTC. */ - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - - intel_crtc->cursor_argb_addr = cursor_addr_base + offset; - intel_crtc->cursor_argb_offset = cursor_offset_base + offset; - offset += HWCURSOR_SIZE_ARGB; - - intel_crtc->cursor_addr = cursor_addr_base + offset; - intel_crtc->cursor_offset = cursor_offset_base + offset; - offset += HWCURSOR_SIZE; - } - + if (pI830->cursor_mem != NULL) return TRUE; - } /* * Allocate four separate buffers when the kernel doesn't support @@ -1265,21 +1238,6 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) if (!pI830->cursor_mem_argb[i]) return FALSE; - /* - * Set up the pointers into the allocations - */ - if (pI830->CursorNeedsPhysical) - { - intel_crtc->cursor_addr = pI830->cursor_mem_classic[i]->bus_addr; - intel_crtc->cursor_argb_addr = pI830->cursor_mem_argb[i]->bus_addr; - } - else - { - intel_crtc->cursor_addr = pI830->cursor_mem_classic[i]->offset; - intel_crtc->cursor_argb_addr = pI830->cursor_mem_argb[i]->offset; - } - intel_crtc->cursor_offset = pI830->cursor_mem_classic[i]->offset; - intel_crtc->cursor_argb_offset = pI830->cursor_mem_argb[i]->offset; } return TRUE; } @@ -1935,6 +1893,7 @@ i830_bind_all_memory(ScrnInfoPtr pScrn) } #endif } + i830_update_cursor_offsets(pScrn); return TRUE; }