ct_cursor.c revision a1d73b4b
1c06b6b69Smrg
2c06b6b69Smrg/*
3c06b6b69Smrg * Copyright 1994  The XFree86 Project
4c06b6b69Smrg *
5c06b6b69Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6c06b6b69Smrg * copy of this software and associated documentation files (the "Software"),
7c06b6b69Smrg * to deal in the Software without restriction, including without limitation
8c06b6b69Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9c06b6b69Smrg * and/or sell copies of the Software, and to permit persons to whom the
10c06b6b69Smrg * Software is furnished to do so, subject to the following conditions:
11c06b6b69Smrg *
12c06b6b69Smrg * The above copyright notice and this permission notice shall be included in
13c06b6b69Smrg * all copies or substantial portions of the Software.
14c06b6b69Smrg *
15c06b6b69Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16c06b6b69Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17c06b6b69Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18c06b6b69Smrg * DAVID WEXELBLAT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19c06b6b69Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20c06b6b69Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21c06b6b69Smrg * SOFTWARE.
22c06b6b69Smrg *
23c06b6b69Smrg * Hardware Cursor for Trident utilizing XAA Cursor code.
24c06b6b69Smrg * Written by Alan Hourihane <alanh@fairlite.demon.co.uk>
25c06b6b69Smrg * Modified for Chips and Technologies by David Bateman <dbateman@eng.uts.edu.au>
26c06b6b69Smrg */
27c06b6b69Smrg
28c06b6b69Smrg#ifdef HAVE_CONFIG_H
29c06b6b69Smrg#include "config.h"
30c06b6b69Smrg#endif
31c06b6b69Smrg
32c06b6b69Smrg/* All drivers should typically include these */
33c06b6b69Smrg#include "xf86.h"
34c06b6b69Smrg#include "xf86_OSproc.h"
35c06b6b69Smrg
36c06b6b69Smrg/* Everything using inb/outb, etc needs "compiler.h" */
37c06b6b69Smrg#include "compiler.h"
38c06b6b69Smrg
39c06b6b69Smrg/* Drivers that need to access the PCI config space directly need this */
40c06b6b69Smrg#include "xf86Pci.h"
41c06b6b69Smrg
42c06b6b69Smrg#include "xf86Cursor.h"
43c06b6b69Smrg
44c06b6b69Smrg/* Driver specific headers */
45c06b6b69Smrg#include "ct_driver.h"
46c06b6b69Smrg
47c06b6b69Smrg/* Sync function, maybe this should check infoRec->NeedToSync before syncing */
48c06b6b69Smrg#define CURSOR_SYNC(pScrn) \
49c06b6b69Smrg    if (IS_HiQV(cPtr)) { \
50c06b6b69Smrg	CHIPSHiQVSync(pScrn); \
51c06b6b69Smrg    } else { \
52c06b6b69Smrg	if(!cPtr->UseMMIO) { \
53c06b6b69Smrg	    CHIPSSync(pScrn); \
54c06b6b69Smrg	} else { \
55c06b6b69Smrg	    CHIPSMMIOSync(pScrn); \
56c06b6b69Smrg	} \
57c06b6b69Smrg    }
58c06b6b69Smrg
59c06b6b69Smrg/* Swing your cursor bytes round and round... yeehaw! */
60c06b6b69Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN
61c06b6b69Smrg#define P_SWAP32( a , b )                \
62c06b6b69Smrg       ((char *)a)[0] = ((char *)b)[3];  \
63c06b6b69Smrg       ((char *)a)[1] = ((char *)b)[2];  \
64c06b6b69Smrg       ((char *)a)[2] = ((char *)b)[1];  \
65c06b6b69Smrg       ((char *)a)[3] = ((char *)b)[0]
66c06b6b69Smrg
67c06b6b69Smrg#define P_SWAP16( a , b )                \
68c06b6b69Smrg       ((char *)a)[0] = ((char *)b)[1];  \
69c06b6b69Smrg       ((char *)a)[1] = ((char *)b)[0];  \
70c06b6b69Smrg       ((char *)a)[2] = ((char *)b)[3];  \
71c06b6b69Smrg       ((char *)a)[3] = ((char *)b)[2]
72c06b6b69Smrg#endif
73c06b6b69Smrg
74c06b6b69Smrgstatic void
75c06b6b69SmrgCHIPSShowCursor(ScrnInfoPtr pScrn)
76c06b6b69Smrg{
77c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
78c06b6b69Smrg    unsigned char tmp;
79c06b6b69Smrg
80c06b6b69Smrg    CURSOR_SYNC(pScrn);
81c06b6b69Smrg
82c06b6b69Smrg    /* turn the cursor on */
83c06b6b69Smrg    if (IS_HiQV(cPtr)) {
84c06b6b69Smrg	tmp = cPtr->readXR(cPtr, 0xA0);
85c06b6b69Smrg	cPtr->writeXR(cPtr, 0xA0, (tmp & 0xF8) | 5);
86c06b6b69Smrg	if (cPtr->UseDualChannel &&
87c06b6b69Smrg	    (! xf86IsEntityShared(pScrn->entityList[0]))) {
88c06b6b69Smrg	    unsigned int IOSS, MSS;
89c06b6b69Smrg	    IOSS = cPtr->readIOSS(cPtr);
90c06b6b69Smrg	    MSS = cPtr->readMSS(cPtr);
91c06b6b69Smrg	    cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
92c06b6b69Smrg				   IOSS_PIPE_B));
93c06b6b69Smrg	    cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS &
94c06b6b69Smrg				  MSS_MASK) | MSS_PIPE_B));
95c06b6b69Smrg	    tmp = cPtr->readXR(cPtr, 0xA0);
96c06b6b69Smrg	    cPtr->writeXR(cPtr, 0xA0, (tmp & 0xF8) | 5);
97c06b6b69Smrg	    cPtr->writeIOSS(cPtr, IOSS);
98c06b6b69Smrg	    cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS);
99c06b6b69Smrg	}
100c06b6b69Smrg    } else {
101c06b6b69Smrg	if(!cPtr->UseMMIO) {
102c06b6b69Smrg	    HW_DEBUG(0x8);
103c06b6b69Smrg	    outw(cPtr->PIOBase+DR(0x8), 0x21);
104c06b6b69Smrg	} else {
105c06b6b69Smrg	    HW_DEBUG(DR(8));
106c06b6b69Smrg	    /*  Used to be: MMIOmemw(MR(8)) = 0x21; */
107c06b6b69Smrg	    MMIOmeml(MR(8)) = 0x21;
108c06b6b69Smrg	}
109c06b6b69Smrg    }
110c06b6b69Smrg    cPtr->HWCursorShown = TRUE;
111c06b6b69Smrg}
112c06b6b69Smrg
113c06b6b69Smrgstatic void
114c06b6b69SmrgCHIPSHideCursor(ScrnInfoPtr pScrn)
115c06b6b69Smrg{
116c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
117c06b6b69Smrg    unsigned char tmp;
118c06b6b69Smrg
119c06b6b69Smrg    CURSOR_SYNC(pScrn);
120c06b6b69Smrg
121c06b6b69Smrg    /* turn the cursor off */
122c06b6b69Smrg    if (IS_HiQV(cPtr)) {
123c06b6b69Smrg	tmp = cPtr->readXR(cPtr, 0xA0);
124c06b6b69Smrg	cPtr->writeXR(cPtr, 0xA0, tmp & 0xF8);
125c06b6b69Smrg	if (cPtr->UseDualChannel &&
126c06b6b69Smrg	    (! xf86IsEntityShared(pScrn->entityList[0]))) {
127c06b6b69Smrg	    unsigned int IOSS, MSS;
128c06b6b69Smrg	    IOSS = cPtr->readIOSS(cPtr);
129c06b6b69Smrg	    MSS = cPtr->readMSS(cPtr);
130c06b6b69Smrg	    cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
131c06b6b69Smrg				   IOSS_PIPE_B));
132c06b6b69Smrg	    cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS &
133c06b6b69Smrg				  MSS_MASK) | MSS_PIPE_B));
134c06b6b69Smrg	    tmp = cPtr->readXR(cPtr, 0xA0);
135c06b6b69Smrg	    cPtr->writeXR(cPtr, 0xA0, tmp & 0xF8);
136c06b6b69Smrg	    cPtr->writeIOSS(cPtr, IOSS);
137c06b6b69Smrg	    cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS);
138c06b6b69Smrg	}
139c06b6b69Smrg    } else {
140c06b6b69Smrg	if(!cPtr->UseMMIO) {
141c06b6b69Smrg	    HW_DEBUG(0x8);
142c06b6b69Smrg	    outw(cPtr->PIOBase+DR(0x8), 0x20);
143c06b6b69Smrg	} else {
144c06b6b69Smrg	    HW_DEBUG(DR(0x8));
145c06b6b69Smrg	    /* Used to be: MMIOmemw(DR(0x8)) = 0x20; */
146c06b6b69Smrg	    MMIOmeml(DR(0x8)) = 0x20;
147c06b6b69Smrg	}
148c06b6b69Smrg    }
149c06b6b69Smrg    cPtr->HWCursorShown = FALSE;
150c06b6b69Smrg}
151c06b6b69Smrg
152c06b6b69Smrgstatic void
153c06b6b69SmrgCHIPSSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
154c06b6b69Smrg{
155c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
156c06b6b69Smrg
157c06b6b69Smrg    CURSOR_SYNC(pScrn);
158c06b6b69Smrg
159c06b6b69Smrg    if (x < 0)
160c06b6b69Smrg	x = ~(x-1) | 0x8000;
161c06b6b69Smrg    if (y < 0)
162c06b6b69Smrg	y = ~(y-1) | 0x8000;
163c06b6b69Smrg
164c06b6b69Smrg    /* Program the cursor origin (offset into the cursor bitmap). */
165c06b6b69Smrg    if (IS_HiQV(cPtr)) {
166c06b6b69Smrg	cPtr->writeXR(cPtr, 0xA4, x & 0xFF);
167c06b6b69Smrg	cPtr->writeXR(cPtr, 0xA5, (x >> 8) & 0x87);
168c06b6b69Smrg	cPtr->writeXR(cPtr, 0xA6, y & 0xFF);
169c06b6b69Smrg	cPtr->writeXR(cPtr, 0xA7, (y >> 8) & 0x87);
170c06b6b69Smrg	if (cPtr->UseDualChannel &&
171c06b6b69Smrg	    (! xf86IsEntityShared(pScrn->entityList[0]))) {
172c06b6b69Smrg	    unsigned int IOSS, MSS;
173c06b6b69Smrg	    IOSS = cPtr->readIOSS(cPtr);
174c06b6b69Smrg	    MSS = cPtr->readMSS(cPtr);
175c06b6b69Smrg	    cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
176c06b6b69Smrg				   IOSS_PIPE_B));
177c06b6b69Smrg	    cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS &
178c06b6b69Smrg				  MSS_MASK) | MSS_PIPE_B));
179c06b6b69Smrg	    cPtr->writeXR(cPtr, 0xA4, x & 0xFF);
180c06b6b69Smrg	    cPtr->writeXR(cPtr, 0xA5, (x >> 8) & 0x87);
181c06b6b69Smrg	    cPtr->writeXR(cPtr, 0xA6, y & 0xFF);
182c06b6b69Smrg	    cPtr->writeXR(cPtr, 0xA7, (y >> 8) & 0x87);
183c06b6b69Smrg	    cPtr->writeIOSS(cPtr, IOSS);
184c06b6b69Smrg	    cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS);
185c06b6b69Smrg	}
186c06b6b69Smrg    } else {
187c06b6b69Smrg	CARD32 xy;
188c06b6b69Smrg
189c06b6b69Smrg	xy = y;
190c06b6b69Smrg	xy = (xy << 16) | x;
191c06b6b69Smrg	if(!cPtr->UseMMIO) {
192c06b6b69Smrg	    HW_DEBUG(0xB);
193c06b6b69Smrg	    outl(cPtr->PIOBase+DR(0xB), xy);
194c06b6b69Smrg	} else {
195c06b6b69Smrg	    HW_DEBUG(MR(0xB));
196c06b6b69Smrg	    MMIOmeml(MR(0xB)) = xy;
197c06b6b69Smrg	}
198c06b6b69Smrg    }
199c06b6b69Smrg}
200c06b6b69Smrg
201c06b6b69Smrgstatic void
202c06b6b69SmrgCHIPSSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
203c06b6b69Smrg{
204c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
205c06b6b69Smrg    vgaHWPtr hwp = VGAHWPTR(pScrn);
206c06b6b69Smrg    CARD32 packedcolfg, packedcolbg;
207c06b6b69Smrg
208c06b6b69Smrg    CURSOR_SYNC(pScrn);
209c06b6b69Smrg
210c06b6b69Smrg    if (IS_HiQV(cPtr)) {
211c06b6b69Smrg	unsigned char xr80;
212c06b6b69Smrg
213c06b6b69Smrg	/* Enable extended palette addressing */
214c06b6b69Smrg	xr80 = cPtr->readXR(cPtr, 0x80);
215c06b6b69Smrg	cPtr->writeXR(cPtr, 0x80, xr80 | 0x1);
216c06b6b69Smrg
217c06b6b69Smrg	/* Write the new colours to the extended VGA palette. Palette
218c06b6b69Smrg	 * index is incremented after each write, so only write index
219c06b6b69Smrg	 * once
220c06b6b69Smrg	 */
221c06b6b69Smrg	hwp->writeDacWriteAddr(hwp, 0x04);
222c06b6b69Smrg	if (xr80 & 0x80) {
223c06b6b69Smrg	    /* 8bit DAC */
224c06b6b69Smrg	    hwp->writeDacData(hwp, (bg >> 16) & 0xFF);
225c06b6b69Smrg	    hwp->writeDacData(hwp, (bg >> 8) & 0xFF);
226c06b6b69Smrg	    hwp->writeDacData(hwp, bg & 0xFF);
227c06b6b69Smrg	    hwp->writeDacData(hwp, (fg >> 16) & 0xFF);
228c06b6b69Smrg	    hwp->writeDacData(hwp, (fg >> 8) & 0xFF);
229c06b6b69Smrg	    hwp->writeDacData(hwp, fg & 0xFF);
230c06b6b69Smrg	} else {
231c06b6b69Smrg	    /* 6bit DAC */
232c06b6b69Smrg	    hwp->writeDacData(hwp, (bg >> 18) & 0xFF);
233c06b6b69Smrg	    hwp->writeDacData(hwp, (bg >> 10) & 0xFF);
234c06b6b69Smrg	    hwp->writeDacData(hwp, (bg >> 2) & 0xFF);
235c06b6b69Smrg	    hwp->writeDacData(hwp, (fg >> 18) & 0xFF);
236c06b6b69Smrg	    hwp->writeDacData(hwp, (fg >> 10) & 0xFF);
237c06b6b69Smrg	    hwp->writeDacData(hwp, (fg >> 2) & 0xFF);
238c06b6b69Smrg	}
239c06b6b69Smrg	/* Enable normal palette addressing */
240c06b6b69Smrg	cPtr->writeXR(cPtr, 0x80, xr80);
241c06b6b69Smrg
242c06b6b69Smrg	if (cPtr->UseDualChannel &&
243c06b6b69Smrg	    (! xf86IsEntityShared(pScrn->entityList[0]))) {
244c06b6b69Smrg	    unsigned int IOSS, MSS;
245c06b6b69Smrg	    IOSS = cPtr->readIOSS(cPtr);
246c06b6b69Smrg	    MSS = cPtr->readMSS(cPtr);
247c06b6b69Smrg	    cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
248c06b6b69Smrg				   IOSS_PIPE_B));
249c06b6b69Smrg	    cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) |
250c06b6b69Smrg				   MSS_PIPE_B));
251c06b6b69Smrg	    /* Enable extended palette addressing */
252c06b6b69Smrg	    xr80 = cPtr->readXR(cPtr, 0x80);
253c06b6b69Smrg	    cPtr->writeXR(cPtr, 0x80, xr80 | 0x1);
254c06b6b69Smrg
255c06b6b69Smrg	    /* Write the new colours to the extended VGA palette. Palette
256c06b6b69Smrg	     * index is incremented after each write, so only write index
257c06b6b69Smrg	     * once
258c06b6b69Smrg	     */
259c06b6b69Smrg	    hwp->writeDacWriteAddr(hwp, 0x04);
260c06b6b69Smrg	    if (xr80 & 0x80) {
261c06b6b69Smrg		/* 8bit DAC */
262c06b6b69Smrg		hwp->writeDacData(hwp, (bg >> 16) & 0xFF);
263c06b6b69Smrg		hwp->writeDacData(hwp, (bg >> 8) & 0xFF);
264c06b6b69Smrg		hwp->writeDacData(hwp, bg & 0xFF);
265c06b6b69Smrg		hwp->writeDacData(hwp, (fg >> 16) & 0xFF);
266c06b6b69Smrg		hwp->writeDacData(hwp, (fg >> 8) & 0xFF);
267c06b6b69Smrg		hwp->writeDacData(hwp, fg & 0xFF);
268c06b6b69Smrg	    } else {
269c06b6b69Smrg		/* 6bit DAC */
270c06b6b69Smrg		hwp->writeDacData(hwp, (bg >> 18) & 0xFF);
271c06b6b69Smrg		hwp->writeDacData(hwp, (bg >> 10) & 0xFF);
272c06b6b69Smrg		hwp->writeDacData(hwp, (bg >> 2) & 0xFF);
273c06b6b69Smrg		hwp->writeDacData(hwp, (fg >> 18) & 0xFF);
274c06b6b69Smrg		hwp->writeDacData(hwp, (fg >> 10) & 0xFF);
275c06b6b69Smrg		hwp->writeDacData(hwp, (fg >> 2) & 0xFF);
276c06b6b69Smrg	    }
277c06b6b69Smrg	    /* Enable normal palette addressing */
278c06b6b69Smrg	    cPtr->writeXR(cPtr, 0x80, xr80);
279c06b6b69Smrg	    cPtr->writeIOSS(cPtr, IOSS);
280c06b6b69Smrg	    cPtr->writeMSS(cPtr, hwp, MSS);
281c06b6b69Smrg	}
282c06b6b69Smrg    } else if (IS_Wingine(cPtr)) {
283c06b6b69Smrg	outl(cPtr->PIOBase+DR(0xA), (bg & 0xFFFFFF));
284c06b6b69Smrg	outl(cPtr->PIOBase+DR(0x9), (fg & 0xFFFFFF));
285c06b6b69Smrg    } else {
286c06b6b69Smrg	packedcolfg =  ((fg & 0xF80000) >> 8) | ((fg & 0xFC00) >> 5)
287c06b6b69Smrg	    | ((fg & 0xF8) >> 3);
288c06b6b69Smrg	packedcolbg =  ((bg & 0xF80000) >> 8) | ((bg & 0xFC00) >> 5)
289c06b6b69Smrg	    | ((bg & 0xF8) >> 3);
290c06b6b69Smrg	packedcolfg = (packedcolfg << 16) | packedcolbg;
291c06b6b69Smrg	if(!cPtr->UseMMIO) {
292c06b6b69Smrg	    HW_DEBUG(0x9);
293c06b6b69Smrg	    outl(cPtr->PIOBase+DR(0x9), packedcolfg);
294c06b6b69Smrg	} else {
295c06b6b69Smrg	    MMIOmeml(MR(0x9)) = packedcolfg;
296c06b6b69Smrg	    HW_DEBUG(MR(0x9));
297c06b6b69Smrg	}
298c06b6b69Smrg    }
299c06b6b69Smrg}
300c06b6b69Smrg
301c06b6b69Smrgstatic void
302c06b6b69SmrgCHIPSLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
303c06b6b69Smrg{
304c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
305c06b6b69Smrg    CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
306c06b6b69Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN
307c06b6b69Smrg    CARD32 *s = (pointer)src;
308c06b6b69Smrg    CARD32 *d = (pointer)(cPtr->FbBase + cAcl->CursorAddress);
309c06b6b69Smrg    int y;
310c06b6b69Smrg#endif
311c06b6b69Smrg
312c06b6b69Smrg    CURSOR_SYNC(pScrn);
313c06b6b69Smrg
314c06b6b69Smrg    if (cPtr->cursorDelay) {
315c06b6b69Smrg	usleep(200000);
316c06b6b69Smrg	cPtr->cursorDelay = FALSE;
317c06b6b69Smrg    }
318c06b6b69Smrg
319c06b6b69Smrg    if (IS_Wingine(cPtr)) {
320c06b6b69Smrg	int i;
321c06b6b69Smrg	CARD32 *tmp = (CARD32 *)src;
322c06b6b69Smrg
323c06b6b69Smrg	outl(cPtr->PIOBase+DR(0x8),0x20);
324c06b6b69Smrg	for (i=0; i<64; i++) {
325c06b6b69Smrg	    outl(cPtr->PIOBase+DR(0xC),*(CARD32 *)tmp);
326c06b6b69Smrg	    tmp++;
327c06b6b69Smrg	}
328c06b6b69Smrg    } else {
329c06b6b69Smrg	if (cPtr->Flags & ChipsLinearSupport) {
330c06b6b69Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN
331c06b6b69Smrg	    /* On big endian machines we must flip our cursor image around. */
332c06b6b69Smrg    	    switch(pScrn->bitsPerPixel >> 3) {
333c06b6b69Smrg    	        case 4:
334c06b6b69Smrg    	        case 3:
335c06b6b69Smrg#if 1
336c06b6b69Smrg		    memcpy((unsigned char *)cPtr->FbBase + cAcl->CursorAddress,
337c06b6b69Smrg			   src, cPtr->CursorInfoRec->MaxWidth *
338c06b6b69Smrg			   cPtr->CursorInfoRec->MaxHeight / 4);
339c06b6b69Smrg#else
340c06b6b69Smrg        	    for (y = 0; y < 64; y++) {
341c06b6b69Smrg            	        P_SWAP32(d,s);
342c06b6b69Smrg            	        d++; s++;
343c06b6b69Smrg            	        P_SWAP32(d,s);
344c06b6b69Smrg            	        d++; s++;
345c06b6b69Smrg            	        P_SWAP32(d,s);
346c06b6b69Smrg            	        d++; s++;
347c06b6b69Smrg            	        P_SWAP32(d,s);
348c06b6b69Smrg            	        d++; s++;
349c06b6b69Smrg        	    }
350c06b6b69Smrg#endif
351c06b6b69Smrg        	    break;
352c06b6b69Smrg    	        case 2:
353c06b6b69Smrg           	    for (y = 0; y < 64; y++) {
354c06b6b69Smrg            	        P_SWAP16(d,s);
355c06b6b69Smrg            	        d++; s++;
356c06b6b69Smrg                        P_SWAP16(d,s);
357c06b6b69Smrg                        d++; s++;
358c06b6b69Smrg                        P_SWAP16(d,s);
359c06b6b69Smrg                        d++; s++;
360c06b6b69Smrg                        P_SWAP16(d,s);
361c06b6b69Smrg                        d++; s++;
362c06b6b69Smrg                    }
363c06b6b69Smrg                    break;
364c06b6b69Smrg                default:
365c06b6b69Smrg                    for (y = 0; y < 64; y++) {
366c06b6b69Smrg                        *d++ = *s++;
367c06b6b69Smrg                        *d++ = *s++;
368c06b6b69Smrg                        *d++ = *s++;
369c06b6b69Smrg                        *d++ = *s++;
370c06b6b69Smrg                    }
371c06b6b69Smrg            }
372c06b6b69Smrg#else
373c06b6b69Smrg	    memcpy((unsigned char *)cPtr->FbBase + cAcl->CursorAddress,
374c06b6b69Smrg			src, cPtr->CursorInfoRec->MaxWidth *
375c06b6b69Smrg			cPtr->CursorInfoRec->MaxHeight / 4);
376c06b6b69Smrg#endif
377c06b6b69Smrg	} else {
378c06b6b69Smrg	    /*
379c06b6b69Smrg	     * The cursor can only be in the last 16K of video memory,
380c06b6b69Smrg	     * which fits in the last banking window.
381c06b6b69Smrg	     */
382c06b6b69Smrg	    if (IS_HiQV(cPtr))
383c06b6b69Smrg		if (pScrn->bitsPerPixel < 8)
384c06b6b69Smrg		    CHIPSHiQVSetReadWritePlanar(pScrn->pScreen,
385c06b6b69Smrg					    (int)(cAcl->CursorAddress >> 16));
386c06b6b69Smrg		else
387c06b6b69Smrg		    CHIPSHiQVSetReadWrite(pScrn->pScreen,
388c06b6b69Smrg					    (int)(cAcl->CursorAddress >> 16));
389c06b6b69Smrg	    else
390c06b6b69Smrg		if (pScrn->bitsPerPixel < 8)
391c06b6b69Smrg		    CHIPSSetWritePlanar(pScrn->pScreen,
392c06b6b69Smrg					    (int)(cAcl->CursorAddress >> 16));
393c06b6b69Smrg		else
394c06b6b69Smrg		    CHIPSSetWrite(pScrn->pScreen,
395c06b6b69Smrg					    (int)(cAcl->CursorAddress >> 16));
396c06b6b69Smrg	    memcpy((unsigned char *)cPtr->FbBase + (cAcl->CursorAddress &
397c06b6b69Smrg			0xFFFF), src,  cPtr->CursorInfoRec->MaxWidth *
398c06b6b69Smrg			cPtr->CursorInfoRec->MaxHeight / 4);
399c06b6b69Smrg	}
400c06b6b69Smrg    }
401c06b6b69Smrg
402c06b6b69Smrg    /* set cursor address here or we loose the cursor on video mode change */
403c06b6b69Smrg    if (IS_HiQV(cPtr)) {
404c06b6b69Smrg	cPtr->writeXR(cPtr, 0xA2, (cAcl->CursorAddress >> 8) & 0xFF);
405c06b6b69Smrg	cPtr->writeXR(cPtr, 0xA3, (cAcl->CursorAddress >> 16) & 0x3F);
406c06b6b69Smrg	if (cPtr->UseDualChannel &&
407c06b6b69Smrg	    (! xf86IsEntityShared(pScrn->entityList[0]))) {
408c06b6b69Smrg	    unsigned int IOSS, MSS;
409c06b6b69Smrg	    IOSS = cPtr->readIOSS(cPtr);
410c06b6b69Smrg	    MSS = cPtr->readMSS(cPtr);
411c06b6b69Smrg	    cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
412c06b6b69Smrg				   IOSS_PIPE_B));
413c06b6b69Smrg	    cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS &
414c06b6b69Smrg				  MSS_MASK) | MSS_PIPE_B));
415c06b6b69Smrg	    cPtr->writeXR(cPtr, 0xA2, (cAcl->CursorAddress >> 8) & 0xFF);
416c06b6b69Smrg	    cPtr->writeXR(cPtr, 0xA3, (cAcl->CursorAddress >> 16) & 0x3F);
417c06b6b69Smrg	    cPtr->writeIOSS(cPtr, IOSS);
418c06b6b69Smrg	    cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS);
419c06b6b69Smrg	}
420c06b6b69Smrg    } else if (!IS_Wingine(cPtr)) {
421c06b6b69Smrg	if (!cPtr->UseMMIO) {
422c06b6b69Smrg	    HW_DEBUG(0xC);
423c06b6b69Smrg	    outl(cPtr->PIOBase+DR(0xC), cAcl->CursorAddress);
424c06b6b69Smrg	} else {
425c06b6b69Smrg	    HW_DEBUG(MR(0xC));
426c06b6b69Smrg	    MMIOmeml(MR(0xC)) = cAcl->CursorAddress;
427c06b6b69Smrg	}
428c06b6b69Smrg    }
429c06b6b69Smrg}
430c06b6b69Smrg
431c06b6b69Smrgstatic Bool
432c06b6b69SmrgCHIPSUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
433c06b6b69Smrg{
434a1d73b4bSmrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
435c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
436c06b6b69Smrg
437c06b6b69Smrg    return (((cPtr->Flags & ChipsHWCursor) != 0)
438c06b6b69Smrg	    && !(pScrn->currentMode->Flags & V_DBLSCAN));
439c06b6b69Smrg}
440c06b6b69Smrg
441c06b6b69SmrgBool
442c06b6b69SmrgCHIPSCursorInit(ScreenPtr pScreen)
443c06b6b69Smrg{
444a1d73b4bSmrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
445c06b6b69Smrg    CHIPSPtr cPtr = CHIPSPTR(pScrn);
446c06b6b69Smrg    xf86CursorInfoPtr infoPtr;
447c06b6b69Smrg
448c06b6b69Smrg    infoPtr = xf86CreateCursorInfoRec();
449c06b6b69Smrg    if(!infoPtr) return FALSE;
450c06b6b69Smrg
451c06b6b69Smrg    cPtr->CursorInfoRec = infoPtr;
452c06b6b69Smrg
453c06b6b69Smrg    infoPtr->Flags =
454c06b6b69Smrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
455c06b6b69Smrg	HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
456c06b6b69Smrg#endif
457c06b6b69Smrg	HARDWARE_CURSOR_INVERT_MASK |
458c06b6b69Smrg	HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
459c06b6b69Smrg	HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
460c06b6b69Smrg
461c06b6b69Smrg    if (IS_HiQV(cPtr)) {
462c06b6b69Smrg	infoPtr->Flags |= HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64;
463c06b6b69Smrg	infoPtr->MaxHeight = 64;
464c06b6b69Smrg	infoPtr->MaxWidth = 64;
465c06b6b69Smrg    } else if (IS_Wingine(cPtr)) {
466c06b6b69Smrg	infoPtr->Flags |= HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
467c06b6b69Smrg	infoPtr->MaxHeight = 32;
468c06b6b69Smrg	infoPtr->MaxWidth = 32;
469c06b6b69Smrg    } else {
470c06b6b69Smrg	infoPtr->Flags |= HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8;
471c06b6b69Smrg	infoPtr->MaxHeight = 32;
472c06b6b69Smrg	infoPtr->MaxWidth = 32;
473c06b6b69Smrg    }
474c06b6b69Smrg
475c06b6b69Smrg    infoPtr->SetCursorColors = CHIPSSetCursorColors;
476c06b6b69Smrg    infoPtr->SetCursorPosition = CHIPSSetCursorPosition;
477c06b6b69Smrg    infoPtr->LoadCursorImage = CHIPSLoadCursorImage;
478c06b6b69Smrg    infoPtr->HideCursor = CHIPSHideCursor;
479c06b6b69Smrg    infoPtr->ShowCursor = CHIPSShowCursor;
480c06b6b69Smrg    infoPtr->UseHWCursor = CHIPSUseHWCursor;
481c06b6b69Smrg
482c06b6b69Smrg    return(xf86InitCursor(pScreen, infoPtr));
483c06b6b69Smrg}
484c06b6b69Smrg
485