neo_2070.c revision c3c9db83
1692f60a7Smrg/********************************************************************** 2692f60a7SmrgCopyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas. 3692f60a7Smrg 4692f60a7Smrg All Rights Reserved 5692f60a7Smrg 6692f60a7SmrgPermission to use, copy, modify, distribute, and sell this software and 7692f60a7Smrgits documentation for any purpose is hereby granted without fee, 8692f60a7Smrgprovided that the above copyright notice appear in all copies and that 9692f60a7Smrgboth that copyright notice and this permission notice appear in 10692f60a7Smrgsupporting documentation, and that the name of Precision Insight not be 11692f60a7Smrgused in advertising or publicity pertaining to distribution of the 12692f60a7Smrgsoftware without specific, written prior permission. Precision Insight 13692f60a7Smrgand its suppliers make no representations about the suitability of this 14692f60a7Smrgsoftware for any purpose. It is provided "as is" without express or 15692f60a7Smrgimplied warranty. 16692f60a7Smrg 17692f60a7SmrgPRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18692f60a7SmrgINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19692f60a7SmrgEVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY 20692f60a7SmrgSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 21692f60a7SmrgRESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 22692f60a7SmrgCONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 23692f60a7SmrgCONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 24692f60a7Smrg**********************************************************************/ 25692f60a7Smrg 26692f60a7Smrg/* 27692f60a7Smrg * The original Precision Insight driver for 28692f60a7Smrg * XFree86 v.3.3 has been sponsored by Red Hat. 29692f60a7Smrg * 30692f60a7Smrg * Authors: 31692f60a7Smrg * Jens Owen (jens@tungstengraphics.com) 32692f60a7Smrg * Kevin E. Martin (kevin@precisioninsight.com) 33692f60a7Smrg * 34692f60a7Smrg * Port to Xfree86 v.4.0 35692f60a7Smrg * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE) 36692f60a7Smrg */ 37692f60a7Smrg 38692f60a7Smrg#ifdef HAVE_CONFIG_H 39692f60a7Smrg#include "config.h" 40692f60a7Smrg#endif 41692f60a7Smrg 42692f60a7Smrg#include "xf86.h" 43692f60a7Smrg#include "xf86_OSproc.h" 44692f60a7Smrg#include "compiler.h" 45692f60a7Smrg 46692f60a7Smrg/* Drivers that use XAA need this */ 47692f60a7Smrg#include "xf86fbman.h" 48692f60a7Smrg 49692f60a7Smrg#include "miline.h" 50692f60a7Smrg 51692f60a7Smrg#include "neo.h" 52692f60a7Smrg#include "neo_reg.h" 53692f60a7Smrg#include "neo_macros.h" 54692f60a7Smrg 55692f60a7Smrg/* Memory Mapped I/O for BitBlt */ 56692f60a7Smrg#define NEO2070_BLTSTAT 0x00 57692f60a7Smrg#define NEO2070_BLTCNTL 0x04 58692f60a7Smrg#define NEO2070_XPCOLOR 0x08 59692f60a7Smrg#define NEO2070_FGCOLOR 0x0c 60692f60a7Smrg#define NEO2070_BGCOLOR 0x10 61692f60a7Smrg#define NEO2070_PLANEMASK 0x14 62692f60a7Smrg#define NEO2070_XYEXT 0x18 63692f60a7Smrg#define NEO2070_SRCPITCH 0x1c 64692f60a7Smrg#define NEO2070_SRCBITOFF 0x20 65692f60a7Smrg#define NEO2070_SRCSTART 0x24 66692f60a7Smrg#define NEO2070_DSTPITCH 0x28 67692f60a7Smrg#define NEO2070_DSTBITOFF 0x2c 68692f60a7Smrg#define NEO2070_DSTSTART 0x30 69692f60a7Smrg 70692f60a7Smrgstatic unsigned int neo2070Rop[16] = { 71692f60a7Smrg 0x000000, /* 0x0000 - GXclear */ 72692f60a7Smrg 0x080000, /* 0x1000 - GXand */ 73692f60a7Smrg 0x040000, /* 0x0100 - GXandReverse */ 74692f60a7Smrg 0x0c0000, /* 0x1100 - GXcopy */ 75692f60a7Smrg 0x020000, /* 0x0010 - GXandInvert */ 76692f60a7Smrg 0x0a0000, /* 0x1010 - GXnoop */ 77692f60a7Smrg 0x060000, /* 0x0110 - GXxor */ 78692f60a7Smrg 0x0e0000, /* 0x1110 - GXor */ 79692f60a7Smrg 0x010000, /* 0x0001 - GXnor */ 80692f60a7Smrg 0x090000, /* 0x1001 - GXequiv */ 81692f60a7Smrg 0x050000, /* 0x0101 - GXinvert */ 82692f60a7Smrg 0x0d0000, /* 0x1101 - GXorReverse */ 83692f60a7Smrg 0x030000, /* 0x0011 - GXcopyInvert */ 84692f60a7Smrg 0x0b0000, /* 0x1011 - GXorInverted */ 85692f60a7Smrg 0x070000, /* 0x0111 - GXnand */ 86692f60a7Smrg 0x0f0000 /* 0x1111 - GXset */ 87692f60a7Smrg}; 88692f60a7Smrg 89692f60a7Smrgstatic void Neo2070Sync(ScrnInfoPtr pScrn); 90692f60a7Smrgstatic void Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, 91692f60a7Smrg int ydir, int rop, 92692f60a7Smrg unsigned int planemask, 93692f60a7Smrg int trans_color); 94692f60a7Smrgstatic void Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX, 95692f60a7Smrg int srcY, int dstX, int dstY, 96692f60a7Smrg int w, int h); 97692f60a7Smrgstatic void Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, 98692f60a7Smrg unsigned int planemask); 99692f60a7Smrgstatic void Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, 100692f60a7Smrg int w, int h); 101692f60a7Smrg 102692f60a7SmrgBool 103692f60a7SmrgNeo2070AccelInit(ScreenPtr pScreen) 104692f60a7Smrg{ 105692f60a7Smrg XAAInfoRecPtr infoPtr; 106692f60a7Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 107692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 108692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 109692f60a7Smrg 110692f60a7Smrg nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); 111692f60a7Smrg if(!infoPtr) return FALSE; 112692f60a7Smrg 113692f60a7Smrg /* 114692f60a7Smrg * Set up the main acceleration flags. 115692f60a7Smrg */ 116692f60a7Smrg infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; 117692f60a7Smrg if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE; 118692f60a7Smrg#if 0 119692f60a7Smrg infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES; 120692f60a7Smrg#endif 121692f60a7Smrg /* sync */ 122692f60a7Smrg infoPtr->Sync = Neo2070Sync; 123692f60a7Smrg 124692f60a7Smrg /* screen to screen copy */ 125692f60a7Smrg infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | GXCOPY_ONLY); 126692f60a7Smrg infoPtr->SetupForScreenToScreenCopy = 127692f60a7Smrg Neo2070SetupForScreenToScreenCopy; 128692f60a7Smrg infoPtr->SubsequentScreenToScreenCopy = 129692f60a7Smrg Neo2070SubsequentScreenToScreenCopy; 130692f60a7Smrg 131692f60a7Smrg /* solid filled rectangles */ 132692f60a7Smrg infoPtr->SolidFillFlags = GXCOPY_ONLY; 133692f60a7Smrg infoPtr->SetupForSolidFill = 134692f60a7Smrg Neo2070SetupForSolidFillRect; 135692f60a7Smrg infoPtr->SubsequentSolidFillRect = 136692f60a7Smrg Neo2070SubsequentSolidFillRect; 137692f60a7Smrg 138692f60a7Smrg /* 139692f60a7Smrg * Setup some global variables 140692f60a7Smrg */ 141692f60a7Smrg 142692f60a7Smrg /* Initialize for 8bpp or 15/16bpp support accellerated */ 143692f60a7Smrg switch (pScrn->bitsPerPixel) { 144692f60a7Smrg case 8: 145692f60a7Smrg nAcl->BltCntlFlags = NEO_BC1_DEPTH8; 146692f60a7Smrg nAcl->ColorShiftAmt = 8; 147692f60a7Smrg nAcl->PixelWidth = 1; 148692f60a7Smrg nAcl->PlaneMask = 0xff; 149692f60a7Smrg break; 150692f60a7Smrg case 15: 151692f60a7Smrg case 16: 152692f60a7Smrg nAcl->BltCntlFlags = NEO_BC1_DEPTH16; 153692f60a7Smrg nAcl->ColorShiftAmt = 0; 154692f60a7Smrg nAcl->PixelWidth = 2; 155692f60a7Smrg nAcl->PlaneMask = 0xffff; 156692f60a7Smrg break; 157692f60a7Smrg case 24: /* not supported, but check anyway */ 158692f60a7Smrg default: 159692f60a7Smrg return FALSE; 160692f60a7Smrg } 161692f60a7Smrg 162c3c9db83Smrg return(XAAInit(pScreen, infoPtr)); 163692f60a7Smrg 164692f60a7Smrg} 165692f60a7Smrg 166692f60a7Smrgstatic void 167692f60a7SmrgNeo2070Sync(ScrnInfoPtr pScrn) 168692f60a7Smrg{ 169692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 170692f60a7Smrg WAIT_ENGINE_IDLE(); 171692f60a7Smrg} 172692f60a7Smrg 173692f60a7Smrgstatic void 174692f60a7SmrgNeo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 175692f60a7Smrg int rop, 176692f60a7Smrg unsigned int planemask, 177692f60a7Smrg int trans_color) 178692f60a7Smrg{ 179692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 180692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 181692f60a7Smrg 182692f60a7Smrg /* set blt control */ 183692f60a7Smrg WAIT_ENGINE_IDLE(); 184692f60a7Smrg OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags); 185692f60a7Smrg OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt)); 186692f60a7Smrg OUTREG(NEO2070_SRCPITCH, nAcl->Pitch); 187692f60a7Smrg OUTREG(NEO2070_DSTPITCH, nAcl->Pitch); 188692f60a7Smrg OUTREG(NEO2070_SRCBITOFF, 0); 189692f60a7Smrg OUTREG(NEO2070_DSTBITOFF, 0); 190692f60a7Smrg} 191692f60a7Smrg 192692f60a7Smrgstatic void 193692f60a7SmrgNeo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 194692f60a7Smrg int srcX, int srcY, 195692f60a7Smrg int dstX, int dstY, 196692f60a7Smrg int w, int h) 197692f60a7Smrg{ 198692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 199692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 200692f60a7Smrg 201692f60a7Smrg if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) { 202692f60a7Smrg /* start with upper left corner */ 203692f60a7Smrg WAIT_ENGINE_IDLE(); 204692f60a7Smrg OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags); 205692f60a7Smrg OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff)); 206692f60a7Smrg OUTREG(NEO2070_SRCSTART, 207692f60a7Smrg (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth)); 208692f60a7Smrg OUTREG(NEO2070_DSTSTART, 209692f60a7Smrg (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth)); 210692f60a7Smrg } 211692f60a7Smrg else { 212692f60a7Smrg /* start with lower right corner */ 213692f60a7Smrg WAIT_ENGINE_IDLE(); 214692f60a7Smrg OUTREG(NEO2070_BLTCNTL, (nAcl->tmpBltCntlFlags | NEO_BC0_X_DEC 215692f60a7Smrg | NEO_BC0_DST_Y_DEC 216692f60a7Smrg | NEO_BC0_SRC_Y_DEC)); 217692f60a7Smrg OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff)); 218692f60a7Smrg OUTREG(NEO2070_SRCSTART, 219692f60a7Smrg ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1) * nAcl->PixelWidth)); 220692f60a7Smrg OUTREG(NEO2070_DSTSTART, 221692f60a7Smrg ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1) * nAcl->PixelWidth)); 222692f60a7Smrg } 223692f60a7Smrg} 224692f60a7Smrg 225692f60a7Smrg 226692f60a7Smrgstatic void 227692f60a7SmrgNeo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, 228692f60a7Smrg unsigned int planemask) 229692f60a7Smrg{ 230692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 231692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 232692f60a7Smrg 233692f60a7Smrg planemask &= nAcl->PlaneMask; 234692f60a7Smrg if (!rop) color=0; 235692f60a7Smrg 236692f60a7Smrg WAIT_ENGINE_IDLE(); 237692f60a7Smrg 238692f60a7Smrg OUTREG(NEO2070_BLTCNTL, nAcl->BltCntlFlags | 239692f60a7Smrg NEO_BC0_SRC_IS_FG | neo2070Rop[3]); 240692f60a7Smrg OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt)); 241692f60a7Smrg if (pScrn->bitsPerPixel == 8) 242692f60a7Smrg OUTREG(NEO2070_FGCOLOR, color |= (color << 8)); 243692f60a7Smrg else 244692f60a7Smrg /* swap bytes in color */ 245692f60a7Smrg OUTREG(NEO2070_FGCOLOR, ((color&0xff00) >> 8) | (color << 8)); 246692f60a7Smrg OUTREG(NEO2070_SRCPITCH, nAcl->Pitch); 247692f60a7Smrg OUTREG(NEO2070_DSTPITCH, nAcl->Pitch); 248692f60a7Smrg OUTREG(NEO2070_SRCBITOFF, 0); 249692f60a7Smrg OUTREG(NEO2070_DSTBITOFF, 0); 250692f60a7Smrg} 251692f60a7Smrg 252692f60a7Smrg 253692f60a7Smrgstatic void 254692f60a7SmrgNeo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 255692f60a7Smrg{ 256692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 257692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 258692f60a7Smrg 259692f60a7Smrg WAIT_ENGINE_IDLE(); 260692f60a7Smrg OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff)); 261692f60a7Smrg OUTREG(NEO2070_DSTSTART, (y * nAcl->Pitch) + (x * nAcl->PixelWidth)); 262692f60a7Smrg} 263692f60a7Smrg 264692f60a7Smrg 265692f60a7Smrg 266692f60a7Smrg 267692f60a7Smrg 268