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