s3v_dga.c revision eb61724e
1 2/* 3Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 4 5Permission is hereby granted, free of charge, to any person obtaining a copy of 6this software and associated documentation files (the "Software"), to deal in 7the Software without restriction, including without limitation the rights to 8use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9of the Software, and to permit persons to whom the Software is furnished to do 10so, subject to the following conditions: 11 12The above copyright notice and this permission notice shall be included in all 13copies or substantial portions of the Software. 14 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 17NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22Except as contained in this notice, the name of the XFree86 Project shall not 23be used in advertising or otherwise to promote the sale, use or other dealings 24in this Software without prior written authorization from the XFree86 Project. 25*/ 26 27/* 28Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 29 30Permission is hereby granted, free of charge, to any person obtaining a copy of 31this software and associated documentation files (the "Software"), to deal in 32the Software without restriction, including without limitation the rights to 33use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 34of the Software, and to permit persons to whom the Software is furnished to do 35so, subject to the following conditions: 36 37The above copyright notice and this permission notice shall be included in all 38copies or substantial portions of the Software. 39 40THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 41IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 42NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 43XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 44AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 45WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 46 47Except as contained in this notice, the name of the XFree86 Project shall not 48be used in advertising or otherwise to promote the sale, use or other dealings 49in this Software without prior written authorization from the XFree86 Project. 50*/ 51 52/* 53 * file: s3v_dga.c 54 * ported from mga 55 * 56 */ 57 58#ifdef HAVE_CONFIG_H 59#include "config.h" 60#endif 61 62#include "xf86.h" 63#include "xf86_OSproc.h" 64#include "xf86Pci.h" 65#include "xf86PciInfo.h" 66#include "xaa.h" 67#include "xaalocal.h" 68#include "s3v.h" 69 70#include "dgaproc.h" 71 72 73static Bool S3V_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 74 int *, int *, int *); 75static Bool S3V_SetMode(ScrnInfoPtr, DGAModePtr); 76static int S3V_GetViewport(ScrnInfoPtr); 77static void S3V_SetViewport(ScrnInfoPtr, int, int, int); 78static void S3V_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 79static void S3V_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 80/* dummy... */ 81 82 83static 84DGAFunctionRec S3V_DGAFuncs = { 85 S3V_OpenFramebuffer, 86 NULL, 87 S3V_SetMode, 88 S3V_SetViewport, 89 S3V_GetViewport, 90 S3VAccelSync, 91 S3V_FillRect, 92 S3V_BlitRect, 93 NULL 94 /* dummy... MGA_BlitTransRect */ 95}; 96 97 98Bool 99S3VDGAInit(ScreenPtr pScreen) 100{ 101 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 102 S3VPtr ps3v = S3VPTR(pScrn); 103 DGAModePtr modes = NULL, newmodes = NULL, currentMode; 104 DisplayModePtr pMode, firstMode; 105 int Bpp = pScrn->bitsPerPixel >> 3; 106 int num = 0; 107 Bool oneMore; 108 109 PVERB5(" S3VDGAInit\n"); 110 111 pMode = firstMode = pScrn->modes; 112 113 while(pMode) { 114 /* The MGA driver wasn't designed with switching depths in 115 mind. Subsequently, large chunks of it will probably need 116 to be rewritten to accommodate depth changes in DGA mode */ 117 118 if(0 /*pScrn->displayWidth != pMode->HDisplay*/) { 119 newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec)); 120 oneMore = TRUE; 121 } else { 122 newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); 123 oneMore = FALSE; 124 } 125 126 if(!newmodes) { 127 xfree(modes); 128 return FALSE; 129 } 130 modes = newmodes; 131 132SECOND_PASS: 133 134 currentMode = modes + num; 135 num++; 136 137 currentMode->mode = pMode; 138 currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 139 if(!ps3v->NoAccel) 140 currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 141 if(pMode->Flags & V_DBLSCAN) 142 currentMode->flags |= DGA_DOUBLESCAN; 143 if(pMode->Flags & V_INTERLACE) 144 currentMode->flags |= DGA_INTERLACED; 145 currentMode->byteOrder = pScrn->imageByteOrder; 146 currentMode->depth = pScrn->depth; 147 currentMode->bitsPerPixel = pScrn->bitsPerPixel; 148 currentMode->red_mask = pScrn->mask.red; 149 currentMode->green_mask = pScrn->mask.green; 150 currentMode->blue_mask = pScrn->mask.blue; 151 currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 152 currentMode->viewportWidth = pMode->HDisplay; 153 currentMode->viewportHeight = pMode->VDisplay; 154 /* currentMode->xViewportStep = (3 - ps3v->BppShift); */ 155 /* always 1 on ViRGE ? */ 156 currentMode->xViewportStep = 1; 157 currentMode->yViewportStep = 1; 158 currentMode->viewportFlags = DGA_FLIP_RETRACE; 159 /* currentMode->offset = ps3v->YDstOrg * (pScrn->bitsPerPixel / 8); 160 * MGA, 0 for ViRGE */ 161 currentMode->offset = 0; 162 /* currentMode->address = pMga->FbStart; MGA */ 163 currentMode->address = ps3v->FBBase; 164/*cep*/ 165 xf86ErrorFVerb(VERBLEV, 166 " S3VDGAInit firstone vpWid=%d, vpHgt=%d, Bpp=%d, mdbitsPP=%d\n", 167 currentMode->viewportWidth, 168 currentMode->viewportHeight, 169 Bpp, 170 currentMode->bitsPerPixel 171 ); 172 173 174 if(oneMore) { /* first one is narrow width */ 175 currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; 176 currentMode->imageWidth = pMode->HDisplay; 177 /* currentMode->imageHeight = pMga->FbUsableSize / 178 currentMode->bytesPerScanline; 179 MGA above */ 180 currentMode->imageHeight = pMode->VDisplay; 181 currentMode->pixmapWidth = currentMode->imageWidth; 182 currentMode->pixmapHeight = currentMode->imageHeight; 183 currentMode->maxViewportX = currentMode->imageWidth - 184 currentMode->viewportWidth; 185 /* this might need to get clamped to some maximum */ 186 currentMode->maxViewportY = currentMode->imageHeight - 187 currentMode->viewportHeight; 188 oneMore = FALSE; 189 190/*cep*/ 191 xf86ErrorFVerb(VERBLEV, 192 " S3VDGAInit imgHgt=%d, ram=%d, bytesPerScanl=%d\n", 193 currentMode->imageHeight, 194 ps3v->videoRambytes, 195 currentMode->bytesPerScanline ); 196 197 goto SECOND_PASS; 198 } else { 199 currentMode->bytesPerScanline = 200 ((pScrn->displayWidth * Bpp) + 3) & ~3L; 201 currentMode->imageWidth = pScrn->displayWidth; 202 /* currentMode->imageHeight = pMga->FbUsableSize / 203 currentMode->bytesPerScanline; 204 */ 205 currentMode->imageHeight = ps3v->videoRambytes / 206 currentMode->bytesPerScanline; 207 currentMode->pixmapWidth = currentMode->imageWidth; 208 currentMode->pixmapHeight = currentMode->imageHeight; 209 currentMode->maxViewportX = currentMode->imageWidth - 210 currentMode->viewportWidth; 211 /* this might need to get clamped to some maximum */ 212 currentMode->maxViewportY = currentMode->imageHeight - 213 currentMode->viewportHeight; 214 } 215 216 pMode = pMode->next; 217 if(pMode == firstMode) 218 break; 219 } 220 221 ps3v->numDGAModes = num; 222 ps3v->DGAModes = modes; 223 224 return DGAInit(pScreen, &S3V_DGAFuncs, modes, num); 225} 226 227 228static Bool 229S3V_SetMode( 230 ScrnInfoPtr pScrn, 231 DGAModePtr pMode 232){ 233 static int OldDisplayWidth[MAXSCREENS]; 234 int index = pScrn->pScreen->myNum; 235 236 S3VPtr ps3v = S3VPTR(pScrn); 237 238 if(!pMode) { /* restore the original mode */ 239 /* put the ScreenParameters back */ 240 241 pScrn->displayWidth = OldDisplayWidth[index]; 242 243 S3VSwitchMode(index, pScrn->currentMode, 0); 244 ps3v->DGAactive = FALSE; 245 } else { 246 if(!ps3v->DGAactive) { /* save the old parameters */ 247 OldDisplayWidth[index] = pScrn->displayWidth; 248 249 ps3v->DGAactive = TRUE; 250 } 251 252 pScrn->displayWidth = pMode->bytesPerScanline / 253 (pMode->bitsPerPixel >> 3); 254 255 S3VSwitchMode(index, pMode->mode, 0); 256 } 257 258 return TRUE; 259} 260 261 262 263static int 264S3V_GetViewport( 265 ScrnInfoPtr pScrn 266){ 267 S3VPtr ps3v = S3VPTR(pScrn); 268 269 return ps3v->DGAViewportStatus; 270} 271 272static void 273S3V_SetViewport( 274 ScrnInfoPtr pScrn, 275 int x, int y, 276 int flags 277){ 278 S3VPtr ps3v = S3VPTR(pScrn); 279 280 S3VAdjustFrame(pScrn->pScreen->myNum, x, y, flags); 281 ps3v->DGAViewportStatus = 0; /* MGAAdjustFrame loops until finished */ 282} 283 284static void 285S3V_FillRect ( 286 ScrnInfoPtr pScrn, 287 int x, int y, int w, int h, 288 unsigned long color 289){ 290 S3VPtr ps3v = S3VPTR(pScrn); 291 292 if(ps3v->AccelInfoRec) { 293 (*ps3v->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 294 (*ps3v->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 295 SET_SYNC_FLAG(ps3v->AccelInfoRec); 296 } 297} 298 299static void 300S3V_BlitRect( 301 ScrnInfoPtr pScrn, 302 int srcx, int srcy, 303 int w, int h, 304 int dstx, int dsty 305){ 306 S3VPtr ps3v = S3VPTR(pScrn); 307 308 if(ps3v->AccelInfoRec) { 309 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 310 int ydir = (srcy < dsty) ? -1 : 1; 311 312 (*ps3v->AccelInfoRec->SetupForScreenToScreenCopy)( 313 pScrn, xdir, ydir, GXcopy, ~0, -1); 314 (*ps3v->AccelInfoRec->SubsequentScreenToScreenCopy)( 315 pScrn, srcx, srcy, dstx, dsty, w, h); 316 SET_SYNC_FLAG(ps3v->AccelInfoRec); 317 } 318} 319 320 321 322static Bool 323S3V_OpenFramebuffer( 324 ScrnInfoPtr pScrn, 325 char **name, 326 unsigned char **mem, 327 int *size, 328 int *offset, 329 int *flags 330){ 331 S3VPtr ps3v = S3VPTR(pScrn); 332 333 *name = NULL; /* no special device */ 334 *mem = (unsigned char*)(uintptr_t)PCI_REGION_BASE(ps3v->PciInfo, 0, REGION_MEM); 335 *size = ps3v->videoRambytes; 336 *offset = 0; 337 *flags = DGA_NEED_ROOT; 338 339 return TRUE; 340} 341