1301ea0f4Smrg 2301ea0f4Smrg/************************************************************************** 3301ea0f4Smrg 4301ea0f4SmrgCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 5301ea0f4SmrgAll Rights Reserved. 6301ea0f4Smrg 7301ea0f4SmrgPermission is hereby granted, free of charge, to any person obtaining a 8301ea0f4Smrgcopy of this software and associated documentation files (the 9301ea0f4Smrg"Software"), to deal in the Software without restriction, including 10301ea0f4Smrgwithout limitation the rights to use, copy, modify, merge, publish, 11301ea0f4Smrgdistribute, sub license, and/or sell copies of the Software, and to 12301ea0f4Smrgpermit persons to whom the Software is furnished to do so, subject to 13301ea0f4Smrgthe following conditions: 14301ea0f4Smrg 15301ea0f4SmrgThe above copyright notice and this permission notice (including the 16301ea0f4Smrgnext paragraph) shall be included in all copies or substantial portions 17301ea0f4Smrgof the Software. 18301ea0f4Smrg 19301ea0f4SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20301ea0f4SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21301ea0f4SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22301ea0f4SmrgIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 23301ea0f4SmrgANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24301ea0f4SmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25301ea0f4SmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26301ea0f4Smrg 27301ea0f4Smrg**************************************************************************/ 28301ea0f4Smrg 29301ea0f4Smrg/* 30301ea0f4Smrg * Authors: 31301ea0f4Smrg * Daryll Strauss <daryll@precisioninsight.com> 32301ea0f4Smrg * 33301ea0f4Smrg */ 34301ea0f4Smrg 35301ea0f4Smrg#ifdef HAVE_CONFIG_H 36301ea0f4Smrg#include "config.h" 37301ea0f4Smrg#endif 38301ea0f4Smrg 39301ea0f4Smrg#include "xf86.h" 40301ea0f4Smrg#include "xf86_OSproc.h" 41301ea0f4Smrg#include "compiler.h" 42301ea0f4Smrg 43301ea0f4Smrg#include "xf86fbman.h" 44301ea0f4Smrg 45301ea0f4Smrg#include "vgaHW.h" 46301ea0f4Smrg#include "xf86xv.h" 47301ea0f4Smrg#include "i740.h" 48301ea0f4Smrg 49301ea0f4Smrgstatic void I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src); 50301ea0f4Smrgstatic void I740ShowCursor(ScrnInfoPtr pScrn); 51301ea0f4Smrgstatic void I740HideCursor(ScrnInfoPtr pScrn); 52301ea0f4Smrgstatic void I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y); 53301ea0f4Smrgstatic void I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb); 54301ea0f4Smrgstatic Bool I740UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs); 55301ea0f4Smrg 56301ea0f4SmrgBool 57301ea0f4SmrgI740CursorInit(ScreenPtr pScreen) 58301ea0f4Smrg{ 59301ea0f4Smrg ScrnInfoPtr pScrn; 60301ea0f4Smrg I740Ptr pI740; 61301ea0f4Smrg xf86CursorInfoPtr infoPtr; 62301ea0f4Smrg FBAreaPtr fbarea; 63301ea0f4Smrg 64213fdd94Smrg pScrn = xf86ScreenToScrn(pScreen); 65301ea0f4Smrg pI740 = I740PTR(pScrn); 66301ea0f4Smrg pI740->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec(); 67301ea0f4Smrg if (!infoPtr) return FALSE; 68301ea0f4Smrg 69301ea0f4Smrg infoPtr->MaxWidth = 64; 70301ea0f4Smrg infoPtr->MaxHeight = 64; 71301ea0f4Smrg infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 72301ea0f4Smrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 73301ea0f4Smrg HARDWARE_CURSOR_INVERT_MASK | 74301ea0f4Smrg HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | 75301ea0f4Smrg HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 76301ea0f4Smrg HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64; 77301ea0f4Smrg 78301ea0f4Smrg infoPtr->SetCursorColors = I740SetCursorColors; 79301ea0f4Smrg infoPtr->SetCursorPosition = I740SetCursorPosition; 80301ea0f4Smrg infoPtr->LoadCursorImage = I740LoadCursorImage; 81301ea0f4Smrg infoPtr->HideCursor = I740HideCursor; 82301ea0f4Smrg infoPtr->ShowCursor = I740ShowCursor; 83301ea0f4Smrg infoPtr->UseHWCursor = I740UseHWCursor; 84301ea0f4Smrg 85301ea0f4Smrg/* 86301ea0f4Smrg * Allocate a region the full width and tall enough 87301ea0f4Smrg * that at least 6K of video memory is consumed. 88301ea0f4Smrg * Then use a 1 kilobyte piece that is 4K byte aligned 89301ea0f4Smrg * within that region. KAO. 90301ea0f4Smrg */ 91301ea0f4Smrg fbarea = xf86AllocateOffscreenArea(pScreen, 92301ea0f4Smrg pScrn->displayWidth, 93301ea0f4Smrg ((6*1024)/(pScrn->displayWidth*pI740->cpp))+1, 94301ea0f4Smrg 0,0,0,0); 95301ea0f4Smrg if (fbarea == NULL) { 96301ea0f4Smrg pI740->CursorStart=0; 97301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 98301ea0f4Smrg "Hardware cursor disabled due to failure allocating offscreen memory.\n"); 99301ea0f4Smrg } 100301ea0f4Smrg else { 101301ea0f4Smrg pI740->CursorStart = ((((fbarea->box.x1 + pScrn->displayWidth * fbarea->box.y1) * pI740->cpp)+4096)&0xfff000); 102301ea0f4Smrg } 103301ea0f4Smrg /* 104301ea0f4Smrg * Perhaps move the cursor to the beginning of the frame buffer 105301ea0f4Smrg * so that it never fails? 106301ea0f4Smrg */ 107301ea0f4Smrg if (pI740->CursorStart>4*1024*1024) { 108301ea0f4Smrg pI740->CursorStart=0; 109301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 110301ea0f4Smrg "Disabling hardware cursor due to large framebuffer\n"); 111301ea0f4Smrg } 112301ea0f4Smrg return xf86InitCursor(pScreen, infoPtr); 113301ea0f4Smrg} 114301ea0f4Smrg 115301ea0f4Smrgstatic Bool 116301ea0f4SmrgI740UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) { 117301ea0f4Smrg ScrnInfoPtr pScrn; 118301ea0f4Smrg I740Ptr pI740; 119301ea0f4Smrg 120213fdd94Smrg pScrn = xf86ScreenToScrn(pScreen); 121301ea0f4Smrg pI740 = I740PTR(pScrn); 122301ea0f4Smrg if (pScrn->currentMode->Flags&V_DBLSCAN) 123301ea0f4Smrg return FALSE; 124301ea0f4Smrg if (!pI740->CursorStart) return FALSE; 125301ea0f4Smrg return TRUE; 126301ea0f4Smrg} 127301ea0f4Smrg 128301ea0f4Smrgstatic void 129301ea0f4SmrgI740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) { 130301ea0f4Smrg I740Ptr pI740; 131301ea0f4Smrg int x, y; 132301ea0f4Smrg CARD8 *pcurs; 133301ea0f4Smrg 134301ea0f4Smrg pI740 = I740PTR(pScrn); 135301ea0f4Smrg pcurs = (CARD8 *)(pI740->FbBase + pI740->CursorStart); 136301ea0f4Smrg for (y = 0; y < 64; y++) { 137301ea0f4Smrg for (x = 0; x < 64 / 4; x++) { 138301ea0f4Smrg *pcurs++ = *src++; 139301ea0f4Smrg } 140301ea0f4Smrg } 141301ea0f4Smrg} 142301ea0f4Smrg 143301ea0f4Smrgstatic void 144301ea0f4SmrgI740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) { 145301ea0f4Smrg I740Ptr pI740; 146301ea0f4Smrg int flag; 147301ea0f4Smrg 148301ea0f4Smrg pI740 = I740PTR(pScrn); 149301ea0f4Smrg if (x >= 0) flag = CURSOR_X_POS; 150301ea0f4Smrg else { 151301ea0f4Smrg flag = CURSOR_X_NEG; 152301ea0f4Smrg x=-x; 153301ea0f4Smrg } 154301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_X_LO, x&0xFF); 155301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_X_HI, (((x >> 8) & 0x07) | flag)); 156301ea0f4Smrg 157301ea0f4Smrg if (y >= 0) flag = CURSOR_Y_POS; 158301ea0f4Smrg else { 159301ea0f4Smrg flag = CURSOR_Y_NEG; 160301ea0f4Smrg y=-y; 161301ea0f4Smrg } 162301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_Y_LO, y&0xFF); 163301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_Y_HI, (((y >> 8) & 0x07) | flag)); 164301ea0f4Smrg} 165301ea0f4Smrg 166301ea0f4Smrgstatic void 167301ea0f4SmrgI740ShowCursor(ScrnInfoPtr pScrn) { 168301ea0f4Smrg I740Ptr pI740; 169301ea0f4Smrg unsigned char tmp; 170301ea0f4Smrg 171301ea0f4Smrg pI740 = I740PTR(pScrn); 172301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_LO, 173301ea0f4Smrg (pI740->CursorStart & 0x0000F000) >> 8); 174301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_HI, 175301ea0f4Smrg (pI740->CursorStart & 0x003F0000) >> 16); 176301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_CONTROL, 177301ea0f4Smrg CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C); 178301ea0f4Smrg 179301ea0f4Smrg tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 180301ea0f4Smrg tmp |= HW_CURSOR_ENABLE; 181301ea0f4Smrg pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 182301ea0f4Smrg} 183301ea0f4Smrg 184301ea0f4Smrgstatic void 185301ea0f4SmrgI740HideCursor(ScrnInfoPtr pScrn) { 186301ea0f4Smrg unsigned char tmp; 187301ea0f4Smrg I740Ptr pI740; 188301ea0f4Smrg 189301ea0f4Smrg pI740 = I740PTR(pScrn); 190301ea0f4Smrg tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 191301ea0f4Smrg tmp &= ~HW_CURSOR_ENABLE; 192301ea0f4Smrg pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 193301ea0f4Smrg} 194301ea0f4Smrg 195301ea0f4Smrgstatic void 196301ea0f4SmrgI740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) { 197301ea0f4Smrg int tmp; 198301ea0f4Smrg I740Ptr pI740; 199301ea0f4Smrg 200301ea0f4Smrg pI740 = I740PTR(pScrn); 201301ea0f4Smrg tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 202301ea0f4Smrg tmp |= EXTENDED_PALETTE; 203301ea0f4Smrg pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 204301ea0f4Smrg 205301ea0f4Smrg pI740->writeStandard(pI740, DACMASK, 0xFF); 206301ea0f4Smrg pI740->writeStandard(pI740, DACWX, 0x04); 207301ea0f4Smrg 208301ea0f4Smrg pI740->writeStandard(pI740, DACDATA, (bg & 0x00FF0000) >> 16); 209301ea0f4Smrg pI740->writeStandard(pI740, DACDATA, (bg & 0x0000FF00) >> 8); 210301ea0f4Smrg pI740->writeStandard(pI740, DACDATA, (bg & 0x000000FF)); 211301ea0f4Smrg 212301ea0f4Smrg pI740->writeStandard(pI740, DACDATA, (fg & 0x00FF0000) >> 16); 213301ea0f4Smrg pI740->writeStandard(pI740, DACDATA, (fg & 0x0000FF00) >> 8); 214301ea0f4Smrg pI740->writeStandard(pI740, DACDATA, (fg & 0x000000FF)); 215301ea0f4Smrg 216301ea0f4Smrg tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 217301ea0f4Smrg tmp &= ~EXTENDED_PALETTE; 218301ea0f4Smrg pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 219301ea0f4Smrg} 220301ea0f4Smrg 221301ea0f4Smrg 222301ea0f4Smrg 223