ast_cursor.c revision b4d38c65
115fb4814Smrg/*
215fb4814Smrg * Copyright (c) 2005 ASPEED Technology Inc.
315fb4814Smrg *
415fb4814Smrg * Permission to use, copy, modify, distribute, and sell this software and its
515fb4814Smrg * documentation for any purpose is hereby granted without fee, provided that
615fb4814Smrg * the above copyright notice appear in all copies and that both that
715fb4814Smrg * copyright notice and this permission notice appear in supporting
815fb4814Smrg * documentation, and that the name of the authors not be used in
915fb4814Smrg * advertising or publicity pertaining to distribution of the software without
1015fb4814Smrg * specific, written prior permission.  The authors makes no representations
1115fb4814Smrg * about the suitability of this software for any purpose.  It is provided
1215fb4814Smrg * "as is" without express or implied warranty.
1315fb4814Smrg *
1415fb4814Smrg * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1515fb4814Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1615fb4814Smrg * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1715fb4814Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1815fb4814Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
1915fb4814Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2015fb4814Smrg * PERFORMANCE OF THIS SOFTWARE.
2115fb4814Smrg */
2215fb4814Smrg
2315fb4814Smrg#ifdef HAVE_CONFIG_H
2415fb4814Smrg#include <config.h>
2515fb4814Smrg#endif
2615fb4814Smrg#include "xf86.h"
2715fb4814Smrg#include "xf86_OSproc.h"
2815fb4814Smrg#include "xf86cmap.h"
2915fb4814Smrg#include "compiler.h"
3015fb4814Smrg#include "mibstore.h"
3115fb4814Smrg#include "vgaHW.h"
3215fb4814Smrg#include "mipointer.h"
3315fb4814Smrg#include "micmap.h"
3415fb4814Smrg
3515fb4814Smrg#include "fb.h"
3615fb4814Smrg#include "regionstr.h"
3715fb4814Smrg#include "xf86xv.h"
3815fb4814Smrg#include <X11/extensions/Xv.h>
3915fb4814Smrg#include "vbe.h"
4015fb4814Smrg
4115fb4814Smrg#include "xf86PciInfo.h"
4215fb4814Smrg#include "xf86Pci.h"
4315fb4814Smrg
4415fb4814Smrg/* framebuffer offscreen manager */
4515fb4814Smrg#include "xf86fbman.h"
4615fb4814Smrg
4715fb4814Smrg/* include xaa includes */
4815fb4814Smrg#include "xaarop.h"
4915fb4814Smrg
5015fb4814Smrg/* H/W cursor support */
5115fb4814Smrg#include "xf86Cursor.h"
5215fb4814Smrg#include "cursorstr.h"
5315fb4814Smrg
5415fb4814Smrg/* Driver specific headers */
5515fb4814Smrg#include "ast.h"
5615fb4814Smrg
5715fb4814Smrg#ifdef	HWC
5815fb4814Smrg/* Prototype type declaration */
5915fb4814SmrgBool ASTCursorInit(ScreenPtr pScreen);
6015fb4814SmrgBool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST);
61b534f209Smrgvoid ASTDisableHWC(ScrnInfoPtr pScrn);
6215fb4814Smrgstatic void ASTShowCursor(ScrnInfoPtr pScrn);
63b534f209Smrgstatic void ASTHideCursor(ScrnInfoPtr pScrn);
6415fb4814Smrgstatic void ASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
6515fb4814Smrgstatic void ASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
6615fb4814Smrgstatic void ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src);
6715fb4814Smrgstatic Bool ASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs);
6815fb4814Smrgstatic void ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs);
6915fb4814Smrgstatic Bool ASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs);
7015fb4814Smrgstatic void ASTFireCursor(ScrnInfoPtr pScrn);
71b534f209Smrgstatic void ASTShowCursor_AST1180(ScrnInfoPtr pScrn);
72b534f209Smrgstatic void ASTHideCursor_AST1180(ScrnInfoPtr pScrn);
73b534f209Smrgstatic void ASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y);
7415fb4814Smrg
7515fb4814SmrgBool
7615fb4814SmrgASTCursorInit(ScreenPtr pScreen)
7715fb4814Smrg{
78b4d38c65Smrg    ScrnInfoPtr	pScrn = xf86ScreenToScrn(pScreen);
7915fb4814Smrg    ASTRecPtr 	pAST = ASTPTR(pScrn);
8015fb4814Smrg    xf86CursorInfoPtr infoPtr;
8115fb4814Smrg
8215fb4814Smrg    infoPtr = xf86CreateCursorInfoRec();
8315fb4814Smrg    if(!infoPtr) return FALSE;
8415fb4814Smrg
8515fb4814Smrg    pAST->HWCInfoPtr = infoPtr;
8615fb4814Smrg
8715fb4814Smrg    infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
8815fb4814Smrg                     HARDWARE_CURSOR_INVERT_MASK |
8915fb4814Smrg                     HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
9015fb4814Smrg
9115fb4814Smrg    infoPtr->MaxWidth  = MAX_HWC_WIDTH;
9215fb4814Smrg    infoPtr->MaxHeight = MAX_HWC_HEIGHT;
93b534f209Smrg    if (pAST->jChipType == AST1180)
94b534f209Smrg    {
95b534f209Smrg        infoPtr->ShowCursor = ASTShowCursor_AST1180;
96b534f209Smrg        infoPtr->HideCursor = ASTHideCursor_AST1180;
97b534f209Smrg        infoPtr->SetCursorPosition = ASTSetCursorPosition_AST1180;
98b534f209Smrg    }
99b534f209Smrg    else
100b534f209Smrg    {
101b534f209Smrg        infoPtr->ShowCursor = ASTShowCursor;
102b534f209Smrg        infoPtr->HideCursor = ASTHideCursor;
103b534f209Smrg        infoPtr->SetCursorPosition = ASTSetCursorPosition;
104b534f209Smrg    }
105b534f209Smrg    infoPtr->SetCursorColors = ASTSetCursorColors;
10615fb4814Smrg    infoPtr->LoadCursorImage = ASTLoadCursorImage;
10715fb4814Smrg    infoPtr->UseHWCursor = ASTUseHWCursor;
10815fb4814Smrg#ifdef ARGB_CURSOR
10915fb4814Smrg    infoPtr->UseHWCursorARGB = ASTUseHWCursorARGB;
11015fb4814Smrg    infoPtr->LoadCursorARGB = ASTLoadCursorARGB;
11115fb4814Smrg#endif
11215fb4814Smrg
11315fb4814Smrg    return(xf86InitCursor(pScreen, infoPtr));
11415fb4814Smrg
11515fb4814Smrg}
11615fb4814Smrg
11715fb4814SmrgBool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST)
11815fb4814Smrg{
11915fb4814Smrg    ScreenPtr	pScreen;
12015fb4814Smrg
12115fb4814Smrg    /* init cursor cache info */
12215fb4814Smrg    /* Set HWC_NUM in Options instead */
12315fb4814Smrg    /* pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM; */
12415fb4814Smrg    pAST->HWCInfo.HWC_NUM_Next = 0;
12515fb4814Smrg
12615fb4814Smrg    /* allocate HWC cache */
12715fb4814Smrg    if (!pAST->pHWCPtr) {
128b4d38c65Smrg        pScreen = xf86ScrnToScreen(pScrn);
12915fb4814Smrg        pAST->pHWCPtr = xf86AllocateOffscreenLinear (pScreen, (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM, HWC_ALIGN, NULL, NULL, NULL);
13015fb4814Smrg
13115fb4814Smrg        if (!pAST->pHWCPtr) {
13215fb4814Smrg           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Allocate HWC Cache failed \n");
13315fb4814Smrg           return (FALSE);
13415fb4814Smrg        }
13515fb4814Smrg
13615fb4814Smrg        pAST->HWCInfo.ulHWCOffsetAddr  = pAST->pHWCPtr->offset*((pScrn->bitsPerPixel + 1) / 8);
13715fb4814Smrg        pAST->HWCInfo.pjHWCVirtualAddr = pAST->FBVirtualAddr + pAST->HWCInfo.ulHWCOffsetAddr;
13815fb4814Smrg    }
13915fb4814Smrg
14015fb4814Smrg    return (TRUE);
14115fb4814Smrg}
14215fb4814Smrg
143b534f209Smrgvoid ASTDisableHWC(ScrnInfoPtr pScrn)
144b534f209Smrg{
145b534f209Smrg    ASTRecPtr   pAST = ASTPTR(pScrn);
146b534f209Smrg
147b534f209Smrg    if (pAST->jChipType == AST1180)
148b534f209Smrg        ASTHideCursor_AST1180(pScrn);
149b534f209Smrg    else
150b534f209Smrg        ASTHideCursor(pScrn);
151b534f209Smrg}
15215fb4814Smrg
15315fb4814Smrgstatic void
15415fb4814SmrgASTShowCursor(ScrnInfoPtr pScrn)
15515fb4814Smrg{
15615fb4814Smrg    ASTRecPtr   pAST = ASTPTR(pScrn);
15715fb4814Smrg    UCHAR 	jReg;
15815fb4814Smrg
15915fb4814Smrg    jReg= 0x02;
16015fb4814Smrg    if (pAST->HWCInfo.cursortype ==HWC_COLOR)
16115fb4814Smrg        jReg |= 0x01;
16215fb4814Smrg
16315fb4814Smrg    SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, jReg);	/* enable mono */
16415fb4814Smrg
16515fb4814Smrg}
16615fb4814Smrg
167b534f209Smrgstatic void
16815fb4814SmrgASTHideCursor(ScrnInfoPtr pScrn)
16915fb4814Smrg{
17015fb4814Smrg    ASTRecPtr  pAST = ASTPTR(pScrn);
17115fb4814Smrg
17215fb4814Smrg    SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, 0x00);	/* disable HWC */
17315fb4814Smrg
17415fb4814Smrg}
17515fb4814Smrg
17615fb4814Smrgstatic void
17715fb4814SmrgASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
17815fb4814Smrg{
17915fb4814Smrg    ASTRecPtr	pAST = ASTPTR(pScrn);
18015fb4814Smrg    DisplayModePtr mode = pAST->ModePtr;
18115fb4814Smrg    int		x_offset, y_offset;
18215fb4814Smrg    UCHAR 	*pjSignature;
18315fb4814Smrg
18415fb4814Smrg    /* Set cursor info to Offscreen */
18515fb4814Smrg    pjSignature = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
18615fb4814Smrg    *((ULONG *) (pjSignature + HWC_SIGNATURE_X)) = x;
18715fb4814Smrg    *((ULONG *) (pjSignature + HWC_SIGNATURE_Y)) = y;
18815fb4814Smrg
18915fb4814Smrg    x_offset = pAST->HWCInfo.offset_x;
19015fb4814Smrg    y_offset = pAST->HWCInfo.offset_y;
19115fb4814Smrg
19215fb4814Smrg    if(x < 0) {
19315fb4814Smrg       x_offset = (-x) + pAST->HWCInfo.offset_x;
19415fb4814Smrg       x = 0;
19515fb4814Smrg    }
19615fb4814Smrg
19715fb4814Smrg    if(y < 0) {
19815fb4814Smrg       y_offset = (-y) + pAST->HWCInfo.offset_y;
19915fb4814Smrg       y = 0;
20015fb4814Smrg    }
20115fb4814Smrg
20215fb4814Smrg    if(mode->Flags & V_DBLSCAN)  y *= 2;
20315fb4814Smrg
20415fb4814Smrg    /* Set to Reg. */
20515fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC2, (UCHAR) (x_offset));
20615fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC3, (UCHAR) (y_offset));
20715fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC4, (UCHAR) (x & 0xFF));
20815fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC5, (UCHAR) ((x >> 8) & 0x0F));
20915fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC6, (UCHAR) (y & 0xFF));
21015fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC7, (UCHAR) ((y >> 8) & 0x07));
21115fb4814Smrg
21215fb4814Smrg    /* Fire HWC */
21315fb4814Smrg    ASTFireCursor(pScrn);
21415fb4814Smrg
21515fb4814Smrg}
21615fb4814Smrg
21715fb4814Smrgstatic void
21815fb4814SmrgASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
21915fb4814Smrg{
22015fb4814Smrg    ASTRecPtr 	pAST = ASTPTR(pScrn);
221de78e416Smrg    ULONG fg1, bg1;
222de78e416Smrg
223de78e416Smrg    fg1 = (fg & 0x0F) | (((fg>>8) & 0x0F) << 4) | (((fg>>16) & 0x0F) << 8);
224de78e416Smrg    bg1 = (bg & 0x0F) | (((bg>>8) & 0x0F) << 4) | (((bg>>16) & 0x0F) << 8);
225de78e416Smrg
226de78e416Smrg    /* Fixed xorg bugzilla #20609, ycchen@031209 */
227de78e416Smrg    if ( (fg1 != pAST->HWCInfo.fg) || (bg1 != pAST->HWCInfo.bg) )
228de78e416Smrg    {
229de78e416Smrg    	pAST->HWCInfo.fg = fg1;
230de78e416Smrg    	pAST->HWCInfo.bg = bg1;
231de78e416Smrg        ASTLoadCursorImage(pScrn, pAST->HWCInfo.cursorpattern);
232de78e416Smrg    }
233de78e416Smrg
23415fb4814Smrg}
23515fb4814Smrg
23615fb4814Smrgstatic void
23715fb4814SmrgASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src)
23815fb4814Smrg{
23915fb4814Smrg    ASTRecPtr	pAST = ASTPTR(pScrn);
24015fb4814Smrg    int 	i, j, k;
24115fb4814Smrg    UCHAR 	*pjSrcAnd, *pjSrcXor, *pjDstData;
24215fb4814Smrg    ULONG   	ulTempDstAnd32[2], ulTempDstXor32[2], ulTempDstData32[2];
24315fb4814Smrg    UCHAR    	jTempSrcAnd32, jTempSrcXor32;
24415fb4814Smrg    ULONG	ulCheckSum = 0;
24515fb4814Smrg    ULONG 	ulPatternAddr;
24615fb4814Smrg
24715fb4814Smrg    /* init cursor info. */
24815fb4814Smrg    pAST->HWCInfo.cursortype = HWC_MONO;
24915fb4814Smrg    pAST->HWCInfo.width  = (USHORT) MAX_HWC_WIDTH;
25015fb4814Smrg    pAST->HWCInfo.height = (USHORT) MAX_HWC_HEIGHT;
25115fb4814Smrg    pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width;
25215fb4814Smrg    pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height;
25315fb4814Smrg
254de78e416Smrg    /* copy to hwc info */
255de78e416Smrg    for (i=0; i< MAX_HWC_WIDTH*MAX_HWC_HEIGHT/4; i+=4)
256de78e416Smrg       *(ULONG *) (pAST->HWCInfo.cursorpattern + i) = *(ULONG *) (src + i);
257de78e416Smrg
25815fb4814Smrg    /* copy cursor image to cache */
25915fb4814Smrg    pjSrcXor = src;
26015fb4814Smrg    pjSrcAnd = src + (MAX_HWC_WIDTH*MAX_HWC_HEIGHT/8);
26115fb4814Smrg    pjDstData =  pAST->HWCInfo.pjHWCVirtualAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next;
26215fb4814Smrg
26315fb4814Smrg    for (j = 0; j < MAX_HWC_HEIGHT; j++)
26415fb4814Smrg    {
26515fb4814Smrg       for (i = 0; i < (MAX_HWC_WIDTH/8); i++ )
26615fb4814Smrg       {
26715fb4814Smrg       	    for (k=7; k>0; k-=2)
26815fb4814Smrg       	    {
26915fb4814Smrg                jTempSrcAnd32 = *((UCHAR *) pjSrcAnd);
270de78e416Smrg                jTempSrcXor32 = *((UCHAR *) pjSrcXor);
271de78e416Smrg                ulTempDstAnd32[0] = ((jTempSrcAnd32 >> k) & 0x01) ? 0x00008000L:0x00L;
27215fb4814Smrg                ulTempDstXor32[0] = ((jTempSrcXor32 >> k) & 0x01) ? 0x00004000L:0x00L;
27315fb4814Smrg                ulTempDstData32[0] = ((jTempSrcXor32 >> k) & 0x01) ? pAST->HWCInfo.fg:pAST->HWCInfo.bg;
27415fb4814Smrg                ulTempDstAnd32[1] = ((jTempSrcAnd32 >> (k-1)) & 0x01) ? 0x80000000L:0x00L;
27515fb4814Smrg                ulTempDstXor32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? 0x40000000L:0x00L;
27615fb4814Smrg                ulTempDstData32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? (pAST->HWCInfo.fg << 16):(pAST->HWCInfo.bg << 16);
277de78e416Smrg                /* No inverse for X Window cursor, ycchen@111808 */
278de78e416Smrg                if (ulTempDstAnd32[0])
279de78e416Smrg                    ulTempDstXor32[0] = 0;
280de78e416Smrg                if (ulTempDstAnd32[1])
281de78e416Smrg                    ulTempDstXor32[1] = 0;
28215fb4814Smrg                *((ULONG *) pjDstData) = ulTempDstAnd32[0] | ulTempDstXor32[0] | ulTempDstData32[0] | ulTempDstAnd32[1] | ulTempDstXor32[1] | ulTempDstData32[1];
28315fb4814Smrg                ulCheckSum += *((ULONG *) pjDstData);
28415fb4814Smrg                pjDstData += 4;
28515fb4814Smrg
28615fb4814Smrg            }
28715fb4814Smrg            pjSrcAnd ++;
28815fb4814Smrg            pjSrcXor ++;
28915fb4814Smrg
29015fb4814Smrg       }
29115fb4814Smrg
29215fb4814Smrg    }
29315fb4814Smrg
294b534f209Smrg    if (pAST->jChipType == AST1180)
295b534f209Smrg    {
296b534f209Smrg        ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next);
297b534f209Smrg        WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr);
298b534f209Smrg    }
299b534f209Smrg    else
300b534f209Smrg    {
301b534f209Smrg        /* Write Checksum as signature */
302b534f209Smrg        pjDstData = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
303b534f209Smrg        *((ULONG *) pjDstData) = ulCheckSum;
304b534f209Smrg        *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width;
305b534f209Smrg        *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height;
306b534f209Smrg        *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTX)) = 0;
307b534f209Smrg        *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTY)) = 0;
308b534f209Smrg
309b534f209Smrg        /* set pattern offset */
310b534f209Smrg        ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3);
311b534f209Smrg        SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF));
312b534f209Smrg        SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF));
313b534f209Smrg        SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF));
314b534f209Smrg    }
31515fb4814Smrg
31615fb4814Smrg    /* update HWC_NUM_Next */
31715fb4814Smrg    pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM;
31815fb4814Smrg
31915fb4814Smrg}
32015fb4814Smrg
32115fb4814Smrgstatic Bool
32215fb4814SmrgASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
32315fb4814Smrg{
324de78e416Smrg    if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) )
325de78e416Smrg        return FALSE;
326de78e416Smrg
32715fb4814Smrg    return TRUE;
32815fb4814Smrg}
32915fb4814Smrg
33015fb4814Smrgstatic void
33115fb4814SmrgASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
33215fb4814Smrg{
33315fb4814Smrg    ASTRecPtr 	pAST = ASTPTR(pScrn);
33415fb4814Smrg
33515fb4814Smrg    UCHAR	*pjDstXor, *pjSrcXor;
33615fb4814Smrg    ULONG       i, j, ulSrcWidth, ulSrcHeight;
33715fb4814Smrg    ULONG	ulPerPixelCopy, ulTwoPixelCopy;
33815fb4814Smrg    LONG        lAlphaDstDelta, lLastAlphaDstDelta;
33915fb4814Smrg    union
34015fb4814Smrg    {
34115fb4814Smrg        ULONG   ul;
34215fb4814Smrg        UCHAR   b[4];
34315fb4814Smrg    } ulSrcData32[2], ulData32;
34415fb4814Smrg    union
34515fb4814Smrg    {
34615fb4814Smrg        USHORT  us;
34715fb4814Smrg        UCHAR   b[2];
34815fb4814Smrg    } usData16;
34915fb4814Smrg    ULONG	ulCheckSum = 0;
35015fb4814Smrg    ULONG 	ulPatternAddr;
35115fb4814Smrg
35215fb4814Smrg    /* init cursor info. */
35315fb4814Smrg    pAST->HWCInfo.cursortype = HWC_COLOR;
35415fb4814Smrg    pAST->HWCInfo.width  = pCurs->bits->width;
35515fb4814Smrg    pAST->HWCInfo.height = pCurs->bits->height;
35615fb4814Smrg    pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width;
35715fb4814Smrg    pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height;
35815fb4814Smrg
35915fb4814Smrg    /* copy cursor image to cache */
36015fb4814Smrg    ulSrcWidth  =  pAST->HWCInfo.width;
36115fb4814Smrg    ulSrcHeight =  pAST->HWCInfo.height;
36215fb4814Smrg
36315fb4814Smrg    lAlphaDstDelta = MAX_HWC_WIDTH << 1;
36415fb4814Smrg    lLastAlphaDstDelta = lAlphaDstDelta - (ulSrcWidth << 1);
36515fb4814Smrg
36615fb4814Smrg    pjSrcXor  = (UCHAR *) pCurs->bits->argb;;
36715fb4814Smrg    pjDstXor  = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next
36815fb4814Smrg                        + lLastAlphaDstDelta + (MAX_HWC_HEIGHT - ulSrcHeight) * lAlphaDstDelta;
36915fb4814Smrg
37015fb4814Smrg    ulPerPixelCopy =  ulSrcWidth & 1;
37115fb4814Smrg    ulTwoPixelCopy =  ulSrcWidth >> 1;
37215fb4814Smrg
37315fb4814Smrg    for (j = 0; j < ulSrcHeight; j++)
37415fb4814Smrg    {
37515fb4814Smrg
37615fb4814Smrg        for (i = 0; i < ulTwoPixelCopy; i++ )
37715fb4814Smrg        {
37815fb4814Smrg            ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0;
37915fb4814Smrg            ulSrcData32[1].ul = *((ULONG *) (pjSrcXor+4)) & 0xF0F0F0F0;
38015fb4814Smrg            ulData32.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4);
38115fb4814Smrg            ulData32.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4);
38215fb4814Smrg            ulData32.b[2] = ulSrcData32[1].b[1] | (ulSrcData32[1].b[0] >> 4);
38315fb4814Smrg            ulData32.b[3] = ulSrcData32[1].b[3] | (ulSrcData32[1].b[2] >> 4);
38415fb4814Smrg            *((ULONG *) pjDstXor) = ulData32.ul;
38515fb4814Smrg            ulCheckSum += (ULONG) ulData32.ul;
38615fb4814Smrg            pjDstXor += 4;
38715fb4814Smrg            pjSrcXor += 8;
38815fb4814Smrg        }
38915fb4814Smrg
39015fb4814Smrg        for (i = 0; i < ulPerPixelCopy; i++ )
39115fb4814Smrg        {
39215fb4814Smrg            ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0;
39315fb4814Smrg            usData16.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4);
39415fb4814Smrg            usData16.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4);
39515fb4814Smrg            *((USHORT *) pjDstXor) = usData16.us;
39615fb4814Smrg            ulCheckSum += (ULONG) usData16.us;
39715fb4814Smrg            pjDstXor += 2;
39815fb4814Smrg            pjSrcXor += 4;
39915fb4814Smrg        }
40015fb4814Smrg
40115fb4814Smrg        /* Point to next source and dest scans */
40215fb4814Smrg        pjDstXor += lLastAlphaDstDelta;
40315fb4814Smrg
40415fb4814Smrg    } /* end of for-loop */
40515fb4814Smrg
406b534f209Smrg    if (pAST->jChipType == AST1180)
407b534f209Smrg    {
408b534f209Smrg        ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next);
409b534f209Smrg        WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr);
410b534f209Smrg    }
411b534f209Smrg    else
412b534f209Smrg    {
413b534f209Smrg        /* Write Checksum as signature */
414b534f209Smrg        pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
415b534f209Smrg        *((ULONG *) pjDstXor) = ulCheckSum;
416b534f209Smrg        *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width;
417b534f209Smrg        *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height;
418b534f209Smrg        *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTX)) = 0;
419b534f209Smrg        *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTY)) = 0;
420b534f209Smrg
421b534f209Smrg        /* set pattern offset */
422b534f209Smrg        ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr +(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3);
423b534f209Smrg        SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF));
424b534f209Smrg        SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF));
425b534f209Smrg        SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF));
426b534f209Smrg    }
42715fb4814Smrg
42815fb4814Smrg    /* update HWC_NUM_Next */
42915fb4814Smrg    pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM;
43015fb4814Smrg
43115fb4814Smrg}
43215fb4814Smrg
43315fb4814Smrgstatic Bool
43415fb4814SmrgASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
43515fb4814Smrg{
436de78e416Smrg    if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) )
437de78e416Smrg        return FALSE;
438de78e416Smrg
43915fb4814Smrg    return TRUE;
44015fb4814Smrg}
44115fb4814Smrg
44215fb4814Smrgstatic void
44315fb4814SmrgASTFireCursor(ScrnInfoPtr pScrn)
44415fb4814Smrg{
44515fb4814Smrg    ASTRecPtr  pAST = ASTPTR(pScrn);
44615fb4814Smrg
44715fb4814Smrg    SetIndexRegMask(CRTC_PORT, 0xCB, 0xFF, 0x00);	/* dummp write to fire HWC */
44815fb4814Smrg
44915fb4814Smrg}
45015fb4814Smrg
451b534f209Smrg/* AST1180 */
452b534f209Smrgstatic void
453b534f209SmrgASTShowCursor_AST1180(ScrnInfoPtr pScrn)
454b534f209Smrg{
455b534f209Smrg    ASTRecPtr   pAST = ASTPTR(pScrn);
456b534f209Smrg    ULONG 	ulData, ulTemp;
457b534f209Smrg
458b534f209Smrg    ReadAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp);
459b534f209Smrg
460b534f209Smrg    ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData);
461b534f209Smrg    ulData &= ~AST1180_ALPHAHWC;
462b534f209Smrg    if (pAST->HWCInfo.cursortype ==HWC_COLOR)
463b534f209Smrg        ulData |= AST1180_ALPHAHWC;
464b534f209Smrg    ulData |= AST1180_ENABLEHWC;
465b534f209Smrg    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData);
466b534f209Smrg
467b534f209Smrg    /* fire cursor */
468b534f209Smrg    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp);
469b534f209Smrg
470b534f209Smrg} /* ASTShowCursor_AST1180 */
471b534f209Smrg
472b534f209Smrgstatic void
473b534f209SmrgASTHideCursor_AST1180(ScrnInfoPtr pScrn)
474b534f209Smrg{
475b534f209Smrg    ASTRecPtr  pAST = ASTPTR(pScrn);
476b534f209Smrg    ULONG 	ulData;
477b534f209Smrg
478b534f209Smrg    ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData);
479b534f209Smrg    ulData &= ~AST1180_ENABLEHWC;
480b534f209Smrg    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData);
481b534f209Smrg
482b534f209Smrg    /* fire cursor */
483b534f209Smrg    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, 0x07ff07ff);
484b534f209Smrg
485b534f209Smrg} /* ASTHideCursor_AST1180 */
486b534f209Smrg
487b534f209Smrgstatic void
488b534f209SmrgASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y)
489b534f209Smrg{
490b534f209Smrg    ASTRecPtr	pAST = ASTPTR(pScrn);
491b534f209Smrg    DisplayModePtr mode = pAST->ModePtr;
492b534f209Smrg    int		x_offset, y_offset;
493b534f209Smrg    ULONG	ulData;
494b534f209Smrg
495b534f209Smrg    x_offset = pAST->HWCInfo.offset_x;
496b534f209Smrg    y_offset = pAST->HWCInfo.offset_y;
497b534f209Smrg
498b534f209Smrg    if(x < 0) {
499b534f209Smrg       x_offset = (-x) + pAST->HWCInfo.offset_x;
500b534f209Smrg       x = 0;
501b534f209Smrg    }
502b534f209Smrg
503b534f209Smrg    if(y < 0) {
504b534f209Smrg       y_offset = (-y) + pAST->HWCInfo.offset_y;
505b534f209Smrg       y = 0;
506b534f209Smrg    }
507b534f209Smrg
508b534f209Smrg    if(mode->Flags & V_DBLSCAN)  y *= 2;
509b534f209Smrg
510b534f209Smrg    /* Set to Reg. */
511b534f209Smrg    ulData = (x_offset) | (y_offset << 8);
512b534f209Smrg    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_OFFSET, ulData);
513b534f209Smrg    ulData = (x) | (y << 16);
514b534f209Smrg    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulData);
515b534f209Smrg
516b534f209Smrg} /* ASTSetCursorPosition_AST1180 */
517b534f209Smrg
51815fb4814Smrg#endif	/* End of HWC */
519