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