ast_cursor.c revision b534f209
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 "xaa.h"
4915fb4814Smrg#include "xaarop.h"
5015fb4814Smrg
5115fb4814Smrg/* H/W cursor support */
5215fb4814Smrg#include "xf86Cursor.h"
5315fb4814Smrg#include "cursorstr.h"
5415fb4814Smrg
5515fb4814Smrg/* Driver specific headers */
5615fb4814Smrg#include "ast.h"
5715fb4814Smrg
5815fb4814Smrg#ifdef	HWC
5915fb4814Smrg/* Prototype type declaration */
6015fb4814SmrgBool ASTCursorInit(ScreenPtr pScreen);
6115fb4814SmrgBool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST);
62b534f209Smrgvoid ASTDisableHWC(ScrnInfoPtr pScrn);
6315fb4814Smrgstatic void ASTShowCursor(ScrnInfoPtr pScrn);
64b534f209Smrgstatic void ASTHideCursor(ScrnInfoPtr pScrn);
6515fb4814Smrgstatic void ASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
6615fb4814Smrgstatic void ASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
6715fb4814Smrgstatic void ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src);
6815fb4814Smrgstatic Bool ASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs);
6915fb4814Smrgstatic void ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs);
7015fb4814Smrgstatic Bool ASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs);
7115fb4814Smrgstatic void ASTFireCursor(ScrnInfoPtr pScrn);
72b534f209Smrgstatic void ASTShowCursor_AST1180(ScrnInfoPtr pScrn);
73b534f209Smrgstatic void ASTHideCursor_AST1180(ScrnInfoPtr pScrn);
74b534f209Smrgstatic void ASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y);
7515fb4814Smrg
7615fb4814SmrgBool
7715fb4814SmrgASTCursorInit(ScreenPtr pScreen)
7815fb4814Smrg{
7915fb4814Smrg    ScrnInfoPtr	pScrn = xf86Screens[pScreen->myNum];
8015fb4814Smrg    ASTRecPtr 	pAST = ASTPTR(pScrn);
8115fb4814Smrg    xf86CursorInfoPtr infoPtr;
8215fb4814Smrg
8315fb4814Smrg    infoPtr = xf86CreateCursorInfoRec();
8415fb4814Smrg    if(!infoPtr) return FALSE;
8515fb4814Smrg
8615fb4814Smrg    pAST->HWCInfoPtr = infoPtr;
8715fb4814Smrg
8815fb4814Smrg    infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
8915fb4814Smrg                     HARDWARE_CURSOR_INVERT_MASK |
9015fb4814Smrg                     HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
9115fb4814Smrg
9215fb4814Smrg    infoPtr->MaxWidth  = MAX_HWC_WIDTH;
9315fb4814Smrg    infoPtr->MaxHeight = MAX_HWC_HEIGHT;
94b534f209Smrg    if (pAST->jChipType == AST1180)
95b534f209Smrg    {
96b534f209Smrg        infoPtr->ShowCursor = ASTShowCursor_AST1180;
97b534f209Smrg        infoPtr->HideCursor = ASTHideCursor_AST1180;
98b534f209Smrg        infoPtr->SetCursorPosition = ASTSetCursorPosition_AST1180;
99b534f209Smrg    }
100b534f209Smrg    else
101b534f209Smrg    {
102b534f209Smrg        infoPtr->ShowCursor = ASTShowCursor;
103b534f209Smrg        infoPtr->HideCursor = ASTHideCursor;
104b534f209Smrg        infoPtr->SetCursorPosition = ASTSetCursorPosition;
105b534f209Smrg    }
106b534f209Smrg    infoPtr->SetCursorColors = ASTSetCursorColors;
10715fb4814Smrg    infoPtr->LoadCursorImage = ASTLoadCursorImage;
10815fb4814Smrg    infoPtr->UseHWCursor = ASTUseHWCursor;
10915fb4814Smrg#ifdef ARGB_CURSOR
11015fb4814Smrg    infoPtr->UseHWCursorARGB = ASTUseHWCursorARGB;
11115fb4814Smrg    infoPtr->LoadCursorARGB = ASTLoadCursorARGB;
11215fb4814Smrg#endif
11315fb4814Smrg
11415fb4814Smrg    return(xf86InitCursor(pScreen, infoPtr));
11515fb4814Smrg
11615fb4814Smrg}
11715fb4814Smrg
11815fb4814SmrgBool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST)
11915fb4814Smrg{
12015fb4814Smrg    ScreenPtr	pScreen;
12115fb4814Smrg
12215fb4814Smrg    /* init cursor cache info */
12315fb4814Smrg    /* Set HWC_NUM in Options instead */
12415fb4814Smrg    /* pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM; */
12515fb4814Smrg    pAST->HWCInfo.HWC_NUM_Next = 0;
12615fb4814Smrg
12715fb4814Smrg    /* allocate HWC cache */
12815fb4814Smrg    if (!pAST->pHWCPtr) {
12915fb4814Smrg        pScreen = screenInfo.screens[pScrn->scrnIndex];
13015fb4814Smrg        pAST->pHWCPtr = xf86AllocateOffscreenLinear (pScreen, (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM, HWC_ALIGN, NULL, NULL, NULL);
13115fb4814Smrg
13215fb4814Smrg        if (!pAST->pHWCPtr) {
13315fb4814Smrg           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Allocate HWC Cache failed \n");
13415fb4814Smrg           return (FALSE);
13515fb4814Smrg        }
13615fb4814Smrg
13715fb4814Smrg        pAST->HWCInfo.ulHWCOffsetAddr  = pAST->pHWCPtr->offset*((pScrn->bitsPerPixel + 1) / 8);
13815fb4814Smrg        pAST->HWCInfo.pjHWCVirtualAddr = pAST->FBVirtualAddr + pAST->HWCInfo.ulHWCOffsetAddr;
13915fb4814Smrg    }
14015fb4814Smrg
14115fb4814Smrg    return (TRUE);
14215fb4814Smrg}
14315fb4814Smrg
144b534f209Smrgvoid ASTDisableHWC(ScrnInfoPtr pScrn)
145b534f209Smrg{
146b534f209Smrg    ASTRecPtr   pAST = ASTPTR(pScrn);
147b534f209Smrg
148b534f209Smrg    if (pAST->jChipType == AST1180)
149b534f209Smrg        ASTHideCursor_AST1180(pScrn);
150b534f209Smrg    else
151b534f209Smrg        ASTHideCursor(pScrn);
152b534f209Smrg}
15315fb4814Smrg
15415fb4814Smrgstatic void
15515fb4814SmrgASTShowCursor(ScrnInfoPtr pScrn)
15615fb4814Smrg{
15715fb4814Smrg    ASTRecPtr   pAST = ASTPTR(pScrn);
15815fb4814Smrg    UCHAR 	jReg;
15915fb4814Smrg
16015fb4814Smrg    jReg= 0x02;
16115fb4814Smrg    if (pAST->HWCInfo.cursortype ==HWC_COLOR)
16215fb4814Smrg        jReg |= 0x01;
16315fb4814Smrg
16415fb4814Smrg    SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, jReg);	/* enable mono */
16515fb4814Smrg
16615fb4814Smrg}
16715fb4814Smrg
168b534f209Smrgstatic void
16915fb4814SmrgASTHideCursor(ScrnInfoPtr pScrn)
17015fb4814Smrg{
17115fb4814Smrg    ASTRecPtr  pAST = ASTPTR(pScrn);
17215fb4814Smrg
17315fb4814Smrg    SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, 0x00);	/* disable HWC */
17415fb4814Smrg
17515fb4814Smrg}
17615fb4814Smrg
17715fb4814Smrgstatic void
17815fb4814SmrgASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
17915fb4814Smrg{
18015fb4814Smrg    ASTRecPtr	pAST = ASTPTR(pScrn);
18115fb4814Smrg    DisplayModePtr mode = pAST->ModePtr;
18215fb4814Smrg    int		x_offset, y_offset;
18315fb4814Smrg    UCHAR 	*pjSignature;
18415fb4814Smrg
18515fb4814Smrg    /* Set cursor info to Offscreen */
18615fb4814Smrg    pjSignature = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
18715fb4814Smrg    *((ULONG *) (pjSignature + HWC_SIGNATURE_X)) = x;
18815fb4814Smrg    *((ULONG *) (pjSignature + HWC_SIGNATURE_Y)) = y;
18915fb4814Smrg
19015fb4814Smrg    x_offset = pAST->HWCInfo.offset_x;
19115fb4814Smrg    y_offset = pAST->HWCInfo.offset_y;
19215fb4814Smrg
19315fb4814Smrg    if(x < 0) {
19415fb4814Smrg       x_offset = (-x) + pAST->HWCInfo.offset_x;
19515fb4814Smrg       x = 0;
19615fb4814Smrg    }
19715fb4814Smrg
19815fb4814Smrg    if(y < 0) {
19915fb4814Smrg       y_offset = (-y) + pAST->HWCInfo.offset_y;
20015fb4814Smrg       y = 0;
20115fb4814Smrg    }
20215fb4814Smrg
20315fb4814Smrg    if(mode->Flags & V_DBLSCAN)  y *= 2;
20415fb4814Smrg
20515fb4814Smrg    /* Set to Reg. */
20615fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC2, (UCHAR) (x_offset));
20715fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC3, (UCHAR) (y_offset));
20815fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC4, (UCHAR) (x & 0xFF));
20915fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC5, (UCHAR) ((x >> 8) & 0x0F));
21015fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC6, (UCHAR) (y & 0xFF));
21115fb4814Smrg    SetIndexReg(CRTC_PORT, 0xC7, (UCHAR) ((y >> 8) & 0x07));
21215fb4814Smrg
21315fb4814Smrg    /* Fire HWC */
21415fb4814Smrg    ASTFireCursor(pScrn);
21515fb4814Smrg
21615fb4814Smrg}
21715fb4814Smrg
21815fb4814Smrgstatic void
21915fb4814SmrgASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
22015fb4814Smrg{
22115fb4814Smrg    ASTRecPtr 	pAST = ASTPTR(pScrn);
222de78e416Smrg    ULONG fg1, bg1;
223de78e416Smrg
224de78e416Smrg    fg1 = (fg & 0x0F) | (((fg>>8) & 0x0F) << 4) | (((fg>>16) & 0x0F) << 8);
225de78e416Smrg    bg1 = (bg & 0x0F) | (((bg>>8) & 0x0F) << 4) | (((bg>>16) & 0x0F) << 8);
226de78e416Smrg
227de78e416Smrg    /* Fixed xorg bugzilla #20609, ycchen@031209 */
228de78e416Smrg    if ( (fg1 != pAST->HWCInfo.fg) || (bg1 != pAST->HWCInfo.bg) )
229de78e416Smrg    {
230de78e416Smrg    	pAST->HWCInfo.fg = fg1;
231de78e416Smrg    	pAST->HWCInfo.bg = bg1;
232de78e416Smrg        ASTLoadCursorImage(pScrn, pAST->HWCInfo.cursorpattern);
233de78e416Smrg    }
234de78e416Smrg
23515fb4814Smrg}
23615fb4814Smrg
23715fb4814Smrgstatic void
23815fb4814SmrgASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src)
23915fb4814Smrg{
24015fb4814Smrg    ASTRecPtr	pAST = ASTPTR(pScrn);
24115fb4814Smrg    int 	i, j, k;
24215fb4814Smrg    UCHAR 	*pjSrcAnd, *pjSrcXor, *pjDstData;
24315fb4814Smrg    ULONG   	ulTempDstAnd32[2], ulTempDstXor32[2], ulTempDstData32[2];
24415fb4814Smrg    UCHAR    	jTempSrcAnd32, jTempSrcXor32;
24515fb4814Smrg    ULONG	ulCheckSum = 0;
24615fb4814Smrg    ULONG 	ulPatternAddr;
24715fb4814Smrg
24815fb4814Smrg    /* init cursor info. */
24915fb4814Smrg    pAST->HWCInfo.cursortype = HWC_MONO;
25015fb4814Smrg    pAST->HWCInfo.width  = (USHORT) MAX_HWC_WIDTH;
25115fb4814Smrg    pAST->HWCInfo.height = (USHORT) MAX_HWC_HEIGHT;
25215fb4814Smrg    pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width;
25315fb4814Smrg    pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height;
25415fb4814Smrg
255de78e416Smrg    /* copy to hwc info */
256de78e416Smrg    for (i=0; i< MAX_HWC_WIDTH*MAX_HWC_HEIGHT/4; i+=4)
257de78e416Smrg       *(ULONG *) (pAST->HWCInfo.cursorpattern + i) = *(ULONG *) (src + i);
258de78e416Smrg
25915fb4814Smrg    /* copy cursor image to cache */
26015fb4814Smrg    pjSrcXor = src;
26115fb4814Smrg    pjSrcAnd = src + (MAX_HWC_WIDTH*MAX_HWC_HEIGHT/8);
26215fb4814Smrg    pjDstData =  pAST->HWCInfo.pjHWCVirtualAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next;
26315fb4814Smrg
26415fb4814Smrg    for (j = 0; j < MAX_HWC_HEIGHT; j++)
26515fb4814Smrg    {
26615fb4814Smrg       for (i = 0; i < (MAX_HWC_WIDTH/8); i++ )
26715fb4814Smrg       {
26815fb4814Smrg       	    for (k=7; k>0; k-=2)
26915fb4814Smrg       	    {
27015fb4814Smrg                jTempSrcAnd32 = *((UCHAR *) pjSrcAnd);
271de78e416Smrg                jTempSrcXor32 = *((UCHAR *) pjSrcXor);
272de78e416Smrg                ulTempDstAnd32[0] = ((jTempSrcAnd32 >> k) & 0x01) ? 0x00008000L:0x00L;
27315fb4814Smrg                ulTempDstXor32[0] = ((jTempSrcXor32 >> k) & 0x01) ? 0x00004000L:0x00L;
27415fb4814Smrg                ulTempDstData32[0] = ((jTempSrcXor32 >> k) & 0x01) ? pAST->HWCInfo.fg:pAST->HWCInfo.bg;
27515fb4814Smrg                ulTempDstAnd32[1] = ((jTempSrcAnd32 >> (k-1)) & 0x01) ? 0x80000000L:0x00L;
27615fb4814Smrg                ulTempDstXor32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? 0x40000000L:0x00L;
27715fb4814Smrg                ulTempDstData32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? (pAST->HWCInfo.fg << 16):(pAST->HWCInfo.bg << 16);
278de78e416Smrg                /* No inverse for X Window cursor, ycchen@111808 */
279de78e416Smrg                if (ulTempDstAnd32[0])
280de78e416Smrg                    ulTempDstXor32[0] = 0;
281de78e416Smrg                if (ulTempDstAnd32[1])
282de78e416Smrg                    ulTempDstXor32[1] = 0;
28315fb4814Smrg                *((ULONG *) pjDstData) = ulTempDstAnd32[0] | ulTempDstXor32[0] | ulTempDstData32[0] | ulTempDstAnd32[1] | ulTempDstXor32[1] | ulTempDstData32[1];
28415fb4814Smrg                ulCheckSum += *((ULONG *) pjDstData);
28515fb4814Smrg                pjDstData += 4;
28615fb4814Smrg
28715fb4814Smrg            }
28815fb4814Smrg            pjSrcAnd ++;
28915fb4814Smrg            pjSrcXor ++;
29015fb4814Smrg
29115fb4814Smrg       }
29215fb4814Smrg
29315fb4814Smrg    }
29415fb4814Smrg
295b534f209Smrg    if (pAST->jChipType == AST1180)
296b534f209Smrg    {
297b534f209Smrg        ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next);
298b534f209Smrg        WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr);
299b534f209Smrg    }
300b534f209Smrg    else
301b534f209Smrg    {
302b534f209Smrg        /* Write Checksum as signature */
303b534f209Smrg        pjDstData = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
304b534f209Smrg        *((ULONG *) pjDstData) = ulCheckSum;
305b534f209Smrg        *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width;
306b534f209Smrg        *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height;
307b534f209Smrg        *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTX)) = 0;
308b534f209Smrg        *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTY)) = 0;
309b534f209Smrg
310b534f209Smrg        /* set pattern offset */
311b534f209Smrg        ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3);
312b534f209Smrg        SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF));
313b534f209Smrg        SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF));
314b534f209Smrg        SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF));
315b534f209Smrg    }
31615fb4814Smrg
31715fb4814Smrg    /* update HWC_NUM_Next */
31815fb4814Smrg    pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM;
31915fb4814Smrg
32015fb4814Smrg}
32115fb4814Smrg
32215fb4814Smrgstatic Bool
32315fb4814SmrgASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
32415fb4814Smrg{
325de78e416Smrg    if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) )
326de78e416Smrg        return FALSE;
327de78e416Smrg
32815fb4814Smrg    return TRUE;
32915fb4814Smrg}
33015fb4814Smrg
33115fb4814Smrgstatic void
33215fb4814SmrgASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
33315fb4814Smrg{
33415fb4814Smrg    ASTRecPtr 	pAST = ASTPTR(pScrn);
33515fb4814Smrg
33615fb4814Smrg    UCHAR	*pjDstXor, *pjSrcXor;
33715fb4814Smrg    ULONG       i, j, ulSrcWidth, ulSrcHeight;
33815fb4814Smrg    ULONG	ulPerPixelCopy, ulTwoPixelCopy;
33915fb4814Smrg    LONG        lAlphaDstDelta, lLastAlphaDstDelta;
34015fb4814Smrg    union
34115fb4814Smrg    {
34215fb4814Smrg        ULONG   ul;
34315fb4814Smrg        UCHAR   b[4];
34415fb4814Smrg    } ulSrcData32[2], ulData32;
34515fb4814Smrg    union
34615fb4814Smrg    {
34715fb4814Smrg        USHORT  us;
34815fb4814Smrg        UCHAR   b[2];
34915fb4814Smrg    } usData16;
35015fb4814Smrg    ULONG	ulCheckSum = 0;
35115fb4814Smrg    ULONG 	ulPatternAddr;
35215fb4814Smrg
35315fb4814Smrg    /* init cursor info. */
35415fb4814Smrg    pAST->HWCInfo.cursortype = HWC_COLOR;
35515fb4814Smrg    pAST->HWCInfo.width  = pCurs->bits->width;
35615fb4814Smrg    pAST->HWCInfo.height = pCurs->bits->height;
35715fb4814Smrg    pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width;
35815fb4814Smrg    pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height;
35915fb4814Smrg
36015fb4814Smrg    /* copy cursor image to cache */
36115fb4814Smrg    ulSrcWidth  =  pAST->HWCInfo.width;
36215fb4814Smrg    ulSrcHeight =  pAST->HWCInfo.height;
36315fb4814Smrg
36415fb4814Smrg    lAlphaDstDelta = MAX_HWC_WIDTH << 1;
36515fb4814Smrg    lLastAlphaDstDelta = lAlphaDstDelta - (ulSrcWidth << 1);
36615fb4814Smrg
36715fb4814Smrg    pjSrcXor  = (UCHAR *) pCurs->bits->argb;;
36815fb4814Smrg    pjDstXor  = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next
36915fb4814Smrg                        + lLastAlphaDstDelta + (MAX_HWC_HEIGHT - ulSrcHeight) * lAlphaDstDelta;
37015fb4814Smrg
37115fb4814Smrg    ulPerPixelCopy =  ulSrcWidth & 1;
37215fb4814Smrg    ulTwoPixelCopy =  ulSrcWidth >> 1;
37315fb4814Smrg
37415fb4814Smrg    for (j = 0; j < ulSrcHeight; j++)
37515fb4814Smrg    {
37615fb4814Smrg
37715fb4814Smrg        for (i = 0; i < ulTwoPixelCopy; i++ )
37815fb4814Smrg        {
37915fb4814Smrg            ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0;
38015fb4814Smrg            ulSrcData32[1].ul = *((ULONG *) (pjSrcXor+4)) & 0xF0F0F0F0;
38115fb4814Smrg            ulData32.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4);
38215fb4814Smrg            ulData32.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4);
38315fb4814Smrg            ulData32.b[2] = ulSrcData32[1].b[1] | (ulSrcData32[1].b[0] >> 4);
38415fb4814Smrg            ulData32.b[3] = ulSrcData32[1].b[3] | (ulSrcData32[1].b[2] >> 4);
38515fb4814Smrg            *((ULONG *) pjDstXor) = ulData32.ul;
38615fb4814Smrg            ulCheckSum += (ULONG) ulData32.ul;
38715fb4814Smrg            pjDstXor += 4;
38815fb4814Smrg            pjSrcXor += 8;
38915fb4814Smrg        }
39015fb4814Smrg
39115fb4814Smrg        for (i = 0; i < ulPerPixelCopy; i++ )
39215fb4814Smrg        {
39315fb4814Smrg            ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0;
39415fb4814Smrg            usData16.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4);
39515fb4814Smrg            usData16.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4);
39615fb4814Smrg            *((USHORT *) pjDstXor) = usData16.us;
39715fb4814Smrg            ulCheckSum += (ULONG) usData16.us;
39815fb4814Smrg            pjDstXor += 2;
39915fb4814Smrg            pjSrcXor += 4;
40015fb4814Smrg        }
40115fb4814Smrg
40215fb4814Smrg        /* Point to next source and dest scans */
40315fb4814Smrg        pjDstXor += lLastAlphaDstDelta;
40415fb4814Smrg
40515fb4814Smrg    } /* end of for-loop */
40615fb4814Smrg
407b534f209Smrg    if (pAST->jChipType == AST1180)
408b534f209Smrg    {
409b534f209Smrg        ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next);
410b534f209Smrg        WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr);
411b534f209Smrg    }
412b534f209Smrg    else
413b534f209Smrg    {
414b534f209Smrg        /* Write Checksum as signature */
415b534f209Smrg        pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
416b534f209Smrg        *((ULONG *) pjDstXor) = ulCheckSum;
417b534f209Smrg        *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width;
418b534f209Smrg        *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height;
419b534f209Smrg        *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTX)) = 0;
420b534f209Smrg        *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTY)) = 0;
421b534f209Smrg
422b534f209Smrg        /* set pattern offset */
423b534f209Smrg        ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr +(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3);
424b534f209Smrg        SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF));
425b534f209Smrg        SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF));
426b534f209Smrg        SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF));
427b534f209Smrg    }
42815fb4814Smrg
42915fb4814Smrg    /* update HWC_NUM_Next */
43015fb4814Smrg    pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM;
43115fb4814Smrg
43215fb4814Smrg}
43315fb4814Smrg
43415fb4814Smrgstatic Bool
43515fb4814SmrgASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
43615fb4814Smrg{
437de78e416Smrg    if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) )
438de78e416Smrg        return FALSE;
439de78e416Smrg
44015fb4814Smrg    return TRUE;
44115fb4814Smrg}
44215fb4814Smrg
44315fb4814Smrgstatic void
44415fb4814SmrgASTFireCursor(ScrnInfoPtr pScrn)
44515fb4814Smrg{
44615fb4814Smrg    ASTRecPtr  pAST = ASTPTR(pScrn);
44715fb4814Smrg
44815fb4814Smrg    SetIndexRegMask(CRTC_PORT, 0xCB, 0xFF, 0x00);	/* dummp write to fire HWC */
44915fb4814Smrg
45015fb4814Smrg}
45115fb4814Smrg
452b534f209Smrg/* AST1180 */
453b534f209Smrgstatic void
454b534f209SmrgASTShowCursor_AST1180(ScrnInfoPtr pScrn)
455b534f209Smrg{
456b534f209Smrg    ASTRecPtr   pAST = ASTPTR(pScrn);
457b534f209Smrg    ULONG 	ulData, ulTemp;
458b534f209Smrg
459b534f209Smrg    ReadAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp);
460b534f209Smrg
461b534f209Smrg    ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData);
462b534f209Smrg    ulData &= ~AST1180_ALPHAHWC;
463b534f209Smrg    if (pAST->HWCInfo.cursortype ==HWC_COLOR)
464b534f209Smrg        ulData |= AST1180_ALPHAHWC;
465b534f209Smrg    ulData |= AST1180_ENABLEHWC;
466b534f209Smrg    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData);
467b534f209Smrg
468b534f209Smrg    /* fire cursor */
469b534f209Smrg    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp);
470b534f209Smrg
471b534f209Smrg} /* ASTShowCursor_AST1180 */
472b534f209Smrg
473b534f209Smrgstatic void
474b534f209SmrgASTHideCursor_AST1180(ScrnInfoPtr pScrn)
475b534f209Smrg{
476b534f209Smrg    ASTRecPtr  pAST = ASTPTR(pScrn);
477b534f209Smrg    ULONG 	ulData;
478b534f209Smrg
479b534f209Smrg    ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData);
480b534f209Smrg    ulData &= ~AST1180_ENABLEHWC;
481b534f209Smrg    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData);
482b534f209Smrg
483b534f209Smrg    /* fire cursor */
484b534f209Smrg    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, 0x07ff07ff);
485b534f209Smrg
486b534f209Smrg} /* ASTHideCursor_AST1180 */
487b534f209Smrg
488b534f209Smrgstatic void
489b534f209SmrgASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y)
490b534f209Smrg{
491b534f209Smrg    ASTRecPtr	pAST = ASTPTR(pScrn);
492b534f209Smrg    DisplayModePtr mode = pAST->ModePtr;
493b534f209Smrg    int		x_offset, y_offset;
494b534f209Smrg    ULONG	ulData;
495b534f209Smrg
496b534f209Smrg    x_offset = pAST->HWCInfo.offset_x;
497b534f209Smrg    y_offset = pAST->HWCInfo.offset_y;
498b534f209Smrg
499b534f209Smrg    if(x < 0) {
500b534f209Smrg       x_offset = (-x) + pAST->HWCInfo.offset_x;
501b534f209Smrg       x = 0;
502b534f209Smrg    }
503b534f209Smrg
504b534f209Smrg    if(y < 0) {
505b534f209Smrg       y_offset = (-y) + pAST->HWCInfo.offset_y;
506b534f209Smrg       y = 0;
507b534f209Smrg    }
508b534f209Smrg
509b534f209Smrg    if(mode->Flags & V_DBLSCAN)  y *= 2;
510b534f209Smrg
511b534f209Smrg    /* Set to Reg. */
512b534f209Smrg    ulData = (x_offset) | (y_offset << 8);
513b534f209Smrg    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_OFFSET, ulData);
514b534f209Smrg    ulData = (x) | (y << 16);
515b534f209Smrg    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulData);
516b534f209Smrg
517b534f209Smrg} /* ASTSetCursorPosition_AST1180 */
518b534f209Smrg
51915fb4814Smrg#endif	/* End of HWC */
520