diff options
-rw-r--r-- | man/imstt.man | 30 | ||||
-rw-r--r-- | src/imstt.h | 79 | ||||
-rw-r--r-- | src/imstt_accel.c | 224 | ||||
-rw-r--r-- | src/imstt_driver.c | 1297 | ||||
-rw-r--r-- | src/imstt_reg.h | 215 |
5 files changed, 1845 insertions, 0 deletions
diff --git a/man/imstt.man b/man/imstt.man new file mode 100644 index 0000000..377d117 --- /dev/null +++ b/man/imstt.man @@ -0,0 +1,30 @@ +.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/imstt/imstt.man,v 1.2 2001/01/27 18:20:48 dawes Exp $ +.\" shorthand for double quote that works everywhere. +.ds q \N'34' +.TH IMSTT __drivermansuffix__ __vendorversion__ +.SH NAME +imstt \- Integrated Micro Solutions Twin Turbo 128 driver +.SH SYNOPSIS +.nf +.B "Section \*qDevice\*q" +.BI " Identifier \*q" devname \*q +.B " Driver \*qimstt\*q" +\ \ ... +.B EndSection +.fi +.SH DESCRIPTION +.B imstt +is an XFree86 driver for Integrated Micro Solutions Twin Turbo 128 video chips. +THIS MAN PAGE NEEDS TO BE FILLED IN. +.SH SUPPORTED HARDWARE +The +.B imstt +driver supports... +.SH CONFIGURATION DETAILS +Please refer to XF86Config(__filemansuffix__) for general configuration +details. This section only covers configuration details specific to this +driver. +.SH "SEE ALSO" +XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__) +.SH AUTHORS +Authors include: ... diff --git a/src/imstt.h b/src/imstt.h new file mode 100644 index 0000000..b714aaf --- /dev/null +++ b/src/imstt.h @@ -0,0 +1,79 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/imstt/imstt.h,v 1.5 2001/05/16 06:48:09 keithp Exp $ */ + +#ifndef _IMSTT_H +#define _IMSTT_H + +#include "xf86.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" +#include "xaa.h" +#include "xf86_ansic.h" + + +typedef struct _IMSTTRec { + pciVideoPtr PciInfo; + PCITAG PciTag; + EntityInfoPtr pEnt; + CARD32 IOAddress; + CARD32 FBAddress; + unsigned char * FBBase; + unsigned long * MMIOBase; + unsigned char * CMAPBase; + long FBMapSize; + unsigned long videoRam; + unsigned long ramdac; + int rev; + OptionInfoPtr Options; + unsigned int Flags; + CARD32 Bus; + XAAInfoRecPtr AccelInfoRec; +/* xf86CursorInfoPtr CursorInfoRec; */ + Bool NoAccel; + Bool HWCursor; + Bool InitDAC; + Bool FBDev; + int Chipset, ChipRev; + int ydir; + int color; + unsigned long pitch; + unsigned long ll; + unsigned long screen_width; + unsigned long sp; + unsigned long dp; + unsigned long cnt; + unsigned long bltctl; + unsigned short hes; + unsigned short heb; + unsigned short hsb; + unsigned short ht; + unsigned short ves; + unsigned short veb; + unsigned short vsb; + unsigned short vt; + unsigned short vil; + unsigned char pclk_m; + unsigned char pclk_n; + unsigned char pclk_p; + unsigned char mlc[3]; + unsigned char lckl_p[3]; +} IMSTTRec, *IMSTTPtr; + +#if 0 +#define IMSTTTRACE(s) ErrorF(s) +#define IMSTTTRACE1(s,a) ErrorF(s,a) +#else +#define IMSTTTRACE(s) +#define IMSTTTRACE1(s,a) +#endif + +#define IMSTTPTR(p) ((IMSTTPtr)((p)->driverPrivate)) + +#define PCI_IMSTT128 0x9128 /* IMS,tt128mbA */ +#define PCI_IMSTT3D 0x9135 /* IMS,tt3d */ + +#define RAMDAC_IBM 1 +#define RAMDAC_TVP 2 + +Bool IMSTTAccelInit(ScreenPtr pScreen); + +#endif /* _IMSTT_H */ diff --git a/src/imstt_accel.c b/src/imstt_accel.c new file mode 100644 index 0000000..86dca58 --- /dev/null +++ b/src/imstt_accel.c @@ -0,0 +1,224 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/imstt/imstt_accel.c,v 1.6 2001/05/16 06:48:09 keithp Exp $ */ + +/* + * Copyright 2000 Ani Joshi <ajoshi@unixbox.com> + * + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation and + * that the name of Ani Joshi not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Ani Joshi makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ANI JOSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + + +#include "Xarch.h" +#include "xf86.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86_OSproc.h" +#include "xaa.h" +#include "xf86PciInfo.h" + +#include "imstt.h" +#include "imstt_reg.h" + + + +static void IMSTTSync(ScrnInfoPtr pScrn) +{ + IMSTTPtr iptr = IMSTTPTR(pScrn); +/* IMSTTMMIO_VARS(); */ + + while(INREG(IMSTT_SSTATUS) & 0x80); + while(INREG(IMSTT_SSTATUS) & 0x40); + + return; +} + + +static void IMSTTSetupForSolidFill(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + IMSTTPtr iptr = IMSTTPTR(pScrn); +/* IMSTTMMIO_VARS(); */ + + switch (pScrn->depth) { + case 8: + iptr->color = color | (color << 8) | (color << 16) | (color << 24); + break; + case 15: + case 16: + iptr->color = color | (color << 8) | (color << 16); + break; + default: + iptr->color = color; + break; + } +} + + +static void IMSTTSubsequentSolidFillRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h) +{ + IMSTTPtr iptr = IMSTTPTR(pScrn); +/* IMSTTMMIO_VARS(); */ + + x *= (pScrn->bitsPerPixel >> 3); + y *= iptr->ll; + w *= (pScrn->bitsPerPixel >> 3); + h--; + w--; + + while(INREG(IMSTT_SSTATUS) & 0x80); + OUTREG(IMSTT_DSA, x + y); + OUTREG(IMSTT_CNT, (h << 16) | w); + OUTREG(IMSTT_DP_OCTL, iptr->ll); + OUTREG(IMSTT_SP, iptr->ll); + OUTREG(IMSTT_BI, 0xffffffff); + OUTREG(IMSTT_MBC, 0xffffffff); + OUTREG(IMSTT_CLR, iptr->color); + + if (iptr->rev == 2) + OUTREG(IMSTT_BLTCTL, 0x200000); + else + OUTREG(IMSTT_BLTCTL, 0x840); + + while(INREG(IMSTT_SSTATUS) & 0x80); + while(INREG(IMSTT_SSTATUS) & 0x40); +} + + +static void IMSTTSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, + int ydir, int rop, unsigned int planemask, + int trans_color) +{ + IMSTTPtr iptr = IMSTTPTR(pScrn); +/* IMSTTMMIO_VARS(); */ + unsigned long sp, dp, ll; + + iptr->bltctl = 0x05; + + ll = pScrn->displayWidth * (pScrn->bitsPerPixel >> 3); + ll = iptr->ll; + + sp = ll << 16; + + if (xdir < 0) { + iptr->bltctl |= 0x80; + iptr->cnt = 1; + } else { + iptr->cnt = 0; + } + + if (ydir < 0) { + sp |= -(ll) & 0xffff; + dp = -(ll) & 0xffff; + iptr->ydir = 1; + } else { + sp |= ll; + dp = ll; + iptr->ydir = 0; + } + + iptr->sp = sp; + iptr->dp = dp; + iptr->ll = ll; +} + + +static void IMSTTSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int x1, int y1, + int x2, int y2, + int w, int h) +{ + IMSTTPtr iptr = IMSTTPTR(pScrn); +/* IMSTTMMIO_VARS(); */ + unsigned long cnt; + + x1 *= (pScrn->bitsPerPixel >> 3); + x2 *= (pScrn->bitsPerPixel >> 3); + w *= (pScrn->bitsPerPixel >> 3); + w--; + h--; + cnt = h << 16; + + if (iptr->cnt) { + x1 += w; + x2 += w; + cnt |= -(w) & 0xffff; + } + else + cnt |= w; + + if (iptr->ydir) { + y1 += h; + y2 += h; + } + + OUTREG(IMSTT_S1SA, y1 * iptr->ll + x1); + OUTREG(IMSTT_SP, iptr->sp); + OUTREG(IMSTT_DSA, y2 * iptr->ll + x2); + OUTREG(IMSTT_CNT, cnt); + OUTREG(IMSTT_DP_OCTL, iptr->dp); + OUTREG(IMSTT_BLTCTL, iptr->bltctl); + while(INREG(IMSTT_SSTATUS) & 0x80); + while(INREG(IMSTT_SSTATUS) & 0x40); +} + + + +Bool IMSTTAccelInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + IMSTTPtr iptr = IMSTTPTR(pScrn); + XAAInfoRecPtr xaaptr; + + if (!(xaaptr = iptr->AccelInfoRec = XAACreateInfoRec())) + return FALSE; + + iptr->ll = pScrn->displayWidth * (pScrn->bitsPerPixel >> 3); + + switch (pScrn->bitsPerPixel) { + case 16: + iptr->screen_width = iptr->pitch >> 1; + break; + case 24: + case 32: + iptr->screen_width = iptr->pitch >> 2; + break; + default: + iptr->screen_width = iptr->pitch = iptr->ll; + break; + } + + xaaptr->Flags = (PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER); + + xaaptr->Sync = IMSTTSync; + + if (pScrn->bitsPerPixel == 8) { + /* FIXME fills are broken > 8bpp, iptr->color needs to be setup right */ + xaaptr->SetupForSolidFill = IMSTTSetupForSolidFill; + xaaptr->SubsequentSolidFillRect = IMSTTSubsequentSolidFillRect; + } + + xaaptr->ScreenToScreenCopyFlags = NO_TRANSPARENCY; + xaaptr->SetupForScreenToScreenCopy = IMSTTSetupForScreenToScreenCopy; + xaaptr->SubsequentScreenToScreenCopy = IMSTTSubsequentScreenToScreenCopy; + + return XAAInit(pScreen, xaaptr); +} + diff --git a/src/imstt_driver.c b/src/imstt_driver.c new file mode 100644 index 0000000..f0c5a53 --- /dev/null +++ b/src/imstt_driver.c @@ -0,0 +1,1297 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/imstt/imstt_driver.c,v 1.20 2002/09/24 15:23:55 tsi Exp $ */ + +/* + * Copyright 2000 Ani Joshi <ajoshi@unixbox.com> + * + * XFree86 4.0 driver for the Integrated Micro Solutions + * Twin Turbo 128 chipset + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation and + * that the name of Ani Joshi not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Ani Joshi makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ANI JOSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Credits: + * Sigurdur Asgeirsson, Jeffrey Kuskin, Ryan Nielsen + * for their work on imsttfb + * + */ + + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86Version.h" +#include "xf86Resources.h" +#include "xf86fbman.h" +#include "compiler.h" +#include "xaa.h" +#include "mipointer.h" +#include "micmap.h" +#include "mibstore.h" +#include "fbdevhw.h" + +#include "fb.h" + +#include "xf86cmap.h" + +#include "imstt.h" +#include "imstt_reg.h" + + +/* To get it to build on non-PPC */ +#ifndef __powerpc__ +#define eieio() +#endif + +/* + * prototypes + */ +static const OptionInfoRec * IMSTTAvailableOptions(int chipid, int busid); +static void IMSTTIdentify(int flags); +static Bool IMSTTProbe(DriverPtr drv, int flags); +static Bool IMSTTPreInit(ScrnInfoPtr pScrn, int flags); + +#if 0 +static Bool IMSTTEnterVT(int scrnIndex, int flags); +static void IMSTTLeaveVT(int scrnIndex, int flags); +static void IMSTTSave(ScrnInfoPtr pScrn); +#endif +static Bool IMSTTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, + char **argv); +#if 0 +static int IMSTTInternalScreenInit(int scrnIndex, ScreenPtr pScreen); +static ModeStatus IMSTTValidMode(int index, DisplayModePtr mode, + Bool verbose, int flags); +#endif + +static Bool IMSTTMapMem(ScrnInfoPtr pScrn); +static void IMSTTUnmapMem(ScrnInfoPtr pScrn); +static Bool IMSTTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static void IMSTTAdjustFrame(int scrnIndex, int x, int y, int flags); +Bool IMSTTCloseScreen(int scrnIndex, ScreenPtr pScreen); +Bool IMSTTSaveScreen(ScreenPtr pScreen, int mode); +#if 0 +static void IMSTTLoadPalette(ScrnInfoPtr pScrn, int numColors, + int *indicies, LOCO *colors, + VisualPtr pVisual); +#endif +static void IMSTTGetVideoMemSize(ScrnInfoPtr pScrn); +static void IMSTTSetClock(ScrnInfoPtr pScrn, unsigned long mhz); +static void IMSTTWriteMode(ScrnInfoPtr pScrn); + +#define DRIVER_NAME "imstt" +#define DRIVER_VERSION "1.0.0" +#define VERSION_MAJOR 1 +#define VERSION_MINOR 0 +#define PATCHLEVEL 0 +#define IMSTT_VERSION ((VERSION_MAJOR << 24) | \ + (VERSION_MINOR << 16) | \ + PATCHLEVEL) + + +DriverRec IMSTT = +{ + IMSTT_VERSION, + DRIVER_NAME, + IMSTTIdentify, + IMSTTProbe, + IMSTTAvailableOptions, + NULL, + 0 +}; + + +/* supported chipsets */ +static SymTabRec IMSTTChipsets[] = { + { PCI_IMSTT128, "imstt128" }, + { PCI_IMSTT3D, "imstt3d" }, + { -1, NULL } +}; + +static PciChipsets IMSTTPciChipsets[] = { + { PCI_IMSTT128, PCI_IMSTT128, RES_SHARED_VGA }, + { PCI_IMSTT3D, PCI_IMSTT3D, RES_SHARED_VGA }, + { -1, -1, RES_UNDEFINED } +}; + +typedef enum { + OPTION_NOACCEL, + OPTION_SWCURSOR, + OPTION_INITDAC, + OPTION_FBDEV +} IMSTTOpts; + +static const OptionInfoRec IMSTTOptions[] = +{ + { OPTION_NOACCEL, "noaccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SWCURSOR, "swcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_INITDAC, "initdac", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +static const char *fbSymbols[] = { + "fbPictureInit", + "fbScreenInit", + NULL +}; + +static const char *xaaSymbols[] = { + "XAACreateInfoRec", + "XAAInit", + NULL +}; + + +static const char *fbdevHWSymbols[] = { + "fbdevHWAdjustFrame", + "fbdevHWEnterVT", + "fbdevHWGetVidmem", + "fbdevHWInit", + "fbdevHWLeaveVT", + "fbdevHWLoadPalette", + "fbdevHWMapVidmem", + "fbdevHWModeInit", + "fbdevHWSave", + "fbdevHWSwitchMode", + "fbdevHWUnmapMMIO", + "fbdevHWUnmapVidmem", + "fbdevHWUseBuildinMode", + "fbdevHWValidMode", + NULL +}; + + +#ifdef XFree86LOADER + +MODULESETUPPROTO(IMSTTSetup); + +/* +pointer IMSTTSetup(pointer module, pointer opts, int *errmaj, + int *errmin); +*/ + +static XF86ModuleVersionInfo IMSTTVersRec = { + "imstt", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +XF86ModuleData imsttModuleData = { &IMSTTVersRec, IMSTTSetup, NULL }; + +pointer IMSTTSetup(pointer module, pointer opts, int *errmaj, + int *errmin) +{ + static Bool setupDone = FALSE; + + IMSTTTRACE("IMSTTSetup -- begin\n"); + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&IMSTT, module, 0); + LoaderRefSymLists(fbSymbols, xaaSymbols, fbdevHWSymbols, NULL); + return (pointer) 1; + } else { + if (errmaj) + *errmaj = LDR_ONCEONLY; + return NULL; + } + IMSTTTRACE("IMSTTSetup -- end\n"); +} + + +#endif /* XFree86LOADER */ + + +static Bool IMSTTGetRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(IMSTTRec), 1); + return TRUE; +} + + +static void IMSTTFreeRec(ScrnInfoPtr pScrn) +{ + if (!pScrn->driverPrivate) + return; + + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; + IMSTTUnmapMem(pScrn); +} + + +static const OptionInfoRec * IMSTTAvailableOptions(int chipid, int busid) +{ + return IMSTTOptions; +} + + +static void IMSTTIdentify(int flags) +{ + xf86PrintChipsets("IMSTT", "driver (version " DRIVER_VERSION ") for IMS TwinTurbo chipsets ", + IMSTTChipsets); +} + + +static Bool IMSTTProbe(DriverPtr drv, int flags) +{ + int i; + GDevPtr *devSections; + int *usedChips; + int numDevSections; + int numUsed; + Bool foundScreen = FALSE; + + IMSTTTRACE("IMSTTProbe begin\n"); + /* sanity checks */ + if ((numDevSections = xf86MatchDevice("imstt", &devSections)) <= 0) + return FALSE; + if (xf86GetPciVideoInfo() == NULL) + return FALSE; + + numUsed = xf86MatchPciInstances("imstt", PCI_VENDOR_IMS, + IMSTTChipsets, IMSTTPciChipsets, + devSections, numDevSections, drv, + &usedChips); + + xfree(devSections); + + if (numUsed <= 0) + return FALSE; + + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else for (i=0; i<numUsed; i++) { + ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0); + + pScrn->driverVersion = VERSION_MAJOR; + pScrn->driverName = DRIVER_NAME; + pScrn->name = "imstt"; + pScrn->Probe = IMSTTProbe; + pScrn->PreInit = IMSTTPreInit; + pScrn->ScreenInit = IMSTTScreenInit; +/* pScrn->SwitchMode = IMSTTSwitchMode; */ + pScrn->AdjustFrame = IMSTTAdjustFrame; +/* pScrn->EnterVT = IMSTTEnterVT; + pScrn->LeaveVT = IMSTTLeaveVT; */ + pScrn->FreeScreen = NULL; +/* pScrn->ValidMode = IMSTTValidMode; */ + foundScreen = TRUE; + xf86ConfigActivePciEntity(pScrn, usedChips[i], IMSTTPciChipsets, + NULL, NULL, NULL, NULL, NULL); + } + + + IMSTTTRACE("IMSTTProbe end\n"); + + xfree(usedChips); + return foundScreen; +} + + +static Bool IMSTTPreInit(ScrnInfoPtr pScrn, int flags) +{ + EntityInfoPtr pEnt; + IMSTTPtr iptr; + int i; + ClockRangePtr clockRanges; + rgb zeros = {0, 0, 0}; + Gamma gzeros = {0.0, 0.0, 0.0}; + + + if (flags & PROBE_DETECT) + return FALSE; + + pScrn->monitor = pScrn->confScreen->monitor; + + if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb | Support32bppFb | + SupportConvert32to24 | PreferConvert32to24)) + return FALSE; + else { + switch (pScrn->depth) { + case 8: + case 15: + case 16: + case 24: + case 32: + /* OK */ + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by this driver\n", + pScrn->depth); + return FALSE; + } + } + + xf86PrintDepthBpp(pScrn); + + if (pScrn->depth > 8) { + if (!xf86SetWeight(pScrn, zeros, zeros)) + return FALSE; + } + + pScrn->rgbBits = 8; + + if (!xf86SetDefaultVisual(pScrn, -1)) + return FALSE; + + pScrn->progClock = TRUE; + + if (!IMSTTGetRec(pScrn)) + return FALSE; + iptr = IMSTTPTR(pScrn); + + xf86CollectOptions(pScrn, NULL); + + if (!(iptr->Options = xalloc(sizeof(IMSTTOptions)))) + return FALSE; + memcpy(iptr->Options, IMSTTOptions, sizeof(IMSTTOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, iptr->Options); + + if (xf86ReturnOptValBool(iptr->Options, OPTION_NOACCEL, FALSE)) { + iptr->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - acceleration disabled\n"); + } else + iptr->NoAccel = FALSE; +#if 0 + if (xf86ReturnOptValBool(iptr->Options, OPTION_SWCURSOR, FALSE)) + iptr->HWCursor = FALSE; + else + iptr->HWCursor = TRUE; +#else + /* HW cursor support not ready yet... */ + iptr->HWCursor = FALSE; +#endif + + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using %s cursor\n", + iptr->HWCursor ? "HW" : "SW"); + + if (xf86ReturnOptValBool(iptr->Options, OPTION_INITDAC, FALSE)) { + iptr->InitDAC = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: not initalizing DACn"); + } else { + iptr->InitDAC = FALSE; + } + + if (xf86ReturnOptValBool(iptr->Options, OPTION_FBDEV, FALSE)) { + iptr->FBDev = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using framebuffer device\n"); + } else { + iptr->FBDev = FALSE; + } + + /* hack */ + iptr->FBDev = TRUE; + + if (iptr->FBDev) { + if (!xf86LoadSubModule(pScrn, "fbdevhw")) + return FALSE; + xf86LoaderReqSymLists(fbdevHWSymbols, NULL); + if (!fbdevHWInit(pScrn, iptr->PciInfo, NULL)) + return FALSE; + pScrn->SwitchMode = fbdevHWSwitchMode; + pScrn->AdjustFrame = fbdevHWAdjustFrame; + pScrn->EnterVT = fbdevHWEnterVT; + pScrn->LeaveVT = fbdevHWLeaveVT; + pScrn->ValidMode = fbdevHWValidMode; + } + + if (pScrn->numEntities > 1) { + IMSTTFreeRec(pScrn); + return FALSE; + } + + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + if (pEnt->resources) { + xfree(pEnt); + IMSTTFreeRec(pScrn); + return FALSE; + } + + iptr->PciInfo = xf86GetPciInfoForEntity(pEnt->index); + xf86RegisterResources(pEnt->index, NULL, ResNone); + xf86SetOperatingState(resVgaIo, pEnt->index, ResUnusedOpr); + xf86SetOperatingState(resVgaMem, pEnt->index, ResDisableOpr); + + if (pEnt->device->chipset && *pEnt->device->chipset) { + pScrn->chipset = pEnt->device->chipset; + iptr->Chipset = xf86StringToToken(IMSTTChipsets, pScrn->chipset); + } else if (pEnt->device->chipID >= 0) { + iptr->Chipset = pEnt->device->chipID; + pScrn->chipset = (char *)xf86TokenToString(IMSTTChipsets, + iptr->Chipset); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", + iptr->Chipset); + } else { + iptr->Chipset = iptr->PciInfo->chipType; + pScrn->chipset = (char *)xf86TokenToString(IMSTTChipsets, + iptr->Chipset); + } + + if (pEnt->device->chipRev >= 0) { + iptr->ChipRev = pEnt->device->chipRev; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", + iptr->ChipRev); + } else + iptr->ChipRev = iptr->PciInfo->chipRev; + + xfree(pEnt); + + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Chipset: \"%s\"\n", pScrn->chipset); + + iptr->PciTag = pciTag(iptr->PciInfo->bus, iptr->PciInfo->device, + iptr->PciInfo->func); + + if (!xf86SetGamma(pScrn, gzeros)) + return FALSE; + + if (iptr->Chipset == PCI_IMSTT3D) { + iptr->ramdac = RAMDAC_TVP; + iptr->videoRam = 0x800000; + } + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "using %s ramdac\n", iptr->ramdac == RAMDAC_TVP ? "TVP" : "IBM"); + + if (!IMSTTMapMem(pScrn)) { + IMSTTFreeRec(pScrn); + return FALSE; + } + + iptr->rev = (INREG(IMSTT_SSTATUS) & 0x0f00) >> 8; + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "revision %d\n", iptr->rev); + + if (!pScrn->videoRam) { + pScrn->videoRam = iptr->videoRam / 1024; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "probed videoram = %dk\n", + pScrn->videoRam); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "videoram = %dk\n", + pScrn->videoRam / 1024); + } + + /* XXX this is sorta a guess, got some info from the TVP3030 manual */ + pScrn->numClocks = 2; + pScrn->clock[0] = 110000; + pScrn->clock[1] = 220000; + + clockRanges = xnfcalloc(sizeof(ClockRange), 1); + clockRanges->next = NULL; + clockRanges->minClock = 20000; + clockRanges->maxClock = 120000; /* i don't want to blow up anything */ + clockRanges->clockIndex = -1; + clockRanges->interlaceAllowed = FALSE; /* ? */ + clockRanges->doubleScanAllowed = FALSE; /* ? */ + + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, + NULL, 256, 2048, pScrn->bitsPerPixel, + 128, 2048, pScrn->display->virtualX, + pScrn->display->virtualY, + iptr->videoRam, LOOKUP_BEST_REFRESH); + + if (i < 1 && iptr->FBDev) { + fbdevHWUseBuildinMode(pScrn); + pScrn->displayWidth = pScrn->virtualX; /* XXX */ + i = i; + } + + if (i == -1) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes left\n"); + IMSTTFreeRec(pScrn); + return FALSE; + } + + xf86PruneDriverModes(pScrn); + + if (i == 0 || pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + IMSTTFreeRec(pScrn); + return FALSE; + } + + xf86SetCrtcForModes(pScrn, 0); + pScrn->currentMode = pScrn->modes; + xf86PrintModes(pScrn); + xf86SetDpi(pScrn, 0, 0); + + if (!xf86LoadSubModule(pScrn, "fb")) + return FALSE; + + xf86LoaderReqSymLists(fbSymbols, NULL); + + if (!xf86LoadSubModule(pScrn, "xaa")) + return FALSE; + + xf86LoaderReqSymLists(xaaSymbols, NULL); + + IMSTTTRACE("PreInit -- END\n"); + + return TRUE; +} + + + +static Bool IMSTTMapMem(ScrnInfoPtr pScrn) +{ + IMSTTPtr iptr; + + iptr = IMSTTPTR(pScrn); + + iptr->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, iptr->PciTag, + iptr->PciInfo->memBase[0] + 0x800000, + 0x41000); + if (!iptr->MMIOBase) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal error: could not map MMIO\n"); + return FALSE; + } + + IMSTTTRACE1("Mapped MMIO @ 0x%x with size 0x1000\n", iptr->PciInfo->memBase[0] + 0x800000); + + IMSTTGetVideoMemSize(pScrn); + + if (iptr->FBDev) { + iptr->FBBase = fbdevHWMapVidmem(pScrn); + } else { + iptr->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, iptr->PciTag, + iptr->PciInfo->memBase[0], + iptr->videoRam); + } + if (!iptr->FBBase) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal error: could not map framebuffer\n"); + return FALSE; + } + + if (iptr->InitDAC) { + iptr->CMAPBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, iptr->PciTag, + iptr->PciInfo->memBase[0] + 0x840000, + 0x1000); + if (!iptr->CMAPBase) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal error: could not map CMAP\n"); + return FALSE; + } + } + + pScrn->fbOffset = 0; + + return TRUE; +} + + +static void IMSTTUnmapMem(ScrnInfoPtr pScrn) +{ + IMSTTPtr iptr; + + iptr = IMSTTPTR(pScrn); + + if (iptr->FBDev) { + fbdevHWUnmapMMIO(pScrn); + } else { + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)iptr->MMIOBase, + 0x1000); + } + + if (iptr->InitDAC) { + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)iptr->CMAPBase, + 0x1000); + } + + if (iptr->FBDev) { + fbdevHWUnmapVidmem(pScrn); + } else { + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)iptr->FBBase, + iptr->videoRam); + } + + return; +} + + + +static void IMSTTGetVideoMemSize(ScrnInfoPtr pScrn) +{ + IMSTTPtr iptr = IMSTTPTR(pScrn); + unsigned long tmp; + + if (iptr->FBDev) { + iptr->videoRam = fbdevHWGetVidmem(pScrn); + return; + } + + tmp = INREG(IMSTT_PRC); + if (iptr->ramdac == RAMDAC_IBM) + iptr->videoRam = (tmp & 0x0004) ? 0x400000 : 0x200000; + else + iptr->videoRam = 0x800000; + + return; +} + + +static Bool IMSTTScreenInit(int scrnIndex, ScreenPtr pScreen, + int argc, char **argv) +{ + ScrnInfoPtr pScrn; + IMSTTPtr iptr; + unsigned long tmp; + VisualPtr visual; + int r = TRUE; + + IMSTTTRACE("ScreenInit -- Begin\n"); + + pScrn = xf86Screens[pScreen->myNum]; + + iptr = IMSTTPTR(pScrn); + + if (!iptr->FBDev) { + /* initialize the card */ + tmp = INREG(IMSTT_STGCTL); + + OUTREG(IMSTT_STGCTL, tmp & ~0x1); + OUTREG(IMSTT_SSR, 0); + + if (iptr->InitDAC) { + /* set default values for DAC registers */ + if (iptr->ramdac == RAMDAC_IBM) { + iptr->CMAPBase[IBM624_PPMASK] = 0xff; eieio(); + iptr->CMAPBase[IBM624_PIDXHI] = 0; eieio(); + OUTREGPI(IBM624_CLKCTL, 0x21); + OUTREGPI(IBM624_SYNCCTL, 0x00); + OUTREGPI(IBM624_HSYNCPOS, 0x00); + OUTREGPI(IBM624_PWRMNGMT, 0x00); + OUTREGPI(IBM624_DACOP, 0x02); + OUTREGPI(IBM624_PALETCTL, 0x00); + OUTREGPI(IBM624_SYSCLKCTL, 0x01); + OUTREGPI(IBM624_BPP8, 0x00); + OUTREGPI(IBM624_BPP16, 0x01); + OUTREGPI(IBM624_BPP24, 0x00); + OUTREGPI(IBM624_BPP32, 0x00); + OUTREGPI(IBM624_PIXCTL1, 0x05); + OUTREGPI(IBM624_PIXCTL2, 0x00); + OUTREGPI(IBM624_SYSCLKN, 0x08); + OUTREGPI(IBM624_SYSCLKM, 0x4f); + OUTREGPI(IBM624_SYSCLKP, 0x00); + OUTREGPI(IBM624_SYSCLKC, 0x00); + OUTREGPI(IBM624_CURSCTL, 0x00); + OUTREGPI(IBM624_CURSACCTL, 0x01); + OUTREGPI(IBM624_CURSACATTR, 0xa8); + OUTREGPI(IBM624_CURS1R, 0xff); + OUTREGPI(IBM624_CURS1G, 0xff); + OUTREGPI(IBM624_CURS1B, 0xff); + OUTREGPI(IBM624_CURS2R, 0xff); + OUTREGPI(IBM624_CURS2G, 0xff); + OUTREGPI(IBM624_CURS2B, 0xff); + OUTREGPI(IBM624_CURS3R, 0xff); + OUTREGPI(IBM624_CURS3G, 0xff); + OUTREGPI(IBM624_CURS3B, 0xff); + OUTREGPI(IBM624_BORDR, 0xff); + OUTREGPI(IBM624_BORDG, 0xff); + OUTREGPI(IBM624_BORDB, 0xff); + OUTREGPI(IBM624_MISCTL1, 0x01); + OUTREGPI(IBM624_MISCTL2, 0x45); + OUTREGPI(IBM624_MISCTL3, 0x00); + OUTREGPI(IBM624_KEYCTL, 0x00); + } else { + OUTREGPT(TVP_IRICC, 0x00); + OUTREGPT(TVP_IRBRC, 0xe4); + OUTREGPT(TVP_IRLAC, 0x06); + OUTREGPT(TVP_IRTCC, 0x80); + OUTREGPT(TVP_IRMXC, 0x4d); + OUTREGPT(TVP_IRCLS, 0x05); + OUTREGPT(TVP_IRPPG, 0x00); + OUTREGPT(TVP_IRGEC, 0x00); + OUTREGPT(TVP_IRMIC, 0x08); + OUTREGPT(TVP_IRCKL, 0xff); + OUTREGPT(TVP_IRCKH, 0xff); + OUTREGPT(TVP_IRCRL, 0xff); + OUTREGPT(TVP_IRCRH, 0xff); + OUTREGPT(TVP_IRCGL, 0xff); + OUTREGPT(TVP_IRCGH, 0xff); + OUTREGPT(TVP_IRCBL, 0xff); + OUTREGPT(TVP_IRCBH, 0xff); + OUTREGPT(TVP_IRCKC, 0x00); + OUTREGPT(TVP_IRPLA, 0x00); + OUTREGPT(TVP_IRPPD, 0xc0); + OUTREGPT(TVP_IRPPD, 0xd5); + OUTREGPT(TVP_IRPPD, 0xea); + OUTREGPT(TVP_IRPLA, 0x00); + OUTREGPT(TVP_IRMPD, 0xb9); + OUTREGPT(TVP_IRMPD, 0x3a); + OUTREGPT(TVP_IRMPD, 0xb1); + OUTREGPT(TVP_IRPLA, 0x00); + OUTREGPT(TVP_IRLPD, 0xc1); + OUTREGPT(TVP_IRLPD, 0x3d); + OUTREGPT(TVP_IRLPD, 0xf3); + } + } + } + + iptr->pitch = pScrn->displayWidth; + + if (iptr->FBDev) { + if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) + return FALSE; + } else { + if (!IMSTTModeInit(pScrn, pScrn->currentMode)) + return FALSE; + } + + pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + miClearVisualTypes(); + + if (pScrn->bitsPerPixel > 8) { + if (!miSetVisualTypes(pScrn->depth, TrueColorMask, + pScrn->rgbBits, TrueColor)) + return FALSE; + } else { + if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + } + + miSetPixmapDepths (); + + r = fbScreenInit(pScreen, iptr->FBBase, pScrn->virtualX, + pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth, pScrn->bitsPerPixel); + + if (!r) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ScreenInit failed\n"); + return FALSE; + } + + if (pScrn->bitsPerPixel > 8) { + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + + fbPictureInit (pScreen, 0, 0); + + xf86SetBlackWhitePixels(pScreen); + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + if (!iptr->NoAccel) { + if (IMSTTAccelInit(pScreen)) { + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Acceleration initailizatino failed\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); + } + } else { + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); + } + + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + if (!miCreateDefColormap(pScreen)) + return FALSE; + + if (!xf86HandleColormaps(pScreen, 256, 8, fbdevHWLoadPalette, + NULL, CMAP_PALETTED_TRUECOLOR)) + return FALSE; + + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + + pScreen->SaveScreen = IMSTTSaveScreen; + pScreen->CloseScreen = IMSTTCloseScreen; + + IMSTTTRACE("ScreenInit -- End\n"); + + + return TRUE; +} + + + + +static Bool IMSTTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + IMSTTPtr iptr; + unsigned long mhz; + unsigned short hes, heb, veb, htp, vtp; + + iptr = IMSTTPTR(pScrn); + + if (iptr->ramdac == RAMDAC_IBM) { + switch (pScrn->displayWidth) { + case 640: + hes = 0x0008; + heb = 0x0012; + veb = 0x002a; + htp = 10; + vtp = 2; + mhz = 30; + break; + case 832: + hes = 0x0005; + heb = 0x0020; + veb = 0x0028; + htp = 8; + vtp = 3; + mhz = 57; + break; + case 1024: + hes = 0x000a; + heb = 0x001c; + veb = 0x0020; + htp = 8; + vtp = 3; + mhz = 80; + break; + case 1152: + hes = 0x0012; + heb = 0x0022; + veb = 0x0031; + htp = 4; + vtp = 3; + mhz = 101; + break; + case 1280: + hes = 0x0012; + heb = 0x002f; + veb = 0x0029; + htp = 4; + vtp = 1; + mhz = 135; /* XXX check for 1280x960 */ + break; + case 1600: + hes = 0x0018; + heb = 0x0040; + veb = 0x002a; + htp = 4; + vtp = 3; + mhz = 200; + break; + default: + return FALSE; + } + + IMSTTSetClock(pScrn, mhz); + + iptr->hes = hes; + iptr->heb = heb; + iptr->hsb = heb + (pScrn->displayWidth >> 3); + iptr->ht = iptr->hsb + htp; + iptr->ves = 0x0003; + iptr->veb = veb; + iptr->vsb = veb + pScrn->virtualY; + iptr->vt = iptr->vsb + vtp; + iptr->vil = iptr->vsb; + iptr->pitch = pScrn->displayWidth; + } else { + iptr->pitch = pScrn->displayWidth; + switch (pScrn->displayWidth) { + case 640: + iptr->hes = 0x0004; + iptr->heb = 0x0009; + iptr->hsb = 0x0031; + iptr->ht = 0x0036; + iptr->ves = 0x0003; + iptr->veb = 0x002a; + iptr->vsb = 0x020a; + iptr->vt = 0x020d; + iptr->vil = 0x020a; + iptr->pclk_m = 0xef; + iptr->pclk_n = 0x2e; + iptr->pclk_p = 0xb2; + iptr->mlc[0] = 0x39; + iptr->mlc[1] = 0x39; + iptr->mlc[2] = 0x38; + iptr->lckl_p[0] = 0xf3; + iptr->lckl_p[1] = 0xf3; + iptr->lckl_p[2] = 0xf3; + case 800: + iptr->hes = 0x0005; + iptr->heb = 0x000e; + iptr->hsb = 0x0040; + iptr->ht = 0x0042; + iptr->ves = 0x0003; + iptr->veb = 0x0018; + iptr->vsb = 0x0270; + iptr->vt = 0x0271; + iptr->vil = 0x0270; + iptr->pclk_m = 0xf6; + iptr->pclk_n = 0x2e; + iptr->pclk_p = 0xf2; + iptr->mlc[0] = 0x3a; + iptr->mlc[1] = 0x39; + iptr->mlc[2] = 0x38; + iptr->lckl_p[0] = 0xf3; + iptr->lckl_p[1] = 0xf3; + iptr->lckl_p[2] = 0xf3; + case 832: + iptr->hes = 0x0004; + iptr->heb = 0x0011; + iptr->hsb = 0x0045; + iptr->ht = 0x0048; + iptr->ves = 0x0003; + iptr->veb = 0x002a; + iptr->vsb = 0x029a; + iptr->vt = 0x029b; + iptr->vil = 0x0000; + iptr->pclk_m = 0xfe; + iptr->pclk_n = 0x3e; + iptr->pclk_p = 0xf1; + iptr->mlc[0] = 0x39; + iptr->mlc[1] = 0x38; + iptr->mlc[2] = 0x38; + iptr->lckl_p[0] = 0xf3; + iptr->lckl_p[1] = 0xf3; + iptr->lckl_p[2] = 0xf2; + case 1024: + iptr->hes = 0x0006; + iptr->heb = 0x0210; + iptr->hsb = 0x0250; + iptr->ht = 0x0053; + iptr->ves = 0x1003; + iptr->veb = 0x0021; + iptr->vsb = 0x0321; + iptr->vt = 0x0324; + iptr->vil = 0x0000; + iptr->pclk_m = 0xfc; + iptr->pclk_n = 0x3a; + iptr->pclk_p = 0xf1; + iptr->mlc[0] = 0x39; + iptr->mlc[1] = 0x38; + iptr->mlc[2] = 0x38; + iptr->lckl_p[0] = 0xf3; + iptr->lckl_p[1] = 0xf3; + iptr->lckl_p[2] = 0xf2; + case 1152: + iptr->hes = 0x0009; + iptr->heb = 0x0011; + iptr->hsb = 0x0059; + iptr->ht = 0x005b; + iptr->ves = 0x0003; + iptr->veb = 0x0031; + iptr->vsb = 0x0397; + iptr->vt = 0x039a; + iptr->vil = 0x0000; + iptr->pclk_m = 0xfd; + iptr->pclk_n = 0x3a; + iptr->pclk_p = 0xf1; + iptr->mlc[0] = 0x39; + iptr->mlc[1] = 0x38; + iptr->mlc[2] = 0x38; + iptr->lckl_p[0] = 0xf3; + iptr->lckl_p[1] = 0xf3; + iptr->lckl_p[2] = 0xf2; + case 1280: + iptr->hes = 0x0009; + iptr->heb = 0x0018; + iptr->hsb = 0x0068; + iptr->ht = 0x006a; + iptr->ves = 0x0003; + iptr->veb = 0x0029; + iptr->vsb = 0x0429; + iptr->vt = 0x042a; + iptr->vil = 0x0000; + iptr->pclk_m = 0xf0; + iptr->pclk_n = 0x2d; + iptr->pclk_p = 0xf0; + iptr->mlc[0] = 0x38; + iptr->mlc[1] = 0x38; + iptr->mlc[2] = 0x38; + iptr->lckl_p[0] = 0xf3; + iptr->lckl_p[1] = 0xf2; + iptr->lckl_p[2] = 0xf1; + default: + return FALSE; + } + } + + /* do it! */ + IMSTTWriteMode(pScrn); + IMSTTAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + return TRUE; +} + + + + +static void IMSTTSetClock(ScrnInfoPtr pScrn, unsigned long mhz) +{ + IMSTTPtr iptr; + unsigned long clk_m, clk_n, clk_p, x, stage, spilled; + + iptr = IMSTTPTR(pScrn); + clk_m = clk_n = clk_p = 0; + stage = spilled = 0; + + for (;;) { + switch (stage) { + case 0: + clk_m++; + break; + case 1: + clk_n++; + break; + } + x = 20 * (clk_m + 1) / ((clk_n + 1) * (clk_p ? 2 * clk_p : 1)); + if (x == mhz) + break; + if (x > mhz) { + spilled = 1; + stage = 1; + } else if (spilled && x < mhz) { + stage = 0; + } + } + + iptr->pclk_m = clk_m; + iptr->pclk_n = clk_n; + iptr->pclk_p = clk_p; +} + + +static void IMSTTWriteMode(ScrnInfoPtr pScrn) +{ + IMSTTPtr iptr; + unsigned char pixformat; + unsigned long ctl = 0, pitch = 0, byteswap = 0, scr = 0; + unsigned char tcc = 0, mxc = 0, lckl_n = 0, mic, mlc = 0, lckl_p = 0; + + iptr = IMSTTPTR(pScrn); + + pixformat = (pScrn->bitsPerPixel >> 3) + 2; + + if (iptr->InitDAC && (pScrn->bitsPerPixel == 16)) { + if (iptr->ramdac == RAMDAC_IBM) { + iptr->CMAPBase[IBM624_PIDXHI] = 0; eieio(); + iptr->CMAPBase[IBM624_PIDXLO] = IBM624_BPP16; eieio(); + iptr->CMAPBase[IBM624_PIDXDATA] = 0x03; eieio(); + } else { + iptr->CMAPBase[TVP_ADDRW] = TVP_IRTCC; eieio(); + iptr->CMAPBase[TVP_IDATA] = 0x45; eieio(); + } + } + + /* XXX do for 15bpp */ + + if ((iptr->ramdac == RAMDAC_IBM) && (iptr->InitDAC)) { + iptr->CMAPBase[IBM624_PIDXHI] = 0; eieio(); + iptr->CMAPBase[IBM624_PIDXLO] = IBM624_PIXM0; eieio(); + iptr->CMAPBase[IBM624_PIDXDATA] = iptr->pclk_m; eieio(); + iptr->CMAPBase[IBM624_PIDXLO] = IBM624_PIXN0; eieio(); + iptr->CMAPBase[IBM624_PIDXDATA] = iptr->pclk_n; eieio(); + iptr->CMAPBase[IBM624_PIDXLO] = IBM624_PIXP0; eieio(); + iptr->CMAPBase[IBM624_PIDXDATA] = iptr->pclk_p; eieio(); + iptr->CMAPBase[IBM624_PIDXLO] = IBM624_PIXC0; eieio(); + iptr->CMAPBase[IBM624_PIDXDATA] = 0x02; eieio(); + iptr->CMAPBase[IBM624_PIDXLO] = IBM624_PIXFMT; eieio(); + iptr->CMAPBase[IBM624_PIDXDATA] = pixformat; eieio(); + } + + if ((iptr->ramdac == RAMDAC_TVP) && (iptr->InitDAC)) { + switch (pScrn->bitsPerPixel) { + case 8: + tcc = 0x80; + mxc = 0x4d; + lckl_n = 0xc1; + mlc = iptr->mlc[0]; + lckl_p = iptr->lckl_p[0]; + break; + case 16: + tcc = 0x44; + mxc = 0x55; + lckl_n = 0xe1; + mlc = iptr->mlc[1]; + lckl_p = iptr->lckl_p[1]; + break; + case 24: + tcc = 0x5e; + mxc = 0x5d; + lckl_n = 0xf1; + mlc = iptr->mlc[2]; + lckl_p = iptr->lckl_p[2]; + break; + case 32: + tcc = 0x46; + mxc = 0x5d; + lckl_n = 0xf1; + mlc = iptr->mlc[2]; + lckl_p = iptr->lckl_p[2]; + break; + } + + mic = 0x08; + + iptr->CMAPBase[TVP_ADDRW] = TVP_IRPLA; eieio(); + iptr->CMAPBase[TVP_IDATA] = 0x00; eieio(); + iptr->CMAPBase[TVP_ADDRW] = TVP_IRPPD; eieio(); + iptr->CMAPBase[TVP_IDATA] = iptr->pclk_m; eieio(); + iptr->CMAPBase[TVP_ADDRW] = TVP_IRPPD; eieio(); + iptr->CMAPBase[TVP_IDATA] = iptr->pclk_n; eieio(); + iptr->CMAPBase[TVP_ADDRW] = TVP_IRPPD; eieio(); + iptr->CMAPBase[TVP_IDATA] = iptr->pclk_p; eieio(); + iptr->CMAPBase[TVP_ADDRW] = TVP_IRTCC; eieio(); + iptr->CMAPBase[TVP_IDATA] = tcc; eieio(); + iptr->CMAPBase[TVP_ADDRW] = TVP_IRMXC; eieio(); + iptr->CMAPBase[TVP_IDATA] = mxc; eieio(); + iptr->CMAPBase[TVP_ADDRW] = TVP_IRMIC; eieio(); + iptr->CMAPBase[TVP_IDATA] = mic; eieio(); + iptr->CMAPBase[TVP_ADDRW] = TVP_IRPLA; eieio(); + iptr->CMAPBase[TVP_IDATA] = 0x00; eieio(); + iptr->CMAPBase[TVP_ADDRW] = TVP_IRLPD; eieio(); + iptr->CMAPBase[TVP_IDATA] = lckl_n; eieio(); + iptr->CMAPBase[TVP_ADDRW] = TVP_IRPLA; eieio(); + iptr->CMAPBase[TVP_IDATA] = 0x15; eieio(); + iptr->CMAPBase[TVP_ADDRW] = TVP_IRMLC; eieio(); + iptr->CMAPBase[TVP_IDATA] = mlc; eieio(); + iptr->CMAPBase[TVP_ADDRW] = TVP_IRPLA; eieio(); + iptr->CMAPBase[TVP_IDATA] = 0x2a; eieio(); + iptr->CMAPBase[TVP_ADDRW] = TVP_IRLPD; eieio(); + iptr->CMAPBase[TVP_IDATA] = lckl_p; eieio(); + } + + switch (pScrn->bitsPerPixel) { + case 8: + ctl = 0x17b1; + pitch = iptr->pitch >> 2; + byteswap = 0x000; + break; + case 16: + ctl = 0x17b3; + pitch = iptr->pitch >> 1; + byteswap = 0x100; + break; + case 24: + ctl = 0x17b9; + pitch = iptr->pitch - (iptr->pitch >> 2); + byteswap = 0x200; + break; + case 32: + ctl = 0x17b5; + pitch = iptr->pitch; + byteswap = 0x300; + break; + } + + if (iptr->ramdac == RAMDAC_TVP) + ctl -= 0x30; + + OUTREG(IMSTT_HES, iptr->hes); + OUTREG(IMSTT_HEB, iptr->heb); + OUTREG(IMSTT_HSB, iptr->hsb); + OUTREG(IMSTT_HT, iptr->ht); + OUTREG(IMSTT_VES, iptr->ves); + OUTREG(IMSTT_VEB, iptr->veb); + OUTREG(IMSTT_VSB, iptr->vsb); + OUTREG(IMSTT_VT, iptr->vt); + OUTREG(IMSTT_VIL, iptr->vil); + OUTREG(IMSTT_HCIV, 1); + OUTREG(IMSTT_VCIV, 1); + OUTREG(IMSTT_TCDR, 4); + OUTREG(IMSTT_RRCIV, 1); + OUTREG(IMSTT_RRSC, 0x980); + OUTREG(IMSTT_RRCR, 0x11); + + if (iptr->ramdac == RAMDAC_IBM) { + OUTREG(IMSTT_HRIR, 0x0100); + OUTREG(IMSTT_CMR, 0x00ff); + OUTREG(IMSTT_SRGCTL, 0x0073); + } else { + OUTREG(IMSTT_HRIR, 0x0200); + OUTREG(IMSTT_CMR, 0x01ff); + OUTREG(IMSTT_SRGCTL, 0x0003); + } + + switch (iptr->videoRam) { + case 0x200000: + scr = 0x059d | byteswap; + break; + default: + /* 0x400000 and 0x800000 */ + pitch >>= 1; + scr = 0x150dd | byteswap; + break; + } + + OUTREG(IMSTT_SCR, scr); + OUTREG(IMSTT_SPR, pitch); + OUTREG(IMSTT_STGCTL, ctl); + + return; +} + + + +static void IMSTTAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + IMSTTPtr iptr; + unsigned long offset; + + iptr = IMSTTPTR(pScrn); + + offset = y * pScrn->displayWidth + x; + offset &= ~7; + + OUTREG(IMSTT_SSR, offset); + + return; +} + + +Bool IMSTTCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + IMSTTPtr iptr = IMSTTPTR(pScrn); + + if (iptr->FBDev) + fbdevHWSave(pScrn); + + return TRUE; +} + + +Bool IMSTTSaveScreen(ScreenPtr pScreen, int mode) +{ + return TRUE; +} diff --git a/src/imstt_reg.h b/src/imstt_reg.h new file mode 100644 index 0000000..343fb6c --- /dev/null +++ b/src/imstt_reg.h @@ -0,0 +1,215 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/imstt/imstt_reg.h,v 1.5 2002/08/06 19:57:30 herrb Exp $ */ + +#ifndef _IMSTT_REG_H +#define _IMSTT_REG_H + + + +#if defined(__powerpc__) + +static __inline__ void regw(unsigned long base_addr, unsigned long regindex, unsigned long regdata) +{ + asm volatile ("stwbrx %1,%2,%3; eieio" + : "=m" (*(volatile unsigned *)(base_addr+regindex)) + : "r" (regdata), "b" (regindex), "r" (base_addr)); +} + + +static __inline__ unsigned long regr(unsigned long base_addr, unsigned long regindex) +{ + register unsigned long val; + + asm volatile ("lwbrx %0,%1,%2; eieio" + : "=r" (val) + : "b" (regindex), "r" (base_addr), + "m" (*(volatile unsigned *)(base_addr+regindex))); + + return (val); +} + + +#define INREG(addr) regr(((unsigned long)(iptr->MMIOBase)), (addr)) +#define OUTREG(addr, val) regw(((unsigned long)(iptr->MMIOBase)), (addr), (val)) + +#else + +#define INREG(addr) MMIO_IN32(iptr->MMIOBase, addr) +#define OUTREG(addr, val) MMIO_OUT32(iptr->MMIOBase, addr, val) + +#endif + +#define OUTREGPI(addr, val) iptr->CMAPBase[IBM624_PIDXLO] = addr; eieio(); \ + iptr->CMAPBase[IBM624_PIDXDATA] = val; eieio() +#define OUTREGPT(addr, val) iptr->CMAPBase[TVP_ADDRW] = addr; eieio(); \ + iptr->CMAPBase[TVP_IDATA] = val; eieio() + +#define IMSTTMMIO_VARS() \ + unsigned long *IMSTTMMIO = IMSTTPTR(pScrn)->MMIOBase + + +/* TwinTurbo (Cosmo) registers */ + +#define IMSTT_S1SA 0x00 +#define IMSTT_S2SA 0x04 +#define IMSTT_SP 0x08 +#define IMSTT_DSA 0x0c +#define IMSTT_CNT 0x10 +#define IMSTT_DP_OCTL 0x14 +#define IMSTT_CLR 0x18 +#define IMSTT_BI 0x20 +#define IMSTT_MBC 0x24 +#define IMSTT_BLTCTL 0x28 + +/* scan timing generator registers */ + +#define IMSTT_HES 0x30 +#define IMSTT_HEB 0x34 +#define IMSTT_HSB 0x38 +#define IMSTT_HT 0x3c +#define IMSTT_VES 0x40 +#define IMSTT_VEB 0x44 +#define IMSTT_VSB 0x48 +#define IMSTT_VT 0x4c +#define IMSTT_HCIV 0x50 +#define IMSTT_VCIV 0x54 +#define IMSTT_TCDR 0x58 +#define IMSTT_VIL 0x5c +#define IMSTT_STGCTL 0x60 + +/* screen refresh generator registers */ + +#define IMSTT_SSR 0x64 +#define IMSTT_HRIR 0x68 +#define IMSTT_SPR 0x6c +#define IMSTT_CMR 0x70 +#define IMSTT_SRGCTL 0x74 + +/* RAM refresh generator registers */ + +#define IMSTT_RRCIV 0x78 +#define IMSTT_RRSC 0x7c +#define IMSTT_RRCR 0x88 + +/* system registers */ + +#define IMSTT_GIOE 0x80 +#define IMSTT_GIO 0x84 +#define IMSTT_SCR 0x8c +#define IMSTT_SSTATUS 0x90 +#define IMSTT_PRC 0x94 + + +/* IBM 624 RAMDAC direct registers */ + +#define IBM624_PADDRW 0x00 +#define IBM624_PDATA 0x04 +#define IBM624_PPMASK 0x08 +#define IBM624_PADDRR 0x0c +#define IBM624_PIDXLO 0x10 +#define IBM624_PIDXHI 0x14 +#define IBM624_PIDXDATA 0x18 +#define IBM624_PIDXCTL 0x1c + +/* IBM 624 RAMDAC indirect registers */ + +#define IBM624_CLKCTL 0x02 /* Misc Clock Control */ +#define IBM624_SYNCCTL 0x03 /* Sync Control */ +#define IBM624_HSYNCPOS 0x04 /* Horiz Sync Position */ +#define IBM624_PWRMNGMT 0x05 /* Power Management */ +#define IBM624_DACOP 0x06 /* DAC Operation */ +#define IBM624_PALETCTL 0x07 /* Palette Control */ +#define IBM624_SYSCLKCTL 0x08 /* System Clock Control */ +#define IBM624_PIXFMT 0x0a /* Pixel Format [bpp >> 3 + 2] */ +#define IBM624_BPP8 0x0b /* 8bpp */ +#define IBM624_BPP16 0x0c /* 16bpp */ +#define IBM624_BPP24 0x0d /* 24bpp */ +#define IBM624_BPP32 0x0e /* 32bpp */ +#define IBM624_PIXCTL1 0x10 /* Pixel PLL Control 1 */ +#define IBM624_PIXCTL2 0x11 /* Pixel PLL Control 2 */ +#define IBM624_SYSCLKN 0x15 /* System Clock N */ +#define IBM624_SYSCLKM 0x16 /* System Clock M */ +#define IBM624_SYSCLKP 0x17 /* System Clock P */ +#define IBM624_SYSCLKC 0x18 /* System Clock C */ +#define IBM624_PIXM0 0x20 /* Pixel M 0 */ +#define IBM624_PIXN0 0x21 /* Pixel N 0 */ +#define IBM624_PIXP0 0x22 /* Pixel P 0 */ +#define IBM624_PIXC0 0x23 /* Pixel C 0 */ +#define IBM624_CURSCTL 0x30 /* Cursor Control */ +#define IBM624_CURSXLO 0x31 /* Cursor X position, low 8 bits */ +#define IBM624_CURSXHI 0x32 /* Cursor X position, high 8 bits */ +#define IBM624_CURSYLO 0x33 /* Cursor Y position, low 8 bits */ +#define IBM624_CURSYHI 0x34 /* Cursor Y postition, high 8 bits */ +#define IBM624_CURSHOTX 0x35 /* Cursor Hot Spot X */ +#define IBM624_CURSHOTY 0x36 /* Cursor Hot Spot Y */ +#define IBM624_CURSACCTL 0x37 /* Advanced Cursor Control Enable */ +#define IBM624_CURSACATTR 0x38 /* Advanced Cursor Attribute */ +#define IBM624_CURS1R 0x40 /* Cursor 1 red */ +#define IBM624_CURS1G 0x41 /* Cursor 1 green */ +#define IBM624_CURS1B 0x42 /* Cursor 1 blue */ +#define IBM624_CURS2R 0x43 /* Cursor 2 red */ +#define IBM624_CURS2G 0x44 /* Cursor 2 green */ +#define IBM624_CURS2B 0x45 /* Cursor 2 blue */ +#define IBM624_CURS3R 0x46 /* Cursor 3 red */ +#define IBM624_CURS3G 0x47 /* Cursor 3 green */ +#define IBM624_CURS3B 0x48 /* Cursor 3 blue */ +#define IBM624_BORDR 0x60 /* Border color red */ +#define IBM624_BORDG 0x61 /* Border color green */ +#define IBM624_BORDB 0x62 /* Border color blue */ +#define IBM624_MISCTL1 0x70 /* Misc control 1 */ +#define IBM624_MISCTL2 0x71 /* Misc control 2 */ +#define IBM624_MISCTL3 0x72 /* Misc control 3 */ +#define IBM624_KEYCTL 0x78 /* Key Control/DB operation */ + +/* TI TVP 3030 RAMDAC direct registers */ + +#define TVP_ADDRW 0x00 +#define TVP_PDATA 0x04 +#define TVP_PMASK 0x08 +#define TVP_PADRR 0x0c +#define TVP_CADRW 0x10 +#define TVP_CDATA 0x14 +#define TVP_CADRR 0x1c +#define TVP_DCCTL 0x24 +#define TVP_IDATA 0x28 +#define TVP_CRDAT 0x2c +#define TVP_CXPOL 0x30 +#define TVP_CXPOH 0x34 +#define TVP_CYPOL 0x38 +#define TVP_CYPOH 0x3c + +/* TI TVP 3030 RAMDAC indirect registers */ + + +#define TVP_IRREV 0x01 +#define TVP_IRICC 0x06 +#define TVP_IRBRC 0x07 +#define TVP_IRLAC 0x0f +#define TVP_IRTCC 0x18 +#define TVP_IRMXC 0x19 +#define TVP_IRCLS 0x1a +#define TVP_IRPPG 0x1c +#define TVP_IRGEC 0x1d +#define TVP_IRMIC 0x1e +#define TVP_IRPLA 0x2c +#define TVP_IRPPD 0x2d +#define TVP_IRMPD 0x2e +#define TVP_IRLPD 0x2f +#define TVP_IRCKL 0x30 +#define TVP_IRCKH 0x31 +#define TVP_IRCRL 0x32 +#define TVP_IRCRH 0x33 +#define TVP_IRCGL 0x34 +#define TVP_IRCGH 0x35 +#define TVP_IRCBL 0x36 +#define TVP_IRCBH 0x37 +#define TVP_IRCKC 0x38 +#define TVP_IRMLC 0x39 +#define TVP_IRSEN 0x3a +#define TVP_IRTMD 0x3b +#define TVP_IRRML 0x3c +#define TVP_IRRMM 0x3d +#define TVP_IRRMS 0x3e +#define TVP_IRDID 0x3f +#define TVP_IRRES 0xff + +#endif /* _IMSTT_REG_H */ |