diff options
Diffstat (limited to 'src/amd_lx_dga.c')
-rw-r--r-- | src/amd_lx_dga.c | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/src/amd_lx_dga.c b/src/amd_lx_dga.c new file mode 100644 index 0000000..02320ec --- /dev/null +++ b/src/amd_lx_dga.c @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2006 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Neither the name of the Advanced Micro Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + */ + +/* + * File contents: DGA(Direct Acess Graphics mode) is feature of + * XFree86 that allows the program to access directly to video + * memory on the graphics card. DGA supports the double + * flickering. This file has the functions to support the DGA + * modes. + * + * Project: Geode Xfree Frame buffer device driver. + * + */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "xaa.h" +#include "xaalocal.h" +#include "amd.h" +#include "dgaproc.h" + +/* forward declarations */ +Bool LXDGAInit(ScreenPtr pScrn); +static Bool LX_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, + int *, int *, int *); +static void LX_CloseFramebuffer(ScrnInfoPtr pScrni); +static Bool LX_SetMode(ScrnInfoPtr, DGAModePtr); +static int LX_GetViewport(ScrnInfoPtr); +static void LX_SetViewport(ScrnInfoPtr, int, int, int); +static void LX_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); +static void LX_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); + +extern void LXAdjustFrame(int, int, int, int); +extern Bool LXSwitchMode(int, DisplayModePtr, int); +extern void LXAccelSync(ScrnInfoPtr pScrni); + +static DGAFunctionRec LXDGAFuncs = { + LX_OpenFramebuffer, + LX_CloseFramebuffer, + LX_SetMode, + LX_SetViewport, + LX_GetViewport, + LXAccelSync, + LX_FillRect, + LX_BlitRect, + NULL +}; + +/*---------------------------------------------------------------------------- + * LXDGAInit. + * + * Description :This function is used to initialize the DGA modes and sets + * the viewport based on the screen mode. + * Parameters. + * pScreeen :Pointer to screen info structure. + * + * Returns :TRUE on success and FALSE on failure. + * + * Comments :This function prepares the DGA mode settings for + * other func reference. + * +*---------------------------------------------------------------------------- +*/ +Bool +LXDGAInit(ScreenPtr pScrn) +{ + ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + DGAModePtr modes = NULL, newmodes = NULL, currentMode; + DisplayModePtr pMode, firstMode; + int Bpp = pScrni->bitsPerPixel >> 3; + int num = 0; + Bool oneMore; + + pMode = firstMode = pScrni->modes; + DEBUGMSG(0, (0, X_NONE, "LXDGAInit %d\n", Bpp)); + while (pMode) { + /* one record is allocated here */ + newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); + oneMore = FALSE; + + if (!newmodes) { + xfree(modes); + return FALSE; + } + + modes = newmodes; + + SECOND_PASS: /* DGA mode flgas and viewport parametrs are set here. */ + currentMode = modes + num; + num++; + currentMode->mode = pMode; + currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; + currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; + if (pMode->Flags & V_DBLSCAN) + currentMode->flags |= DGA_DOUBLESCAN; + if (pMode->Flags & V_INTERLACE) + currentMode->flags |= DGA_INTERLACED; + currentMode->byteOrder = pScrni->imageByteOrder; + currentMode->depth = pScrni->depth; + currentMode->bitsPerPixel = pScrni->bitsPerPixel; + currentMode->red_mask = pScrni->mask.red; + currentMode->green_mask = pScrni->mask.green; + currentMode->blue_mask = pScrni->mask.blue; + currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; + currentMode->viewportWidth = pMode->HDisplay; + currentMode->viewportHeight = pMode->VDisplay; + currentMode->xViewportStep = 1; + currentMode->yViewportStep = 1; + currentMode->viewportFlags = DGA_FLIP_RETRACE; + currentMode->offset = 0; + currentMode->address = pGeode->FBBase; + if (oneMore) { /* first one is narrow width */ + currentMode->bytesPerScanline = + ((pMode->HDisplay * Bpp) + 3) & ~3L; + currentMode->imageWidth = pMode->HDisplay; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + oneMore = FALSE; + goto SECOND_PASS; + } else { + currentMode->bytesPerScanline = + ((pScrni->displayWidth * Bpp) + 3) & ~3L; + currentMode->imageWidth = pScrni->displayWidth; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + } + pMode = pMode->next; + if (pMode == firstMode) + break; + } + pGeode->numDGAModes = num; + pGeode->DGAModes = modes; + + return DGAInit(pScrn, &LXDGAFuncs, modes, num); +} + +/*---------------------------------------------------------------------------- + * LX_SetMode. + * + * Description :This function is sets into the DGA mode. + *. + * Parameters. + * pScreeen :Pointer to screen info structure. + * pMode :Points to the DGAmode ptr data + * Returns :TRUE on success and FALSE on failure. + * + * Comments :none. + * + * +*---------------------------------------------------------------------------- +*/ +static Bool +LX_SetMode(ScrnInfoPtr pScrni, DGAModePtr pMode) +{ + static int OldDisplayWidth[MAXSCREENS]; + int index = pScrni->pScreen->myNum; + GeodeRec *pGeode = GEODEPTR(pScrni); + + DEBUGMSG(0, (0, X_NONE, "LX_SetMode\n")); + + if (!pMode) { + /* restore the original mode + * put the ScreenParameters back + */ + pScrni->displayWidth = OldDisplayWidth[index]; + DEBUGMSG(0, + (0, X_NONE, "LX_SetMode !pMode %d\n", pScrni->displayWidth)); + LXSwitchMode(index, pScrni->currentMode, 0); + pGeode->DGAactive = FALSE; + } else { + if (!pGeode->DGAactive) { /* save the old parameters */ + OldDisplayWidth[index] = pScrni->displayWidth; + pGeode->DGAactive = TRUE; + DEBUGMSG(0, (0, X_NONE, "LX_SetMode pMode+ NA %d\n", + pScrni->displayWidth)); + } + pGeode->PrevDisplayOffset = vg_get_display_offset(); + + pScrni->displayWidth = pMode->bytesPerScanline / + (pMode->bitsPerPixel >> 3); + DEBUGMSG(0, (0, X_NONE, + "LX_SetMode pMode+ %d\n", pScrni->displayWidth)); + LXSwitchMode(index, pMode->mode, 0); + } + /* enable/disable Compression */ + if (pGeode->Compression) { + vg_set_compression_enable(!pGeode->DGAactive); + } + + /* enable/disable cursor */ + if (pGeode->HWCursor) { + vg_set_cursor_enable(!pGeode->DGAactive); + } + + return TRUE; +} + +/*---------------------------------------------------------------------------- + * LX_GetViewPort. + * + * Description :This function is Gets the viewport window memory. + *. + * Parameters. + * pScrni :Pointer to screen info structure. + * + * Returns :returns the viewport status. + * + * Comments :none. + * + * +*---------------------------------------------------------------------------- +*/ +static int +LX_GetViewport(ScrnInfoPtr pScrni) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + + return pGeode->DGAViewportStatus; +} + +/*---------------------------------------------------------------------------- + * LX_SetViewPort. + * + * Description :This function is Gets the viewport window memory. + * + * Parameters. + * pScrni :Pointer to screen info structure. + x :x-cordinate of viewport window + * y :y-codinate of the viewport window. + * flags :indicates the viewport to be flipped or not. + * Returns :returns the viewport status as zero. + * + * Comments :none. + * +*---------------------------------------------------------------------------- +*/ +static void +LX_SetViewport(ScrnInfoPtr pScrni, int x, int y, int flags) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + + LXAdjustFrame(pScrni->pScreen->myNum, x, y, flags); + pGeode->DGAViewportStatus = 0; /* LXAdjustFrame loops until finished */ +} + +/*---------------------------------------------------------------------------- + * LX_FillRect. + * + * Description :This function is Gets the viewport window memory. + *. + * Parameters. + * pScrni :Pointer to screen info structure. + * x :x-cordinate of viewport window + * y :y-codinate of the viewport window. + * w :width of the rectangle + * h :height of the rectangle. + * color :color to be filled in rectangle. + * + * Returns :returns the viewport status as zero. + * + * Comments :This function is implemented by solidfill routines.. + * +*---------------------------------------------------------------------------- +*/ +static void +LX_FillRect(ScrnInfoPtr pScrni, int x, int y, + int w, int h, unsigned long color) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + + if (pGeode->AccelInfoRec) { + (*pGeode->AccelInfoRec->SetupForSolidFill) (pScrni, color, GXcopy, + ~0); + (*pGeode->AccelInfoRec->SubsequentSolidFillRect) (pScrni, x, y, w, h); + SET_SYNC_FLAG(pGeode->AccelInfoRec); + } +} + +/*---------------------------------------------------------------------------- + * LX_BlitRect. + * + * Description :This function implementing Blit and it moves a + * Rectangular block of data from one location to other + * Location. + * + * Parameters. + * pScrni :Pointer to screen info structure. + * srcx :x-cordinate of the src rectangle + * srcy :y-codinate of src rectangle. + * w :width of the rectangle + * h :height of the rectangle. + * dstx :x-cordinate of the dst rectangle. + * dsty :y -coordinates of the dst rectangle. + * Returns :none. + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static void +LX_BlitRect(ScrnInfoPtr pScrni, + int srcx, int srcy, int w, int h, int dstx, int dsty) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + + if (pGeode->AccelInfoRec) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + + (*pGeode->AccelInfoRec->SetupForScreenToScreenCopy) + (pScrni, xdir, ydir, GXcopy, ~0, -1); + (*pGeode->AccelInfoRec->SubsequentScreenToScreenCopy) + (pScrni, srcx, srcy, dstx, dsty, w, h); + SET_SYNC_FLAG(pGeode->AccelInfoRec); + } +} + +/*---------------------------------------------------------------------------- + * LX_OpenFramebuffer. + * + * Description :This function open the framebuffer driver for DGA. + * + * Parameters. + * pScrni :Pointer to screen info structure. + * srcx :x-cordinate of the src rectangle + * srcy :y-codinate of src rectangle. + * w :width of the rectangle + * h :height of the rectangle. + * dstx :x-cordinate of the dst rectangle. + * dsty :y -coordinates of the dst rectangle. + * Returns :none. + * + * Comments :none + * +*---------------------------------------------------------------------------- +*/ +static Bool +LX_OpenFramebuffer(ScrnInfoPtr pScrni, + char **name, unsigned char **mem, int *size, int *offset, int *flags) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + + *name = NULL; /* no special device */ + *mem = (unsigned char *)pGeode->FBLinearAddr; + *size = pGeode->FBAvail; + *offset = 0; + *flags = DGA_NEED_ROOT; + + return TRUE; +} + +static void +LX_CloseFramebuffer(ScrnInfoPtr pScrni) +{ +} |