alp_xaa.c revision 76888252
176888252Smrg/* (c) Itai Nahshon */ 276888252Smrg 376888252Smrg#ifdef HAVE_CONFIG_H 476888252Smrg#include "config.h" 576888252Smrg#endif 676888252Smrg 776888252Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_xaa.c,v 1.7 2001/10/01 13:44:05 eich Exp $ */ 876888252Smrg 976888252Smrg#include "xf86.h" 1076888252Smrg#include "xf86_OSproc.h" 1176888252Smrg#include "compiler.h" 1276888252Smrg 1376888252Smrg#include "xf86Pci.h" 1476888252Smrg#include "xf86PciInfo.h" 1576888252Smrg 1676888252Smrg#include "vgaHW.h" 1776888252Smrg 1876888252Smrg#include "cir.h" 1976888252Smrg#define _ALP_PRIVATE_ 2076888252Smrg#include "alp.h" 2176888252Smrg 2276888252Smrg#define WAIT outb(pCir->PIOReg, 0x31); \ 2376888252Smrg while(inb(pCir->PIOReg + 1) & pCir->chip.alp->waitMsk){}; 2476888252Smrg#define WAIT_1 outb(pCir->PIOReg, 0x31); \ 2576888252Smrg while(inb(pCir->PIOReg + 1) & 0x1){}; 2676888252Smrg 2776888252Smrgstatic const CARD16 translated_rop[] = 2876888252Smrg{ 2976888252Smrg /* GXclear */ 0x0032U, 3076888252Smrg /* GXand */ 0x0532U, 3176888252Smrg /* GXandreverse */ 0x0932U, 3276888252Smrg /* GXcopy */ 0x0D32U, 3376888252Smrg /* GXandinversted */ 0x5032U, 3476888252Smrg /* GXnoop */ 0x0632U, 3576888252Smrg /* GXxor */ 0x5932U, 3676888252Smrg /* GXor */ 0x6D32U, 3776888252Smrg /* GXnor */ 0x9032U, 3876888252Smrg /* GXequiv */ 0x9532U, 3976888252Smrg /* GXinvert */ 0x0B32U, 4076888252Smrg /* GXorReverse */ 0xAD32U, 4176888252Smrg /* GXcopyInverted */ 0xD032U, 4276888252Smrg /* GXorInverted */ 0xD632U, 4376888252Smrg /* GXnand */ 0xDA32U, 4476888252Smrg /* GXset */ 0x0E32U 4576888252Smrg}; 4676888252Smrg 4776888252Smrg#if 1 4876888252Smrg#define SetupForRop(rop) outw(pCir->PIOReg, translated_rop[rop]) 4976888252Smrg#else 5076888252Smrg#define SetupForRop(rop) outw(pCir->PIOReg, 0x0D32) 5176888252Smrg#endif 5276888252Smrg 5376888252Smrgstatic void AlpSync(ScrnInfoPtr pScrn) 5476888252Smrg{ 5576888252Smrg CirPtr pCir = CIRPTR(pScrn); 5676888252Smrg 5776888252Smrg#ifdef ALP_DEBUG 5876888252Smrg ErrorF("AlpSync\n"); 5976888252Smrg#endif 6076888252Smrg WAIT_1; 6176888252Smrg return; 6276888252Smrg} 6376888252Smrg 6476888252Smrgstatic void 6576888252SmrgAlpSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 6676888252Smrg int rop, unsigned int planemask, 6776888252Smrg int trans_color) 6876888252Smrg{ 6976888252Smrg CirPtr pCir = CIRPTR(pScrn); 7076888252Smrg int pitch = pCir->pitch; 7176888252Smrg 7276888252Smrg#ifdef ALP_DEBUG 7376888252Smrg ErrorF("AlpSetupForScreenToScreenCopy xdir=%d ydir=%d rop=%x planemask=%x trans_color=%x\n", 7476888252Smrg xdir, ydir, rop, planemask, trans_color); 7576888252Smrg#endif 7676888252Smrg WAIT; 7776888252Smrg SetupForRop(rop); 7876888252Smrg /* Set dest pitch */ 7976888252Smrg outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24); 8076888252Smrg outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25); 8176888252Smrg /* Set source pitch */ 8276888252Smrg outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x26); 8376888252Smrg outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x27); 8476888252Smrg} 8576888252Smrg 8676888252Smrgstatic void 8776888252SmrgAlpSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, 8876888252Smrg int y2, int w, int h) 8976888252Smrg{ 9076888252Smrg CirPtr pCir = CIRPTR(pScrn); 9176888252Smrg int source, dest; 9276888252Smrg int hh, ww; 9376888252Smrg int decrement = 0; 9476888252Smrg int pitch = pCir->pitch; 9576888252Smrg 9676888252Smrg ww = (w * pScrn->bitsPerPixel / 8) - 1; 9776888252Smrg hh = h - 1; 9876888252Smrg dest = y2 * pitch + x2 * pScrn->bitsPerPixel / 8; 9976888252Smrg source = y1 * pitch + x1 * pScrn->bitsPerPixel / 8; 10076888252Smrg if (dest > source) { 10176888252Smrg decrement = 1 << 8; 10276888252Smrg dest += hh * pitch + ww; 10376888252Smrg source += hh * pitch + ww; 10476888252Smrg } 10576888252Smrg 10676888252Smrg WAIT; 10776888252Smrg 10876888252Smrg outw(pCir->PIOReg, decrement | 0x30); 10976888252Smrg 11076888252Smrg /* Width */ 11176888252Smrg outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20); 11276888252Smrg outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21); 11376888252Smrg /* Height */ 11476888252Smrg outw(pCir->PIOReg, ((hh << 8) & 0xff00) | 0x22); 11576888252Smrg outw(pCir->PIOReg, ((hh) & 0x0700) | 0x23); 11676888252Smrg 11776888252Smrg 11876888252Smrg /* source */ 11976888252Smrg outw(pCir->PIOReg, ((source << 8) & 0xff00) | 0x2C); 12076888252Smrg outw(pCir->PIOReg, ((source) & 0xff00) | 0x2D); 12176888252Smrg outw(pCir->PIOReg, ((source >> 8) & 0x3f00)| 0x2E); 12276888252Smrg 12376888252Smrg /* dest */ 12476888252Smrg outw(pCir->PIOReg, ((dest << 8) & 0xff00) | 0x28); 12576888252Smrg outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29); 12676888252Smrg outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A); 12776888252Smrg if (!pCir->chip.alp->autoStart) 12876888252Smrg outw(pCir->PIOReg, 0x0231); 12976888252Smrg 13076888252Smrg#ifdef ALP_DEBUG 13176888252Smrg ErrorF("AlpSubsequentScreenToScreenCopy x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n", 13276888252Smrg x1, y1, x2, y2, w, h); 13376888252Smrg ErrorF("AlpSubsequentScreenToScreenCopy s=%d d=%d ww=%d hh=%d\n", 13476888252Smrg source, dest, ww, hh); 13576888252Smrg#endif 13676888252Smrg 13776888252Smrg} 13876888252Smrg 13976888252Smrgstatic void 14076888252SmrgAlpSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 14176888252Smrg unsigned int planemask) 14276888252Smrg{ 14376888252Smrg CirPtr pCir = CIRPTR(pScrn); 14476888252Smrg AlpPtr pAlp = ALPPTR(pCir); 14576888252Smrg int pitch = pCir->pitch; 14676888252Smrg 14776888252Smrg#ifdef ALP_DEBUG 14876888252Smrg ErrorF("AlpSetupForSolidFill color=%x rop=%x planemask=%x\n", 14976888252Smrg color, rop, planemask); 15076888252Smrg#endif 15176888252Smrg WAIT; 15276888252Smrg 15376888252Smrg SetupForRop(rop); 15476888252Smrg 15576888252Smrg switch (pCir -> Chipset) 15676888252Smrg { 15776888252Smrg case PCI_CHIP_GD7548: 15876888252Smrg /* The GD7548 does not (apparently) support solid filling 15976888252Smrg directly, it always need an actual source. 16076888252Smrg We therefore use it as a pattern fill with a solid 16176888252Smrg pattern */ 16276888252Smrg { 16376888252Smrg int source = pAlp->monoPattern8x8; 16476888252Smrg /* source = 8x8 solid mono pattern */ 16576888252Smrg outw(pCir->PIOReg, ((source << 8) & 0xff00) | 0x2C); 16676888252Smrg outw(pCir->PIOReg, ((source) & 0xff00) | 0x2D); 16776888252Smrg outw(pCir->PIOReg, ((source >> 8) & 0x3f00) | 0x2E); 16876888252Smrg /* memset() may not be the fastest */ 16976888252Smrg memset(pCir->FbBase + pAlp->monoPattern8x8, 0xFF, 8); 17076888252Smrg write_mem_barrier(); 17176888252Smrg break; 17276888252Smrg } 17376888252Smrg default: 17476888252Smrg /* GR33 = 0x04 => does not exist on GD7548 */ 17576888252Smrg outw(pCir->PIOReg, 0x0433); 17676888252Smrg } 17776888252Smrg 17876888252Smrg /* GR30 = color expansion, pattern copy */ 17976888252Smrg /* Choses 8bpp / 16bpp color expansion */ 18076888252Smrg outw(pCir->PIOReg, 0xC030 |((pScrn->bitsPerPixel - 8) << 9)); 18176888252Smrg 18276888252Smrg outw(pCir->PIOReg, ((color << 8) & 0xff00) | 0x01); 18376888252Smrg outw(pCir->PIOReg, ((color) & 0xff00) | 0x11); 18476888252Smrg outw(pCir->PIOReg, ((color >> 8) & 0xff00) | 0x13); 18576888252Smrg outw(pCir->PIOReg, 0x15); 18676888252Smrg 18776888252Smrg /* Set dest pitch */ 18876888252Smrg outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24); 18976888252Smrg outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25); 19076888252Smrg} 19176888252Smrg 19276888252Smrgstatic void 19376888252SmrgAlpSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 19476888252Smrg{ 19576888252Smrg CirPtr pCir = CIRPTR(pScrn); 19676888252Smrg int dest; 19776888252Smrg int hh, ww; 19876888252Smrg int pitch = pCir->pitch; 19976888252Smrg 20076888252Smrg ww = (w * pScrn->bitsPerPixel / 8) - 1; 20176888252Smrg hh = h - 1; 20276888252Smrg dest = y * pitch + x * pScrn->bitsPerPixel / 8; 20376888252Smrg 20476888252Smrg WAIT; 20576888252Smrg 20676888252Smrg /* Width */ 20776888252Smrg outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20); 20876888252Smrg outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21); 20976888252Smrg /* Height */ 21076888252Smrg outw(pCir->PIOReg, ((hh << 8) & 0xff00) | 0x22); 21176888252Smrg outw(pCir->PIOReg, ((hh) & 0x0700) | 0x23); 21276888252Smrg 21376888252Smrg /* dest */ 21476888252Smrg outw(pCir->PIOReg, ((dest << 8) & 0xff00) | 0x28); 21576888252Smrg outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29); 21676888252Smrg outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A); 21776888252Smrg if (!pCir->chip.alp->autoStart) 21876888252Smrg outw(pCir->PIOReg, 0x0231); 21976888252Smrg 22076888252Smrg#ifdef ALP_DEBUG 22176888252Smrg ErrorF("AlpSubsequentSolidFillRect x=%d y=%d w=%d h=%d\n", 22276888252Smrg x, y, w, h); 22376888252Smrg#endif 22476888252Smrg 22576888252Smrg} 22676888252Smrg 22776888252Smrgstatic void 22876888252SmrgAlpSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, 22976888252Smrg int patx, int paty, 23076888252Smrg int fg, int bg, 23176888252Smrg int rop, unsigned int planemask) 23276888252Smrg{ 23376888252Smrg CirPtr pCir = CIRPTR(pScrn); 23476888252Smrg AlpPtr pAlp = ALPPTR(pCir); 23576888252Smrg int pitch = pCir->pitch; 23676888252Smrg 23776888252Smrg#ifdef ALP_DEBUG 23876888252Smrg ErrorF("AlpSetupFor8x8PatternFill pattern=%8x%8x" 23976888252Smrg "fg=%x bg=%x rop=%x planemask=%x\n", 24076888252Smrg patx, paty, fg, bg, rop, planemask); 24176888252Smrg#endif 24276888252Smrg WAIT; 24376888252Smrg 24476888252Smrg SetupForRop(rop); 24576888252Smrg 24676888252Smrg { 24776888252Smrg int source = pAlp->monoPattern8x8; 24876888252Smrg /* source = 8x8 solid mono pattern */ 24976888252Smrg outw(pCir->PIOReg, ((source << 8) & 0xff00) | 0x2C); 25076888252Smrg outw(pCir->PIOReg, ((source) & 0xff00) | 0x2D); 25176888252Smrg outw(pCir->PIOReg, ((source >> 8) & 0x3f00) | 0x2E); 25276888252Smrg } 25376888252Smrg 25476888252Smrg /* GR30 = color expansion, pattern copy */ 25576888252Smrg /* Choses 8bpp / 16bpp color expansion */ 25676888252Smrg if (bg == -1) 25776888252Smrg { /* transparency requested */ 25876888252Smrg outw(pCir->PIOReg, 0xC830 |((pScrn->bitsPerPixel - 8) << 9)); 25976888252Smrg 26076888252Smrg bg = ~fg; 26176888252Smrg /* transparent color compare */ 26276888252Smrg outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x34); 26376888252Smrg outw(pCir->PIOReg, ((bg) & 0xff00) | 0x35); 26476888252Smrg 26576888252Smrg /* transparent color mask = 0 (all bits matters) */ 26676888252Smrg outw(pCir->PIOReg, 0x38); 26776888252Smrg outw(pCir->PIOReg, 0x39); 26876888252Smrg } 26976888252Smrg else 27076888252Smrg { 27176888252Smrg outw(pCir->PIOReg, 0xC030 |((pScrn->bitsPerPixel - 8) << 9)); 27276888252Smrg } 27376888252Smrg 27476888252Smrg outw(pCir->PIOReg, ((fg << 8) & 0xff00) | 0x01); 27576888252Smrg outw(pCir->PIOReg, ((fg) & 0xff00) | 0x11); 27676888252Smrg 27776888252Smrg outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x00); 27876888252Smrg outw(pCir->PIOReg, ((bg) & 0xff00) | 0x10); 27976888252Smrg 28076888252Smrg /* Set dest pitch */ 28176888252Smrg outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24); 28276888252Smrg outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25); 28376888252Smrg} 28476888252Smrg 28576888252Smrgstatic void 28676888252SmrgAlpSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty, 28776888252Smrg int x, int y, int w, int h) 28876888252Smrg{ 28976888252Smrg CirPtr pCir = CIRPTR(pScrn); 29076888252Smrg AlpPtr pAlp = ALPPTR(pCir); 29176888252Smrg int dest; 29276888252Smrg int hh, ww; 29376888252Smrg int pitch = pCir->pitch; 29476888252Smrg 29576888252Smrg ww = (w * pScrn->bitsPerPixel / 8) - 1; 29676888252Smrg hh = h - 1; 29776888252Smrg dest = y * pitch + x * pScrn->bitsPerPixel / 8; 29876888252Smrg 29976888252Smrg WAIT; 30076888252Smrg /* memcpy() may not be the fastest */ 30176888252Smrg memcpy(pCir->FbBase + pAlp->monoPattern8x8, &patx, 4); 30276888252Smrg memcpy(pCir->FbBase + pAlp->monoPattern8x8 + 4, &paty, 4); 30376888252Smrg write_mem_barrier(); 30476888252Smrg 30576888252Smrg /* Width */ 30676888252Smrg outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20); 30776888252Smrg outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21); 30876888252Smrg /* Height */ 30976888252Smrg outw(pCir->PIOReg, ((hh << 8) & 0xff00) | 0x22); 31076888252Smrg outw(pCir->PIOReg, ((hh) & 0x0700) | 0x23); 31176888252Smrg 31276888252Smrg /* dest */ 31376888252Smrg outw(pCir->PIOReg, ((dest << 8) & 0xff00) | 0x28); 31476888252Smrg outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29); 31576888252Smrg outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A); 31676888252Smrg if (!pCir->chip.alp->autoStart) 31776888252Smrg outw(pCir->PIOReg, 0x0231); 31876888252Smrg 31976888252Smrg#ifdef ALP_DEBUG 32076888252Smrg ErrorF("AlpSubsequent8x8PatternFill x=%d y=%d w=%d h=%d\n", 32176888252Smrg x, y, w, h); 32276888252Smrg#endif 32376888252Smrg 32476888252Smrg} 32576888252Smrg 32676888252Smrg#if 0 32776888252Smrg/* XF86 does not support byte-padded scanlines */ 32876888252Smrg 32976888252Smrgstatic void 33076888252SmrgAlpSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 33176888252Smrg int fg, int bg, 33276888252Smrg int rop, 33376888252Smrg unsigned int planemask) 33476888252Smrg{ 33576888252Smrg CirPtr pCir = CIRPTR(pScrn); 33676888252Smrg AlpPtr pAlp = ALPPTR(pCir); 33776888252Smrg int pitch = pCir->pitch; 33876888252Smrg 33976888252Smrg#ifdef ALP_DEBUG 34076888252Smrg ErrorF("AlpSetupForCPUToScreenColorExpandFill " 34176888252Smrg "fg=%x bg=%x rop=%x planemask=%x\n", 34276888252Smrg fg, bg, rop, planemask); 34376888252Smrg#endif 34476888252Smrg WAIT; 34576888252Smrg 34676888252Smrg SetupForRop(rop); 34776888252Smrg 34876888252Smrg /* GR30 = color expansion, CPU->display copy */ 34976888252Smrg /* Choses 8bpp / 16bpp color expansion */ 35076888252Smrg if (bg == -1) 35176888252Smrg { /* transparency requested */ 35276888252Smrg outw(pCir->PIOReg, 0x8C30 |((pScrn->bitsPerPixel - 8) << 9)); 35376888252Smrg 35476888252Smrg bg = ~fg; 35576888252Smrg /* transparent color compare */ 35676888252Smrg outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x34); 35776888252Smrg outw(pCir->PIOReg, ((bg) & 0xff00) | 0x35); 35876888252Smrg 35976888252Smrg /* transparent color mask = 0 (all bits matters) */ 36076888252Smrg outw(pCir->PIOReg, 0x38); 36176888252Smrg outw(pCir->PIOReg, 0x39); 36276888252Smrg } 36376888252Smrg else 36476888252Smrg { 36576888252Smrg outw(pCir->PIOReg, 0x8430 |((pScrn->bitsPerPixel - 8) << 9)); 36676888252Smrg } 36776888252Smrg 36876888252Smrg outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x00); 36976888252Smrg outw(pCir->PIOReg, ((bg) & 0xff00) | 0x10); 37076888252Smrg 37176888252Smrg outw(pCir->PIOReg, ((fg << 8) & 0xff00) | 0x01); 37276888252Smrg outw(pCir->PIOReg, ((fg) & 0xff00) | 0x11); 37376888252Smrg 37476888252Smrg /* Set dest pitch */ 37576888252Smrg outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24); 37676888252Smrg outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25); 37776888252Smrg} 37876888252Smrg 37976888252Smrgstatic void 38076888252SmrgAlpSubsequentCPUToScreenColorExpandFill( 38176888252Smrg ScrnInfoPtr pScrn, 38276888252Smrg int x, int y, int w, int h, 38376888252Smrg int skipleft) 38476888252Smrg{ 38576888252Smrg CirPtr pCir = CIRPTR(pScrn); 38676888252Smrg int dest; 38776888252Smrg int hh, ww; 38876888252Smrg int pitch = pCir->pitch; 38976888252Smrg 39076888252Smrg ww = (((w+7) & ~7) * pScrn->bitsPerPixel / 8) - 1; 39176888252Smrg hh = h - 1; 39276888252Smrg dest = y * pitch + x * pScrn->bitsPerPixel / 8; 39376888252Smrg 39476888252Smrg WAIT; 39576888252Smrg 39676888252Smrg /* Width */ 39776888252Smrg outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20); 39876888252Smrg outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21); 39976888252Smrg /* Height */ 40076888252Smrg outw(pCir->PIOReg, ((hh << 8) & 0xff00) | 0x22); 40176888252Smrg outw(pCir->PIOReg, ((hh) & 0x0700) | 0x23); 40276888252Smrg 40376888252Smrg /* source = CPU ; description of bit 2 of GR30 in the 7548 manual 40476888252Smrg says that if we do color expansion we must zero the source 40576888252Smrg adress registers (GR2C, GR2D, GR2E) */ 40676888252Smrg outw(pCir->PIOReg, 0x2C); 40776888252Smrg outw(pCir->PIOReg, 0x2D); 40876888252Smrg outw(pCir->PIOReg, 0x2E); 40976888252Smrg 41076888252Smrg /* dest */ 41176888252Smrg outw(pCir->PIOReg, ((dest << 8) & 0xff00) | 0x28); 41276888252Smrg outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29); 41376888252Smrg outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A); 41476888252Smrg if (!pCir->chip.alp->autoStart) 41576888252Smrg outw(pCir->PIOReg, 0x0231); 41676888252Smrg 41776888252Smrg#ifdef ALP_DEBUG 41876888252Smrg ErrorF("AlpSubsequentCPUToScreenColorExpandFill x=%d y=%d w=%d h=%d\n", 41976888252Smrg x, y, w, h); 42076888252Smrg#endif 42176888252Smrg} 42276888252Smrg#endif 42376888252Smrg 42476888252Smrg#if 1 42576888252Smrgstatic void 42676888252SmrgAlpSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 42776888252Smrg int fg, int bg, 42876888252Smrg int rop, 42976888252Smrg unsigned int planemask) 43076888252Smrg{ 43176888252Smrg CirPtr pCir = CIRPTR(pScrn); 43276888252Smrg int pitch = pCir->pitch; 43376888252Smrg 43476888252Smrg#ifdef ALP_DEBUG 43576888252Smrg ErrorF("AlpSetupForCPUToScreenColorExpandFill " 43676888252Smrg "fg=%x bg=%x rop=%x planemask=%x, bpp=%d\n", 43776888252Smrg fg, bg, rop, planemask, pScrn->bitsPerPixel); 43876888252Smrg#endif 43976888252Smrg WAIT; 44076888252Smrg 44176888252Smrg SetupForRop(rop); 44276888252Smrg 44376888252Smrg /* GR30 = color expansion, CPU->display copy */ 44476888252Smrg /* Choses 8bpp / 16bpp color expansion */ 44576888252Smrg if (bg == -1) 44676888252Smrg { /* transparency requested */ 44776888252Smrg if (pScrn->bitsPerPixel > 8) /* 16 bpp */ 44876888252Smrg { 44976888252Smrg outw(pCir->PIOReg, 0x9C30); 45076888252Smrg 45176888252Smrg bg = ~fg; 45276888252Smrg /* transparent color compare */ 45376888252Smrg outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x34); 45476888252Smrg outw(pCir->PIOReg, ((bg) & 0xff00) | 0x35); 45576888252Smrg } else /* 8 bpp */ 45676888252Smrg { 45776888252Smrg outw(pCir->PIOReg, 0x8C30); 45876888252Smrg 45976888252Smrg bg = ~fg; 46076888252Smrg /* transparent color compare */ 46176888252Smrg outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x34); 46276888252Smrg outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x35); 46376888252Smrg } 46476888252Smrg 46576888252Smrg /* transparent color mask = 0 (all bits matters) */ 46676888252Smrg outw(pCir->PIOReg, 0x38); 46776888252Smrg outw(pCir->PIOReg, 0x39); 46876888252Smrg } 46976888252Smrg else 47076888252Smrg { 47176888252Smrg outw(pCir->PIOReg, 0x8430 |((pScrn->bitsPerPixel - 8) << 9)); 47276888252Smrg } 47376888252Smrg 47476888252Smrg outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x00); 47576888252Smrg outw(pCir->PIOReg, ((bg) & 0xff00) | 0x10); 47676888252Smrg 47776888252Smrg outw(pCir->PIOReg, ((fg << 8) & 0xff00) | 0x01); 47876888252Smrg outw(pCir->PIOReg, ((fg) & 0xff00) | 0x11); 47976888252Smrg 48076888252Smrg /* Set dest pitch */ 48176888252Smrg outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24); 48276888252Smrg outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25); 48376888252Smrg} 48476888252Smrg 48576888252Smrgstatic void 48676888252SmrgAlpSubsequentScanlineCPUToScreenColorExpandFill( 48776888252Smrg ScrnInfoPtr pScrn, 48876888252Smrg int x, int y, int w, int h, 48976888252Smrg int skipleft) 49076888252Smrg{ 49176888252Smrg CirPtr pCir = CIRPTR(pScrn); 49276888252Smrg AlpPtr pAlp = ALPPTR(pCir); 49376888252Smrg 49476888252Smrg int pitch = pCir->pitch; 49576888252Smrg 49676888252Smrg pAlp->SubsequentColorExpandScanlineByteWidth = 49776888252Smrg (w * pScrn->bitsPerPixel / 8) - 1; 49876888252Smrg pAlp->SubsequentColorExpandScanlineDWordWidth = 49976888252Smrg (w + 31) >> 5; 50076888252Smrg pAlp->SubsequentColorExpandScanlineDest = 50176888252Smrg y * pitch + x * pScrn->bitsPerPixel / 8; 50276888252Smrg 50376888252Smrg#ifdef ALP_DEBUG 50476888252Smrg ErrorF("AlpSubsequentScanlineCPUToScreenColorExpandFill x=%d y=%d w=%d h=%d skipleft=%d\n", 50576888252Smrg x, y, w, h, skipleft); 50676888252Smrg#endif 50776888252Smrg} 50876888252Smrg 50976888252Smrgstatic void 51076888252SmrgAlpSubsequentColorExpandScanline( 51176888252Smrg ScrnInfoPtr pScrn, 51276888252Smrg int bufno) 51376888252Smrg{ 51476888252Smrg CirPtr pCir = CIRPTR(pScrn); 51576888252Smrg AlpPtr pAlp = ALPPTR(pCir); 51676888252Smrg int dest=pAlp->SubsequentColorExpandScanlineDest; 51776888252Smrg int ww=pAlp->SubsequentColorExpandScanlineByteWidth; 51876888252Smrg int width=pAlp->SubsequentColorExpandScanlineDWordWidth; 51976888252Smrg CARD32* from; 52076888252Smrg volatile CARD32 *to; 52176888252Smrg 52276888252Smrg#ifdef ALP_DEBUG 52376888252Smrg ErrorF("AlpSubsequentColorExpandScanline\n"); 52476888252Smrg#endif 52576888252Smrg 52676888252Smrg pAlp->SubsequentColorExpandScanlineDest += pCir->pitch; 52776888252Smrg 52876888252Smrg to = (CARD32*) pCir->FbBase; 52976888252Smrg from = (CARD32*) (pCir->ScanlineColorExpandBuffers[bufno]); 53076888252Smrg WAIT_1; 53176888252Smrg 53276888252Smrg /* Width */ 53376888252Smrg outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20); 53476888252Smrg outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21); 53576888252Smrg 53676888252Smrg /* Height = 1 */ 53776888252Smrg outw(pCir->PIOReg, 0x22); 53876888252Smrg outw(pCir->PIOReg, 0x23); 53976888252Smrg 54076888252Smrg /* source = CPU ; description of bit 2 of GR30 in the 7548 manual 54176888252Smrg says that if we do color expansion we must zero the source 54276888252Smrg adress registers (GR2C, GR2D, GR2E) */ 54376888252Smrg outw(pCir->PIOReg, 0x2C); 54476888252Smrg outw(pCir->PIOReg, 0x2D); 54576888252Smrg outw(pCir->PIOReg, 0x2E); 54676888252Smrg 54776888252Smrg /* dest */ 54876888252Smrg outw(pCir->PIOReg, ((dest << 8) & 0xff00) | 0x28); 54976888252Smrg outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29); 55076888252Smrg write_mem_barrier(); 55176888252Smrg 55276888252Smrg#ifdef ALP_DEBUG 55376888252Smrg ErrorF("AlpSubsequentColorExpandScanline (2)\n"); 55476888252Smrg#endif 55576888252Smrg 55676888252Smrg outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A); 55776888252Smrg if (!pCir->chip.alp->autoStart) 55876888252Smrg outw(pCir->PIOReg, 0x0231); 55976888252Smrg 56076888252Smrg { 56176888252Smrg int i; 56276888252Smrg for (i=0; i<width; i++) 56376888252Smrg *to=*(from++); 56476888252Smrg write_mem_barrier(); 56576888252Smrg } 56676888252Smrg 56776888252Smrg#ifdef ALP_DEBUG 56876888252Smrg ErrorF("AlpSubsequentColorExpandScanline (3)\n"); 56976888252Smrg#endif 57076888252Smrg} 57176888252Smrg#endif 57276888252Smrg 57376888252Smrgstatic void 57476888252SmrgAlpAccelEngineInit(ScrnInfoPtr pScrn) 57576888252Smrg{ 57676888252Smrg CirPtr pCir = CIRPTR(pScrn); 57776888252Smrg 57876888252Smrg outw(pCir->PIOReg, 0x200E); /* enable writes to gr33 */ 57976888252Smrg /* Setup things for autostart */ 58076888252Smrg if (pCir->properties & ACCEL_AUTOSTART) { 58176888252Smrg outw(pCir->PIOReg, 0x8031); /* enable autostart */ 58276888252Smrg pCir->chip.alp->waitMsk = 0x10; 58376888252Smrg pCir->chip.alp->autoStart = TRUE; 58476888252Smrg } else { 58576888252Smrg pCir->chip.alp->waitMsk = 0x1; 58676888252Smrg pCir->chip.alp->autoStart = FALSE; 58776888252Smrg } 58876888252Smrg} 58976888252Smrg 59076888252SmrgBool 59176888252SmrgAlpXAAInit(ScreenPtr pScreen) 59276888252Smrg{ 59376888252Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 59476888252Smrg CirPtr pCir = CIRPTR(pScrn); 59576888252Smrg AlpPtr pAlp = ALPPTR(pCir); 59676888252Smrg XAAInfoRecPtr XAAPtr; 59776888252Smrg 59876888252Smrg pCir->InitAccel = AlpAccelEngineInit; 59976888252Smrg#ifdef ALP_DEBUG 60076888252Smrg ErrorF("AlpXAAInit\n"); 60176888252Smrg#endif 60276888252Smrg 60376888252Smrg XAAPtr = XAACreateInfoRec(); 60476888252Smrg if (!XAAPtr) return FALSE; 60576888252Smrg 60676888252Smrg /* Pixmap cache */ 60776888252Smrg XAAPtr->Flags |= LINEAR_FRAMEBUFFER; 60876888252Smrg XAAPtr->Sync = AlpSync; 60976888252Smrg 61076888252Smrg XAAPtr->SetupForScreenToScreenCopy = AlpSetupForScreenToScreenCopy; 61176888252Smrg XAAPtr->SubsequentScreenToScreenCopy = AlpSubsequentScreenToScreenCopy; 61276888252Smrg XAAPtr->ScreenToScreenCopyFlags = 61376888252Smrg NO_TRANSPARENCY | NO_PLANEMASK; 61476888252Smrg 61576888252Smrg XAAPtr->SetupForSolidFill = AlpSetupForSolidFill; 61676888252Smrg XAAPtr->SubsequentSolidFillRect = AlpSubsequentSolidFillRect; 61776888252Smrg XAAPtr->SubsequentSolidFillTrap = NULL; 61876888252Smrg XAAPtr->SolidFillFlags = NO_PLANEMASK; 61976888252Smrg 62076888252Smrg if (pCir->Chipset == PCI_CHIP_GD7548) { 62176888252Smrg if (pAlp->monoPattern8x8) { 62276888252Smrg XAAPtr->SetupForMono8x8PatternFill 62376888252Smrg = AlpSetupForMono8x8PatternFill; 62476888252Smrg XAAPtr->SubsequentMono8x8PatternFillRect 62576888252Smrg = AlpSubsequentMono8x8PatternFillRect; 62676888252Smrg XAAPtr->SubsequentMono8x8PatternFillTrap = NULL; 62776888252Smrg XAAPtr->Mono8x8PatternFillFlags = 62876888252Smrg NO_PLANEMASK | 62976888252Smrg HARDWARE_PATTERN_PROGRAMMED_BITS | BIT_ORDER_IN_BYTE_MSBFIRST; 63076888252Smrg } 63176888252Smrg#if 1 63276888252Smrg /* kludge: since XF86 does not support byte-padded 63376888252Smrg mono bitmaps (only dword-padded), use the 63476888252Smrg scanline version */ 63576888252Smrg XAAPtr->SetupForScanlineCPUToScreenColorExpandFill = 63676888252Smrg AlpSetupForScanlineCPUToScreenColorExpandFill; 63776888252Smrg XAAPtr->SubsequentScanlineCPUToScreenColorExpandFill = 63876888252Smrg AlpSubsequentScanlineCPUToScreenColorExpandFill; 63976888252Smrg XAAPtr->SubsequentColorExpandScanline = 64076888252Smrg AlpSubsequentColorExpandScanline; 64176888252Smrg { 64276888252Smrg const int NumScanlineColorExpandBuffers = 2; 64376888252Smrg int i; 64476888252Smrg int buffer_size = (pCir->pScrn->virtualX + 31) & ~31; 64576888252Smrg#ifdef ALP_DEBUG 64676888252Smrg ErrorF("Computing buffers for %d pixel lines\n", 64776888252Smrg pCir->pScrn->virtualX); 64876888252Smrg#endif 64976888252Smrg XAAPtr->NumScanlineColorExpandBuffers = 65076888252Smrg NumScanlineColorExpandBuffers; 65176888252Smrg XAAPtr->ScanlineColorExpandBuffers = 65276888252Smrg pCir->ScanlineColorExpandBuffers = (unsigned char **) 65376888252Smrg (malloc(sizeof(unsigned char *) * 65476888252Smrg NumScanlineColorExpandBuffers)); 65576888252Smrg /* TODO: are those mallocs to be freed ? */ 65676888252Smrg 65776888252Smrg for(i=0; i<NumScanlineColorExpandBuffers; i++) 65876888252Smrg pCir->ScanlineColorExpandBuffers[i] = (unsigned char *) 65976888252Smrg malloc(buffer_size); 66076888252Smrg } 66176888252Smrg XAAPtr->ScanlineCPUToScreenColorExpandFillFlags = 66276888252Smrg NO_PLANEMASK | BIT_ORDER_IN_BYTE_MSBFIRST | 66376888252Smrg SCANLINE_PAD_DWORD | ROP_NEEDS_SOURCE; 66476888252Smrg#endif 66576888252Smrg#if 0 66676888252Smrg /* Currently disabled: XF86 sends DWORD-padded data, 66776888252Smrg not byte-padded */ 66876888252Smrg XAAPtr->SetupForCPUToScreenColorExpandFill = 66976888252Smrg AlpSetupForCPUToScreenColorExpandFill; 67076888252Smrg XAAPtr->SubsequentCPUToScreenColorExpandFill = 67176888252Smrg AlpSubsequentCPUToScreenColorExpandFill; 67276888252Smrg XAAPtr->ColorExpandBase = pCir->FbBase + 4; 67376888252Smrg XAAPtr->CPUToScreenColorExpandFillFlags = 67476888252Smrg NO_PLANEMASK | BIT_ORDER_IN_BYTE_MSBFIRST | 67576888252Smrg SCANLINE_PAD_DWORD | ROP_NEEDS_SOURCE | 67676888252Smrg CPU_TRANSFER_PAD_DWORD | CPU_TRANSFER_BASE_FIXED; 67776888252Smrg#endif 67876888252Smrg } 67976888252Smrg 68076888252Smrg AlpAccelEngineInit(pScrn); 68176888252Smrg 68276888252Smrg pCir->AccelInfoRec = XAAPtr; 68376888252Smrg 68476888252Smrg if (!XAAInit(pScreen, XAAPtr)) 68576888252Smrg return FALSE; 68676888252Smrg 68776888252Smrg return TRUE; 68876888252Smrg} 68976888252Smrg 690