neo_2090.c revision 3f6d0e1d
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#include "xf86PciInfo.h" 46 47/* Drivers that use XAA need this */ 48#include "xf86fbman.h" 49 50#include "miline.h" 51 52#include "neo.h" 53#include "neo_reg.h" 54#include "neo_macros.h" 55 56#ifdef HAVE_XAA_H 57static unsigned int neo2090Rop[16] = { 58 0x000000, /* 0x0000 - GXclear */ 59 0x080000, /* 0x1000 - GXand */ 60 0x040000, /* 0x0100 - GXandReverse */ 61 0x0c0000, /* 0x1100 - GXcopy */ 62 0x020000, /* 0x0010 - GXandInvert */ 63 0x0a0000, /* 0x1010 - GXnoop */ 64 0x060000, /* 0x0110 - GXxor */ 65 0x0e0000, /* 0x1110 - GXor */ 66 0x010000, /* 0x0001 - GXnor */ 67 0x090000, /* 0x1001 - GXequiv */ 68 0x050000, /* 0x0101 - GXinvert */ 69 0x0d0000, /* 0x1101 - GXorReverse */ 70 0x030000, /* 0x0011 - GXcopyInvert */ 71 0x0b0000, /* 0x1011 - GXorInverted */ 72 0x070000, /* 0x0111 - GXnand */ 73 0x0f0000 /* 0x1111 - GXset */ 74}; 75 76static void Neo2090Sync(ScrnInfoPtr pScrn); 77static void Neo2090SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, 78 int ydir, int rop, 79 unsigned int planemask, 80 int trans_color); 81static void Neo2090SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX, 82 int srcY, int dstX, int dstY, 83 int w, int h); 84static void Neo2090SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, 85 unsigned int planemask); 86static void Neo2090SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, 87 int w, int h); 88static void Neo2093SetupForScanlineCPUToScreenColorExpandFill( 89 ScrnInfoPtr pScrn, 90 int fg, int bg, 91 int rop, 92 unsigned int planemask); 93static void Neo2093SubsequentScanlineCPUToScreenColorExpandFill( 94 ScrnInfoPtr pScrn, 95 int x, int y, 96 int w, int h, 97 int skipleft); 98static void Neo2093SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); 99#endif 100Bool 101Neo2090AccelInit(ScreenPtr pScreen) 102{ 103#ifdef HAVE_XAA_H 104 XAAInfoRecPtr infoPtr; 105 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 106 NEOPtr nPtr = NEOPTR(pScrn); 107 NEOACLPtr nAcl = NEOACLPTR(pScrn); 108 109 nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); 110 if(!infoPtr) return FALSE; 111 112 /* 113 * Set up the main acceleration flags. 114 */ 115 infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; 116 if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE; 117#if 0 118 infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES; 119#endif 120 /* sync */ 121 infoPtr->Sync = Neo2090Sync; 122 123 /* screen to screen copy */ 124 infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | NO_PLANEMASK); 125 infoPtr->SetupForScreenToScreenCopy = 126 Neo2090SetupForScreenToScreenCopy; 127 infoPtr->SubsequentScreenToScreenCopy = 128 Neo2090SubsequentScreenToScreenCopy; 129 130 /* solid filled rectangles */ 131 infoPtr->SolidFillFlags = NO_PLANEMASK; 132 infoPtr->SetupForSolidFill = 133 Neo2090SetupForSolidFillRect; 134 infoPtr->SubsequentSolidFillRect = 135 Neo2090SubsequentSolidFillRect; 136 137 if (nPtr->NeoChipset == PCI_CHIP_NM2093 && !nPtr->strangeLockups) { 138 /* 139 * We do CPUToScreenColorExpand (ab)using the Scanline functions: 140 * the neo chipsets need byte padding however we can only do dword 141 * padding. Fortunately the graphics engine doesn't choke if we 142 * transfer up to 3 bytes more than it wants. 143 */ 144 145 /* cpu to screen color expansion */ 146 infoPtr->ScanlineColorExpandBuffers = 147 (unsigned char **)xnfalloc(sizeof(char*)); 148 infoPtr->ScanlineColorExpandBuffers[0] = 149 (unsigned char *)(nPtr->NeoMMIOBase + 0x100000); 150 infoPtr->NumScanlineColorExpandBuffers = 1; 151 infoPtr->ScanlineCPUToScreenColorExpandFillFlags = ( NO_PLANEMASK | 152 SCANLINE_PAD_DWORD | 153 CPU_TRANSFER_PAD_DWORD | 154 BIT_ORDER_IN_BYTE_MSBFIRST ); 155 156 infoPtr->SetupForScanlineCPUToScreenColorExpandFill = 157 Neo2093SetupForScanlineCPUToScreenColorExpandFill; 158 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = 159 Neo2093SubsequentScanlineCPUToScreenColorExpandFill; 160 infoPtr->SubsequentColorExpandScanline = 161 Neo2093SubsequentColorExpandScanline; 162 } 163 164 /* 165 * Setup some global variables 166 */ 167 nAcl->ColorShiftAmt = 0; 168 169 /* Initialize for 8bpp or 15/16bpp support accellerated */ 170 switch (pScrn->bitsPerPixel) { 171 case 8: 172 nAcl->BltCntlFlags = NEO_BC1_DEPTH8; 173 nAcl->ColorShiftAmt = 8; 174 break; 175 case 15: 176 case 16: 177 nAcl->BltCntlFlags = NEO_BC1_DEPTH16; 178 nAcl->ColorShiftAmt = 0; 179 break; 180 case 24: 181 default: 182 return FALSE; 183 } 184 185 /* Initialize for widths */ 186 switch (pScrn->displayWidth) { 187 case 640: 188 nAcl->BltCntlFlags |= NEO_BC1_X_640; 189 break; 190 case 800: 191 nAcl->BltCntlFlags |= NEO_BC1_X_800; 192 break; 193 case 1024: 194 nAcl->BltCntlFlags |= NEO_BC1_X_1024; 195 break; 196 default: 197 return FALSE; 198 } 199 200 nAcl->BltCntlFlags |= NEO_BC3_FIFO_EN; 201 202 return(XAAInit(pScreen, infoPtr)); 203#else 204 return FALSE; 205#endif 206} 207 208#ifdef HAVE_XAA_H 209static void 210Neo2090Sync(ScrnInfoPtr pScrn) 211{ 212 NEOPtr nPtr = NEOPTR(pScrn); 213 214 WAIT_ENGINE_IDLE(); 215} 216 217static void 218Neo2090SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 219 int rop, 220 unsigned int planemask, 221 int trans_color) 222{ 223 NEOPtr nPtr = NEOPTR(pScrn); 224 NEOACLPtr nAcl = NEOACLPTR(pScrn); 225 226 nAcl->tmpBltCntlFlags = (nAcl->BltCntlFlags | 227 NEO_BC3_SKIP_MAPPING | 228 NEO_BC3_DST_XY_ADDR | 229 NEO_BC3_SRC_XY_ADDR | neo2090Rop[rop]); 230 231 /* set blt control */ 232 WAIT_FIFO(2); 233 OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); 234} 235 236static void 237Neo2090SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 238 int srcX, int srcY, 239 int dstX, int dstY, 240 int w, int h) 241{ 242 NEOPtr nPtr = NEOPTR(pScrn); 243 NEOACLPtr nAcl = NEOACLPTR(pScrn); 244 245 if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) { 246 /* start with upper left corner */ 247 WAIT_FIFO(4); 248 OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); 249 OUTREG(NEOREG_SRCSTARTOFF, (srcY<<16) | (srcX & 0xffff)); 250 OUTREG(NEOREG_DSTSTARTOFF, (dstY<<16) | (dstX & 0xffff)); 251 OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); 252 } 253 else { 254 /* start with lower right corner */ 255 WAIT_FIFO(4); 256 OUTREG(NEOREG_BLTCNTL, (nAcl->tmpBltCntlFlags | NEO_BC0_X_DEC 257 | NEO_BC0_DST_Y_DEC 258 | NEO_BC0_SRC_Y_DEC)); 259 OUTREG(NEOREG_SRCSTARTOFF, ((srcY+h-1)<<16) | ((srcX+w-1) & 0xffff)); 260 OUTREG(NEOREG_DSTSTARTOFF, ((dstY+h-1)<<16) | ((dstX+w-1) & 0xffff)); 261 OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); 262 } 263} 264 265 266static void 267Neo2090SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, 268 unsigned int planemask) 269{ 270 NEOPtr nPtr = NEOPTR(pScrn); 271 NEOACLPtr nAcl = NEOACLPTR(pScrn); 272 273 WAIT_FIFO(2); 274 275 /* set blt control */ 276 OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags | 277 NEO_BC0_SRC_IS_FG | 278 NEO_BC3_SKIP_MAPPING | 279 NEO_BC3_DST_XY_ADDR | 280 NEO_BC3_SRC_XY_ADDR | neo2090Rop[rop]); 281 282 /* set foreground color */ 283 OUTREG(NEOREG_FGCOLOR, color |= (color << nAcl->ColorShiftAmt)); 284} 285 286 287static void 288Neo2090SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 289{ 290 NEOPtr nPtr = NEOPTR(pScrn); 291 292 WAIT_FIFO(2); 293 OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff)); 294 OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); 295 296} 297 298static void 299Neo2093SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 300 int fg, int bg, 301 int rop, 302 unsigned int planemask) 303{ 304 NEOPtr nPtr = NEOPTR(pScrn); 305 NEOACLPtr nAcl = NEOACLPTR(pScrn); 306 307 if (bg == -1) { 308 /* transparent setup */ 309 WAIT_FIFO(2); 310 OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags | 311 NEO_BC0_SYS_TO_VID | 312 NEO_BC0_SRC_MONO | 313 NEO_BC0_SRC_TRANS | 314 NEO_BC3_SKIP_MAPPING | 315 NEO_BC3_DST_XY_ADDR | neo2090Rop[rop]); 316 317 OUTREG(NEOREG_FGCOLOR, fg |= (fg << nAcl->ColorShiftAmt)); 318 } 319 else { 320 /* opaque setup */ 321 WAIT_FIFO(3); 322 OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags | 323 NEO_BC0_SYS_TO_VID | 324 NEO_BC0_SRC_MONO | 325 NEO_BC3_SKIP_MAPPING | 326 NEO_BC3_DST_XY_ADDR | neo2090Rop[rop]); 327 328 OUTREG(NEOREG_FGCOLOR, fg |= (fg << nAcl->ColorShiftAmt)); 329 OUTREG(NEOREG_BGCOLOR, bg |= (bg << nAcl->ColorShiftAmt)); 330 } 331} 332 333static void 334Neo2093SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 335 int x, int y, 336 int w, int h, 337 int skipleft) 338{ 339 NEOPtr nPtr = NEOPTR(pScrn); 340 NEOACLPtr nAcl = NEOACLPTR(pScrn); 341 342 nAcl->CPUToScreenColorExpandFill_x = x; 343 nAcl->CPUToScreenColorExpandFill_y = y; 344 nAcl->CPUToScreenColorExpandFill_w = w; 345 nAcl->CPUToScreenColorExpandFill_h = h; 346 nAcl->CPUToScreenColorExpandFill_skipleft = skipleft; 347 348 WAIT_FIFO(4); 349 OUTREG(NEOREG_SRCBITOFF, skipleft); 350 OUTREG(NEOREG_SRCSTARTOFF, 0); 351 OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff)); 352 OUTREG(NEOREG_XYEXT, (1<<16) | (w & 0xffff)); 353} 354 355static void 356Neo2093SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 357{ 358 NEOPtr nPtr = NEOPTR(pScrn); 359 NEOACLPtr nAcl = NEOACLPTR(pScrn); 360 361 if (!(--nAcl->CPUToScreenColorExpandFill_h)) 362 return; 363 364 WAIT_FIFO(4); 365 OUTREG(NEOREG_SRCBITOFF, nAcl->CPUToScreenColorExpandFill_skipleft); 366 OUTREG(NEOREG_SRCSTARTOFF, 0); 367 OUTREG(NEOREG_DSTSTARTOFF, ((++nAcl->CPUToScreenColorExpandFill_y)<<16) 368 | (nAcl->CPUToScreenColorExpandFill_x & 0xffff)); 369 OUTREG(NEOREG_XYEXT, (1<<16) 370 | (nAcl->CPUToScreenColorExpandFill_w & 0xffff)); 371} 372#endif 373