diff -ruN xf86-video-r128-master.orig/src/Makefile.am xf86-video-r128-master/src/Makefile.am --- xf86-video-r128-master.orig/src/Makefile.am 2012-03-23 15:39:14.624681988 -0700 +++ xf86-video-r128-master/src/Makefile.am 2012-03-23 15:45:45.857398809 -0700 @@ -36,7 +36,7 @@ r128_drv_la_LDFLAGS = -module -avoid-version r128_drv_ladir = @moduledir@/drivers r128_drv_la_SOURCES = \ - r128_accel.c r128_cursor.c r128_dga.c r128_driver.c \ + r128_accel.c r128_cursor.c r128_dga.c r128_driver.c r128_exa.c \ r128_video.c r128_misc.c r128_probe.c $(R128_DRI_SRCS) EXTRA_DIST = \ diff -ruN xf86-video-r128-master.orig/src/r128.h xf86-video-r128-master/src/r128.h --- xf86-video-r128-master.orig/src/r128.h 2012-03-23 15:39:14.624681988 -0700 +++ xf86-video-r128-master/src/r128.h 2012-03-23 15:49:40.377692493 -0700 @@ -43,6 +43,9 @@ /* PCI support */ #include "xf86Pci.h" + /* EXA support */ +#include "exa.h" + /* XAA and Cursor Support */ #include "xaa.h" #include "xf86Cursor.h" @@ -69,7 +72,7 @@ #include "atipcirename.h" -#define R128_DEBUG 0 /* Turn off debugging output */ +#define R128_DEBUG 1 /* Turn off debugging output */ #define R128_IDLE_RETRY 32 /* Fall out of idle loops after this count */ #define R128_TIMEOUT 2000000 /* Fall out of wait loops after this count */ #define R128_MMIOSIZE 0x4000 @@ -77,6 +80,8 @@ #define R128_VBIOS_SIZE 0x00010000 #if R128_DEBUG +#include "r128_version.h" + #define R128TRACE(x) \ do { \ ErrorF("(**) %s(%d): ", R128_NAME, pScrn->scrnIndex); \ @@ -277,6 +282,11 @@ XAAInfoRecPtr accel; Bool accelOn; + + ExaDriverPtr ExaDriver; + XF86ModReqInfo exaReq; + Bool useEXA; + xf86CursorInfoPtr cursor; unsigned long cursor_start; unsigned long cursor_end; @@ -470,6 +480,7 @@ extern void R128WaitForVerticalSync(ScrnInfoPtr pScrn); extern Bool R128AccelInit(ScreenPtr pScreen); +extern Bool R128ExaInit(ScreenPtr pScreen); extern void R128EngineInit(ScrnInfoPtr pScrn); extern Bool R128CursorInit(ScreenPtr pScreen); extern Bool R128DGAInit(ScreenPtr pScreen); diff -ruN xf86-video-r128-master.orig/src/r128_accel.c xf86-video-r128-master/src/r128_accel.c --- xf86-video-r128-master.orig/src/r128_accel.c 2012-03-23 15:39:14.624681988 -0700 +++ xf86-video-r128-master/src/r128_accel.c 2012-03-23 17:59:59.705282864 -0700 @@ -1866,8 +1866,26 @@ R128InfoPtr info = R128PTR(pScrn); XAAInfoRecPtr a; - if (!xf86LoadSubModule(pScrn, "xaa")) - return FALSE; + if (info->useEXA) { + int errmaj = 0, errmin = 0; + + info->exaReq.majorversion = 2; + info->exaReq.minorversion = 0; + + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Loading EXA module...\n"); + if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &info->exaReq, &errmaj, &errmin)) { + LoaderErrorMsg(NULL, "exa", errmaj, errmin); + return FALSE; + } + + /* don't init EXA here because it'll be taken care of in mm init */ + info->ExaDriver = exaDriverAlloc(); + if (!info->ExaDriver) info->accel = FALSE; + + return TRUE; + } else { + if (!xf86LoadSubModule(pScrn, "xaa")) return FALSE; + } if (!(a = info->accel = XAACreateInfoRec())) return FALSE; diff -ruN xf86-video-r128-master.orig/src/r128_cursor.c xf86-video-r128-master/src/r128_cursor.c --- xf86-video-r128-master.orig/src/r128_cursor.c 2012-03-23 15:39:14.624681988 -0700 +++ xf86-video-r128-master/src/r128_cursor.c 2012-03-23 16:26:27.248487743 -0700 @@ -54,6 +54,9 @@ /* X and server generic header files */ #include "xf86.h" + /* Because for EXA we need to use a different allocator */ +#include "exa.h" + #if X_BYTE_ORDER == X_BIG_ENDIAN #define P_SWAP32( a , b ) \ ((char *)a)[0] = ((char *)b)[3]; \ @@ -253,10 +256,15 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; R128InfoPtr info = R128PTR(pScrn); xf86CursorInfoPtr cursor; - FBAreaPtr fbarea; + FBAreaPtr fbarea = NULL; + ExaOffscreenArea* osArea = NULL; int width; int height; int size; + int cpp = info->CurrentLayout.pixel_bytes; + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int x1, x2, y1, y2; if (!(cursor = info->cursor = xf86CreateCursorInfoRec())) return FALSE; @@ -284,24 +292,37 @@ size = (cursor->MaxWidth/4) * cursor->MaxHeight; width = pScrn->displayWidth; height = (size*2 + 1023) / pScrn->displayWidth; - fbarea = xf86AllocateOffscreenArea(pScreen, - width, - height, - 16, - NULL, - NULL, - NULL); + + if(!info->useEXA) { + fbarea = xf86AllocateOffscreenArea(pScreen, width, height, + 16, NULL, NULL, NULL); + + if (fbarea) { + x1 = fbarea->box.x1; + x2 = fbarea->box.x2; + y1 = fbarea->box.y1; + y2 = fbarea->box.y2; + } + } else { + osArea = exaOffscreenAlloc(pScreen, width * height, 16, + TRUE, NULL, NULL); + + if (osArea) { + x1 = osArea->offset % width_bytes; + x2 = (osArea->offset + osArea->size) % width_bytes; + y1 = osArea->offset / width_bytes; + y2 = (osArea->offset + osArea->size) / width_bytes; + } + } - if (!fbarea) { + if ((!info->useEXA && !fbarea) || (info->useEXA && !osArea)) { info->cursor_start = 0; xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Hardware cursor disabled" " due to insufficient offscreen memory\n"); } else { - info->cursor_start = R128_ALIGN((fbarea->box.x1 - + width * fbarea->box.y1) - * info->CurrentLayout.pixel_bytes, 16); - info->cursor_end = info->cursor_start + size; + info->cursor_start = x1 * cpp + y1 * pScrn->virtualX * cpp; + info->cursor_end = x2 * cpp + y2 * pScrn->virtualX * cpp; } R128TRACE(("R128CursorInit (0x%08x-0x%08x)\n", diff -ruN xf86-video-r128-master.orig/src/r128_dri.c xf86-video-r128-master/src/r128_dri.c --- xf86-video-r128-master.orig/src/r128_dri.c 2012-03-23 15:39:14.628015363 -0700 +++ xf86-video-r128-master/src/r128_dri.c 2012-03-24 11:10:11.756023827 -0700 @@ -305,6 +305,7 @@ R128InfoPtr info = R128PTR(pScrn); if (info->accel) info->accel->NeedToSync = TRUE; + if (info->ExaDriver) exaMarkSync(pScreen); } /* Called when the X server goes to sleep to allow the X server's @@ -1419,7 +1420,9 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; R128InfoPtr info = R128PTR(pScrn); R128SAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); - + + if (info->useEXA) return; + if (info->allowPageFlip) { /* Duplicate the frontbuffer to the backbuffer */ (*info->accel->SetupForScreenToScreenCopy)(pScrn, @@ -1471,6 +1474,8 @@ if (info->cursor_start) xf86ForceHWCursor(pScreen, TRUE); + + if (info->ExaDriver) exaMarkSync(pScreen); } static void R128DRITransitionTo2d(ScreenPtr pScreen) diff -ruN xf86-video-r128-master.orig/src/r128_driver.c xf86-video-r128-master/src/r128_driver.c --- xf86-video-r128-master.orig/src/r128_driver.c 2012-03-23 15:39:14.631348758 -0700 +++ xf86-video-r128-master/src/r128_driver.c 2012-03-23 18:27:39.404282987 -0700 @@ -156,7 +156,8 @@ OPTION_FBDEV, OPTION_VIDEO_KEY, OPTION_SHOW_CACHE, - OPTION_VGA_ACCESS + OPTION_VGA_ACCESS, + OPTION_ACCELMETHOD } R128Opts; static const OptionInfoRec R128Options[] = { @@ -184,6 +185,7 @@ { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, { OPTION_SHOW_CACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_VGA_ACCESS, "VGAAccess", OPTV_BOOLEAN, {0}, TRUE }, + { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -2185,6 +2187,26 @@ } } +Bool R128VerboseInitEXA(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + + xf86DrvMsg(scrnIndex, X_INFO, "Going to init EXA...\n"); + + if (R128EXAInit(pScreen)) { + xf86DrvMsg(scrnIndex, X_INFO, "EXA Acceleration enabled\n"); + info->accelOn = TRUE; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "EXA Acceleration initialization failed\n"); + xf86DrvMsg(scrnIndex, X_INFO, "EXA Acceleration disabled\n"); + info->accelOn = FALSE; + + return FALSE; + } +} + /* Called at the start of each server generation. */ Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) @@ -2192,8 +2214,23 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; R128InfoPtr info = R128PTR(pScrn); BoxRec MemBox; - int y2; + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int x1, x2, y1, y2; Bool noAccel; + ExaOffscreenArea* osArea; + char *optstr; + + info->useEXA = FALSE; + + optstr = (char *)xf86GetOptValString(info->Options, OPTION_ACCELMETHOD); + if (optstr != NULL) { + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"AccelMethod option found\n"); + if (xf86NameCmp(optstr, "EXA") == 0) { + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"AccelMethod is set to EXA, turning EXA on\n"); + info->useEXA = TRUE; + } + } R128TRACE(("R128ScreenInit %x %d\n", pScrn->memPhysBase, pScrn->fbOffset)); @@ -2245,8 +2282,6 @@ /* FIXME: When we move to dynamic allocation of back and depth buffers, we will want to revisit the following check for 3 times the virtual size of the screen below. */ - int width_bytes = (pScrn->displayWidth * - info->CurrentLayout.pixel_bytes); int maxy = info->FbMapSize / width_bytes; if (noAccel) { @@ -2318,6 +2353,22 @@ /* must be after RGB order fixed */ fbPictureInit (pScreen, 0, 0); + + /* Acceleration setup */ + if (!noAccel) { + if (R128AccelInit(pScreen)) { + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); + info->accelOn = TRUE; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Acceleration initialization failed\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); + info->accelOn = FALSE; + } + } else { + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); + info->accelOn = FALSE; + } /* Memory manager setup */ #ifdef R128DRI @@ -2387,7 +2438,7 @@ info->textureOffset = 0; info->textureSize = 0; } - + total = info->FbMapSize - info->textureSize; scanlines = total / width_bytes; if (scanlines > 8191) scanlines = 8191; @@ -2402,50 +2453,91 @@ MemBox.x2 = pScrn->displayWidth; MemBox.y2 = scanlines; - if (!xf86InitFBManager(pScreen, &MemBox)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Memory manager initialization to (%d,%d) (%d,%d) failed\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - return FALSE; - } else { - int width, height; - - xf86DrvMsg(scrnIndex, X_INFO, - "Memory manager initialized to (%d,%d) (%d,%d)\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->displayWidth, - 2, 0, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved area from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); + if (!info->useEXA) { + if (!xf86InitFBManager(pScreen, &MemBox)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Memory manager initialization to (%d,%d) (%d,%d) failed\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + return FALSE; } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + int width, height; + + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->displayWidth, + 2, 0, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved area from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + } + if (xf86QueryLargestOffscreenArea(pScreen, &width, + &height, 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } } - if (xf86QueryLargestOffscreenArea(pScreen, &width, - &height, 0, 0, 0)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Filling in EXA memory info\n"); + info->ExaDriver->offScreenBase = pScrn->virtualY * width_bytes; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Filled in offs\n"); + + /* Don't give EXA the true full memory size, because the + textureSize sized chunk on the end is handled by DRI */ + info->ExaDriver->memorySize = total; + + R128VerboseInitEXA(scrnIndex, pScreen); + } + + /* Allocate the shared back buffer */ + if(!info->useEXA) { + fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY, + 32, NULL, NULL, NULL); + + if (fbarea) { + x1 = fbarea->box.x1; + x2 = fbarea->box.x2; + y1 = fbarea->box.y1; + y2 = fbarea->box.y2; + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Actually trying an EXA allocation...\n"); + osArea = exaOffscreenAlloc(pScreen, + pScrn->virtualX * pScrn->virtualY, + 32, TRUE, NULL, NULL); + + if (osArea) { + x1 = osArea->offset % width_bytes; + x2 = (osArea->offset + osArea->size) % width_bytes; + y1 = osArea->offset / width_bytes; + y2 = (osArea->offset + osArea->size) / width_bytes; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Went swimmingly...\n"); } } + + if ((!info->useEXA && fbarea) || (info->useEXA && osArea)) { + /* info->backOffset = y1 * width_bytes + x1 * cpp; */ + info->backOffset = R128_ALIGN(y1 * width_bytes + x1 * cpp, 16); + info->backX = info->backOffset % width_bytes; + info->backY = info->backOffset / width_bytes; + info->backPitch = pScrn->displayWidth; - /* Allocate the shared back buffer */ - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->virtualX, - pScrn->virtualY, - 32, NULL, NULL, NULL))) { xf86DrvMsg(scrnIndex, X_INFO, - "Reserved back buffer from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - - info->backX = fbarea->box.x1; - info->backY = fbarea->box.y1; - info->backOffset = (fbarea->box.y1 * width_bytes + - fbarea->box.x1 * cpp); - info->backPitch = pScrn->displayWidth; + "Reserved back buffer from (%d,%d) to (%d,%d) offset: %x\n", + x1, y1, + x2, y2, info->backOffset); } else { xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); info->backX = -1; @@ -2455,25 +2547,46 @@ } /* Allocate the shared depth buffer */ - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->virtualX, - pScrn->virtualY + 1, - 32, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved depth buffer from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - - info->depthX = fbarea->box.x1; - info->depthY = fbarea->box.y1; - info->depthOffset = (fbarea->box.y1 * width_bytes + - fbarea->box.x1 * cpp); + if(!info->useEXA) { + fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY + 1, + 32, NULL, NULL, NULL); + if (fbarea) { + x1 = fbarea->box.x1; + x2 = fbarea->box.x2; + y1 = fbarea->box.y1; + y2 = fbarea->box.y2; + } + } else { + osArea = exaOffscreenAlloc(pScreen, + pScrn->virtualX * (pScrn->virtualY+1), + 32, TRUE, NULL, NULL); + + if (osArea) { + x1 = osArea->offset % width_bytes; + x2 = (osArea->offset + osArea->size) % width_bytes; + y1 = osArea->offset / width_bytes; + y2 = (osArea->offset + osArea->size) / width_bytes; + } + } + + if ((!info->useEXA && fbarea) || (info->useEXA && osArea)) { + /* info->depthOffset = y1 * width_bytes + x1 * cpp; */ + info->depthOffset = R128_ALIGN(y1 * width_bytes + x1 * cpp, 16); + info->depthX = info->depthOffset % width_bytes; + info->depthY = info->depthOffset / width_bytes; info->depthPitch = pScrn->displayWidth; - info->spanOffset = ((fbarea->box.y2 - 1) * width_bytes + - fbarea->box.x1 * cpp); + info->spanOffset = (y2 - 1) * width_bytes + x1 * cpp; + + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved depth buffer from (%d,%d) to (%d,%d) offset: %x\n", + x1, y1, + x2, y2, info->depthOffset); + xf86DrvMsg(scrnIndex, X_INFO, "Reserved depth span from (%d,%d) offset 0x%x\n", - fbarea->box.x1, fbarea->box.y2 - 1, info->spanOffset); + x1, y2 - 1, info->spanOffset); } else { xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve depth buffer\n"); info->depthX = -1; @@ -2501,51 +2614,39 @@ drawable caches beyond this region. */ if (y2 > 8191) y2 = 8191; MemBox.y2 = y2; - - if (!xf86InitFBManager(pScreen, &MemBox)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Memory manager initialization to (%d,%d) (%d,%d) failed\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - return FALSE; - } else { - int width, height; - FBAreaPtr fbarea; - - xf86DrvMsg(scrnIndex, X_INFO, - "Memory manager initialized to (%d,%d) (%d,%d)\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - if ((fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, - 2, 0, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved area from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); + + if (!info->useEXA) { + if (!xf86InitFBManager(pScreen, &MemBox)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Memory manager initialization to (%d,%d) (%d,%d) failed\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + return FALSE; } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); - } - if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, - 0, 0, 0)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height); - } - } - } + int width, height; + FBAreaPtr fbarea; - /* Acceleration setup */ - if (!noAccel) { - if (R128AccelInit(pScreen)) { - xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); - info->accelOn = TRUE; + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, 2, 0, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved area from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + } + if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Acceleration initialization failed\n"); - xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); - info->accelOn = FALSE; + info->ExaDriver->offScreenBase = width_bytes * pScrn->virtualY; + info->ExaDriver->memorySize = info->FbMapSize; + R128VerboseInitEXA(scrnIndex, pScreen); } - } else { - xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); - info->accelOn = FALSE; } /* DGA setup */ @@ -2897,16 +2998,6 @@ | R128_P2PLL_ATOMIC_UPDATE_EN | R128_P2PLL_VGA_ATOMIC_UPDATE_EN)); - R128TRACE(("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", - restore->p2pll_ref_div, - restore->p2pll_div_0, - restore->htotal_cntl2, - INPLL(pScrn, RADEON_P2PLL_CNTL))); - R128TRACE(("Wrote: rd=%d, fd=%d, pd=%d\n", - restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK, - restore->p2pll_div_0 & RADEON_P2PLL_FB3_DIV_MASK, - (restore->p2pll_div_0 & RADEON_P2PLL_POST3_DIV_MASK) >>16)); - usleep(5000); /* Let the clock to lock */ OUTPLLP(pScrn, R128_V2CLK_VCLKTV_CNTL, @@ -3793,12 +3884,6 @@ pll->reference_freq); save->post_div_2 = post_div->divider; - R128TRACE(("dc=%d, of=%d, fd=%d, pd=%d\n", - save->dot_clock_freq_2, - save->pll_output_freq_2, - save->feedback_div_2, - save->post_div_2)); - save->p2pll_ref_div = pll->reference_div; save->p2pll_div_0 = (save->feedback_div_2 | (post_div->bitvalue<<16)); save->htotal_cntl2 = 0; diff -ruN xf86-video-r128-master.orig/src/r128_exa.c xf86-video-r128-master/src/r128_exa.c --- xf86-video-r128-master.orig/src/r128_exa.c 1969-12-31 16:00:00.000000000 -0800 +++ xf86-video-r128-master/src/r128_exa.c 2012-03-24 16:28:39.151514504 -0700 @@ -0,0 +1,367 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "r128.h" +#include "exa.h" + +#include "r128_reg.h" + +#include "xf86.h" + +static struct { + int rop; + int pattern; +} R128_ROP[] = { + { R128_ROP3_ZERO, R128_ROP3_ZERO }, /* GXclear */ + { R128_ROP3_DSa, R128_ROP3_DPa }, /* Gxand */ + { R128_ROP3_SDna, R128_ROP3_PDna }, /* GXandReverse */ + { R128_ROP3_S, R128_ROP3_P }, /* GXcopy */ + { R128_ROP3_DSna, R128_ROP3_DPna }, /* GXandInverted */ + { R128_ROP3_D, R128_ROP3_D }, /* GXnoop */ + { R128_ROP3_DSx, R128_ROP3_DPx }, /* GXxor */ + { R128_ROP3_DSo, R128_ROP3_DPo }, /* GXor */ + { R128_ROP3_DSon, R128_ROP3_DPon }, /* GXnor */ + { R128_ROP3_DSxn, R128_ROP3_PDxn }, /* GXequiv */ + { R128_ROP3_Dn, R128_ROP3_Dn }, /* GXinvert */ + { R128_ROP3_SDno, R128_ROP3_PDno }, /* GXorReverse */ + { R128_ROP3_Sn, R128_ROP3_Pn }, /* GXcopyInverted */ + { R128_ROP3_DSno, R128_ROP3_DPno }, /* GXorInverted */ + { R128_ROP3_DSan, R128_ROP3_DPan }, /* GXnand */ + { R128_ROP3_ONE, R128_ROP3_ONE } /* GXset */ +}; + +static Bool +R128PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + unsigned long pxPitch = exaGetPixmapPitch(pPixmap); + unsigned long pxOffset = exaGetPixmapOffset(pPixmap); + int bpp = pPixmap->drawable.bitsPerPixel; + CARD32 regValue; + + regValue = ((pxPitch / bpp) << 21) | (pxOffset >> 5); + + + R128WaitForFifo(pScrn, 5); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_DST_PITCH_OFFSET_CNTL + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[alu].pattern)); + OUTREG(R128_DP_BRUSH_FRGD_CLR, fg); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT + | R128_DST_Y_TOP_TO_BOTTOM)); + OUTREG(R128_DST_PITCH_OFFSET, regValue); + return TRUE; +} + +static void +R128Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 2); + OUTREG(R128_DST_Y_X, (y1 << 16) | x1); + OUTREG(R128_DST_WIDTH_HEIGHT, ((x2-x1) << 16) | (y2-y1)); +} + +static void +R128DoneSolid(PixmapPtr pPixmap) +{ +} + +static Bool +R128PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, + int alu, Pixel planemask) +{ + ScreenPtr pScreen = pSrcPixmap->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + unsigned long srcpxPitch = exaGetPixmapPitch(pSrcPixmap); + unsigned long srcpxOffset = exaGetPixmapOffset(pSrcPixmap); + int srcbpp = pSrcPixmap->drawable.bitsPerPixel; + CARD32 srcRegValue; + + unsigned long dstpxPitch = exaGetPixmapPitch(pDstPixmap); + unsigned long dstpxOffset = exaGetPixmapOffset(pDstPixmap); + int dstbpp = pDstPixmap->drawable.bitsPerPixel; + CARD32 dstRegValue; + + dstRegValue = ((dstpxPitch / dstbpp) << 21) | (dstpxOffset >> 5); + srcRegValue = ((srcpxPitch / srcbpp) << 21) | (srcpxOffset >> 5); + + info->xdir = xdir; + info->ydir = ydir; + R128WaitForFifo(pScrn, 5); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[alu].rop + | R128_DP_SRC_SOURCE_MEMORY)); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_CNTL, ((xdir >= 0 ? R128_DST_X_LEFT_TO_RIGHT : 0) + | (ydir >= 0 + ? R128_DST_Y_TOP_TO_BOTTOM + : 0))); + OUTREG(R128_DST_PITCH_OFFSET, dstRegValue); + OUTREG(R128_SRC_PITCH_OFFSET, srcRegValue); + + return TRUE; +} + +static void +R128Copy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, + int width, int height) +{ + ScreenPtr pScreen = pDstPixmap->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + if (info->xdir < 0) srcX += width - 1, dstX += width - 1; + if (info->ydir < 0) srcY += height - 1, dstY += height - 1; + + R128WaitForFifo(pScrn, 3); + OUTREG(R128_SRC_Y_X, (srcY << 16) | srcX); + OUTREG(R128_DST_Y_X, (dstY << 16) | dstX); + OUTREG(R128_DST_HEIGHT_WIDTH, (height << 16) | width); +} + +static void +R128DoneCopy(PixmapPtr pPixmap) +{ +} + +static void +R128Sync(ScreenPtr pScreen, int marker) +{ + R128WaitForIdle(xf86Screens[pScreen->myNum]); +} + +#ifdef R128DRI +static Bool +R128CCEPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + unsigned long pxPitch = exaGetPixmapPitch(pPixmap); + unsigned long pxOffset = exaGetPixmapOffset(pPixmap); + int bpp = pPixmap->drawable.bitsPerPixel; + CARD32 regValue; + RING_LOCALS; + + regValue = ((pxPitch / bpp) << 21) | (pxOffset >> 5); + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( 10 ); + + OUT_RING_REG( R128_DP_GUI_MASTER_CNTL, + (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[alu].pattern) ); + + OUT_RING_REG( R128_DP_BRUSH_FRGD_CLR, fg ); + OUT_RING_REG( R128_DP_WRITE_MASK, planemask ); + OUT_RING_REG( R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT | + R128_DST_Y_TOP_TO_BOTTOM)); + + OUT_RING_REG(R128_DST_PITCH_OFFSET, regValue); + + ADVANCE_RING(); + + return TRUE; +} + +static void +R128CCESolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + BEGIN_RING( 4 ); + + OUT_RING_REG(R128_DST_Y_X, (y1 << 16) | x1); + OUT_RING_REG(R128_DST_WIDTH_HEIGHT, ((x2-x1) << 16) | (y2-y1)); + + ADVANCE_RING(); +} + + +static void +R128CCEDoneSolid(PixmapPtr pPixmap) +{ +} + +static Bool +R128CCEPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, + int alu, Pixel planemask) +{ + ScreenPtr pScreen = pSrcPixmap->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + + unsigned long srcpxPitch = exaGetPixmapPitch(pSrcPixmap); + unsigned long srcpxOffset = exaGetPixmapOffset(pSrcPixmap); + int srcbpp = pSrcPixmap->drawable.bitsPerPixel; + CARD32 srcRegValue; + + unsigned long dstpxPitch = exaGetPixmapPitch(pDstPixmap); + unsigned long dstpxOffset = exaGetPixmapOffset(pDstPixmap); + int dstbpp = pDstPixmap->drawable.bitsPerPixel; + CARD32 dstRegValue; + + RING_LOCALS; + + dstRegValue = ((dstpxPitch / dstbpp) << 21) | (dstpxOffset >> 5); + srcRegValue = ((srcpxPitch / srcbpp) << 21) | (srcpxOffset >> 5); + + R128CCE_REFRESH( pScrn, info ); + + info->xdir = xdir; + info->ydir = ydir; + + BEGIN_RING( 10 ); + + OUT_RING_REG( R128_DP_GUI_MASTER_CNTL, + (info->dp_gui_master_cntl + | R128_GMC_BRUSH_NONE + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[alu].rop + | R128_DP_SRC_SOURCE_MEMORY) ); + + OUT_RING_REG( R128_DP_WRITE_MASK, planemask ); + OUT_RING_REG( R128_DP_CNTL, + ((xdir >= 0 ? R128_DST_X_LEFT_TO_RIGHT : 0) | + (ydir >= 0 ? R128_DST_Y_TOP_TO_BOTTOM : 0)) ); + + OUT_RING_REG(R128_DST_PITCH_OFFSET, dstRegValue); + OUT_RING_REG(R128_SRC_PITCH_OFFSET, srcRegValue); + + ADVANCE_RING(); + + return TRUE; +} + +static void +R128CCECopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, + int width, int height) +{ + ScreenPtr pScreen = pDstPixmap->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + RING_LOCALS; + + R128CCE_REFRESH( pScrn, info ); + + if (info->xdir < 0) srcX += width - 1, dstX += width - 1; + if (info->ydir < 0) srcY += height - 1, dstY += height - 1; + + BEGIN_RING( 6 ); + + OUT_RING_REG( R128_SRC_Y_X, (srcY << 16) | srcX ); + OUT_RING_REG( R128_DST_Y_X, (dstY << 16) | dstX ); + OUT_RING_REG( R128_DST_HEIGHT_WIDTH, (height << 16) | width ); + + ADVANCE_RING(); +} + +static void +R128CCEDoneCopy(PixmapPtr pPixmap) +{ +} + +static void +R128CCESync(ScreenPtr pScreen, int marker) +{ + R128CCEWaitForIdle(xf86Screens[pScreen->myNum]); +} +#endif + +Bool +R128EXAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Allocating EXA driver...\n"); + + + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "EXA driver allocated...\n"); + + info->ExaDriver->exa_major = 2; + info->ExaDriver->exa_minor = 0; + + info->ExaDriver->flags = EXA_OFFSCREEN_PIXMAPS; + info->ExaDriver->memoryBase = info->FB + pScrn->fbOffset; + + /* Pitch alignment is in sets of 32 pixels, and we need to cover 32bpp, so it's 128 bytes */ + info->ExaDriver->pixmapPitchAlign = 128; + + /* Taken from radeon driver */ + info->ExaDriver->pixmapOffsetAlign = 4096; + info->ExaDriver->maxX = 8191; + info->ExaDriver->maxY = 8191; + + info->ExaDriver->PrepareAccess = NULL; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Setting up EXA callbacks\n"); + +#ifdef R128DRI + if (info->directRenderingEnabled) { + info->ExaDriver->PrepareSolid = R128CCEPrepareSolid; + info->ExaDriver->Solid = R128CCESolid; + info->ExaDriver->DoneSolid = R128CCEDoneSolid; + + info->ExaDriver->PrepareCopy = R128CCEPrepareCopy; + info->ExaDriver->Copy = R128CCECopy; + info->ExaDriver->DoneCopy = R128CCEDoneCopy; + + info->ExaDriver->WaitMarker = R128CCESync; + } else +#endif + { + info->ExaDriver->PrepareSolid = R128PrepareSolid; + info->ExaDriver->Solid = R128Solid; + info->ExaDriver->DoneSolid = R128DoneSolid; + + info->ExaDriver->PrepareCopy = R128PrepareCopy; + info->ExaDriver->Copy = R128Copy; + info->ExaDriver->DoneCopy = R128DoneCopy; + + info->ExaDriver->WaitMarker = R128Sync; + } + + info->ExaDriver->PrepareComposite = NULL; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Initalizing 2D acceleration engine...\n"); + + R128EngineInit(pScrn); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Initializing EXA driver...\n"); + + return (exaDriverInit(pScreen, info->ExaDriver)); +} diff -ruN xf86-video-r128-master.orig/src/r128_video.c xf86-video-r128-master/src/r128_video.c --- xf86-video-r128-master.orig/src/r128_video.c 2012-03-23 15:39:14.688016327 -0700 +++ xf86-video-r128-master/src/r128_video.c 2012-03-24 16:10:44.311559065 -0700 @@ -56,7 +56,8 @@ int saturation; Bool doubleBuffer; unsigned char currentBuffer; - FBLinearPtr linear; + void* BufferHandle; + int videoOffset; RegionRec clip; CARD32 colorKey; CARD32 videoStatus; @@ -270,9 +271,13 @@ if(pPriv->videoStatus & CLIENT_VIDEO_ON) { OUTREG(R128_OV0_SCALE_CNTL, 0); } - if(pPriv->linear) { - xf86FreeOffscreenLinear(pPriv->linear); - pPriv->linear = NULL; + if(pPriv->BufferHandle) { + if (!info->useEXA) { + xf86FreeOffscreenLinear((FBLinearPtr) pPriv->BufferHandle); + } else { + exaOffscreenFree(pScrn->pScreen, (ExaOffscreenArea *) pPriv->BufferHandle); + } + pPriv->BufferHandle = NULL; } pPriv->videoStatus = 0; } else { @@ -564,45 +569,75 @@ } -static FBLinearPtr +static CARD32 R128AllocateMemory( ScrnInfoPtr pScrn, - FBLinearPtr linear, + void **mem_struct, int size ){ - ScreenPtr pScreen; - FBLinearPtr new_linear; + R128InfoPtr info = R128PTR(pScrn); + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];; + int offset = 0; - if(linear) { - if(linear->size >= size) - return linear; + if(!info->useEXA) { + FBLinearPtr linear = *mem_struct; + int cpp = info->CurrentLayout.pixel_bytes; + + /* XAA allocates in units of pixels at the screen bpp, so adjust size appropriately. */ + size = (size + cpp - 1) / cpp; + + if(linear) { + if(linear->size >= size) + return linear->offset * cpp; - if(xf86ResizeOffscreenLinear(linear, size)) - return linear; + if(xf86ResizeOffscreenLinear(linear, size)) + return linear->offset * cpp; - xf86FreeOffscreenLinear(linear); - } + xf86FreeOffscreenLinear(linear); + } - pScreen = screenInfo.screens[pScrn->scrnIndex]; - new_linear = xf86AllocateOffscreenLinear(pScreen, size, 8, + linear = xf86AllocateOffscreenLinear(pScreen, size, 8, NULL, NULL, NULL); + *mem_struct = linear; - if(!new_linear) { - int max_size; + if(!linear) { + int max_size; - xf86QueryLargestOffscreenLinear(pScreen, &max_size, 8, + xf86QueryLargestOffscreenLinear(pScreen, &max_size, 8, PRIORITY_EXTREME); - if(max_size < size) - return NULL; + if(max_size < size) + return NULL; - xf86PurgeUnlockedOffscreenAreas(pScreen); - new_linear = xf86AllocateOffscreenLinear(pScreen, size, 8, + xf86PurgeUnlockedOffscreenAreas(pScreen); + linear = xf86AllocateOffscreenLinear(pScreen, size, 8, NULL, NULL, NULL); + + if(!linear) return 0; + } + + offset = linear->offset * cpp; + } else { + /* EXA support based on mga driver */ + ExaOffscreenArea *area = *mem_struct; + + if(area) { + if(area->size >= size) + return area->offset; + + exaOffscreenFree(pScrn->pScreen, area); + } + + area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE, NULL, NULL); + *mem_struct = area; + + if(!area) return 0; + + offset = area->offset; } - return new_linear; + return offset; } static void @@ -841,7 +876,7 @@ srcPitch = (width + 3) & ~3; srcPitch2 = ((width >> 1) + 3) & ~3; dstPitch = (width + 31) & ~31; /* of luma */ - new_size = ((dstPitch * (height + (height >> 1))) + bpp - 1) / bpp; + new_size = dstPitch * (height + (height >> 1)); s1offset = 0; s2offset = srcPitch * height; s3offset = (srcPitch2 * (height >> 1)) + s2offset; @@ -852,14 +887,14 @@ srcPitch = width << 1; srcPitch2 = 0; dstPitch = ((width << 1) + 15) & ~15; - new_size = ((dstPitch * height) + bpp - 1) / bpp; + new_size = dstPitch * height; s1offset = 0; s2offset = 0; s3offset = 0; break; } - if(!(pPriv->linear = R128AllocateMemory(pScrn, pPriv->linear, + if(!(pPriv->videoOffset = R128AllocateMemory(pScrn, &(pPriv->BufferHandle), pPriv->doubleBuffer ? (new_size << 1) : new_size))) { return BadAlloc; @@ -872,9 +907,9 @@ left = (xa >> 16) & ~1; npixels = ((((xb + 0xffff) >> 16) + 1) & ~1) - left; - offset = pPriv->linear->offset * bpp; + offset = pPriv->videoOffset; if(pPriv->doubleBuffer) - offset += pPriv->currentBuffer * new_size * bpp; + offset += pPriv->currentBuffer * new_size; switch(id) { case FOURCC_YV12: @@ -1015,9 +1050,13 @@ } } else { /* FREE_TIMER */ if(pPriv->freeTime < now) { - if(pPriv->linear) { - xf86FreeOffscreenLinear(pPriv->linear); - pPriv->linear = NULL; + if(pPriv->BufferHandle) { + if (!info->useEXA) { + xf86FreeOffscreenLinear((FBLinearPtr) pPriv->BufferHandle); + } else { + exaOffscreenAreaFree(pScrn->pScreen, (ExaOffscreenArea *) pPriv->BufferHandle); + } + pPriv->BufferHandle = NULL; } pPriv->videoStatus = 0; info->VideoTimerCallback = NULL;