1340e3fbdSmrg/* 2340e3fbdSmrg * Copyright 2001 Ani Joshi <ajoshi@unixbox.com> 3340e3fbdSmrg * 4340e3fbdSmrg * XFree86 4.x driver for S3 chipsets 5340e3fbdSmrg * 6340e3fbdSmrg * 7340e3fbdSmrg * Permission to use, copy, modify, distribute, and sell this software and its 8340e3fbdSmrg * documentation for any purpose is hereby granted without fee, provided that 9340e3fbdSmrg * the above copyright notice appear in all copies and that both that copyright 10340e3fbdSmrg * notice and this permission notice appear in supporting documentation and 11340e3fbdSmrg * that the name of Ani Joshi not be used in advertising or 12340e3fbdSmrg * publicity pertaining to distribution of the software without specific, 13340e3fbdSmrg * written prior permission. Ani Joshi makes no representations 14340e3fbdSmrg * about the suitability of this software for any purpose. It is provided 15340e3fbdSmrg * "as-is" without express or implied warranty. 16340e3fbdSmrg * 17340e3fbdSmrg * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18340e3fbdSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19340e3fbdSmrg * EVENT SHALL ANI JOSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20340e3fbdSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21340e3fbdSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22340e3fbdSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23340e3fbdSmrg * PERFORMANCE OF THIS SOFTWARE. 24340e3fbdSmrg * 25340e3fbdSmrg * 26340e3fbdSmrg */ 27340e3fbdSmrg 28340e3fbdSmrg#ifdef HAVE_CONFIG_H 29340e3fbdSmrg#include "config.h" 30340e3fbdSmrg#endif 31340e3fbdSmrg 32340e3fbdSmrg#include "xf86.h" 33340e3fbdSmrg#include "xf86_OSproc.h" 34340e3fbdSmrg 35340e3fbdSmrg#include "compiler.h" 36340e3fbdSmrg 37340e3fbdSmrg#include "s3.h" 38340e3fbdSmrg#include "s3_reg.h" 39340e3fbdSmrg 40340e3fbdSmrg 41340e3fbdSmrgstatic void S3SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 42340e3fbdSmrg{ 43340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 44340e3fbdSmrg int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 45340e3fbdSmrg unsigned short packfg, packbg; 46340e3fbdSmrg 47340e3fbdSmrg switch (pS3->s3Bpp) { 48340e3fbdSmrg case 1: 49340e3fbdSmrg /* XXX Trio series only */ 50340e3fbdSmrg outb(vgaCRIndex, 0x45); 51340e3fbdSmrg inb(vgaCRReg); 52340e3fbdSmrg outb(vgaCRIndex, 0x4a); 53340e3fbdSmrg outb(vgaCRReg, fg); 54340e3fbdSmrg outb(vgaCRReg, fg); 55340e3fbdSmrg 56340e3fbdSmrg outb(vgaCRIndex, 0x45); 57340e3fbdSmrg inb(vgaCRReg); 58340e3fbdSmrg outb(vgaCRIndex, 0x4b); 59340e3fbdSmrg outb(vgaCRReg, bg); 60340e3fbdSmrg outb(vgaCRReg, bg); 61340e3fbdSmrg 62340e3fbdSmrg break; 63340e3fbdSmrg case 2: 64340e3fbdSmrg /* XXX depth 16 */ 65340e3fbdSmrg packfg = ((fg & 0x00f80000) >> 19) | ((fg & 0x0000fc00) >> 5) | 66340e3fbdSmrg ((fg & 0x000000f8) << 8); 67340e3fbdSmrg packbg = ((bg & 0x00f80000) >> 19) | ((bg & 0x0000fc00) >> 5) | 68340e3fbdSmrg ((bg & 0x000000f8) << 8); 69340e3fbdSmrg 70340e3fbdSmrg outb(vgaCRIndex, 0x45); 71340e3fbdSmrg inb(vgaCRReg); 72340e3fbdSmrg outb(vgaCRIndex, 0x4a); 73340e3fbdSmrg outb(vgaCRReg, packfg); 74340e3fbdSmrg outb(vgaCRReg, packfg >> 8); 75340e3fbdSmrg 76340e3fbdSmrg outb(vgaCRIndex, 0x45); 77340e3fbdSmrg inb(vgaCRReg); 78340e3fbdSmrg outb(vgaCRIndex, 0x4b); 79340e3fbdSmrg outb(vgaCRReg, packbg); 80340e3fbdSmrg outb(vgaCRReg, packbg >> 8); 81340e3fbdSmrg 82340e3fbdSmrg break; 83340e3fbdSmrg default: 84340e3fbdSmrg outb(vgaCRIndex, 0x45); 85340e3fbdSmrg inb(vgaCRReg); 86340e3fbdSmrg outb(vgaCRIndex, 0x4a); 87340e3fbdSmrg outb(vgaCRReg, (fg & 0x00ff0000) >> 16); 88340e3fbdSmrg outb(vgaCRReg, (fg & 0x0000ff00) >> 8); 89340e3fbdSmrg outb(vgaCRReg, (fg & 0x000000ff)); 90340e3fbdSmrg 91340e3fbdSmrg outb(vgaCRIndex, 0x45); 92340e3fbdSmrg inb(vgaCRReg); 93340e3fbdSmrg outb(vgaCRIndex, 0x4b); 94340e3fbdSmrg outb(vgaCRReg, (bg & 0x00ff0000) >> 16); 95340e3fbdSmrg outb(vgaCRReg, (bg & 0x0000ff00) >> 8); 96340e3fbdSmrg outb(vgaCRReg, (bg & 0x000000ff)); 97340e3fbdSmrg 98340e3fbdSmrg break; 99340e3fbdSmrg } 100340e3fbdSmrg} 101340e3fbdSmrg 102340e3fbdSmrg 103340e3fbdSmrgstatic void S3SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 104340e3fbdSmrg{ 105340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 106340e3fbdSmrg int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 107340e3fbdSmrg 108340e3fbdSmrg outb(vgaCRIndex, 0x39); 109340e3fbdSmrg outb(vgaCRReg, 0xa5); 110340e3fbdSmrg 111340e3fbdSmrg outb(vgaCRIndex, 0x46); 112340e3fbdSmrg outb(vgaCRReg, x >> 8); 113340e3fbdSmrg outb(vgaCRIndex, 0x47); 114340e3fbdSmrg outb(vgaCRReg, x); 115340e3fbdSmrg 116340e3fbdSmrg outb(vgaCRIndex, 0x49); 117340e3fbdSmrg outb(vgaCRReg, y); 118340e3fbdSmrg outb(vgaCRIndex, 0x48); 119340e3fbdSmrg outb(vgaCRReg, y >> 8); 120340e3fbdSmrg} 121340e3fbdSmrg 122340e3fbdSmrg 123340e3fbdSmrgstatic void S3HideCursor(ScrnInfoPtr pScrn) 124340e3fbdSmrg{ 125340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 126340e3fbdSmrg int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 127340e3fbdSmrg unsigned char tmp; 128340e3fbdSmrg 129340e3fbdSmrg outb(vgaCRIndex, 0x45); 130340e3fbdSmrg tmp = inb(vgaCRReg); 131340e3fbdSmrg outb(vgaCRReg, tmp & ~0x01); 132340e3fbdSmrg} 133340e3fbdSmrg 134340e3fbdSmrg 135340e3fbdSmrgstatic void S3ShowCursor(ScrnInfoPtr pScrn) 136340e3fbdSmrg{ 137340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 138340e3fbdSmrg int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 139340e3fbdSmrg unsigned char tmp; 140340e3fbdSmrg 141340e3fbdSmrg outb(vgaCRIndex, 0x39); 142340e3fbdSmrg outb(vgaCRReg, 0xa5); 143340e3fbdSmrg 144340e3fbdSmrg outb(vgaCRIndex, 0x55); 145340e3fbdSmrg tmp = inb(vgaCRReg); 146340e3fbdSmrg outb(vgaCRReg, tmp | 0x10); 147340e3fbdSmrg 148340e3fbdSmrg outb(vgaCRIndex, 0x4c); 149340e3fbdSmrg outb(vgaCRReg, pS3->FBCursorOffset >> 8); 150340e3fbdSmrg outb(vgaCRIndex, 0x4d); 151340e3fbdSmrg outb(vgaCRReg, pS3->FBCursorOffset); 152340e3fbdSmrg 153340e3fbdSmrg outb(vgaCRIndex, 0x45); 154340e3fbdSmrg tmp = inb(vgaCRReg); 155340e3fbdSmrg outb(vgaCRReg, tmp | 0x01); 156340e3fbdSmrg} 157340e3fbdSmrg 158340e3fbdSmrg 159340e3fbdSmrgstatic void S3LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image) 160340e3fbdSmrg{ 161340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 162340e3fbdSmrg int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 163340e3fbdSmrg unsigned char cr45; 164340e3fbdSmrg 165340e3fbdSmrg outb(vgaCRIndex, 0x39); 166340e3fbdSmrg outb(vgaCRReg, 0xa5); 167340e3fbdSmrg 168340e3fbdSmrg WaitIdle(); 169340e3fbdSmrg 170340e3fbdSmrg VerticalRetraceWait(); 171340e3fbdSmrg 172340e3fbdSmrg outb(vgaCRIndex, 0x45); 173340e3fbdSmrg cr45 = inb(vgaCRReg); 174340e3fbdSmrg outb(vgaCRReg, cr45 & 0xfe); 175340e3fbdSmrg 176340e3fbdSmrg outb(vgaCRIndex, 0x46); 177340e3fbdSmrg outb(vgaCRReg, 0xff); 178340e3fbdSmrg outb(vgaCRIndex, 0x47); 179340e3fbdSmrg outb(vgaCRReg, 0x7f); 180340e3fbdSmrg outb(vgaCRIndex, 0x49); 181340e3fbdSmrg outb(vgaCRReg, 0xff); 182340e3fbdSmrg outb(vgaCRIndex, 0x4e); 183340e3fbdSmrg outb(vgaCRReg, 0x3f); 184340e3fbdSmrg outb(vgaCRIndex, 0x4f); 185340e3fbdSmrg outb(vgaCRReg, 0x3f); 186340e3fbdSmrg outb(vgaCRIndex, 0x48); 187340e3fbdSmrg outb(vgaCRReg, 0x7f); 188340e3fbdSmrg 189340e3fbdSmrg memcpy(pS3->FBBase + (pS3->FBCursorOffset * 1024), image, 1024); 190340e3fbdSmrg 191340e3fbdSmrg VerticalRetraceWait(); 192340e3fbdSmrg 193340e3fbdSmrg outb(vgaCRIndex, 0x45); 194340e3fbdSmrg outb(vgaCRReg, cr45); 195340e3fbdSmrg} 196340e3fbdSmrg 197340e3fbdSmrg 198340e3fbdSmrgstatic Bool S3UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 199340e3fbdSmrg{ 200b27e1915Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 201340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 202340e3fbdSmrg return (pS3->hwCursor); 203340e3fbdSmrg} 204340e3fbdSmrg 205340e3fbdSmrg 206340e3fbdSmrgBool S3_CursorInit(ScreenPtr pScreen) 207340e3fbdSmrg{ 208b27e1915Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 209340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 210340e3fbdSmrg xf86CursorInfoPtr pCurs; 211340e3fbdSmrg 212340e3fbdSmrg if (!(pCurs = pS3->pCurs = xf86CreateCursorInfoRec())) 213340e3fbdSmrg return FALSE; 214340e3fbdSmrg 215340e3fbdSmrg pCurs->MaxWidth = 64; 216340e3fbdSmrg pCurs->MaxHeight = 64; 217340e3fbdSmrg pCurs->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 218340e3fbdSmrg HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | 219340e3fbdSmrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST; 220340e3fbdSmrg 221340e3fbdSmrg pCurs->SetCursorColors = S3SetCursorColors; 222340e3fbdSmrg pCurs->SetCursorPosition = S3SetCursorPosition; 223340e3fbdSmrg pCurs->LoadCursorImage = S3LoadCursorImage; 224340e3fbdSmrg pCurs->HideCursor = S3HideCursor; 225340e3fbdSmrg pCurs->ShowCursor = S3ShowCursor; 226340e3fbdSmrg pCurs->UseHWCursor = S3UseHWCursor; 227340e3fbdSmrg 228340e3fbdSmrg return xf86InitCursor(pScreen, pCurs); 229340e3fbdSmrg} 230340e3fbdSmrg 231