ast_cursor.c revision b534f209
1/*
2 * Copyright (c) 2005 ASPEED Technology Inc.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the authors not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  The authors makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as is" without express or implied warranty.
13 *
14 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26#include "xf86.h"
27#include "xf86_OSproc.h"
28#include "xf86cmap.h"
29#include "compiler.h"
30#include "mibstore.h"
31#include "vgaHW.h"
32#include "mipointer.h"
33#include "micmap.h"
34
35#include "fb.h"
36#include "regionstr.h"
37#include "xf86xv.h"
38#include <X11/extensions/Xv.h>
39#include "vbe.h"
40
41#include "xf86PciInfo.h"
42#include "xf86Pci.h"
43
44/* framebuffer offscreen manager */
45#include "xf86fbman.h"
46
47/* include xaa includes */
48#include "xaa.h"
49#include "xaarop.h"
50
51/* H/W cursor support */
52#include "xf86Cursor.h"
53#include "cursorstr.h"
54
55/* Driver specific headers */
56#include "ast.h"
57
58#ifdef	HWC
59/* Prototype type declaration */
60Bool ASTCursorInit(ScreenPtr pScreen);
61Bool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST);
62void ASTDisableHWC(ScrnInfoPtr pScrn);
63static void ASTShowCursor(ScrnInfoPtr pScrn);
64static void ASTHideCursor(ScrnInfoPtr pScrn);
65static void ASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
66static void ASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
67static void ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src);
68static Bool ASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs);
69static void ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs);
70static Bool ASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs);
71static void ASTFireCursor(ScrnInfoPtr pScrn);
72static void ASTShowCursor_AST1180(ScrnInfoPtr pScrn);
73static void ASTHideCursor_AST1180(ScrnInfoPtr pScrn);
74static void ASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y);
75
76Bool
77ASTCursorInit(ScreenPtr pScreen)
78{
79    ScrnInfoPtr	pScrn = xf86Screens[pScreen->myNum];
80    ASTRecPtr 	pAST = ASTPTR(pScrn);
81    xf86CursorInfoPtr infoPtr;
82
83    infoPtr = xf86CreateCursorInfoRec();
84    if(!infoPtr) return FALSE;
85
86    pAST->HWCInfoPtr = infoPtr;
87
88    infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
89                     HARDWARE_CURSOR_INVERT_MASK |
90                     HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
91
92    infoPtr->MaxWidth  = MAX_HWC_WIDTH;
93    infoPtr->MaxHeight = MAX_HWC_HEIGHT;
94    if (pAST->jChipType == AST1180)
95    {
96        infoPtr->ShowCursor = ASTShowCursor_AST1180;
97        infoPtr->HideCursor = ASTHideCursor_AST1180;
98        infoPtr->SetCursorPosition = ASTSetCursorPosition_AST1180;
99    }
100    else
101    {
102        infoPtr->ShowCursor = ASTShowCursor;
103        infoPtr->HideCursor = ASTHideCursor;
104        infoPtr->SetCursorPosition = ASTSetCursorPosition;
105    }
106    infoPtr->SetCursorColors = ASTSetCursorColors;
107    infoPtr->LoadCursorImage = ASTLoadCursorImage;
108    infoPtr->UseHWCursor = ASTUseHWCursor;
109#ifdef ARGB_CURSOR
110    infoPtr->UseHWCursorARGB = ASTUseHWCursorARGB;
111    infoPtr->LoadCursorARGB = ASTLoadCursorARGB;
112#endif
113
114    return(xf86InitCursor(pScreen, infoPtr));
115
116}
117
118Bool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST)
119{
120    ScreenPtr	pScreen;
121
122    /* init cursor cache info */
123    /* Set HWC_NUM in Options instead */
124    /* pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM; */
125    pAST->HWCInfo.HWC_NUM_Next = 0;
126
127    /* allocate HWC cache */
128    if (!pAST->pHWCPtr) {
129        pScreen = screenInfo.screens[pScrn->scrnIndex];
130        pAST->pHWCPtr = xf86AllocateOffscreenLinear (pScreen, (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM, HWC_ALIGN, NULL, NULL, NULL);
131
132        if (!pAST->pHWCPtr) {
133           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Allocate HWC Cache failed \n");
134           return (FALSE);
135        }
136
137        pAST->HWCInfo.ulHWCOffsetAddr  = pAST->pHWCPtr->offset*((pScrn->bitsPerPixel + 1) / 8);
138        pAST->HWCInfo.pjHWCVirtualAddr = pAST->FBVirtualAddr + pAST->HWCInfo.ulHWCOffsetAddr;
139    }
140
141    return (TRUE);
142}
143
144void ASTDisableHWC(ScrnInfoPtr pScrn)
145{
146    ASTRecPtr   pAST = ASTPTR(pScrn);
147
148    if (pAST->jChipType == AST1180)
149        ASTHideCursor_AST1180(pScrn);
150    else
151        ASTHideCursor(pScrn);
152}
153
154static void
155ASTShowCursor(ScrnInfoPtr pScrn)
156{
157    ASTRecPtr   pAST = ASTPTR(pScrn);
158    UCHAR 	jReg;
159
160    jReg= 0x02;
161    if (pAST->HWCInfo.cursortype ==HWC_COLOR)
162        jReg |= 0x01;
163
164    SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, jReg);	/* enable mono */
165
166}
167
168static void
169ASTHideCursor(ScrnInfoPtr pScrn)
170{
171    ASTRecPtr  pAST = ASTPTR(pScrn);
172
173    SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, 0x00);	/* disable HWC */
174
175}
176
177static void
178ASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
179{
180    ASTRecPtr	pAST = ASTPTR(pScrn);
181    DisplayModePtr mode = pAST->ModePtr;
182    int		x_offset, y_offset;
183    UCHAR 	*pjSignature;
184
185    /* Set cursor info to Offscreen */
186    pjSignature = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
187    *((ULONG *) (pjSignature + HWC_SIGNATURE_X)) = x;
188    *((ULONG *) (pjSignature + HWC_SIGNATURE_Y)) = y;
189
190    x_offset = pAST->HWCInfo.offset_x;
191    y_offset = pAST->HWCInfo.offset_y;
192
193    if(x < 0) {
194       x_offset = (-x) + pAST->HWCInfo.offset_x;
195       x = 0;
196    }
197
198    if(y < 0) {
199       y_offset = (-y) + pAST->HWCInfo.offset_y;
200       y = 0;
201    }
202
203    if(mode->Flags & V_DBLSCAN)  y *= 2;
204
205    /* Set to Reg. */
206    SetIndexReg(CRTC_PORT, 0xC2, (UCHAR) (x_offset));
207    SetIndexReg(CRTC_PORT, 0xC3, (UCHAR) (y_offset));
208    SetIndexReg(CRTC_PORT, 0xC4, (UCHAR) (x & 0xFF));
209    SetIndexReg(CRTC_PORT, 0xC5, (UCHAR) ((x >> 8) & 0x0F));
210    SetIndexReg(CRTC_PORT, 0xC6, (UCHAR) (y & 0xFF));
211    SetIndexReg(CRTC_PORT, 0xC7, (UCHAR) ((y >> 8) & 0x07));
212
213    /* Fire HWC */
214    ASTFireCursor(pScrn);
215
216}
217
218static void
219ASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
220{
221    ASTRecPtr 	pAST = ASTPTR(pScrn);
222    ULONG fg1, bg1;
223
224    fg1 = (fg & 0x0F) | (((fg>>8) & 0x0F) << 4) | (((fg>>16) & 0x0F) << 8);
225    bg1 = (bg & 0x0F) | (((bg>>8) & 0x0F) << 4) | (((bg>>16) & 0x0F) << 8);
226
227    /* Fixed xorg bugzilla #20609, ycchen@031209 */
228    if ( (fg1 != pAST->HWCInfo.fg) || (bg1 != pAST->HWCInfo.bg) )
229    {
230    	pAST->HWCInfo.fg = fg1;
231    	pAST->HWCInfo.bg = bg1;
232        ASTLoadCursorImage(pScrn, pAST->HWCInfo.cursorpattern);
233    }
234
235}
236
237static void
238ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src)
239{
240    ASTRecPtr	pAST = ASTPTR(pScrn);
241    int 	i, j, k;
242    UCHAR 	*pjSrcAnd, *pjSrcXor, *pjDstData;
243    ULONG   	ulTempDstAnd32[2], ulTempDstXor32[2], ulTempDstData32[2];
244    UCHAR    	jTempSrcAnd32, jTempSrcXor32;
245    ULONG	ulCheckSum = 0;
246    ULONG 	ulPatternAddr;
247
248    /* init cursor info. */
249    pAST->HWCInfo.cursortype = HWC_MONO;
250    pAST->HWCInfo.width  = (USHORT) MAX_HWC_WIDTH;
251    pAST->HWCInfo.height = (USHORT) MAX_HWC_HEIGHT;
252    pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width;
253    pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height;
254
255    /* copy to hwc info */
256    for (i=0; i< MAX_HWC_WIDTH*MAX_HWC_HEIGHT/4; i+=4)
257       *(ULONG *) (pAST->HWCInfo.cursorpattern + i) = *(ULONG *) (src + i);
258
259    /* copy cursor image to cache */
260    pjSrcXor = src;
261    pjSrcAnd = src + (MAX_HWC_WIDTH*MAX_HWC_HEIGHT/8);
262    pjDstData =  pAST->HWCInfo.pjHWCVirtualAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next;
263
264    for (j = 0; j < MAX_HWC_HEIGHT; j++)
265    {
266       for (i = 0; i < (MAX_HWC_WIDTH/8); i++ )
267       {
268       	    for (k=7; k>0; k-=2)
269       	    {
270                jTempSrcAnd32 = *((UCHAR *) pjSrcAnd);
271                jTempSrcXor32 = *((UCHAR *) pjSrcXor);
272                ulTempDstAnd32[0] = ((jTempSrcAnd32 >> k) & 0x01) ? 0x00008000L:0x00L;
273                ulTempDstXor32[0] = ((jTempSrcXor32 >> k) & 0x01) ? 0x00004000L:0x00L;
274                ulTempDstData32[0] = ((jTempSrcXor32 >> k) & 0x01) ? pAST->HWCInfo.fg:pAST->HWCInfo.bg;
275                ulTempDstAnd32[1] = ((jTempSrcAnd32 >> (k-1)) & 0x01) ? 0x80000000L:0x00L;
276                ulTempDstXor32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? 0x40000000L:0x00L;
277                ulTempDstData32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? (pAST->HWCInfo.fg << 16):(pAST->HWCInfo.bg << 16);
278                /* No inverse for X Window cursor, ycchen@111808 */
279                if (ulTempDstAnd32[0])
280                    ulTempDstXor32[0] = 0;
281                if (ulTempDstAnd32[1])
282                    ulTempDstXor32[1] = 0;
283                *((ULONG *) pjDstData) = ulTempDstAnd32[0] | ulTempDstXor32[0] | ulTempDstData32[0] | ulTempDstAnd32[1] | ulTempDstXor32[1] | ulTempDstData32[1];
284                ulCheckSum += *((ULONG *) pjDstData);
285                pjDstData += 4;
286
287            }
288            pjSrcAnd ++;
289            pjSrcXor ++;
290
291       }
292
293    }
294
295    if (pAST->jChipType == AST1180)
296    {
297        ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next);
298        WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr);
299    }
300    else
301    {
302        /* Write Checksum as signature */
303        pjDstData = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
304        *((ULONG *) pjDstData) = ulCheckSum;
305        *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width;
306        *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height;
307        *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTX)) = 0;
308        *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTY)) = 0;
309
310        /* set pattern offset */
311        ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3);
312        SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF));
313        SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF));
314        SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF));
315    }
316
317    /* update HWC_NUM_Next */
318    pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM;
319
320}
321
322static Bool
323ASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
324{
325    if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) )
326        return FALSE;
327
328    return TRUE;
329}
330
331static void
332ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
333{
334    ASTRecPtr 	pAST = ASTPTR(pScrn);
335
336    UCHAR	*pjDstXor, *pjSrcXor;
337    ULONG       i, j, ulSrcWidth, ulSrcHeight;
338    ULONG	ulPerPixelCopy, ulTwoPixelCopy;
339    LONG        lAlphaDstDelta, lLastAlphaDstDelta;
340    union
341    {
342        ULONG   ul;
343        UCHAR   b[4];
344    } ulSrcData32[2], ulData32;
345    union
346    {
347        USHORT  us;
348        UCHAR   b[2];
349    } usData16;
350    ULONG	ulCheckSum = 0;
351    ULONG 	ulPatternAddr;
352
353    /* init cursor info. */
354    pAST->HWCInfo.cursortype = HWC_COLOR;
355    pAST->HWCInfo.width  = pCurs->bits->width;
356    pAST->HWCInfo.height = pCurs->bits->height;
357    pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width;
358    pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height;
359
360    /* copy cursor image to cache */
361    ulSrcWidth  =  pAST->HWCInfo.width;
362    ulSrcHeight =  pAST->HWCInfo.height;
363
364    lAlphaDstDelta = MAX_HWC_WIDTH << 1;
365    lLastAlphaDstDelta = lAlphaDstDelta - (ulSrcWidth << 1);
366
367    pjSrcXor  = (UCHAR *) pCurs->bits->argb;;
368    pjDstXor  = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next
369                        + lLastAlphaDstDelta + (MAX_HWC_HEIGHT - ulSrcHeight) * lAlphaDstDelta;
370
371    ulPerPixelCopy =  ulSrcWidth & 1;
372    ulTwoPixelCopy =  ulSrcWidth >> 1;
373
374    for (j = 0; j < ulSrcHeight; j++)
375    {
376
377        for (i = 0; i < ulTwoPixelCopy; i++ )
378        {
379            ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0;
380            ulSrcData32[1].ul = *((ULONG *) (pjSrcXor+4)) & 0xF0F0F0F0;
381            ulData32.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4);
382            ulData32.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4);
383            ulData32.b[2] = ulSrcData32[1].b[1] | (ulSrcData32[1].b[0] >> 4);
384            ulData32.b[3] = ulSrcData32[1].b[3] | (ulSrcData32[1].b[2] >> 4);
385            *((ULONG *) pjDstXor) = ulData32.ul;
386            ulCheckSum += (ULONG) ulData32.ul;
387            pjDstXor += 4;
388            pjSrcXor += 8;
389        }
390
391        for (i = 0; i < ulPerPixelCopy; i++ )
392        {
393            ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0;
394            usData16.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4);
395            usData16.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4);
396            *((USHORT *) pjDstXor) = usData16.us;
397            ulCheckSum += (ULONG) usData16.us;
398            pjDstXor += 2;
399            pjSrcXor += 4;
400        }
401
402        /* Point to next source and dest scans */
403        pjDstXor += lLastAlphaDstDelta;
404
405    } /* end of for-loop */
406
407    if (pAST->jChipType == AST1180)
408    {
409        ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next);
410        WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr);
411    }
412    else
413    {
414        /* Write Checksum as signature */
415        pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
416        *((ULONG *) pjDstXor) = ulCheckSum;
417        *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width;
418        *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height;
419        *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTX)) = 0;
420        *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTY)) = 0;
421
422        /* set pattern offset */
423        ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr +(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3);
424        SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF));
425        SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF));
426        SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF));
427    }
428
429    /* update HWC_NUM_Next */
430    pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM;
431
432}
433
434static Bool
435ASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
436{
437    if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) )
438        return FALSE;
439
440    return TRUE;
441}
442
443static void
444ASTFireCursor(ScrnInfoPtr pScrn)
445{
446    ASTRecPtr  pAST = ASTPTR(pScrn);
447
448    SetIndexRegMask(CRTC_PORT, 0xCB, 0xFF, 0x00);	/* dummp write to fire HWC */
449
450}
451
452/* AST1180 */
453static void
454ASTShowCursor_AST1180(ScrnInfoPtr pScrn)
455{
456    ASTRecPtr   pAST = ASTPTR(pScrn);
457    ULONG 	ulData, ulTemp;
458
459    ReadAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp);
460
461    ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData);
462    ulData &= ~AST1180_ALPHAHWC;
463    if (pAST->HWCInfo.cursortype ==HWC_COLOR)
464        ulData |= AST1180_ALPHAHWC;
465    ulData |= AST1180_ENABLEHWC;
466    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData);
467
468    /* fire cursor */
469    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp);
470
471} /* ASTShowCursor_AST1180 */
472
473static void
474ASTHideCursor_AST1180(ScrnInfoPtr pScrn)
475{
476    ASTRecPtr  pAST = ASTPTR(pScrn);
477    ULONG 	ulData;
478
479    ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData);
480    ulData &= ~AST1180_ENABLEHWC;
481    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData);
482
483    /* fire cursor */
484    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, 0x07ff07ff);
485
486} /* ASTHideCursor_AST1180 */
487
488static void
489ASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y)
490{
491    ASTRecPtr	pAST = ASTPTR(pScrn);
492    DisplayModePtr mode = pAST->ModePtr;
493    int		x_offset, y_offset;
494    ULONG	ulData;
495
496    x_offset = pAST->HWCInfo.offset_x;
497    y_offset = pAST->HWCInfo.offset_y;
498
499    if(x < 0) {
500       x_offset = (-x) + pAST->HWCInfo.offset_x;
501       x = 0;
502    }
503
504    if(y < 0) {
505       y_offset = (-y) + pAST->HWCInfo.offset_y;
506       y = 0;
507    }
508
509    if(mode->Flags & V_DBLSCAN)  y *= 2;
510
511    /* Set to Reg. */
512    ulData = (x_offset) | (y_offset << 8);
513    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_OFFSET, ulData);
514    ulData = (x) | (y << 16);
515    WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulData);
516
517} /* ASTSetCursorPosition_AST1180 */
518
519#endif	/* End of HWC */
520