1d983712dSmrg 2d983712dSmrg#ifdef HAVE_CONFIG_H 3d983712dSmrg#include "config.h" 4d983712dSmrg#endif 5d983712dSmrg 6d983712dSmrg#include "tseng.h" 7d983712dSmrg 8d983712dSmrg/* 9d983712dSmrg * 10d983712dSmrg * ET4000 HWCursor is disabled currently: we need to find a way to set the 11d983712dSmrg * sprite colours. 12d983712dSmrg * 13d983712dSmrg */ 14d983712dSmrg 15d983712dSmrg/* 16d983712dSmrg * ET4000W32 sprite engine. 17d983712dSmrg */ 18d983712dSmrgstatic CARD8 19d983712dSmrgET4000CursorRead(CARD8 Index) 20d983712dSmrg{ 21d983712dSmrg outb(0x217A, Index); 22d983712dSmrg return inb(0x217B); 23d983712dSmrg} 24d983712dSmrg 25d983712dSmrgstatic void 26d983712dSmrgET4000CursorWrite(CARD8 Index, CARD8 Value) 27d983712dSmrg{ 28d983712dSmrg outb(0x217A, Index); 29d983712dSmrg outb(0x217B, Value); 30d983712dSmrg} 31d983712dSmrg 32d983712dSmrg/* 33d983712dSmrg * 34d983712dSmrg */ 35d983712dSmrgstatic Bool 36d983712dSmrgTsengUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 37d983712dSmrg{ 38d983712dSmrg /* have this return false for DoubleScan and Interlaced ? */ 39d983712dSmrg return TRUE; 40d983712dSmrg} 41d983712dSmrg 42d983712dSmrgstatic void 43d983712dSmrgTsengShowCursor(ScrnInfoPtr pScrn) 44d983712dSmrg{ 45d983712dSmrg unsigned char tmp; 46d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 47d983712dSmrg 48d983712dSmrg /* Enable the hardware cursor. */ 49d983712dSmrg if (pTseng->ChipType == ET6000) { 50d983712dSmrg tmp = ET6000IORead(pTseng, 0x46); 51d983712dSmrg ET6000IOWrite(pTseng, 0x46, (tmp | 0x01)); 52d983712dSmrg } else { 53d983712dSmrg tmp = ET4000CursorRead(0xF7); 54d983712dSmrg ET4000CursorWrite(0xF7, tmp | 0x80); 55d983712dSmrg } 56d983712dSmrg} 57d983712dSmrg 58d983712dSmrgstatic void 59d983712dSmrgTsengHideCursor(ScrnInfoPtr pScrn) 60d983712dSmrg{ 61d983712dSmrg unsigned char tmp; 62d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 63d983712dSmrg 64d983712dSmrg /* Disable the hardware cursor. */ 65d983712dSmrg if (pTseng->ChipType == ET6000) { 66d983712dSmrg tmp = ET6000IORead(pTseng, 0x46); 67d983712dSmrg ET6000IOWrite(pTseng, 0x46, (tmp & 0xfe)); 68d983712dSmrg } else { 69d983712dSmrg tmp = ET4000CursorRead(0xF7); 70d983712dSmrg ET4000CursorWrite(0xF7, tmp & ~0x80); 71d983712dSmrg } 72d983712dSmrg} 73d983712dSmrg 74d983712dSmrgstatic void 75d983712dSmrgTsengSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 76d983712dSmrg{ 77d983712dSmrg int xorigin, yorigin; 78d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 79d983712dSmrg 80d983712dSmrg /* 81d983712dSmrg * If the cursor is partly out of screen at the left or top, 82d983712dSmrg * we need to modify the origin. 83d983712dSmrg */ 84d983712dSmrg xorigin = 0; 85d983712dSmrg yorigin = 0; 86d983712dSmrg if (x < 0) { 87d983712dSmrg xorigin = -x; 88d983712dSmrg x = 0; 89d983712dSmrg } 90d983712dSmrg if (y < 0) { 91d983712dSmrg yorigin = -y; 92d983712dSmrg y = 0; 93d983712dSmrg } 94d983712dSmrg#ifdef TODO 95d983712dSmrg /* Correct cursor position in DoubleScan modes */ 96d983712dSmrg if (XF86SCRNINFO(pScr)->modes->Flags & V_DBLSCAN) 97d983712dSmrg y *= 2; 98d983712dSmrg#endif 99d983712dSmrg 100d983712dSmrg if (pTseng->ChipType == ET6000) { 101d983712dSmrg ET6000IOWrite(pTseng, 0x82, xorigin); 102d983712dSmrg ET6000IOWrite(pTseng, 0x83, yorigin); 103d983712dSmrg 104d983712dSmrg ET6000IOWrite(pTseng, 0x84, (x & 0xff)); 105d983712dSmrg ET6000IOWrite(pTseng, 0x85, ((x >> 8) & 0x0f)); 106d983712dSmrg 107d983712dSmrg ET6000IOWrite(pTseng, 0x86, (y & 0xff)); 108d983712dSmrg ET6000IOWrite(pTseng, 0x87, ((y >> 8) & 0x0f)); 109d983712dSmrg } else { 110d983712dSmrg ET4000CursorWrite(0xE2, xorigin); 111d983712dSmrg ET4000CursorWrite(0xE6, yorigin); 112d983712dSmrg 113d983712dSmrg ET4000CursorWrite(0xE0, x & 0xFF); 114d983712dSmrg ET4000CursorWrite(0xE1, (x >> 8) & 0x0F); 115d983712dSmrg 116d983712dSmrg ET4000CursorWrite(0xE4, y & 0xFF); 117d983712dSmrg ET4000CursorWrite(0xE5, (y >> 8) & 0x0F); 118d983712dSmrg } 119d983712dSmrg} 120d983712dSmrg 121d983712dSmrg/* 122d983712dSmrg * The ET6000 cursor color is only 6 bits, with 2 bits per color. This 123d983712dSmrg * is of course very inaccurate, but high-bit-depth color differences 124d983712dSmrg * are only visible on _large_ planes of equal color. i.e. small areas 125d983712dSmrg * of a certain color (like a cursor) don't need many bits per pixel at 126d983712dSmrg * all, because the difference will not be seen. 127d983712dSmrg * 128d983712dSmrg * So it won't be as bad, but should still be documented nonetheless. 129d983712dSmrg */ 130d983712dSmrgstatic void 131d983712dSmrgTsengSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 132d983712dSmrg{ 133d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 134d983712dSmrg unsigned char et6k_fg, et6k_bg; 135d983712dSmrg 136d983712dSmrg if (pTseng->ChipType == ET6000) { 137d983712dSmrg et6k_fg = (fg & 0x00000003) 138d983712dSmrg | ((fg & 0x00000300) >> 6) 139d983712dSmrg | ((fg & 0x00030000) >> 12); 140d983712dSmrg et6k_bg = (bg & 0x00000003) 141d983712dSmrg | ((bg & 0x00000300) >> 6) 142d983712dSmrg | ((bg & 0x00030000) >> 12); 143d983712dSmrg 144d983712dSmrg ET6000IOWrite(pTseng, 0x67, 0x09); /* prepare for colour data */ 145d983712dSmrg ET6000IOWrite(pTseng, 0x69, et6k_bg); 146d983712dSmrg ET6000IOWrite(pTseng, 0x69, et6k_fg); 147d983712dSmrg } else { 148d983712dSmrg /* 149d983712dSmrg * The ET4000 uses color 0 as sprite color "0", and color 0xFF as 150d983712dSmrg * sprite color "1". Changing colors implies changing colors 0 and 151d983712dSmrg * 255. This is currently not implemented. 152d983712dSmrg * 153d983712dSmrg * In non-8bpp modes, this would result in always black and white 154d983712dSmrg * colors (since the colormap isn't there to translate 0 and 255 to 155d983712dSmrg * other colors). And besides, in non-8bpp, there seem to be TWO 156d983712dSmrg * cursor images on the screen... 157d983712dSmrg */ 158d983712dSmrg xf86Msg(X_ERROR, "Internal error: ET4000 hardware cursor color changes not implemented\n"); 159d983712dSmrg } 160d983712dSmrg} 161d983712dSmrg 1624b9470b1Smrgstatic void 163d983712dSmrgTsengLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits) 164d983712dSmrg{ 165d983712dSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 166d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 167d983712dSmrg CARD8 tmp; 168d983712dSmrg 169d983712dSmrg#ifdef DEBUG_HWC 170d983712dSmrg int i; 171d983712dSmrg int d; 172d983712dSmrg 173d983712dSmrg for (i = 0; i < 1024; i++) { 174d983712dSmrg d = *(bits + i); 175d983712dSmrg ErrorF("%d%d%d%d", d & 0x03, (d >> 2) & 0x03, (d >> 4) & 0x03, (d >> 6) & 0x03); 176d983712dSmrg if ((i & 15) == 15) 177d983712dSmrg ErrorF("\n"); 178d983712dSmrg } 179d983712dSmrg#endif 180d983712dSmrg 181d983712dSmrg /* 182d983712dSmrg * Program the cursor image address in video memory. 183d983712dSmrg * We need to set it here or we might loose it on mode/vt switches. 184d983712dSmrg */ 185d983712dSmrg 186d983712dSmrg if (pTseng->ChipType == ET6000) { 187d983712dSmrg /* bits 19:16 */ 188d983712dSmrg tmp = hwp->readCrtc(hwp, 0x0E) & 0xF0; 189d983712dSmrg tmp |= ((pTseng->HWCursorBufferOffset / 4) >> 16) & 0x0F; 190d983712dSmrg hwp->writeCrtc(hwp, 0x0E, tmp); 191d983712dSmrg 192d983712dSmrg /* bits 15:8 */ 193d983712dSmrg hwp->writeCrtc(hwp, 0x0F, ((pTseng->HWCursorBufferOffset / 4) >> 8) & 0xFF); 194d983712dSmrg /* on the ET6000, bits (7:0) are always 0 */ 195d983712dSmrg } else { 196d983712dSmrg /* bits 19:16 */ 197d983712dSmrg tmp = ET4000CursorRead(0xEA) & 0xF0; 198d983712dSmrg ET4000CursorWrite(0xEA, tmp | (((pTseng->HWCursorBufferOffset / 4) >> 16) & 0x0F)); 199d983712dSmrg /* bits 15:8 */ 200d983712dSmrg ET4000CursorWrite(0xE9, ((pTseng->HWCursorBufferOffset / 4) >> 8) & 0xFF); 201d983712dSmrg /* bits 7:0 */ 202d983712dSmrg ET4000CursorWrite(0xE8, (pTseng->HWCursorBufferOffset / 4) & 0xFF); 203d983712dSmrg 204d983712dSmrg /* this needs to be set for the sprite */ 205d983712dSmrg ET4000CursorWrite(0xEB, 0x02); 206d983712dSmrg 207d983712dSmrg tmp = ET4000CursorRead(0xEC); 208d983712dSmrg ET4000CursorWrite(0xEC, tmp & 0xFE); 209d983712dSmrg 210d983712dSmrg tmp = ET4000CursorRead(0xEF) & 0xF8; 211d983712dSmrg ET4000CursorWrite(0xEF, tmp | 0x02); 212d983712dSmrg 213d983712dSmrg ET4000CursorWrite(0xEE, 0x01); 214d983712dSmrg } 215d983712dSmrg /* this assumes the apertures have been set up correctly for banked mode */ 216d983712dSmrg memcpy(pTseng->HWCursorBuffer, bits, 1024); 217d983712dSmrg} 218d983712dSmrg 219d983712dSmrg/* 220d983712dSmrg * 221d983712dSmrg * 222d983712dSmrg */ 223d983712dSmrgBool 224d983712dSmrgTsengHWCursorInit(ScreenPtr pScreen) 225d983712dSmrg{ 2264b9470b1Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 227d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 228d983712dSmrg xf86CursorInfoPtr infoPtr; 229d983712dSmrg 230d983712dSmrg PDEBUG(" TsengHWCursorInit\n"); 231d983712dSmrg 232d983712dSmrg if (!pTseng->HWCursor) 233d983712dSmrg return FALSE; 234d983712dSmrg 235d983712dSmrg infoPtr = xf86CreateCursorInfoRec(); 236d983712dSmrg if (!infoPtr) 237d983712dSmrg return FALSE; 238d983712dSmrg 239d983712dSmrg pTseng->CursorInfoRec = infoPtr; 240d983712dSmrg 241d983712dSmrg /* calculate memory addres from video memory offsets */ 242d983712dSmrg pTseng->HWCursorBuffer = 243d983712dSmrg pTseng->FbBase + pTseng->HWCursorBufferOffset; 244d983712dSmrg 245d983712dSmrg /* set up the XAA HW cursor structure */ 246d983712dSmrg infoPtr->MaxWidth = 64; 247d983712dSmrg infoPtr->MaxHeight = 64; 248d983712dSmrg infoPtr->Flags = 249d983712dSmrg HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 250d983712dSmrg HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | 251d983712dSmrg HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 252d983712dSmrg HARDWARE_CURSOR_INVERT_MASK; 253d983712dSmrg infoPtr->SetCursorColors = TsengSetCursorColors; 254d983712dSmrg infoPtr->SetCursorPosition = TsengSetCursorPosition; 255d983712dSmrg infoPtr->LoadCursorImage = TsengLoadCursorImage; 256d983712dSmrg infoPtr->HideCursor = TsengHideCursor; 257d983712dSmrg infoPtr->ShowCursor = TsengShowCursor; 258d983712dSmrg infoPtr->UseHWCursor = TsengUseHWCursor; 259d983712dSmrg 260d983712dSmrg return (xf86InitCursor(pScreen, infoPtr)); 261d983712dSmrg} 262d983712dSmrg 263d983712dSmrg/* 264d983712dSmrg * 265d983712dSmrg */ 266d983712dSmrgvoid 267d983712dSmrgTsengCursorStore(ScrnInfoPtr pScrn, TsengRegPtr Reg) 268d983712dSmrg{ 269d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 270d983712dSmrg 271d983712dSmrg if (pTseng->ChipType == ET4000) 272d983712dSmrg Reg->CursorCtrl = ET4000CursorRead(0xF7); 273d983712dSmrg} 274d983712dSmrg 275d983712dSmrg/* 276d983712dSmrg * 277d983712dSmrg */ 278d983712dSmrgvoid 279d983712dSmrgTsengCursorRestore(ScrnInfoPtr pScrn, TsengRegPtr Reg) 280d983712dSmrg{ 281d983712dSmrg TsengPtr pTseng = TsengPTR(pScrn); 282d983712dSmrg 283d983712dSmrg if (pTseng->ChipType == ET4000) 284d983712dSmrg ET4000CursorWrite(0xF7, Reg->CursorCtrl); 285d983712dSmrg} 286