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