i128accel.c revision a73423d7
1 2/* 3 * Copyright 1997-2000 by Robin Cutshaw <robin@XFree86.Org> 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of Robin Cutshaw not be used in 10 * advertising or publicity pertaining to distribution of the software without 11 * specific, written prior permission. Robin Cutshaw makes no representations 12 * about the suitability of this software for any purpose. It is provided 13 * "as is" without express or implied warranty. 14 * 15 * ROBIN CUTSHAW DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 * EVENT SHALL ROBIN CUTSHAW BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 * PERFORMANCE OF THIS SOFTWARE. 22 * 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#endif 28 29 30#include "xf86fbman.h" 31#include "miline.h" 32#include "servermd.h" 33 34#include "xf86.h" 35#include "xf86_OSproc.h" 36#include "xf86Pci.h" 37#include "xf86PciInfo.h" 38 39#include "i128.h" 40#include "i128reg.h" 41 42#ifdef HAVE_XAA_H 43#include "xaalocal.h" 44 45static void I128BitBlit(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, 46 int w, int h); 47static void I128SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, 48 int ydir, int rop, unsigned planemask, int transparency_color); 49static void I128SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, 50 int x2, int y2, int w, int h); 51static void I128SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 52 unsigned planemask); 53static void I128SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, 54 int h); 55static void I128SubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, 56 int x2, int y2, int flags); 57static void I128SetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, 58 int x2, int y2); 59static void I128FillSolidRects(ScrnInfoPtr pScrn, int fg, int rop, 60 unsigned int planemask, int nBox, register BoxPtr pBoxI); 61#if 0 62static void I128ScreenToScreenBitBlt(ScrnInfoPtr pScrn, int nbox, 63 DDXPointPtr pptSrc, BoxPtr pbox, int xdir, int ydir, int alu, 64 unsigned planemask); 65#endif 66 67#endif 68#define ENG_PIPELINE_READY() { while (pI128->mem.rbase_a[BUSY] & BUSY_BUSY) ; } 69#define ENG_DONE() { while (pI128->mem.rbase_a[FLOW] & (FLOW_DEB | FLOW_MCB | FLOW_PRV)) ;} 70 71 72/* pre-shift rops and just or in as needed */ 73 74static const CARD32 i128alu[16] = 75{ 76 CR_CLEAR<<8, 77 CR_AND<<8, 78 CR_AND_REV<<8, 79 CR_COPY<<8, 80 CR_AND_INV<<8, 81 CR_NOOP<<8, 82 CR_XOR<<8, 83 CR_OR<<8, 84 CR_NOR<<8, 85 CR_EQUIV<<8, 86 CR_INVERT<<8, 87 CR_OR_REV<<8, 88 CR_COPY_INV<<8, 89 CR_OR_INV<<8, 90 CR_NAND<<8, 91 CR_SET<<8 92}; 93 /* 8bpp 16bpp 32bpp unused */ 94static const int min_size[] = { 0x62, 0x32, 0x1A, 0x00 }; 95static const int max_size[] = { 0x80, 0x40, 0x20, 0x00 }; 96static const int split_size[] = { 0x20, 0x10, 0x08, 0x00 }; 97 98 99void 100I128EngineDone(ScrnInfoPtr pScrn) 101{ 102 I128Ptr pI128 = I128PTR(pScrn); 103 ENG_DONE(); 104} 105 106#ifdef HAVE_XAA_H 107static void 108I128BitBlit(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h) 109{ 110 I128Ptr pI128 = I128PTR(pScrn); 111 112#if 0 113 if (pI128->Debug) 114 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BB %d,%d %d,%d %d,%d 0x%x/0x%x\n", x1, y1, x2, y2, w, h, pI128->cmd); 115#endif 116 117 ENG_PIPELINE_READY(); 118 119 pI128->mem.rbase_a[CMD] = pI128->cmd; 120 /*pI128->mem.rbase_a[XY3_DIR] = pI128->blitdir;*/ 121 122 if (pI128->blitdir & DIR_RL_TB) { 123 x1 += w; x1--; 124 x2 += w; x2--; 125 } 126 if (pI128->blitdir & DIR_LR_BT) { 127 y1 += h; y1--; 128 y2 += h; y2--; 129 } 130 131 132 133 if (pI128->Chipset == PCI_CHIP_I128) { 134 int bppi; 135 136 static int first_time_through = 1; 137 138 /* The I128-1 has a nasty bitblit bug 139 * that occurs when dest is exactly 8 pages wide 140 */ 141 142 bppi = (pI128->mem.rbase_a[BUF_CTRL] & BC_PSIZ_MSK) >> 24; 143 144 if ((w >= min_size[bppi]) && (w <= max_size[bppi])) { 145 if (first_time_through) { 146 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 147 "Using I128-1 workarounds.\n"); 148 first_time_through = 0; 149 } 150 151 bppi = split_size[bppi]; 152#if 1 153 /* split method */ 154 155 pI128->mem.rbase_a[XY2_WH] = (bppi<<16) | h; 156 pI128->mem.rbase_a[XY0_SRC] = (x1<<16) | y1; MB; 157 pI128->mem.rbase_a[XY1_DST] = (x2<<16) | y2; MB; 158 159 ENG_PIPELINE_READY(); 160 161 w -= bppi; 162 163 if (pI128->blitdir & DIR_RL_TB) { 164 /* right to left blit */ 165 x1 -= bppi; 166 x2 -= bppi; 167 } else { 168 /* left to right blit */ 169 x1 += bppi; 170 x2 += bppi; 171 } 172#else 173 /* clip method */ 174 pI128->mem.rbase_a[CLPTL] = (x2<<16) | y2; 175 pI128->mem.rbase_a[CLPBR] = ((x2+w)<<16) | (y2+h); 176 w += bppi; 177#endif 178 } 179 } 180 181 pI128->mem.rbase_a[XY2_WH] = (w<<16) | h; 182 pI128->mem.rbase_a[XY0_SRC] = (x1<<16) | y1; MB; 183 pI128->mem.rbase_a[XY1_DST] = (x2<<16) | y2; MB; 184} 185 186static void 187I128SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 188 int rop, unsigned planemask, int transparency_color) 189{ 190 I128Ptr pI128 = I128PTR(pScrn); 191 192#if 0 193 if (pI128->Debug) 194 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SFSSC %d,%d %d 0x%x %d\n", xdir, ydir, rop, planemask, transparency_color); 195#endif 196 197 ENG_PIPELINE_READY(); 198 199 if (planemask == -1) 200 pI128->mem.rbase_a[MASK] = -1; 201 else switch (pI128->bitsPerPixel) { 202 case 8: 203 pI128->mem.rbase_a[MASK] = planemask | 204 (planemask<<8) | 205 (planemask<<16) | 206 (planemask<<24); 207 break; 208 case 16: 209 pI128->mem.rbase_a[MASK] = planemask | (planemask<<16); 210 break; 211 case 24: 212 case 32: 213 default: 214 pI128->mem.rbase_a[MASK] = planemask; 215 break; 216 } 217 218 219 pI128->mem.rbase_a[CLPTL] = 0x00000000; 220 pI128->mem.rbase_a[CLPBR] = (4095<<16) | 2047; 221 222 if (transparency_color != -1) 223 pI128->mem.rbase_a[BACK] = transparency_color; 224 225 226 if (xdir == -1) { 227 if (ydir == -1) pI128->blitdir = DIR_RL_BT; 228 else pI128->blitdir = DIR_RL_TB; 229 } else { 230 if (ydir == -1) pI128->blitdir = DIR_LR_BT; 231 else pI128->blitdir = DIR_LR_TB; 232 } 233 pI128->mem.rbase_a[XY3_DIR] = pI128->blitdir; 234 235 pI128->rop = i128alu[rop]; 236 pI128->cmd = (transparency_color != -1 ? (CS_TRNSP<<16) : 0) | 237 pI128->rop | CO_BITBLT; 238 pI128->mem.rbase_a[CMD] = pI128->cmd; 239} 240 241static void 242I128SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, 243 int x2, int y2, int w, int h) 244{ 245 I128BitBlit(pScrn, x1, y1, x2, y2, w, h); 246} 247 248static void 249I128SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask) 250{ 251 I128Ptr pI128 = I128PTR(pScrn); 252 253#if 0 254 if (pI128->Debug) 255 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SFSF color 0x%x rop 0x%x (I128rop 0x%x) pmask 0x%x\n", color, rop, i128alu[rop]>>8, planemask); 256#endif 257 258 ENG_PIPELINE_READY(); 259 260 if (planemask == -1) 261 pI128->mem.rbase_a[MASK] = -1; 262 else switch (pI128->bitsPerPixel) { 263 case 8: 264 pI128->mem.rbase_a[MASK] = planemask | 265 (planemask<<8) | 266 (planemask<<16) | 267 (planemask<<24); 268 break; 269 case 16: 270 pI128->mem.rbase_a[MASK] = planemask | (planemask<<16); 271 break; 272 case 24: 273 case 32: 274 default: 275 pI128->mem.rbase_a[MASK] = planemask; 276 break; 277 } 278 279 pI128->mem.rbase_a[FORE] = color; 280 281 pI128->clptl = pI128->mem.rbase_a[CLPTL] = 0x00000000; 282 pI128->clpbr = pI128->mem.rbase_a[CLPBR] = (4095<<16) | 2047 ; 283 284 pI128->mem.rbase_a[XY3_DIR] = pI128->blitdir = DIR_LR_TB; 285 286 pI128->rop = i128alu[rop]; 287 pI128->cmd = (CS_SOLID<<16) | pI128->rop | CO_BITBLT; 288 pI128->mem.rbase_a[CMD] = pI128->cmd; 289} 290 291static void 292I128SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 293{ 294#if 0 295 I128Ptr pI128 = I128PTR(pScrn); 296 297 if (pI128->Debug) 298 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SSFR %d,%d %d,%d\n", x, y, w, h); 299#endif 300 I128BitBlit(pScrn, 0, 0, x, y, w, h); 301} 302 303static void 304I128SubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, 305 int y2, int flags) 306{ 307 I128Ptr pI128 = I128PTR(pScrn); 308 309#if 0 310 if (pI128->Debug) 311 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "STPL I128rop 0x%x %d,%d %d,%d clip %d,%d %d,%d\n", pI128->rop, x1, y1, x2, y2, pI128->clptl>>16, pI128->clptl&0xffff, (pI128->clpbr>>16)&0xffff, pI128->clpbr&0xffff); 312#endif 313 314 ENG_PIPELINE_READY(); 315 316 pI128->mem.rbase_a[CMD] = 317 ((flags&0x0100) ? (CP_NLST<<24) : 0) | 318 (CC_CLPRECI<<21) | 319 (CS_SOLID<<16) | 320 pI128->rop | 321 CO_LINE; 322 323 pI128->mem.rbase_a[CLPTL] = pI128->clptl; 324 pI128->mem.rbase_a[CLPBR] = pI128->clpbr; 325 326 pI128->mem.rbase_a[XY0_SRC] = (x1<<16) | y1; MB; 327 pI128->mem.rbase_a[XY1_DST] = (x2<<16) | y2; MB; 328} 329 330static void 331I128SetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) 332{ 333 I128Ptr pI128 = I128PTR(pScrn); 334 int tmp; 335 336#if 0 337 if (pI128->Debug) 338 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SCR %d,%d %d,%d\n", x1, y1, x2, y2); 339#endif 340 341 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } 342 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } 343 344 pI128->clptl = (x1<<16) | y1; 345 pI128->clpbr = (x2<<16) | y2; 346} 347 348 349static void 350I128FillSolidRects(ScrnInfoPtr pScrn, int fg, int rop, unsigned int planemask, 351 int nBox, register BoxPtr pBoxI) 352{ 353 I128Ptr pI128 = I128PTR(pScrn); 354 register int w, h; 355 356#if 0 357 if (pI128->Debug) 358 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "FSR color 0x%x rop 0x%x (I128rop 0x%x) pmask 0x%x\n", fg, rop, i128alu[rop]>>8, planemask); 359#endif 360 361 ENG_PIPELINE_READY(); 362 363 if (planemask != -1) { 364 if (pI128->bitsPerPixel == 8) { 365 planemask |= (planemask<<8) | 366 (planemask<<16) | 367 (planemask<<24); 368 } else if (pI128->bitsPerPixel == 16) 369 planemask |= planemask<<16; 370 } 371 372 pI128->mem.rbase_a[MASK] = planemask; 373 pI128->mem.rbase_a[FORE] = fg; 374 pI128->mem.rbase_a[CMD] = (CS_SOLID<<16) | i128alu[rop] | CO_BITBLT; 375 pI128->mem.rbase_a[CLPTL] = 0x00000000; 376 pI128->mem.rbase_a[CLPBR] = (4095<<16) | 2047; 377 378 pI128->mem.rbase_a[XY3_DIR] = DIR_LR_TB; 379 pI128->mem.rbase_a[XY0_SRC] = 0x00000000; 380 381 while (nBox > 0) { 382 w = pBoxI->x2 - pBoxI->x1; 383 h = pBoxI->y2 - pBoxI->y1; 384 if (w > 0 && h > 0) { 385 pI128->mem.rbase_a[XY2_WH] = (w<<16) | h; MB; 386 pI128->mem.rbase_a[XY1_DST] = 387 (pBoxI->x1<<16) | pBoxI->y1; MB; 388 389 ENG_PIPELINE_READY(); 390#if 0 391 if (pI128->Debug) 392 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "FSR x,y %d,%d w,h %d,%d\n", pBoxI->x1, pBoxI->y1, w, h); 393#endif 394 395 } 396 pBoxI++; 397 nBox--; 398 } 399 400 ENG_DONE(); 401 402} 403 404#if 0 405static void 406I128ScreenToScreenBitBlt(ScrnInfoPtr pScrn, int nbox, DDXPointPtr pptSrc, 407 BoxPtr pbox, int xdir, int ydir, int alu, unsigned planemask) 408{ 409 I128Ptr pI128 = I128PTR(pScrn); 410 I128SetupForScreenToScreenCopy(pScrn, xdir, ydir, alu, planemask, -1); 411 for (; nbox; pbox++, pptSrc++, nbox--) 412 I128SubsequentScreenToScreenCopy(pScrn, pptSrc->x, pptSrc->y, 413 pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); 414 ENG_DONE(); 415} 416#endif 417 418#endif 419 420Bool 421I128XaaInit(ScreenPtr pScreen) 422{ 423#ifdef HAVE_XAA_H 424 XAAInfoRecPtr infoPtr; 425 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 426 I128Ptr pI128 = I128PTR(pScrn); 427 BoxRec AvailFBArea; 428 CARD32 buf_ctrl; 429 int maxlines; 430 431 pI128->XaaInfoRec = infoPtr = XAACreateInfoRec(); 432 if (!infoPtr) return FALSE; 433 434 infoPtr->Flags = PIXMAP_CACHE | 435 OFFSCREEN_PIXMAPS | 436 LINEAR_FRAMEBUFFER ; 437 438 infoPtr->Sync = I128EngineDone; 439 440 /* screen to screen copy */ 441 infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 442 if (pI128->Chipset == PCI_CHIP_I128_T2R) 443 infoPtr->ScreenToScreenCopyFlags |= ONLY_LEFT_TO_RIGHT_BITBLT; 444 445 infoPtr->SetupForScreenToScreenCopy = I128SetupForScreenToScreenCopy; 446 infoPtr->SubsequentScreenToScreenCopy = 447 I128SubsequentScreenToScreenCopy; 448 449#if 0 450 /* screen to screen color expansion */ 451 if (pI128->Chipset == PCI_CHIP_I128_T2R) 452 infoPtr->ScreenToScreenColorExpandFillFlags |= 453 ONLY_LEFT_TO_RIGHT_BITBLT; 454 455 infoPtr->SetupForScreenToScreenColorExpandFill = 456 I128SetupForScreenToScreenColorExpandFill; 457 infoPtr->SubsequentScreenToScreenColorExpandFill = 458 I128SubsequentScreenToScreenColorExpandFill; 459#endif 460 461 /* solid fills */ 462 infoPtr->SetupForSolidFill = I128SetupForSolidFill; 463 infoPtr->SubsequentSolidFillRect = I128SubsequentSolidFillRect; 464 465 infoPtr->FillSolidRects = I128FillSolidRects; 466 467 /* solid lines */ 468 infoPtr->SubsequentSolidTwoPointLine = I128SubsequentSolidTwoPointLine; 469 470 /* clipping */ 471 infoPtr->ClippingFlags = HARDWARE_CLIP_LINE; 472 infoPtr->SetClippingRectangle = I128SetClippingRectangle; 473 474 infoPtr->PolyFillRectSolidFlags = 0; 475 476 maxlines = ((pI128->MemorySize * 1024) - 1024) / 477 (pScrn->displayWidth * pI128->bitsPerPixel / 8); 478 AvailFBArea.x1 = 0; 479 AvailFBArea.x2 = pI128->displayWidth; 480 AvailFBArea.y1 = 0; 481 AvailFBArea.y2 = maxlines; 482 xf86InitFBManager(pScreen, &AvailFBArea); 483 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 484 "Using %d lines for offscreen memory\n", 485 maxlines - pScrn->virtualY); 486 487 switch (pI128->bitsPerPixel) { 488 case 8: buf_ctrl = BC_PSIZ_8B; break; 489 case 16: buf_ctrl = BC_PSIZ_16B; break; 490 case 24: 491 case 32: buf_ctrl = BC_PSIZ_32B; break; 492 default: buf_ctrl = 0; break; /* error */ 493 } 494 if (pI128->Chipset == PCI_CHIP_I128_T2R) { 495 if (pI128->MemoryType == I128_MEMORY_SGRAM) 496 buf_ctrl |= BC_MDM_PLN; 497 else 498 buf_ctrl |= BC_BLK_ENA; 499 } 500 pI128->mem.rbase_a[BUF_CTRL] = buf_ctrl; 501 502 pI128->mem.rbase_a[DE_PGE] = 0x00; 503 pI128->mem.rbase_a[DE_SORG] = pI128->displayOffset; 504 pI128->mem.rbase_a[DE_DORG] = pI128->displayOffset; 505 pI128->mem.rbase_a[DE_MSRC] = 0x00; 506 pI128->mem.rbase_a[DE_WKEY] = 0x00; 507 pI128->mem.rbase_a[DE_SPTCH] = pI128->mem.rbase_g[DB_PTCH]; 508 pI128->mem.rbase_a[DE_DPTCH] = pI128->mem.rbase_g[DB_PTCH]; 509 if (pI128->Chipset == PCI_CHIP_I128_T2R4) 510 pI128->mem.rbase_a[DE_ZPTCH] = pI128->mem.rbase_g[DB_PTCH]; 511 pI128->mem.rbase_a[RMSK] = 0x00000000; 512 pI128->mem.rbase_a[XY4_ZM] = ZOOM_NONE; 513 pI128->mem.rbase_a[LPAT] = 0xffffffff; /* for lines */ 514 pI128->mem.rbase_a[PCTRL] = 0x00000000; /* for lines */ 515 pI128->mem.rbase_a[CLPTL] = 0x00000000; 516 pI128->mem.rbase_a[CLPBR] = (4095<<16) | 2047 ; 517 if (pI128->Chipset == PCI_CHIP_I128_T2R || 518 pI128->Chipset == PCI_CHIP_I128_T2R4) 519 pI128->mem.rbase_a[ACNTRL] = 0x00000000; 520 pI128->mem.rbase_a[INTM] = 0x03; 521 522 if (pI128->Debug) { 523 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I128XaaInit done\n"); 524 I128DumpActiveRegisters(pScrn); 525 } 526 527 return(XAAInit(pScreen, infoPtr)); 528#else 529 return FALSE; 530#endif 531} 532