103b705cfSriastradh/* 203b705cfSriastradh * Copyright 2000 by Alan Hourihane, Sychdyn, North Wales, UK. 303b705cfSriastradh * 403b705cfSriastradh * Permission to use, copy, modify, distribute, and sell this software and its 503b705cfSriastradh * documentation for any purpose is hereby granted without fee, provided that 603b705cfSriastradh * the above copyright notice appear in all copies and that both that 703b705cfSriastradh * copyright notice and this permission notice appear in supporting 803b705cfSriastradh * documentation, and that the name of Alan Hourihane not be used in 903b705cfSriastradh * advertising or publicity pertaining to distribution of the software without 1003b705cfSriastradh * specific, written prior permission. Alan Hourihane makes no representations 1103b705cfSriastradh * about the suitability of this software for any purpose. It is provided 1203b705cfSriastradh * "as is" without express or implied warranty. 1303b705cfSriastradh * 1403b705cfSriastradh * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1503b705cfSriastradh * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1603b705cfSriastradh * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1703b705cfSriastradh * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1803b705cfSriastradh * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1903b705cfSriastradh * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2003b705cfSriastradh * PERFORMANCE OF THIS SOFTWARE. 2103b705cfSriastradh * 2203b705cfSriastradh * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> 2303b705cfSriastradh */ 2403b705cfSriastradh 2503b705cfSriastradh#ifdef HAVE_CONFIG_H 2603b705cfSriastradh#include "config.h" 2703b705cfSriastradh#endif 2803b705cfSriastradh 2942542f5fSchristos#include "xorg-server.h" 3003b705cfSriastradh#include "xf86.h" 3103b705cfSriastradh#include "xf86_OSproc.h" 3203b705cfSriastradh#include "xf86Pci.h" 3303b705cfSriastradh#include "i810.h" 3403b705cfSriastradh#include "i810_reg.h" 3503b705cfSriastradh#include "dgaproc.h" 3603b705cfSriastradh#include "vgaHW.h" 3703b705cfSriastradh 3803b705cfSriastradhstatic Bool I810_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 3903b705cfSriastradh int *, int *, int *); 4003b705cfSriastradhstatic Bool I810_SetMode(ScrnInfoPtr, DGAModePtr); 4103b705cfSriastradhstatic int I810_GetViewport(ScrnInfoPtr); 4203b705cfSriastradhstatic void I810_SetViewport(ScrnInfoPtr, int, int, int); 4303b705cfSriastradh 4403b705cfSriastradh#ifdef HAVE_XAA_H 4503b705cfSriastradhstatic void I810_Sync(ScrnInfoPtr); 4603b705cfSriastradhstatic void I810_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 4703b705cfSriastradhstatic void I810_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 4803b705cfSriastradh#endif 4903b705cfSriastradh 5003b705cfSriastradh#if 0 5103b705cfSriastradhstatic void I810_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 5203b705cfSriastradh unsigned long); 5303b705cfSriastradh#endif 5403b705cfSriastradh 5503b705cfSriastradhstatic 5603b705cfSriastradhDGAFunctionRec I810DGAFuncs = { 5703b705cfSriastradh I810_OpenFramebuffer, 5803b705cfSriastradh NULL, 5903b705cfSriastradh I810_SetMode, 6003b705cfSriastradh I810_SetViewport, 6103b705cfSriastradh I810_GetViewport, 6203b705cfSriastradh#ifdef HAVE_XAA_H 6303b705cfSriastradh I810_Sync, 6403b705cfSriastradh I810_FillRect, 6503b705cfSriastradh I810_BlitRect, 6603b705cfSriastradh#else 6703b705cfSriastradh NULL, 6803b705cfSriastradh NULL, 6903b705cfSriastradh NULL, 7003b705cfSriastradh#endif 7103b705cfSriastradh#if 0 7203b705cfSriastradh I810_BlitTransRect 7303b705cfSriastradh#else 7403b705cfSriastradh NULL 7503b705cfSriastradh#endif 7603b705cfSriastradh}; 7703b705cfSriastradh 7803b705cfSriastradhBool 7903b705cfSriastradhI810DGAInit(ScreenPtr pScreen) 8003b705cfSriastradh{ 8103b705cfSriastradh ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 8203b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 8303b705cfSriastradh DGAModePtr modes = NULL, newmodes = NULL, currentMode; 8403b705cfSriastradh DisplayModePtr pMode, firstMode; 8503b705cfSriastradh int Bpp = pScrn->bitsPerPixel >> 3; 8603b705cfSriastradh int num = 0; 8703b705cfSriastradh 8803b705cfSriastradh pMode = firstMode = pScrn->modes; 8903b705cfSriastradh 9003b705cfSriastradh while (pMode) { 9103b705cfSriastradh 9203b705cfSriastradh newmodes = realloc(modes, (num + 1) * sizeof(DGAModeRec)); 9303b705cfSriastradh 9403b705cfSriastradh if (!newmodes) { 9503b705cfSriastradh free(modes); 9603b705cfSriastradh return FALSE; 9703b705cfSriastradh } 9803b705cfSriastradh modes = newmodes; 9903b705cfSriastradh 10003b705cfSriastradh currentMode = modes + num; 10103b705cfSriastradh num++; 10203b705cfSriastradh 10303b705cfSriastradh currentMode->mode = pMode; 10403b705cfSriastradh currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 10503b705cfSriastradh if (!pI810->noAccel) 10603b705cfSriastradh currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 10703b705cfSriastradh if (pMode->Flags & V_DBLSCAN) 10803b705cfSriastradh currentMode->flags |= DGA_DOUBLESCAN; 10903b705cfSriastradh if (pMode->Flags & V_INTERLACE) 11003b705cfSriastradh currentMode->flags |= DGA_INTERLACED; 11103b705cfSriastradh currentMode->byteOrder = pScrn->imageByteOrder; 11203b705cfSriastradh currentMode->depth = pScrn->depth; 11303b705cfSriastradh currentMode->bitsPerPixel = pScrn->bitsPerPixel; 11403b705cfSriastradh currentMode->red_mask = pScrn->mask.red; 11503b705cfSriastradh currentMode->green_mask = pScrn->mask.green; 11603b705cfSriastradh currentMode->blue_mask = pScrn->mask.blue; 11703b705cfSriastradh currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 11803b705cfSriastradh currentMode->viewportWidth = pMode->HDisplay; 11903b705cfSriastradh currentMode->viewportHeight = pMode->VDisplay; 12003b705cfSriastradh currentMode->xViewportStep = (Bpp == 3) ? 2 : 1; 12103b705cfSriastradh currentMode->yViewportStep = 1; 12203b705cfSriastradh currentMode->viewportFlags = DGA_FLIP_RETRACE; 12303b705cfSriastradh currentMode->offset = 0; 12403b705cfSriastradh currentMode->address = pI810->FbBase; 12503b705cfSriastradh 12603b705cfSriastradh currentMode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L; 12703b705cfSriastradh currentMode->imageWidth = pI810->FbMemBox.x2; 12803b705cfSriastradh currentMode->imageHeight = pI810->FbMemBox.y2; 12903b705cfSriastradh currentMode->pixmapWidth = currentMode->imageWidth; 13003b705cfSriastradh currentMode->pixmapHeight = currentMode->imageHeight; 13103b705cfSriastradh currentMode->maxViewportX = currentMode->imageWidth - 13203b705cfSriastradh currentMode->viewportWidth; 13303b705cfSriastradh /* this might need to get clamped to some maximum */ 13403b705cfSriastradh currentMode->maxViewportY = currentMode->imageHeight - 13503b705cfSriastradh currentMode->viewportHeight; 13603b705cfSriastradh 13703b705cfSriastradh pMode = pMode->next; 13803b705cfSriastradh if (pMode == firstMode) 13903b705cfSriastradh break; 14003b705cfSriastradh } 14103b705cfSriastradh 14203b705cfSriastradh pI810->numDGAModes = num; 14303b705cfSriastradh pI810->DGAModes = modes; 14403b705cfSriastradh 14503b705cfSriastradh return DGAInit(pScreen, &I810DGAFuncs, modes, num); 14603b705cfSriastradh} 14703b705cfSriastradh 14803b705cfSriastradhstatic DisplayModePtr I810SavedDGAModes[MAXSCREENS]; 14903b705cfSriastradh 15003b705cfSriastradhstatic Bool 15103b705cfSriastradhI810_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) 15203b705cfSriastradh{ 15303b705cfSriastradh int index = pScrn->pScreen->myNum; 15403b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 15503b705cfSriastradh 15603b705cfSriastradh if (!pMode) { /* restore the original mode */ 15703b705cfSriastradh if (pI810->DGAactive) { 15803b705cfSriastradh pScrn->currentMode = I810SavedDGAModes[index]; 15903b705cfSriastradh pScrn->SwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode)); 16003b705cfSriastradh pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, 0, 0)); 16103b705cfSriastradh pI810->DGAactive = FALSE; 16203b705cfSriastradh } 16303b705cfSriastradh } else { 16403b705cfSriastradh if (!pI810->DGAactive) { 16503b705cfSriastradh I810SavedDGAModes[index] = pScrn->currentMode; 16603b705cfSriastradh pI810->DGAactive = TRUE; 16703b705cfSriastradh } 16803b705cfSriastradh pScrn->SwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode)); 16903b705cfSriastradh } 17003b705cfSriastradh 17103b705cfSriastradh return TRUE; 17203b705cfSriastradh} 17303b705cfSriastradh 17403b705cfSriastradhstatic int 17503b705cfSriastradhI810_GetViewport(ScrnInfoPtr pScrn) 17603b705cfSriastradh{ 17703b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 17803b705cfSriastradh 17903b705cfSriastradh return pI810->DGAViewportStatus; 18003b705cfSriastradh} 18103b705cfSriastradh 18203b705cfSriastradhstatic void 18303b705cfSriastradhI810_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) 18403b705cfSriastradh{ 18503b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 18603b705cfSriastradh vgaHWPtr hwp = VGAHWPTR(pScrn); 18703b705cfSriastradh 18803b705cfSriastradh pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); 18903b705cfSriastradh 19003b705cfSriastradh /* wait for retrace */ 19103b705cfSriastradh while ((hwp->readST01(hwp) & 0x08)) ; 19203b705cfSriastradh while (!(hwp->readST01(hwp) & 0x08)) ; 19303b705cfSriastradh 19403b705cfSriastradh pI810->DGAViewportStatus = 0; 19503b705cfSriastradh} 19603b705cfSriastradh 19703b705cfSriastradh#ifdef HAVE_XAA_H 19803b705cfSriastradhstatic void 19903b705cfSriastradhI810_FillRect(ScrnInfoPtr pScrn, 20003b705cfSriastradh int x, int y, int w, int h, unsigned long color) 20103b705cfSriastradh{ 20203b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 20303b705cfSriastradh 20403b705cfSriastradh if (pI810->AccelInfoRec) { 20503b705cfSriastradh (*pI810->AccelInfoRec->SetupForSolidFill) (pScrn, color, GXcopy, ~0); 20603b705cfSriastradh (*pI810->AccelInfoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h); 20703b705cfSriastradh SET_SYNC_FLAG(pI810->AccelInfoRec); 20803b705cfSriastradh } 20903b705cfSriastradh} 21003b705cfSriastradh 21103b705cfSriastradhstatic void 21203b705cfSriastradhI810_Sync(ScrnInfoPtr pScrn) 21303b705cfSriastradh{ 21403b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 21503b705cfSriastradh 21603b705cfSriastradh if (pI810->AccelInfoRec) { 21703b705cfSriastradh (*pI810->AccelInfoRec->Sync) (pScrn); 21803b705cfSriastradh } 21903b705cfSriastradh} 22003b705cfSriastradh 22103b705cfSriastradhstatic void 22203b705cfSriastradhI810_BlitRect(ScrnInfoPtr pScrn, 22303b705cfSriastradh int srcx, int srcy, int w, int h, int dstx, int dsty) 22403b705cfSriastradh{ 22503b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 22603b705cfSriastradh 22703b705cfSriastradh if (pI810->AccelInfoRec) { 22803b705cfSriastradh int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 22903b705cfSriastradh int ydir = (srcy < dsty) ? -1 : 1; 23003b705cfSriastradh 23103b705cfSriastradh (*pI810->AccelInfoRec->SetupForScreenToScreenCopy) (pScrn, xdir, ydir, 23203b705cfSriastradh GXcopy, ~0, -1); 23303b705cfSriastradh (*pI810->AccelInfoRec->SubsequentScreenToScreenCopy) (pScrn, srcx, srcy, 23403b705cfSriastradh dstx, dsty, w, h); 23503b705cfSriastradh SET_SYNC_FLAG(pI810->AccelInfoRec); 23603b705cfSriastradh } 23703b705cfSriastradh} 23803b705cfSriastradh#endif 23903b705cfSriastradh 24003b705cfSriastradh#if 0 24103b705cfSriastradhstatic void 24203b705cfSriastradhI810_BlitTransRect(ScrnInfoPtr pScrn, 24303b705cfSriastradh int srcx, int srcy, 24403b705cfSriastradh int w, int h, int dstx, int dsty, unsigned long color) 24503b705cfSriastradh{ 24603b705cfSriastradh 24703b705cfSriastradh /* this one should be separate since the XAA function would 24803b705cfSriastradh * prohibit usage of ~0 as the key */ 24903b705cfSriastradh} 25003b705cfSriastradh#endif 25103b705cfSriastradh 25203b705cfSriastradhstatic Bool 25303b705cfSriastradhI810_OpenFramebuffer(ScrnInfoPtr pScrn, 25403b705cfSriastradh char **name, 25503b705cfSriastradh unsigned char **mem, int *size, int *offset, int *flags) 25603b705cfSriastradh{ 25703b705cfSriastradh I810Ptr pI810 = I810PTR(pScrn); 25803b705cfSriastradh 25903b705cfSriastradh *name = NULL; /* no special device */ 26003b705cfSriastradh *mem = (unsigned char *)pI810->LinearAddr; 26103b705cfSriastradh *size = pI810->FbMapSize; 26203b705cfSriastradh *offset = 0; 26303b705cfSriastradh *flags = DGA_NEED_ROOT; 26403b705cfSriastradh 26503b705cfSriastradh return TRUE; 26603b705cfSriastradh} 267