ast_cursor.c revision b534f209
115fb4814Smrg/* 215fb4814Smrg * Copyright (c) 2005 ASPEED Technology Inc. 315fb4814Smrg * 415fb4814Smrg * Permission to use, copy, modify, distribute, and sell this software and its 515fb4814Smrg * documentation for any purpose is hereby granted without fee, provided that 615fb4814Smrg * the above copyright notice appear in all copies and that both that 715fb4814Smrg * copyright notice and this permission notice appear in supporting 815fb4814Smrg * documentation, and that the name of the authors not be used in 915fb4814Smrg * advertising or publicity pertaining to distribution of the software without 1015fb4814Smrg * specific, written prior permission. The authors makes no representations 1115fb4814Smrg * about the suitability of this software for any purpose. It is provided 1215fb4814Smrg * "as is" without express or implied warranty. 1315fb4814Smrg * 1415fb4814Smrg * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1515fb4814Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1615fb4814Smrg * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1715fb4814Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1815fb4814Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1915fb4814Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2015fb4814Smrg * PERFORMANCE OF THIS SOFTWARE. 2115fb4814Smrg */ 2215fb4814Smrg 2315fb4814Smrg#ifdef HAVE_CONFIG_H 2415fb4814Smrg#include <config.h> 2515fb4814Smrg#endif 2615fb4814Smrg#include "xf86.h" 2715fb4814Smrg#include "xf86_OSproc.h" 2815fb4814Smrg#include "xf86cmap.h" 2915fb4814Smrg#include "compiler.h" 3015fb4814Smrg#include "mibstore.h" 3115fb4814Smrg#include "vgaHW.h" 3215fb4814Smrg#include "mipointer.h" 3315fb4814Smrg#include "micmap.h" 3415fb4814Smrg 3515fb4814Smrg#include "fb.h" 3615fb4814Smrg#include "regionstr.h" 3715fb4814Smrg#include "xf86xv.h" 3815fb4814Smrg#include <X11/extensions/Xv.h> 3915fb4814Smrg#include "vbe.h" 4015fb4814Smrg 4115fb4814Smrg#include "xf86PciInfo.h" 4215fb4814Smrg#include "xf86Pci.h" 4315fb4814Smrg 4415fb4814Smrg/* framebuffer offscreen manager */ 4515fb4814Smrg#include "xf86fbman.h" 4615fb4814Smrg 4715fb4814Smrg/* include xaa includes */ 4815fb4814Smrg#include "xaa.h" 4915fb4814Smrg#include "xaarop.h" 5015fb4814Smrg 5115fb4814Smrg/* H/W cursor support */ 5215fb4814Smrg#include "xf86Cursor.h" 5315fb4814Smrg#include "cursorstr.h" 5415fb4814Smrg 5515fb4814Smrg/* Driver specific headers */ 5615fb4814Smrg#include "ast.h" 5715fb4814Smrg 5815fb4814Smrg#ifdef HWC 5915fb4814Smrg/* Prototype type declaration */ 6015fb4814SmrgBool ASTCursorInit(ScreenPtr pScreen); 6115fb4814SmrgBool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST); 62b534f209Smrgvoid ASTDisableHWC(ScrnInfoPtr pScrn); 6315fb4814Smrgstatic void ASTShowCursor(ScrnInfoPtr pScrn); 64b534f209Smrgstatic void ASTHideCursor(ScrnInfoPtr pScrn); 6515fb4814Smrgstatic void ASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y); 6615fb4814Smrgstatic void ASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); 6715fb4814Smrgstatic void ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src); 6815fb4814Smrgstatic Bool ASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs); 6915fb4814Smrgstatic void ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs); 7015fb4814Smrgstatic Bool ASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs); 7115fb4814Smrgstatic void ASTFireCursor(ScrnInfoPtr pScrn); 72b534f209Smrgstatic void ASTShowCursor_AST1180(ScrnInfoPtr pScrn); 73b534f209Smrgstatic void ASTHideCursor_AST1180(ScrnInfoPtr pScrn); 74b534f209Smrgstatic void ASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y); 7515fb4814Smrg 7615fb4814SmrgBool 7715fb4814SmrgASTCursorInit(ScreenPtr pScreen) 7815fb4814Smrg{ 7915fb4814Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 8015fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 8115fb4814Smrg xf86CursorInfoPtr infoPtr; 8215fb4814Smrg 8315fb4814Smrg infoPtr = xf86CreateCursorInfoRec(); 8415fb4814Smrg if(!infoPtr) return FALSE; 8515fb4814Smrg 8615fb4814Smrg pAST->HWCInfoPtr = infoPtr; 8715fb4814Smrg 8815fb4814Smrg infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 8915fb4814Smrg HARDWARE_CURSOR_INVERT_MASK | 9015fb4814Smrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST; 9115fb4814Smrg 9215fb4814Smrg infoPtr->MaxWidth = MAX_HWC_WIDTH; 9315fb4814Smrg infoPtr->MaxHeight = MAX_HWC_HEIGHT; 94b534f209Smrg if (pAST->jChipType == AST1180) 95b534f209Smrg { 96b534f209Smrg infoPtr->ShowCursor = ASTShowCursor_AST1180; 97b534f209Smrg infoPtr->HideCursor = ASTHideCursor_AST1180; 98b534f209Smrg infoPtr->SetCursorPosition = ASTSetCursorPosition_AST1180; 99b534f209Smrg } 100b534f209Smrg else 101b534f209Smrg { 102b534f209Smrg infoPtr->ShowCursor = ASTShowCursor; 103b534f209Smrg infoPtr->HideCursor = ASTHideCursor; 104b534f209Smrg infoPtr->SetCursorPosition = ASTSetCursorPosition; 105b534f209Smrg } 106b534f209Smrg infoPtr->SetCursorColors = ASTSetCursorColors; 10715fb4814Smrg infoPtr->LoadCursorImage = ASTLoadCursorImage; 10815fb4814Smrg infoPtr->UseHWCursor = ASTUseHWCursor; 10915fb4814Smrg#ifdef ARGB_CURSOR 11015fb4814Smrg infoPtr->UseHWCursorARGB = ASTUseHWCursorARGB; 11115fb4814Smrg infoPtr->LoadCursorARGB = ASTLoadCursorARGB; 11215fb4814Smrg#endif 11315fb4814Smrg 11415fb4814Smrg return(xf86InitCursor(pScreen, infoPtr)); 11515fb4814Smrg 11615fb4814Smrg} 11715fb4814Smrg 11815fb4814SmrgBool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST) 11915fb4814Smrg{ 12015fb4814Smrg ScreenPtr pScreen; 12115fb4814Smrg 12215fb4814Smrg /* init cursor cache info */ 12315fb4814Smrg /* Set HWC_NUM in Options instead */ 12415fb4814Smrg /* pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM; */ 12515fb4814Smrg pAST->HWCInfo.HWC_NUM_Next = 0; 12615fb4814Smrg 12715fb4814Smrg /* allocate HWC cache */ 12815fb4814Smrg if (!pAST->pHWCPtr) { 12915fb4814Smrg pScreen = screenInfo.screens[pScrn->scrnIndex]; 13015fb4814Smrg pAST->pHWCPtr = xf86AllocateOffscreenLinear (pScreen, (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM, HWC_ALIGN, NULL, NULL, NULL); 13115fb4814Smrg 13215fb4814Smrg if (!pAST->pHWCPtr) { 13315fb4814Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Allocate HWC Cache failed \n"); 13415fb4814Smrg return (FALSE); 13515fb4814Smrg } 13615fb4814Smrg 13715fb4814Smrg pAST->HWCInfo.ulHWCOffsetAddr = pAST->pHWCPtr->offset*((pScrn->bitsPerPixel + 1) / 8); 13815fb4814Smrg pAST->HWCInfo.pjHWCVirtualAddr = pAST->FBVirtualAddr + pAST->HWCInfo.ulHWCOffsetAddr; 13915fb4814Smrg } 14015fb4814Smrg 14115fb4814Smrg return (TRUE); 14215fb4814Smrg} 14315fb4814Smrg 144b534f209Smrgvoid ASTDisableHWC(ScrnInfoPtr pScrn) 145b534f209Smrg{ 146b534f209Smrg ASTRecPtr pAST = ASTPTR(pScrn); 147b534f209Smrg 148b534f209Smrg if (pAST->jChipType == AST1180) 149b534f209Smrg ASTHideCursor_AST1180(pScrn); 150b534f209Smrg else 151b534f209Smrg ASTHideCursor(pScrn); 152b534f209Smrg} 15315fb4814Smrg 15415fb4814Smrgstatic void 15515fb4814SmrgASTShowCursor(ScrnInfoPtr pScrn) 15615fb4814Smrg{ 15715fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 15815fb4814Smrg UCHAR jReg; 15915fb4814Smrg 16015fb4814Smrg jReg= 0x02; 16115fb4814Smrg if (pAST->HWCInfo.cursortype ==HWC_COLOR) 16215fb4814Smrg jReg |= 0x01; 16315fb4814Smrg 16415fb4814Smrg SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, jReg); /* enable mono */ 16515fb4814Smrg 16615fb4814Smrg} 16715fb4814Smrg 168b534f209Smrgstatic void 16915fb4814SmrgASTHideCursor(ScrnInfoPtr pScrn) 17015fb4814Smrg{ 17115fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 17215fb4814Smrg 17315fb4814Smrg SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, 0x00); /* disable HWC */ 17415fb4814Smrg 17515fb4814Smrg} 17615fb4814Smrg 17715fb4814Smrgstatic void 17815fb4814SmrgASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 17915fb4814Smrg{ 18015fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 18115fb4814Smrg DisplayModePtr mode = pAST->ModePtr; 18215fb4814Smrg int x_offset, y_offset; 18315fb4814Smrg UCHAR *pjSignature; 18415fb4814Smrg 18515fb4814Smrg /* Set cursor info to Offscreen */ 18615fb4814Smrg pjSignature = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; 18715fb4814Smrg *((ULONG *) (pjSignature + HWC_SIGNATURE_X)) = x; 18815fb4814Smrg *((ULONG *) (pjSignature + HWC_SIGNATURE_Y)) = y; 18915fb4814Smrg 19015fb4814Smrg x_offset = pAST->HWCInfo.offset_x; 19115fb4814Smrg y_offset = pAST->HWCInfo.offset_y; 19215fb4814Smrg 19315fb4814Smrg if(x < 0) { 19415fb4814Smrg x_offset = (-x) + pAST->HWCInfo.offset_x; 19515fb4814Smrg x = 0; 19615fb4814Smrg } 19715fb4814Smrg 19815fb4814Smrg if(y < 0) { 19915fb4814Smrg y_offset = (-y) + pAST->HWCInfo.offset_y; 20015fb4814Smrg y = 0; 20115fb4814Smrg } 20215fb4814Smrg 20315fb4814Smrg if(mode->Flags & V_DBLSCAN) y *= 2; 20415fb4814Smrg 20515fb4814Smrg /* Set to Reg. */ 20615fb4814Smrg SetIndexReg(CRTC_PORT, 0xC2, (UCHAR) (x_offset)); 20715fb4814Smrg SetIndexReg(CRTC_PORT, 0xC3, (UCHAR) (y_offset)); 20815fb4814Smrg SetIndexReg(CRTC_PORT, 0xC4, (UCHAR) (x & 0xFF)); 20915fb4814Smrg SetIndexReg(CRTC_PORT, 0xC5, (UCHAR) ((x >> 8) & 0x0F)); 21015fb4814Smrg SetIndexReg(CRTC_PORT, 0xC6, (UCHAR) (y & 0xFF)); 21115fb4814Smrg SetIndexReg(CRTC_PORT, 0xC7, (UCHAR) ((y >> 8) & 0x07)); 21215fb4814Smrg 21315fb4814Smrg /* Fire HWC */ 21415fb4814Smrg ASTFireCursor(pScrn); 21515fb4814Smrg 21615fb4814Smrg} 21715fb4814Smrg 21815fb4814Smrgstatic void 21915fb4814SmrgASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 22015fb4814Smrg{ 22115fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 222de78e416Smrg ULONG fg1, bg1; 223de78e416Smrg 224de78e416Smrg fg1 = (fg & 0x0F) | (((fg>>8) & 0x0F) << 4) | (((fg>>16) & 0x0F) << 8); 225de78e416Smrg bg1 = (bg & 0x0F) | (((bg>>8) & 0x0F) << 4) | (((bg>>16) & 0x0F) << 8); 226de78e416Smrg 227de78e416Smrg /* Fixed xorg bugzilla #20609, ycchen@031209 */ 228de78e416Smrg if ( (fg1 != pAST->HWCInfo.fg) || (bg1 != pAST->HWCInfo.bg) ) 229de78e416Smrg { 230de78e416Smrg pAST->HWCInfo.fg = fg1; 231de78e416Smrg pAST->HWCInfo.bg = bg1; 232de78e416Smrg ASTLoadCursorImage(pScrn, pAST->HWCInfo.cursorpattern); 233de78e416Smrg } 234de78e416Smrg 23515fb4814Smrg} 23615fb4814Smrg 23715fb4814Smrgstatic void 23815fb4814SmrgASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src) 23915fb4814Smrg{ 24015fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 24115fb4814Smrg int i, j, k; 24215fb4814Smrg UCHAR *pjSrcAnd, *pjSrcXor, *pjDstData; 24315fb4814Smrg ULONG ulTempDstAnd32[2], ulTempDstXor32[2], ulTempDstData32[2]; 24415fb4814Smrg UCHAR jTempSrcAnd32, jTempSrcXor32; 24515fb4814Smrg ULONG ulCheckSum = 0; 24615fb4814Smrg ULONG ulPatternAddr; 24715fb4814Smrg 24815fb4814Smrg /* init cursor info. */ 24915fb4814Smrg pAST->HWCInfo.cursortype = HWC_MONO; 25015fb4814Smrg pAST->HWCInfo.width = (USHORT) MAX_HWC_WIDTH; 25115fb4814Smrg pAST->HWCInfo.height = (USHORT) MAX_HWC_HEIGHT; 25215fb4814Smrg pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width; 25315fb4814Smrg pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height; 25415fb4814Smrg 255de78e416Smrg /* copy to hwc info */ 256de78e416Smrg for (i=0; i< MAX_HWC_WIDTH*MAX_HWC_HEIGHT/4; i+=4) 257de78e416Smrg *(ULONG *) (pAST->HWCInfo.cursorpattern + i) = *(ULONG *) (src + i); 258de78e416Smrg 25915fb4814Smrg /* copy cursor image to cache */ 26015fb4814Smrg pjSrcXor = src; 26115fb4814Smrg pjSrcAnd = src + (MAX_HWC_WIDTH*MAX_HWC_HEIGHT/8); 26215fb4814Smrg pjDstData = pAST->HWCInfo.pjHWCVirtualAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next; 26315fb4814Smrg 26415fb4814Smrg for (j = 0; j < MAX_HWC_HEIGHT; j++) 26515fb4814Smrg { 26615fb4814Smrg for (i = 0; i < (MAX_HWC_WIDTH/8); i++ ) 26715fb4814Smrg { 26815fb4814Smrg for (k=7; k>0; k-=2) 26915fb4814Smrg { 27015fb4814Smrg jTempSrcAnd32 = *((UCHAR *) pjSrcAnd); 271de78e416Smrg jTempSrcXor32 = *((UCHAR *) pjSrcXor); 272de78e416Smrg ulTempDstAnd32[0] = ((jTempSrcAnd32 >> k) & 0x01) ? 0x00008000L:0x00L; 27315fb4814Smrg ulTempDstXor32[0] = ((jTempSrcXor32 >> k) & 0x01) ? 0x00004000L:0x00L; 27415fb4814Smrg ulTempDstData32[0] = ((jTempSrcXor32 >> k) & 0x01) ? pAST->HWCInfo.fg:pAST->HWCInfo.bg; 27515fb4814Smrg ulTempDstAnd32[1] = ((jTempSrcAnd32 >> (k-1)) & 0x01) ? 0x80000000L:0x00L; 27615fb4814Smrg ulTempDstXor32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? 0x40000000L:0x00L; 27715fb4814Smrg ulTempDstData32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? (pAST->HWCInfo.fg << 16):(pAST->HWCInfo.bg << 16); 278de78e416Smrg /* No inverse for X Window cursor, ycchen@111808 */ 279de78e416Smrg if (ulTempDstAnd32[0]) 280de78e416Smrg ulTempDstXor32[0] = 0; 281de78e416Smrg if (ulTempDstAnd32[1]) 282de78e416Smrg ulTempDstXor32[1] = 0; 28315fb4814Smrg *((ULONG *) pjDstData) = ulTempDstAnd32[0] | ulTempDstXor32[0] | ulTempDstData32[0] | ulTempDstAnd32[1] | ulTempDstXor32[1] | ulTempDstData32[1]; 28415fb4814Smrg ulCheckSum += *((ULONG *) pjDstData); 28515fb4814Smrg pjDstData += 4; 28615fb4814Smrg 28715fb4814Smrg } 28815fb4814Smrg pjSrcAnd ++; 28915fb4814Smrg pjSrcXor ++; 29015fb4814Smrg 29115fb4814Smrg } 29215fb4814Smrg 29315fb4814Smrg } 29415fb4814Smrg 295b534f209Smrg if (pAST->jChipType == AST1180) 296b534f209Smrg { 297b534f209Smrg ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next); 298b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr); 299b534f209Smrg } 300b534f209Smrg else 301b534f209Smrg { 302b534f209Smrg /* Write Checksum as signature */ 303b534f209Smrg pjDstData = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; 304b534f209Smrg *((ULONG *) pjDstData) = ulCheckSum; 305b534f209Smrg *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width; 306b534f209Smrg *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height; 307b534f209Smrg *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTX)) = 0; 308b534f209Smrg *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTY)) = 0; 309b534f209Smrg 310b534f209Smrg /* set pattern offset */ 311b534f209Smrg ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3); 312b534f209Smrg SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF)); 313b534f209Smrg SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF)); 314b534f209Smrg SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF)); 315b534f209Smrg } 31615fb4814Smrg 31715fb4814Smrg /* update HWC_NUM_Next */ 31815fb4814Smrg pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM; 31915fb4814Smrg 32015fb4814Smrg} 32115fb4814Smrg 32215fb4814Smrgstatic Bool 32315fb4814SmrgASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 32415fb4814Smrg{ 325de78e416Smrg if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) ) 326de78e416Smrg return FALSE; 327de78e416Smrg 32815fb4814Smrg return TRUE; 32915fb4814Smrg} 33015fb4814Smrg 33115fb4814Smrgstatic void 33215fb4814SmrgASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs) 33315fb4814Smrg{ 33415fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 33515fb4814Smrg 33615fb4814Smrg UCHAR *pjDstXor, *pjSrcXor; 33715fb4814Smrg ULONG i, j, ulSrcWidth, ulSrcHeight; 33815fb4814Smrg ULONG ulPerPixelCopy, ulTwoPixelCopy; 33915fb4814Smrg LONG lAlphaDstDelta, lLastAlphaDstDelta; 34015fb4814Smrg union 34115fb4814Smrg { 34215fb4814Smrg ULONG ul; 34315fb4814Smrg UCHAR b[4]; 34415fb4814Smrg } ulSrcData32[2], ulData32; 34515fb4814Smrg union 34615fb4814Smrg { 34715fb4814Smrg USHORT us; 34815fb4814Smrg UCHAR b[2]; 34915fb4814Smrg } usData16; 35015fb4814Smrg ULONG ulCheckSum = 0; 35115fb4814Smrg ULONG ulPatternAddr; 35215fb4814Smrg 35315fb4814Smrg /* init cursor info. */ 35415fb4814Smrg pAST->HWCInfo.cursortype = HWC_COLOR; 35515fb4814Smrg pAST->HWCInfo.width = pCurs->bits->width; 35615fb4814Smrg pAST->HWCInfo.height = pCurs->bits->height; 35715fb4814Smrg pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width; 35815fb4814Smrg pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height; 35915fb4814Smrg 36015fb4814Smrg /* copy cursor image to cache */ 36115fb4814Smrg ulSrcWidth = pAST->HWCInfo.width; 36215fb4814Smrg ulSrcHeight = pAST->HWCInfo.height; 36315fb4814Smrg 36415fb4814Smrg lAlphaDstDelta = MAX_HWC_WIDTH << 1; 36515fb4814Smrg lLastAlphaDstDelta = lAlphaDstDelta - (ulSrcWidth << 1); 36615fb4814Smrg 36715fb4814Smrg pjSrcXor = (UCHAR *) pCurs->bits->argb;; 36815fb4814Smrg pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next 36915fb4814Smrg + lLastAlphaDstDelta + (MAX_HWC_HEIGHT - ulSrcHeight) * lAlphaDstDelta; 37015fb4814Smrg 37115fb4814Smrg ulPerPixelCopy = ulSrcWidth & 1; 37215fb4814Smrg ulTwoPixelCopy = ulSrcWidth >> 1; 37315fb4814Smrg 37415fb4814Smrg for (j = 0; j < ulSrcHeight; j++) 37515fb4814Smrg { 37615fb4814Smrg 37715fb4814Smrg for (i = 0; i < ulTwoPixelCopy; i++ ) 37815fb4814Smrg { 37915fb4814Smrg ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0; 38015fb4814Smrg ulSrcData32[1].ul = *((ULONG *) (pjSrcXor+4)) & 0xF0F0F0F0; 38115fb4814Smrg ulData32.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4); 38215fb4814Smrg ulData32.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4); 38315fb4814Smrg ulData32.b[2] = ulSrcData32[1].b[1] | (ulSrcData32[1].b[0] >> 4); 38415fb4814Smrg ulData32.b[3] = ulSrcData32[1].b[3] | (ulSrcData32[1].b[2] >> 4); 38515fb4814Smrg *((ULONG *) pjDstXor) = ulData32.ul; 38615fb4814Smrg ulCheckSum += (ULONG) ulData32.ul; 38715fb4814Smrg pjDstXor += 4; 38815fb4814Smrg pjSrcXor += 8; 38915fb4814Smrg } 39015fb4814Smrg 39115fb4814Smrg for (i = 0; i < ulPerPixelCopy; i++ ) 39215fb4814Smrg { 39315fb4814Smrg ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0; 39415fb4814Smrg usData16.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4); 39515fb4814Smrg usData16.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4); 39615fb4814Smrg *((USHORT *) pjDstXor) = usData16.us; 39715fb4814Smrg ulCheckSum += (ULONG) usData16.us; 39815fb4814Smrg pjDstXor += 2; 39915fb4814Smrg pjSrcXor += 4; 40015fb4814Smrg } 40115fb4814Smrg 40215fb4814Smrg /* Point to next source and dest scans */ 40315fb4814Smrg pjDstXor += lLastAlphaDstDelta; 40415fb4814Smrg 40515fb4814Smrg } /* end of for-loop */ 40615fb4814Smrg 407b534f209Smrg if (pAST->jChipType == AST1180) 408b534f209Smrg { 409b534f209Smrg ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next); 410b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr); 411b534f209Smrg } 412b534f209Smrg else 413b534f209Smrg { 414b534f209Smrg /* Write Checksum as signature */ 415b534f209Smrg pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; 416b534f209Smrg *((ULONG *) pjDstXor) = ulCheckSum; 417b534f209Smrg *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width; 418b534f209Smrg *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height; 419b534f209Smrg *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTX)) = 0; 420b534f209Smrg *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTY)) = 0; 421b534f209Smrg 422b534f209Smrg /* set pattern offset */ 423b534f209Smrg ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr +(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3); 424b534f209Smrg SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF)); 425b534f209Smrg SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF)); 426b534f209Smrg SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF)); 427b534f209Smrg } 42815fb4814Smrg 42915fb4814Smrg /* update HWC_NUM_Next */ 43015fb4814Smrg pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM; 43115fb4814Smrg 43215fb4814Smrg} 43315fb4814Smrg 43415fb4814Smrgstatic Bool 43515fb4814SmrgASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs) 43615fb4814Smrg{ 437de78e416Smrg if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) ) 438de78e416Smrg return FALSE; 439de78e416Smrg 44015fb4814Smrg return TRUE; 44115fb4814Smrg} 44215fb4814Smrg 44315fb4814Smrgstatic void 44415fb4814SmrgASTFireCursor(ScrnInfoPtr pScrn) 44515fb4814Smrg{ 44615fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 44715fb4814Smrg 44815fb4814Smrg SetIndexRegMask(CRTC_PORT, 0xCB, 0xFF, 0x00); /* dummp write to fire HWC */ 44915fb4814Smrg 45015fb4814Smrg} 45115fb4814Smrg 452b534f209Smrg/* AST1180 */ 453b534f209Smrgstatic void 454b534f209SmrgASTShowCursor_AST1180(ScrnInfoPtr pScrn) 455b534f209Smrg{ 456b534f209Smrg ASTRecPtr pAST = ASTPTR(pScrn); 457b534f209Smrg ULONG ulData, ulTemp; 458b534f209Smrg 459b534f209Smrg ReadAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp); 460b534f209Smrg 461b534f209Smrg ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); 462b534f209Smrg ulData &= ~AST1180_ALPHAHWC; 463b534f209Smrg if (pAST->HWCInfo.cursortype ==HWC_COLOR) 464b534f209Smrg ulData |= AST1180_ALPHAHWC; 465b534f209Smrg ulData |= AST1180_ENABLEHWC; 466b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); 467b534f209Smrg 468b534f209Smrg /* fire cursor */ 469b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp); 470b534f209Smrg 471b534f209Smrg} /* ASTShowCursor_AST1180 */ 472b534f209Smrg 473b534f209Smrgstatic void 474b534f209SmrgASTHideCursor_AST1180(ScrnInfoPtr pScrn) 475b534f209Smrg{ 476b534f209Smrg ASTRecPtr pAST = ASTPTR(pScrn); 477b534f209Smrg ULONG ulData; 478b534f209Smrg 479b534f209Smrg ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); 480b534f209Smrg ulData &= ~AST1180_ENABLEHWC; 481b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); 482b534f209Smrg 483b534f209Smrg /* fire cursor */ 484b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, 0x07ff07ff); 485b534f209Smrg 486b534f209Smrg} /* ASTHideCursor_AST1180 */ 487b534f209Smrg 488b534f209Smrgstatic void 489b534f209SmrgASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y) 490b534f209Smrg{ 491b534f209Smrg ASTRecPtr pAST = ASTPTR(pScrn); 492b534f209Smrg DisplayModePtr mode = pAST->ModePtr; 493b534f209Smrg int x_offset, y_offset; 494b534f209Smrg ULONG ulData; 495b534f209Smrg 496b534f209Smrg x_offset = pAST->HWCInfo.offset_x; 497b534f209Smrg y_offset = pAST->HWCInfo.offset_y; 498b534f209Smrg 499b534f209Smrg if(x < 0) { 500b534f209Smrg x_offset = (-x) + pAST->HWCInfo.offset_x; 501b534f209Smrg x = 0; 502b534f209Smrg } 503b534f209Smrg 504b534f209Smrg if(y < 0) { 505b534f209Smrg y_offset = (-y) + pAST->HWCInfo.offset_y; 506b534f209Smrg y = 0; 507b534f209Smrg } 508b534f209Smrg 509b534f209Smrg if(mode->Flags & V_DBLSCAN) y *= 2; 510b534f209Smrg 511b534f209Smrg /* Set to Reg. */ 512b534f209Smrg ulData = (x_offset) | (y_offset << 8); 513b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_OFFSET, ulData); 514b534f209Smrg ulData = (x) | (y << 16); 515b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulData); 516b534f209Smrg 517b534f209Smrg} /* ASTSetCursorPosition_AST1180 */ 518b534f209Smrg 51915fb4814Smrg#endif /* End of HWC */ 520