1/* 2 * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. 3 * 4 * Permission to use, copy, modify, distribute, and sell this software 5 * and its documentation for any purpose is hereby granted without 6 * fee, provided that the above copyright notice appear in all copies 7 * and that both that copyright notice and this permission notice 8 * appear in supporting documentation, and that the name of Alan 9 * Hourihane not be used in advertising or publicity pertaining to 10 * distribution of the software without specific, written prior 11 * permission. Alan Hourihane makes no representations about the 12 * suitability of this software for any purpose. It is provided 13 * "as is" without express or implied warranty. 14 * 15 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 16 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 17 * FITNESS, IN NO EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY 18 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 20 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 21 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 22 * SOFTWARE. 23 * 24 * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> 25 * 26 * BladeXP accelerated options. 27 */ 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#include "xf86.h" 34#include "xf86_OSproc.h" 35 36#include "xf86Pci.h" 37 38#include "miline.h" 39 40#include "trident.h" 41#include "trident_regs.h" 42 43#ifdef HAVE_XAA_H 44#include "xaarop.h" 45 46static void XPSync(ScrnInfoPtr pScrn); 47#if 0 48static void XPSetupForDashedLine(ScrnInfoPtr pScrn, 49 int fg, int bg, 50 int rop, 51 unsigned int planemask, 52 int length, 53 unsigned char *pattern); 54static void XPSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, 55 int x, int y, 56 int dmaj, int dmin, 57 int e, int len, 58 int octant, int phase); 59static void XPSetupForSolidLine(ScrnInfoPtr pScrn, 60 int color, 61 int rop, 62 unsigned int planemask); 63static void XPSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, 64 int x, int y, 65 int dmaj, int dmin, 66 int e, int len, 67 int octant); 68#endif 69static void XPSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, 70 int x, int y, 71 int len, int dir); 72static void XPSetupForFillRectSolid(ScrnInfoPtr pScrn, 73 int color, 74 int rop, 75 unsigned int planemask); 76static void XPSubsequentFillRectSolid(ScrnInfoPtr pScrn, 77 int x, int y, 78 int w, int h); 79static void XPSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 80 int x1, int y1, 81 int x2, int y2, 82 int w, int h); 83static void XPSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, 84 int xdir, int ydir, 85 int rop, 86 unsigned int planemask, 87 int transparency_color); 88static void XPSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, 89 int patternx, 90 int patterny, 91 int fg, int bg, 92 int rop, 93 unsigned int planemask); 94static void XPSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, 95 int patternx, 96 int patterny, 97 int x, int y, 98 int w, int h); 99#if 0 100static void XPSetupForScanlineCPUToScreenColorExpandFill( 101 ScrnInfoPtr pScrn, 102 int fg, int bg, 103 int rop, 104 unsigned int planemask); 105static void XPSubsequentScanlineCPUToScreenColorExpandFill( 106 ScrnInfoPtr pScrn, 107 int x, int y, 108 int w, int h, 109 int skipleft); 110static void XPSubsequentColorExpandScanline(ScrnInfoPtr pScrn, 111 int bufno); 112#endif 113 114static void 115XPInitializeAccelerator(ScrnInfoPtr pScrn) 116{ 117 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 118 int shift; 119 120 /* This forces updating the clipper */ 121 pTrident->Clipping = TRUE; 122 123 CHECKCLIPPING; 124 125 BLADE_XP_OPERMODE(pTrident->EngineOperation); 126 pTrident->EngineOperation |= 0x40; 127 switch (pScrn->bitsPerPixel) { 128 case 8: 129 default: /* Muffle compiler */ 130 shift = 18; 131 break; 132 case 16: 133 shift = 19; 134 break; 135 case 32: 136 shift = 20; 137 break; 138 } 139 140 MMIO_OUT32(pTrident->IOBase, 0x2154, 141 (pScrn->displayWidth) << shift); 142 MMIO_OUT32(pTrident->IOBase, 0x2150, 143 (pScrn->displayWidth) << shift); 144 MMIO_OUT8(pTrident->IOBase, 0x2126, 3); 145} 146#endif 147 148Bool XPAccelInit(ScreenPtr pScreen) { 149#ifdef HAVE_XAA_H 150 XAAInfoRecPtr infoPtr; 151 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 152 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 153 154 if (pTrident->NoAccel) 155 return FALSE; 156 157 pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec(); 158 if (!infoPtr) return FALSE; 159 160 infoPtr->Flags = PIXMAP_CACHE | 161 OFFSCREEN_PIXMAPS | 162 LINEAR_FRAMEBUFFER; 163 164 pTrident->InitializeAccelerator = XPInitializeAccelerator; 165 XPInitializeAccelerator(pScrn); 166 167 infoPtr->Sync = XPSync; 168 169#if 0 /* TO DO for the XP */ 170 infoPtr->SolidLineFlags = NO_PLANEMASK; 171 infoPtr->SetupForSolidLine = XPSetupForSolidLine; 172 infoPtr->SolidBresenhamLineErrorTermBits = 12; 173 infoPtr->SubsequentSolidBresenhamLine = 174 XPSubsequentSolidBresenhamLine; 175 176 infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | 177 NO_PLANEMASK | 178 LINE_PATTERN_POWER_OF_2_ONLY; 179 infoPtr->SetupForDashedLine = XPSetupForDashedLine; 180 infoPtr->DashedBresenhamLineErrorTermBits = 12; 181 infoPtr->SubsequentDashedBresenhamLine = 182 XPSubsequentDashedBresenhamLine; 183 infoPtr->DashPatternMaxLength = 16; 184#endif 185 186 infoPtr->SolidFillFlags = NO_PLANEMASK; 187 infoPtr->SetupForSolidFill = XPSetupForFillRectSolid; 188 infoPtr->SubsequentSolidFillRect = XPSubsequentFillRectSolid; 189 infoPtr->SubsequentSolidHorVertLine = XPSubsequentSolidHorVertLine; 190 191 infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | 192 NO_TRANSPARENCY; 193 194 infoPtr->SetupForScreenToScreenCopy = 195 XPSetupForScreenToScreenCopy; 196 infoPtr->SubsequentScreenToScreenCopy = 197 XPSubsequentScreenToScreenCopy; 198 199 infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | 200 HARDWARE_PATTERN_PROGRAMMED_BITS | 201 BIT_ORDER_IN_BYTE_MSBFIRST; 202 203 infoPtr->SetupForMono8x8PatternFill = 204 XPSetupForMono8x8PatternFill; 205 infoPtr->SubsequentMono8x8PatternFillRect = 206 XPSubsequentMono8x8PatternFillRect; 207 208#if 0 /* Needs fixing */ 209 infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | 210 BIT_ORDER_IN_BYTE_MSBFIRST; 211 212 pTrident->XAAScanlineColorExpandBuffers[0] = 213 xnfalloc(((pScrn->virtualX + 63)) * 214 4 * (pScrn->bitsPerPixel / 8)); 215 216 infoPtr->NumScanlineColorExpandBuffers = 1; 217 infoPtr->ScanlineColorExpandBuffers = 218 pTrident->XAAScanlineColorExpandBuffers; 219 220 infoPtr->SetupForScanlineCPUToScreenColorExpandFill = 221 XPSetupForScanlineCPUToScreenColorExpandFill; 222 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = 223 XPSubsequentScanlineCPUToScreenColorExpandFill; 224 infoPtr->SubsequentColorExpandScanline = 225 XPSubsequentColorExpandScanline; 226#endif 227 228 return(XAAInit(pScreen, infoPtr)); 229#else 230 return FALSE; 231#endif 232} 233 234#ifdef HAVE_XAA_H 235static void 236XPSync(ScrnInfoPtr pScrn) 237{ 238 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 239 int count = 0, timeout = 0; 240 int busy; 241 242 BLADE_XP_OPERMODE(pTrident->EngineOperation); 243 244 for (;;) { 245 BLTBUSY(busy); 246 if (busy != GE_BUSY) { 247 return; 248 } 249 250 count++; 251 if (count == 10000000) { 252 ErrorF("XP: BitBLT engine time-out.\n"); 253 count = 9990000; 254 timeout++; 255 if (timeout == 8) { 256 /* 257 * Reset BitBLT Engine. 258 */ 259 TGUI_STATUS(0x00); 260 return; 261 } 262 } 263 } 264} 265 266static void 267XPClearSync(ScrnInfoPtr pScrn) 268{ 269 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 270 int count = 0, timeout = 0; 271 int busy; 272 273 for (;;) { 274 BLTBUSY(busy); 275 if (busy != GE_BUSY) { 276 return; 277 } 278 279 count++; 280 if (count == 10000000) { 281 ErrorF("XP: BitBLT engine time-out.\n"); 282 count = 9990000; 283 timeout++; 284 if (timeout == 8) { 285 /* 286 * Reset BitBLT Engine. 287 */ 288 TGUI_STATUS(0x00); 289 return; 290 } 291 } 292 } 293} 294 295static void 296XPSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, 297 int xdir, int ydir, 298 int rop, 299 unsigned int planemask, 300 int transparency_color) 301{ 302 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 303 int dst = 0; 304 305 pTrident->BltScanDirection = 0; 306 if (xdir < 0) pTrident->BltScanDirection |= XNEG; 307 if (ydir < 0) pTrident->BltScanDirection |= YNEG; 308 309 REPLICATE(transparency_color); 310 if (transparency_color != -1) { 311 dst |= (3 << 16); 312 MMIO_OUT32(pTrident->IOBase, 0x2134, transparency_color); 313 } 314 315 TGUI_DRAWFLAG(pTrident->BltScanDirection | SCR2SCR | dst); 316 TGUI_FMIX(XAAGetCopyROP(rop)); 317} 318 319static void 320XPSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 321 int x1, int y1, 322 int x2, int y2, 323 int w, int h) 324{ 325 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 326 327 if (pTrident->BltScanDirection & YNEG) { 328 y1 = y1 + h - 1; 329 y2 = y2 + h - 1; 330 } 331 332 if (pTrident->BltScanDirection & XNEG) { 333 x1 = x1 + w - 1; 334 x2 = x2 + w - 1; 335 } 336 337 XP_SRC_XY(x1,y1); 338 XP_DEST_XY(x2,y2); 339 XP_DIM_XY(w,h); 340 TGUI_COMMAND(GE_BLT); 341 XPClearSync(pScrn); 342} 343 344#if 0 345static void 346XPSetupForSolidLine(ScrnInfoPtr pScrn, 347 int color, 348 int rop, 349 unsigned int planemask) 350{ 351 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 352 353 pTrident->BltScanDirection = 0; 354 REPLICATE(color); 355 TGUI_FMIX(XAAGetPatternROP(rop)); 356 if (pTrident->Chipset >= PROVIDIA9685) { 357 TGUI_FPATCOL(color); 358 } else { 359 TGUI_FCOLOUR(color); 360 } 361} 362 363static void 364XPSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, 365 int x, int y, 366 int dmaj, int dmin, 367 int e, int len, 368 int octant) 369{ 370 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 371 int tmp = pTrident->BltScanDirection; 372 373 if (octant & YMAJOR) tmp |= YMAJ; 374 if (octant & XDECREASING) tmp |= XNEG; 375 if (octant & YDECREASING) tmp |= YNEG; 376 TGUI_DRAWFLAG(SOLIDFILL | STENCIL | tmp); 377 XP_SRC_XY(dmin - dmaj, dmin); 378 XP_DEST_XY(x, y); 379 XP_DIM_XY(dmin + e, len); 380 TGUI_COMMAND(GE_BRESLINE); 381 XPSync(pScrn); 382} 383#endif 384 385static void 386XPSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, 387 int x, int y, 388 int len, int dir) 389{ 390 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 391 392 TGUI_DRAWFLAG(SOLIDFILL); 393 if (dir == DEGREES_0) { 394 XP_DIM_XY(len, 1); 395 XP_DEST_XY(x, y); 396 } else { 397 XP_DIM_XY(1, len); 398 XP_DEST_XY(x, y); 399 } 400 401 TGUI_COMMAND(GE_BLT); 402 XPSync(pScrn); 403} 404 405#if 0 406void 407XPSetupForDashedLine(ScrnInfoPtr pScrn, 408 int fg, int bg, 409 int rop, 410 unsigned int planemask, 411 int length, 412 unsigned char *pattern) 413{ 414 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 415 CARD32 *DashPattern = (CARD32*)pattern; 416 CARD32 NiceDashPattern = DashPattern[0]; 417 418 NiceDashPattern = *((CARD16 *)pattern) & ((1 << length) - 1); 419 switch(length) { 420 case 2: NiceDashPattern |= NiceDashPattern << 2; 421 case 4: NiceDashPattern |= NiceDashPattern << 4; 422 case 8: NiceDashPattern |= NiceDashPattern << 8; 423 } 424 425 pTrident->BltScanDirection = 0; 426 REPLICATE(fg); 427 if (pTrident->Chipset >= PROVIDIA9685) { 428 TGUI_FPATCOL(fg); 429 if (bg == -1) { 430 pTrident->BltScanDirection |= (1 << 12); 431 TGUI_BPATCOL(~fg); 432 } else { 433 REPLICATE(bg); 434 TGUI_BPATCOL(bg); 435 } 436 } else { 437 TGUI_FCOLOUR(fg); 438 if (bg == -1) { 439 pTrident->BltScanDirection |= (1 << 12); 440 TGUI_BCOLOUR(~fg); 441 } else { 442 REPLICATE(bg); 443 TGUI_BCOLOUR(bg); 444 } 445 } 446 447 TGUI_FMIX(XAAGetPatternROP(rop)); 448 pTrident->LinePattern = NiceDashPattern; 449} 450 451void 452XPSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, 453 int x, int y, 454 int dmaj, int dmin, 455 int e, int len, 456 int octant, int phase) 457{ 458 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 459 int tmp = pTrident->BltScanDirection; 460 461 if (octant & YMAJOR) tmp |= YMAJ; 462 if (octant & XDECREASING) tmp |= XNEG; 463 if (octant & YDECREASING) tmp |= YNEG; 464 465 TGUI_STYLE(((pTrident->LinePattern >> phase) | 466 (pTrident->LinePattern << (16 - phase))) & 467 0x0000FFFF); 468 TGUI_DRAWFLAG(STENCIL | tmp); 469 XP_SRC_XY(dmin - dmaj, dmin); 470 XP_DEST_XY(x, y); 471 XP_DIM_XY(e + dmin, len); 472 TGUI_COMMAND(GE_BRESLINE); 473 XPSync(pScrn); 474} 475#endif 476 477static void 478XPSetupForFillRectSolid(ScrnInfoPtr pScrn, 479 int color, 480 int rop, unsigned int planemask) 481{ 482 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 483 484 REPLICATE(color); 485 TGUI_FMIX(XAAGetPatternROP(rop)); 486 MMIO_OUT32(pTrident->IOBase, 0x2158, color); 487 TGUI_DRAWFLAG(SOLIDFILL); 488} 489 490static void 491XPSubsequentFillRectSolid(ScrnInfoPtr pScrn, 492 int x, int y, 493 int w, int h) 494{ 495 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 496 497 XP_DIM_XY(w, h); 498 XP_DEST_XY(x, y); 499 TGUI_COMMAND(GE_BLT); 500 XPSync(pScrn); 501} 502 503#if 0 504static void MoveDWORDS(register CARD32* dest, 505 register CARD32* src, 506 register int dwords) 507{ 508 while(dwords & ~0x03) { 509 *dest = *src; 510 *(dest + 1) = *(src + 1); 511 *(dest + 2) = *(src + 2); 512 *(dest + 3) = *(src + 3); 513 src += 4; 514 dest += 4; 515 dwords -= 4; 516 } 517 518 if (!dwords) return; 519 *dest = *src; 520 dest += 1; 521 src += 1; 522 if (dwords == 1) return; 523 *dest = *src; 524 dest += 1; 525 src += 1; 526 if (dwords == 2) return; 527 *dest = *src; 528 dest += 1; 529 src += 1; 530} 531#endif 532 533#if 0 534static void 535MoveDWORDS_FixedBase(register CARD32* dest, 536 register CARD32* src, 537 register int dwords) 538{ 539 while(dwords & ~0x03) { 540 *dest = *src; 541 *dest = *(src + 1); 542 *dest = *(src + 2); 543 *dest = *(src + 3); 544 dwords -= 4; 545 src += 4; 546 } 547 548 if(!dwords) return; 549 *dest = *src; 550 if(dwords == 1) return; 551 *dest = *(src + 1); 552 if(dwords == 2) return; 553 *dest = *(src + 2); 554} 555#endif 556 557static void 558XPSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, 559 int patternx, int patterny, 560 int fg, int bg, 561 int rop, 562 unsigned int planemask) 563{ 564 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 565 int drawflag = 0; 566 567 REPLICATE(fg); 568 MMIO_OUT32(pTrident->IOBase, 0x2158, fg); 569 570 if (bg == -1) { 571 drawflag |= (1 << 12); 572 MMIO_OUT32(pTrident->IOBase, 0x215C, ~fg); 573 } else { 574 REPLICATE(bg); 575 MMIO_OUT32(pTrident->IOBase, 0x215C, bg); 576 } 577 578 drawflag |= (7 << 18); 579 TGUI_DRAWFLAG(PATMONO | drawflag); 580 MMIO_OUT32(pTrident->IOBase, 0x2180, patternx); 581 MMIO_OUT32(pTrident->IOBase, 0x2184, patterny); 582 TGUI_FMIX(XAAGetPatternROP(rop)); 583} 584 585static void 586XPSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, 587 int patternx, int patterny, 588 int x, int y, 589 int w, int h) 590{ 591 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 592 593 XP_DEST_XY(x, y); 594 XP_DIM_XY(w, h); 595 TGUI_COMMAND(GE_BLT); 596 XPSync(pScrn); 597} 598 599#if 0 600static void 601XPSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 602 int fg, int bg, 603 int rop, 604 unsigned int planemask) 605{ 606 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 607 608 TGUI_FMIX(XAAGetCopyROP(rop)); 609 if (bg == -1) { 610 TGUI_DRAWFLAG(SRCMONO | (1 << 12)); 611 REPLICATE(fg); 612 TGUI_FCOLOUR(fg); 613 } else { 614 TGUI_DRAWFLAG(SRCMONO); 615 REPLICATE(fg); 616 REPLICATE(bg); 617 TGUI_FCOLOUR(fg); 618 TGUI_BCOLOUR(bg); 619 } 620} 621 622static void 623XPSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 624 int x, int y, 625 int w, int h, 626 int skipleft) 627{ 628 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 629 pTrident->dwords = (w + 31) >> 5; 630 pTrident->h = h; 631 632 XP_DEST_XY(x, y); 633 XP_DIM_XY(w >> 1, h); 634 TGUI_COMMAND(GE_BLT); 635} 636 637static void 638XPSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 639{ 640 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 641 XAAInfoRecPtr infoRec; 642 infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 643 644 MoveDWORDS_FixedBase((CARD32 *)pTrident->IOBase + 0x2160, 645 (CARD32 *)pTrident->XAAScanlineColorExpandBuffers[0], 646 pTrident->dwords); 647 648 pTrident->h--; 649 if (pTrident->h) 650 XPSync(pScrn); 651} 652#endif 653#endif 654