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 553f6d0e1dSmrg#ifdef HAVE_XAA_H 56692f60a7Smrg/* Memory Mapped I/O for BitBlt */ 57692f60a7Smrg#define NEO2070_BLTSTAT 0x00 58692f60a7Smrg#define NEO2070_BLTCNTL 0x04 59692f60a7Smrg#define NEO2070_XPCOLOR 0x08 60692f60a7Smrg#define NEO2070_FGCOLOR 0x0c 61692f60a7Smrg#define NEO2070_BGCOLOR 0x10 62692f60a7Smrg#define NEO2070_PLANEMASK 0x14 63692f60a7Smrg#define NEO2070_XYEXT 0x18 64692f60a7Smrg#define NEO2070_SRCPITCH 0x1c 65692f60a7Smrg#define NEO2070_SRCBITOFF 0x20 66692f60a7Smrg#define NEO2070_SRCSTART 0x24 67692f60a7Smrg#define NEO2070_DSTPITCH 0x28 68692f60a7Smrg#define NEO2070_DSTBITOFF 0x2c 69692f60a7Smrg#define NEO2070_DSTSTART 0x30 70692f60a7Smrg 71692f60a7Smrgstatic unsigned int neo2070Rop[16] = { 72692f60a7Smrg 0x000000, /* 0x0000 - GXclear */ 73692f60a7Smrg 0x080000, /* 0x1000 - GXand */ 74692f60a7Smrg 0x040000, /* 0x0100 - GXandReverse */ 75692f60a7Smrg 0x0c0000, /* 0x1100 - GXcopy */ 76692f60a7Smrg 0x020000, /* 0x0010 - GXandInvert */ 77692f60a7Smrg 0x0a0000, /* 0x1010 - GXnoop */ 78692f60a7Smrg 0x060000, /* 0x0110 - GXxor */ 79692f60a7Smrg 0x0e0000, /* 0x1110 - GXor */ 80692f60a7Smrg 0x010000, /* 0x0001 - GXnor */ 81692f60a7Smrg 0x090000, /* 0x1001 - GXequiv */ 82692f60a7Smrg 0x050000, /* 0x0101 - GXinvert */ 83692f60a7Smrg 0x0d0000, /* 0x1101 - GXorReverse */ 84692f60a7Smrg 0x030000, /* 0x0011 - GXcopyInvert */ 85692f60a7Smrg 0x0b0000, /* 0x1011 - GXorInverted */ 86692f60a7Smrg 0x070000, /* 0x0111 - GXnand */ 87692f60a7Smrg 0x0f0000 /* 0x1111 - GXset */ 88692f60a7Smrg}; 89692f60a7Smrg 90692f60a7Smrgstatic void Neo2070Sync(ScrnInfoPtr pScrn); 91692f60a7Smrgstatic void Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, 92692f60a7Smrg int ydir, int rop, 93692f60a7Smrg unsigned int planemask, 94692f60a7Smrg int trans_color); 95692f60a7Smrgstatic void Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX, 96692f60a7Smrg int srcY, int dstX, int dstY, 97692f60a7Smrg int w, int h); 98692f60a7Smrgstatic void Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, 99692f60a7Smrg unsigned int planemask); 100692f60a7Smrgstatic void Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, 101692f60a7Smrg int w, int h); 102692f60a7Smrg 1033f6d0e1dSmrg#endif 1043f6d0e1dSmrg 105692f60a7SmrgBool 106692f60a7SmrgNeo2070AccelInit(ScreenPtr pScreen) 107692f60a7Smrg{ 1083f6d0e1dSmrg#ifdef HAVE_XAA_H 109692f60a7Smrg XAAInfoRecPtr infoPtr; 1103f6d0e1dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 111692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 112692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 113692f60a7Smrg 114692f60a7Smrg nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); 115692f60a7Smrg if(!infoPtr) return FALSE; 116692f60a7Smrg 117692f60a7Smrg /* 118692f60a7Smrg * Set up the main acceleration flags. 119692f60a7Smrg */ 120692f60a7Smrg infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; 121692f60a7Smrg if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE; 122692f60a7Smrg#if 0 123692f60a7Smrg infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES; 124692f60a7Smrg#endif 125692f60a7Smrg /* sync */ 126692f60a7Smrg infoPtr->Sync = Neo2070Sync; 127692f60a7Smrg 128692f60a7Smrg /* screen to screen copy */ 129692f60a7Smrg infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | GXCOPY_ONLY); 130692f60a7Smrg infoPtr->SetupForScreenToScreenCopy = 131692f60a7Smrg Neo2070SetupForScreenToScreenCopy; 132692f60a7Smrg infoPtr->SubsequentScreenToScreenCopy = 133692f60a7Smrg Neo2070SubsequentScreenToScreenCopy; 134692f60a7Smrg 135692f60a7Smrg /* solid filled rectangles */ 136692f60a7Smrg infoPtr->SolidFillFlags = GXCOPY_ONLY; 137692f60a7Smrg infoPtr->SetupForSolidFill = 138692f60a7Smrg Neo2070SetupForSolidFillRect; 139692f60a7Smrg infoPtr->SubsequentSolidFillRect = 140692f60a7Smrg Neo2070SubsequentSolidFillRect; 141692f60a7Smrg 142692f60a7Smrg /* 143692f60a7Smrg * Setup some global variables 144692f60a7Smrg */ 145692f60a7Smrg 146efb46889Smrg /* Initialize for 8bpp or 15/16bpp support accelerated */ 147692f60a7Smrg switch (pScrn->bitsPerPixel) { 148692f60a7Smrg case 8: 149692f60a7Smrg nAcl->BltCntlFlags = NEO_BC1_DEPTH8; 150692f60a7Smrg nAcl->ColorShiftAmt = 8; 151692f60a7Smrg nAcl->PixelWidth = 1; 152692f60a7Smrg nAcl->PlaneMask = 0xff; 153692f60a7Smrg break; 154692f60a7Smrg case 15: 155692f60a7Smrg case 16: 156692f60a7Smrg nAcl->BltCntlFlags = NEO_BC1_DEPTH16; 157692f60a7Smrg nAcl->ColorShiftAmt = 0; 158692f60a7Smrg nAcl->PixelWidth = 2; 159692f60a7Smrg nAcl->PlaneMask = 0xffff; 160692f60a7Smrg break; 161692f60a7Smrg case 24: /* not supported, but check anyway */ 162692f60a7Smrg default: 163692f60a7Smrg return FALSE; 164692f60a7Smrg } 165692f60a7Smrg 166c3c9db83Smrg return(XAAInit(pScreen, infoPtr)); 1673f6d0e1dSmrg#else 1683f6d0e1dSmrg return FALSE; 1693f6d0e1dSmrg#endif 170692f60a7Smrg} 171692f60a7Smrg 1723f6d0e1dSmrg#ifdef HAVE_XAA_H 173692f60a7Smrgstatic void 174692f60a7SmrgNeo2070Sync(ScrnInfoPtr pScrn) 175692f60a7Smrg{ 176692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 177692f60a7Smrg WAIT_ENGINE_IDLE(); 178692f60a7Smrg} 179692f60a7Smrg 180692f60a7Smrgstatic void 181692f60a7SmrgNeo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 182692f60a7Smrg int rop, 183692f60a7Smrg unsigned int planemask, 184692f60a7Smrg int trans_color) 185692f60a7Smrg{ 186692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 187692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 188692f60a7Smrg 189692f60a7Smrg /* set blt control */ 190692f60a7Smrg WAIT_ENGINE_IDLE(); 191692f60a7Smrg OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags); 192692f60a7Smrg OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt)); 193692f60a7Smrg OUTREG(NEO2070_SRCPITCH, nAcl->Pitch); 194692f60a7Smrg OUTREG(NEO2070_DSTPITCH, nAcl->Pitch); 195692f60a7Smrg OUTREG(NEO2070_SRCBITOFF, 0); 196692f60a7Smrg OUTREG(NEO2070_DSTBITOFF, 0); 197692f60a7Smrg} 198692f60a7Smrg 199692f60a7Smrgstatic void 200692f60a7SmrgNeo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 201692f60a7Smrg int srcX, int srcY, 202692f60a7Smrg int dstX, int dstY, 203692f60a7Smrg int w, int h) 204692f60a7Smrg{ 205692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 206692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 207692f60a7Smrg 208692f60a7Smrg if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) { 209692f60a7Smrg /* start with upper left corner */ 210692f60a7Smrg WAIT_ENGINE_IDLE(); 211692f60a7Smrg OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags); 212692f60a7Smrg OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff)); 213692f60a7Smrg OUTREG(NEO2070_SRCSTART, 214692f60a7Smrg (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth)); 215692f60a7Smrg OUTREG(NEO2070_DSTSTART, 216692f60a7Smrg (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth)); 217692f60a7Smrg } 218692f60a7Smrg else { 219692f60a7Smrg /* start with lower right corner */ 220692f60a7Smrg WAIT_ENGINE_IDLE(); 221692f60a7Smrg OUTREG(NEO2070_BLTCNTL, (nAcl->tmpBltCntlFlags | NEO_BC0_X_DEC 222692f60a7Smrg | NEO_BC0_DST_Y_DEC 223692f60a7Smrg | NEO_BC0_SRC_Y_DEC)); 224692f60a7Smrg OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff)); 225692f60a7Smrg OUTREG(NEO2070_SRCSTART, 226692f60a7Smrg ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1) * nAcl->PixelWidth)); 227692f60a7Smrg OUTREG(NEO2070_DSTSTART, 228692f60a7Smrg ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1) * nAcl->PixelWidth)); 229692f60a7Smrg } 230692f60a7Smrg} 231692f60a7Smrg 232692f60a7Smrg 233692f60a7Smrgstatic void 234692f60a7SmrgNeo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, 235692f60a7Smrg unsigned int planemask) 236692f60a7Smrg{ 237692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 238692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 239692f60a7Smrg 240692f60a7Smrg planemask &= nAcl->PlaneMask; 241692f60a7Smrg if (!rop) color=0; 242692f60a7Smrg 243692f60a7Smrg WAIT_ENGINE_IDLE(); 244692f60a7Smrg 245692f60a7Smrg OUTREG(NEO2070_BLTCNTL, nAcl->BltCntlFlags | 246692f60a7Smrg NEO_BC0_SRC_IS_FG | neo2070Rop[3]); 247692f60a7Smrg OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt)); 248692f60a7Smrg if (pScrn->bitsPerPixel == 8) 249692f60a7Smrg OUTREG(NEO2070_FGCOLOR, color |= (color << 8)); 250692f60a7Smrg else 251692f60a7Smrg /* swap bytes in color */ 252692f60a7Smrg OUTREG(NEO2070_FGCOLOR, ((color&0xff00) >> 8) | (color << 8)); 253692f60a7Smrg OUTREG(NEO2070_SRCPITCH, nAcl->Pitch); 254692f60a7Smrg OUTREG(NEO2070_DSTPITCH, nAcl->Pitch); 255692f60a7Smrg OUTREG(NEO2070_SRCBITOFF, 0); 256692f60a7Smrg OUTREG(NEO2070_DSTBITOFF, 0); 257692f60a7Smrg} 258692f60a7Smrg 259692f60a7Smrg 260692f60a7Smrgstatic void 261692f60a7SmrgNeo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 262692f60a7Smrg{ 263692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 264692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 265692f60a7Smrg 266692f60a7Smrg WAIT_ENGINE_IDLE(); 267692f60a7Smrg OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff)); 268692f60a7Smrg OUTREG(NEO2070_DSTSTART, (y * nAcl->Pitch) + (x * nAcl->PixelWidth)); 269692f60a7Smrg} 2703f6d0e1dSmrg#endif 271692f60a7Smrg 272