ast_cursor.c revision b4d38c65
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 "xaarop.h" 4915fb4814Smrg 5015fb4814Smrg/* H/W cursor support */ 5115fb4814Smrg#include "xf86Cursor.h" 5215fb4814Smrg#include "cursorstr.h" 5315fb4814Smrg 5415fb4814Smrg/* Driver specific headers */ 5515fb4814Smrg#include "ast.h" 5615fb4814Smrg 5715fb4814Smrg#ifdef HWC 5815fb4814Smrg/* Prototype type declaration */ 5915fb4814SmrgBool ASTCursorInit(ScreenPtr pScreen); 6015fb4814SmrgBool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST); 61b534f209Smrgvoid ASTDisableHWC(ScrnInfoPtr pScrn); 6215fb4814Smrgstatic void ASTShowCursor(ScrnInfoPtr pScrn); 63b534f209Smrgstatic void ASTHideCursor(ScrnInfoPtr pScrn); 6415fb4814Smrgstatic void ASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y); 6515fb4814Smrgstatic void ASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); 6615fb4814Smrgstatic void ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src); 6715fb4814Smrgstatic Bool ASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs); 6815fb4814Smrgstatic void ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs); 6915fb4814Smrgstatic Bool ASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs); 7015fb4814Smrgstatic void ASTFireCursor(ScrnInfoPtr pScrn); 71b534f209Smrgstatic void ASTShowCursor_AST1180(ScrnInfoPtr pScrn); 72b534f209Smrgstatic void ASTHideCursor_AST1180(ScrnInfoPtr pScrn); 73b534f209Smrgstatic void ASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y); 7415fb4814Smrg 7515fb4814SmrgBool 7615fb4814SmrgASTCursorInit(ScreenPtr pScreen) 7715fb4814Smrg{ 78b4d38c65Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 7915fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 8015fb4814Smrg xf86CursorInfoPtr infoPtr; 8115fb4814Smrg 8215fb4814Smrg infoPtr = xf86CreateCursorInfoRec(); 8315fb4814Smrg if(!infoPtr) return FALSE; 8415fb4814Smrg 8515fb4814Smrg pAST->HWCInfoPtr = infoPtr; 8615fb4814Smrg 8715fb4814Smrg infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 8815fb4814Smrg HARDWARE_CURSOR_INVERT_MASK | 8915fb4814Smrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST; 9015fb4814Smrg 9115fb4814Smrg infoPtr->MaxWidth = MAX_HWC_WIDTH; 9215fb4814Smrg infoPtr->MaxHeight = MAX_HWC_HEIGHT; 93b534f209Smrg if (pAST->jChipType == AST1180) 94b534f209Smrg { 95b534f209Smrg infoPtr->ShowCursor = ASTShowCursor_AST1180; 96b534f209Smrg infoPtr->HideCursor = ASTHideCursor_AST1180; 97b534f209Smrg infoPtr->SetCursorPosition = ASTSetCursorPosition_AST1180; 98b534f209Smrg } 99b534f209Smrg else 100b534f209Smrg { 101b534f209Smrg infoPtr->ShowCursor = ASTShowCursor; 102b534f209Smrg infoPtr->HideCursor = ASTHideCursor; 103b534f209Smrg infoPtr->SetCursorPosition = ASTSetCursorPosition; 104b534f209Smrg } 105b534f209Smrg infoPtr->SetCursorColors = ASTSetCursorColors; 10615fb4814Smrg infoPtr->LoadCursorImage = ASTLoadCursorImage; 10715fb4814Smrg infoPtr->UseHWCursor = ASTUseHWCursor; 10815fb4814Smrg#ifdef ARGB_CURSOR 10915fb4814Smrg infoPtr->UseHWCursorARGB = ASTUseHWCursorARGB; 11015fb4814Smrg infoPtr->LoadCursorARGB = ASTLoadCursorARGB; 11115fb4814Smrg#endif 11215fb4814Smrg 11315fb4814Smrg return(xf86InitCursor(pScreen, infoPtr)); 11415fb4814Smrg 11515fb4814Smrg} 11615fb4814Smrg 11715fb4814SmrgBool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST) 11815fb4814Smrg{ 11915fb4814Smrg ScreenPtr pScreen; 12015fb4814Smrg 12115fb4814Smrg /* init cursor cache info */ 12215fb4814Smrg /* Set HWC_NUM in Options instead */ 12315fb4814Smrg /* pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM; */ 12415fb4814Smrg pAST->HWCInfo.HWC_NUM_Next = 0; 12515fb4814Smrg 12615fb4814Smrg /* allocate HWC cache */ 12715fb4814Smrg if (!pAST->pHWCPtr) { 128b4d38c65Smrg pScreen = xf86ScrnToScreen(pScrn); 12915fb4814Smrg pAST->pHWCPtr = xf86AllocateOffscreenLinear (pScreen, (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM, HWC_ALIGN, NULL, NULL, NULL); 13015fb4814Smrg 13115fb4814Smrg if (!pAST->pHWCPtr) { 13215fb4814Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Allocate HWC Cache failed \n"); 13315fb4814Smrg return (FALSE); 13415fb4814Smrg } 13515fb4814Smrg 13615fb4814Smrg pAST->HWCInfo.ulHWCOffsetAddr = pAST->pHWCPtr->offset*((pScrn->bitsPerPixel + 1) / 8); 13715fb4814Smrg pAST->HWCInfo.pjHWCVirtualAddr = pAST->FBVirtualAddr + pAST->HWCInfo.ulHWCOffsetAddr; 13815fb4814Smrg } 13915fb4814Smrg 14015fb4814Smrg return (TRUE); 14115fb4814Smrg} 14215fb4814Smrg 143b534f209Smrgvoid ASTDisableHWC(ScrnInfoPtr pScrn) 144b534f209Smrg{ 145b534f209Smrg ASTRecPtr pAST = ASTPTR(pScrn); 146b534f209Smrg 147b534f209Smrg if (pAST->jChipType == AST1180) 148b534f209Smrg ASTHideCursor_AST1180(pScrn); 149b534f209Smrg else 150b534f209Smrg ASTHideCursor(pScrn); 151b534f209Smrg} 15215fb4814Smrg 15315fb4814Smrgstatic void 15415fb4814SmrgASTShowCursor(ScrnInfoPtr pScrn) 15515fb4814Smrg{ 15615fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 15715fb4814Smrg UCHAR jReg; 15815fb4814Smrg 15915fb4814Smrg jReg= 0x02; 16015fb4814Smrg if (pAST->HWCInfo.cursortype ==HWC_COLOR) 16115fb4814Smrg jReg |= 0x01; 16215fb4814Smrg 16315fb4814Smrg SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, jReg); /* enable mono */ 16415fb4814Smrg 16515fb4814Smrg} 16615fb4814Smrg 167b534f209Smrgstatic void 16815fb4814SmrgASTHideCursor(ScrnInfoPtr pScrn) 16915fb4814Smrg{ 17015fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 17115fb4814Smrg 17215fb4814Smrg SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, 0x00); /* disable HWC */ 17315fb4814Smrg 17415fb4814Smrg} 17515fb4814Smrg 17615fb4814Smrgstatic void 17715fb4814SmrgASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 17815fb4814Smrg{ 17915fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 18015fb4814Smrg DisplayModePtr mode = pAST->ModePtr; 18115fb4814Smrg int x_offset, y_offset; 18215fb4814Smrg UCHAR *pjSignature; 18315fb4814Smrg 18415fb4814Smrg /* Set cursor info to Offscreen */ 18515fb4814Smrg pjSignature = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; 18615fb4814Smrg *((ULONG *) (pjSignature + HWC_SIGNATURE_X)) = x; 18715fb4814Smrg *((ULONG *) (pjSignature + HWC_SIGNATURE_Y)) = y; 18815fb4814Smrg 18915fb4814Smrg x_offset = pAST->HWCInfo.offset_x; 19015fb4814Smrg y_offset = pAST->HWCInfo.offset_y; 19115fb4814Smrg 19215fb4814Smrg if(x < 0) { 19315fb4814Smrg x_offset = (-x) + pAST->HWCInfo.offset_x; 19415fb4814Smrg x = 0; 19515fb4814Smrg } 19615fb4814Smrg 19715fb4814Smrg if(y < 0) { 19815fb4814Smrg y_offset = (-y) + pAST->HWCInfo.offset_y; 19915fb4814Smrg y = 0; 20015fb4814Smrg } 20115fb4814Smrg 20215fb4814Smrg if(mode->Flags & V_DBLSCAN) y *= 2; 20315fb4814Smrg 20415fb4814Smrg /* Set to Reg. */ 20515fb4814Smrg SetIndexReg(CRTC_PORT, 0xC2, (UCHAR) (x_offset)); 20615fb4814Smrg SetIndexReg(CRTC_PORT, 0xC3, (UCHAR) (y_offset)); 20715fb4814Smrg SetIndexReg(CRTC_PORT, 0xC4, (UCHAR) (x & 0xFF)); 20815fb4814Smrg SetIndexReg(CRTC_PORT, 0xC5, (UCHAR) ((x >> 8) & 0x0F)); 20915fb4814Smrg SetIndexReg(CRTC_PORT, 0xC6, (UCHAR) (y & 0xFF)); 21015fb4814Smrg SetIndexReg(CRTC_PORT, 0xC7, (UCHAR) ((y >> 8) & 0x07)); 21115fb4814Smrg 21215fb4814Smrg /* Fire HWC */ 21315fb4814Smrg ASTFireCursor(pScrn); 21415fb4814Smrg 21515fb4814Smrg} 21615fb4814Smrg 21715fb4814Smrgstatic void 21815fb4814SmrgASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 21915fb4814Smrg{ 22015fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 221de78e416Smrg ULONG fg1, bg1; 222de78e416Smrg 223de78e416Smrg fg1 = (fg & 0x0F) | (((fg>>8) & 0x0F) << 4) | (((fg>>16) & 0x0F) << 8); 224de78e416Smrg bg1 = (bg & 0x0F) | (((bg>>8) & 0x0F) << 4) | (((bg>>16) & 0x0F) << 8); 225de78e416Smrg 226de78e416Smrg /* Fixed xorg bugzilla #20609, ycchen@031209 */ 227de78e416Smrg if ( (fg1 != pAST->HWCInfo.fg) || (bg1 != pAST->HWCInfo.bg) ) 228de78e416Smrg { 229de78e416Smrg pAST->HWCInfo.fg = fg1; 230de78e416Smrg pAST->HWCInfo.bg = bg1; 231de78e416Smrg ASTLoadCursorImage(pScrn, pAST->HWCInfo.cursorpattern); 232de78e416Smrg } 233de78e416Smrg 23415fb4814Smrg} 23515fb4814Smrg 23615fb4814Smrgstatic void 23715fb4814SmrgASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src) 23815fb4814Smrg{ 23915fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 24015fb4814Smrg int i, j, k; 24115fb4814Smrg UCHAR *pjSrcAnd, *pjSrcXor, *pjDstData; 24215fb4814Smrg ULONG ulTempDstAnd32[2], ulTempDstXor32[2], ulTempDstData32[2]; 24315fb4814Smrg UCHAR jTempSrcAnd32, jTempSrcXor32; 24415fb4814Smrg ULONG ulCheckSum = 0; 24515fb4814Smrg ULONG ulPatternAddr; 24615fb4814Smrg 24715fb4814Smrg /* init cursor info. */ 24815fb4814Smrg pAST->HWCInfo.cursortype = HWC_MONO; 24915fb4814Smrg pAST->HWCInfo.width = (USHORT) MAX_HWC_WIDTH; 25015fb4814Smrg pAST->HWCInfo.height = (USHORT) MAX_HWC_HEIGHT; 25115fb4814Smrg pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width; 25215fb4814Smrg pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height; 25315fb4814Smrg 254de78e416Smrg /* copy to hwc info */ 255de78e416Smrg for (i=0; i< MAX_HWC_WIDTH*MAX_HWC_HEIGHT/4; i+=4) 256de78e416Smrg *(ULONG *) (pAST->HWCInfo.cursorpattern + i) = *(ULONG *) (src + i); 257de78e416Smrg 25815fb4814Smrg /* copy cursor image to cache */ 25915fb4814Smrg pjSrcXor = src; 26015fb4814Smrg pjSrcAnd = src + (MAX_HWC_WIDTH*MAX_HWC_HEIGHT/8); 26115fb4814Smrg pjDstData = pAST->HWCInfo.pjHWCVirtualAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next; 26215fb4814Smrg 26315fb4814Smrg for (j = 0; j < MAX_HWC_HEIGHT; j++) 26415fb4814Smrg { 26515fb4814Smrg for (i = 0; i < (MAX_HWC_WIDTH/8); i++ ) 26615fb4814Smrg { 26715fb4814Smrg for (k=7; k>0; k-=2) 26815fb4814Smrg { 26915fb4814Smrg jTempSrcAnd32 = *((UCHAR *) pjSrcAnd); 270de78e416Smrg jTempSrcXor32 = *((UCHAR *) pjSrcXor); 271de78e416Smrg ulTempDstAnd32[0] = ((jTempSrcAnd32 >> k) & 0x01) ? 0x00008000L:0x00L; 27215fb4814Smrg ulTempDstXor32[0] = ((jTempSrcXor32 >> k) & 0x01) ? 0x00004000L:0x00L; 27315fb4814Smrg ulTempDstData32[0] = ((jTempSrcXor32 >> k) & 0x01) ? pAST->HWCInfo.fg:pAST->HWCInfo.bg; 27415fb4814Smrg ulTempDstAnd32[1] = ((jTempSrcAnd32 >> (k-1)) & 0x01) ? 0x80000000L:0x00L; 27515fb4814Smrg ulTempDstXor32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? 0x40000000L:0x00L; 27615fb4814Smrg ulTempDstData32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? (pAST->HWCInfo.fg << 16):(pAST->HWCInfo.bg << 16); 277de78e416Smrg /* No inverse for X Window cursor, ycchen@111808 */ 278de78e416Smrg if (ulTempDstAnd32[0]) 279de78e416Smrg ulTempDstXor32[0] = 0; 280de78e416Smrg if (ulTempDstAnd32[1]) 281de78e416Smrg ulTempDstXor32[1] = 0; 28215fb4814Smrg *((ULONG *) pjDstData) = ulTempDstAnd32[0] | ulTempDstXor32[0] | ulTempDstData32[0] | ulTempDstAnd32[1] | ulTempDstXor32[1] | ulTempDstData32[1]; 28315fb4814Smrg ulCheckSum += *((ULONG *) pjDstData); 28415fb4814Smrg pjDstData += 4; 28515fb4814Smrg 28615fb4814Smrg } 28715fb4814Smrg pjSrcAnd ++; 28815fb4814Smrg pjSrcXor ++; 28915fb4814Smrg 29015fb4814Smrg } 29115fb4814Smrg 29215fb4814Smrg } 29315fb4814Smrg 294b534f209Smrg if (pAST->jChipType == AST1180) 295b534f209Smrg { 296b534f209Smrg ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next); 297b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr); 298b534f209Smrg } 299b534f209Smrg else 300b534f209Smrg { 301b534f209Smrg /* Write Checksum as signature */ 302b534f209Smrg pjDstData = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; 303b534f209Smrg *((ULONG *) pjDstData) = ulCheckSum; 304b534f209Smrg *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width; 305b534f209Smrg *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height; 306b534f209Smrg *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTX)) = 0; 307b534f209Smrg *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTY)) = 0; 308b534f209Smrg 309b534f209Smrg /* set pattern offset */ 310b534f209Smrg ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3); 311b534f209Smrg SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF)); 312b534f209Smrg SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF)); 313b534f209Smrg SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF)); 314b534f209Smrg } 31515fb4814Smrg 31615fb4814Smrg /* update HWC_NUM_Next */ 31715fb4814Smrg pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM; 31815fb4814Smrg 31915fb4814Smrg} 32015fb4814Smrg 32115fb4814Smrgstatic Bool 32215fb4814SmrgASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 32315fb4814Smrg{ 324de78e416Smrg if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) ) 325de78e416Smrg return FALSE; 326de78e416Smrg 32715fb4814Smrg return TRUE; 32815fb4814Smrg} 32915fb4814Smrg 33015fb4814Smrgstatic void 33115fb4814SmrgASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs) 33215fb4814Smrg{ 33315fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 33415fb4814Smrg 33515fb4814Smrg UCHAR *pjDstXor, *pjSrcXor; 33615fb4814Smrg ULONG i, j, ulSrcWidth, ulSrcHeight; 33715fb4814Smrg ULONG ulPerPixelCopy, ulTwoPixelCopy; 33815fb4814Smrg LONG lAlphaDstDelta, lLastAlphaDstDelta; 33915fb4814Smrg union 34015fb4814Smrg { 34115fb4814Smrg ULONG ul; 34215fb4814Smrg UCHAR b[4]; 34315fb4814Smrg } ulSrcData32[2], ulData32; 34415fb4814Smrg union 34515fb4814Smrg { 34615fb4814Smrg USHORT us; 34715fb4814Smrg UCHAR b[2]; 34815fb4814Smrg } usData16; 34915fb4814Smrg ULONG ulCheckSum = 0; 35015fb4814Smrg ULONG ulPatternAddr; 35115fb4814Smrg 35215fb4814Smrg /* init cursor info. */ 35315fb4814Smrg pAST->HWCInfo.cursortype = HWC_COLOR; 35415fb4814Smrg pAST->HWCInfo.width = pCurs->bits->width; 35515fb4814Smrg pAST->HWCInfo.height = pCurs->bits->height; 35615fb4814Smrg pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width; 35715fb4814Smrg pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height; 35815fb4814Smrg 35915fb4814Smrg /* copy cursor image to cache */ 36015fb4814Smrg ulSrcWidth = pAST->HWCInfo.width; 36115fb4814Smrg ulSrcHeight = pAST->HWCInfo.height; 36215fb4814Smrg 36315fb4814Smrg lAlphaDstDelta = MAX_HWC_WIDTH << 1; 36415fb4814Smrg lLastAlphaDstDelta = lAlphaDstDelta - (ulSrcWidth << 1); 36515fb4814Smrg 36615fb4814Smrg pjSrcXor = (UCHAR *) pCurs->bits->argb;; 36715fb4814Smrg pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next 36815fb4814Smrg + lLastAlphaDstDelta + (MAX_HWC_HEIGHT - ulSrcHeight) * lAlphaDstDelta; 36915fb4814Smrg 37015fb4814Smrg ulPerPixelCopy = ulSrcWidth & 1; 37115fb4814Smrg ulTwoPixelCopy = ulSrcWidth >> 1; 37215fb4814Smrg 37315fb4814Smrg for (j = 0; j < ulSrcHeight; j++) 37415fb4814Smrg { 37515fb4814Smrg 37615fb4814Smrg for (i = 0; i < ulTwoPixelCopy; i++ ) 37715fb4814Smrg { 37815fb4814Smrg ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0; 37915fb4814Smrg ulSrcData32[1].ul = *((ULONG *) (pjSrcXor+4)) & 0xF0F0F0F0; 38015fb4814Smrg ulData32.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4); 38115fb4814Smrg ulData32.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4); 38215fb4814Smrg ulData32.b[2] = ulSrcData32[1].b[1] | (ulSrcData32[1].b[0] >> 4); 38315fb4814Smrg ulData32.b[3] = ulSrcData32[1].b[3] | (ulSrcData32[1].b[2] >> 4); 38415fb4814Smrg *((ULONG *) pjDstXor) = ulData32.ul; 38515fb4814Smrg ulCheckSum += (ULONG) ulData32.ul; 38615fb4814Smrg pjDstXor += 4; 38715fb4814Smrg pjSrcXor += 8; 38815fb4814Smrg } 38915fb4814Smrg 39015fb4814Smrg for (i = 0; i < ulPerPixelCopy; i++ ) 39115fb4814Smrg { 39215fb4814Smrg ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0; 39315fb4814Smrg usData16.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4); 39415fb4814Smrg usData16.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4); 39515fb4814Smrg *((USHORT *) pjDstXor) = usData16.us; 39615fb4814Smrg ulCheckSum += (ULONG) usData16.us; 39715fb4814Smrg pjDstXor += 2; 39815fb4814Smrg pjSrcXor += 4; 39915fb4814Smrg } 40015fb4814Smrg 40115fb4814Smrg /* Point to next source and dest scans */ 40215fb4814Smrg pjDstXor += lLastAlphaDstDelta; 40315fb4814Smrg 40415fb4814Smrg } /* end of for-loop */ 40515fb4814Smrg 406b534f209Smrg if (pAST->jChipType == AST1180) 407b534f209Smrg { 408b534f209Smrg ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next); 409b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr); 410b534f209Smrg } 411b534f209Smrg else 412b534f209Smrg { 413b534f209Smrg /* Write Checksum as signature */ 414b534f209Smrg pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; 415b534f209Smrg *((ULONG *) pjDstXor) = ulCheckSum; 416b534f209Smrg *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width; 417b534f209Smrg *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height; 418b534f209Smrg *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTX)) = 0; 419b534f209Smrg *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTY)) = 0; 420b534f209Smrg 421b534f209Smrg /* set pattern offset */ 422b534f209Smrg ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr +(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3); 423b534f209Smrg SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF)); 424b534f209Smrg SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF)); 425b534f209Smrg SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF)); 426b534f209Smrg } 42715fb4814Smrg 42815fb4814Smrg /* update HWC_NUM_Next */ 42915fb4814Smrg pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM; 43015fb4814Smrg 43115fb4814Smrg} 43215fb4814Smrg 43315fb4814Smrgstatic Bool 43415fb4814SmrgASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs) 43515fb4814Smrg{ 436de78e416Smrg if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) ) 437de78e416Smrg return FALSE; 438de78e416Smrg 43915fb4814Smrg return TRUE; 44015fb4814Smrg} 44115fb4814Smrg 44215fb4814Smrgstatic void 44315fb4814SmrgASTFireCursor(ScrnInfoPtr pScrn) 44415fb4814Smrg{ 44515fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 44615fb4814Smrg 44715fb4814Smrg SetIndexRegMask(CRTC_PORT, 0xCB, 0xFF, 0x00); /* dummp write to fire HWC */ 44815fb4814Smrg 44915fb4814Smrg} 45015fb4814Smrg 451b534f209Smrg/* AST1180 */ 452b534f209Smrgstatic void 453b534f209SmrgASTShowCursor_AST1180(ScrnInfoPtr pScrn) 454b534f209Smrg{ 455b534f209Smrg ASTRecPtr pAST = ASTPTR(pScrn); 456b534f209Smrg ULONG ulData, ulTemp; 457b534f209Smrg 458b534f209Smrg ReadAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp); 459b534f209Smrg 460b534f209Smrg ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); 461b534f209Smrg ulData &= ~AST1180_ALPHAHWC; 462b534f209Smrg if (pAST->HWCInfo.cursortype ==HWC_COLOR) 463b534f209Smrg ulData |= AST1180_ALPHAHWC; 464b534f209Smrg ulData |= AST1180_ENABLEHWC; 465b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); 466b534f209Smrg 467b534f209Smrg /* fire cursor */ 468b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp); 469b534f209Smrg 470b534f209Smrg} /* ASTShowCursor_AST1180 */ 471b534f209Smrg 472b534f209Smrgstatic void 473b534f209SmrgASTHideCursor_AST1180(ScrnInfoPtr pScrn) 474b534f209Smrg{ 475b534f209Smrg ASTRecPtr pAST = ASTPTR(pScrn); 476b534f209Smrg ULONG ulData; 477b534f209Smrg 478b534f209Smrg ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); 479b534f209Smrg ulData &= ~AST1180_ENABLEHWC; 480b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); 481b534f209Smrg 482b534f209Smrg /* fire cursor */ 483b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, 0x07ff07ff); 484b534f209Smrg 485b534f209Smrg} /* ASTHideCursor_AST1180 */ 486b534f209Smrg 487b534f209Smrgstatic void 488b534f209SmrgASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y) 489b534f209Smrg{ 490b534f209Smrg ASTRecPtr pAST = ASTPTR(pScrn); 491b534f209Smrg DisplayModePtr mode = pAST->ModePtr; 492b534f209Smrg int x_offset, y_offset; 493b534f209Smrg ULONG ulData; 494b534f209Smrg 495b534f209Smrg x_offset = pAST->HWCInfo.offset_x; 496b534f209Smrg y_offset = pAST->HWCInfo.offset_y; 497b534f209Smrg 498b534f209Smrg if(x < 0) { 499b534f209Smrg x_offset = (-x) + pAST->HWCInfo.offset_x; 500b534f209Smrg x = 0; 501b534f209Smrg } 502b534f209Smrg 503b534f209Smrg if(y < 0) { 504b534f209Smrg y_offset = (-y) + pAST->HWCInfo.offset_y; 505b534f209Smrg y = 0; 506b534f209Smrg } 507b534f209Smrg 508b534f209Smrg if(mode->Flags & V_DBLSCAN) y *= 2; 509b534f209Smrg 510b534f209Smrg /* Set to Reg. */ 511b534f209Smrg ulData = (x_offset) | (y_offset << 8); 512b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_OFFSET, ulData); 513b534f209Smrg ulData = (x) | (y << 16); 514b534f209Smrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulData); 515b534f209Smrg 516b534f209Smrg} /* ASTSetCursorPosition_AST1180 */ 517b534f209Smrg 51815fb4814Smrg#endif /* End of HWC */ 519