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 * The original Precision Insight driver for 27692f60a7Smrg * XFree86 v.3.3 has been sponsored by Red Hat. 28692f60a7Smrg * 29692f60a7Smrg * Authors: 30692f60a7Smrg * Jens Owen (jens@tungstengraphics.com) 31692f60a7Smrg * Kevin E. Martin (kevin@precisioninsight.com) 32692f60a7Smrg * 33692f60a7Smrg * Port to Xfree86 v.4.0 34692f60a7Smrg * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE) 35692f60a7Smrg */ 36692f60a7Smrg 37692f60a7Smrg#ifdef HAVE_CONFIG_H 38692f60a7Smrg#include "config.h" 39692f60a7Smrg#endif 40692f60a7Smrg 41692f60a7Smrg#include "xf86.h" 42692f60a7Smrg#include "xf86_OSproc.h" 43692f60a7Smrg#include "compiler.h" 44692f60a7Smrg 45692f60a7Smrg/* Drivers that use XAA need this */ 46692f60a7Smrg#include "xf86fbman.h" 47692f60a7Smrg 48692f60a7Smrg#include "miline.h" 49692f60a7Smrg 50692f60a7Smrg#include "neo.h" 51692f60a7Smrg#include "neo_reg.h" 52692f60a7Smrg#include "neo_macros.h" 53692f60a7Smrg 543f6d0e1dSmrg#ifdef HAVE_XAA_H 55692f60a7Smrgstatic void Neo2200Sync(ScrnInfoPtr pScrn); 56692f60a7Smrgstatic void Neo2200SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, 57692f60a7Smrg int ydir, int rop, 58692f60a7Smrg unsigned int planemask, 59692f60a7Smrg int trans_color); 60692f60a7Smrg#ifdef NOT_BROKEN 61692f60a7Smrgstatic void Neo2200SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX, 62692f60a7Smrg int srcY, int dstX, int dstY, 63692f60a7Smrg int w, int h); 64692f60a7Smrg#else 65692f60a7Smrgstatic void Neo2200SubsequentScreenToScreenCopyBroken(ScrnInfoPtr pScrn, int srcX, 66692f60a7Smrg int srcY, int dstX, int dstY, 67692f60a7Smrg int w, int h); 68692f60a7Smrg#endif 69692f60a7Smrgstatic void Neo2200SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, 70692f60a7Smrg unsigned int planemask); 71692f60a7Smrgstatic void Neo2200SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, 72692f60a7Smrg int w, int h); 73692f60a7Smrgstatic void Neo2200SetupForScanlineCPUToScreenColorExpandFill( 74692f60a7Smrg ScrnInfoPtr pScrn, 75692f60a7Smrg int fg, int bg, 76692f60a7Smrg int rop, 77692f60a7Smrg unsigned int planemask); 78692f60a7Smrgstatic void Neo2200SubsequentScanlineCPUToScreenColorExpandFill( 79692f60a7Smrg ScrnInfoPtr pScrn, 80692f60a7Smrg int x, int y, 81692f60a7Smrg int w, int h, 82692f60a7Smrg int skipleft); 83692f60a7Smrgstatic void Neo2200SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); 84692f60a7Smrg#if 0 85692f60a7Smrgstatic void Neo2200SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, 86692f60a7Smrg int patternx, 87692f60a7Smrg int patterny, 88692f60a7Smrg int bg, 89692f60a7Smrg int fg, 90692f60a7Smrg int rop, 91692f60a7Smrg unsigned int planemask); 92692f60a7Smrgstatic void Neo2200SubsequentMono8x8PatternFill(ScrnInfoPtr pScrn, 93692f60a7Smrg int patternx, 94692f60a7Smrg int patterny, 95692f60a7Smrg int x, int y, 96692f60a7Smrg int w, int h); 97692f60a7Smrg#endif 98692f60a7Smrg 99692f60a7Smrg 100692f60a7Smrgstatic unsigned int neo2200Rop[16] = { 101692f60a7Smrg 0x000000, /* 0x0000 - GXclear */ 102692f60a7Smrg 0x080000, /* 0x1000 - GXand */ 103692f60a7Smrg 0x040000, /* 0x0100 - GXandReverse */ 104692f60a7Smrg 0x0c0000, /* 0x1100 - GXcopy */ 105692f60a7Smrg 0x020000, /* 0x0010 - GXandInvert */ 106692f60a7Smrg 0x0a0000, /* 0x1010 - GXnoop */ 107692f60a7Smrg 0x060000, /* 0x0110 - GXxor */ 108692f60a7Smrg 0x0e0000, /* 0x1110 - GXor */ 109692f60a7Smrg 0x010000, /* 0x0001 - GXnor */ 110692f60a7Smrg 0x090000, /* 0x1001 - GXequiv */ 111692f60a7Smrg 0x050000, /* 0x0101 - GXinvert */ 112692f60a7Smrg 0x0d0000, /* 0x1101 - GXorReverse */ 113692f60a7Smrg 0x030000, /* 0x0011 - GXcopyInvert */ 114692f60a7Smrg 0x0b0000, /* 0x1011 - GXorInverted */ 115692f60a7Smrg 0x070000, /* 0x0111 - GXnand */ 116692f60a7Smrg 0x0f0000 /* 0x1111 - GXset */ 117692f60a7Smrg}; 118692f60a7Smrg 1193f6d0e1dSmrg#endif 120692f60a7SmrgBool 121692f60a7SmrgNeo2200AccelInit(ScreenPtr pScreen) 122692f60a7Smrg{ 1233f6d0e1dSmrg#ifdef HAVE_XAA_H 124692f60a7Smrg XAAInfoRecPtr infoPtr; 1253f6d0e1dSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 126692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 127692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 128692f60a7Smrg 129692f60a7Smrg nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec(); 130692f60a7Smrg if(!infoPtr) return FALSE; 131692f60a7Smrg 132692f60a7Smrg /* 133692f60a7Smrg * Set up the main acceleration flags. 134692f60a7Smrg */ 135692f60a7Smrg infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; 136692f60a7Smrg if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE; 137692f60a7Smrg#if 0 138692f60a7Smrg infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES; 139692f60a7Smrg#endif 140692f60a7Smrg /* sync */ 141692f60a7Smrg infoPtr->Sync = Neo2200Sync; 142692f60a7Smrg 143692f60a7Smrg /* screen to screen copy */ 144692f60a7Smrg infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | NO_PLANEMASK); 145692f60a7Smrg infoPtr->SetupForScreenToScreenCopy = 146692f60a7Smrg Neo2200SetupForScreenToScreenCopy; 147692f60a7Smrg infoPtr->SubsequentScreenToScreenCopy 148692f60a7Smrg#ifdef NOT_BROKEN 149692f60a7Smrg = Neo2200SubsequentScreenToScreenCopy; 150692f60a7Smrg#else 151692f60a7Smrg = Neo2200SubsequentScreenToScreenCopyBroken; 152692f60a7Smrg#endif 153692f60a7Smrg 154692f60a7Smrg /* solid filled rectangles */ 155692f60a7Smrg infoPtr->SolidFillFlags = NO_PLANEMASK; 156692f60a7Smrg infoPtr->SetupForSolidFill = 157692f60a7Smrg Neo2200SetupForSolidFillRect; 158692f60a7Smrg infoPtr->SubsequentSolidFillRect = 159692f60a7Smrg Neo2200SubsequentSolidFillRect; 160692f60a7Smrg 161692f60a7Smrg /* cpu to screen color expansion */ 162692f60a7Smrg /* 163692f60a7Smrg * We do CPUToScreenColorExpand (ab)using the Scanline functions: 164692f60a7Smrg * the neo chipsets need byte padding however we can only do dword 165692f60a7Smrg * padding. Fortunately the graphics engine doesn't choke if we 166692f60a7Smrg * transfer up to 3 bytes more than it wants. 167692f60a7Smrg */ 168692f60a7Smrg 169692f60a7Smrg if (!nPtr->strangeLockups) { 170692f60a7Smrg 171692f60a7Smrg infoPtr->ScanlineCPUToScreenColorExpandFillFlags = ( NO_PLANEMASK | 172692f60a7Smrg#ifdef NEO_DO_CLIPPING 173692f60a7Smrg LEFT_EDGE_CLIPPING | 174692f60a7Smrg#endif 175692f60a7Smrg SCANLINE_PAD_DWORD | 176692f60a7Smrg CPU_TRANSFER_PAD_DWORD | 177692f60a7Smrg BIT_ORDER_IN_BYTE_MSBFIRST ); 178692f60a7Smrg infoPtr->ScanlineColorExpandBuffers = 179692f60a7Smrg (unsigned char **)xnfalloc(sizeof(char*)); 180692f60a7Smrg infoPtr->ScanlineColorExpandBuffers[0] = 181692f60a7Smrg (unsigned char *)(nPtr->NeoMMIOBase + 0x100000); 182692f60a7Smrg infoPtr->NumScanlineColorExpandBuffers = 1; 183692f60a7Smrg infoPtr->SetupForScanlineCPUToScreenColorExpandFill = 184692f60a7Smrg Neo2200SetupForScanlineCPUToScreenColorExpandFill; 185692f60a7Smrg infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = 186692f60a7Smrg Neo2200SubsequentScanlineCPUToScreenColorExpandFill; 187692f60a7Smrg infoPtr->SubsequentColorExpandScanline = 188692f60a7Smrg Neo2200SubsequentColorExpandScanline; 189692f60a7Smrg } 190692f60a7Smrg 191692f60a7Smrg#if 0 192692f60a7Smrg /* 8x8 pattern fills */ 193692f60a7Smrg infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK 194692f60a7Smrg | HARDWARE_PATTERN_PROGRAMMED_ORIGIN 195692f60a7Smrg |BIT_ORDER_IN_BYTE_MSBFIRST; 196692f60a7Smrg 197692f60a7Smrg infoPtr->SetupForMono8x8PatternFill = 198692f60a7Smrg Neo2200SetupForMono8x8PatternFill; 199692f60a7Smrg infoPtr->SubsequentMono8x8PatternFillRect = 200692f60a7Smrg Neo2200SubsequentMono8x8PatternFill; 201692f60a7Smrg#endif 202692f60a7Smrg 203692f60a7Smrg /* 204692f60a7Smrg * Setup some global variables 205692f60a7Smrg */ 206692f60a7Smrg 207692f60a7Smrg /* Initialize for 8bpp or 15/16bpp support accelerated */ 208692f60a7Smrg switch (pScrn->bitsPerPixel) { 209692f60a7Smrg case 8: 210692f60a7Smrg nAcl->BltModeFlags = NEO_MODE1_DEPTH8; 211692f60a7Smrg nAcl->PixelWidth = 1; 212692f60a7Smrg break; 213692f60a7Smrg case 15: 214692f60a7Smrg case 16: 215692f60a7Smrg nAcl->BltModeFlags = NEO_MODE1_DEPTH16; 216692f60a7Smrg nAcl->PixelWidth = 2; 217692f60a7Smrg break; 218692f60a7Smrg case 24: 219692f60a7Smrg if (nPtr->noAccelSet || nPtr->NeoChipset == NM2230 220692f60a7Smrg || nPtr->NeoChipset == NM2360 221692f60a7Smrg || nPtr->NeoChipset == NM2380) { 222692f60a7Smrg nAcl->BltModeFlags = NEO_MODE1_DEPTH24; 223692f60a7Smrg nAcl->PixelWidth = 3; 224692f60a7Smrg } else 225692f60a7Smrg return FALSE; 226692f60a7Smrg break; 227692f60a7Smrg default: 228692f60a7Smrg return FALSE; 229692f60a7Smrg } 230692f60a7Smrg nAcl->Pitch = pScrn->displayWidth * nAcl->PixelWidth; 231692f60a7Smrg 232692f60a7Smrg /* Initialize for widths */ 233692f60a7Smrg switch (pScrn->displayWidth) { 234692f60a7Smrg case 320: 235692f60a7Smrg nAcl->BltModeFlags |= NEO_MODE1_X_320; 236692f60a7Smrg break; 237692f60a7Smrg case 640: 238692f60a7Smrg nAcl->BltModeFlags |= NEO_MODE1_X_640; 239692f60a7Smrg break; 240692f60a7Smrg case 800: 241692f60a7Smrg nAcl->BltModeFlags |= NEO_MODE1_X_800; 242692f60a7Smrg break; 243692f60a7Smrg case 1024: 244692f60a7Smrg nAcl->BltModeFlags |= NEO_MODE1_X_1024; 245692f60a7Smrg break; 246692f60a7Smrg case 1152: 247692f60a7Smrg nAcl->BltModeFlags |= NEO_MODE1_X_1152; 248692f60a7Smrg break; 249692f60a7Smrg case 1280: 250692f60a7Smrg nAcl->BltModeFlags |= NEO_MODE1_X_1280; 251692f60a7Smrg break; 252692f60a7Smrg case 1600: 253692f60a7Smrg nAcl->BltModeFlags |= NEO_MODE1_X_1600; 254692f60a7Smrg break; 255692f60a7Smrg default: 256692f60a7Smrg return FALSE; 257692f60a7Smrg } 258692f60a7Smrg 259c3c9db83Smrg return(XAAInit(pScreen, infoPtr)); 2603f6d0e1dSmrg#else 2613f6d0e1dSmrg return FALSE; 2623f6d0e1dSmrg#endif 263692f60a7Smrg} 264692f60a7Smrg 2653f6d0e1dSmrg#ifdef HAVE_XAA_H 266692f60a7Smrgstatic void 267692f60a7SmrgNeo2200Sync(ScrnInfoPtr pScrn) 268692f60a7Smrg{ 269692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 270692f60a7Smrg 271692f60a7Smrg WAIT_ENGINE_IDLE(); 272692f60a7Smrg} 273692f60a7Smrg 274692f60a7Smrgstatic void 275692f60a7SmrgNeo2200SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 276692f60a7Smrg int rop, 277692f60a7Smrg unsigned int planemask, 278692f60a7Smrg int trans_color) 279692f60a7Smrg{ 280692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 281692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 282692f60a7Smrg 283692f60a7Smrg nAcl->tmpBltCntlFlags = (NEO_BC3_SKIP_MAPPING | neo2200Rop[rop]); 284692f60a7Smrg /* set blt control */ 285692f60a7Smrg WAIT_ENGINE_IDLE(); 286692f60a7Smrg /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/ 287692f60a7Smrg OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16); 288692f60a7Smrg OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); 289692f60a7Smrg OUTREG(NEOREG_PITCH, (nAcl->Pitch<<16) 290692f60a7Smrg | (nAcl->Pitch & 0xffff)); 291692f60a7Smrg} 292692f60a7Smrg 293692f60a7Smrg#ifdef NOT_BROKEN 294692f60a7Smrgstatic void 295692f60a7SmrgNeo2200SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 296692f60a7Smrg int srcX, int srcY, 297692f60a7Smrg int dstX, int dstY, 298692f60a7Smrg int w, int h) 299692f60a7Smrg{ 300692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 301692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 302692f60a7Smrg 303692f60a7Smrg if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) { 304692f60a7Smrg /* start with upper left corner */ 305692f60a7Smrg WAIT_ENGINE_IDLE(); 306692f60a7Smrg#if 0 307692f60a7Smrg OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); 308692f60a7Smrg#endif 309692f60a7Smrg OUTREG(NEOREG_SRCSTARTOFF, 310692f60a7Smrg (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth)); 311692f60a7Smrg OUTREG(NEOREG_DSTSTARTOFF, 312692f60a7Smrg (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth)); 313692f60a7Smrg OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); 314692f60a7Smrg } 315692f60a7Smrg else { 316692f60a7Smrg /* start with lower right corner */ 317692f60a7Smrg WAIT_ENGINE_IDLE(); 318692f60a7Smrg#if 0 319692f60a7Smrg OUTREG(NEOREG_BLTCNTL, (nAcl->tmpBltCntlFlags 320692f60a7Smrg | NEO_BC0_X_DEC 321692f60a7Smrg | NEO_BC0_DST_Y_DEC 322692f60a7Smrg | NEO_BC0_SRC_Y_DEC)); 323692f60a7Smrg#endif 324692f60a7Smrg OUTREG(NEOREG_SRCSTARTOFF, 325692f60a7Smrg ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1) 326692f60a7Smrg * nAcl->PixelWidth)); 327692f60a7Smrg OUTREG(NEOREG_DSTSTARTOFF, 328692f60a7Smrg ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1) 329692f60a7Smrg * nAcl->PixelWidth)); 330692f60a7Smrg OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); 331692f60a7Smrg } 332692f60a7Smrg} 333692f60a7Smrg 334692f60a7Smrg#else /* NOT_BROKEN */ 335692f60a7Smrg 336692f60a7Smrgstatic void 337692f60a7SmrgNeo2200SubsequentScreenToScreenCopyBroken(ScrnInfoPtr pScrn, 338692f60a7Smrg int srcX, int srcY, 339692f60a7Smrg int dstX, int dstY, 340692f60a7Smrg int w, int h) 341692f60a7Smrg{ 342692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 343692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 344692f60a7Smrg 345692f60a7Smrg if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) { 346692f60a7Smrg if ((((dstX < 64) && ((srcX + w + 64) >= pScrn->displayWidth)) || 347692f60a7Smrg ((dstX == 0) && (w > (pScrn->displayWidth - 64)))) && (w > 64)) { 348692f60a7Smrg 349692f60a7Smrg#define COPY_64 \ 350692f60a7Smrg OUTREG(NEOREG_SRCSTARTOFF,\ 351692f60a7Smrg (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth));\ 352692f60a7Smrg OUTREG(NEOREG_DSTSTARTOFF,\ 353692f60a7Smrg (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth));\ 354692f60a7Smrg OUTREG(NEOREG_XYEXT, (h<<16) | (64)); 355692f60a7Smrg#define COPY_W \ 356692f60a7Smrg OUTREG(NEOREG_SRCSTARTOFF,\ 357692f60a7Smrg (srcY * nAcl->Pitch) + (srcX1 * nAcl->PixelWidth));\ 358692f60a7Smrg OUTREG(NEOREG_DSTSTARTOFF,\ 359692f60a7Smrg (dstY * nAcl->Pitch) + (dstX1 * nAcl->PixelWidth));\ 360692f60a7Smrg OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); 361692f60a7Smrg 362692f60a7Smrg int srcX1 = srcX + 64; 363692f60a7Smrg int dstX1 = dstX + 64; 364692f60a7Smrg w -= 64; 365692f60a7Smrg /* start with upper left corner */ 366692f60a7Smrg WAIT_ENGINE_IDLE(); 367692f60a7Smrg OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); 368692f60a7Smrg if (srcX < dstX) { 369692f60a7Smrg COPY_W; 370692f60a7Smrg WAIT_ENGINE_IDLE(); 371692f60a7Smrg COPY_64; 372692f60a7Smrg } else { 373692f60a7Smrg COPY_64; 374692f60a7Smrg WAIT_ENGINE_IDLE(); 375692f60a7Smrg COPY_W; 376692f60a7Smrg } 377692f60a7Smrg#undef COPY_W 378692f60a7Smrg#undef COPY_64 379692f60a7Smrg } else { 380692f60a7Smrg /* start with upper left corner */ 381692f60a7Smrg WAIT_ENGINE_IDLE(); 382692f60a7Smrg OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); 383692f60a7Smrg OUTREG(NEOREG_SRCSTARTOFF, 384692f60a7Smrg (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth)); 385692f60a7Smrg OUTREG(NEOREG_DSTSTARTOFF, 386692f60a7Smrg (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth)); 387692f60a7Smrg OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); 388692f60a7Smrg } 389692f60a7Smrg } else { 390692f60a7Smrg if (((((dstX + w) > (pScrn->displayWidth - 64)) && (srcX == 0)) 391692f60a7Smrg || (((dstX + w + 64) >= pScrn->displayWidth) 392692f60a7Smrg && (w > (pScrn->displayWidth - 64)))) && (w > 64)) { 393692f60a7Smrg#define COPY_64 \ 394692f60a7Smrg OUTREG(NEOREG_SRCSTARTOFF, \ 395692f60a7Smrg ((srcY+h-1) * nAcl->Pitch) + ((srcX1+64-1) \ 396692f60a7Smrg * nAcl->PixelWidth)); \ 397692f60a7Smrg OUTREG(NEOREG_DSTSTARTOFF, \ 398692f60a7Smrg ((dstY+h-1) * nAcl->Pitch) + ((dstX1+64-1) \ 399692f60a7Smrg * nAcl->PixelWidth)); \ 400692f60a7Smrg OUTREG(NEOREG_XYEXT, (h<<16) | (64 & 0xffff)); 401692f60a7Smrg#define COPY_W \ 402692f60a7Smrg OUTREG(NEOREG_SRCSTARTOFF, \ 403692f60a7Smrg ((srcY+h-1) * nAcl->Pitch) + ((srcX + w -1) \ 404692f60a7Smrg * nAcl->PixelWidth)); \ 405692f60a7Smrg OUTREG(NEOREG_DSTSTARTOFF, \ 406692f60a7Smrg ((dstY+h-1) * nAcl->Pitch) + ((dstX + w -1) \ 407692f60a7Smrg * nAcl->PixelWidth)); \ 408692f60a7Smrg OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); 409692f60a7Smrg 410692f60a7Smrg int srcX1, dstX1; 411692f60a7Smrg 412692f60a7Smrg w -= 64; 413692f60a7Smrg srcX1 = srcX + w; 414692f60a7Smrg dstX1 = dstX + w; 415692f60a7Smrg /* start with lower right corner */ 416692f60a7Smrg WAIT_ENGINE_IDLE(); 417692f60a7Smrg OUTREG(NEOREG_BLTCNTL, (nAcl->tmpBltCntlFlags 418692f60a7Smrg | NEO_BC0_X_DEC 419692f60a7Smrg | NEO_BC0_DST_Y_DEC 420692f60a7Smrg | NEO_BC0_SRC_Y_DEC)); 421692f60a7Smrg if (srcX < dstX) { 422692f60a7Smrg COPY_64; 423692f60a7Smrg WAIT_ENGINE_IDLE(); 424692f60a7Smrg COPY_W; 425692f60a7Smrg } else { 426692f60a7Smrg COPY_W; 427692f60a7Smrg WAIT_ENGINE_IDLE(); 428692f60a7Smrg COPY_64; 429692f60a7Smrg } 430692f60a7Smrg#undef COPY_W 431692f60a7Smrg#undef COPY_64 432692f60a7Smrg } else { 433692f60a7Smrg /* start with lower right corner */ 434692f60a7Smrg WAIT_ENGINE_IDLE(); 435692f60a7Smrg OUTREG(NEOREG_BLTCNTL, (nAcl->tmpBltCntlFlags 436692f60a7Smrg | NEO_BC0_X_DEC 437692f60a7Smrg | NEO_BC0_DST_Y_DEC 438692f60a7Smrg | NEO_BC0_SRC_Y_DEC)); 439692f60a7Smrg OUTREG(NEOREG_SRCSTARTOFF, 440692f60a7Smrg ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1) 441692f60a7Smrg * nAcl->PixelWidth)); 442692f60a7Smrg OUTREG(NEOREG_DSTSTARTOFF, 443692f60a7Smrg ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1) 444692f60a7Smrg * nAcl->PixelWidth)); 445692f60a7Smrg OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); 446692f60a7Smrg } 447692f60a7Smrg } 448692f60a7Smrg} 449692f60a7Smrg 450692f60a7Smrg#endif /* NOT_BROKEN */ 451692f60a7Smrg 452692f60a7Smrgstatic void 453692f60a7SmrgNeo2200SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop, 454692f60a7Smrg unsigned int planemask) 455692f60a7Smrg{ 456692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 457692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 458692f60a7Smrg 459692f60a7Smrg WAIT_ENGINE_IDLE(); 460692f60a7Smrg 461692f60a7Smrg /* set blt control */ 462692f60a7Smrg /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/ 463692f60a7Smrg OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16); 464692f60a7Smrg OUTREG(NEOREG_BLTCNTL, NEO_BC0_SRC_IS_FG | 465692f60a7Smrg NEO_BC3_SKIP_MAPPING | 466692f60a7Smrg NEO_BC3_DST_XY_ADDR | 467692f60a7Smrg NEO_BC3_SRC_XY_ADDR | neo2200Rop[rop]); 468692f60a7Smrg 469692f60a7Smrg /* set foreground color */ 470692f60a7Smrg OUTREG(NEOREG_FGCOLOR, color); 471692f60a7Smrg} 472692f60a7Smrg 473692f60a7Smrg 474692f60a7Smrgstatic void 475692f60a7SmrgNeo2200SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 476692f60a7Smrg{ 477692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 478692f60a7Smrg 479692f60a7Smrg WAIT_ENGINE_IDLE(); 480692f60a7Smrg OUTREG(NEOREG_DSTSTARTOFF, (y <<16) | (x & 0xffff)); 481692f60a7Smrg OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); 482692f60a7Smrg} 483692f60a7Smrg 484692f60a7Smrgstatic void 485692f60a7SmrgNeo2200SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 486692f60a7Smrg int fg, int bg, 487692f60a7Smrg int rop, 488692f60a7Smrg unsigned int planemask) 489692f60a7Smrg{ 490692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 491692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 492692f60a7Smrg 493692f60a7Smrg if (bg == -1) { 494692f60a7Smrg /* transparent setup */ 495692f60a7Smrg nAcl->tmpBltCntlFlags = ( NEO_BC0_SYS_TO_VID | 496692f60a7Smrg NEO_BC0_SRC_MONO | 497692f60a7Smrg NEO_BC0_SRC_TRANS | 498692f60a7Smrg NEO_BC3_SKIP_MAPPING | 499692f60a7Smrg NEO_BC3_DST_XY_ADDR | 500692f60a7Smrg#ifdef NEO_DO_CLIPPING 501692f60a7Smrg NEO_BC3_CLIP_ON | 502692f60a7Smrg#endif 503692f60a7Smrg neo2200Rop[rop]); 504692f60a7Smrg 505692f60a7Smrg WAIT_ENGINE_IDLE(); 506692f60a7Smrg /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/ 507692f60a7Smrg OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16); 508692f60a7Smrg OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags); 509692f60a7Smrg OUTREG(NEOREG_FGCOLOR, fg); 510692f60a7Smrg } 511692f60a7Smrg else { 512692f60a7Smrg /* opaque setup */ 513692f60a7Smrg nAcl->tmpBltCntlFlags = ( NEO_BC0_SYS_TO_VID | 514692f60a7Smrg NEO_BC0_SRC_MONO | 515692f60a7Smrg NEO_BC3_SKIP_MAPPING | 516692f60a7Smrg NEO_BC3_DST_XY_ADDR | 517692f60a7Smrg#ifdef NEO_DO_CLIPPING 518692f60a7Smrg NEO_BC3_CLIP_ON | 519692f60a7Smrg#endif 520692f60a7Smrg neo2200Rop[rop]); 521692f60a7Smrg 522692f60a7Smrg WAIT_ENGINE_IDLE(); 523692f60a7Smrg /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/ 524692f60a7Smrg OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16); 525692f60a7Smrg OUTREG(NEOREG_FGCOLOR, fg); 526692f60a7Smrg OUTREG(NEOREG_BGCOLOR, bg); 527692f60a7Smrg } 528692f60a7Smrg} 529692f60a7Smrg 530692f60a7Smrg 531692f60a7Smrgstatic void 532692f60a7SmrgNeo2200SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 533692f60a7Smrg int x, int y, 534692f60a7Smrg int w, int h, 535692f60a7Smrg int skipleft) 536692f60a7Smrg{ 537692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 538692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 539692f60a7Smrg 540692f60a7Smrg#ifdef NEO_DO_CLIPPING 541692f60a7Smrg w = (w + 31) & ~31; 542692f60a7Smrg#else 543692f60a7Smrg nAcl->CPUToScreenColorExpandFill_x = x; 544692f60a7Smrg nAcl->CPUToScreenColorExpandFill_y = y; 545692f60a7Smrg nAcl->CPUToScreenColorExpandFill_w = w; 546692f60a7Smrg nAcl->CPUToScreenColorExpandFill_h = h; 547692f60a7Smrg nAcl->CPUToScreenColorExpandFill_skipleft = skipleft; 548692f60a7Smrg#endif 549692f60a7Smrg OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags 550692f60a7Smrg | ((skipleft << 2) & 0x1C)); 551692f60a7Smrg#ifdef NEO_DO_CLIPPING 552692f60a7Smrg OUTREG(NEOREG_CLIPLT, (y << 16) | (x + skipleft)); 553692f60a7Smrg OUTREG(NEOREG_CLIPRB, ((y + h) << 16) | (x + w)); 554692f60a7Smrg#endif 555692f60a7Smrg OUTREG(NEOREG_SRCSTARTOFF, 0); 556692f60a7Smrg OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff)); 557692f60a7Smrg#ifdef NEO_DO_CLIPPING 558692f60a7Smrg OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); 559692f60a7Smrg#else 560692f60a7Smrg OUTREG(NEOREG_XYEXT, (1<<16) | (w & 0xffff)); 561692f60a7Smrg#endif 562692f60a7Smrg} 563692f60a7Smrg 564692f60a7Smrgstatic void 565692f60a7SmrgNeo2200SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 566692f60a7Smrg{ 567692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 568692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 569692f60a7Smrg 570692f60a7Smrg#ifdef NEO_DO_CLIPPING 571692f60a7Smrg /* Should I be waiting for fifo slots to prevent retries ? 572692f60a7Smrg How do I do that on this engine ? */ 573692f60a7Smrg#else 574692f60a7Smrg if (!(--nAcl->CPUToScreenColorExpandFill_h)) 575692f60a7Smrg return; 576692f60a7Smrg 577692f60a7Smrg WAIT_ENGINE_IDLE(); 578692f60a7Smrg OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags 579692f60a7Smrg | ((nAcl->CPUToScreenColorExpandFill_skipleft << 2) & 0x1C)); 580692f60a7Smrg OUTREG(NEOREG_SRCSTARTOFF, 0); 581692f60a7Smrg OUTREG(NEOREG_DSTSTARTOFF, ((++nAcl->CPUToScreenColorExpandFill_y)<<16) 582692f60a7Smrg | (nAcl->CPUToScreenColorExpandFill_x & 0xffff)); 583692f60a7Smrg OUTREG(NEOREG_XYEXT, (1<<16) 584692f60a7Smrg | (nAcl->CPUToScreenColorExpandFill_w & 0xffff)); 585692f60a7Smrg#endif 586692f60a7Smrg} 587692f60a7Smrg 588692f60a7Smrg#if 0 589692f60a7Smrgstatic void 590692f60a7SmrgNeo2200SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, 591692f60a7Smrg int patternx, 592692f60a7Smrg int patterny, 593692f60a7Smrg int fg, int bg, 594692f60a7Smrg int rop, unsigned int planemask) 595692f60a7Smrg{ 596692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 597692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 598692f60a7Smrg 599692f60a7Smrg if (bg == -1) { 600692f60a7Smrg /* transparent setup */ 601692f60a7Smrg nAcl->tmpBltCntlFlags = ( NEO_BC0_SRC_MONO | 602692f60a7Smrg NEO_BC0_FILL_PAT | 603692f60a7Smrg NEO_BC0_SRC_TRANS | 604692f60a7Smrg NEO_BC3_SKIP_MAPPING | 605692f60a7Smrg NEO_BC3_DST_XY_ADDR | 606692f60a7Smrg neo2200Rop[rop]); 607692f60a7Smrg 608692f60a7Smrg WAIT_ENGINE_IDLE(); 609692f60a7Smrg /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/ 610692f60a7Smrg OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16); 611692f60a7Smrg OUTREG(NEOREG_FGCOLOR, fg); 612692f60a7Smrg OUTREG(NEOREG_SRCSTARTOFF, 613692f60a7Smrg (patterny * pScrn->displayWidth * pScrn->bitsPerPixel 614692f60a7Smrg + patternx) >> 3); 615692f60a7Smrg } 616692f60a7Smrg else { 617692f60a7Smrg /* opaque setup */ 618692f60a7Smrg nAcl->tmpBltCntlFlags = ( NEO_BC0_SRC_MONO | 619692f60a7Smrg NEO_BC0_FILL_PAT | 620692f60a7Smrg NEO_BC3_SKIP_MAPPING | 621692f60a7Smrg NEO_BC3_DST_XY_ADDR | 622692f60a7Smrg neo2200Rop[rop]); 623692f60a7Smrg 624692f60a7Smrg WAIT_ENGINE_IDLE(); 625692f60a7Smrg /*OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);*/ 626692f60a7Smrg OUTREG(NEOREG_BLTSTAT, nAcl->BltModeFlags << 16); 627692f60a7Smrg OUTREG(NEOREG_FGCOLOR, fg); 628692f60a7Smrg OUTREG(NEOREG_BGCOLOR, bg); 629692f60a7Smrg OUTREG(NEOREG_SRCSTARTOFF, 630692f60a7Smrg (patterny * pScrn->displayWidth * pScrn->bitsPerPixel 631692f60a7Smrg + patternx) >> 3); 632692f60a7Smrg } 633692f60a7Smrg} 634692f60a7Smrg 635692f60a7Smrg 636692f60a7Smrgstatic void 637692f60a7SmrgNeo2200SubsequentMono8x8PatternFill(ScrnInfoPtr pScrn, 638692f60a7Smrg int patternx, 639692f60a7Smrg int patterny, 640692f60a7Smrg int x, int y, 641692f60a7Smrg int w, int h) 642692f60a7Smrg{ 643692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 644692f60a7Smrg NEOACLPtr nAcl = NEOACLPTR(pScrn); 645692f60a7Smrg 646692f60a7Smrg patterny &= 0x7; 647692f60a7Smrg 648692f60a7Smrg WAIT_ENGINE_IDLE(); 649692f60a7Smrg OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags | 650692f60a7Smrg (patterny << 20) | 651692f60a7Smrg ((patternx << 10) & 0x1C00)); 652692f60a7Smrg OUTREG(NEOREG_SRCBITOFF, patternx); 653692f60a7Smrg OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff)); 654692f60a7Smrg OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff)); 655692f60a7Smrg} 656692f60a7Smrg#endif 6573f6d0e1dSmrg#endif 658