1d87a3195Smrg/* 2d87a3195Smrg * Copyright 2006 by Alan Hourihane, North Wales, UK. 3d87a3195Smrg * 4d87a3195Smrg * Permission to use, copy, modify, distribute, and sell this software and its 5d87a3195Smrg * documentation for any purpose is hereby granted without fee, provided that 6d87a3195Smrg * the above copyright notice appear in all copies and that both that 7d87a3195Smrg * copyright notice and this permission notice appear in supporting 8d87a3195Smrg * documentation, and that the name of the authors not be used in 9d87a3195Smrg * advertising or publicity pertaining to distribution of the software without 10d87a3195Smrg * specific, written prior permission. The authors make no representations 11d87a3195Smrg * about the suitability of this software for any purpose. It is provided 12d87a3195Smrg * "as is" without express or implied warranty. 13d87a3195Smrg * 14d87a3195Smrg * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15d87a3195Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16d87a3195Smrg * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17d87a3195Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18d87a3195Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19d87a3195Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20d87a3195Smrg * PERFORMANCE OF THIS SOFTWARE. 21d87a3195Smrg * 22d87a3195Smrg * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> 23d87a3195Smrg * 24d87a3195Smrg * Trident XP4/XP5 accelerated options. 25d87a3195Smrg */ 26d87a3195Smrg 27d87a3195Smrg#ifdef HAVE_CONFIG_H 28d87a3195Smrg#include "config.h" 29d87a3195Smrg#endif 30d87a3195Smrg 31d87a3195Smrg#include "exa.h" 32d87a3195Smrg#include "picture.h" 33d87a3195Smrg 34d87a3195Smrg#include "xf86.h" 35d87a3195Smrg#include "xf86_OSproc.h" 36d87a3195Smrg#include "xf86Pci.h" 37d87a3195Smrg#include "xaarop.h" 38d87a3195Smrg 39d87a3195Smrg#include "trident.h" 40d87a3195Smrg#include "trident_regs.h" 41d87a3195Smrg 42d87a3195Smrgstatic int ropcode; 43d87a3195Smrg 44d87a3195Smrgstatic int CopyROP[16] = 45d87a3195Smrg{ 46d87a3195Smrg ROP_0, /* GXclear */ 47d87a3195Smrg ROP_DSa, /* GXand */ 48d87a3195Smrg ROP_SDna, /* GXandReverse */ 49d87a3195Smrg ROP_S, /* GXcopy */ 50d87a3195Smrg ROP_DSna, /* GXandInverted */ 51d87a3195Smrg ROP_D, /* GXnoop */ 52d87a3195Smrg ROP_DSx, /* GXxor */ 53d87a3195Smrg ROP_DSo, /* GXor */ 54d87a3195Smrg ROP_DSon, /* GXnor */ 55d87a3195Smrg ROP_DSxn, /* GXequiv */ 56d87a3195Smrg ROP_Dn, /* GXinvert*/ 57d87a3195Smrg ROP_SDno, /* GXorReverse */ 58d87a3195Smrg ROP_Sn, /* GXcopyInverted */ 59d87a3195Smrg ROP_DSno, /* GXorInverted */ 60d87a3195Smrg ROP_DSan, /* GXnand */ 61d87a3195Smrg ROP_1 /* GXset */ 62d87a3195Smrg}; 63d87a3195Smrg 64d87a3195Smrgstatic int PatternROP[16]= 65d87a3195Smrg{ 66d87a3195Smrg ROP_0, 67d87a3195Smrg ROP_DPa, 68d87a3195Smrg ROP_PDna, 69d87a3195Smrg ROP_P, 70d87a3195Smrg ROP_DPna, 71d87a3195Smrg ROP_D, 72d87a3195Smrg ROP_DPx, 73d87a3195Smrg ROP_DPo, 74d87a3195Smrg ROP_DPon, 75d87a3195Smrg ROP_PDxn, 76d87a3195Smrg ROP_Dn, 77d87a3195Smrg ROP_PDno, 78d87a3195Smrg ROP_Pn, 79d87a3195Smrg ROP_DPno, 80d87a3195Smrg ROP_DPan, 81d87a3195Smrg ROP_1 82d87a3195Smrg}; 83d87a3195Smrg 84d87a3195Smrgstatic int 85d87a3195SmrgGetCopyROP(int i) 86d87a3195Smrg{ 87d87a3195Smrg return CopyROP[i]; 88d87a3195Smrg} 89d87a3195Smrg 90d87a3195Smrgstatic int 91d87a3195SmrgGetPatternROP(int i) 92d87a3195Smrg{ 93d87a3195Smrg return PatternROP[i]; 94d87a3195Smrg} 95d87a3195Smrg 96d87a3195Smrgstatic void 97d87a3195SmrgXP4WaitMarker(ScreenPtr pScreen, int Marker) 98d87a3195Smrg{ 99d87a3195Smrg /* Don't need a wait marker as we need to sync on all operations */ 100d87a3195Smrg} 101d87a3195Smrg 102d87a3195Smrgstatic void 103d87a3195SmrgXP4Done(PixmapPtr p) 104d87a3195Smrg{ 105d87a3195Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(p->drawable.pScreen); 106d87a3195Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 107d87a3195Smrg int count = 0, timeout = 0; 108d87a3195Smrg int busy; 109d87a3195Smrg 110d87a3195Smrg for (;;) { 111d87a3195Smrg BLTBUSY(busy); 112d87a3195Smrg if (busy != GE_BUSY) { 113d87a3195Smrg return; 114d87a3195Smrg } 115d87a3195Smrg 116d87a3195Smrg count++; 117d87a3195Smrg if (count == 10000000) { 118d87a3195Smrg ErrorF("XP: BitBLT engine time-out.\n"); 119d87a3195Smrg count = 9990000; 120d87a3195Smrg timeout++; 121d87a3195Smrg if (timeout == 4) { 122d87a3195Smrg /* Reset BitBLT Engine */ 123d87a3195Smrg TGUI_STATUS(0x00); 124d87a3195Smrg return; 125d87a3195Smrg } 126d87a3195Smrg } 127d87a3195Smrg } 128d87a3195Smrg} 129d87a3195Smrg 130d87a3195Smrgstatic Bool 131d87a3195SmrgXP4PrepareSolid(PixmapPtr pPixmap, 132d87a3195Smrg int alu, Pixel planemask, Pixel fg) 133d87a3195Smrg{ 134d87a3195Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 135d87a3195Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 136d87a3195Smrg unsigned int dorg = exaGetPixmapOffset(pPixmap); 137d87a3195Smrg unsigned int dptch = exaGetPixmapPitch(pPixmap); 138d87a3195Smrg 139d87a3195Smrg if (planemask != -1) 140d87a3195Smrg return FALSE; 141d87a3195Smrg 142d87a3195Smrg ropcode = alu; 143d87a3195Smrg 144d87a3195Smrg MMIO_OUT32(pTrident->IOBase, 0x2150, (dptch << 18) | (dorg >> 4)); 145d87a3195Smrg 146d87a3195Smrg REPLICATE(fg); 147d87a3195Smrg MMIO_OUT32(pTrident->IOBase, 0x2158, fg); 148d87a3195Smrg MMIO_OUT32(pTrident->IOBase, 0x2128, 1 << 14); 149d87a3195Smrg 150d87a3195Smrg return TRUE; 151d87a3195Smrg} 152d87a3195Smrg 153d87a3195Smrgstatic void 154d87a3195SmrgXP4Solid(PixmapPtr pPixmap, 155d87a3195Smrg int x1, int y1, 156d87a3195Smrg int x2, int y2) 157d87a3195Smrg{ 158d87a3195Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 159d87a3195Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 160d87a3195Smrg int bpp; 161d87a3195Smrg 162d87a3195Smrg switch (pPixmap->drawable.bitsPerPixel) { 163d87a3195Smrg case 8: 164d87a3195Smrg bpp = 0x40; 165d87a3195Smrg break; 166d87a3195Smrg case 16: 167d87a3195Smrg bpp = 0x41; 168d87a3195Smrg break; 169d87a3195Smrg case 32: 170d87a3195Smrg bpp = 0x42; 171d87a3195Smrg break; 172d87a3195Smrg } 173d87a3195Smrg 174d87a3195Smrg MMIO_OUT32(pTrident->IOBase, 0x2138, (x1 << 16) | y1); 175d87a3195Smrg MMIO_OUT32(pTrident->IOBase, 0x2140, ((x2 - x1) << 16) | 176d87a3195Smrg (y2 - y1)); 177d87a3195Smrg MMIO_OUT32(pTrident->IOBase, 0x2124, 178d87a3195Smrg (GetPatternROP(ropcode) << 24) | 179d87a3195Smrg (bpp << 8) | 180d87a3195Smrg 2); 181d87a3195Smrg} 182d87a3195Smrg 183d87a3195Smrgstatic Bool 184d87a3195SmrgXP4PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, 185d87a3195Smrg int dx, int dy, 186d87a3195Smrg int alu, Pixel planemask) 187d87a3195Smrg{ 188d87a3195Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 189d87a3195Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 190d87a3195Smrg unsigned int sorg = exaGetPixmapOffset(pSrcPixmap); 191d87a3195Smrg unsigned int dorg = exaGetPixmapOffset(pDstPixmap); 192d87a3195Smrg unsigned int sptch = exaGetPixmapPitch(pSrcPixmap); 193d87a3195Smrg unsigned int dptch = exaGetPixmapPitch(pDstPixmap); 194d87a3195Smrg 195d87a3195Smrg if (planemask != -1) 196d87a3195Smrg return FALSE; 197d87a3195Smrg 198d87a3195Smrg pTrident->BltScanDirection = 0; 199d87a3195Smrg if (dx < 0) 200d87a3195Smrg pTrident->BltScanDirection |= XNEG; 201d87a3195Smrg if (dy < 0) 202d87a3195Smrg pTrident->BltScanDirection |= YNEG; 203d87a3195Smrg 204d87a3195Smrg ropcode = alu; 205d87a3195Smrg 206d87a3195Smrg MMIO_OUT32(pTrident->IOBase, 0x2154, (sptch << 18) | (sorg >> 4)); 207d87a3195Smrg MMIO_OUT32(pTrident->IOBase, 0x2150, (dptch << 18) | (dorg >> 4)); 208d87a3195Smrg 209d87a3195Smrg return TRUE; 210d87a3195Smrg} 211d87a3195Smrg 212d87a3195Smrgstatic void 213d87a3195SmrgXP4Copy(PixmapPtr pDstPixmap, 214d87a3195Smrg int x1, int y1, 215d87a3195Smrg int x2, int y2, 216d87a3195Smrg int w, int h) 217d87a3195Smrg{ 218d87a3195Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 219d87a3195Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 220d87a3195Smrg int bpp; 221d87a3195Smrg 222d87a3195Smrg switch (pDstPixmap->drawable.bitsPerPixel) { 223d87a3195Smrg case 8: 224d87a3195Smrg bpp = 0x40; 225d87a3195Smrg break; 226d87a3195Smrg case 16: 227d87a3195Smrg bpp = 0x41; 228d87a3195Smrg break; 229d87a3195Smrg case 32: 230d87a3195Smrg bpp = 0x42; 231d87a3195Smrg break; 232d87a3195Smrg } 233d87a3195Smrg 234d87a3195Smrg if (pTrident->BltScanDirection & YNEG) { 235d87a3195Smrg y1 = y1 + h - 1; 236d87a3195Smrg y2 = y2 + h - 1; 237d87a3195Smrg } 238d87a3195Smrg if (pTrident->BltScanDirection & XNEG) { 239d87a3195Smrg x1 = x1 + w - 1; 240d87a3195Smrg x2 = x2 + w - 1; 241d87a3195Smrg } 242d87a3195Smrg MMIO_OUT32(pTrident->IOBase, 0x2128, pTrident->BltScanDirection | 243d87a3195Smrg SCR2SCR); 244d87a3195Smrg MMIO_OUT32(pTrident->IOBase, 0x2138, (x2 << 16) | y2); 245d87a3195Smrg MMIO_OUT32(pTrident->IOBase, 0x213C, (x1 << 16) | y1); 246d87a3195Smrg MMIO_OUT32(pTrident->IOBase, 0x2140, (w << 16) | h); 247d87a3195Smrg MMIO_OUT32(pTrident->IOBase, 0x2124, (GetCopyROP(ropcode) << 24) | 248d87a3195Smrg (bpp << 8) | 249d87a3195Smrg 1); 250d87a3195Smrg} 251d87a3195Smrg 252d87a3195SmrgBool 253d87a3195SmrgXP4ExaInit(ScreenPtr pScreen) 254d87a3195Smrg{ 255d87a3195Smrg ExaDriverPtr pExa; 256d87a3195Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 257d87a3195Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 258d87a3195Smrg 259d87a3195Smrg if (pTrident->NoAccel) 260d87a3195Smrg return FALSE; 261d87a3195Smrg 262d87a3195Smrg if (!(pExa = pTrident->EXADriverPtr = exaDriverAlloc())) { 263d87a3195Smrg pTrident->NoAccel = TRUE; 264d87a3195Smrg return FALSE; 265d87a3195Smrg } 266d87a3195Smrg 267d87a3195Smrg pExa->exa_major = 2; 268d87a3195Smrg pExa->exa_minor = 0; 269d87a3195Smrg 270d87a3195Smrg pExa->flags = EXA_OFFSCREEN_PIXMAPS; 271d87a3195Smrg pExa->memoryBase = pTrident->FbBase; 272d87a3195Smrg pExa->memorySize = pTrident->FbMapSize; 273d87a3195Smrg pExa->offScreenBase = pScrn->displayWidth * pScrn->virtualY * 274d87a3195Smrg ((pScrn->bitsPerPixel + 7) / 8); 275d87a3195Smrg 276d87a3195Smrg pExa->pixmapOffsetAlign = 16; 277d87a3195Smrg pExa->pixmapPitchAlign = 16; 278d87a3195Smrg 279d87a3195Smrg pExa->maxX = 4095; 280d87a3195Smrg pExa->maxY = 4095; 281d87a3195Smrg 282d87a3195Smrg pExa->WaitMarker = XP4WaitMarker; 283d87a3195Smrg 284d87a3195Smrg pExa->PrepareSolid = XP4PrepareSolid; 285d87a3195Smrg pExa->Solid = XP4Solid; 286d87a3195Smrg pExa->DoneSolid = XP4Done; 287d87a3195Smrg 288d87a3195Smrg pExa->PrepareCopy = XP4PrepareCopy; 289d87a3195Smrg pExa->Copy = XP4Copy; 290d87a3195Smrg pExa->DoneCopy = XP4Done; 291d87a3195Smrg 292d87a3195Smrg return (exaDriverInit(pScreen, pExa)); 293d87a3195Smrg} 294