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