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