117a48c7cSmrg
217a48c7cSmrg#ifdef HAVE_CONFIG_H
317a48c7cSmrg#include "config.h"
417a48c7cSmrg#endif
517a48c7cSmrg
617a48c7cSmrg#include "apm.h"
717a48c7cSmrg#include "miline.h"
817a48c7cSmrg
90dd80ee0Smrg#ifdef HAVE_XAA_H
1017a48c7cSmrg/* Defines */
1117a48c7cSmrg#define MAXLOOP 1000000
1217a48c7cSmrg
1317a48c7cSmrg/* Translation from X ROP's to APM ROP's. */
1417a48c7cSmrgstatic unsigned char apmROP[] = {
1517a48c7cSmrg  0,
1617a48c7cSmrg  0x88,
1717a48c7cSmrg  0x44,
1817a48c7cSmrg  0xCC,
1917a48c7cSmrg  0x22,
2017a48c7cSmrg  0xAA,
2117a48c7cSmrg  0x66,
2217a48c7cSmrg  0xEE,
2317a48c7cSmrg  0x11,
2417a48c7cSmrg  0x99,
2517a48c7cSmrg  0x55,
2617a48c7cSmrg  0xDD,
2717a48c7cSmrg  0x33,
2817a48c7cSmrg  0xBB,
2917a48c7cSmrg  0x77,
3017a48c7cSmrg  0xFF
3117a48c7cSmrg};
3217a48c7cSmrg
3317a48c7cSmrg
3417a48c7cSmrg#include "apm_funcs.c"
3517a48c7cSmrg
3617a48c7cSmrg#define PSZ	24
3717a48c7cSmrg#include "apm_funcs.c"
3817a48c7cSmrg
3917a48c7cSmrgstatic void
4017a48c7cSmrgApmRemoveStipple(FBAreaPtr area)
4117a48c7cSmrg{
4217a48c7cSmrg    ((struct ApmStippleCacheRec *)area->devPrivate.ptr)->apmStippleCached = FALSE;
4317a48c7cSmrg}
4417a48c7cSmrg
4517a48c7cSmrgstatic void
4617a48c7cSmrgApmMoveStipple(FBAreaPtr from, FBAreaPtr to)
4717a48c7cSmrg{
4817a48c7cSmrg    struct ApmStippleCacheRec *pApm = (struct ApmStippleCacheRec *)to->devPrivate.ptr;
4917a48c7cSmrg
5017a48c7cSmrg    pApm->apmStippleCache.x = to->box.x1;
5117a48c7cSmrg    pApm->apmStippleCache.y += to->box.y1 - from->box.y1;
5217a48c7cSmrg    /* TODO : move data */
5317a48c7cSmrg}
5417a48c7cSmrg
5517a48c7cSmrg/*
5617a48c7cSmrg * ApmCacheMonoStipple
5717a48c7cSmrg * because my poor AT3D needs stipples stored linearly in memory.
5817a48c7cSmrg */
5917a48c7cSmrgstatic XAACacheInfoPtr
6017a48c7cSmrgApmCacheMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
6117a48c7cSmrg{
6217a48c7cSmrg    APMDECL(pScrn);
6317a48c7cSmrg    int		w = pPix->drawable.width, W = (w + 31) & ~31;
6417a48c7cSmrg    int		h = pPix->drawable.height;
6517a48c7cSmrg    int		i, j, dwords, mem, width, funcNo;
6617a48c7cSmrg    FBAreaPtr	draw;
6717a48c7cSmrg    struct ApmStippleCacheRec	*pCache;
6817a48c7cSmrg    unsigned char	*srcPtr;
6917a48c7cSmrg    CARD32		*dstPtr;
7017a48c7cSmrg    static StippleScanlineProcPtr *StippleTab = NULL;
7117a48c7cSmrg
7217a48c7cSmrg    if (!StippleTab)
7317a48c7cSmrg        StippleTab = XAAGetStippleScanlineFuncMSBFirst();
7417a48c7cSmrg
7517a48c7cSmrg    for (i = 0; i < APM_CACHE_NUMBER; i++)
7617a48c7cSmrg	if ((pApm->apmCache[i].apmStippleCache.serialNumber == pPix->drawable.serialNumber)
7717a48c7cSmrg		&& pApm->apmCache[i].apmStippleCached &&
7817a48c7cSmrg		(pApm->apmCache[i].apmStippleCache.fg == -1) &&
7917a48c7cSmrg		(pApm->apmCache[i].apmStippleCache.bg == -1)) {
8017a48c7cSmrg	    pApm->apmCache[i].apmStippleCache.trans_color = -1;
8117a48c7cSmrg	    return &pApm->apmCache[i].apmStippleCache;
8217a48c7cSmrg	}
8317a48c7cSmrg    if ((i = ++pApm->apmCachePtr) >= APM_CACHE_NUMBER)
8417a48c7cSmrg	i = pApm->apmCachePtr = 0;
8517a48c7cSmrg    pCache = &pApm->apmCache[i];
8617a48c7cSmrg    if (pCache->apmStippleCached) {
8717a48c7cSmrg	pCache->apmStippleCached = FALSE;
8817a48c7cSmrg	xf86FreeOffscreenArea(pCache->area);
8917a48c7cSmrg    }
9017a48c7cSmrg
9117a48c7cSmrg    draw = xf86AllocateLinearOffscreenArea(pApm->pScreen, (W * h + 7) / 8,
9217a48c7cSmrg				    (pApm->CurrentLayout.mask32 + 1) << 1,
9317a48c7cSmrg				    ApmMoveStipple, ApmRemoveStipple, pCache);
9417a48c7cSmrg    if (!draw)
9517a48c7cSmrg	return NULL;	/* Let's hope this will never happen... */
9617a48c7cSmrg
9717a48c7cSmrg    pCache->area = draw;
9817a48c7cSmrg    pCache->apmStippleCache.serialNumber = pPix->drawable.serialNumber;
9917a48c7cSmrg    pCache->apmStippleCache.trans_color =
10017a48c7cSmrg	pCache->apmStippleCache.bg =
10117a48c7cSmrg	pCache->apmStippleCache.fg = -1;
10217a48c7cSmrg    pCache->apmStippleCache.orig_w = w;
10317a48c7cSmrg    pCache->apmStippleCache.orig_h = h;
10417a48c7cSmrg    pCache->apmStippleCache.x = draw->box.x1;
10517a48c7cSmrg    pCache->apmStippleCache.y = draw->box.y1 + ((pCache - pApm->apmCache) + 1) * pApm->CurrentLayout.Scanlines;
10617a48c7cSmrg    mem = ((draw->box.x2 - draw->box.x1) * (draw->box.y2 - draw->box.y1) *
10717a48c7cSmrg			pScrn->bitsPerPixel) / (W * h);
10817a48c7cSmrg    width = 2;
10917a48c7cSmrg    while (width * width <= mem)
11017a48c7cSmrg	width++;
11117a48c7cSmrg    width--;
11217a48c7cSmrg    pCache->apmStippleCache.w = (width * W + pScrn->bitsPerPixel - 1) /
11317a48c7cSmrg			pScrn->bitsPerPixel;
11417a48c7cSmrg    pCache->apmStippleCache.h = ((draw->box.x2 - draw->box.x1) *
11517a48c7cSmrg			(draw->box.y2 - draw->box.y1)) /
11617a48c7cSmrg			pCache->apmStippleCache.w;
11717a48c7cSmrg    pCache->apmStippleCached = TRUE;
11817a48c7cSmrg
11917a48c7cSmrg    if (w < 32) {
12017a48c7cSmrg	if (w & (w - 1))	funcNo = 1;
12117a48c7cSmrg	else			funcNo = 0;
12217a48c7cSmrg    } else			funcNo = 2;
12317a48c7cSmrg
12417a48c7cSmrg    dstPtr = ((CARD32 *)pApm->FbBase) + (draw->box.x1 +
12517a48c7cSmrg			draw->box.y1*pApm->CurrentLayout.bytesPerScanline) / 4;
12617a48c7cSmrg    j = 0;
12717a48c7cSmrg    dwords = (pCache->apmStippleCache.w * pScrn->bitsPerPixel) / 32;
12817a48c7cSmrg    while (j + h <= pCache->apmStippleCache.h) {
12917a48c7cSmrg	srcPtr = (unsigned char *)pPix->devPrivate.ptr;
13017a48c7cSmrg	for (i = h; --i >= 0; ) {
13117a48c7cSmrg	    StippleTab[funcNo](dstPtr, (CARD32 *)srcPtr, 0, w, dwords);
13217a48c7cSmrg	    srcPtr += pPix->devKind;
13317a48c7cSmrg	    dstPtr += dwords;
13417a48c7cSmrg	}
13517a48c7cSmrg	j += h;
13617a48c7cSmrg    }
13717a48c7cSmrg    srcPtr = (unsigned char *)pPix->devPrivate.ptr;
13817a48c7cSmrg    for (i = pCache->apmStippleCache.h - j ; --i >= 0; ) {
13917a48c7cSmrg	StippleTab[funcNo](dstPtr, (CARD32 *)srcPtr, 0, w, dwords);
14017a48c7cSmrg	srcPtr += pPix->devKind;
14117a48c7cSmrg	dstPtr += dwords;
14217a48c7cSmrg    }
14317a48c7cSmrg
14417a48c7cSmrg    return &pCache->apmStippleCache;
14517a48c7cSmrg}
14617a48c7cSmrg
14717a48c7cSmrg#if 0
14817a48c7cSmrgextern GCOps XAAPixmapOps;
14917a48c7cSmrgstatic RegionPtr (*SaveCopyAreaPixmap)(DrawablePtr, DrawablePtr, GC *, int, int, int, int, int, int);
15017a48c7cSmrg
15117a48c7cSmrgstatic RegionPtr
15217a48c7cSmrgApmCopyAreaPixmap(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GC *pGC,
15317a48c7cSmrg		int srcx, int srcy,
15417a48c7cSmrg		int width, int height,
15517a48c7cSmrg		int dstx, int dsty )
15617a48c7cSmrg{
15717a48c7cSmrg    register int Scanlines;
15817a48c7cSmrg    int is;
15917a48c7cSmrg    int id;
16017a48c7cSmrg    int sx = 0, sy = 0, dx = 0, dy = 0, pitch;
16117a48c7cSmrg    RegionPtr pReg;
16217a48c7cSmrg
16317a48c7cSmrg    if (APMPTR(xf86Screens[(pGC)->pScreen->myNum])->Chipset == AT3D) {
16417a48c7cSmrg	Scanlines = APMPTR(xf86Screens[(pGC)->pScreen->myNum])->CurrentLayout.Scanlines;
16517a48c7cSmrg	is = (pSrcDrawable->type == DRAWABLE_PIXMAP) ? APM_GET_PIXMAP_PRIVATE(pSrcDrawable)->num : 0;
16617a48c7cSmrg	id = (pDstDrawable->type == DRAWABLE_PIXMAP) ? APM_GET_PIXMAP_PRIVATE(pDstDrawable)->num : 0;
16717a48c7cSmrg	if (is) {
16817a48c7cSmrg	    sx = pSrcDrawable->x;
16917a48c7cSmrg	    sy = pSrcDrawable->y % Scanlines;
17017a48c7cSmrg	    pitch = 2 * pSrcDrawable->width;
17117a48c7cSmrg	    pSrcDrawable->x = (sx + ((PixmapPtr)pSrcDrawable)->devKind * sy) % pitch;
17217a48c7cSmrg	    pSrcDrawable->y = (sx + ((PixmapPtr)pSrcDrawable)->devKind * sy) / pitch;
17317a48c7cSmrg	    ((PixmapPtr)pSrcDrawable)->devKind = pitch;
17417a48c7cSmrg	    pSrcDrawable->depth = 16;
17517a48c7cSmrg	}
17617a48c7cSmrg	if (id) {
17717a48c7cSmrg	    dx = pDstDrawable->x;
17817a48c7cSmrg	    dy = pDstDrawable->y % Scanlines;
17917a48c7cSmrg	    pitch = 2 * pDstDrawable->width;
18017a48c7cSmrg	    pDstDrawable->x = (dx + ((PixmapPtr)pDstDrawable)->devKind * dy) % pitch;
18117a48c7cSmrg	    pDstDrawable->y = (dx + ((PixmapPtr)pDstDrawable)->devKind * dy) / pitch;
18217a48c7cSmrg	    ((PixmapPtr)pDstDrawable)->devKind = pitch;
18317a48c7cSmrg	    pDstDrawable->depth = 16;
18417a48c7cSmrg	}
18517a48c7cSmrg	pReg = (*SaveCopyAreaPixmap)(pSrcDrawable, pDstDrawable, pGC,
18617a48c7cSmrg					    srcx, srcy % Scanlines,
18717a48c7cSmrg					    width, height,
18817a48c7cSmrg					    dstx, dsty % Scanlines);
18917a48c7cSmrg	if (is) {
19017a48c7cSmrg	    pSrcDrawable->x = sx;
19117a48c7cSmrg	    pSrcDrawable->y = sy + is * Scanlines;
19217a48c7cSmrg	}
19317a48c7cSmrg	if (id) {
19417a48c7cSmrg	    pDstDrawable->x = dx;
19517a48c7cSmrg	    pDstDrawable->y = dy + id * Scanlines;
19617a48c7cSmrg	}
19717a48c7cSmrg	return pReg;
19817a48c7cSmrg    }
19917a48c7cSmrg    return (*SaveCopyAreaPixmap)(pSrcDrawable, pDstDrawable, pGC,
20017a48c7cSmrg					srcx, srcy,
20117a48c7cSmrg					width, height,
20217a48c7cSmrg					dstx, dsty);
20317a48c7cSmrg}
20417a48c7cSmrg#endif
20517a48c7cSmrg
20617a48c7cSmrgvoid ApmAccelReserveSpace(ApmPtr pApm)
20717a48c7cSmrg{
20817a48c7cSmrg    memType	mem, ScratchMemOffset;
20917a48c7cSmrg
2100dd80ee0Smrg    mem			= xf86ScreenToScrn(pApm->pScreen)->videoRam << 10;
21117a48c7cSmrg    /*
21217a48c7cSmrg     * Reserve at least four lines for mono to color expansion
21317a48c7cSmrg     */
21417a48c7cSmrg    ScratchMemOffset	= ((mem - pApm->OffscreenReserved) /
21517a48c7cSmrg			pApm->CurrentLayout.bytesPerScanline - 4) *
21617a48c7cSmrg			pApm->CurrentLayout.bytesPerScanline;
21717a48c7cSmrg    pApm->ScratchMemSize= mem - ScratchMemOffset - pApm->OffscreenReserved;
21817a48c7cSmrg    pApm->ScratchMemPtr	= pApm->ScratchMemOffset
21917a48c7cSmrg			= (memType)pApm->FbBase + ScratchMemOffset;
22017a48c7cSmrg    pApm->ScratchMemEnd	= (memType)pApm->FbBase + mem - pApm->OffscreenReserved;
22117a48c7cSmrg}
22217a48c7cSmrg
22317a48c7cSmrg/*********************************************************************************************/
22417a48c7cSmrg
22517a48c7cSmrgint
22617a48c7cSmrgApmAccelInit(ScreenPtr pScreen)
22717a48c7cSmrg{
2280dd80ee0Smrg    ScrnInfoPtr		pScrn = xf86ScreenToScrn(pScreen);
22917a48c7cSmrg    APMDECL(pScrn);
23017a48c7cSmrg    XAAInfoRecPtr	pXAAinfo;
23117a48c7cSmrg    BoxRec		AvailFBArea;
23217a48c7cSmrg    memType		mem, ScratchMemOffset;
23317a48c7cSmrg    int			i, stat;
23417a48c7cSmrg
23517a48c7cSmrg    pApm->AccelInfoRec	= pXAAinfo = XAACreateInfoRec();
23617a48c7cSmrg    if (!pXAAinfo)
23717a48c7cSmrg	return FALSE;
23817a48c7cSmrg
23917a48c7cSmrg    mem			= pScrn->videoRam << 10;
24017a48c7cSmrg    ScratchMemOffset	= pApm->ScratchMemOffset - (memType)pApm->FbBase;
24117a48c7cSmrg    switch (pApm->CurrentLayout.bitsPerPixel) {
24217a48c7cSmrg    case 8:
24317a48c7cSmrg    case 24:
24417a48c7cSmrg	pApm->ScratchMemWidth =
24517a48c7cSmrg		(mem - ScratchMemOffset - pApm->OffscreenReserved) / 1;
24617a48c7cSmrg	pApm->ScratchMem =
24717a48c7cSmrg		((ScratchMemOffset & 0xFFF000) << 4) |
24817a48c7cSmrg		    (ScratchMemOffset & 0xFFF);
24917a48c7cSmrg	break;
25017a48c7cSmrg
25117a48c7cSmrg    case 16:
25217a48c7cSmrg	pApm->ScratchMemWidth =
25317a48c7cSmrg		(mem - ScratchMemOffset - pApm->OffscreenReserved) / 2;
25417a48c7cSmrg	pApm->ScratchMem =
25517a48c7cSmrg		((ScratchMemOffset & 0xFFE000) << 3) |
25617a48c7cSmrg		    ((ScratchMemOffset & 0x1FFE) >> 1);
25717a48c7cSmrg	break;
25817a48c7cSmrg
25917a48c7cSmrg    case 32:
26017a48c7cSmrg	pApm->ScratchMemWidth =
26117a48c7cSmrg		(mem - ScratchMemOffset - pApm->OffscreenReserved) / 4;
26217a48c7cSmrg	pApm->ScratchMem =
26317a48c7cSmrg		((ScratchMemOffset & 0xFFC000) << 2) |
26417a48c7cSmrg		    ((ScratchMemOffset & 0x3FFC) >> 2);
26517a48c7cSmrg	break;
26617a48c7cSmrg    }
26717a48c7cSmrg    pApm->OffscreenReserved = mem - ScratchMemOffset;
26817a48c7cSmrg
26917a48c7cSmrg    /*
27017a48c7cSmrg     * Abort
27117a48c7cSmrg     */
27217a48c7cSmrg    if (pApm->Chipset == AP6422)
27317a48c7cSmrg	i = 4;
27417a48c7cSmrg    else
27517a48c7cSmrg	i = 8;
2760dd80ee0Smrg    stat = RDXL_M(0x1FC);
2770dd80ee0Smrg    while ((stat & (STATUS_HOSTBLTBUSY | STATUS_ENGINEBUSY)) ||
2780dd80ee0Smrg	    ((stat & STATUS_FIFO) < i)) {
2790dd80ee0Smrg	WRXB_M(0x1FC, 0);
28017a48c7cSmrg	stat = RDXL_M(0x1FC);
28117a48c7cSmrg    }
28217a48c7cSmrg
28317a48c7cSmrg    /* Setup current register values */
28417a48c7cSmrg    for (i = 0; i < sizeof(pApm->regcurr) / 4; i++)
28517a48c7cSmrg	((CARD32 *)curr)[i] = RDXL(0x30 + 4*i);
28617a48c7cSmrg
28717a48c7cSmrg    SETCLIP_CTRL(1);
28817a48c7cSmrg    SETCLIP_CTRL(0);
28917a48c7cSmrg    SETBYTEMASK(0x00);
29017a48c7cSmrg    SETBYTEMASK(0xFF);
29117a48c7cSmrg    SETROP(ROP_S_xor_D);
29217a48c7cSmrg    SETROP(ROP_S);
29317a48c7cSmrg
29417a48c7cSmrg#if 0
29517a48c7cSmrg    if (XAAPixmapOps.CopyArea != ApmCopyAreaPixmap) {
29617a48c7cSmrg	SaveCopyAreaPixmap = XAAPixmapOps.CopyArea;
29717a48c7cSmrg	XAAPixmapOps.CopyArea = ApmCopyAreaPixmap;
29817a48c7cSmrg    }
29917a48c7cSmrg#endif
30017a48c7cSmrg
30117a48c7cSmrg    ApmSetupXAAInfo(pApm, pXAAinfo);
30217a48c7cSmrg
3030dd80ee0Smrg    pApm->SetupForSolidFill		= ApmSetupForSolidFill;
3040dd80ee0Smrg    pApm->SubsequentSolidFillRect	= ApmSubsequentSolidFillRect;
3050dd80ee0Smrg    pApm->SetupForSolidFill24		= ApmSetupForSolidFill24;
3060dd80ee0Smrg    pApm->SubsequentSolidFillRect24	= ApmSubsequentSolidFillRect24;
3070dd80ee0Smrg    pApm->SetupForScreenToScreenCopy	= ApmSetupForScreenToScreenCopy;
3080dd80ee0Smrg    pApm->SubsequentScreenToScreenCopy	= ApmSubsequentScreenToScreenCopy;
3090dd80ee0Smrg    pApm->SetupForScreenToScreenCopy24	= ApmSetupForScreenToScreenCopy24;
3100dd80ee0Smrg    pApm->SubsequentScreenToScreenCopy24= ApmSubsequentScreenToScreenCopy24;
31117a48c7cSmrg
31217a48c7cSmrg    /*
31317a48c7cSmrg     * Init Rush extension.
31417a48c7cSmrg     * Must be initialized once per generation.
31517a48c7cSmrg     */
31617a48c7cSmrg#ifdef XF86RUSH_EXT
31717a48c7cSmrg    if (!pApm->CreatePixmap) {
31817a48c7cSmrg	pApm->CreatePixmap	= pScreen->CreatePixmap;
31917a48c7cSmrg	pApm->DestroyPixmap	= pScreen->DestroyPixmap;
32017a48c7cSmrg    }
32117a48c7cSmrg    XFree86RushExtensionInit(pScreen);
32217a48c7cSmrg#endif
32317a48c7cSmrg
32417a48c7cSmrg    /* Pixmap cache setup */
32517a48c7cSmrg    pXAAinfo->CachePixelGranularity = (pApm->CurrentLayout.mask32 + 1) << 1;
32617a48c7cSmrg    AvailFBArea.x1 = 0;
32717a48c7cSmrg    AvailFBArea.y1 = 0;
32817a48c7cSmrg    AvailFBArea.x2 = pScrn->displayWidth;
32917a48c7cSmrg    AvailFBArea.y2 = (pScrn->videoRam * 1024 - pApm->OffscreenReserved) /
33017a48c7cSmrg	(pScrn->displayWidth * ((pScrn->bitsPerPixel + 7) >> 3));
33117a48c7cSmrg
33217a48c7cSmrg    xf86InitFBManager(pScreen, &AvailFBArea);
33317a48c7cSmrg
33417a48c7cSmrg    bzero(pApm->apmCache, sizeof pApm->apmCache);
33517a48c7cSmrg
33617a48c7cSmrg    return XAAInit(pScreen, pXAAinfo);
33717a48c7cSmrg}
33817a48c7cSmrg
33917a48c7cSmrgvoid ApmSetupXAAInfo(ApmPtr pApm, XAAInfoRecPtr pXAAinfo)
34017a48c7cSmrg{
34117a48c7cSmrg    pApm->CurrentLayout.Setup_DEC = 0;
34217a48c7cSmrg    switch(pApm->CurrentLayout.bitsPerPixel)
34317a48c7cSmrg    {
34417a48c7cSmrg      case 8:
34517a48c7cSmrg           pApm->CurrentLayout.Setup_DEC |= DEC_BITDEPTH_8;
34617a48c7cSmrg           break;
34717a48c7cSmrg      case 16:
34817a48c7cSmrg           pApm->CurrentLayout.Setup_DEC |= DEC_BITDEPTH_16;
34917a48c7cSmrg           break;
35017a48c7cSmrg      case 24:
35117a48c7cSmrg	   /* Note : in 24 bpp, the accelerator wants linear coordinates */
35217a48c7cSmrg           pApm->CurrentLayout.Setup_DEC |= DEC_BITDEPTH_24 | DEC_SOURCE_LINEAR |
35317a48c7cSmrg				   DEC_DEST_LINEAR;
35417a48c7cSmrg           break;
35517a48c7cSmrg      case 32:
35617a48c7cSmrg           pApm->CurrentLayout.Setup_DEC |= DEC_BITDEPTH_32;
35717a48c7cSmrg           break;
35817a48c7cSmrg      default:
3590dd80ee0Smrg           xf86DrvMsg(xf86ScreenToScrn(pApm->pScreen)->scrnIndex, X_WARNING,
36017a48c7cSmrg		    "Cannot set up drawing engine control for bpp = %d\n",
36117a48c7cSmrg		    pApm->CurrentLayout.bitsPerPixel);
36217a48c7cSmrg           break;
36317a48c7cSmrg    }
36417a48c7cSmrg
36517a48c7cSmrg    switch(pApm->CurrentLayout.displayWidth)
36617a48c7cSmrg    {
36717a48c7cSmrg      case 640:
36817a48c7cSmrg           pApm->CurrentLayout.Setup_DEC |= DEC_WIDTH_640;
36917a48c7cSmrg           break;
37017a48c7cSmrg      case 800:
37117a48c7cSmrg           pApm->CurrentLayout.Setup_DEC |= DEC_WIDTH_800;
37217a48c7cSmrg           break;
37317a48c7cSmrg      case 1024:
37417a48c7cSmrg           pApm->CurrentLayout.Setup_DEC |= DEC_WIDTH_1024;
37517a48c7cSmrg           break;
37617a48c7cSmrg      case 1152:
37717a48c7cSmrg           pApm->CurrentLayout.Setup_DEC |= DEC_WIDTH_1152;
37817a48c7cSmrg           break;
37917a48c7cSmrg      case 1280:
38017a48c7cSmrg           pApm->CurrentLayout.Setup_DEC |= DEC_WIDTH_1280;
38117a48c7cSmrg           break;
38217a48c7cSmrg      case 1600:
38317a48c7cSmrg           pApm->CurrentLayout.Setup_DEC |= DEC_WIDTH_1600;
38417a48c7cSmrg           break;
38517a48c7cSmrg      default:
3860dd80ee0Smrg           xf86DrvMsg(xf86ScreenToScrn(pApm->pScreen)->scrnIndex, X_WARNING,
38717a48c7cSmrg		       "Cannot set up drawing engine control "
38817a48c7cSmrg		       "for screen width = %d\n", pApm->CurrentLayout.displayWidth);
38917a48c7cSmrg           break;
39017a48c7cSmrg    }
39117a48c7cSmrg
39217a48c7cSmrg    if (!pXAAinfo)
39317a48c7cSmrg	return;
39417a48c7cSmrg
39517a48c7cSmrg    /*
39617a48c7cSmrg     * Set up the main acceleration flags.
39717a48c7cSmrg     */
39817a48c7cSmrg    pXAAinfo->Flags = PIXMAP_CACHE | LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
39917a48c7cSmrg    pXAAinfo->CacheMonoStipple = ApmCacheMonoStipple;
40017a48c7cSmrg
40117a48c7cSmrg    if (pApm->CurrentLayout.bitsPerPixel != 24) {
40217a48c7cSmrg#define	XAA(s)		pXAAinfo->s = Apm##s
4030dd80ee0Smrg	if (pApm->Chipset < AT24)
4040dd80ee0Smrg	    pXAAinfo->Sync = ApmSync6422;
4050dd80ee0Smrg	else
40617a48c7cSmrg	    XAA(Sync);
40717a48c7cSmrg
4080dd80ee0Smrg	/* Accelerated filled rectangles */
4090dd80ee0Smrg	pXAAinfo->SolidFillFlags = NO_PLANEMASK;
4100dd80ee0Smrg	XAA(SetupForSolidFill);
4110dd80ee0Smrg	XAA(SubsequentSolidFillRect);
41217a48c7cSmrg
4130dd80ee0Smrg	/* Accelerated screen to screen color expansion */
4140dd80ee0Smrg	pXAAinfo->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK;
4150dd80ee0Smrg	XAA(SetupForScreenToScreenColorExpandFill);
4160dd80ee0Smrg	XAA(SubsequentScreenToScreenColorExpandFill);
41717a48c7cSmrg
41817a48c7cSmrg#if 0
4190dd80ee0Smrg	The constraints of the transfer range are incompatible with the
4200dd80ee0Smrg	XAA architecture. I rewrote the XAA functions using ImageWrite
4210dd80ee0Smrg	/* Accelerated CPU to screen color expansion */
4220dd80ee0Smrg	if ((pApm->Chipset == AT24 && pApm->ChipRev >= 4) ||
4230dd80ee0Smrg		pApm->Chipset == AT3D) {
4240dd80ee0Smrg	    pXAAinfo->CPUToScreenColorExpandFillFlags =
4250dd80ee0Smrg	      NO_PLANEMASK | SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD
4260dd80ee0Smrg	      | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING |
4270dd80ee0Smrg	      LEFT_EDGE_CLIPPING_NEGATIVE_X | SYNC_AFTER_COLOR_EXPAND;
4280dd80ee0Smrg	    XAA(SetupForCPUToScreenColorExpandFill);
4290dd80ee0Smrg	    XAA(SubsequentCPUToScreenColorExpandFill);
4300dd80ee0Smrg	    pXAAinfo->ColorExpandBase	= pApm->BltMap;
4310dd80ee0Smrg	    pXAAinfo->ColorExpandRange	= (pApm->Chipset >= AT3D) ? 32*1024 : 30*1024;
4320dd80ee0Smrg	}
43317a48c7cSmrg
4340dd80ee0Smrg	/* Accelerated image transfers */
4350dd80ee0Smrg	pXAAinfo->ImageWriteFlags	=
4360dd80ee0Smrg			LEFT_EDGE_CLIPPING | NO_PLANEMASK |
4370dd80ee0Smrg			SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD |
4380dd80ee0Smrg			LEFT_EDGE_CLIPPING_NEGATIVE_X |
4390dd80ee0Smrg			SYNC_AFTER_IMAGE_WRITE;
4400dd80ee0Smrg	pXAAinfo->ImageWriteBase	= pApm->BltMap;
4410dd80ee0Smrg	pXAAinfo->ImageWriteRange	= (pApm->Chipset >= AT3D) ? 32*1024 : 30*1024;
4420dd80ee0Smrg	XAA(SetupForImageWrite);
4430dd80ee0Smrg	XAA(SubsequentImageWriteRect);
44417a48c7cSmrg#endif
4450dd80ee0Smrg	pXAAinfo->WritePixmapFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
4460dd80ee0Smrg			LEFT_EDGE_CLIPPING_NEGATIVE_X;
4470dd80ee0Smrg	XAA(WritePixmap);
4480dd80ee0Smrg	pXAAinfo->FillImageWriteRectsFlags	=
4490dd80ee0Smrg			LEFT_EDGE_CLIPPING | NO_PLANEMASK |
4500dd80ee0Smrg			LEFT_EDGE_CLIPPING_NEGATIVE_X;
4510dd80ee0Smrg	XAA(FillImageWriteRects);
4520dd80ee0Smrg	pXAAinfo->WriteBitmapFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
4530dd80ee0Smrg			LEFT_EDGE_CLIPPING_NEGATIVE_X |
4540dd80ee0Smrg			BIT_ORDER_IN_BYTE_LSBFIRST;
4550dd80ee0Smrg	XAA(WriteBitmap);
4560dd80ee0Smrg	pXAAinfo->TEGlyphRendererFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
4570dd80ee0Smrg			LEFT_EDGE_CLIPPING_NEGATIVE_X;
4580dd80ee0Smrg	XAA(TEGlyphRenderer);
4590dd80ee0Smrg
4600dd80ee0Smrg	/* Accelerated screen-screen bitblts */
4610dd80ee0Smrg	pXAAinfo->ScreenToScreenCopyFlags = NO_PLANEMASK;
4620dd80ee0Smrg	XAA(SetupForScreenToScreenCopy);
4630dd80ee0Smrg	XAA(SubsequentScreenToScreenCopy);
4640dd80ee0Smrg
4650dd80ee0Smrg	/* Accelerated Line drawing */
4660dd80ee0Smrg	pXAAinfo->SolidLineFlags = NO_PLANEMASK | HARDWARE_CLIP_LINE;
4670dd80ee0Smrg	XAA(SetClippingRectangle);
4680dd80ee0Smrg	pXAAinfo->SolidBresenhamLineErrorTermBits = 15;
4690dd80ee0Smrg
4700dd80ee0Smrg	if (pApm->Chipset >= AT24) {
47117a48c7cSmrg	    XAA(SubsequentSolidBresenhamLine);
47217a48c7cSmrg
47317a48c7cSmrg	    /* Pattern fill */
4740dd80ee0Smrg	    pXAAinfo->Mono8x8PatternFillFlags = NO_PLANEMASK |
47517a48c7cSmrg			    HARDWARE_PATTERN_PROGRAMMED_BITS |
47617a48c7cSmrg			    HARDWARE_PATTERN_SCREEN_ORIGIN;
47717a48c7cSmrg	    XAA(SetupForMono8x8PatternFill);
47817a48c7cSmrg	    XAA(SubsequentMono8x8PatternFillRect);
4790dd80ee0Smrg	    if (pApm->CurrentLayout.bitsPerPixel == 8) {
4800dd80ee0Smrg		pXAAinfo->Color8x8PatternFillFlags = NO_PLANEMASK |
4810dd80ee0Smrg				HARDWARE_PATTERN_SCREEN_ORIGIN;
4820dd80ee0Smrg		XAA(SetupForColor8x8PatternFill);
4830dd80ee0Smrg		XAA(SubsequentColor8x8PatternFillRect);
4840dd80ee0Smrg	    }
48517a48c7cSmrg	}
4860dd80ee0Smrg	else
4870dd80ee0Smrg	    pXAAinfo->SubsequentSolidBresenhamLine =
4880dd80ee0Smrg		ApmSubsequentSolidBresenhamLine6422;
4890dd80ee0Smrg#undef XAA
4900dd80ee0Smrg    }
4910dd80ee0Smrg    else {
4920dd80ee0Smrg#define	XAA(s)		pXAAinfo->s = Apm##s##24
4930dd80ee0Smrg	XAA(Sync);
49417a48c7cSmrg
4950dd80ee0Smrg	/* Accelerated filled rectangles */
4960dd80ee0Smrg	pXAAinfo->SolidFillFlags = NO_PLANEMASK;
4970dd80ee0Smrg	XAA(SetupForSolidFill);
4980dd80ee0Smrg	XAA(SubsequentSolidFillRect);
49917a48c7cSmrg
50017a48c7cSmrg#if 0
5010dd80ee0Smrg	/* Accelerated screen to screen color expansion */
5020dd80ee0Smrg	pXAAinfo->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK;
5030dd80ee0Smrg	XAA(SetupForScreenToScreenColorExpandFill);
5040dd80ee0Smrg	XAA(SubsequentScreenToScreenColorExpandFill);
50517a48c7cSmrg
50617a48c7cSmrg#if 0
5070dd80ee0Smrg	The constraints of the transfer range are incompatible with the
5080dd80ee0Smrg	XAA architecture. I rewrote the XAA functions using ImageWrite
5090dd80ee0Smrg	/* Accelerated CPU to screen color expansion */
5100dd80ee0Smrg	if (pApm->Chipset == AT3D && pApm->ChipRev >= 4) {
5110dd80ee0Smrg	    pXAAinfo->CPUToScreenColorExpandFillFlags =
5120dd80ee0Smrg	      NO_PLANEMASK | SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD
5130dd80ee0Smrg	      | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING |
5140dd80ee0Smrg	      LEFT_EDGE_CLIPPING_NEGATIVE_X | SYNC_AFTER_COLOR_EXPAND;
5150dd80ee0Smrg	    XAA(SetupForCPUToScreenColorExpandFill);
5160dd80ee0Smrg	    XAA(SubsequentCPUToScreenColorExpandFill);
5170dd80ee0Smrg	    pXAAinfo->ColorExpandBase	= pApm->BltMap;
5180dd80ee0Smrg	    pXAAinfo->ColorExpandRange	= 32*1024;
5190dd80ee0Smrg	}
52017a48c7cSmrg
5210dd80ee0Smrg	/* Accelerated image transfers */
5220dd80ee0Smrg	pXAAinfo->ImageWriteFlags	=
5230dd80ee0Smrg			LEFT_EDGE_CLIPPING | NO_PLANEMASK |
5240dd80ee0Smrg			SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD |
5250dd80ee0Smrg			SYNC_AFTER_IMAGE_WRITE;
5260dd80ee0Smrg	pXAAinfo->ImageWriteBase	= pApm->BltMap;
5270dd80ee0Smrg	pXAAinfo->ImageWriteRange	= 32*1024;
5280dd80ee0Smrg	XAA(SetupForImageWrite);
5290dd80ee0Smrg	XAA(SubsequentImageWriteRect);
53017a48c7cSmrg#endif
5310dd80ee0Smrg	pXAAinfo->WritePixmapFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
5320dd80ee0Smrg			LEFT_EDGE_CLIPPING_NEGATIVE_X;
5330dd80ee0Smrg	XAA(WritePixmap);
5340dd80ee0Smrg	pXAAinfo->FillImageWriteRectsFlags	=
5350dd80ee0Smrg			LEFT_EDGE_CLIPPING | NO_PLANEMASK |
5360dd80ee0Smrg			LEFT_EDGE_CLIPPING_NEGATIVE_X;
5370dd80ee0Smrg	XAA(FillImageWriteRects);
5380dd80ee0Smrg	pXAAinfo->WriteBitmapFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
5390dd80ee0Smrg			LEFT_EDGE_CLIPPING_NEGATIVE_X |
5400dd80ee0Smrg			BIT_ORDER_IN_BYTE_LSBFIRST;
5410dd80ee0Smrg	XAA(WriteBitmap);
5420dd80ee0Smrg	pXAAinfo->TEGlyphRendererFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
5430dd80ee0Smrg			LEFT_EDGE_CLIPPING_NEGATIVE_X;
5440dd80ee0Smrg	XAA(TEGlyphRenderer);
5450dd80ee0Smrg
5460dd80ee0Smrg	/* Accelerated Line drawing */
5470dd80ee0Smrg	pXAAinfo->SolidLineFlags = NO_PLANEMASK | HARDWARE_CLIP_LINE;
5480dd80ee0Smrg	XAA(SubsequentSolidBresenhamLine);
5490dd80ee0Smrg	XAA(SetClippingRectangle);
5500dd80ee0Smrg	pXAAinfo->SolidBresenhamLineErrorTermBits = 15;
5510dd80ee0Smrg
5520dd80ee0Smrg	/* Pattern fill */
5530dd80ee0Smrg	pXAAinfo->Mono8x8PatternFillFlags = NO_PLANEMASK | NO_TRANSPARENCY |
5540dd80ee0Smrg			HARDWARE_PATTERN_PROGRAMMED_BITS |
5550dd80ee0Smrg			HARDWARE_PATTERN_SCREEN_ORIGIN;
5560dd80ee0Smrg	XAA(SetupForMono8x8PatternFill);
5570dd80ee0Smrg	XAA(SubsequentMono8x8PatternFillRect);
55817a48c7cSmrg#endif
55917a48c7cSmrg
5600dd80ee0Smrg	/* Accelerated screen-screen bitblts */
5610dd80ee0Smrg	pXAAinfo->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY;
5620dd80ee0Smrg	XAA(SetupForScreenToScreenCopy);
5630dd80ee0Smrg	XAA(SubsequentScreenToScreenCopy);
56417a48c7cSmrg#undef XAA
56517a48c7cSmrg    }
56617a48c7cSmrg}
5670dd80ee0Smrg#endif
568