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