176888252Smrg/* (c) Itai Nahshon */ 276888252Smrg/* #define DEBUG */ 376888252Smrg 476888252Smrg#ifdef HAVE_CONFIG_H 576888252Smrg#include "config.h" 676888252Smrg#endif 776888252Smrg 876888252Smrg#include "xf86.h" 976888252Smrg#include "xf86_OSproc.h" 1076888252Smrg#include "compiler.h" 1176888252Smrg 1276888252Smrg#include "xf86Pci.h" 1376888252Smrg 1476888252Smrg#include "vgaHW.h" 1576888252Smrg 1676888252Smrg#include "cir.h" 1776888252Smrg#define _ALP_PRIVATE_ 1876888252Smrg#include "alp.h" 1976888252Smrg 2063847c39Smrg#ifdef HAVE_XAA_H 2176888252Smrg#ifdef DEBUG 2276888252Smrg#define minb(p) \ 2376888252Smrg (ErrorF("minb(%X)\n", p),\ 2476888252Smrg MMIO_IN8(pCir->chip.alp->BLTBase, (p))) 2576888252Smrg#define moutb(p,v) \ 2676888252Smrg (ErrorF("moutb(%X, %X)\n", p,v),\ 2776888252Smrg MMIO_OUT8(pCir->chip.alp->BLTBase, (p),(v))) 2876888252Smrg#define vga_minb(p) \ 2976888252Smrg (ErrorF("minb(%X)\n", p),\ 3076888252Smrg MMIO_IN8(hwp->MMIOBase, (hwp->MMIOOffset + (p)))) 3176888252Smrg#define vga_moutb(p,v) \ 3276888252Smrg { ErrorF("moutb(%X, %X)\n", p,v);\ 3376888252Smrg MMIO_OUT8(hwp->MMIOBase, (hwp->MMIOOffset + (p)),(v));} 3476888252Smrg#define minl(p) \ 3576888252Smrg (ErrorF("minl(%X)\n", p),\ 3676888252Smrg MMIO_IN32(pCir->chip.alp->BLTBase, (p))) 3776888252Smrg#define moutl(p,v) \ 3876888252Smrg (ErrorF("moutl(%X, %X)\n", p,v),\ 3976888252Smrg MMIO_OUT32(pCir->chip.alp->BLTBase, (p),(v))) 4076888252Smrg#else 4176888252Smrg#define minb(p) MMIO_IN8(pCir->chip.alp->BLTBase, (p)) 4276888252Smrg#define moutb(p,v) MMIO_OUT8(pCir->chip.alp->BLTBase, (p),(v)) 4376888252Smrg#define vga_minb(p) MMIO_IN8(hwp->MMIIOBase, (hwp->MMIOOffset + (p))) 4476888252Smrg#define vga_moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (hwp->MMIOOffset + (p)),(v)) 4576888252Smrg#define minl(p) MMIO_IN32(pCir->chip.alp->BLTBase, (p)) 4676888252Smrg#define moutl(p,v) MMIO_OUT32(pCir->chip.alp->BLTBase, (p),(v)) 4776888252Smrg#endif 4876888252Smrg 4976888252Smrgstatic const CARD8 translated_rop[] = 5076888252Smrg{ 5176888252Smrg /* GXclear */ 0x00U, 5276888252Smrg /* GXand */ 0x05U, 5376888252Smrg /* GXandreverse */ 0x09U, 5476888252Smrg /* GXcopy */ 0x0DU, 5576888252Smrg /* GXandinversted */ 0x50U, 5676888252Smrg /* GXnoop */ 0x06U, 5776888252Smrg /* GXxor */ 0x59U, 5876888252Smrg /* GXor */ 0x6DU, 5976888252Smrg /* GXnor */ 0x90U, 6076888252Smrg /* GXequiv */ 0x95U, 6176888252Smrg /* GXinvert */ 0x0BU, 6276888252Smrg /* GXorReverse */ 0xADU, 6376888252Smrg /* GXcopyInverted */ 0xD0U, 6476888252Smrg /* GXorInverted */ 0xD6U, 6576888252Smrg /* GXnand */ 0xDAU, 6676888252Smrg /* GXset */ 0x0EU 6776888252Smrg}; 6876888252Smrg 6976888252Smrg#define WAIT while(minl(0x40) & pCir->chip.alp->waitMsk){}; 7076888252Smrg#define WAIT_1 while((minl(0x40)) & 0x1){}; 7176888252Smrg 7276888252Smrgstatic void AlpSync(ScrnInfoPtr pScrn) 7376888252Smrg{ 7476888252Smrg CirPtr pCir = CIRPTR(pScrn); 7576888252Smrg#ifdef ALP_DEBUG 7676888252Smrg ErrorF("AlpSync mm\n"); 7776888252Smrg#endif 7876888252Smrg WAIT_1; 7976888252Smrg return; 8076888252Smrg} 8176888252Smrg 8276888252Smrgstatic void 8376888252SmrgAlpSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, 8476888252Smrg unsigned int planemask, int trans_color) 8576888252Smrg{ 8676888252Smrg CirPtr pCir = CIRPTR(pScrn); 8776888252Smrg int pitch = pCir->pitch; 8876888252Smrg 8976888252Smrg WAIT; 9076888252Smrg 9176888252Smrg pCir->chip.alp->transRop = translated_rop[rop] << 16; 9276888252Smrg 9376888252Smrg#ifdef ALP_DEBUG 9476888252Smrg ErrorF("AlpSetupForScreenToScreenCopy xdir=%d ydir=%d rop=%x planemask=%x trans_color=%x\n", 9576888252Smrg xdir, ydir, rop, planemask, trans_color); 9676888252Smrg#endif 9776888252Smrg moutl(0x0C, (pitch << 16) | pitch); 9876888252Smrg 9976888252Smrg} 10076888252Smrg 10176888252Smrgstatic void 10276888252SmrgAlpSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, 10376888252Smrg int y2, int w, int h) 10476888252Smrg{ 10576888252Smrg CirPtr pCir = CIRPTR(pScrn); 10676888252Smrg int source, dest; 10776888252Smrg int hh, ww; 10876888252Smrg int decrement = 0; 10976888252Smrg int pitch = pCir->pitch; 11076888252Smrg 11176888252Smrg ww = ((w * pScrn->bitsPerPixel / 8) - 1) & 0x1fff; 11276888252Smrg hh = (h - 1) & 0x1fff; 11376888252Smrg dest = y2 * pitch + x2 * pScrn->bitsPerPixel / 8; 11476888252Smrg source = y1 * pitch + x1 * pScrn->bitsPerPixel / 8; 11576888252Smrg if (dest > source) { 11676888252Smrg decrement = 1; 11776888252Smrg dest += hh * pitch + ww; 11876888252Smrg source += hh * pitch + ww; 11976888252Smrg } 12076888252Smrg 12176888252Smrg WAIT; 12276888252Smrg 12376888252Smrg /* Width / Height */ 12476888252Smrg moutl(0x08, (hh << 16) | ww); 12576888252Smrg /* source */ 12676888252Smrg moutl(0x14, source & 0x3fffff); 12776888252Smrg moutl(0x18, pCir->chip.alp->transRop | decrement); 12876888252Smrg 12976888252Smrg /* dest */ 13076888252Smrg write_mem_barrier(); 13176888252Smrg moutl(0x10, dest & 0x3fffff); 13276888252Smrg 13376888252Smrg#ifdef ALP_DEBUG 13476888252Smrg ErrorF("AlpSubsequentScreenToScreenCopy x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n", 13576888252Smrg x1, y1, x2, y2, w, h); 13676888252Smrg ErrorF("AlpSubsequentScreenToScreenCopy s=%d d=%d ww=%d hh=%d\n", 13776888252Smrg source, dest, ww, hh); 13876888252Smrg#endif 13976888252Smrg if (!pCir->chip.alp->autoStart) { 14076888252Smrg CARD32 val = minl(0x40); 14176888252Smrg moutl(0x40,val | 0x02); 14276888252Smrg } 14376888252Smrg write_mem_barrier(); 14476888252Smrg} 14576888252Smrg 14676888252Smrg 14776888252Smrgstatic void 14876888252SmrgAlpSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 14976888252Smrg unsigned int planemask) 15076888252Smrg{ 15176888252Smrg CirPtr pCir = CIRPTR(pScrn); 15276888252Smrg int pitch = pCir->pitch; 15376888252Smrg 15476888252Smrg WAIT; 15576888252Smrg 15676888252Smrg#ifdef ALP_DEBUG 15776888252Smrg ErrorF("AlpSetupForSolidFill color=%x rop=%x planemask=%x\n", 15876888252Smrg color, rop, planemask); 15976888252Smrg#endif 16076888252Smrg 16176888252Smrg moutl(0x04, color & 0xffffff); 16276888252Smrg 16376888252Smrg /* Set dest pitch */ 16476888252Smrg moutl(0x0C, pitch & 0x1fff); 16576888252Smrg moutl(0x18, (((pScrn->bitsPerPixel - 8) << 1)) 16676888252Smrg | translated_rop[rop] << 16 16776888252Smrg | 0x040000C0); 16876888252Smrg} 16976888252Smrg 17076888252Smrgstatic void 17176888252SmrgAlpSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 17276888252Smrg{ 17376888252Smrg int dest; 17476888252Smrg int hh, ww; 17576888252Smrg CirPtr pCir = CIRPTR(pScrn); 17676888252Smrg int pitch = pCir->pitch; 17776888252Smrg 17876888252Smrg ww = ((w * pScrn->bitsPerPixel / 8) - 1) & 0x1fff; 17976888252Smrg hh = (h - 1) & 0x7ff; 18076888252Smrg dest = y * pitch + x * pScrn->bitsPerPixel / 8; 18176888252Smrg 18276888252Smrg WAIT; 18376888252Smrg 18476888252Smrg /* Width / Height */ 18576888252Smrg write_mem_barrier(); 18676888252Smrg moutl(0x08, (hh << 16) | ww); 18776888252Smrg 18876888252Smrg#ifdef ALP_DEBUG 18976888252Smrg ErrorF("AlpSubsequentSolidFillRect x=%d y=%d w=%d h=%d\n", 19076888252Smrg x, y, w, h); 19176888252Smrg#endif 19276888252Smrg /* dest */ 19376888252Smrg moutl(0x10, (dest & 0x3fffff)); 19476888252Smrg 19576888252Smrg if (!pCir->chip.alp->autoStart) { 19676888252Smrg CARD32 val = minl(0x40); 19776888252Smrg moutl(0x40, val | 0x02); 19876888252Smrg } 19976888252Smrg write_mem_barrier(); 20076888252Smrg} 20176888252Smrg 20276888252Smrgstatic void 20376888252SmrgAlpAccelEngineInit(ScrnInfoPtr pScrn) 20476888252Smrg{ 20576888252Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 20676888252Smrg CirPtr pCir = CIRPTR(pScrn); 20776888252Smrg 20876888252Smrg if (pCir->Chipset != PCI_CHIP_GD7548) { 20976888252Smrg vga_moutb(0x3CE, 0x0E); /* enable writes to gr33 */ 21076888252Smrg vga_moutb(0x3CF, 0x20); /* enable writes to gr33 */ 21176888252Smrg } 21276888252Smrg if (pCir->properties & ACCEL_AUTOSTART) { 21376888252Smrg moutl(0x40, 0x80); /* enable autostart */ 21476888252Smrg pCir->chip.alp->waitMsk = 0x10; 21576888252Smrg pCir->chip.alp->autoStart = TRUE; 21676888252Smrg } else { 21776888252Smrg pCir->chip.alp->waitMsk = 0x1; 21876888252Smrg pCir->chip.alp->autoStart = FALSE; 21976888252Smrg } 22076888252Smrg} 22176888252Smrg 22276888252SmrgBool 22376888252SmrgAlpXAAInitMMIO(ScreenPtr pScreen) 22476888252Smrg{ 22563847c39Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 22676888252Smrg CirPtr pCir = CIRPTR(pScrn); 22776888252Smrg XAAInfoRecPtr XAAPtr; 22876888252Smrg 22976888252Smrg pCir->InitAccel = AlpAccelEngineInit; 23076888252Smrg#ifdef ALP_DEBUG 23176888252Smrg ErrorF("AlpXAAInitMM\n"); 23276888252Smrg#endif 23376888252Smrg 23476888252Smrg XAAPtr = XAACreateInfoRec(); 23576888252Smrg if (!XAAPtr) return FALSE; 23676888252Smrg 23776888252Smrg XAAPtr->Flags |= LINEAR_FRAMEBUFFER; 23876888252Smrg XAAPtr->Sync = AlpSync; 23976888252Smrg 24076888252Smrg XAAPtr->SetupForScreenToScreenCopy = AlpSetupForScreenToScreenCopy; 24176888252Smrg XAAPtr->SubsequentScreenToScreenCopy = AlpSubsequentScreenToScreenCopy; 24276888252Smrg XAAPtr->ScreenToScreenCopyFlags = 24376888252Smrg (NO_TRANSPARENCY | NO_PLANEMASK); 24476888252Smrg 24576888252Smrg XAAPtr->SetupForSolidFill = AlpSetupForSolidFill; 24676888252Smrg XAAPtr->SubsequentSolidFillRect = AlpSubsequentSolidFillRect; 24776888252Smrg XAAPtr->SubsequentSolidFillTrap = NULL; 24876888252Smrg XAAPtr->SolidFillFlags = NO_PLANEMASK; 24976888252Smrg 25076888252Smrg switch (pCir->Chipset) { 25176888252Smrg case PCI_CHIP_GD5480: 25276888252Smrg case PCI_CHIP_GD5446: 25376888252Smrg pCir->chip.alp->BLTBase = pCir->IOBase + 0x100; 25476888252Smrg break; 25576888252Smrg default: 25676888252Smrg pCir->chip.alp->BLTBase = pCir->IOBase; 25776888252Smrg break; 25876888252Smrg } 25976888252Smrg 26076888252Smrg AlpAccelEngineInit(pScrn); 26176888252Smrg 26276888252Smrg pCir->AccelInfoRec = XAAPtr; 26376888252Smrg 26476888252Smrg if (!XAAInit(pScreen, XAAPtr)) 26576888252Smrg return FALSE; 26676888252Smrg 26776888252Smrg return TRUE; 26876888252Smrg} 26976888252Smrg 27063847c39Smrg#endif 271