cir_dga.c revision 76888252
176888252Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_dga.c,v 1.5 2001/02/15 17:39:27 eich Exp $ */ 276888252Smrg/* 376888252Smrg * Copyright 2000 by Egbert Eich 476888252Smrg * 576888252Smrg * Permission to use, copy, modify, distribute, and sell this software and its 676888252Smrg * documentation for any purpose is hereby granted without fee, provided that 776888252Smrg * the above copyright notice appear in all copies and that both that 876888252Smrg * copyright notice and this permission notice appear in supporting 976888252Smrg * documentation, and that the name of Alan Hourihane not be used in 1076888252Smrg * advertising or publicity pertaining to distribution of the software without 1176888252Smrg * specific, written prior permission. Alan Hourihane makes no representations 1276888252Smrg * about the suitability of this software for any purpose. It is provided 1376888252Smrg * "as is" without express or implied warranty. 1476888252Smrg * 1576888252Smrg * EGBERT EICH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1676888252Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1776888252Smrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1876888252Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1976888252Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 2076888252Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2176888252Smrg * PERFORMANCE OF THIS SOFTWARE. 2276888252Smrg * 2376888252Smrg * Authors: Adapted from: Alan Hourihane, <alanh@fairlite.demon.co.uk> 2476888252Smrg * by: Egbert Eich 2576888252Smrg */ 2676888252Smrg 2776888252Smrg#ifdef HAVE_CONFIG_H 2876888252Smrg#include "config.h" 2976888252Smrg#endif 3076888252Smrg 3176888252Smrg#include "xf86.h" 3276888252Smrg#include "xf86_OSproc.h" 3376888252Smrg#include "xf86Pci.h" 3476888252Smrg#include "xf86PciInfo.h" 3576888252Smrg#include "xaa.h" 3676888252Smrg#include "xaalocal.h" 3776888252Smrg#include "vgaHW.h" 3876888252Smrg#include "cir.h" 3976888252Smrg#include "dgaproc.h" 4076888252Smrg 4176888252Smrgstatic Bool Cir_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 4276888252Smrg int *, int *, int *); 4376888252Smrgstatic Bool Cir_SetMode(ScrnInfoPtr, DGAModePtr); 4476888252Smrgstatic void Cir_Sync(ScrnInfoPtr); 4576888252Smrgstatic int Cir_GetViewport(ScrnInfoPtr); 4676888252Smrgstatic void Cir_SetViewport(ScrnInfoPtr, int, int, int); 4776888252Smrgstatic void Cir_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 4876888252Smrgstatic void Cir_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 4976888252Smrg/* 5076888252Smrgstatic void Cir_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 5176888252Smrg unsigned long); 5276888252Smrg*/ 5376888252Smrg 5476888252Smrgstatic 5576888252SmrgDGAFunctionRec CirDGAFuncs = { 5676888252Smrg Cir_OpenFramebuffer, 5776888252Smrg NULL, /* Cir_CloseFramebuffer */ 5876888252Smrg Cir_SetMode, 5976888252Smrg Cir_SetViewport, 6076888252Smrg Cir_GetViewport, 6176888252Smrg Cir_Sync, 6276888252Smrg Cir_FillRect, 6376888252Smrg Cir_BlitRect, 6476888252Smrg NULL /* Cir_BlitTransRect */ 6576888252Smrg}; 6676888252Smrg 6776888252Smrg 6876888252Smrg 6976888252Smrg 7076888252SmrgBool 7176888252SmrgCirDGAInit(ScreenPtr pScreen) 7276888252Smrg{ 7376888252Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 7476888252Smrg CirPtr pCir = CIRPTR(pScrn); 7576888252Smrg DGAModePtr modes = NULL, newmodes = NULL, currentMode; 7676888252Smrg DisplayModePtr pMode, firstMode; 7776888252Smrg int Bpp = pScrn->bitsPerPixel >> 3; 7876888252Smrg int num = 0; 7976888252Smrg int imlines = (pScrn->videoRam * 1024) / 8076888252Smrg (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); 8176888252Smrg 8276888252Smrg 8376888252Smrg if (!pCir->DGAnumModes) { 8476888252Smrg pMode = firstMode = pScrn->modes; 8576888252Smrg while (pMode) { 8676888252Smrg newmodes = xrealloc(modes, (num + 1) * sizeof (DGAModeRec)); 8776888252Smrg if (!newmodes) { 8876888252Smrg xfree(modes); 8976888252Smrg return FALSE; 9076888252Smrg } 9176888252Smrg modes = newmodes; 9276888252Smrg currentMode = modes + num; 9376888252Smrg num++; 9476888252Smrg (void)memset(currentMode, 1, sizeof(DGAModeRec)); 9576888252Smrg currentMode->mode = pMode; 9676888252Smrg currentMode->flags = DGA_PIXMAP_AVAILABLE 9776888252Smrg | ((!pCir->NoAccel) ? (DGA_FILL_RECT | DGA_BLIT_RECT) : 0); 9876888252Smrg if (pMode->Flags & V_DBLSCAN) 9976888252Smrg currentMode->flags |= DGA_DOUBLESCAN; 10076888252Smrg if(pMode->Flags & V_INTERLACE) 10176888252Smrg currentMode->flags |= DGA_INTERLACED; 10276888252Smrg currentMode->byteOrder = pScrn->imageByteOrder; 10376888252Smrg currentMode->depth = pScrn->depth; 10476888252Smrg currentMode->bitsPerPixel = pScrn->bitsPerPixel; 10576888252Smrg currentMode->red_mask = pScrn->mask.red; 10676888252Smrg currentMode->green_mask = pScrn->mask.green; 10776888252Smrg currentMode->blue_mask = pScrn->mask.blue; 10876888252Smrg currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 10976888252Smrg currentMode->viewportWidth = pMode->HDisplay; 11076888252Smrg currentMode->viewportHeight = pMode->VDisplay; 11176888252Smrg currentMode->xViewportStep = 1; /* The granularity of x and y pos. */ 11276888252Smrg currentMode->yViewportStep = 1; 11376888252Smrg currentMode->viewportFlags = 0 /*DGA_FLIP_RETRACE*/; 11476888252Smrg currentMode->offset = 0; 11576888252Smrg currentMode->address = pCir->FbBase; 11676888252Smrg currentMode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L; 11776888252Smrg currentMode->pixmapWidth = currentMode->imageWidth 11876888252Smrg = pScrn->displayWidth; 11976888252Smrg currentMode->pixmapHeight = currentMode->imageHeight = imlines; 12076888252Smrg currentMode->maxViewportX = currentMode->imageWidth - 12176888252Smrg currentMode->viewportWidth; 12276888252Smrg /* this might need to get clamped to some maximum */ 12376888252Smrg currentMode->maxViewportY = currentMode->imageHeight - 12476888252Smrg currentMode->viewportHeight; 12576888252Smrg 12676888252Smrg pMode = pMode->next; 12776888252Smrg if(pMode == firstMode) 12876888252Smrg break; 12976888252Smrg } 13076888252Smrg pCir->DGAnumModes = num; 13176888252Smrg pCir->DGAModes = modes; 13276888252Smrg } 13376888252Smrg return DGAInit(pScreen, &CirDGAFuncs, pCir->DGAModes, pCir->DGAnumModes); 13476888252Smrg} 13576888252Smrg 13676888252Smrgstatic Bool 13776888252SmrgCir_OpenFramebuffer( 13876888252Smrg ScrnInfoPtr pScrn, 13976888252Smrg char **name, 14076888252Smrg unsigned char **mem, 14176888252Smrg int *size, 14276888252Smrg int *offset, 14376888252Smrg int *flags 14476888252Smrg){ 14576888252Smrg CirPtr pCir = CIRPTR(pScrn); 14676888252Smrg 14776888252Smrg *name = NULL; /* no special device */ 14876888252Smrg *mem = (unsigned char*)(long)pCir->FbAddress; 14976888252Smrg *size = pCir->FbMapSize; 15076888252Smrg *offset = 0; /* Always */ 15176888252Smrg *flags = 0; /* Root permissions OS-dependent */ 15276888252Smrg 15376888252Smrg return TRUE; 15476888252Smrg} 15576888252Smrg 15676888252Smrg 15776888252Smrgstatic Bool 15876888252SmrgCir_SetMode( 15976888252Smrg ScrnInfoPtr pScrn, 16076888252Smrg DGAModePtr pMode 16176888252Smrg){ 16276888252Smrg CirPtr pCir = CIRPTR(pScrn); 16376888252Smrg static int OldDisplayWidth[MAXSCREENS]; 16476888252Smrg int index = pScrn->pScreen->myNum; 16576888252Smrg Bool ret = FALSE; 16676888252Smrg 16776888252Smrg if(!pMode) { /* restore the original mode */ 16876888252Smrg /* put the ScreenParameters back */ 16976888252Smrg pScrn->displayWidth = OldDisplayWidth[index]; 17076888252Smrg ret = pCir->DGAModeInit(xf86Screens[index], pScrn->currentMode); 17176888252Smrg pCir->DGAactive = FALSE; 17276888252Smrg } else { 17376888252Smrg if(!pCir->DGAactive) { /* save the old parameters */ 17476888252Smrg OldDisplayWidth[index] = pScrn->displayWidth; 17576888252Smrg 17676888252Smrg pCir->DGAactive = TRUE; 17776888252Smrg } 17876888252Smrg pScrn->displayWidth = pMode->bytesPerScanline / 17976888252Smrg (pMode->bitsPerPixel >> 3); 18076888252Smrg 18176888252Smrg ret = pCir->DGAModeInit(xf86Screens[index], pMode->mode); 18276888252Smrg } 18376888252Smrg return ret; 18476888252Smrg} 18576888252Smrg 18676888252Smrgstatic void 18776888252SmrgCir_SetViewport( 18876888252Smrg ScrnInfoPtr pScrn, 18976888252Smrg int x, int y, 19076888252Smrg int flags 19176888252Smrg){ 19276888252Smrg CirPtr pCir = CIRPTR(pScrn); 19376888252Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 19476888252Smrg 19576888252Smrg pScrn->AdjustFrame(pScrn->pScreen->myNum, x, y, flags); 19676888252Smrg 19776888252Smrg while((hwp->readST01(hwp) & 0x08)); 19876888252Smrg while(!(hwp->readST01(hwp) & 0x08)); 19976888252Smrg 20076888252Smrg pCir->DGAViewportStatus = 0; /* AdjustFrame loops until finished */ 20176888252Smrg} 20276888252Smrg 20376888252Smrgstatic int 20476888252SmrgCir_GetViewport( 20576888252Smrg ScrnInfoPtr pScrn 20676888252Smrg){ 20776888252Smrg CirPtr pCir = CIRPTR(pScrn); 20876888252Smrg 20976888252Smrg return pCir->DGAViewportStatus; 21076888252Smrg} 21176888252Smrg 21276888252Smrg 21376888252Smrg 21476888252Smrgstatic void 21576888252SmrgCir_Sync( 21676888252Smrg ScrnInfoPtr pScrn 21776888252Smrg){ 21876888252Smrg CirPtr pCir = CIRPTR(pScrn); 21976888252Smrg 22076888252Smrg if(pCir->AccelInfoRec) { 22176888252Smrg (*pCir->AccelInfoRec->Sync)(pScrn); 22276888252Smrg } 22376888252Smrg} 22476888252Smrg 22576888252Smrgstatic void 22676888252SmrgCir_FillRect ( 22776888252Smrg ScrnInfoPtr pScrn, 22876888252Smrg int x, int y, int w, int h, 22976888252Smrg unsigned long color 23076888252Smrg){ 23176888252Smrg CirPtr pCir = CIRPTR(pScrn); 23276888252Smrg 23376888252Smrg if(pCir->AccelInfoRec) { 23476888252Smrg (*pCir->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 23576888252Smrg (*pCir->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 23676888252Smrg SET_SYNC_FLAG(pCir->AccelInfoRec); 23776888252Smrg } 23876888252Smrg} 23976888252Smrg 24076888252Smrgstatic void 24176888252SmrgCir_BlitRect( 24276888252Smrg ScrnInfoPtr pScrn, 24376888252Smrg int srcx, int srcy, 24476888252Smrg int w, int h, 24576888252Smrg int dstx, int dsty 24676888252Smrg){ 24776888252Smrg CirPtr pCir = CIRPTR(pScrn); 24876888252Smrg 24976888252Smrg if(pCir->AccelInfoRec) { 25076888252Smrg int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 25176888252Smrg int ydir = (srcy < dsty) ? -1 : 1; 25276888252Smrg 25376888252Smrg (*pCir->AccelInfoRec->SetupForScreenToScreenCopy)( 25476888252Smrg pScrn, xdir, ydir, GXcopy, ~0, -1); 25576888252Smrg (*pCir->AccelInfoRec->SubsequentScreenToScreenCopy)( 25676888252Smrg pScrn, srcx, srcy, dstx, dsty, w, h); 25776888252Smrg SET_SYNC_FLAG(pCir->AccelInfoRec); 25876888252Smrg } 25976888252Smrg} 260