1301ea0f4Smrg/* 2301ea0f4Smrg * Copyright 2001 by Patrick LERDA 3301ea0f4Smrg * 4301ea0f4Smrg * Permission to use, copy, modify, distribute, and sell this software and its 5301ea0f4Smrg * documentation for any purpose is hereby granted without fee, provided that 6301ea0f4Smrg * the above copyright notice appear in all copies and that both that 7301ea0f4Smrg * copyright notice and this permission notice appear in supporting 8301ea0f4Smrg * documentation, and that the name of Patrick LERDA not be used in 9301ea0f4Smrg * advertising or publicity pertaining to distribution of the software without 10301ea0f4Smrg * specific, written prior permission. Patrick LERDA makes no representations 11301ea0f4Smrg * about the suitability of this software for any purpose. It is provided 12301ea0f4Smrg * "as is" without express or implied warranty. 13301ea0f4Smrg * 14301ea0f4Smrg * PATRICK LERDA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15301ea0f4Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16301ea0f4Smrg * EVENT SHALL PATRICK LERDA BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17301ea0f4Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18301ea0f4Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19301ea0f4Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20301ea0f4Smrg * PERFORMANCE OF THIS SOFTWARE. 21301ea0f4Smrg * 22301ea0f4Smrg * Authors: Patrick LERDA 23301ea0f4Smrg */ 24301ea0f4Smrg 25301ea0f4Smrg#ifdef HAVE_CONFIG_H 26301ea0f4Smrg#include "config.h" 27301ea0f4Smrg#endif 28301ea0f4Smrg 29301ea0f4Smrg#include "xf86.h" 30301ea0f4Smrg#include "xf86_OSproc.h" 31301ea0f4Smrg#include "xf86Pci.h" 32301ea0f4Smrg#include "vgaHW.h" 33301ea0f4Smrg#include "xf86xv.h" 34301ea0f4Smrg#include "i740.h" 35213fdd94Smrg#ifdef HAVE_XAA_H 36213fdd94Smrg#include "xaalocal.h" 37213fdd94Smrg#endif 38301ea0f4Smrg#include "dgaproc.h" 39301ea0f4Smrg#include "i740_dga.h" 40301ea0f4Smrg 41301ea0f4Smrgstatic Bool I740_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, int *, int *, int *); 42301ea0f4Smrgstatic Bool I740_SetMode(ScrnInfoPtr, DGAModePtr); 43301ea0f4Smrgstatic int I740_GetViewport(ScrnInfoPtr); 44301ea0f4Smrgstatic void I740_SetViewport(ScrnInfoPtr, int, int, int); 45213fdd94Smrg#ifdef HAVE_XAA_H 4634d2f1a1Schristosstatic void I740_Sync(ScrnInfoPtr); 47301ea0f4Smrgstatic void I740_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 48301ea0f4Smrgstatic void I740_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 49301ea0f4Smrg#if 0 50301ea0f4Smrgstatic void I740_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, unsigned long); 51301ea0f4Smrg#endif 52213fdd94Smrg#endif 53301ea0f4Smrgstatic DGAFunctionRec I740DGAFuncs = { 54301ea0f4Smrg I740_OpenFramebuffer, 55301ea0f4Smrg NULL, 56301ea0f4Smrg I740_SetMode, 57301ea0f4Smrg I740_SetViewport, 58301ea0f4Smrg I740_GetViewport, 59213fdd94Smrg#ifdef HAVE_XAA_H 6034d2f1a1Schristos I740_Sync, 61301ea0f4Smrg I740_FillRect, 62301ea0f4Smrg I740_BlitRect, 63301ea0f4Smrg#if 0 64301ea0f4Smrg I740_BlitTransRect 65301ea0f4Smrg#else 66301ea0f4Smrg NULL 67301ea0f4Smrg#endif 68213fdd94Smrg#else 6968ffe993Swiz NULL, NULL, NULL, NULL 70213fdd94Smrg#endif 71301ea0f4Smrg}; 72301ea0f4Smrg 73301ea0f4SmrgBool I740DGAInit(ScreenPtr pScreen) 74301ea0f4Smrg{ 75213fdd94Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 76301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 77301ea0f4Smrg DGAModePtr modes = NULL, newmodes = NULL, currentMode; 78301ea0f4Smrg DisplayModePtr pMode, firstMode; 79301ea0f4Smrg int Bpp = pScrn->bitsPerPixel >> 3; 80301ea0f4Smrg int num = 0; 81301ea0f4Smrg 82301ea0f4Smrg pMode = firstMode = pScrn->modes; 83301ea0f4Smrg 84301ea0f4Smrg while(pMode) { 85301ea0f4Smrg 86213fdd94Smrg newmodes = realloc(modes, (num + 1) * sizeof(DGAModeRec)); 87301ea0f4Smrg 88301ea0f4Smrg if(!newmodes) { 89213fdd94Smrg free(modes); 90301ea0f4Smrg return FALSE; 91301ea0f4Smrg } 92301ea0f4Smrg modes = newmodes; 93301ea0f4Smrg 94301ea0f4Smrg currentMode = modes + num; 95301ea0f4Smrg num++; 96301ea0f4Smrg 97301ea0f4Smrg currentMode->mode = pMode; 98301ea0f4Smrg currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 99213fdd94Smrg#ifdef HAVE_XAA_H 100301ea0f4Smrg if(pI740->AccelInfoRec) 101301ea0f4Smrg currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 102213fdd94Smrg#endif 103301ea0f4Smrg if(pMode->Flags & V_DBLSCAN) 104301ea0f4Smrg currentMode->flags |= DGA_DOUBLESCAN; 105301ea0f4Smrg if(pMode->Flags & V_INTERLACE) 106301ea0f4Smrg currentMode->flags |= DGA_INTERLACED; 107301ea0f4Smrg currentMode->byteOrder = pScrn->imageByteOrder; 108301ea0f4Smrg currentMode->depth = pScrn->depth; 109301ea0f4Smrg currentMode->bitsPerPixel = pScrn->bitsPerPixel; 110301ea0f4Smrg currentMode->red_mask = pScrn->mask.red; 111301ea0f4Smrg currentMode->green_mask = pScrn->mask.green; 112301ea0f4Smrg currentMode->blue_mask = pScrn->mask.blue; 113301ea0f4Smrg currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 114301ea0f4Smrg currentMode->viewportWidth = pMode->HDisplay; 115301ea0f4Smrg currentMode->viewportHeight = pMode->VDisplay; 116301ea0f4Smrg currentMode->xViewportStep = (Bpp == 3) ? 2 : 1; 117301ea0f4Smrg currentMode->yViewportStep = 1; 118301ea0f4Smrg currentMode->viewportFlags = DGA_FLIP_RETRACE; 119301ea0f4Smrg currentMode->offset = 0; 120301ea0f4Smrg currentMode->address = pI740->FbBase; 121301ea0f4Smrg 122301ea0f4Smrg currentMode->bytesPerScanline = 123301ea0f4Smrg ((pScrn->displayWidth * Bpp) + 3) & ~3L; 124301ea0f4Smrg currentMode->imageWidth = pI740->FbMemBox.x2; 125301ea0f4Smrg currentMode->imageHeight = pI740->FbMemBox.y2; 126301ea0f4Smrg currentMode->pixmapWidth = currentMode->imageWidth; 127301ea0f4Smrg currentMode->pixmapHeight = currentMode->imageHeight; 128301ea0f4Smrg currentMode->maxViewportX = currentMode->imageWidth - 129301ea0f4Smrg currentMode->viewportWidth; 130301ea0f4Smrg /* this might need to get clamped to some maximum */ 131301ea0f4Smrg currentMode->maxViewportY = currentMode->imageHeight - 132301ea0f4Smrg currentMode->viewportHeight; 133301ea0f4Smrg 134301ea0f4Smrg pMode = pMode->next; 135301ea0f4Smrg if(pMode == firstMode) 136301ea0f4Smrg break; 137301ea0f4Smrg } 138301ea0f4Smrg 139301ea0f4Smrg pI740->numDGAModes = num; 140301ea0f4Smrg pI740->DGAModes = modes; 141301ea0f4Smrg 142301ea0f4Smrg return DGAInit(pScreen, &I740DGAFuncs, modes, num); 143301ea0f4Smrg} 144301ea0f4Smrg 145301ea0f4Smrgstatic DisplayModePtr I740SavedDGAModes[MAXSCREENS]; 146301ea0f4Smrg 147301ea0f4Smrgstatic Bool I740_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) 148301ea0f4Smrg{ 149301ea0f4Smrg int index = pScrn->pScreen->myNum; 150301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 151301ea0f4Smrg 152301ea0f4Smrg if(!pMode) { /* restore the original mode */ 153301ea0f4Smrg if(pI740->DGAactive) { 154301ea0f4Smrg pScrn->currentMode = I740SavedDGAModes[index]; 155213fdd94Smrg I740SwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode)); 156213fdd94Smrg I740AdjustFrame(ADJUST_FRAME_ARGS(pScrn, 0, 0)); 157301ea0f4Smrg pI740->DGAactive = FALSE; 158301ea0f4Smrg } 159301ea0f4Smrg } else { 160301ea0f4Smrg if(!pI740->DGAactive) { 161301ea0f4Smrg I740SavedDGAModes[index] = pScrn->currentMode; 162301ea0f4Smrg pI740->DGAactive = TRUE; 163301ea0f4Smrg } 164301ea0f4Smrg 165213fdd94Smrg I740SwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode)); 166301ea0f4Smrg } 167301ea0f4Smrg 168301ea0f4Smrg return TRUE; 169301ea0f4Smrg} 170301ea0f4Smrg 171301ea0f4Smrgstatic int I740_GetViewport(ScrnInfoPtr pScrn) 172301ea0f4Smrg{ 173301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 174301ea0f4Smrg 175301ea0f4Smrg return pI740->DGAViewportStatus; 176301ea0f4Smrg} 177301ea0f4Smrg 178301ea0f4Smrgstatic void I740_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) 179301ea0f4Smrg{ 180301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 181301ea0f4Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 182301ea0f4Smrg 183213fdd94Smrg I740AdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); 184301ea0f4Smrg 185301ea0f4Smrg /* wait for retrace */ 186301ea0f4Smrg while((hwp->readST01(hwp) & 0x08)); 187301ea0f4Smrg while(!(hwp->readST01(hwp) & 0x08)); 188301ea0f4Smrg 189301ea0f4Smrg pI740->DGAViewportStatus = 0; 190301ea0f4Smrg} 191301ea0f4Smrg 192213fdd94Smrg#ifdef HAVE_XAA_H 193301ea0f4Smrgstatic void I740_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned long color) 194301ea0f4Smrg{ 195301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 196301ea0f4Smrg 197301ea0f4Smrg if(pI740->AccelInfoRec) { 198301ea0f4Smrg (*pI740->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 199301ea0f4Smrg (*pI740->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 200301ea0f4Smrg SET_SYNC_FLAG(pI740->AccelInfoRec); 201301ea0f4Smrg } 202301ea0f4Smrg} 203301ea0f4Smrg 204301ea0f4Smrgstatic void I740_Sync(ScrnInfoPtr pScrn) 205301ea0f4Smrg{ 206301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 207301ea0f4Smrg 208301ea0f4Smrg if(pI740->AccelInfoRec) { 209301ea0f4Smrg (*pI740->AccelInfoRec->Sync)(pScrn); 210301ea0f4Smrg } 211301ea0f4Smrg} 212301ea0f4Smrg 213301ea0f4Smrgstatic void I740_BlitRect( 214301ea0f4Smrg ScrnInfoPtr pScrn, 215301ea0f4Smrg int srcx, int srcy, 216301ea0f4Smrg int w, int h, 217301ea0f4Smrg int dstx, int dsty 218301ea0f4Smrg ){ 219301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 220301ea0f4Smrg 221301ea0f4Smrg if(pI740->AccelInfoRec) { 222301ea0f4Smrg int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 223301ea0f4Smrg int ydir = (srcy < dsty) ? -1 : 1; 224301ea0f4Smrg 225301ea0f4Smrg (*pI740->AccelInfoRec->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy, ~0, -1); 226301ea0f4Smrg (*pI740->AccelInfoRec->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy, dstx, dsty, w, h); 227301ea0f4Smrg SET_SYNC_FLAG(pI740->AccelInfoRec); 228301ea0f4Smrg } 229301ea0f4Smrg} 230213fdd94Smrg#endif 231301ea0f4Smrg#if 0 232301ea0f4Smrgstatic void I740_BlitTransRect(ScrnInfoPtr pScrn, 233301ea0f4Smrg int srcx, int srcy, 234301ea0f4Smrg int w, int h, 235301ea0f4Smrg int dstx, int dsty, 236301ea0f4Smrg unsigned long color 237301ea0f4Smrg ) 238301ea0f4Smrg{ 239301ea0f4Smrg /* this one should be separate since the XAA function would 240301ea0f4Smrg prohibit usage of ~0 as the key */ 241301ea0f4Smrg} 242301ea0f4Smrg#endif 243301ea0f4Smrg 244301ea0f4Smrgstatic Bool I740_OpenFramebuffer( 245301ea0f4Smrg ScrnInfoPtr pScrn, 246301ea0f4Smrg char **name, 247301ea0f4Smrg unsigned char **mem, 248301ea0f4Smrg int *size, 249301ea0f4Smrg int *offset, 250301ea0f4Smrg int *flags 251301ea0f4Smrg ){ 252301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 253301ea0f4Smrg 254301ea0f4Smrg *name = NULL; /* no special device */ 255301ea0f4Smrg *mem = (unsigned char*)pI740->LinearAddr; 256301ea0f4Smrg *size = pI740->FbMapSize; 257301ea0f4Smrg *offset = 0; 258301ea0f4Smrg *flags = DGA_NEED_ROOT; 259301ea0f4Smrg 260301ea0f4Smrg return TRUE; 261301ea0f4Smrg} 262