1c35d236eSmrg/* 2c35d236eSmrg * Copyright 2000-2001 by Alan Hourihane, Sychdyn, North Wales, UK. 3c35d236eSmrg * 4c35d236eSmrg * Permission to use, copy, modify, distribute, and sell this software and its 5c35d236eSmrg * documentation for any purpose is hereby granted without fee, provided that 6c35d236eSmrg * the above copyright notice appear in all copies and that both that 7c35d236eSmrg * copyright notice and this permission notice appear in supporting 8c35d236eSmrg * documentation, and that the name of Alan Hourihane not be used in 9c35d236eSmrg * advertising or publicity pertaining to distribution of the software without 10c35d236eSmrg * specific, written prior permission. Alan Hourihane makes no representations 11c35d236eSmrg * about the suitability of this software for any purpose. It is provided 12c35d236eSmrg * "as is" without express or implied warranty. 13c35d236eSmrg * 14c35d236eSmrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15c35d236eSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16c35d236eSmrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17c35d236eSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18c35d236eSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19c35d236eSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20c35d236eSmrg * PERFORMANCE OF THIS SOFTWARE. 21c35d236eSmrg * 22c35d236eSmrg * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> 23c35d236eSmrg */ 24c35d236eSmrg 25c35d236eSmrg#ifdef HAVE_CONFIG_H 26c35d236eSmrg#include "config.h" 27c35d236eSmrg#endif 28c35d236eSmrg 29c35d236eSmrg#include "xf86.h" 30c35d236eSmrg#include "xf86_OSproc.h" 31c35d236eSmrg#include "xf86Pci.h" 32c35d236eSmrg#include "glint.h" 331fb744b4Smrg#ifdef HAVE_XAA_H 341fb744b4Smrg#include "xaalocal.h" 351fb744b4Smrg#endif 36c35d236eSmrg#include "glint_regs.h" 37c35d236eSmrg#include "dgaproc.h" 38c35d236eSmrg 39c35d236eSmrgstatic Bool GLINT_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 40c35d236eSmrg int *, int *, int *); 41c35d236eSmrgstatic Bool GLINT_SetMode(ScrnInfoPtr, DGAModePtr); 42c35d236eSmrgstatic void GLINT_Sync(ScrnInfoPtr); 43c35d236eSmrgstatic int GLINT_GetViewport(ScrnInfoPtr); 44c35d236eSmrgstatic void GLINT_SetViewport(ScrnInfoPtr, int, int, int); 451fb744b4Smrg#ifdef HAVE_XAA_H 46c35d236eSmrgstatic void GLINT_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 47c35d236eSmrgstatic void GLINT_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 481fb744b4Smrg#endif 49c35d236eSmrg 50c35d236eSmrgstatic 51c35d236eSmrgDGAFunctionRec GLINTDGAFuncs = { 52c35d236eSmrg GLINT_OpenFramebuffer, 53c35d236eSmrg NULL, 54c35d236eSmrg GLINT_SetMode, 55c35d236eSmrg GLINT_SetViewport, 56c35d236eSmrg GLINT_GetViewport, 57c35d236eSmrg GLINT_Sync, 581fb744b4Smrg#ifdef HAVE_XAA_H 59c35d236eSmrg GLINT_FillRect, 60c35d236eSmrg GLINT_BlitRect, 611fb744b4Smrg#else 621fb744b4Smrg NULL, NULL, 631fb744b4Smrg#endif 64c35d236eSmrg NULL 65c35d236eSmrg}; 66c35d236eSmrg 67c35d236eSmrgBool 68c35d236eSmrgGLINTDGAInit(ScreenPtr pScreen) 69c35d236eSmrg{ 701fb744b4Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 71c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 72c35d236eSmrg DGAModePtr modes = NULL, newmodes = NULL, currentMode; 73c35d236eSmrg DisplayModePtr pMode, firstMode; 74c35d236eSmrg int Bpp = pScrn->bitsPerPixel >> 3; 75c35d236eSmrg int num = 0; 76c35d236eSmrg Bool oneMore; 77c35d236eSmrg 78c35d236eSmrg pMode = firstMode = pScrn->modes; 79c35d236eSmrg 80c35d236eSmrg while(pMode) { 81c35d236eSmrg 82c35d236eSmrg if(0 /*pScrn->displayWidth != pMode->HDisplay*/) { 831fb744b4Smrg newmodes = realloc(modes, (num + 2) * sizeof(DGAModeRec)); 84c35d236eSmrg oneMore = TRUE; 85c35d236eSmrg } else { 861fb744b4Smrg newmodes = realloc(modes, (num + 1) * sizeof(DGAModeRec)); 87c35d236eSmrg oneMore = FALSE; 88c35d236eSmrg } 89c35d236eSmrg 90c35d236eSmrg if(!newmodes) { 911fb744b4Smrg free(modes); 92c35d236eSmrg return FALSE; 93c35d236eSmrg } 94c35d236eSmrg modes = newmodes; 95c35d236eSmrg 96c35d236eSmrgSECOND_PASS: 97c35d236eSmrg 98c35d236eSmrg currentMode = modes + num; 99c35d236eSmrg num++; 100c35d236eSmrg 101c35d236eSmrg currentMode->mode = pMode; 102c35d236eSmrg currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 1031fb744b4Smrg#ifdef HAVE_XAA_H 104c35d236eSmrg if(!pGlint->NoAccel) 105c35d236eSmrg currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 1061fb744b4Smrg#endif 107c35d236eSmrg if(pMode->Flags & V_DBLSCAN) 108c35d236eSmrg currentMode->flags |= DGA_DOUBLESCAN; 109c35d236eSmrg if(pMode->Flags & V_INTERLACE) 110c35d236eSmrg currentMode->flags |= DGA_INTERLACED; 111c35d236eSmrg currentMode->byteOrder = pScrn->imageByteOrder; 112c35d236eSmrg currentMode->depth = pScrn->depth; 113c35d236eSmrg currentMode->bitsPerPixel = pScrn->bitsPerPixel; 114c35d236eSmrg currentMode->red_mask = pScrn->mask.red; 115c35d236eSmrg currentMode->green_mask = pScrn->mask.green; 116c35d236eSmrg currentMode->blue_mask = pScrn->mask.blue; 117c35d236eSmrg currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 118c35d236eSmrg currentMode->viewportWidth = pMode->HDisplay; 119c35d236eSmrg currentMode->viewportHeight = pMode->VDisplay; 120c35d236eSmrg currentMode->xViewportStep = 1; 121c35d236eSmrg currentMode->yViewportStep = 1; 122c35d236eSmrg currentMode->viewportFlags = DGA_FLIP_RETRACE; 123c35d236eSmrg currentMode->offset = 0; 124c35d236eSmrg currentMode->address = pGlint->FbBase; 125c35d236eSmrg 126c35d236eSmrg if(oneMore) { /* first one is narrow width */ 127c35d236eSmrg currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; 128c35d236eSmrg currentMode->imageWidth = pMode->HDisplay; 129c35d236eSmrg currentMode->imageHeight = pMode->VDisplay; 130c35d236eSmrg currentMode->pixmapWidth = currentMode->imageWidth; 131c35d236eSmrg currentMode->pixmapHeight = currentMode->imageHeight; 132c35d236eSmrg currentMode->maxViewportX = currentMode->imageWidth - 133c35d236eSmrg currentMode->viewportWidth; 134c35d236eSmrg /* this might need to get clamped to some maximum */ 135c35d236eSmrg currentMode->maxViewportY = currentMode->imageHeight - 136c35d236eSmrg currentMode->viewportHeight; 137c35d236eSmrg oneMore = FALSE; 138c35d236eSmrg goto SECOND_PASS; 139c35d236eSmrg } else { 140c35d236eSmrg currentMode->bytesPerScanline = 141c35d236eSmrg ((pScrn->displayWidth * Bpp) + 3) & ~3L; 142c35d236eSmrg currentMode->imageWidth = pScrn->displayWidth; 143c35d236eSmrg currentMode->imageHeight = pMode->VDisplay; 144c35d236eSmrg currentMode->pixmapWidth = currentMode->imageWidth; 145c35d236eSmrg currentMode->pixmapHeight = currentMode->imageHeight; 146c35d236eSmrg currentMode->maxViewportX = currentMode->imageWidth - 147c35d236eSmrg currentMode->viewportWidth; 148c35d236eSmrg /* this might need to get clamped to some maximum */ 149c35d236eSmrg currentMode->maxViewportY = currentMode->imageHeight - 150c35d236eSmrg currentMode->viewportHeight; 151c35d236eSmrg } 152c35d236eSmrg 153c35d236eSmrg pMode = pMode->next; 154c35d236eSmrg if(pMode == firstMode) 155c35d236eSmrg break; 156c35d236eSmrg } 157c35d236eSmrg 158c35d236eSmrg pGlint->numDGAModes = num; 159c35d236eSmrg pGlint->DGAModes = modes; 160c35d236eSmrg 161c35d236eSmrg return DGAInit(pScreen, &GLINTDGAFuncs, modes, num); 162c35d236eSmrg} 163c35d236eSmrg 164c35d236eSmrg 165c35d236eSmrgstatic Bool 166c35d236eSmrgGLINT_SetMode( 167c35d236eSmrg ScrnInfoPtr pScrn, 168c35d236eSmrg DGAModePtr pMode 169c35d236eSmrg){ 170c35d236eSmrg static int OldDisplayWidth[MAXSCREENS]; 171c35d236eSmrg int index = pScrn->pScreen->myNum; 172c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 173c35d236eSmrg 174c35d236eSmrg if(!pMode) { /* restore the original mode */ 175c35d236eSmrg /* put the ScreenParameters back */ 176c35d236eSmrg 177c35d236eSmrg pScrn->displayWidth = OldDisplayWidth[index]; 178c35d236eSmrg 1791fb744b4Smrg GLINTSwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode)); 180c35d236eSmrg pGlint->DGAactive = FALSE; 181c35d236eSmrg } else { 182c35d236eSmrg if(!pGlint->DGAactive) { /* save the old parameters */ 183c35d236eSmrg OldDisplayWidth[index] = pScrn->displayWidth; 184c35d236eSmrg 185c35d236eSmrg pGlint->DGAactive = TRUE; 186c35d236eSmrg } 187c35d236eSmrg 188c35d236eSmrg pScrn->displayWidth = pMode->bytesPerScanline / 189c35d236eSmrg (pMode->bitsPerPixel >> 3); 190c35d236eSmrg 1911fb744b4Smrg GLINTSwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode)); 192c35d236eSmrg } 193c35d236eSmrg 194c35d236eSmrg return TRUE; 195c35d236eSmrg} 196c35d236eSmrg 197c35d236eSmrgstatic int 198c35d236eSmrgGLINT_GetViewport( 199c35d236eSmrg ScrnInfoPtr pScrn 200c35d236eSmrg){ 201c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 202c35d236eSmrg 203c35d236eSmrg return pGlint->DGAViewportStatus; 204c35d236eSmrg} 205c35d236eSmrg 206c35d236eSmrgstatic void 207c35d236eSmrgGLINT_SetViewport( 208c35d236eSmrg ScrnInfoPtr pScrn, 209c35d236eSmrg int x, int y, 210c35d236eSmrg int flags 211c35d236eSmrg){ 212c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 213c35d236eSmrg 2141fb744b4Smrg GLINTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); 215c35d236eSmrg pGlint->DGAViewportStatus = 0; /* GLINTAdjustFrame loops until finished */ 216c35d236eSmrg} 217c35d236eSmrg 2181fb744b4Smrg#ifdef HAVE_XAA_H 219c35d236eSmrgstatic void 220c35d236eSmrgGLINT_FillRect ( 221c35d236eSmrg ScrnInfoPtr pScrn, 222c35d236eSmrg int x, int y, int w, int h, 223c35d236eSmrg unsigned long color 224c35d236eSmrg){ 225c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 226c35d236eSmrg 227c35d236eSmrg if(pGlint->AccelInfoRec) { 228c35d236eSmrg (*pGlint->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 229c35d236eSmrg (*pGlint->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 230c35d236eSmrg SET_SYNC_FLAG(pGlint->AccelInfoRec); 231c35d236eSmrg } 232c35d236eSmrg} 2331fb744b4Smrg#endif 234c35d236eSmrg 235c35d236eSmrgstatic void 236c35d236eSmrgGLINT_Sync( 237c35d236eSmrg ScrnInfoPtr pScrn 238c35d236eSmrg){ 239c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 2401fb744b4Smrg#ifdef HAVE_XAA_H 241c35d236eSmrg if(pGlint->AccelInfoRec) { 242c35d236eSmrg (*pGlint->AccelInfoRec->Sync)(pScrn); 243c35d236eSmrg } 2441fb744b4Smrg#endif 245c35d236eSmrg} 246c35d236eSmrg 2471fb744b4Smrg#ifdef HAVE_XAA_H 248c35d236eSmrgstatic void 249c35d236eSmrgGLINT_BlitRect( 250c35d236eSmrg ScrnInfoPtr pScrn, 251c35d236eSmrg int srcx, int srcy, 252c35d236eSmrg int w, int h, 253c35d236eSmrg int dstx, int dsty 254c35d236eSmrg){ 255c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 256c35d236eSmrg 257c35d236eSmrg if(pGlint->AccelInfoRec) { 258c35d236eSmrg int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 259c35d236eSmrg int ydir = (srcy < dsty) ? -1 : 1; 260c35d236eSmrg 261c35d236eSmrg (*pGlint->AccelInfoRec->SetupForScreenToScreenCopy)( 262c35d236eSmrg pScrn, xdir, ydir, GXcopy, ~0, -1); 263c35d236eSmrg (*pGlint->AccelInfoRec->SubsequentScreenToScreenCopy)( 264c35d236eSmrg pScrn, srcx, srcy, dstx, dsty, w, h); 265c35d236eSmrg SET_SYNC_FLAG(pGlint->AccelInfoRec); 266c35d236eSmrg } 267c35d236eSmrg} 2681fb744b4Smrg#endif 269c35d236eSmrgstatic Bool 270c35d236eSmrgGLINT_OpenFramebuffer( 271c35d236eSmrg ScrnInfoPtr pScrn, 272c35d236eSmrg char **name, 273c35d236eSmrg unsigned char **mem, 274c35d236eSmrg int *size, 275c35d236eSmrg int *offset, 276c35d236eSmrg int *flags 277c35d236eSmrg){ 278c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 279c35d236eSmrg 280c35d236eSmrg *name = NULL; /* no special device */ 281c35d236eSmrg *mem = (unsigned char*)pGlint->FbAddress; 282c35d236eSmrg *size = pGlint->FbMapSize; 283c35d236eSmrg *offset = 0; 284c35d236eSmrg *flags = DGA_NEED_ROOT; 285c35d236eSmrg 286c35d236eSmrg return TRUE; 287c35d236eSmrg} 288