glint_dga.c revision c35d236e
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/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dga.c,v 1.3 2001/04/10 20:33:30 dawes Exp $ */ 25c35d236eSmrg 26c35d236eSmrg#ifdef HAVE_CONFIG_H 27c35d236eSmrg#include "config.h" 28c35d236eSmrg#endif 29c35d236eSmrg 30c35d236eSmrg#include "xf86.h" 31c35d236eSmrg#include "xf86_OSproc.h" 32c35d236eSmrg#include "xf86Pci.h" 33c35d236eSmrg#include "xf86PciInfo.h" 34c35d236eSmrg#include "xaa.h" 35c35d236eSmrg#include "xaalocal.h" 36c35d236eSmrg#include "glint.h" 37c35d236eSmrg#include "glint_regs.h" 38c35d236eSmrg#include "dgaproc.h" 39c35d236eSmrg 40c35d236eSmrgstatic Bool GLINT_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 41c35d236eSmrg int *, int *, int *); 42c35d236eSmrgstatic Bool GLINT_SetMode(ScrnInfoPtr, DGAModePtr); 43c35d236eSmrgstatic void GLINT_Sync(ScrnInfoPtr); 44c35d236eSmrgstatic int GLINT_GetViewport(ScrnInfoPtr); 45c35d236eSmrgstatic void GLINT_SetViewport(ScrnInfoPtr, int, int, int); 46c35d236eSmrgstatic void GLINT_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 47c35d236eSmrgstatic void GLINT_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 48c35d236eSmrg 49c35d236eSmrgstatic 50c35d236eSmrgDGAFunctionRec GLINTDGAFuncs = { 51c35d236eSmrg GLINT_OpenFramebuffer, 52c35d236eSmrg NULL, 53c35d236eSmrg GLINT_SetMode, 54c35d236eSmrg GLINT_SetViewport, 55c35d236eSmrg GLINT_GetViewport, 56c35d236eSmrg GLINT_Sync, 57c35d236eSmrg GLINT_FillRect, 58c35d236eSmrg GLINT_BlitRect, 59c35d236eSmrg NULL 60c35d236eSmrg}; 61c35d236eSmrg 62c35d236eSmrgBool 63c35d236eSmrgGLINTDGAInit(ScreenPtr pScreen) 64c35d236eSmrg{ 65c35d236eSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 66c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 67c35d236eSmrg DGAModePtr modes = NULL, newmodes = NULL, currentMode; 68c35d236eSmrg DisplayModePtr pMode, firstMode; 69c35d236eSmrg int Bpp = pScrn->bitsPerPixel >> 3; 70c35d236eSmrg int num = 0; 71c35d236eSmrg Bool oneMore; 72c35d236eSmrg 73c35d236eSmrg pMode = firstMode = pScrn->modes; 74c35d236eSmrg 75c35d236eSmrg while(pMode) { 76c35d236eSmrg 77c35d236eSmrg if(0 /*pScrn->displayWidth != pMode->HDisplay*/) { 78c35d236eSmrg newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec)); 79c35d236eSmrg oneMore = TRUE; 80c35d236eSmrg } else { 81c35d236eSmrg newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); 82c35d236eSmrg oneMore = FALSE; 83c35d236eSmrg } 84c35d236eSmrg 85c35d236eSmrg if(!newmodes) { 86c35d236eSmrg xfree(modes); 87c35d236eSmrg return FALSE; 88c35d236eSmrg } 89c35d236eSmrg modes = newmodes; 90c35d236eSmrg 91c35d236eSmrgSECOND_PASS: 92c35d236eSmrg 93c35d236eSmrg currentMode = modes + num; 94c35d236eSmrg num++; 95c35d236eSmrg 96c35d236eSmrg currentMode->mode = pMode; 97c35d236eSmrg currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 98c35d236eSmrg if(!pGlint->NoAccel) 99c35d236eSmrg currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 100c35d236eSmrg if(pMode->Flags & V_DBLSCAN) 101c35d236eSmrg currentMode->flags |= DGA_DOUBLESCAN; 102c35d236eSmrg if(pMode->Flags & V_INTERLACE) 103c35d236eSmrg currentMode->flags |= DGA_INTERLACED; 104c35d236eSmrg currentMode->byteOrder = pScrn->imageByteOrder; 105c35d236eSmrg currentMode->depth = pScrn->depth; 106c35d236eSmrg currentMode->bitsPerPixel = pScrn->bitsPerPixel; 107c35d236eSmrg currentMode->red_mask = pScrn->mask.red; 108c35d236eSmrg currentMode->green_mask = pScrn->mask.green; 109c35d236eSmrg currentMode->blue_mask = pScrn->mask.blue; 110c35d236eSmrg currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 111c35d236eSmrg currentMode->viewportWidth = pMode->HDisplay; 112c35d236eSmrg currentMode->viewportHeight = pMode->VDisplay; 113c35d236eSmrg currentMode->xViewportStep = 1; 114c35d236eSmrg currentMode->yViewportStep = 1; 115c35d236eSmrg currentMode->viewportFlags = DGA_FLIP_RETRACE; 116c35d236eSmrg currentMode->offset = 0; 117c35d236eSmrg currentMode->address = pGlint->FbBase; 118c35d236eSmrg 119c35d236eSmrg if(oneMore) { /* first one is narrow width */ 120c35d236eSmrg currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; 121c35d236eSmrg currentMode->imageWidth = pMode->HDisplay; 122c35d236eSmrg currentMode->imageHeight = pMode->VDisplay; 123c35d236eSmrg currentMode->pixmapWidth = currentMode->imageWidth; 124c35d236eSmrg currentMode->pixmapHeight = currentMode->imageHeight; 125c35d236eSmrg currentMode->maxViewportX = currentMode->imageWidth - 126c35d236eSmrg currentMode->viewportWidth; 127c35d236eSmrg /* this might need to get clamped to some maximum */ 128c35d236eSmrg currentMode->maxViewportY = currentMode->imageHeight - 129c35d236eSmrg currentMode->viewportHeight; 130c35d236eSmrg oneMore = FALSE; 131c35d236eSmrg goto SECOND_PASS; 132c35d236eSmrg } else { 133c35d236eSmrg currentMode->bytesPerScanline = 134c35d236eSmrg ((pScrn->displayWidth * Bpp) + 3) & ~3L; 135c35d236eSmrg currentMode->imageWidth = pScrn->displayWidth; 136c35d236eSmrg currentMode->imageHeight = pMode->VDisplay; 137c35d236eSmrg currentMode->pixmapWidth = currentMode->imageWidth; 138c35d236eSmrg currentMode->pixmapHeight = currentMode->imageHeight; 139c35d236eSmrg currentMode->maxViewportX = currentMode->imageWidth - 140c35d236eSmrg currentMode->viewportWidth; 141c35d236eSmrg /* this might need to get clamped to some maximum */ 142c35d236eSmrg currentMode->maxViewportY = currentMode->imageHeight - 143c35d236eSmrg currentMode->viewportHeight; 144c35d236eSmrg } 145c35d236eSmrg 146c35d236eSmrg pMode = pMode->next; 147c35d236eSmrg if(pMode == firstMode) 148c35d236eSmrg break; 149c35d236eSmrg } 150c35d236eSmrg 151c35d236eSmrg pGlint->numDGAModes = num; 152c35d236eSmrg pGlint->DGAModes = modes; 153c35d236eSmrg 154c35d236eSmrg return DGAInit(pScreen, &GLINTDGAFuncs, modes, num); 155c35d236eSmrg} 156c35d236eSmrg 157c35d236eSmrg 158c35d236eSmrgstatic Bool 159c35d236eSmrgGLINT_SetMode( 160c35d236eSmrg ScrnInfoPtr pScrn, 161c35d236eSmrg DGAModePtr pMode 162c35d236eSmrg){ 163c35d236eSmrg static int OldDisplayWidth[MAXSCREENS]; 164c35d236eSmrg int index = pScrn->pScreen->myNum; 165c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 166c35d236eSmrg 167c35d236eSmrg if(!pMode) { /* restore the original mode */ 168c35d236eSmrg /* put the ScreenParameters back */ 169c35d236eSmrg 170c35d236eSmrg pScrn->displayWidth = OldDisplayWidth[index]; 171c35d236eSmrg 172c35d236eSmrg GLINTSwitchMode(index, pScrn->currentMode, 0); 173c35d236eSmrg pGlint->DGAactive = FALSE; 174c35d236eSmrg } else { 175c35d236eSmrg if(!pGlint->DGAactive) { /* save the old parameters */ 176c35d236eSmrg OldDisplayWidth[index] = pScrn->displayWidth; 177c35d236eSmrg 178c35d236eSmrg pGlint->DGAactive = TRUE; 179c35d236eSmrg } 180c35d236eSmrg 181c35d236eSmrg pScrn->displayWidth = pMode->bytesPerScanline / 182c35d236eSmrg (pMode->bitsPerPixel >> 3); 183c35d236eSmrg 184c35d236eSmrg GLINTSwitchMode(index, pMode->mode, 0); 185c35d236eSmrg } 186c35d236eSmrg 187c35d236eSmrg return TRUE; 188c35d236eSmrg} 189c35d236eSmrg 190c35d236eSmrgstatic int 191c35d236eSmrgGLINT_GetViewport( 192c35d236eSmrg ScrnInfoPtr pScrn 193c35d236eSmrg){ 194c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 195c35d236eSmrg 196c35d236eSmrg return pGlint->DGAViewportStatus; 197c35d236eSmrg} 198c35d236eSmrg 199c35d236eSmrgstatic void 200c35d236eSmrgGLINT_SetViewport( 201c35d236eSmrg ScrnInfoPtr pScrn, 202c35d236eSmrg int x, int y, 203c35d236eSmrg int flags 204c35d236eSmrg){ 205c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 206c35d236eSmrg 207c35d236eSmrg GLINTAdjustFrame(pScrn->pScreen->myNum, x, y, flags); 208c35d236eSmrg pGlint->DGAViewportStatus = 0; /* GLINTAdjustFrame loops until finished */ 209c35d236eSmrg} 210c35d236eSmrg 211c35d236eSmrgstatic void 212c35d236eSmrgGLINT_FillRect ( 213c35d236eSmrg ScrnInfoPtr pScrn, 214c35d236eSmrg int x, int y, int w, int h, 215c35d236eSmrg unsigned long color 216c35d236eSmrg){ 217c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 218c35d236eSmrg 219c35d236eSmrg if(pGlint->AccelInfoRec) { 220c35d236eSmrg (*pGlint->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 221c35d236eSmrg (*pGlint->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 222c35d236eSmrg SET_SYNC_FLAG(pGlint->AccelInfoRec); 223c35d236eSmrg } 224c35d236eSmrg} 225c35d236eSmrg 226c35d236eSmrgstatic void 227c35d236eSmrgGLINT_Sync( 228c35d236eSmrg ScrnInfoPtr pScrn 229c35d236eSmrg){ 230c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 231c35d236eSmrg 232c35d236eSmrg if(pGlint->AccelInfoRec) { 233c35d236eSmrg (*pGlint->AccelInfoRec->Sync)(pScrn); 234c35d236eSmrg } 235c35d236eSmrg} 236c35d236eSmrg 237c35d236eSmrgstatic void 238c35d236eSmrgGLINT_BlitRect( 239c35d236eSmrg ScrnInfoPtr pScrn, 240c35d236eSmrg int srcx, int srcy, 241c35d236eSmrg int w, int h, 242c35d236eSmrg int dstx, int dsty 243c35d236eSmrg){ 244c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 245c35d236eSmrg 246c35d236eSmrg if(pGlint->AccelInfoRec) { 247c35d236eSmrg int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 248c35d236eSmrg int ydir = (srcy < dsty) ? -1 : 1; 249c35d236eSmrg 250c35d236eSmrg (*pGlint->AccelInfoRec->SetupForScreenToScreenCopy)( 251c35d236eSmrg pScrn, xdir, ydir, GXcopy, ~0, -1); 252c35d236eSmrg (*pGlint->AccelInfoRec->SubsequentScreenToScreenCopy)( 253c35d236eSmrg pScrn, srcx, srcy, dstx, dsty, w, h); 254c35d236eSmrg SET_SYNC_FLAG(pGlint->AccelInfoRec); 255c35d236eSmrg } 256c35d236eSmrg} 257c35d236eSmrg 258c35d236eSmrgstatic Bool 259c35d236eSmrgGLINT_OpenFramebuffer( 260c35d236eSmrg ScrnInfoPtr pScrn, 261c35d236eSmrg char **name, 262c35d236eSmrg unsigned char **mem, 263c35d236eSmrg int *size, 264c35d236eSmrg int *offset, 265c35d236eSmrg int *flags 266c35d236eSmrg){ 267c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 268c35d236eSmrg 269c35d236eSmrg *name = NULL; /* no special device */ 270c35d236eSmrg *mem = (unsigned char*)pGlint->FbAddress; 271c35d236eSmrg *size = pGlint->FbMapSize; 272c35d236eSmrg *offset = 0; 273c35d236eSmrg *flags = DGA_NEED_ROOT; 274c35d236eSmrg 275c35d236eSmrg return TRUE; 276c35d236eSmrg} 277