summaryrefslogtreecommitdiff
path: root/src/amd_lx_dga.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/amd_lx_dga.c')
-rw-r--r--src/amd_lx_dga.c394
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)
+{
+}