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