1/* 2 * Copyright 2000 by Egbert Eich 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Alan Hourihane not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Alan Hourihane makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as is" without express or implied warranty. 13 * 14 * EGBERT EICH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 * 22 * Authors: Adapted from: Alan Hourihane, <alanh@fairlite.demon.co.uk> 23 * by: Egbert Eich 24 */ 25 26#ifdef HAVE_CONFIG_H 27#include "config.h" 28#endif 29 30#include "xf86.h" 31#include "xf86_OSproc.h" 32#include "xf86Pci.h" 33#ifdef HAVE_XAA_H 34#include "xaa.h" 35#include "xaalocal.h" 36#endif 37#include "vgaHW.h" 38#include "cir.h" 39#include "dgaproc.h" 40 41static Bool Cir_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 42 int *, int *, int *); 43static Bool Cir_SetMode(ScrnInfoPtr, DGAModePtr); 44static int Cir_GetViewport(ScrnInfoPtr); 45static void Cir_SetViewport(ScrnInfoPtr, int, int, int); 46#ifdef HAVE_XAA_H 47static void Cir_Sync(ScrnInfoPtr); 48static void Cir_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 49static void Cir_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 50/* 51static void Cir_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 52 unsigned long); 53*/ 54#endif 55 56static 57DGAFunctionRec CirDGAFuncs = { 58 Cir_OpenFramebuffer, 59 NULL, /* Cir_CloseFramebuffer */ 60 Cir_SetMode, 61 Cir_SetViewport, 62 Cir_GetViewport, 63#ifdef HAVE_XAA_H 64 Cir_Sync, 65 Cir_FillRect, 66 Cir_BlitRect, 67#else 68 NULL, NULL, NULL, 69#endif 70 NULL /* Cir_BlitTransRect */ 71}; 72 73 74 75 76_X_EXPORT Bool 77CirDGAInit(ScreenPtr pScreen) 78{ 79 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 80 CirPtr pCir = CIRPTR(pScrn); 81 DGAModePtr modes = NULL, newmodes = NULL, currentMode; 82 DisplayModePtr pMode, firstMode; 83 int Bpp = pScrn->bitsPerPixel >> 3; 84 int num = 0; 85 int imlines = (pScrn->videoRam * 1024) / 86 (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); 87 88 89 if (!pCir->DGAnumModes) { 90 pMode = firstMode = pScrn->modes; 91 while (pMode) { 92 newmodes = realloc(modes, (num + 1) * sizeof (DGAModeRec)); 93 if (!newmodes) { 94 free(modes); 95 return FALSE; 96 } 97 modes = newmodes; 98 currentMode = modes + num; 99 num++; 100 (void)memset(currentMode, 1, sizeof(DGAModeRec)); 101 currentMode->mode = pMode; 102 currentMode->flags = DGA_PIXMAP_AVAILABLE 103 | ((!pCir->NoAccel) ? (DGA_FILL_RECT | DGA_BLIT_RECT) : 0); 104 if (pMode->Flags & V_DBLSCAN) 105 currentMode->flags |= DGA_DOUBLESCAN; 106 if(pMode->Flags & V_INTERLACE) 107 currentMode->flags |= DGA_INTERLACED; 108 currentMode->byteOrder = pScrn->imageByteOrder; 109 currentMode->depth = pScrn->depth; 110 currentMode->bitsPerPixel = pScrn->bitsPerPixel; 111 currentMode->red_mask = pScrn->mask.red; 112 currentMode->green_mask = pScrn->mask.green; 113 currentMode->blue_mask = pScrn->mask.blue; 114 currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 115 currentMode->viewportWidth = pMode->HDisplay; 116 currentMode->viewportHeight = pMode->VDisplay; 117 currentMode->xViewportStep = 1; /* The granularity of x and y pos. */ 118 currentMode->yViewportStep = 1; 119 currentMode->viewportFlags = 0 /*DGA_FLIP_RETRACE*/; 120 currentMode->offset = 0; 121 currentMode->address = pCir->FbBase; 122 currentMode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L; 123 currentMode->pixmapWidth = currentMode->imageWidth 124 = pScrn->displayWidth; 125 currentMode->pixmapHeight = currentMode->imageHeight = imlines; 126 currentMode->maxViewportX = currentMode->imageWidth - 127 currentMode->viewportWidth; 128 /* this might need to get clamped to some maximum */ 129 currentMode->maxViewportY = currentMode->imageHeight - 130 currentMode->viewportHeight; 131 132 pMode = pMode->next; 133 if(pMode == firstMode) 134 break; 135 } 136 pCir->DGAnumModes = num; 137 pCir->DGAModes = modes; 138 } 139 return DGAInit(pScreen, &CirDGAFuncs, pCir->DGAModes, pCir->DGAnumModes); 140} 141 142static Bool 143Cir_OpenFramebuffer( 144 ScrnInfoPtr pScrn, 145 char **name, 146 unsigned char **mem, 147 int *size, 148 int *offset, 149 int *flags 150){ 151 CirPtr pCir = CIRPTR(pScrn); 152 153 *name = NULL; /* no special device */ 154 *mem = (unsigned char*)(long)pCir->FbAddress; 155 *size = pCir->FbMapSize; 156 *offset = 0; /* Always */ 157 *flags = 0; /* Root permissions OS-dependent */ 158 159 return TRUE; 160} 161 162 163static Bool 164Cir_SetMode( 165 ScrnInfoPtr pScrn, 166 DGAModePtr pMode 167){ 168 CirPtr pCir = CIRPTR(pScrn); 169 static int OldDisplayWidth[MAXSCREENS]; 170 int index = pScrn->pScreen->myNum; 171 Bool ret = FALSE; 172 173 if(!pMode) { /* restore the original mode */ 174 /* put the ScreenParameters back */ 175 pScrn->displayWidth = OldDisplayWidth[index]; 176 ret = pCir->DGAModeInit(xf86Screens[index], pScrn->currentMode); 177 pCir->DGAactive = FALSE; 178 } else { 179 if(!pCir->DGAactive) { /* save the old parameters */ 180 OldDisplayWidth[index] = pScrn->displayWidth; 181 182 pCir->DGAactive = TRUE; 183 } 184 pScrn->displayWidth = pMode->bytesPerScanline / 185 (pMode->bitsPerPixel >> 3); 186 187 ret = pCir->DGAModeInit(xf86Screens[index], pMode->mode); 188 } 189 return ret; 190} 191 192static void 193Cir_SetViewport( 194 ScrnInfoPtr pScrn, 195 int x, int y, 196 int flags 197){ 198 CirPtr pCir = CIRPTR(pScrn); 199 vgaHWPtr hwp = VGAHWPTR(pScrn); 200 201 pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); 202 203 while((hwp->readST01(hwp) & 0x08)); 204 while(!(hwp->readST01(hwp) & 0x08)); 205 206 pCir->DGAViewportStatus = 0; /* AdjustFrame loops until finished */ 207} 208 209static int 210Cir_GetViewport( 211 ScrnInfoPtr pScrn 212){ 213 CirPtr pCir = CIRPTR(pScrn); 214 215 return pCir->DGAViewportStatus; 216} 217 218#ifdef HAVE_XAA_H 219static void 220Cir_Sync( 221 ScrnInfoPtr pScrn 222){ 223 CirPtr pCir = CIRPTR(pScrn); 224 if(pCir->AccelInfoRec) { 225 (*pCir->AccelInfoRec->Sync)(pScrn); 226 } 227} 228 229static void 230Cir_FillRect ( 231 ScrnInfoPtr pScrn, 232 int x, int y, int w, int h, 233 unsigned long color 234){ 235 CirPtr pCir = CIRPTR(pScrn); 236 237 if(pCir->AccelInfoRec) { 238 (*pCir->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 239 (*pCir->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 240 SET_SYNC_FLAG(pCir->AccelInfoRec); 241 } 242} 243 244static void 245Cir_BlitRect( 246 ScrnInfoPtr pScrn, 247 int srcx, int srcy, 248 int w, int h, 249 int dstx, int dsty 250){ 251 CirPtr pCir = CIRPTR(pScrn); 252 253 if(pCir->AccelInfoRec) { 254 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 255 int ydir = (srcy < dsty) ? -1 : 1; 256 257 (*pCir->AccelInfoRec->SetupForScreenToScreenCopy)( 258 pScrn, xdir, ydir, GXcopy, ~0, -1); 259 (*pCir->AccelInfoRec->SubsequentScreenToScreenCopy)( 260 pScrn, srcx, srcy, dstx, dsty, w, h); 261 SET_SYNC_FLAG(pCir->AccelInfoRec); 262 } 263} 264#endif 265