i810_dga.c revision 03b705cf
1/* 2 * Copyright 2000 by Alan Hourihane, Sychdyn, North Wales, UK. 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 * ALAN HOURIHANE 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: Alan Hourihane, <alanh@fairlite.demon.co.uk> 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#endif 28 29#include "xf86.h" 30#include "xf86_OSproc.h" 31#include "xf86Pci.h" 32#include "i810.h" 33#include "i810_reg.h" 34#include "dgaproc.h" 35#include "vgaHW.h" 36 37static Bool I810_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 38 int *, int *, int *); 39static Bool I810_SetMode(ScrnInfoPtr, DGAModePtr); 40static int I810_GetViewport(ScrnInfoPtr); 41static void I810_SetViewport(ScrnInfoPtr, int, int, int); 42 43#ifdef HAVE_XAA_H 44static void I810_Sync(ScrnInfoPtr); 45static void I810_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 46static void I810_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 47#endif 48 49#if 0 50static void I810_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 51 unsigned long); 52#endif 53 54static 55DGAFunctionRec I810DGAFuncs = { 56 I810_OpenFramebuffer, 57 NULL, 58 I810_SetMode, 59 I810_SetViewport, 60 I810_GetViewport, 61#ifdef HAVE_XAA_H 62 I810_Sync, 63 I810_FillRect, 64 I810_BlitRect, 65#else 66 NULL, 67 NULL, 68 NULL, 69#endif 70#if 0 71 I810_BlitTransRect 72#else 73 NULL 74#endif 75}; 76 77Bool 78I810DGAInit(ScreenPtr pScreen) 79{ 80 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 81 I810Ptr pI810 = I810PTR(pScrn); 82 DGAModePtr modes = NULL, newmodes = NULL, currentMode; 83 DisplayModePtr pMode, firstMode; 84 int Bpp = pScrn->bitsPerPixel >> 3; 85 int num = 0; 86 87 pMode = firstMode = pScrn->modes; 88 89 while (pMode) { 90 91 newmodes = realloc(modes, (num + 1) * sizeof(DGAModeRec)); 92 93 if (!newmodes) { 94 free(modes); 95 return FALSE; 96 } 97 modes = newmodes; 98 99 currentMode = modes + num; 100 num++; 101 102 currentMode->mode = pMode; 103 currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 104 if (!pI810->noAccel) 105 currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 106 if (pMode->Flags & V_DBLSCAN) 107 currentMode->flags |= DGA_DOUBLESCAN; 108 if (pMode->Flags & V_INTERLACE) 109 currentMode->flags |= DGA_INTERLACED; 110 currentMode->byteOrder = pScrn->imageByteOrder; 111 currentMode->depth = pScrn->depth; 112 currentMode->bitsPerPixel = pScrn->bitsPerPixel; 113 currentMode->red_mask = pScrn->mask.red; 114 currentMode->green_mask = pScrn->mask.green; 115 currentMode->blue_mask = pScrn->mask.blue; 116 currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 117 currentMode->viewportWidth = pMode->HDisplay; 118 currentMode->viewportHeight = pMode->VDisplay; 119 currentMode->xViewportStep = (Bpp == 3) ? 2 : 1; 120 currentMode->yViewportStep = 1; 121 currentMode->viewportFlags = DGA_FLIP_RETRACE; 122 currentMode->offset = 0; 123 currentMode->address = pI810->FbBase; 124 125 currentMode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L; 126 currentMode->imageWidth = pI810->FbMemBox.x2; 127 currentMode->imageHeight = pI810->FbMemBox.y2; 128 currentMode->pixmapWidth = currentMode->imageWidth; 129 currentMode->pixmapHeight = currentMode->imageHeight; 130 currentMode->maxViewportX = currentMode->imageWidth - 131 currentMode->viewportWidth; 132 /* this might need to get clamped to some maximum */ 133 currentMode->maxViewportY = currentMode->imageHeight - 134 currentMode->viewportHeight; 135 136 pMode = pMode->next; 137 if (pMode == firstMode) 138 break; 139 } 140 141 pI810->numDGAModes = num; 142 pI810->DGAModes = modes; 143 144 return DGAInit(pScreen, &I810DGAFuncs, modes, num); 145} 146 147static DisplayModePtr I810SavedDGAModes[MAXSCREENS]; 148 149static Bool 150I810_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) 151{ 152 int index = pScrn->pScreen->myNum; 153 I810Ptr pI810 = I810PTR(pScrn); 154 155 if (!pMode) { /* restore the original mode */ 156 if (pI810->DGAactive) { 157 pScrn->currentMode = I810SavedDGAModes[index]; 158 pScrn->SwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode)); 159 pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, 0, 0)); 160 pI810->DGAactive = FALSE; 161 } 162 } else { 163 if (!pI810->DGAactive) { 164 I810SavedDGAModes[index] = pScrn->currentMode; 165 pI810->DGAactive = TRUE; 166 } 167 pScrn->SwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode)); 168 } 169 170 return TRUE; 171} 172 173static int 174I810_GetViewport(ScrnInfoPtr pScrn) 175{ 176 I810Ptr pI810 = I810PTR(pScrn); 177 178 return pI810->DGAViewportStatus; 179} 180 181static void 182I810_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) 183{ 184 I810Ptr pI810 = I810PTR(pScrn); 185 vgaHWPtr hwp = VGAHWPTR(pScrn); 186 187 pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); 188 189 /* wait for retrace */ 190 while ((hwp->readST01(hwp) & 0x08)) ; 191 while (!(hwp->readST01(hwp) & 0x08)) ; 192 193 pI810->DGAViewportStatus = 0; 194} 195 196#ifdef HAVE_XAA_H 197static void 198I810_FillRect(ScrnInfoPtr pScrn, 199 int x, int y, int w, int h, unsigned long color) 200{ 201 I810Ptr pI810 = I810PTR(pScrn); 202 203 if (pI810->AccelInfoRec) { 204 (*pI810->AccelInfoRec->SetupForSolidFill) (pScrn, color, GXcopy, ~0); 205 (*pI810->AccelInfoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h); 206 SET_SYNC_FLAG(pI810->AccelInfoRec); 207 } 208} 209 210static void 211I810_Sync(ScrnInfoPtr pScrn) 212{ 213 I810Ptr pI810 = I810PTR(pScrn); 214 215 if (pI810->AccelInfoRec) { 216 (*pI810->AccelInfoRec->Sync) (pScrn); 217 } 218} 219 220static void 221I810_BlitRect(ScrnInfoPtr pScrn, 222 int srcx, int srcy, int w, int h, int dstx, int dsty) 223{ 224 I810Ptr pI810 = I810PTR(pScrn); 225 226 if (pI810->AccelInfoRec) { 227 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 228 int ydir = (srcy < dsty) ? -1 : 1; 229 230 (*pI810->AccelInfoRec->SetupForScreenToScreenCopy) (pScrn, xdir, ydir, 231 GXcopy, ~0, -1); 232 (*pI810->AccelInfoRec->SubsequentScreenToScreenCopy) (pScrn, srcx, srcy, 233 dstx, dsty, w, h); 234 SET_SYNC_FLAG(pI810->AccelInfoRec); 235 } 236} 237#endif 238 239#if 0 240static void 241I810_BlitTransRect(ScrnInfoPtr pScrn, 242 int srcx, int srcy, 243 int w, int h, int dstx, int dsty, unsigned long color) 244{ 245 246 /* this one should be separate since the XAA function would 247 * prohibit usage of ~0 as the key */ 248} 249#endif 250 251static Bool 252I810_OpenFramebuffer(ScrnInfoPtr pScrn, 253 char **name, 254 unsigned char **mem, int *size, int *offset, int *flags) 255{ 256 I810Ptr pI810 = I810PTR(pScrn); 257 258 *name = NULL; /* no special device */ 259 *mem = (unsigned char *)pI810->LinearAddr; 260 *size = pI810->FbMapSize; 261 *offset = 0; 262 *flags = DGA_NEED_ROOT; 263 264 return TRUE; 265} 266