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