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