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#ifdef HAVE_XAA_H 56/* Memory Mapped I/O for BitBlt */ 57#define NEO2070_BLTSTAT 0x00 58#define NEO2070_BLTCNTL 0x04 59#define NEO2070_XPCOLOR 0x08 60#define NEO2070_FGCOLOR 0x0c 61#define NEO2070_BGCOLOR 0x10 62#define NEO2070_PLANEMASK 0x14 63#define NEO2070_XYEXT 0x18 64#define NEO2070_SRCPITCH 0x1c 65#define NEO2070_SRCBITOFF 0x20 66#define NEO2070_SRCSTART 0x24 67#define NEO2070_DSTPITCH 0x28 68#define NEO2070_DSTBITOFF 0x2c 69#define NEO2070_DSTSTART 0x30 70 71static unsigned int neo2070Rop[16] = { 72 0x000000, /* 0x0000 - GXclear */ 73 0x080000, /* 0x1000 - GXand */ 74 0x040000, /* 0x0100 - GXandReverse */ 75 0x0c0000, /* 0x1100 - GXcopy */ 76 0x020000, /* 0x0010 - GXandInvert */ 77 0x0a0000, /* 0x1010 - GXnoop */ 78 0x060000, /* 0x0110 - GXxor */ 79 0x0e0000, /* 0x1110 - GXor */ 80 0x010000, /* 0x0001 - GXnor */ 81 0x090000, /* 0x1001 - GXequiv */ 82 0x050000, /* 0x0101 - GXinvert */ 83 0x0d0000, /* 0x1101 - GXorReverse */ 84 0x030000, /* 0x0011 - GXcopyInvert */ 85 0x0b0000, /* 0x1011 - GXorInverted */ 86 0x070000, /* 0x0111 - GXnand */ 87 0x0f0000 /* 0x1111 - GXset */ 88}; 89 90static void Neo2070Sync(ScrnInfoPtr pScrn); 91static void Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, 92 int ydir, int rop, 93 unsigned int planemask, 94 int trans_color); 95static void Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX, 96 int srcY, int dstX, int dstY, 97 int w, int h); 98static void Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, 99 unsigned int planemask); 100static void Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, 101 int w, int h); 102 103#endif 104 105Bool 106Neo2070AccelInit(ScreenPtr pScreen) 107{ 108#ifdef HAVE_XAA_H 109 XAAInfoRecPtr infoPtr; 110 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 111 NEOPtr nPtr = NEOPTR(pScrn); 112 NEOACLPtr nAcl = NEOACLPTR(pScrn); 113 114 nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); 115 if(!infoPtr) return FALSE; 116 117 /* 118 * Set up the main acceleration flags. 119 */ 120 infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; 121 if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE; 122#if 0 123 infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES; 124#endif 125 /* sync */ 126 infoPtr->Sync = Neo2070Sync; 127 128 /* screen to screen copy */ 129 infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | GXCOPY_ONLY); 130 infoPtr->SetupForScreenToScreenCopy = 131 Neo2070SetupForScreenToScreenCopy; 132 infoPtr->SubsequentScreenToScreenCopy = 133 Neo2070SubsequentScreenToScreenCopy; 134 135 /* solid filled rectangles */ 136 infoPtr->SolidFillFlags = GXCOPY_ONLY; 137 infoPtr->SetupForSolidFill = 138 Neo2070SetupForSolidFillRect; 139 infoPtr->SubsequentSolidFillRect = 140 Neo2070SubsequentSolidFillRect; 141 142 /* 143 * Setup some global variables 144 */ 145 146 /* Initialize for 8bpp or 15/16bpp support accelerated */ 147 switch (pScrn->bitsPerPixel) { 148 case 8: 149 nAcl->BltCntlFlags = NEO_BC1_DEPTH8; 150 nAcl->ColorShiftAmt = 8; 151 nAcl->PixelWidth = 1; 152 nAcl->PlaneMask = 0xff; 153 break; 154 case 15: 155 case 16: 156 nAcl->BltCntlFlags = NEO_BC1_DEPTH16; 157 nAcl->ColorShiftAmt = 0; 158 nAcl->PixelWidth = 2; 159 nAcl->PlaneMask = 0xffff; 160 break; 161 case 24: /* not supported, but check anyway */ 162 default: 163 return FALSE; 164 } 165 166 return(XAAInit(pScreen, infoPtr)); 167#else 168 return FALSE; 169#endif 170} 171 172#ifdef HAVE_XAA_H 173static void 174Neo2070Sync(ScrnInfoPtr pScrn) 175{ 176 NEOPtr nPtr = NEOPTR(pScrn); 177 WAIT_ENGINE_IDLE(); 178} 179 180static void 181Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 182 int rop, 183 unsigned int planemask, 184 int trans_color) 185{ 186 NEOPtr nPtr = NEOPTR(pScrn); 187 NEOACLPtr nAcl = NEOACLPTR(pScrn); 188 189 /* set blt control */ 190 WAIT_ENGINE_IDLE(); 191 OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags); 192 OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt)); 193 OUTREG(NEO2070_SRCPITCH, nAcl->Pitch); 194 OUTREG(NEO2070_DSTPITCH, nAcl->Pitch); 195 OUTREG(NEO2070_SRCBITOFF, 0); 196 OUTREG(NEO2070_DSTBITOFF, 0); 197} 198 199static void 200Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 201 int srcX, int srcY, 202 int dstX, int dstY, 203 int w, int h) 204{ 205 NEOPtr nPtr = NEOPTR(pScrn); 206 NEOACLPtr nAcl = NEOACLPTR(pScrn); 207 208 if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) { 209 /* start with upper left corner */ 210 WAIT_ENGINE_IDLE(); 211 OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags); 212 OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff)); 213 OUTREG(NEO2070_SRCSTART, 214 (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth)); 215 OUTREG(NEO2070_DSTSTART, 216 (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth)); 217 } 218 else { 219 /* start with lower right corner */ 220 WAIT_ENGINE_IDLE(); 221 OUTREG(NEO2070_BLTCNTL, (nAcl->tmpBltCntlFlags | NEO_BC0_X_DEC 222 | NEO_BC0_DST_Y_DEC 223 | NEO_BC0_SRC_Y_DEC)); 224 OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff)); 225 OUTREG(NEO2070_SRCSTART, 226 ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1) * nAcl->PixelWidth)); 227 OUTREG(NEO2070_DSTSTART, 228 ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1) * nAcl->PixelWidth)); 229 } 230} 231 232 233static void 234Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, 235 unsigned int planemask) 236{ 237 NEOPtr nPtr = NEOPTR(pScrn); 238 NEOACLPtr nAcl = NEOACLPTR(pScrn); 239 240 planemask &= nAcl->PlaneMask; 241 if (!rop) color=0; 242 243 WAIT_ENGINE_IDLE(); 244 245 OUTREG(NEO2070_BLTCNTL, nAcl->BltCntlFlags | 246 NEO_BC0_SRC_IS_FG | neo2070Rop[3]); 247 OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt)); 248 if (pScrn->bitsPerPixel == 8) 249 OUTREG(NEO2070_FGCOLOR, color |= (color << 8)); 250 else 251 /* swap bytes in color */ 252 OUTREG(NEO2070_FGCOLOR, ((color&0xff00) >> 8) | (color << 8)); 253 OUTREG(NEO2070_SRCPITCH, nAcl->Pitch); 254 OUTREG(NEO2070_DSTPITCH, nAcl->Pitch); 255 OUTREG(NEO2070_SRCBITOFF, 0); 256 OUTREG(NEO2070_DSTBITOFF, 0); 257} 258 259 260static void 261Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 262{ 263 NEOPtr nPtr = NEOPTR(pScrn); 264 NEOACLPtr nAcl = NEOACLPTR(pScrn); 265 266 WAIT_ENGINE_IDLE(); 267 OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff)); 268 OUTREG(NEO2070_DSTSTART, (y * nAcl->Pitch) + (x * nAcl->PixelWidth)); 269} 270#endif 271 272