1 2/************************************************************************** 3 4Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 5All Rights Reserved. 6 7Permission is hereby granted, free of charge, to any person obtaining a 8copy of this software and associated documentation files (the 9"Software"), to deal in the Software without restriction, including 10without limitation the rights to use, copy, modify, merge, publish, 11distribute, sub license, and/or sell copies of the Software, and to 12permit persons to whom the Software is furnished to do so, subject to 13the following conditions: 14 15The above copyright notice and this permission notice (including the 16next paragraph) shall be included in all copies or substantial portions 17of the Software. 18 19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 23ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 27**************************************************************************/ 28 29/* 30 * Authors: 31 * Daryll Strauss <daryll@precisioninsight.com> 32 * 33 */ 34 35#ifdef HAVE_CONFIG_H 36#include "config.h" 37#endif 38 39#include "xf86.h" 40#include "xf86_OSproc.h" 41 42#include "compiler.h" 43 44#include "xf86Pci.h" 45 46#include "vgaHW.h" 47 48#include "xf86xv.h" 49#include "i740.h" 50 51#ifdef HAVE_XAA_H 52static unsigned int i740Rop[16] = { 53 0x00, /* GXclear */ 54 0x88, /* GXand */ 55 0x44, /* GXandReverse */ 56 0xCC, /* GXcopy */ 57 0x22, /* GXandInvert */ 58 0xAA, /* GXnoop */ 59 0x66, /* GXxor */ 60 0xEE, /* GXor */ 61 0x11, /* GXnor */ 62 0x99, /* GXequiv */ 63 0x55, /* GXinvert */ 64 0xDD, /* GXorReverse */ 65 0x33, /* GXcopyInvert */ 66 0xBB, /* GXorInverted */ 67 0x77, /* GXnand */ 68 0xFF /* GXset */ 69}; 70 71static unsigned int i740PatternRop[16] = { 72 0x00, /* GXclear */ 73 0xA0, /* GXand */ 74 0x50, /* GXandReverse */ 75 0xF0, /* GXcopy */ 76 0x0A, /* GXandInvert */ 77 0xAA, /* GXnoop */ 78 0x5A, /* GXxor */ 79 0xFA, /* GXor */ 80 0x05, /* GXnor */ 81 0xA5, /* GXequiv */ 82 0x55, /* GXinvert */ 83 0xF5, /* GXorReverse */ 84 0x0F, /* GXcopyInvert */ 85 0xAF, /* GXorInverted */ 86 0x5F, /* GXnand */ 87 0xFF /* GXset */ 88}; 89 90static void I740SyncPIO(ScrnInfoPtr pScrn); 91static void I740SyncMMIO(ScrnInfoPtr pScrn); 92static void I740SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 93 unsigned int planemask); 94static void I740SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, 95 int w, int h); 96static void I740SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, 97 int ydir, int rop, 98 unsigned int planemask, 99 int transparency_color); 100static void I740SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, 101 int x2, int y2, int w, int h); 102static void I740SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, 103 int pattx, int patty, 104 int fg, int bg, int rop, 105 unsigned int planemask); 106static void I740SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, 107 int pattx, int patty, 108 int x, int y, int w, int h); 109#if 0 110static void I740SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 111 int bg, int fg, int rop, 112 unsigned int planemask); 113static void I740SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 114 int x, int y, int w, int h, 115 int skipleft); 116#endif 117#endif 118/* 119 * The following function sets up the supported acceleration. Call it 120 * from the FbInit() function in the SVGA driver, or before ScreenInit 121 * in a monolithic server. 122 */ 123Bool 124I740AccelInit(ScreenPtr pScreen) { 125#ifdef HAVE_XAA_H 126 XAAInfoRecPtr infoPtr; 127 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 128 I740Ptr pI740 = I740PTR(pScrn); 129 130 pI740->AccelInfoRec = infoPtr = XAACreateInfoRec(); 131 if (!infoPtr) return FALSE; 132 133 if (pScrn->bitsPerPixel == 32) { 134 infoPtr->Flags = 0; /* Disables all acceleration */ 135 return TRUE;; 136 } 137 138 infoPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER; 139 140 /* Sync */ 141 if (pI740->usePIO) 142 infoPtr->Sync = I740SyncPIO; 143 else 144 infoPtr->Sync = I740SyncMMIO; 145 146 infoPtr->CachePixelGranularity=8/pI740->cpp; 147 148 /* Solid filled rectangles */ 149 infoPtr->SolidFillFlags = NO_PLANEMASK; 150 infoPtr->SetupForSolidFill = I740SetupForSolidFill; 151 infoPtr->SubsequentSolidFillRect = I740SubsequentSolidFillRect; 152 153 /* Screen to screen copy */ 154 infoPtr->ScreenToScreenCopyFlags = (NO_PLANEMASK | NO_TRANSPARENCY); 155 infoPtr->SetupForScreenToScreenCopy = I740SetupForScreenToScreenCopy; 156 infoPtr->SubsequentScreenToScreenCopy = I740SubsequentScreenToScreenCopy; 157 158 /* 8x8 pattern fills */ 159 infoPtr->SetupForMono8x8PatternFill = I740SetupForMono8x8PatternFill; 160 infoPtr->SubsequentMono8x8PatternFillRect = I740SubsequentMono8x8PatternFillRect; 161 infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | HARDWARE_PATTERN_SCREEN_ORIGIN | 162 BIT_ORDER_IN_BYTE_MSBFIRST; 163 164 /* CPU to screen color expansion */ 165 /* Currently XAA is limited to only DWORD padding. The 3.3 driver 166 * uses NO_PAD scanlines b/c of problems with using the chip in 167 * DWORD mode. Once other padding modes are available in XAA this 168 * Code can be turned back on. 169 */ 170#if 0 171#ifndef ALLOW_PCI_COLOR_EXP 172 if (pI740->Chipset != PCI_CHIP_I740_PCI) { 173#endif 174 /* 175 * Currently, we are not properly able to read the bitblt engine 176 * busy bit on the PCI i740 card. When we are able to do so, we 177 * can re-enable color expansion. 178 */ 179 infoPtr->CPUToScreenColorExpandFillFlags = 180 NO_PLANEMASK | 181#ifdef USE_DWORD_COLOR_EXP 182 SCANLINE_PAD_DWORD | 183#endif 184 CPU_TRANSFER_PAD_QWORD | 185 SYNC_AFTER_COLOR_EXPAND | 186 BIT_ORDER_IN_BYTE_MSBFIRST; 187 infoPtr->ColorExpandBase = (unsigned char *)(pI740->MMIOBase + BLTDATA); 188 infoPtr->ColorExpandRange = 0x10000; 189 infoPtr->SetupForCPUToScreenColorExpandFill = I740SetupForCPUToScreenColorExpandFill; 190 infoPtr->SubsequentCPUToScreenColorExpandFill = I740SubsequentCPUToScreenColorExpandFill; 191#ifndef ALLOW_PCI_COLOR_EXP 192 } 193#endif 194#endif 195 return XAAInit(pScreen, infoPtr); 196#else 197 return FALSE; 198#endif 199} 200 201#ifdef HAVE_XAA_H 202 203static void 204I740SyncPIO(ScrnInfoPtr pScrn) { 205 WAIT_ENGINE_IDLE_PIO(); 206} 207 208static void 209I740SyncMMIO(ScrnInfoPtr pScrn) { 210 I740Ptr pI740; 211 212 pI740 = I740PTR(pScrn); 213 WAIT_ENGINE_IDLE_MMIO(); 214} 215 216static void 217I740SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 218 unsigned int planemask) { 219 I740Ptr pI740; 220 221 pI740 = I740PTR(pScrn); 222 223 pI740->bltcmd.BR00 = ((pScrn->displayWidth * pI740->cpp) << 16) | 224 (pScrn->displayWidth * pI740->cpp); 225 pI740->bltcmd.BR01 = color; 226 pI740->bltcmd.BR04 = SOLID_PAT_SELECT | PAT_IS_MONO | i740PatternRop[rop]; 227} 228 229static void 230I740SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) { 231 I740Ptr pI740; 232 233 pI740 = I740PTR(pScrn); 234 WAIT_LP_FIFO(12); 235 OUTREG(LP_FIFO, 0x6000000A); 236 OUTREG(LP_FIFO, pI740->bltcmd.BR00); 237 OUTREG(LP_FIFO, pI740->bltcmd.BR01); 238 OUTREG(LP_FIFO, 0x00000000); 239 OUTREG(LP_FIFO, 0x00000000); 240 OUTREG(LP_FIFO, pI740->bltcmd.BR04); 241 OUTREG(LP_FIFO, 0x00000000); 242 OUTREG(LP_FIFO, 0x00000000); 243 OUTREG(LP_FIFO, (y * pScrn->displayWidth + x) * pI740->cpp); 244 OUTREG(LP_FIFO, 0x00000000); 245 OUTREG(LP_FIFO, 0x00000000); 246 OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp)); 247} 248 249static void 250I740SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, 251 unsigned int planemask, int transparency_color) 252{ 253 I740Ptr pI740; 254 255 pI740 = I740PTR(pScrn); 256 pI740->bltcmd.BR00 = (((pScrn->displayWidth * pI740->cpp) << 16) | 257 (pScrn->displayWidth * pI740->cpp)); 258 259 pI740->bltcmd.BR04 = SRC_IS_IN_COLOR | SRC_USE_SRC_ADDR | i740Rop[rop]; 260 if (xdir == -1) 261 pI740->bltcmd.BR04 |= BLT_RIGHT_TO_LEFT; 262 else 263 pI740->bltcmd.BR04 |= BLT_LEFT_TO_RIGHT; 264 265 if (ydir == -1) 266 pI740->bltcmd.BR04 |= BLT_BOT_TO_TOP; 267 else 268 pI740->bltcmd.BR04 |= BLT_TOP_TO_BOT; 269 270 pI740->bltcmd.BR01 = 0x00000000; 271 272} 273 274static void 275I740SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, 276 int x2, int y2, int w, int h) { 277 I740Ptr pI740; 278 279 pI740 = I740PTR(pScrn); 280 if (pI740->bltcmd.BR04 & BLT_BOT_TO_TOP) { 281 pI740->bltcmd.BR06 = (y1 + h - 1) * 282 pScrn->displayWidth * pI740->cpp; 283 pI740->bltcmd.BR07 = (y2 + h - 1) * 284 pScrn->displayWidth * pI740->cpp; 285 } else { 286 pI740->bltcmd.BR06 = y1 * pScrn->displayWidth * pI740->cpp; 287 pI740->bltcmd.BR07 = y2 * pScrn->displayWidth * pI740->cpp; 288 } 289 290 if (pI740->bltcmd.BR04 & BLT_RIGHT_TO_LEFT) { 291 pI740->bltcmd.BR06 += (x1 + w - 1) * pI740->cpp + pI740->cpp - 1; 292 pI740->bltcmd.BR07 += (x2 + w - 1) * pI740->cpp + pI740->cpp - 1; 293 } else { 294 pI740->bltcmd.BR06 += x1 * pI740->cpp; 295 pI740->bltcmd.BR07 += x2 * pI740->cpp; 296 } 297 298 WAIT_LP_FIFO(12); 299 OUTREG(LP_FIFO, 0x6000000A); 300 OUTREG(LP_FIFO, pI740->bltcmd.BR00); 301 OUTREG(LP_FIFO, pI740->bltcmd.BR01); 302 OUTREG(LP_FIFO, 0x00000000); 303 OUTREG(LP_FIFO, 0x00000000); 304 OUTREG(LP_FIFO, pI740->bltcmd.BR04); 305 OUTREG(LP_FIFO, 0x00000000); 306 OUTREG(LP_FIFO, pI740->bltcmd.BR06); 307 OUTREG(LP_FIFO, pI740->bltcmd.BR07); 308 OUTREG(LP_FIFO, 0x00000000); 309 OUTREG(LP_FIFO, 0x00000000); 310 OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp)); 311} 312 313static void 314I740SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty, 315 int fg, int bg, int rop, 316 unsigned int planemask) { 317 I740Ptr pI740; 318 319 pI740 = I740PTR(pScrn); 320 pI740->bltcmd.BR00 = ((pScrn->displayWidth * pI740->cpp) << 16) | 321 (pScrn->displayWidth * pI740->cpp); 322 323 pI740->bltcmd.BR01 = bg; 324 pI740->bltcmd.BR02 = fg; 325 326 pI740->bltcmd.BR04 = PAT_IS_MONO | i740PatternRop[rop]; 327 if (bg == -1) pI740->bltcmd.BR04 |= MONO_PAT_TRANSP; 328 329 pI740->bltcmd.BR05 = (pattx + patty * pScrn->displayWidth) * pI740->cpp; 330} 331 332static void 333I740SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty, 334 int x, int y, int w, int h) { 335 I740Ptr pI740; 336 337 pI740 = I740PTR(pScrn); 338 WAIT_LP_FIFO(12); 339 OUTREG(LP_FIFO, 0x6000000A); 340 OUTREG(LP_FIFO, pI740->bltcmd.BR00); 341 OUTREG(LP_FIFO, pI740->bltcmd.BR01); 342 OUTREG(LP_FIFO, pI740->bltcmd.BR02); 343 OUTREG(LP_FIFO, 0x00000000); 344 OUTREG(LP_FIFO, pI740->bltcmd.BR04 | ((y<<20) & PAT_VERT_ALIGN)); 345 OUTREG(LP_FIFO, pI740->bltcmd.BR05); 346 OUTREG(LP_FIFO, 0x00000000); 347 OUTREG(LP_FIFO, (y * pScrn->displayWidth + x) * pI740->cpp); 348 OUTREG(LP_FIFO, 0x00000000); 349 OUTREG(LP_FIFO, 0x00000000); 350 OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp)); 351} 352#if 0 353static void 354I740SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int bg, int fg, 355 int rop, unsigned int planemask) { 356 I740Ptr pI740; 357 358 pI740 = I740PTR(pScrn); 359 pI740->bltcmd.BR00 = (pScrn->displayWidth * pI740->cpp) << 16; 360 pI740->bltcmd.BR01 = bg; 361 pI740->bltcmd.BR02 = fg; 362#ifdef USE_DWORD_COLOR_EXP 363 pI740->bltcmd.BR03 = MONO_DWORD_ALIGN | MONO_USE_COLEXP; 364#else 365 pI740->bltcmd.BR03 = MONO_BIT_ALIGN | MONO_USE_COLEXP; 366#endif 367 pI740->bltcmd.BR04 = SRC_IS_MONO | SRC_USE_BLTDATA | i740Rop[rop]; 368 if (bg == -1) pI740->bltcmd.BR04 |= MONO_SRC_TRANSP; 369} 370 371static void 372I740SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y, 373 int w, int h, int skipleft) { 374 I740Ptr pI740; 375 376 pI740 = I740PTR(pScrn); 377 pI740->AccelInfoRec->Sync(pScrn); 378 OUTREG(LP_FIFO, 0x6000000A); 379 OUTREG(LP_FIFO, pI740->bltcmd.BR00); 380 OUTREG(LP_FIFO, pI740->bltcmd.BR01); 381 OUTREG(LP_FIFO, pI740->bltcmd.BR02); 382 OUTREG(LP_FIFO, pI740->bltcmd.BR03 | (skipleft & MONO_SRC_LEFT_CLIP)); 383 OUTREG(LP_FIFO, pI740->bltcmd.BR04); 384 OUTREG(LP_FIFO, 0x00000000); 385 OUTREG(LP_FIFO, 0x00000000); 386 OUTREG(LP_FIFO, (y * pScrn->displayWidth + x) * pI740->cpp); 387 OUTREG(LP_FIFO, 0x00000000); 388 OUTREG(LP_FIFO, 0x00000000); 389#ifdef USE_DWORD_COLOR_EXP 390 /* 391 * This extra wait is necessary to keep the bitblt engine from 392 * locking up, but I am not sure why it is needed. If we take it 393 * out, "x11perf -copyplane10" will lock the bitblt engine. When 394 * the bitblt engine is locked, it is waiting for mono data to be 395 * written to the BLTDATA region, which seems to imply that some of 396 * the data that was written was lost. This might be fixed by 397 * BLT_SKEW changes. Update: The engine still locks up with this 398 * extra wait. More investigation (and time) is needed. 399 */ 400 WAIT_BLT_IDLE(); 401#endif 402 OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp)); 403} 404#endif 405 406#endif 407