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