ast_cursor.c revision f010a93d
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 "vgaHW.h" 3115fb4814Smrg#include "mipointer.h" 3215fb4814Smrg#include "micmap.h" 3315fb4814Smrg 3415fb4814Smrg#include "fb.h" 3515fb4814Smrg#include "regionstr.h" 3615fb4814Smrg#include "xf86xv.h" 3715fb4814Smrg#include <X11/extensions/Xv.h> 3815fb4814Smrg 3915fb4814Smrg#include "xf86Pci.h" 4015fb4814Smrg 4115fb4814Smrg/* framebuffer offscreen manager */ 4215fb4814Smrg#include "xf86fbman.h" 4315fb4814Smrg 4415fb4814Smrg/* include xaa includes */ 4515fb4814Smrg#include "xaarop.h" 4615fb4814Smrg 4715fb4814Smrg/* H/W cursor support */ 4815fb4814Smrg#include "xf86Cursor.h" 4915fb4814Smrg#include "cursorstr.h" 5015fb4814Smrg 5115fb4814Smrg/* Driver specific headers */ 5215fb4814Smrg#include "ast.h" 53cf503b78Smrg#include "ast_vgatool.h" 54cf503b78Smrg#include "ast_cursor.h" 5515fb4814Smrg 5615fb4814Smrg#ifdef HWC 5715fb4814Smrg/* Prototype type declaration */ 587fe5393cSmrgstatic void ASTShowCursor(ScrnInfoPtr pScrn); 59b534f209Smrgstatic void ASTHideCursor(ScrnInfoPtr pScrn); 6015fb4814Smrgstatic void ASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y); 6115fb4814Smrgstatic void ASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); 6215fb4814Smrgstatic void ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src); 6315fb4814Smrgstatic Bool ASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs); 6415fb4814Smrgstatic void ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs); 6515fb4814Smrgstatic Bool ASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs); 667fe5393cSmrgstatic void ASTFireCursor(ScrnInfoPtr pScrn); 677fe5393cSmrgstatic void ASTShowCursor_AST1180(ScrnInfoPtr pScrn); 68b534f209Smrgstatic void ASTHideCursor_AST1180(ScrnInfoPtr pScrn); 69b534f209Smrgstatic void ASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y); 7015fb4814Smrg 7115fb4814SmrgBool 7215fb4814SmrgASTCursorInit(ScreenPtr pScreen) 7315fb4814Smrg{ 74b4d38c65Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 7515fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 7615fb4814Smrg xf86CursorInfoPtr infoPtr; 7715fb4814Smrg 7815fb4814Smrg infoPtr = xf86CreateCursorInfoRec(); 7915fb4814Smrg if(!infoPtr) return FALSE; 8015fb4814Smrg 8115fb4814Smrg pAST->HWCInfoPtr = infoPtr; 8215fb4814Smrg 8315fb4814Smrg infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 847fe5393cSmrg HARDWARE_CURSOR_INVERT_MASK | 8515fb4814Smrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST; 8615fb4814Smrg 8715fb4814Smrg infoPtr->MaxWidth = MAX_HWC_WIDTH; 8815fb4814Smrg infoPtr->MaxHeight = MAX_HWC_HEIGHT; 89b534f209Smrg if (pAST->jChipType == AST1180) 90b534f209Smrg { 91b534f209Smrg infoPtr->ShowCursor = ASTShowCursor_AST1180; 92b534f209Smrg infoPtr->HideCursor = ASTHideCursor_AST1180; 93b534f209Smrg infoPtr->SetCursorPosition = ASTSetCursorPosition_AST1180; 947fe5393cSmrg } 95b534f209Smrg else 96b534f209Smrg { 97b534f209Smrg infoPtr->ShowCursor = ASTShowCursor; 98b534f209Smrg infoPtr->HideCursor = ASTHideCursor; 99b534f209Smrg infoPtr->SetCursorPosition = ASTSetCursorPosition; 100b534f209Smrg } 1017fe5393cSmrg infoPtr->SetCursorColors = ASTSetCursorColors; 10215fb4814Smrg infoPtr->LoadCursorImage = ASTLoadCursorImage; 10315fb4814Smrg infoPtr->UseHWCursor = ASTUseHWCursor; 10415fb4814Smrg#ifdef ARGB_CURSOR 10515fb4814Smrg infoPtr->UseHWCursorARGB = ASTUseHWCursorARGB; 10615fb4814Smrg infoPtr->LoadCursorARGB = ASTLoadCursorARGB; 10715fb4814Smrg#endif 10815fb4814Smrg 10915fb4814Smrg return(xf86InitCursor(pScreen, infoPtr)); 1107fe5393cSmrg 11115fb4814Smrg} 11215fb4814Smrg 113cf503b78SmrgBool bASTInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST) 11415fb4814Smrg{ 11515fb4814Smrg ScreenPtr pScreen; 11615fb4814Smrg 11715fb4814Smrg /* init cursor cache info */ 1187fe5393cSmrg /* Set HWC_NUM in Options instead */ 11915fb4814Smrg /* pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM; */ 1207fe5393cSmrg pAST->HWCInfo.HWC_NUM_Next = 0; 1217fe5393cSmrg 1227fe5393cSmrg /* allocate HWC cache */ 1237fe5393cSmrg if (!pAST->pHWCPtr) { 124b4d38c65Smrg pScreen = xf86ScrnToScreen(pScrn); 12515fb4814Smrg pAST->pHWCPtr = xf86AllocateOffscreenLinear (pScreen, (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM, HWC_ALIGN, NULL, NULL, NULL); 12615fb4814Smrg 1277fe5393cSmrg if (!pAST->pHWCPtr) { 12815fb4814Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Allocate HWC Cache failed \n"); 12915fb4814Smrg return (FALSE); 13015fb4814Smrg } 1317fe5393cSmrg 13215fb4814Smrg pAST->HWCInfo.ulHWCOffsetAddr = pAST->pHWCPtr->offset*((pScrn->bitsPerPixel + 1) / 8); 1337fe5393cSmrg pAST->HWCInfo.pjHWCVirtualAddr = pAST->FBVirtualAddr + pAST->HWCInfo.ulHWCOffsetAddr; 13415fb4814Smrg } 13515fb4814Smrg 1367fe5393cSmrg return (TRUE); 13715fb4814Smrg} 13815fb4814Smrg 139b534f209Smrgvoid ASTDisableHWC(ScrnInfoPtr pScrn) 140b534f209Smrg{ 1417fe5393cSmrg ASTRecPtr pAST = ASTPTR(pScrn); 1427fe5393cSmrg 143b534f209Smrg if (pAST->jChipType == AST1180) 1447fe5393cSmrg ASTHideCursor_AST1180(pScrn); 1457fe5393cSmrg else 146b534f209Smrg ASTHideCursor(pScrn); 1477fe5393cSmrg} 14815fb4814Smrg 14915fb4814Smrgstatic void 15015fb4814SmrgASTShowCursor(ScrnInfoPtr pScrn) 15115fb4814Smrg{ 1527fe5393cSmrg ASTRecPtr pAST = ASTPTR(pScrn); 15315fb4814Smrg UCHAR jReg; 15415fb4814Smrg 15515fb4814Smrg jReg= 0x02; 15615fb4814Smrg if (pAST->HWCInfo.cursortype ==HWC_COLOR) 15715fb4814Smrg jReg |= 0x01; 1587fe5393cSmrg 1597fe5393cSmrg SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, jReg); /* enable mono */ 1607fe5393cSmrg 16115fb4814Smrg} 16215fb4814Smrg 163b534f209Smrgstatic void 16415fb4814SmrgASTHideCursor(ScrnInfoPtr pScrn) 16515fb4814Smrg{ 16615fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 1677fe5393cSmrg 1687fe5393cSmrg SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, 0x00); /* disable HWC */ 1697fe5393cSmrg 17015fb4814Smrg} 17115fb4814Smrg 17215fb4814Smrgstatic void 17315fb4814SmrgASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 17415fb4814Smrg{ 17515fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 1767fe5393cSmrg DisplayModePtr mode = pAST->ModePtr; 17715fb4814Smrg int x_offset, y_offset; 1787fe5393cSmrg UCHAR *pjSignature; 1797fe5393cSmrg 1807fe5393cSmrg /* Set cursor info to Offscreen */ 1817fe5393cSmrg pjSignature = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; 18215fb4814Smrg *((ULONG *) (pjSignature + HWC_SIGNATURE_X)) = x; 18315fb4814Smrg *((ULONG *) (pjSignature + HWC_SIGNATURE_Y)) = y; 1847fe5393cSmrg 18515fb4814Smrg x_offset = pAST->HWCInfo.offset_x; 18615fb4814Smrg y_offset = pAST->HWCInfo.offset_y; 1877fe5393cSmrg 18815fb4814Smrg if(x < 0) { 18915fb4814Smrg x_offset = (-x) + pAST->HWCInfo.offset_x; 19015fb4814Smrg x = 0; 19115fb4814Smrg } 19215fb4814Smrg 19315fb4814Smrg if(y < 0) { 19415fb4814Smrg y_offset = (-y) + pAST->HWCInfo.offset_y; 19515fb4814Smrg y = 0; 19615fb4814Smrg } 19715fb4814Smrg 19815fb4814Smrg if(mode->Flags & V_DBLSCAN) y *= 2; 1997fe5393cSmrg 20015fb4814Smrg /* Set to Reg. */ 2017fe5393cSmrg SetIndexReg(CRTC_PORT, 0xC2, (UCHAR) (x_offset)); 2027fe5393cSmrg SetIndexReg(CRTC_PORT, 0xC3, (UCHAR) (y_offset)); 2037fe5393cSmrg SetIndexReg(CRTC_PORT, 0xC4, (UCHAR) (x & 0xFF)); 2047fe5393cSmrg SetIndexReg(CRTC_PORT, 0xC5, (UCHAR) ((x >> 8) & 0x0F)); 2057fe5393cSmrg SetIndexReg(CRTC_PORT, 0xC6, (UCHAR) (y & 0xFF)); 2067fe5393cSmrg SetIndexReg(CRTC_PORT, 0xC7, (UCHAR) ((y >> 8) & 0x07)); 2077fe5393cSmrg 20815fb4814Smrg /* Fire HWC */ 20915fb4814Smrg ASTFireCursor(pScrn); 2107fe5393cSmrg 2117fe5393cSmrg} 21215fb4814Smrg 21315fb4814Smrgstatic void 21415fb4814SmrgASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 21515fb4814Smrg{ 21615fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 217de78e416Smrg ULONG fg1, bg1; 2187fe5393cSmrg 219de78e416Smrg fg1 = (fg & 0x0F) | (((fg>>8) & 0x0F) << 4) | (((fg>>16) & 0x0F) << 8); 2207fe5393cSmrg bg1 = (bg & 0x0F) | (((bg>>8) & 0x0F) << 4) | (((bg>>16) & 0x0F) << 8); 221de78e416Smrg 222de78e416Smrg /* Fixed xorg bugzilla #20609, ycchen@031209 */ 2237fe5393cSmrg if ( (fg1 != pAST->HWCInfo.fg) || (bg1 != pAST->HWCInfo.bg) ) 224de78e416Smrg { 225de78e416Smrg pAST->HWCInfo.fg = fg1; 226de78e416Smrg pAST->HWCInfo.bg = bg1; 227de78e416Smrg ASTLoadCursorImage(pScrn, pAST->HWCInfo.cursorpattern); 2287fe5393cSmrg } 229de78e416Smrg 23015fb4814Smrg} 23115fb4814Smrg 23215fb4814Smrgstatic void 23315fb4814SmrgASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src) 23415fb4814Smrg{ 2357fe5393cSmrg ASTRecPtr pAST = ASTPTR(pScrn); 23615fb4814Smrg int i, j, k; 23715fb4814Smrg UCHAR *pjSrcAnd, *pjSrcXor, *pjDstData; 23815fb4814Smrg ULONG ulTempDstAnd32[2], ulTempDstXor32[2], ulTempDstData32[2]; 23915fb4814Smrg UCHAR jTempSrcAnd32, jTempSrcXor32; 2407fe5393cSmrg ULONG ulCheckSum = 0; 2417fe5393cSmrg ULONG ulPatternAddr; 2427fe5393cSmrg 24315fb4814Smrg /* init cursor info. */ 24415fb4814Smrg pAST->HWCInfo.cursortype = HWC_MONO; 24515fb4814Smrg pAST->HWCInfo.width = (USHORT) MAX_HWC_WIDTH; 24615fb4814Smrg pAST->HWCInfo.height = (USHORT) MAX_HWC_HEIGHT; 24715fb4814Smrg pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width; 24815fb4814Smrg pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height; 24915fb4814Smrg 250de78e416Smrg /* copy to hwc info */ 251de78e416Smrg for (i=0; i< MAX_HWC_WIDTH*MAX_HWC_HEIGHT/4; i+=4) 252de78e416Smrg *(ULONG *) (pAST->HWCInfo.cursorpattern + i) = *(ULONG *) (src + i); 2537fe5393cSmrg 25415fb4814Smrg /* copy cursor image to cache */ 25515fb4814Smrg pjSrcXor = src; 25615fb4814Smrg pjSrcAnd = src + (MAX_HWC_WIDTH*MAX_HWC_HEIGHT/8); 25715fb4814Smrg pjDstData = pAST->HWCInfo.pjHWCVirtualAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next; 2587fe5393cSmrg 25915fb4814Smrg for (j = 0; j < MAX_HWC_HEIGHT; j++) 26015fb4814Smrg { 26115fb4814Smrg for (i = 0; i < (MAX_HWC_WIDTH/8); i++ ) 26215fb4814Smrg { 26315fb4814Smrg for (k=7; k>0; k-=2) 26415fb4814Smrg { 26515fb4814Smrg jTempSrcAnd32 = *((UCHAR *) pjSrcAnd); 266de78e416Smrg jTempSrcXor32 = *((UCHAR *) pjSrcXor); 267de78e416Smrg ulTempDstAnd32[0] = ((jTempSrcAnd32 >> k) & 0x01) ? 0x00008000L:0x00L; 2687fe5393cSmrg ulTempDstXor32[0] = ((jTempSrcXor32 >> k) & 0x01) ? 0x00004000L:0x00L; 2697fe5393cSmrg ulTempDstData32[0] = ((jTempSrcXor32 >> k) & 0x01) ? pAST->HWCInfo.fg:pAST->HWCInfo.bg; 2707fe5393cSmrg ulTempDstAnd32[1] = ((jTempSrcAnd32 >> (k-1)) & 0x01) ? 0x80000000L:0x00L; 2717fe5393cSmrg ulTempDstXor32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? 0x40000000L:0x00L; 27215fb4814Smrg ulTempDstData32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? (pAST->HWCInfo.fg << 16):(pAST->HWCInfo.bg << 16); 273de78e416Smrg /* No inverse for X Window cursor, ycchen@111808 */ 274de78e416Smrg if (ulTempDstAnd32[0]) 275de78e416Smrg ulTempDstXor32[0] = 0; 276de78e416Smrg if (ulTempDstAnd32[1]) 2777fe5393cSmrg ulTempDstXor32[1] = 0; 27815fb4814Smrg *((ULONG *) pjDstData) = ulTempDstAnd32[0] | ulTempDstXor32[0] | ulTempDstData32[0] | ulTempDstAnd32[1] | ulTempDstXor32[1] | ulTempDstData32[1]; 2797fe5393cSmrg ulCheckSum += *((ULONG *) pjDstData); 28015fb4814Smrg pjDstData += 4; 28115fb4814Smrg 28215fb4814Smrg } 28315fb4814Smrg pjSrcAnd ++; 28415fb4814Smrg pjSrcXor ++; 2857fe5393cSmrg 2867fe5393cSmrg } 2877fe5393cSmrg 2887fe5393cSmrg } 28915fb4814Smrg 290b534f209Smrg if (pAST->jChipType == AST1180) 291b534f209Smrg { 2927fe5393cSmrg ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next); 2937fe5393cSmrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr); 2947fe5393cSmrg } 295b534f209Smrg else 296b534f209Smrg { 297b534f209Smrg /* Write Checksum as signature */ 2987fe5393cSmrg pjDstData = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; 299b534f209Smrg *((ULONG *) pjDstData) = ulCheckSum; 300b534f209Smrg *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width; 301b534f209Smrg *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height; 302b534f209Smrg *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTX)) = 0; 303b534f209Smrg *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTY)) = 0; 3047fe5393cSmrg 305b534f209Smrg /* set pattern offset */ 306b534f209Smrg ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3); 3077fe5393cSmrg SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF)); 3087fe5393cSmrg SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF)); 3097fe5393cSmrg SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF)); 310b534f209Smrg } 3117fe5393cSmrg 31215fb4814Smrg /* update HWC_NUM_Next */ 31315fb4814Smrg pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM; 3147fe5393cSmrg 31515fb4814Smrg} 31615fb4814Smrg 3177fe5393cSmrgstatic Bool 31815fb4814SmrgASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 31915fb4814Smrg{ 320de78e416Smrg if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) ) 321de78e416Smrg return FALSE; 3227fe5393cSmrg 32315fb4814Smrg return TRUE; 32415fb4814Smrg} 32515fb4814Smrg 32615fb4814Smrgstatic void 32715fb4814SmrgASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs) 32815fb4814Smrg{ 3297fe5393cSmrg ASTRecPtr pAST = ASTPTR(pScrn); 33015fb4814Smrg 33115fb4814Smrg UCHAR *pjDstXor, *pjSrcXor; 33215fb4814Smrg ULONG i, j, ulSrcWidth, ulSrcHeight; 3337fe5393cSmrg ULONG ulPerPixelCopy, ulTwoPixelCopy; 33415fb4814Smrg LONG lAlphaDstDelta, lLastAlphaDstDelta; 33515fb4814Smrg union 33615fb4814Smrg { 33715fb4814Smrg ULONG ul; 33815fb4814Smrg UCHAR b[4]; 3397fe5393cSmrg } ulSrcData32[2], ulData32; 34015fb4814Smrg union 34115fb4814Smrg { 34215fb4814Smrg USHORT us; 34315fb4814Smrg UCHAR b[2]; 34415fb4814Smrg } usData16; 3457fe5393cSmrg ULONG ulCheckSum = 0; 34615fb4814Smrg ULONG ulPatternAddr; 3477fe5393cSmrg 34815fb4814Smrg /* init cursor info. */ 34915fb4814Smrg pAST->HWCInfo.cursortype = HWC_COLOR; 35015fb4814Smrg pAST->HWCInfo.width = pCurs->bits->width; 35115fb4814Smrg pAST->HWCInfo.height = pCurs->bits->height; 35215fb4814Smrg pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width; 35315fb4814Smrg pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height; 3547fe5393cSmrg 35515fb4814Smrg /* copy cursor image to cache */ 3567fe5393cSmrg ulSrcWidth = pAST->HWCInfo.width; 3577fe5393cSmrg ulSrcHeight = pAST->HWCInfo.height; 3587fe5393cSmrg 35915fb4814Smrg lAlphaDstDelta = MAX_HWC_WIDTH << 1; 36015fb4814Smrg lLastAlphaDstDelta = lAlphaDstDelta - (ulSrcWidth << 1); 36115fb4814Smrg 36215fb4814Smrg pjSrcXor = (UCHAR *) pCurs->bits->argb;; 36315fb4814Smrg pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next 36415fb4814Smrg + lLastAlphaDstDelta + (MAX_HWC_HEIGHT - ulSrcHeight) * lAlphaDstDelta; 3657fe5393cSmrg 36615fb4814Smrg ulPerPixelCopy = ulSrcWidth & 1; 36715fb4814Smrg ulTwoPixelCopy = ulSrcWidth >> 1; 3687fe5393cSmrg 36915fb4814Smrg for (j = 0; j < ulSrcHeight; j++) 37015fb4814Smrg { 37115fb4814Smrg 37215fb4814Smrg for (i = 0; i < ulTwoPixelCopy; i++ ) 37315fb4814Smrg { 37415fb4814Smrg ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0; 37515fb4814Smrg ulSrcData32[1].ul = *((ULONG *) (pjSrcXor+4)) & 0xF0F0F0F0; 37615fb4814Smrg ulData32.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4); 37715fb4814Smrg ulData32.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4); 37815fb4814Smrg ulData32.b[2] = ulSrcData32[1].b[1] | (ulSrcData32[1].b[0] >> 4); 3797fe5393cSmrg ulData32.b[3] = ulSrcData32[1].b[3] | (ulSrcData32[1].b[2] >> 4); 38015fb4814Smrg *((ULONG *) pjDstXor) = ulData32.ul; 3817fe5393cSmrg ulCheckSum += (ULONG) ulData32.ul; 38215fb4814Smrg pjDstXor += 4; 38315fb4814Smrg pjSrcXor += 8; 3847fe5393cSmrg } 3857fe5393cSmrg 38615fb4814Smrg for (i = 0; i < ulPerPixelCopy; i++ ) 38715fb4814Smrg { 38815fb4814Smrg ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0; 38915fb4814Smrg usData16.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4); 39015fb4814Smrg usData16.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4); 39115fb4814Smrg *((USHORT *) pjDstXor) = usData16.us; 3927fe5393cSmrg ulCheckSum += (ULONG) usData16.us; 39315fb4814Smrg pjDstXor += 2; 39415fb4814Smrg pjSrcXor += 4; 3957fe5393cSmrg } 39615fb4814Smrg 39715fb4814Smrg /* Point to next source and dest scans */ 39815fb4814Smrg pjDstXor += lLastAlphaDstDelta; 3997fe5393cSmrg 40015fb4814Smrg } /* end of for-loop */ 40115fb4814Smrg 402b534f209Smrg if (pAST->jChipType == AST1180) 403b534f209Smrg { 4047fe5393cSmrg ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next); 4057fe5393cSmrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr); 4067fe5393cSmrg } 407b534f209Smrg else 408b534f209Smrg { 409b534f209Smrg /* Write Checksum as signature */ 4107fe5393cSmrg pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; 411b534f209Smrg *((ULONG *) pjDstXor) = ulCheckSum; 412b534f209Smrg *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width; 413b534f209Smrg *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height; 414b534f209Smrg *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTX)) = 0; 415b534f209Smrg *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTY)) = 0; 4167fe5393cSmrg 417b534f209Smrg /* set pattern offset */ 418b534f209Smrg ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr +(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3); 4197fe5393cSmrg SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF)); 4207fe5393cSmrg SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF)); 4217fe5393cSmrg SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF)); 422b534f209Smrg } 4237fe5393cSmrg 42415fb4814Smrg /* update HWC_NUM_Next */ 42515fb4814Smrg pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM; 4267fe5393cSmrg 42715fb4814Smrg} 42815fb4814Smrg 4297fe5393cSmrgstatic Bool 43015fb4814SmrgASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs) 43115fb4814Smrg{ 432de78e416Smrg if ( (pCurs->bits->width > MAX_HWC_WIDTH) || (pCurs->bits->height > MAX_HWC_HEIGHT) ) 433de78e416Smrg return FALSE; 4347fe5393cSmrg 43515fb4814Smrg return TRUE; 43615fb4814Smrg} 43715fb4814Smrg 43815fb4814Smrgstatic void 43915fb4814SmrgASTFireCursor(ScrnInfoPtr pScrn) 44015fb4814Smrg{ 44115fb4814Smrg ASTRecPtr pAST = ASTPTR(pScrn); 4427fe5393cSmrg 443f010a93dSmrg SetIndexRegMask(CRTC_PORT, 0xCB, 0xFF, 0x00); /* dummy write to fire HWC */ 4447fe5393cSmrg 44515fb4814Smrg} 44615fb4814Smrg 447b534f209Smrg/* AST1180 */ 448b534f209Smrgstatic void 449b534f209SmrgASTShowCursor_AST1180(ScrnInfoPtr pScrn) 450b534f209Smrg{ 4517fe5393cSmrg ASTRecPtr pAST = ASTPTR(pScrn); 452b534f209Smrg ULONG ulData, ulTemp; 453b534f209Smrg 4547fe5393cSmrg ReadAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp); 455b534f209Smrg 456b534f209Smrg ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); 457b534f209Smrg ulData &= ~AST1180_ALPHAHWC; 458b534f209Smrg if (pAST->HWCInfo.cursortype ==HWC_COLOR) 4597fe5393cSmrg ulData |= AST1180_ALPHAHWC; 460b534f209Smrg ulData |= AST1180_ENABLEHWC; 4617fe5393cSmrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); 462b534f209Smrg 463b534f209Smrg /* fire cursor */ 4647fe5393cSmrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp); 4657fe5393cSmrg 466b534f209Smrg} /* ASTShowCursor_AST1180 */ 467b534f209Smrg 468b534f209Smrgstatic void 469b534f209SmrgASTHideCursor_AST1180(ScrnInfoPtr pScrn) 470b534f209Smrg{ 471b534f209Smrg ASTRecPtr pAST = ASTPTR(pScrn); 472b534f209Smrg ULONG ulData; 473b534f209Smrg 474b534f209Smrg ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); 475b534f209Smrg ulData &= ~AST1180_ENABLEHWC; 4767fe5393cSmrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); 4777fe5393cSmrg 478b534f209Smrg /* fire cursor */ 4797fe5393cSmrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, 0x07ff07ff); 4807fe5393cSmrg 481b534f209Smrg} /* ASTHideCursor_AST1180 */ 482b534f209Smrg 483b534f209Smrgstatic void 484b534f209SmrgASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y) 485b534f209Smrg{ 486b534f209Smrg ASTRecPtr pAST = ASTPTR(pScrn); 4877fe5393cSmrg DisplayModePtr mode = pAST->ModePtr; 488b534f209Smrg int x_offset, y_offset; 489b534f209Smrg ULONG ulData; 4907fe5393cSmrg 491b534f209Smrg x_offset = pAST->HWCInfo.offset_x; 492b534f209Smrg y_offset = pAST->HWCInfo.offset_y; 4937fe5393cSmrg 494b534f209Smrg if(x < 0) { 495b534f209Smrg x_offset = (-x) + pAST->HWCInfo.offset_x; 496b534f209Smrg x = 0; 497b534f209Smrg } 498b534f209Smrg 499b534f209Smrg if(y < 0) { 500b534f209Smrg y_offset = (-y) + pAST->HWCInfo.offset_y; 501b534f209Smrg y = 0; 502b534f209Smrg } 503b534f209Smrg 504b534f209Smrg if(mode->Flags & V_DBLSCAN) y *= 2; 5057fe5393cSmrg 506b534f209Smrg /* Set to Reg. */ 507b534f209Smrg ulData = (x_offset) | (y_offset << 8); 5087fe5393cSmrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_OFFSET, ulData); 509b534f209Smrg ulData = (x) | (y << 16); 5107fe5393cSmrg WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulData); 5117fe5393cSmrg 5127fe5393cSmrg} /* ASTSetCursorPosition_AST1180 */ 513b534f209Smrg 51415fb4814Smrg#endif /* End of HWC */ 515