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 */ 4804109a1cSmacallan#ifdef HAVE_XAA_H 49c06b6b69Smrg#define CURSOR_SYNC(pScrn) \ 50c06b6b69Smrg if (IS_HiQV(cPtr)) { \ 51c06b6b69Smrg CHIPSHiQVSync(pScrn); \ 52c06b6b69Smrg } else { \ 53c06b6b69Smrg if(!cPtr->UseMMIO) { \ 54c06b6b69Smrg CHIPSSync(pScrn); \ 55c06b6b69Smrg } else { \ 56c06b6b69Smrg CHIPSMMIOSync(pScrn); \ 57c06b6b69Smrg } \ 58c06b6b69Smrg } 5904109a1cSmacallan#else 6004109a1cSmacallan#define CURSOR_SYNC(pScrn) 6104109a1cSmacallan#endif 62c06b6b69Smrg 63c06b6b69Smrg/* Swing your cursor bytes round and round... yeehaw! */ 64c06b6b69Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN 65c06b6b69Smrg#define P_SWAP32( a , b ) \ 66c06b6b69Smrg ((char *)a)[0] = ((char *)b)[3]; \ 67c06b6b69Smrg ((char *)a)[1] = ((char *)b)[2]; \ 68c06b6b69Smrg ((char *)a)[2] = ((char *)b)[1]; \ 69c06b6b69Smrg ((char *)a)[3] = ((char *)b)[0] 70c06b6b69Smrg 71c06b6b69Smrg#define P_SWAP16( a , b ) \ 72c06b6b69Smrg ((char *)a)[0] = ((char *)b)[1]; \ 73c06b6b69Smrg ((char *)a)[1] = ((char *)b)[0]; \ 74c06b6b69Smrg ((char *)a)[2] = ((char *)b)[3]; \ 75c06b6b69Smrg ((char *)a)[3] = ((char *)b)[2] 76c06b6b69Smrg#endif 77c06b6b69Smrg 78c06b6b69Smrgstatic void 79c06b6b69SmrgCHIPSShowCursor(ScrnInfoPtr pScrn) 80c06b6b69Smrg{ 81c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 82c06b6b69Smrg unsigned char tmp; 83c06b6b69Smrg 84c06b6b69Smrg CURSOR_SYNC(pScrn); 85c06b6b69Smrg 86c06b6b69Smrg /* turn the cursor on */ 87c06b6b69Smrg if (IS_HiQV(cPtr)) { 88c06b6b69Smrg tmp = cPtr->readXR(cPtr, 0xA0); 89c06b6b69Smrg cPtr->writeXR(cPtr, 0xA0, (tmp & 0xF8) | 5); 90c06b6b69Smrg if (cPtr->UseDualChannel && 91c06b6b69Smrg (! xf86IsEntityShared(pScrn->entityList[0]))) { 92c06b6b69Smrg unsigned int IOSS, MSS; 93c06b6b69Smrg IOSS = cPtr->readIOSS(cPtr); 94c06b6b69Smrg MSS = cPtr->readMSS(cPtr); 95c06b6b69Smrg cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 96c06b6b69Smrg IOSS_PIPE_B)); 97c06b6b69Smrg cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS & 98c06b6b69Smrg MSS_MASK) | MSS_PIPE_B)); 99c06b6b69Smrg tmp = cPtr->readXR(cPtr, 0xA0); 100c06b6b69Smrg cPtr->writeXR(cPtr, 0xA0, (tmp & 0xF8) | 5); 101c06b6b69Smrg cPtr->writeIOSS(cPtr, IOSS); 102c06b6b69Smrg cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS); 103c06b6b69Smrg } 104c06b6b69Smrg } else { 105c06b6b69Smrg if(!cPtr->UseMMIO) { 106c06b6b69Smrg HW_DEBUG(0x8); 107c06b6b69Smrg outw(cPtr->PIOBase+DR(0x8), 0x21); 108c06b6b69Smrg } else { 109c06b6b69Smrg HW_DEBUG(DR(8)); 110c06b6b69Smrg /* Used to be: MMIOmemw(MR(8)) = 0x21; */ 111c06b6b69Smrg MMIOmeml(MR(8)) = 0x21; 112c06b6b69Smrg } 113c06b6b69Smrg } 114c06b6b69Smrg cPtr->HWCursorShown = TRUE; 115c06b6b69Smrg} 116c06b6b69Smrg 117c06b6b69Smrgstatic void 118c06b6b69SmrgCHIPSHideCursor(ScrnInfoPtr pScrn) 119c06b6b69Smrg{ 120c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 121c06b6b69Smrg unsigned char tmp; 122c06b6b69Smrg 123c06b6b69Smrg CURSOR_SYNC(pScrn); 124c06b6b69Smrg 125c06b6b69Smrg /* turn the cursor off */ 126c06b6b69Smrg if (IS_HiQV(cPtr)) { 127c06b6b69Smrg tmp = cPtr->readXR(cPtr, 0xA0); 128c06b6b69Smrg cPtr->writeXR(cPtr, 0xA0, tmp & 0xF8); 129c06b6b69Smrg if (cPtr->UseDualChannel && 130c06b6b69Smrg (! xf86IsEntityShared(pScrn->entityList[0]))) { 131c06b6b69Smrg unsigned int IOSS, MSS; 132c06b6b69Smrg IOSS = cPtr->readIOSS(cPtr); 133c06b6b69Smrg MSS = cPtr->readMSS(cPtr); 134c06b6b69Smrg cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 135c06b6b69Smrg IOSS_PIPE_B)); 136c06b6b69Smrg cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS & 137c06b6b69Smrg MSS_MASK) | MSS_PIPE_B)); 138c06b6b69Smrg tmp = cPtr->readXR(cPtr, 0xA0); 139c06b6b69Smrg cPtr->writeXR(cPtr, 0xA0, tmp & 0xF8); 140c06b6b69Smrg cPtr->writeIOSS(cPtr, IOSS); 141c06b6b69Smrg cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS); 142c06b6b69Smrg } 143c06b6b69Smrg } else { 144c06b6b69Smrg if(!cPtr->UseMMIO) { 145c06b6b69Smrg HW_DEBUG(0x8); 146c06b6b69Smrg outw(cPtr->PIOBase+DR(0x8), 0x20); 147c06b6b69Smrg } else { 148c06b6b69Smrg HW_DEBUG(DR(0x8)); 149c06b6b69Smrg /* Used to be: MMIOmemw(DR(0x8)) = 0x20; */ 150c06b6b69Smrg MMIOmeml(DR(0x8)) = 0x20; 151c06b6b69Smrg } 152c06b6b69Smrg } 153c06b6b69Smrg cPtr->HWCursorShown = FALSE; 154c06b6b69Smrg} 155c06b6b69Smrg 156c06b6b69Smrgstatic void 157c06b6b69SmrgCHIPSSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 158c06b6b69Smrg{ 159c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 160c06b6b69Smrg 161c06b6b69Smrg CURSOR_SYNC(pScrn); 162c06b6b69Smrg 163c06b6b69Smrg if (x < 0) 164c06b6b69Smrg x = ~(x-1) | 0x8000; 165c06b6b69Smrg if (y < 0) 166c06b6b69Smrg y = ~(y-1) | 0x8000; 167c06b6b69Smrg 168c06b6b69Smrg /* Program the cursor origin (offset into the cursor bitmap). */ 169c06b6b69Smrg if (IS_HiQV(cPtr)) { 170c06b6b69Smrg cPtr->writeXR(cPtr, 0xA4, x & 0xFF); 171c06b6b69Smrg cPtr->writeXR(cPtr, 0xA5, (x >> 8) & 0x87); 172c06b6b69Smrg cPtr->writeXR(cPtr, 0xA6, y & 0xFF); 173c06b6b69Smrg cPtr->writeXR(cPtr, 0xA7, (y >> 8) & 0x87); 174c06b6b69Smrg if (cPtr->UseDualChannel && 175c06b6b69Smrg (! xf86IsEntityShared(pScrn->entityList[0]))) { 176c06b6b69Smrg unsigned int IOSS, MSS; 177c06b6b69Smrg IOSS = cPtr->readIOSS(cPtr); 178c06b6b69Smrg MSS = cPtr->readMSS(cPtr); 179c06b6b69Smrg cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 180c06b6b69Smrg IOSS_PIPE_B)); 181c06b6b69Smrg cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS & 182c06b6b69Smrg MSS_MASK) | MSS_PIPE_B)); 183c06b6b69Smrg cPtr->writeXR(cPtr, 0xA4, x & 0xFF); 184c06b6b69Smrg cPtr->writeXR(cPtr, 0xA5, (x >> 8) & 0x87); 185c06b6b69Smrg cPtr->writeXR(cPtr, 0xA6, y & 0xFF); 186c06b6b69Smrg cPtr->writeXR(cPtr, 0xA7, (y >> 8) & 0x87); 187c06b6b69Smrg cPtr->writeIOSS(cPtr, IOSS); 188c06b6b69Smrg cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS); 189c06b6b69Smrg } 190c06b6b69Smrg } else { 191c06b6b69Smrg CARD32 xy; 192c06b6b69Smrg 193c06b6b69Smrg xy = y; 194c06b6b69Smrg xy = (xy << 16) | x; 195c06b6b69Smrg if(!cPtr->UseMMIO) { 196c06b6b69Smrg HW_DEBUG(0xB); 197c06b6b69Smrg outl(cPtr->PIOBase+DR(0xB), xy); 198c06b6b69Smrg } else { 199c06b6b69Smrg HW_DEBUG(MR(0xB)); 200c06b6b69Smrg MMIOmeml(MR(0xB)) = xy; 201c06b6b69Smrg } 202c06b6b69Smrg } 203c06b6b69Smrg} 204c06b6b69Smrg 205c06b6b69Smrgstatic void 206c06b6b69SmrgCHIPSSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 207c06b6b69Smrg{ 208c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 209c06b6b69Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 210c06b6b69Smrg CARD32 packedcolfg, packedcolbg; 211c06b6b69Smrg 212c06b6b69Smrg CURSOR_SYNC(pScrn); 213c06b6b69Smrg 214c06b6b69Smrg if (IS_HiQV(cPtr)) { 215c06b6b69Smrg unsigned char xr80; 216c06b6b69Smrg 217c06b6b69Smrg /* Enable extended palette addressing */ 218c06b6b69Smrg xr80 = cPtr->readXR(cPtr, 0x80); 219c06b6b69Smrg cPtr->writeXR(cPtr, 0x80, xr80 | 0x1); 220c06b6b69Smrg 221c06b6b69Smrg /* Write the new colours to the extended VGA palette. Palette 222c06b6b69Smrg * index is incremented after each write, so only write index 223c06b6b69Smrg * once 224c06b6b69Smrg */ 225c06b6b69Smrg hwp->writeDacWriteAddr(hwp, 0x04); 226c06b6b69Smrg if (xr80 & 0x80) { 227c06b6b69Smrg /* 8bit DAC */ 228c06b6b69Smrg hwp->writeDacData(hwp, (bg >> 16) & 0xFF); 229c06b6b69Smrg hwp->writeDacData(hwp, (bg >> 8) & 0xFF); 230c06b6b69Smrg hwp->writeDacData(hwp, bg & 0xFF); 231c06b6b69Smrg hwp->writeDacData(hwp, (fg >> 16) & 0xFF); 232c06b6b69Smrg hwp->writeDacData(hwp, (fg >> 8) & 0xFF); 233c06b6b69Smrg hwp->writeDacData(hwp, fg & 0xFF); 234c06b6b69Smrg } else { 235c06b6b69Smrg /* 6bit DAC */ 236c06b6b69Smrg hwp->writeDacData(hwp, (bg >> 18) & 0xFF); 237c06b6b69Smrg hwp->writeDacData(hwp, (bg >> 10) & 0xFF); 238c06b6b69Smrg hwp->writeDacData(hwp, (bg >> 2) & 0xFF); 239c06b6b69Smrg hwp->writeDacData(hwp, (fg >> 18) & 0xFF); 240c06b6b69Smrg hwp->writeDacData(hwp, (fg >> 10) & 0xFF); 241c06b6b69Smrg hwp->writeDacData(hwp, (fg >> 2) & 0xFF); 242c06b6b69Smrg } 243c06b6b69Smrg /* Enable normal palette addressing */ 244c06b6b69Smrg cPtr->writeXR(cPtr, 0x80, xr80); 245c06b6b69Smrg 246c06b6b69Smrg if (cPtr->UseDualChannel && 247c06b6b69Smrg (! xf86IsEntityShared(pScrn->entityList[0]))) { 248c06b6b69Smrg unsigned int IOSS, MSS; 249c06b6b69Smrg IOSS = cPtr->readIOSS(cPtr); 250c06b6b69Smrg MSS = cPtr->readMSS(cPtr); 251c06b6b69Smrg cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 252c06b6b69Smrg IOSS_PIPE_B)); 253c06b6b69Smrg cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | 254c06b6b69Smrg MSS_PIPE_B)); 255c06b6b69Smrg /* Enable extended palette addressing */ 256c06b6b69Smrg xr80 = cPtr->readXR(cPtr, 0x80); 257c06b6b69Smrg cPtr->writeXR(cPtr, 0x80, xr80 | 0x1); 258c06b6b69Smrg 259c06b6b69Smrg /* Write the new colours to the extended VGA palette. Palette 260c06b6b69Smrg * index is incremented after each write, so only write index 261c06b6b69Smrg * once 262c06b6b69Smrg */ 263c06b6b69Smrg hwp->writeDacWriteAddr(hwp, 0x04); 264c06b6b69Smrg if (xr80 & 0x80) { 265c06b6b69Smrg /* 8bit DAC */ 266c06b6b69Smrg hwp->writeDacData(hwp, (bg >> 16) & 0xFF); 267c06b6b69Smrg hwp->writeDacData(hwp, (bg >> 8) & 0xFF); 268c06b6b69Smrg hwp->writeDacData(hwp, bg & 0xFF); 269c06b6b69Smrg hwp->writeDacData(hwp, (fg >> 16) & 0xFF); 270c06b6b69Smrg hwp->writeDacData(hwp, (fg >> 8) & 0xFF); 271c06b6b69Smrg hwp->writeDacData(hwp, fg & 0xFF); 272c06b6b69Smrg } else { 273c06b6b69Smrg /* 6bit DAC */ 274c06b6b69Smrg hwp->writeDacData(hwp, (bg >> 18) & 0xFF); 275c06b6b69Smrg hwp->writeDacData(hwp, (bg >> 10) & 0xFF); 276c06b6b69Smrg hwp->writeDacData(hwp, (bg >> 2) & 0xFF); 277c06b6b69Smrg hwp->writeDacData(hwp, (fg >> 18) & 0xFF); 278c06b6b69Smrg hwp->writeDacData(hwp, (fg >> 10) & 0xFF); 279c06b6b69Smrg hwp->writeDacData(hwp, (fg >> 2) & 0xFF); 280c06b6b69Smrg } 281c06b6b69Smrg /* Enable normal palette addressing */ 282c06b6b69Smrg cPtr->writeXR(cPtr, 0x80, xr80); 283c06b6b69Smrg cPtr->writeIOSS(cPtr, IOSS); 284c06b6b69Smrg cPtr->writeMSS(cPtr, hwp, MSS); 285c06b6b69Smrg } 286c06b6b69Smrg } else if (IS_Wingine(cPtr)) { 287c06b6b69Smrg outl(cPtr->PIOBase+DR(0xA), (bg & 0xFFFFFF)); 288c06b6b69Smrg outl(cPtr->PIOBase+DR(0x9), (fg & 0xFFFFFF)); 289c06b6b69Smrg } else { 290c06b6b69Smrg packedcolfg = ((fg & 0xF80000) >> 8) | ((fg & 0xFC00) >> 5) 291c06b6b69Smrg | ((fg & 0xF8) >> 3); 292c06b6b69Smrg packedcolbg = ((bg & 0xF80000) >> 8) | ((bg & 0xFC00) >> 5) 293c06b6b69Smrg | ((bg & 0xF8) >> 3); 294c06b6b69Smrg packedcolfg = (packedcolfg << 16) | packedcolbg; 295c06b6b69Smrg if(!cPtr->UseMMIO) { 296c06b6b69Smrg HW_DEBUG(0x9); 297c06b6b69Smrg outl(cPtr->PIOBase+DR(0x9), packedcolfg); 298c06b6b69Smrg } else { 299c06b6b69Smrg MMIOmeml(MR(0x9)) = packedcolfg; 300c06b6b69Smrg HW_DEBUG(MR(0x9)); 301c06b6b69Smrg } 302c06b6b69Smrg } 303c06b6b69Smrg} 304c06b6b69Smrg 305c06b6b69Smrgstatic void 306c06b6b69SmrgCHIPSLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) 307c06b6b69Smrg{ 308c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 309c06b6b69Smrg CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn); 310c06b6b69Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN 311c06b6b69Smrg CARD32 *s = (pointer)src; 312c06b6b69Smrg CARD32 *d = (pointer)(cPtr->FbBase + cAcl->CursorAddress); 313c06b6b69Smrg int y; 314c06b6b69Smrg#endif 315c06b6b69Smrg 316c06b6b69Smrg CURSOR_SYNC(pScrn); 317c06b6b69Smrg 318c06b6b69Smrg if (cPtr->cursorDelay) { 319c06b6b69Smrg usleep(200000); 320c06b6b69Smrg cPtr->cursorDelay = FALSE; 321c06b6b69Smrg } 322c06b6b69Smrg 323c06b6b69Smrg if (IS_Wingine(cPtr)) { 324c06b6b69Smrg int i; 325c06b6b69Smrg CARD32 *tmp = (CARD32 *)src; 326c06b6b69Smrg 327c06b6b69Smrg outl(cPtr->PIOBase+DR(0x8),0x20); 328c06b6b69Smrg for (i=0; i<64; i++) { 329c06b6b69Smrg outl(cPtr->PIOBase+DR(0xC),*(CARD32 *)tmp); 330c06b6b69Smrg tmp++; 331c06b6b69Smrg } 332c06b6b69Smrg } else { 333c06b6b69Smrg if (cPtr->Flags & ChipsLinearSupport) { 334c06b6b69Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN 335c06b6b69Smrg /* On big endian machines we must flip our cursor image around. */ 336c06b6b69Smrg switch(pScrn->bitsPerPixel >> 3) { 337c06b6b69Smrg case 4: 338c06b6b69Smrg case 3: 339c06b6b69Smrg#if 1 340c06b6b69Smrg memcpy((unsigned char *)cPtr->FbBase + cAcl->CursorAddress, 341c06b6b69Smrg src, cPtr->CursorInfoRec->MaxWidth * 342c06b6b69Smrg cPtr->CursorInfoRec->MaxHeight / 4); 343c06b6b69Smrg#else 344c06b6b69Smrg for (y = 0; y < 64; y++) { 345c06b6b69Smrg P_SWAP32(d,s); 346c06b6b69Smrg d++; s++; 347c06b6b69Smrg P_SWAP32(d,s); 348c06b6b69Smrg d++; s++; 349c06b6b69Smrg P_SWAP32(d,s); 350c06b6b69Smrg d++; s++; 351c06b6b69Smrg P_SWAP32(d,s); 352c06b6b69Smrg d++; s++; 353c06b6b69Smrg } 354c06b6b69Smrg#endif 355c06b6b69Smrg break; 356c06b6b69Smrg case 2: 357c06b6b69Smrg for (y = 0; y < 64; y++) { 358c06b6b69Smrg P_SWAP16(d,s); 359c06b6b69Smrg d++; s++; 360c06b6b69Smrg P_SWAP16(d,s); 361c06b6b69Smrg d++; s++; 362c06b6b69Smrg P_SWAP16(d,s); 363c06b6b69Smrg d++; s++; 364c06b6b69Smrg P_SWAP16(d,s); 365c06b6b69Smrg d++; s++; 366c06b6b69Smrg } 367c06b6b69Smrg break; 368c06b6b69Smrg default: 369c06b6b69Smrg for (y = 0; y < 64; y++) { 370c06b6b69Smrg *d++ = *s++; 371c06b6b69Smrg *d++ = *s++; 372c06b6b69Smrg *d++ = *s++; 373c06b6b69Smrg *d++ = *s++; 374c06b6b69Smrg } 375c06b6b69Smrg } 376c06b6b69Smrg#else 377c06b6b69Smrg memcpy((unsigned char *)cPtr->FbBase + cAcl->CursorAddress, 378c06b6b69Smrg src, cPtr->CursorInfoRec->MaxWidth * 379c06b6b69Smrg cPtr->CursorInfoRec->MaxHeight / 4); 380c06b6b69Smrg#endif 381c06b6b69Smrg } else { 382c06b6b69Smrg /* 383c06b6b69Smrg * The cursor can only be in the last 16K of video memory, 384c06b6b69Smrg * which fits in the last banking window. 385c06b6b69Smrg */ 386c06b6b69Smrg if (IS_HiQV(cPtr)) 387c06b6b69Smrg if (pScrn->bitsPerPixel < 8) 388c06b6b69Smrg CHIPSHiQVSetReadWritePlanar(pScrn->pScreen, 389c06b6b69Smrg (int)(cAcl->CursorAddress >> 16)); 390c06b6b69Smrg else 391c06b6b69Smrg CHIPSHiQVSetReadWrite(pScrn->pScreen, 392c06b6b69Smrg (int)(cAcl->CursorAddress >> 16)); 393c06b6b69Smrg else 394c06b6b69Smrg if (pScrn->bitsPerPixel < 8) 395c06b6b69Smrg CHIPSSetWritePlanar(pScrn->pScreen, 396c06b6b69Smrg (int)(cAcl->CursorAddress >> 16)); 397c06b6b69Smrg else 398c06b6b69Smrg CHIPSSetWrite(pScrn->pScreen, 399c06b6b69Smrg (int)(cAcl->CursorAddress >> 16)); 400c06b6b69Smrg memcpy((unsigned char *)cPtr->FbBase + (cAcl->CursorAddress & 401c06b6b69Smrg 0xFFFF), src, cPtr->CursorInfoRec->MaxWidth * 402c06b6b69Smrg cPtr->CursorInfoRec->MaxHeight / 4); 403c06b6b69Smrg } 404c06b6b69Smrg } 405c06b6b69Smrg 406c06b6b69Smrg /* set cursor address here or we loose the cursor on video mode change */ 407c06b6b69Smrg if (IS_HiQV(cPtr)) { 408c06b6b69Smrg cPtr->writeXR(cPtr, 0xA2, (cAcl->CursorAddress >> 8) & 0xFF); 409c06b6b69Smrg cPtr->writeXR(cPtr, 0xA3, (cAcl->CursorAddress >> 16) & 0x3F); 410c06b6b69Smrg if (cPtr->UseDualChannel && 411c06b6b69Smrg (! xf86IsEntityShared(pScrn->entityList[0]))) { 412c06b6b69Smrg unsigned int IOSS, MSS; 413c06b6b69Smrg IOSS = cPtr->readIOSS(cPtr); 414c06b6b69Smrg MSS = cPtr->readMSS(cPtr); 415c06b6b69Smrg cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 416c06b6b69Smrg IOSS_PIPE_B)); 417c06b6b69Smrg cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS & 418c06b6b69Smrg MSS_MASK) | MSS_PIPE_B)); 419c06b6b69Smrg cPtr->writeXR(cPtr, 0xA2, (cAcl->CursorAddress >> 8) & 0xFF); 420c06b6b69Smrg cPtr->writeXR(cPtr, 0xA3, (cAcl->CursorAddress >> 16) & 0x3F); 421c06b6b69Smrg cPtr->writeIOSS(cPtr, IOSS); 422c06b6b69Smrg cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS); 423c06b6b69Smrg } 424c06b6b69Smrg } else if (!IS_Wingine(cPtr)) { 425c06b6b69Smrg if (!cPtr->UseMMIO) { 426c06b6b69Smrg HW_DEBUG(0xC); 427c06b6b69Smrg outl(cPtr->PIOBase+DR(0xC), cAcl->CursorAddress); 428c06b6b69Smrg } else { 429c06b6b69Smrg HW_DEBUG(MR(0xC)); 430c06b6b69Smrg MMIOmeml(MR(0xC)) = cAcl->CursorAddress; 431c06b6b69Smrg } 432c06b6b69Smrg } 433c06b6b69Smrg} 434c06b6b69Smrg 435c06b6b69Smrgstatic Bool 436c06b6b69SmrgCHIPSUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 437c06b6b69Smrg{ 438a1d73b4bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 439c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 440c06b6b69Smrg 441c06b6b69Smrg return (((cPtr->Flags & ChipsHWCursor) != 0) 442c06b6b69Smrg && !(pScrn->currentMode->Flags & V_DBLSCAN)); 443c06b6b69Smrg} 444c06b6b69Smrg 445c06b6b69SmrgBool 446c06b6b69SmrgCHIPSCursorInit(ScreenPtr pScreen) 447c06b6b69Smrg{ 448a1d73b4bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 449c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 450c06b6b69Smrg xf86CursorInfoPtr infoPtr; 451c06b6b69Smrg 452c06b6b69Smrg infoPtr = xf86CreateCursorInfoRec(); 453c06b6b69Smrg if(!infoPtr) return FALSE; 454c06b6b69Smrg 455c06b6b69Smrg cPtr->CursorInfoRec = infoPtr; 456c06b6b69Smrg 457c06b6b69Smrg infoPtr->Flags = 458c06b6b69Smrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 459c06b6b69Smrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 460c06b6b69Smrg#endif 461c06b6b69Smrg HARDWARE_CURSOR_INVERT_MASK | 462c06b6b69Smrg HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | 463c06b6b69Smrg HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; 464c06b6b69Smrg 465c06b6b69Smrg if (IS_HiQV(cPtr)) { 466c06b6b69Smrg infoPtr->Flags |= HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64; 467c06b6b69Smrg infoPtr->MaxHeight = 64; 468c06b6b69Smrg infoPtr->MaxWidth = 64; 469c06b6b69Smrg } else if (IS_Wingine(cPtr)) { 470c06b6b69Smrg infoPtr->Flags |= HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED; 471c06b6b69Smrg infoPtr->MaxHeight = 32; 472c06b6b69Smrg infoPtr->MaxWidth = 32; 473c06b6b69Smrg } else { 474c06b6b69Smrg infoPtr->Flags |= HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8; 475c06b6b69Smrg infoPtr->MaxHeight = 32; 476c06b6b69Smrg infoPtr->MaxWidth = 32; 477c06b6b69Smrg } 478c06b6b69Smrg 479c06b6b69Smrg infoPtr->SetCursorColors = CHIPSSetCursorColors; 480c06b6b69Smrg infoPtr->SetCursorPosition = CHIPSSetCursorPosition; 481c06b6b69Smrg infoPtr->LoadCursorImage = CHIPSLoadCursorImage; 482c06b6b69Smrg infoPtr->HideCursor = CHIPSHideCursor; 483c06b6b69Smrg infoPtr->ShowCursor = CHIPSShowCursor; 484c06b6b69Smrg infoPtr->UseHWCursor = CHIPSUseHWCursor; 485c06b6b69Smrg 486c06b6b69Smrg return(xf86InitCursor(pScreen, infoPtr)); 487c06b6b69Smrg} 488c06b6b69Smrg 489