neo_2070.c revision c3c9db83
1/********************************************************************** 2Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas. 3 4 All Rights Reserved 5 6Permission to use, copy, modify, distribute, and sell this software and 7its documentation for any purpose is hereby granted without fee, 8provided that the above copyright notice appear in all copies and that 9both that copyright notice and this permission notice appear in 10supporting documentation, and that the name of Precision Insight not be 11used in advertising or publicity pertaining to distribution of the 12software without specific, written prior permission. Precision Insight 13and its suppliers make no representations about the suitability of this 14software for any purpose. It is provided "as is" without express or 15implied warranty. 16 17PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY 20SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 21RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 22CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 23CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 24**********************************************************************/ 25 26/* 27 * The original Precision Insight driver for 28 * XFree86 v.3.3 has been sponsored by Red Hat. 29 * 30 * Authors: 31 * Jens Owen (jens@tungstengraphics.com) 32 * Kevin E. Martin (kevin@precisioninsight.com) 33 * 34 * Port to Xfree86 v.4.0 35 * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE) 36 */ 37 38#ifdef HAVE_CONFIG_H 39#include "config.h" 40#endif 41 42#include "xf86.h" 43#include "xf86_OSproc.h" 44#include "compiler.h" 45 46/* Drivers that use XAA need this */ 47#include "xf86fbman.h" 48 49#include "miline.h" 50 51#include "neo.h" 52#include "neo_reg.h" 53#include "neo_macros.h" 54 55/* Memory Mapped I/O for BitBlt */ 56#define NEO2070_BLTSTAT 0x00 57#define NEO2070_BLTCNTL 0x04 58#define NEO2070_XPCOLOR 0x08 59#define NEO2070_FGCOLOR 0x0c 60#define NEO2070_BGCOLOR 0x10 61#define NEO2070_PLANEMASK 0x14 62#define NEO2070_XYEXT 0x18 63#define NEO2070_SRCPITCH 0x1c 64#define NEO2070_SRCBITOFF 0x20 65#define NEO2070_SRCSTART 0x24 66#define NEO2070_DSTPITCH 0x28 67#define NEO2070_DSTBITOFF 0x2c 68#define NEO2070_DSTSTART 0x30 69 70static unsigned int neo2070Rop[16] = { 71 0x000000, /* 0x0000 - GXclear */ 72 0x080000, /* 0x1000 - GXand */ 73 0x040000, /* 0x0100 - GXandReverse */ 74 0x0c0000, /* 0x1100 - GXcopy */ 75 0x020000, /* 0x0010 - GXandInvert */ 76 0x0a0000, /* 0x1010 - GXnoop */ 77 0x060000, /* 0x0110 - GXxor */ 78 0x0e0000, /* 0x1110 - GXor */ 79 0x010000, /* 0x0001 - GXnor */ 80 0x090000, /* 0x1001 - GXequiv */ 81 0x050000, /* 0x0101 - GXinvert */ 82 0x0d0000, /* 0x1101 - GXorReverse */ 83 0x030000, /* 0x0011 - GXcopyInvert */ 84 0x0b0000, /* 0x1011 - GXorInverted */ 85 0x070000, /* 0x0111 - GXnand */ 86 0x0f0000 /* 0x1111 - GXset */ 87}; 88 89static void Neo2070Sync(ScrnInfoPtr pScrn); 90static void Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, 91 int ydir, int rop, 92 unsigned int planemask, 93 int trans_color); 94static void Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX, 95 int srcY, int dstX, int dstY, 96 int w, int h); 97static void Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, 98 unsigned int planemask); 99static void Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, 100 int w, int h); 101 102Bool 103Neo2070AccelInit(ScreenPtr pScreen) 104{ 105 XAAInfoRecPtr infoPtr; 106 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 107 NEOPtr nPtr = NEOPTR(pScrn); 108 NEOACLPtr nAcl = NEOACLPTR(pScrn); 109 110 nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); 111 if(!infoPtr) return FALSE; 112 113 /* 114 * Set up the main acceleration flags. 115 */ 116 infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; 117 if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE; 118#if 0 119 infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES; 120#endif 121 /* sync */ 122 infoPtr->Sync = Neo2070Sync; 123 124 /* screen to screen copy */ 125 infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | GXCOPY_ONLY); 126 infoPtr->SetupForScreenToScreenCopy = 127 Neo2070SetupForScreenToScreenCopy; 128 infoPtr->SubsequentScreenToScreenCopy = 129 Neo2070SubsequentScreenToScreenCopy; 130 131 /* solid filled rectangles */ 132 infoPtr->SolidFillFlags = GXCOPY_ONLY; 133 infoPtr->SetupForSolidFill = 134 Neo2070SetupForSolidFillRect; 135 infoPtr->SubsequentSolidFillRect = 136 Neo2070SubsequentSolidFillRect; 137 138 /* 139 * Setup some global variables 140 */ 141 142 /* Initialize for 8bpp or 15/16bpp support accellerated */ 143 switch (pScrn->bitsPerPixel) { 144 case 8: 145 nAcl->BltCntlFlags = NEO_BC1_DEPTH8; 146 nAcl->ColorShiftAmt = 8; 147 nAcl->PixelWidth = 1; 148 nAcl->PlaneMask = 0xff; 149 break; 150 case 15: 151 case 16: 152 nAcl->BltCntlFlags = NEO_BC1_DEPTH16; 153 nAcl->ColorShiftAmt = 0; 154 nAcl->PixelWidth = 2; 155 nAcl->PlaneMask = 0xffff; 156 break; 157 case 24: /* not supported, but check anyway */ 158 default: 159 return FALSE; 160 } 161 162 return(XAAInit(pScreen, infoPtr)); 163 164} 165 166static void 167Neo2070Sync(ScrnInfoPtr pScrn) 168{ 169 NEOPtr nPtr = NEOPTR(pScrn); 170 WAIT_ENGINE_IDLE(); 171} 172 173static void 174Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 175 int rop, 176 unsigned int planemask, 177 int trans_color) 178{ 179 NEOPtr nPtr = NEOPTR(pScrn); 180 NEOACLPtr nAcl = NEOACLPTR(pScrn); 181 182 /* set blt control */ 183 WAIT_ENGINE_IDLE(); 184 OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags); 185 OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt)); 186 OUTREG(NEO2070_SRCPITCH, nAcl->Pitch); 187 OUTREG(NEO2070_DSTPITCH, nAcl->Pitch); 188 OUTREG(NEO2070_SRCBITOFF, 0); 189 OUTREG(NEO2070_DSTBITOFF, 0); 190} 191 192static void 193Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 194 int srcX, int srcY, 195 int dstX, int dstY, 196 int w, int h) 197{ 198 NEOPtr nPtr = NEOPTR(pScrn); 199 NEOACLPtr nAcl = NEOACLPTR(pScrn); 200 201 if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) { 202 /* start with upper left corner */ 203 WAIT_ENGINE_IDLE(); 204 OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags); 205 OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff)); 206 OUTREG(NEO2070_SRCSTART, 207 (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth)); 208 OUTREG(NEO2070_DSTSTART, 209 (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth)); 210 } 211 else { 212 /* start with lower right corner */ 213 WAIT_ENGINE_IDLE(); 214 OUTREG(NEO2070_BLTCNTL, (nAcl->tmpBltCntlFlags | NEO_BC0_X_DEC 215 | NEO_BC0_DST_Y_DEC 216 | NEO_BC0_SRC_Y_DEC)); 217 OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff)); 218 OUTREG(NEO2070_SRCSTART, 219 ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1) * nAcl->PixelWidth)); 220 OUTREG(NEO2070_DSTSTART, 221 ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1) * nAcl->PixelWidth)); 222 } 223} 224 225 226static void 227Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, 228 unsigned int planemask) 229{ 230 NEOPtr nPtr = NEOPTR(pScrn); 231 NEOACLPtr nAcl = NEOACLPTR(pScrn); 232 233 planemask &= nAcl->PlaneMask; 234 if (!rop) color=0; 235 236 WAIT_ENGINE_IDLE(); 237 238 OUTREG(NEO2070_BLTCNTL, nAcl->BltCntlFlags | 239 NEO_BC0_SRC_IS_FG | neo2070Rop[3]); 240 OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt)); 241 if (pScrn->bitsPerPixel == 8) 242 OUTREG(NEO2070_FGCOLOR, color |= (color << 8)); 243 else 244 /* swap bytes in color */ 245 OUTREG(NEO2070_FGCOLOR, ((color&0xff00) >> 8) | (color << 8)); 246 OUTREG(NEO2070_SRCPITCH, nAcl->Pitch); 247 OUTREG(NEO2070_DSTPITCH, nAcl->Pitch); 248 OUTREG(NEO2070_SRCBITOFF, 0); 249 OUTREG(NEO2070_DSTBITOFF, 0); 250} 251 252 253static void 254Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 255{ 256 NEOPtr nPtr = NEOPTR(pScrn); 257 NEOACLPtr nAcl = NEOACLPTR(pScrn); 258 259 WAIT_ENGINE_IDLE(); 260 OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff)); 261 OUTREG(NEO2070_DSTSTART, (y * nAcl->Pitch) + (x * nAcl->PixelWidth)); 262} 263 264 265 266 267 268