1d983712dSmrg/* 2d983712dSmrg * Copyright 2000 by Rainer Keller, <Rainer.Keller@studmail.uni-stuttgart.de>. 3d983712dSmrg * 4d983712dSmrg * Permission to use, copy, modify, distribute, and sell this software and its 5d983712dSmrg * documentation for any purpose is hereby granted without fee, provided that 6d983712dSmrg * the above copyright notice appear in all copies and that both that 7d983712dSmrg * copyright notice and this permission notice appear in supporting 8d983712dSmrg * documentation, and that the name of Alan Hourihane not be used in 9d983712dSmrg * advertising or publicity pertaining to distribution of the software without 10d983712dSmrg * specific, written prior permission. Alan Hourihane makes no representations 11d983712dSmrg * about the suitability of this software for any purpose. It is provided 12d983712dSmrg * "as is" without express or implied warranty. 13d983712dSmrg * 14d983712dSmrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15d983712dSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16d983712dSmrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17d983712dSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18d983712dSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19d983712dSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20d983712dSmrg * PERFORMANCE OF THIS SOFTWARE. 21d983712dSmrg * 22d983712dSmrg * Authors: Adapted from: Alan Hourihane, <alanh@fairlite.demon.co.uk> 23d983712dSmrg * by: Rainer Keller, <Rainer.Keller@studmail.uni-stuttgart.de> 24d983712dSmrg */ 25d983712dSmrg 26d983712dSmrg#ifdef HAVE_CONFIG_H 27d983712dSmrg#include "config.h" 28d983712dSmrg#endif 29d983712dSmrg 30d983712dSmrg#include "tseng.h" 31d983712dSmrg#include "dgaproc.h" 32d983712dSmrg 33d983712dSmrgstatic Bool Tseng_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 34d983712dSmrg int *, int *, int *); 35d983712dSmrgstatic Bool Tseng_SetMode(ScrnInfoPtr, DGAModePtr); 36d983712dSmrgstatic void Tseng_Sync(ScrnInfoPtr); 37d983712dSmrgstatic int Tseng_GetViewport(ScrnInfoPtr); 38d983712dSmrgstatic void Tseng_SetViewport(ScrnInfoPtr, int, int, int); 394b9470b1Smrg#ifdef HAVE_XAA_H 40d983712dSmrgstatic void Tseng_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 41d983712dSmrgstatic void Tseng_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 42d983712dSmrg/* 43d983712dSmrgstatic void Tseng_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 44d983712dSmrg unsigned long); 45d983712dSmrg*/ 464b9470b1Smrg#endif 47d983712dSmrg 48d983712dSmrgstatic 49d983712dSmrgDGAFunctionRec TsengDGAFuncs = { 50d983712dSmrg Tseng_OpenFramebuffer, 51d983712dSmrg NULL, /* Tseng_CloseFramebuffer */ 52d983712dSmrg Tseng_SetMode, 53d983712dSmrg Tseng_SetViewport, 54d983712dSmrg Tseng_GetViewport, 55d983712dSmrg Tseng_Sync, 564b9470b1Smrg#ifdef HAVE_XAA_H 57d983712dSmrg Tseng_FillRect, 58d983712dSmrg Tseng_BlitRect, 59d983712dSmrg NULL /* Tseng_BlitTransRect */ 604b9470b1Smrg#else 614b9470b1Smrg NULL, NULL, NULL 624b9470b1Smrg#endif 63d983712dSmrg}; 64d983712dSmrg 65d983712dSmrg 66d983712dSmrg 67d983712dSmrg 68d983712dSmrgBool 69d983712dSmrgTsengDGAInit(ScreenPtr pScreen) 70d983712dSmrg{ 714b9470b1Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 72d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 73d983712dSmrg DGAModePtr modes = NULL, newmodes = NULL, currentMode; 74d983712dSmrg DisplayModePtr pMode, firstMode; 75d983712dSmrg int Bpp = pScrn->bitsPerPixel >> 3; 76d983712dSmrg int num = 0; 77d983712dSmrg int imlines = (pScrn->videoRam * 1024) / 78d983712dSmrg (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); 79d983712dSmrg 80d983712dSmrg if (!pTseng->DGAnumModes) { 81d983712dSmrg pMode = firstMode = pScrn->modes; 82d983712dSmrg while (pMode) { 834b9470b1Smrg newmodes = realloc(modes, (num + 1) * sizeof (DGAModeRec)); 84d983712dSmrg if (!newmodes) { 854b9470b1Smrg free(modes); 86d983712dSmrg return FALSE; 87d983712dSmrg } 88d983712dSmrg modes = newmodes; 89d983712dSmrg currentMode = modes + num; 90d983712dSmrg num++; 91d983712dSmrg (void)memset(currentMode, 1, sizeof(DGAModeRec)); 92d983712dSmrg currentMode->mode = pMode; 934b9470b1Smrg currentMode->flags = DGA_PIXMAP_AVAILABLE; 944b9470b1Smrg#ifdef HAVE_XAA_H 954b9470b1Smrg currentMode->flags |= ((pTseng->UseAccel) ? (DGA_FILL_RECT | DGA_BLIT_RECT) : 0); 964b9470b1Smrg#endif 97d983712dSmrg if (pMode->Flags & V_DBLSCAN) 98d983712dSmrg currentMode->flags |= DGA_DOUBLESCAN; 99d983712dSmrg if(pMode->Flags & V_INTERLACE) 100d983712dSmrg currentMode->flags |= DGA_INTERLACED; 101d983712dSmrg currentMode->byteOrder = pScrn->imageByteOrder; 102d983712dSmrg currentMode->depth = pScrn->depth; 103d983712dSmrg currentMode->bitsPerPixel = pScrn->bitsPerPixel; 104d983712dSmrg currentMode->red_mask = pScrn->mask.red; 105d983712dSmrg currentMode->green_mask = pScrn->mask.green; 106d983712dSmrg currentMode->blue_mask = pScrn->mask.blue; 107d983712dSmrg currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 108d983712dSmrg currentMode->viewportWidth = pMode->HDisplay; 109d983712dSmrg currentMode->viewportHeight = pMode->VDisplay; 110d983712dSmrg currentMode->xViewportStep = 1; /* The granularity of x and y pos. */ 111d983712dSmrg currentMode->yViewportStep = 1; 112d983712dSmrg currentMode->viewportFlags = 0 /*DGA_FLIP_RETRACE*/; 113d983712dSmrg currentMode->offset = 0; 114d983712dSmrg currentMode->address = pTseng->FbBase; 115d983712dSmrg currentMode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L; 116d983712dSmrg currentMode->pixmapWidth = currentMode->imageWidth = pScrn->displayWidth; 117d983712dSmrg currentMode->pixmapHeight = currentMode->imageHeight = imlines; 118d983712dSmrg currentMode->maxViewportX = currentMode->imageWidth - 119d983712dSmrg currentMode->viewportWidth; 120d983712dSmrg /* this might need to get clamped to some maximum */ 121d983712dSmrg currentMode->maxViewportY = currentMode->imageHeight - 122d983712dSmrg currentMode->viewportHeight; 123d983712dSmrg 124d983712dSmrg pMode = pMode->next; 125d983712dSmrg if(pMode == firstMode) 126d983712dSmrg break; 127d983712dSmrg } 128d983712dSmrg pTseng->DGAnumModes = num; 129d983712dSmrg pTseng->DGAModes = modes; 130d983712dSmrg } 131d983712dSmrg return DGAInit(pScreen, &TsengDGAFuncs, pTseng->DGAModes, pTseng->DGAnumModes); 132d983712dSmrg} 133d983712dSmrg 134d983712dSmrgstatic Bool 135d983712dSmrgTseng_OpenFramebuffer( 136d983712dSmrg ScrnInfoPtr pScrn, 137d983712dSmrg char **name, 138d983712dSmrg unsigned char **mem, 139d983712dSmrg int *size, 140d983712dSmrg int *offset, 141d983712dSmrg int *flags 142d983712dSmrg){ 143d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 144d983712dSmrg 145d983712dSmrg *name = NULL; /* no special device */ 1464b9470b1Smrg *mem = (unsigned char*)(uintptr_t)pTseng->FbAddress; 147d983712dSmrg *size = pTseng->FbMapSize; 148d983712dSmrg *offset = 0; /* Always */ 149d983712dSmrg *flags = 0; /* Root permissions OS-dependent */ 150d983712dSmrg 151d983712dSmrg return TRUE; 152d983712dSmrg} 153d983712dSmrg 154d983712dSmrg 155d983712dSmrgstatic Bool 156d983712dSmrgTseng_SetMode( 157d983712dSmrg ScrnInfoPtr pScrn, 158d983712dSmrg DGAModePtr pMode 159d983712dSmrg){ 160d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 161d983712dSmrg static int OldDisplayWidth[MAXSCREENS]; 162d983712dSmrg int index = pScrn->pScreen->myNum; 163d983712dSmrg Bool ret; 164d983712dSmrg 165d983712dSmrg if(!pMode) { /* restore the original mode */ 166d983712dSmrg /* put the ScreenParameters back */ 167d983712dSmrg pScrn->displayWidth = OldDisplayWidth[index]; 168d983712dSmrg ret = TsengModeInit(xf86Screens[index], pScrn->currentMode); 169d983712dSmrg pTseng->DGAactive = FALSE; 170d983712dSmrg } else { 171d983712dSmrg if(!pTseng->DGAactive) { /* save the old parameters */ 172d983712dSmrg OldDisplayWidth[index] = pScrn->displayWidth; 173d983712dSmrg 174d983712dSmrg pTseng->DGAactive = TRUE; 175d983712dSmrg } 176d983712dSmrg pScrn->displayWidth = pMode->bytesPerScanline / 177d983712dSmrg (pMode->bitsPerPixel >> 3); 178d983712dSmrg 179d983712dSmrg ret = TsengModeInit(xf86Screens[index], pMode->mode); 180d983712dSmrg } 181d983712dSmrg return ret; 182d983712dSmrg} 183d983712dSmrg 184d983712dSmrgstatic void 185d983712dSmrgTseng_SetViewport( 186d983712dSmrg ScrnInfoPtr pScrn, 187d983712dSmrg int x, int y, 188d983712dSmrg int flags 189d983712dSmrg){ 190d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 191d983712dSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 192d983712dSmrg 1934b9470b1Smrg TsengAdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); 194d983712dSmrg while((hwp->readST01(hwp) & 0x08)); 195d983712dSmrg while(!(hwp->readST01(hwp) & 0x08)); 196d983712dSmrg 197d983712dSmrg pTseng->DGAViewportStatus = 0; /* TsengAdjustFrame loops until finished */ 198d983712dSmrg} 199d983712dSmrg 200d983712dSmrgstatic int 201d983712dSmrgTseng_GetViewport( 202d983712dSmrg ScrnInfoPtr pScrn 203d983712dSmrg){ 204d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 205d983712dSmrg 206d983712dSmrg return pTseng->DGAViewportStatus; 207d983712dSmrg} 208d983712dSmrg 209d983712dSmrg 210d983712dSmrg 211d983712dSmrgstatic void 212d983712dSmrgTseng_Sync( 213d983712dSmrg ScrnInfoPtr pScrn 214d983712dSmrg){ 215d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 2164b9470b1Smrg#ifdef HAVE_XAA_H 217d983712dSmrg if(pTseng->AccelInfoRec) { 218d983712dSmrg (*pTseng->AccelInfoRec->Sync)(pScrn); 219d983712dSmrg } 2204b9470b1Smrg#endif 221d983712dSmrg} 222d983712dSmrg 2234b9470b1Smrg#ifdef HAVE_XAA_H 224d983712dSmrgstatic void 225d983712dSmrgTseng_FillRect ( 226d983712dSmrg ScrnInfoPtr pScrn, 227d983712dSmrg int x, int y, int w, int h, 228d983712dSmrg unsigned long color 229d983712dSmrg){ 230d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 231d983712dSmrg 232d983712dSmrg if(pTseng->AccelInfoRec) { 233d983712dSmrg (*pTseng->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 234d983712dSmrg (*pTseng->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 235d983712dSmrg SET_SYNC_FLAG(pTseng->AccelInfoRec); 236d983712dSmrg } 237d983712dSmrg} 238d983712dSmrg 239d983712dSmrgstatic void 240d983712dSmrgTseng_BlitRect( 241d983712dSmrg ScrnInfoPtr pScrn, 242d983712dSmrg int srcx, int srcy, 243d983712dSmrg int w, int h, 244d983712dSmrg int dstx, int dsty 245d983712dSmrg){ 246d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 247d983712dSmrg 248d983712dSmrg if(pTseng->AccelInfoRec) { 249d983712dSmrg int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 250d983712dSmrg int ydir = (srcy < dsty) ? -1 : 1; 251d983712dSmrg 252d983712dSmrg (*pTseng->AccelInfoRec->SetupForScreenToScreenCopy)( 253d983712dSmrg pScrn, xdir, ydir, GXcopy, ~0, -1); 254d983712dSmrg (*pTseng->AccelInfoRec->SubsequentScreenToScreenCopy)( 255d983712dSmrg pScrn, srcx, srcy, dstx, dsty, w, h); 256d983712dSmrg SET_SYNC_FLAG(pTseng->AccelInfoRec); 257d983712dSmrg } 258d983712dSmrg} 2594b9470b1Smrg#endif 260