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 "neo.h" 33#include "neo_reg.h" 34#include "dgaproc.h" 35#include "vgaHW.h" 36 37static Bool NEO_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 38 int *, int *, int *); 39static Bool NEO_SetMode(ScrnInfoPtr, DGAModePtr); 40static int NEO_GetViewport(ScrnInfoPtr); 41static void NEO_SetViewport(ScrnInfoPtr, int, int, int); 42#ifdef HAVE_XAA_H 43static void NEO_Sync(ScrnInfoPtr); 44static void NEO_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 45static void NEO_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 46#if 0 47static void NEO_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 48 unsigned long); 49#endif 50#endif 51 52static 53DGAFunctionRec NEODGAFuncs = { 54 NEO_OpenFramebuffer, 55 NULL, 56 NEO_SetMode, 57 NEO_SetViewport, 58 NEO_GetViewport, 59#ifdef HAVE_XAA_H 60 NEO_Sync, 61 NEO_FillRect, 62 NEO_BlitRect, 63#if 0 64 NEO_BlitTransRect 65#else 66 NULL 67#endif 68#else 69 NULL, NULL, NULL 70#endif 71}; 72 73Bool 74NEODGAInit(ScreenPtr pScreen) 75{ 76 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 77 NEOPtr pNEO = NEOPTR(pScrn); 78 DGAModePtr modes = NULL, newmodes = NULL, currentMode; 79 DisplayModePtr pMode, firstMode; 80 int Bpp = pScrn->bitsPerPixel >> 3; 81 int num = 0, imlines, pixlines; 82 83 imlines = (pScrn->videoRam * 1024) / 84 (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); 85 86 pixlines = (imlines > 1024 && !pNEO->noAccel) ? 1024 : imlines; 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#ifdef HAVE_XAA_H 106 if (!pNEO->noAccel) 107 currentMode->flags |= (DGA_FILL_RECT | DGA_BLIT_RECT); 108#endif 109 if(pMode->Flags & V_DBLSCAN) 110 currentMode->flags |= DGA_DOUBLESCAN; 111 if(pMode->Flags & V_INTERLACE) 112 currentMode->flags |= DGA_INTERLACED; 113 currentMode->byteOrder = pScrn->imageByteOrder; 114 currentMode->depth = pScrn->depth; 115 currentMode->bitsPerPixel = pScrn->bitsPerPixel; 116 currentMode->red_mask = pScrn->mask.red; 117 currentMode->green_mask = pScrn->mask.green; 118 currentMode->blue_mask = pScrn->mask.blue; 119 currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 120 currentMode->viewportWidth = pMode->HDisplay; 121 currentMode->viewportHeight = pMode->VDisplay; 122 currentMode->xViewportStep = 1; 123 currentMode->yViewportStep = 1; 124 currentMode->viewportFlags = DGA_FLIP_RETRACE; 125 currentMode->offset = 0; 126 currentMode->address = pNEO->NeoFbBase; 127 128 currentMode->bytesPerScanline = 129 ((pScrn->displayWidth * Bpp) + 3) & ~3L; 130 currentMode->imageWidth = pScrn->displayWidth; 131 currentMode->imageHeight = imlines; 132 currentMode->pixmapWidth = currentMode->imageWidth; 133 currentMode->pixmapHeight = pixlines; 134 currentMode->maxViewportX = currentMode->imageWidth - 135 currentMode->viewportWidth; 136 currentMode->maxViewportY = currentMode->imageHeight - 137 currentMode->viewportHeight; 138 139 pMode = pMode->next; 140 if(pMode == firstMode) 141 break; 142 } 143 144 pNEO->numDGAModes = num; 145 pNEO->DGAModes = modes; 146 147 return DGAInit(pScreen, &NEODGAFuncs, modes, num); 148} 149 150static DisplayModePtr NEOSavedDGAModes[MAXSCREENS]; 151 152static Bool 153NEO_SetMode( 154 ScrnInfoPtr pScrn, 155 DGAModePtr pMode 156){ 157 int index = pScrn->pScreen->myNum; 158 NEOPtr pNEO = NEOPTR(pScrn); 159 160 if(!pMode) { /* restore the original mode */ 161 if(pNEO->DGAactive) { 162 pScrn->currentMode = NEOSavedDGAModes[index]; 163 NEOSwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode)); 164 NEOAdjustFrame(ADJUST_FRAME_ARGS(pScrn, 0, 0)); 165 pNEO->DGAactive = FALSE; 166 } 167 } else { 168 if(!pNEO->DGAactive) { /* save the old parameters */ 169 NEOSavedDGAModes[index] = pScrn->currentMode; 170 pNEO->DGAactive = TRUE; 171 } 172 173 NEOSwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode)); 174 } 175 176 return TRUE; 177} 178 179static int 180NEO_GetViewport( 181 ScrnInfoPtr pScrn 182){ 183 NEOPtr pNEO = NEOPTR(pScrn); 184 185 return pNEO->DGAViewportStatus; 186} 187 188static void 189NEO_SetViewport( 190 ScrnInfoPtr pScrn, 191 int x, int y, 192 int flags 193){ 194 NEOPtr pNEO = NEOPTR(pScrn); 195 vgaHWPtr hwp = VGAHWPTR(pScrn); 196 197 NEOAdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); 198 /* wait for retrace */ 199 while((hwp->readST01(hwp) & 0x08)); 200 while(!(hwp->readST01(hwp) & 0x08)); 201 202 pNEO->DGAViewportStatus = 0; 203} 204 205#ifdef HAVE_XAA_H 206static void 207NEO_FillRect ( 208 ScrnInfoPtr pScrn, 209 int x, int y, int w, int h, 210 unsigned long color 211){ 212 NEOPtr pNEO = NEOPTR(pScrn); 213 214 if(pNEO->AccelInfoRec) { 215 (*pNEO->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 216 (*pNEO->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 217 SET_SYNC_FLAG(pNEO->AccelInfoRec); 218 } 219} 220 221static void 222NEO_Sync( 223 ScrnInfoPtr pScrn 224){ 225 NEOPtr pNEO = NEOPTR(pScrn); 226 if(pNEO->AccelInfoRec) { 227 (*pNEO->AccelInfoRec->Sync)(pScrn); 228 } 229} 230 231static void 232NEO_BlitRect( 233 ScrnInfoPtr pScrn, 234 int srcx, int srcy, 235 int w, int h, 236 int dstx, int dsty 237){ 238 NEOPtr pNEO = NEOPTR(pScrn); 239 240 if(pNEO->AccelInfoRec) { 241 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 242 int ydir = (srcy < dsty) ? -1 : 1; 243 244 (*pNEO->AccelInfoRec->SetupForScreenToScreenCopy)( 245 pScrn, xdir, ydir, GXcopy, ~0, -1); 246 (*pNEO->AccelInfoRec->SubsequentScreenToScreenCopy)( 247 pScrn, srcx, srcy, dstx, dsty, w, h); 248 SET_SYNC_FLAG(pNEO->AccelInfoRec); 249 } 250} 251 252#if 0 253static void 254NEO_BlitTransRect( 255 ScrnInfoPtr pScrn, 256 int srcx, int srcy, 257 int w, int h, 258 int dstx, int dsty, 259 unsigned long color 260){ 261 /* this one should be separate since the XAA function would 262 prohibit usage of ~0 as the key */ 263} 264#endif 265#endif 266static Bool 267NEO_OpenFramebuffer( 268 ScrnInfoPtr pScrn, 269 char **name, 270 unsigned char **mem, 271 int *size, 272 int *offset, 273 int *flags 274){ 275 NEOPtr pNEO = NEOPTR(pScrn); 276 277 *name = NULL; /* no special device */ 278 *mem = (unsigned char*)pNEO->NeoLinearAddr; 279 *size = pNEO->NeoFbMapSize; 280 *offset = 0; 281 *flags = DGA_NEED_ROOT; 282 283 return TRUE; 284} 285 286