ast_cursor.c revision 15fb4814
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 "xf86Resources.h" 29#include "xf86RAC.h" 30#include "xf86cmap.h" 31#include "compiler.h" 32#include "mibstore.h" 33#include "vgaHW.h" 34#include "mipointer.h" 35#include "micmap.h" 36 37#include "fb.h" 38#include "regionstr.h" 39#include "xf86xv.h" 40#include <X11/extensions/Xv.h> 41#include "vbe.h" 42 43#include "xf86PciInfo.h" 44#include "xf86Pci.h" 45 46/* framebuffer offscreen manager */ 47#include "xf86fbman.h" 48 49/* include xaa includes */ 50#include "xaa.h" 51#include "xaarop.h" 52 53/* H/W cursor support */ 54#include "xf86Cursor.h" 55#include "cursorstr.h" 56 57/* Driver specific headers */ 58#include "ast.h" 59 60#ifdef HWC 61/* Prototype type declaration */ 62Bool ASTCursorInit(ScreenPtr pScreen); 63Bool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST); 64static void ASTShowCursor(ScrnInfoPtr pScrn); 65static void ASTHideCursor(ScrnInfoPtr pScrn); 66static void ASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y); 67static void ASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); 68static void ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src); 69static Bool ASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs); 70static void ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs); 71static Bool ASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs); 72 73static void ASTFireCursor(ScrnInfoPtr pScrn); 74 75Bool 76ASTCursorInit(ScreenPtr pScreen) 77{ 78 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 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 infoPtr->ShowCursor = ASTShowCursor; 94 infoPtr->HideCursor = ASTHideCursor; 95 infoPtr->SetCursorPosition = ASTSetCursorPosition; 96 infoPtr->SetCursorColors = ASTSetCursorColors; 97 infoPtr->LoadCursorImage = ASTLoadCursorImage; 98 infoPtr->UseHWCursor = ASTUseHWCursor; 99#ifdef ARGB_CURSOR 100 infoPtr->UseHWCursorARGB = ASTUseHWCursorARGB; 101 infoPtr->LoadCursorARGB = ASTLoadCursorARGB; 102#endif 103 104 return(xf86InitCursor(pScreen, infoPtr)); 105 106} 107 108Bool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST) 109{ 110 ScreenPtr pScreen; 111 112 /* init cursor cache info */ 113 /* Set HWC_NUM in Options instead */ 114 /* pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM; */ 115 pAST->HWCInfo.HWC_NUM_Next = 0; 116 117 /* allocate HWC cache */ 118 if (!pAST->pHWCPtr) { 119 pScreen = screenInfo.screens[pScrn->scrnIndex]; 120 pAST->pHWCPtr = xf86AllocateOffscreenLinear (pScreen, (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM, HWC_ALIGN, NULL, NULL, NULL); 121 122 if (!pAST->pHWCPtr) { 123 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Allocate HWC Cache failed \n"); 124 return (FALSE); 125 } 126 127 pAST->HWCInfo.ulHWCOffsetAddr = pAST->pHWCPtr->offset*((pScrn->bitsPerPixel + 1) / 8); 128 pAST->HWCInfo.pjHWCVirtualAddr = pAST->FBVirtualAddr + pAST->HWCInfo.ulHWCOffsetAddr; 129 } 130 131 return (TRUE); 132} 133 134 135static void 136ASTShowCursor(ScrnInfoPtr pScrn) 137{ 138 ASTRecPtr pAST = ASTPTR(pScrn); 139 UCHAR jReg; 140 141 jReg= 0x02; 142 if (pAST->HWCInfo.cursortype ==HWC_COLOR) 143 jReg |= 0x01; 144 145 SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, jReg); /* enable mono */ 146 147} 148 149static void 150ASTHideCursor(ScrnInfoPtr pScrn) 151{ 152 ASTRecPtr pAST = ASTPTR(pScrn); 153 154 SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, 0x00); /* disable HWC */ 155 156} 157 158static void 159ASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 160{ 161 ASTRecPtr pAST = ASTPTR(pScrn); 162 DisplayModePtr mode = pAST->ModePtr; 163 int x_offset, y_offset; 164 UCHAR *pjSignature; 165 166 /* Set cursor info to Offscreen */ 167 pjSignature = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; 168 *((ULONG *) (pjSignature + HWC_SIGNATURE_X)) = x; 169 *((ULONG *) (pjSignature + HWC_SIGNATURE_Y)) = y; 170 171 x_offset = pAST->HWCInfo.offset_x; 172 y_offset = pAST->HWCInfo.offset_y; 173 174 if(x < 0) { 175 x_offset = (-x) + pAST->HWCInfo.offset_x; 176 x = 0; 177 } 178 179 if(y < 0) { 180 y_offset = (-y) + pAST->HWCInfo.offset_y; 181 y = 0; 182 } 183 184 if(mode->Flags & V_DBLSCAN) y *= 2; 185 186 /* Set to Reg. */ 187 SetIndexReg(CRTC_PORT, 0xC2, (UCHAR) (x_offset)); 188 SetIndexReg(CRTC_PORT, 0xC3, (UCHAR) (y_offset)); 189 SetIndexReg(CRTC_PORT, 0xC4, (UCHAR) (x & 0xFF)); 190 SetIndexReg(CRTC_PORT, 0xC5, (UCHAR) ((x >> 8) & 0x0F)); 191 SetIndexReg(CRTC_PORT, 0xC6, (UCHAR) (y & 0xFF)); 192 SetIndexReg(CRTC_PORT, 0xC7, (UCHAR) ((y >> 8) & 0x07)); 193 194 /* Fire HWC */ 195 ASTFireCursor(pScrn); 196 197} 198 199static void 200ASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 201{ 202 ASTRecPtr pAST = ASTPTR(pScrn); 203 204 pAST->HWCInfo.fg = (fg & 0x0F) | (((fg>>8) & 0x0F) << 4) | (((fg>>16) & 0x0F) << 8); 205 pAST->HWCInfo.bg = (bg & 0x0F) | (((bg>>8) & 0x0F) << 4) | (((bg>>16) & 0x0F) << 8); 206} 207 208static void 209ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src) 210{ 211 ASTRecPtr pAST = ASTPTR(pScrn); 212 int i, j, k; 213 UCHAR *pjSrcAnd, *pjSrcXor, *pjDstData; 214 ULONG ulTempDstAnd32[2], ulTempDstXor32[2], ulTempDstData32[2]; 215 UCHAR jTempSrcAnd32, jTempSrcXor32; 216 ULONG ulCheckSum = 0; 217 ULONG ulPatternAddr; 218 219 /* init cursor info. */ 220 pAST->HWCInfo.cursortype = HWC_MONO; 221 pAST->HWCInfo.width = (USHORT) MAX_HWC_WIDTH; 222 pAST->HWCInfo.height = (USHORT) MAX_HWC_HEIGHT; 223 pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width; 224 pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height; 225 226 /* copy cursor image to cache */ 227 pjSrcXor = src; 228 pjSrcAnd = src + (MAX_HWC_WIDTH*MAX_HWC_HEIGHT/8); 229 pjDstData = pAST->HWCInfo.pjHWCVirtualAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next; 230 231 for (j = 0; j < MAX_HWC_HEIGHT; j++) 232 { 233 for (i = 0; i < (MAX_HWC_WIDTH/8); i++ ) 234 { 235 for (k=7; k>0; k-=2) 236 { 237 jTempSrcAnd32 = *((UCHAR *) pjSrcAnd); 238 jTempSrcXor32 = *((UCHAR *) pjSrcXor); 239 ulTempDstAnd32[0] = ((jTempSrcAnd32 >> k) & 0x01) ? 0x00008000L:0x00L; 240 ulTempDstXor32[0] = ((jTempSrcXor32 >> k) & 0x01) ? 0x00004000L:0x00L; 241 ulTempDstData32[0] = ((jTempSrcXor32 >> k) & 0x01) ? pAST->HWCInfo.fg:pAST->HWCInfo.bg; 242 ulTempDstAnd32[1] = ((jTempSrcAnd32 >> (k-1)) & 0x01) ? 0x80000000L:0x00L; 243 ulTempDstXor32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? 0x40000000L:0x00L; 244 ulTempDstData32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? (pAST->HWCInfo.fg << 16):(pAST->HWCInfo.bg << 16); 245 *((ULONG *) pjDstData) = ulTempDstAnd32[0] | ulTempDstXor32[0] | ulTempDstData32[0] | ulTempDstAnd32[1] | ulTempDstXor32[1] | ulTempDstData32[1]; 246 ulCheckSum += *((ULONG *) pjDstData); 247 pjDstData += 4; 248 249 } 250 pjSrcAnd ++; 251 pjSrcXor ++; 252 253 } 254 255 } 256 257 /* Write Checksum as signature */ 258 pjDstData = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; 259 *((ULONG *) pjDstData) = ulCheckSum; 260 *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width; 261 *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height; 262 *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTX)) = 0; 263 *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTY)) = 0; 264 265 /* set pattern offset */ 266 ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3); 267 SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF)); 268 SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF)); 269 SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF)); 270 271 /* update HWC_NUM_Next */ 272 pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM; 273 274} 275 276static Bool 277ASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 278{ 279 return TRUE; 280} 281 282static void 283ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs) 284{ 285 ASTRecPtr pAST = ASTPTR(pScrn); 286 287 UCHAR *pjDstXor, *pjSrcXor; 288 ULONG i, j, ulSrcWidth, ulSrcHeight; 289 ULONG ulPerPixelCopy, ulTwoPixelCopy; 290 LONG lAlphaDstDelta, lLastAlphaDstDelta; 291 union 292 { 293 ULONG ul; 294 UCHAR b[4]; 295 } ulSrcData32[2], ulData32; 296 union 297 { 298 USHORT us; 299 UCHAR b[2]; 300 } usData16; 301 ULONG ulCheckSum = 0; 302 ULONG ulPatternAddr; 303 304 /* init cursor info. */ 305 pAST->HWCInfo.cursortype = HWC_COLOR; 306 pAST->HWCInfo.width = pCurs->bits->width; 307 pAST->HWCInfo.height = pCurs->bits->height; 308 pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width; 309 pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height; 310 311 /* copy cursor image to cache */ 312 ulSrcWidth = pAST->HWCInfo.width; 313 ulSrcHeight = pAST->HWCInfo.height; 314 315 lAlphaDstDelta = MAX_HWC_WIDTH << 1; 316 lLastAlphaDstDelta = lAlphaDstDelta - (ulSrcWidth << 1); 317 318 pjSrcXor = (UCHAR *) pCurs->bits->argb;; 319 pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next 320 + lLastAlphaDstDelta + (MAX_HWC_HEIGHT - ulSrcHeight) * lAlphaDstDelta; 321 322 ulPerPixelCopy = ulSrcWidth & 1; 323 ulTwoPixelCopy = ulSrcWidth >> 1; 324 325 for (j = 0; j < ulSrcHeight; j++) 326 { 327 328 for (i = 0; i < ulTwoPixelCopy; i++ ) 329 { 330 ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0; 331 ulSrcData32[1].ul = *((ULONG *) (pjSrcXor+4)) & 0xF0F0F0F0; 332 ulData32.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4); 333 ulData32.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4); 334 ulData32.b[2] = ulSrcData32[1].b[1] | (ulSrcData32[1].b[0] >> 4); 335 ulData32.b[3] = ulSrcData32[1].b[3] | (ulSrcData32[1].b[2] >> 4); 336 *((ULONG *) pjDstXor) = ulData32.ul; 337 ulCheckSum += (ULONG) ulData32.ul; 338 pjDstXor += 4; 339 pjSrcXor += 8; 340 } 341 342 for (i = 0; i < ulPerPixelCopy; i++ ) 343 { 344 ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0; 345 usData16.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4); 346 usData16.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4); 347 *((USHORT *) pjDstXor) = usData16.us; 348 ulCheckSum += (ULONG) usData16.us; 349 pjDstXor += 2; 350 pjSrcXor += 4; 351 } 352 353 /* Point to next source and dest scans */ 354 pjDstXor += lLastAlphaDstDelta; 355 356 } /* end of for-loop */ 357 358 /* Write Checksum as signature */ 359 pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; 360 *((ULONG *) pjDstXor) = ulCheckSum; 361 *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width; 362 *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height; 363 *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTX)) = 0; 364 *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTY)) = 0; 365 366 /* set pattern offset */ 367 ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr +(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3); 368 SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF)); 369 SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF)); 370 SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF)); 371 372 /* update HWC_NUM_Next */ 373 pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM; 374 375} 376 377static Bool 378ASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs) 379{ 380 return TRUE; 381} 382 383static void 384ASTFireCursor(ScrnInfoPtr pScrn) 385{ 386 ASTRecPtr pAST = ASTPTR(pScrn); 387 388 SetIndexRegMask(CRTC_PORT, 0xCB, 0xFF, 0x00); /* dummp write to fire HWC */ 389 390} 391 392#endif /* End of HWC */ 393