imstt_driver.c revision 53e90a53
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/imstt/imstt_driver.c,v 1.20 2002/09/24 15:23:55 tsi Exp $ */
2
3/*
4 *	Copyright 2000	Ani Joshi <ajoshi@unixbox.com>
5 *
6 *	XFree86 4.0 driver for the Integrated Micro Solutions
7 *		Twin Turbo 128 chipset
8 *
9 * Permission to use, copy, modify, distribute, and sell this software and its
10 * documentation for any purpose is hereby granted without fee, provided that
11 * the above copyright notice appear in all copies and that both that copyright
12 * notice and this permission notice appear in supporting documentation and
13 * that the name of Ani Joshi not be used in advertising or
14 * publicity pertaining to distribution of the software without specific,
15 * written prior permission.  Ani Joshi makes no representations
16 * about the suitability of this software for any purpose.  It is provided
17 * "as-is" without express or implied warranty.
18 *
19 * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
20 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
21 * EVENT SHALL ANI JOSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR
22 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
23 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
24 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
25 * PERFORMANCE OF THIS SOFTWARE.
26 *
27 *	Credits:
28 *		Sigurdur Asgeirsson, Jeffrey Kuskin, Ryan Nielsen
29 *		for their work on imsttfb
30 *
31 */
32
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36
37#include <string.h>
38#include "xf86.h"
39#include "xf86_OSproc.h"
40#include "xf86PciInfo.h"
41#include "xf86Pci.h"
42#include "xf86Version.h"
43#include "xf86Resources.h"
44#include "xf86fbman.h"
45#include "compiler.h"
46#include "xaa.h"
47#include "mipointer.h"
48#include "micmap.h"
49#include "mibstore.h"
50#include "fbdevhw.h"
51
52#include "fb.h"
53
54#include "xf86cmap.h"
55
56#include "imstt.h"
57#include "imstt_reg.h"
58
59
60/* To get it to build on non-PPC */
61#ifndef __powerpc__
62#define eieio()
63#endif
64
65/*
66 * prototypes
67 */
68static const OptionInfoRec * IMSTTAvailableOptions(int chipid, int busid);
69static void IMSTTIdentify(int flags);
70static Bool IMSTTProbe(DriverPtr drv, int flags);
71static Bool IMSTTPreInit(ScrnInfoPtr pScrn, int flags);
72
73#if 0
74static Bool IMSTTEnterVT(int scrnIndex, int flags);
75static void IMSTTLeaveVT(int scrnIndex, int flags);
76static void IMSTTSave(ScrnInfoPtr pScrn);
77#endif
78static Bool IMSTTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
79			    char **argv);
80#if 0
81static int IMSTTInternalScreenInit(int scrnIndex, ScreenPtr pScreen);
82static ModeStatus IMSTTValidMode(int index, DisplayModePtr mode,
83				 Bool verbose, int flags);
84#endif
85
86static Bool IMSTTMapMem(ScrnInfoPtr pScrn);
87static void IMSTTUnmapMem(ScrnInfoPtr pScrn);
88static Bool IMSTTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
89static void IMSTTAdjustFrame(int scrnIndex, int x, int y, int flags);
90Bool IMSTTCloseScreen(int scrnIndex, ScreenPtr pScreen);
91Bool IMSTTSaveScreen(ScreenPtr pScreen, int mode);
92#if 0
93static void IMSTTLoadPalette(ScrnInfoPtr pScrn, int numColors,
94			     int *indicies, LOCO *colors,
95			     VisualPtr pVisual);
96#endif
97static void IMSTTGetVideoMemSize(ScrnInfoPtr pScrn);
98static void IMSTTSetClock(ScrnInfoPtr pScrn, unsigned long mhz);
99static void IMSTTWriteMode(ScrnInfoPtr pScrn);
100
101#define DRIVER_NAME	"imstt"
102#define DRIVER_VERSION	"1.1.0"
103#define VERSION_MAJOR	1
104#define VERSION_MINOR	1
105#define PATCHLEVEL	0
106#define IMSTT_VERSION	((VERSION_MAJOR << 24) | \
107			 (VERSION_MINOR << 16) | \
108			 PATCHLEVEL)
109
110
111_X_EXPORT DriverRec IMSTT =
112{
113	IMSTT_VERSION,
114	DRIVER_NAME,
115	IMSTTIdentify,
116	IMSTTProbe,
117	IMSTTAvailableOptions,
118	NULL,
119	0
120};
121
122
123/* supported chipsets */
124static SymTabRec IMSTTChipsets[] = {
125	{ PCI_IMSTT128,	"imstt128" },
126	{ PCI_IMSTT3D,	"imstt3d" },
127	{ -1,		NULL }
128};
129
130static PciChipsets IMSTTPciChipsets[] = {
131	{ PCI_IMSTT128,	PCI_IMSTT128,	RES_SHARED_VGA },
132	{ PCI_IMSTT3D,	PCI_IMSTT3D,	RES_SHARED_VGA },
133	{ -1,		-1,		RES_UNDEFINED }
134};
135
136typedef enum {
137	OPTION_NOACCEL,
138	OPTION_SWCURSOR,
139	OPTION_INITDAC,
140	OPTION_FBDEV
141} IMSTTOpts;
142
143static const OptionInfoRec IMSTTOptions[] =
144{
145	{ OPTION_NOACCEL, "noaccel", OPTV_BOOLEAN, {0}, FALSE },
146	{ OPTION_SWCURSOR, "swcursor", OPTV_BOOLEAN, {0}, FALSE },
147	{ OPTION_INITDAC, "initdac", OPTV_BOOLEAN, {0}, FALSE },
148	{ OPTION_FBDEV,	"UseFBDev", OPTV_BOOLEAN, {0}, FALSE },
149	{ -1, NULL, OPTV_NONE, {0}, FALSE }
150};
151
152static const char *fbSymbols[] = {
153	"fbPictureInit",
154	"fbScreenInit",
155	NULL
156};
157
158static const char *xaaSymbols[] = {
159	"XAACreateInfoRec",
160	"XAAInit",
161	NULL
162};
163
164
165static const char *fbdevHWSymbols[] = {
166	"fbdevHWAdjustFrameWeak",
167	"fbdevHWEnterVTWeak",
168	"fbdevHWGetVidmem",
169	"fbdevHWInit",
170	"fbdevHWLeaveVTWeak",
171	"fbdevHWLoadPaletteWeak",
172	"fbdevHWMapVidmem",
173	"fbdevHWModeInit",
174	"fbdevHWSave",
175	"fbdevHWSwitchModeWeak",
176	"fbdevHWUnmapMMIO",
177	"fbdevHWUnmapVidmem",
178	"fbdevHWUseBuildinMode",
179	"fbdevHWValidModeWeak",
180	NULL
181};
182
183
184#ifdef XFree86LOADER
185
186MODULESETUPPROTO(IMSTTSetup);
187
188/*
189pointer IMSTTSetup(pointer module, pointer opts, int *errmaj,
190			  int *errmin);
191*/
192
193static XF86ModuleVersionInfo IMSTTVersRec = {
194	"imstt",
195	MODULEVENDORSTRING,
196	MODINFOSTRING1,
197	MODINFOSTRING2,
198	XORG_VERSION_CURRENT,
199	VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL,
200	ABI_CLASS_VIDEODRV,
201	ABI_VIDEODRV_VERSION,
202	MOD_CLASS_VIDEODRV,
203	{0, 0, 0, 0}
204};
205
206_X_EXPORT XF86ModuleData imsttModuleData = { &IMSTTVersRec, IMSTTSetup, NULL };
207
208pointer IMSTTSetup(pointer module, pointer opts, int *errmaj,
209			  int *errmin)
210{
211	static Bool setupDone = FALSE;
212
213	IMSTTTRACE("IMSTTSetup -- begin\n");
214	if (!setupDone) {
215		setupDone = TRUE;
216		xf86AddDriver(&IMSTT, module, 0);
217		LoaderRefSymLists(fbSymbols, xaaSymbols, fbdevHWSymbols, NULL);
218		return (pointer) 1;
219	} else {
220		if (errmaj)
221			*errmaj = LDR_ONCEONLY;
222		return NULL;
223	}
224	IMSTTTRACE("IMSTTSetup -- end\n");
225}
226
227
228#endif /* XFree86LOADER */
229
230
231static Bool IMSTTGetRec(ScrnInfoPtr pScrn)
232{
233	if (pScrn->driverPrivate)
234		return TRUE;
235
236	pScrn->driverPrivate = xnfcalloc(sizeof(IMSTTRec), 1);
237	return TRUE;
238}
239
240
241static void IMSTTFreeRec(ScrnInfoPtr pScrn)
242{
243	if (!pScrn->driverPrivate)
244		return;
245
246	xfree(pScrn->driverPrivate);
247	pScrn->driverPrivate = NULL;
248	IMSTTUnmapMem(pScrn);
249}
250
251
252static const OptionInfoRec * IMSTTAvailableOptions(int chipid, int busid)
253{
254	return IMSTTOptions;
255}
256
257
258static void IMSTTIdentify(int flags)
259{
260	xf86PrintChipsets("IMSTT", "driver (version " DRIVER_VERSION ") for IMS TwinTurbo chipsets ",
261			  IMSTTChipsets);
262}
263
264
265static Bool IMSTTProbe(DriverPtr drv, int flags)
266{
267	int i;
268	GDevPtr *devSections;
269	int *usedChips;
270	int numDevSections;
271	int numUsed;
272	Bool foundScreen = FALSE;
273
274	IMSTTTRACE("IMSTTProbe begin\n");
275	/* sanity checks */
276	if ((numDevSections = xf86MatchDevice("imstt", &devSections)) <= 0)
277		return FALSE;
278	if (xf86GetPciVideoInfo() == NULL)
279		return FALSE;
280
281	numUsed = xf86MatchPciInstances("imstt", PCI_VENDOR_IMS,
282					IMSTTChipsets, IMSTTPciChipsets,
283					devSections, numDevSections, drv,
284					&usedChips);
285
286	xfree(devSections);
287
288	if (numUsed <= 0)
289		return FALSE;
290
291	if (flags & PROBE_DETECT)
292		foundScreen = TRUE;
293	else for (i=0; i<numUsed; i++) {
294		ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0);
295
296		pScrn->driverVersion = VERSION_MAJOR;
297		pScrn->driverName = DRIVER_NAME;
298		pScrn->name = "imstt";
299		pScrn->Probe = IMSTTProbe;
300		pScrn->PreInit = IMSTTPreInit;
301		pScrn->ScreenInit = IMSTTScreenInit;
302/*		pScrn->SwitchMode = IMSTTSwitchMode; */
303		pScrn->AdjustFrame = IMSTTAdjustFrame;
304/*		pScrn->EnterVT = IMSTTEnterVT;
305		pScrn->LeaveVT = IMSTTLeaveVT; */
306		pScrn->FreeScreen = NULL;
307/*		pScrn->ValidMode = IMSTTValidMode; */
308		foundScreen = TRUE;
309		xf86ConfigActivePciEntity(pScrn, usedChips[i], IMSTTPciChipsets,
310					  NULL, NULL, NULL, NULL, NULL);
311	}
312
313
314	IMSTTTRACE("IMSTTProbe end\n");
315
316	xfree(usedChips);
317	return foundScreen;
318}
319
320
321static Bool IMSTTPreInit(ScrnInfoPtr pScrn, int flags)
322{
323	EntityInfoPtr pEnt;
324	IMSTTPtr iptr;
325	int i;
326	ClockRangePtr clockRanges;
327	rgb zeros = {0, 0, 0};
328	Gamma gzeros = {0.0, 0.0, 0.0};
329
330
331	if (flags & PROBE_DETECT)
332		return FALSE;
333
334	pScrn->monitor = pScrn->confScreen->monitor;
335
336	if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb |
337			     SupportConvert32to24 | PreferConvert32to24))
338		return FALSE;
339	else {
340		switch (pScrn->depth) {
341		case 8:
342		case 15:
343		case 16:
344		case 24:
345		case 32:
346			/* OK */
347			break;
348		default:
349			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
350				   "Given depth (%d) is not supported by this driver\n",
351				    pScrn->depth);
352			return FALSE;
353		}
354	}
355
356	xf86PrintDepthBpp(pScrn);
357
358	if (pScrn->depth > 8) {
359		if (!xf86SetWeight(pScrn, zeros, zeros))
360			return FALSE;
361	}
362
363	pScrn->rgbBits = 8;
364
365	if (!xf86SetDefaultVisual(pScrn, -1))
366		return FALSE;
367
368	pScrn->progClock = TRUE;
369
370	if (!IMSTTGetRec(pScrn))
371		return FALSE;
372	iptr = IMSTTPTR(pScrn);
373
374	xf86CollectOptions(pScrn, NULL);
375
376	if (!(iptr->Options = xalloc(sizeof(IMSTTOptions))))
377		return FALSE;
378	memcpy(iptr->Options, IMSTTOptions, sizeof(IMSTTOptions));
379	xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, iptr->Options);
380
381	if (xf86ReturnOptValBool(iptr->Options, OPTION_NOACCEL, FALSE)) {
382		iptr->NoAccel = TRUE;
383		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - acceleration disabled\n");
384	} else
385		iptr->NoAccel = FALSE;
386#if 0
387	if (xf86ReturnOptValBool(iptr->Options, OPTION_SWCURSOR, FALSE))
388		iptr->HWCursor = FALSE;
389	else
390		iptr->HWCursor = TRUE;
391#else
392	/* HW cursor support not ready yet... */
393	iptr->HWCursor = FALSE;
394#endif
395
396	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using %s cursor\n",
397		   iptr->HWCursor ? "HW" : "SW");
398
399	if (xf86ReturnOptValBool(iptr->Options, OPTION_INITDAC, FALSE)) {
400		iptr->InitDAC = TRUE;
401		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: not initalizing DACn");
402	} else {
403		iptr->InitDAC = FALSE;
404	}
405
406	if (xf86ReturnOptValBool(iptr->Options, OPTION_FBDEV, FALSE)) {
407		iptr->FBDev = TRUE;
408		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
409			   "Using framebuffer device\n");
410	} else {
411		iptr->FBDev = FALSE;
412	}
413
414	/* hack */
415	iptr->FBDev = TRUE;
416
417	if (iptr->FBDev) {
418		if (!xf86LoadSubModule(pScrn, "fbdevhw"))
419			return FALSE;
420		xf86LoaderReqSymLists(fbdevHWSymbols, NULL);
421		if (!fbdevHWInit(pScrn, iptr->PciInfo, NULL))
422			return FALSE;
423		pScrn->SwitchMode = fbdevHWSwitchModeWeak();
424		pScrn->AdjustFrame = fbdevHWAdjustFrameWeak();
425		pScrn->EnterVT = fbdevHWEnterVTWeak();
426		pScrn->LeaveVT = fbdevHWLeaveVTWeak();
427		pScrn->ValidMode = fbdevHWValidModeWeak();
428	}
429
430	if (pScrn->numEntities > 1) {
431		IMSTTFreeRec(pScrn);
432		return FALSE;
433	}
434
435	pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
436	if (pEnt->resources) {
437		xfree(pEnt);
438		IMSTTFreeRec(pScrn);
439		return FALSE;
440	}
441
442	iptr->PciInfo = xf86GetPciInfoForEntity(pEnt->index);
443	xf86RegisterResources(pEnt->index, NULL, ResNone);
444	xf86SetOperatingState(resVgaIo, pEnt->index, ResUnusedOpr);
445	xf86SetOperatingState(resVgaMem, pEnt->index, ResDisableOpr);
446
447	pScrn->memPhysBase = iptr->PciInfo->memBase[0];
448	pScrn->fbOffset = 0;
449
450	if (pEnt->device->chipset && *pEnt->device->chipset) {
451		pScrn->chipset = pEnt->device->chipset;
452		iptr->Chipset = xf86StringToToken(IMSTTChipsets, pScrn->chipset);
453	} else if (pEnt->device->chipID >= 0) {
454		iptr->Chipset = pEnt->device->chipID;
455		pScrn->chipset = (char *)xf86TokenToString(IMSTTChipsets,
456							   iptr->Chipset);
457		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
458			   iptr->Chipset);
459	} else {
460		iptr->Chipset = iptr->PciInfo->chipType;
461		pScrn->chipset = (char *)xf86TokenToString(IMSTTChipsets,
462							   iptr->Chipset);
463	}
464
465	if (pEnt->device->chipRev >= 0) {
466		iptr->ChipRev = pEnt->device->chipRev;
467		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
468			   iptr->ChipRev);
469	} else
470		iptr->ChipRev = iptr->PciInfo->chipRev;
471
472	xfree(pEnt);
473
474	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Chipset: \"%s\"\n", pScrn->chipset);
475
476	iptr->PciTag = pciTag(iptr->PciInfo->bus, iptr->PciInfo->device,
477			      iptr->PciInfo->func);
478
479	if (!xf86SetGamma(pScrn, gzeros))
480		return FALSE;
481
482	if (iptr->Chipset == PCI_IMSTT3D) {
483		iptr->ramdac = RAMDAC_TVP;
484		iptr->videoRam = 0x800000;
485	}
486
487	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "using %s ramdac\n", iptr->ramdac == RAMDAC_TVP ? "TVP" : "IBM");
488
489	if (!IMSTTMapMem(pScrn)) {
490		IMSTTFreeRec(pScrn);
491		return FALSE;
492	}
493
494	iptr->rev = (INREG(IMSTT_SSTATUS) & 0x0f00) >> 8;
495
496	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "revision %d\n", iptr->rev);
497
498	if (!pScrn->videoRam) {
499		pScrn->videoRam = iptr->videoRam / 1024;
500		xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
501			   "probed videoram = %dk\n",
502			    pScrn->videoRam);
503	} else {
504		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
505			   "videoram = %dk\n",
506			   pScrn->videoRam / 1024);
507	}
508
509	clockRanges = xnfcalloc(sizeof(ClockRange), 1);
510	clockRanges->next = NULL;
511	clockRanges->minClock = 20000;
512	clockRanges->maxClock = 120000;	/* i don't want to blow up anything */
513	clockRanges->clockIndex = -1;
514	clockRanges->interlaceAllowed = FALSE;	/* ? */
515	clockRanges->doubleScanAllowed = FALSE; /* ? */
516
517	i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
518			      pScrn->display->modes, clockRanges,
519			      NULL, 256, 2048, pScrn->bitsPerPixel,
520			      128, 2048, pScrn->display->virtualX,
521			      pScrn->display->virtualY,
522			      iptr->videoRam, LOOKUP_BEST_REFRESH);
523
524	if (i < 1 && iptr->FBDev) {
525		fbdevHWUseBuildinMode(pScrn);
526		pScrn->displayWidth = pScrn->virtualX;	/* XXX */
527		i = i;
528	}
529
530	if (i == -1) {
531		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes left\n");
532		IMSTTFreeRec(pScrn);
533		return FALSE;
534	}
535
536	xf86PruneDriverModes(pScrn);
537
538	if (i == 0 || pScrn->modes == NULL) {
539		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
540		IMSTTFreeRec(pScrn);
541		return FALSE;
542	}
543
544	xf86SetCrtcForModes(pScrn, 0);
545	pScrn->currentMode = pScrn->modes;
546	xf86PrintModes(pScrn);
547	xf86SetDpi(pScrn, 0, 0);
548
549	if (!xf86LoadSubModule(pScrn, "fb"))
550		return FALSE;
551
552	xf86LoaderReqSymLists(fbSymbols, NULL);
553
554	if (!xf86LoadSubModule(pScrn, "xaa"))
555		return FALSE;
556
557	xf86LoaderReqSymLists(xaaSymbols, NULL);
558
559	IMSTTTRACE("PreInit -- END\n");
560
561	return TRUE;
562}
563
564
565
566static Bool IMSTTMapMem(ScrnInfoPtr pScrn)
567{
568	IMSTTPtr iptr;
569
570	iptr = IMSTTPTR(pScrn);
571
572	iptr->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, iptr->PciTag,
573				       iptr->PciInfo->memBase[0] + 0x800000,
574				       0x41000);
575	if (!iptr->MMIOBase) {
576		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
577			   "Internal error: could not map MMIO\n");
578		return FALSE;
579	}
580
581	IMSTTTRACE1("Mapped MMIO @ 0x%x with size 0x1000\n", iptr->PciInfo->memBase[0] + 0x800000);
582
583	IMSTTGetVideoMemSize(pScrn);
584
585	if (iptr->FBDev) {
586		iptr->FBBase = fbdevHWMapVidmem(pScrn);
587	} else {
588		iptr->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, iptr->PciTag,
589					     iptr->PciInfo->memBase[0],
590					     iptr->videoRam);
591	}
592	if (!iptr->FBBase) {
593		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
594			   "Internal error: could not map framebuffer\n");
595		return FALSE;
596	}
597
598	if (iptr->InitDAC) {
599		iptr->CMAPBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, iptr->PciTag,
600					       iptr->PciInfo->memBase[0] + 0x840000,
601					       0x1000);
602		if (!iptr->CMAPBase) {
603			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
604				   "Internal error: could not map CMAP\n");
605			return FALSE;
606		}
607	}
608
609	pScrn->fbOffset = 0;
610
611	return TRUE;
612}
613
614
615static void IMSTTUnmapMem(ScrnInfoPtr pScrn)
616{
617	IMSTTPtr iptr;
618
619	iptr = IMSTTPTR(pScrn);
620
621	if (iptr->FBDev) {
622		fbdevHWUnmapMMIO(pScrn);
623	} else {
624		xf86UnMapVidMem(pScrn->scrnIndex, (pointer)iptr->MMIOBase,
625				0x1000);
626	}
627
628	if (iptr->InitDAC) {
629		xf86UnMapVidMem(pScrn->scrnIndex, (pointer)iptr->CMAPBase,
630				0x1000);
631	}
632
633	if (iptr->FBDev) {
634		fbdevHWUnmapVidmem(pScrn);
635	} else {
636		xf86UnMapVidMem(pScrn->scrnIndex, (pointer)iptr->FBBase,
637				iptr->videoRam);
638	}
639
640	return;
641}
642
643
644
645static void IMSTTGetVideoMemSize(ScrnInfoPtr pScrn)
646{
647	IMSTTPtr iptr = IMSTTPTR(pScrn);
648	unsigned long tmp;
649
650	if (iptr->FBDev) {
651		iptr->videoRam = fbdevHWGetVidmem(pScrn);
652		return;
653	}
654
655	tmp = INREG(IMSTT_PRC);
656	if (iptr->ramdac == RAMDAC_IBM)
657		iptr->videoRam = (tmp & 0x0004) ? 0x400000 : 0x200000;
658	else
659		iptr->videoRam = 0x800000;
660
661	return;
662}
663
664
665static Bool IMSTTScreenInit(int scrnIndex, ScreenPtr pScreen,
666			    int argc, char **argv)
667{
668	ScrnInfoPtr pScrn;
669	IMSTTPtr iptr;
670	unsigned long tmp;
671	VisualPtr visual;
672	int r = TRUE;
673
674	IMSTTTRACE("ScreenInit -- Begin\n");
675
676	pScrn = xf86Screens[pScreen->myNum];
677
678	iptr = IMSTTPTR(pScrn);
679
680	if (!iptr->FBDev) {
681		/* initialize the card */
682		tmp = INREG(IMSTT_STGCTL);
683
684		OUTREG(IMSTT_STGCTL, tmp & ~0x1);
685		OUTREG(IMSTT_SSR, 0);
686
687		if (iptr->InitDAC) {
688			/* set default values for DAC registers */
689			if (iptr->ramdac == RAMDAC_IBM) {
690				iptr->CMAPBase[IBM624_PPMASK] = 0xff;	eieio();
691				iptr->CMAPBase[IBM624_PIDXHI] = 0;	eieio();
692				OUTREGPI(IBM624_CLKCTL, 0x21);
693				OUTREGPI(IBM624_SYNCCTL, 0x00);
694				OUTREGPI(IBM624_HSYNCPOS, 0x00);
695				OUTREGPI(IBM624_PWRMNGMT, 0x00);
696				OUTREGPI(IBM624_DACOP, 0x02);
697				OUTREGPI(IBM624_PALETCTL, 0x00);
698				OUTREGPI(IBM624_SYSCLKCTL, 0x01);
699				OUTREGPI(IBM624_BPP8, 0x00);
700				OUTREGPI(IBM624_BPP16, 0x01);
701				OUTREGPI(IBM624_BPP24, 0x00);
702				OUTREGPI(IBM624_BPP32, 0x00);
703				OUTREGPI(IBM624_PIXCTL1, 0x05);
704				OUTREGPI(IBM624_PIXCTL2, 0x00);
705				OUTREGPI(IBM624_SYSCLKN, 0x08);
706				OUTREGPI(IBM624_SYSCLKM, 0x4f);
707				OUTREGPI(IBM624_SYSCLKP, 0x00);
708				OUTREGPI(IBM624_SYSCLKC, 0x00);
709				OUTREGPI(IBM624_CURSCTL, 0x00);
710				OUTREGPI(IBM624_CURSACCTL, 0x01);
711				OUTREGPI(IBM624_CURSACATTR, 0xa8);
712				OUTREGPI(IBM624_CURS1R, 0xff);
713				OUTREGPI(IBM624_CURS1G, 0xff);
714				OUTREGPI(IBM624_CURS1B, 0xff);
715				OUTREGPI(IBM624_CURS2R, 0xff);
716				OUTREGPI(IBM624_CURS2G, 0xff);
717				OUTREGPI(IBM624_CURS2B, 0xff);
718				OUTREGPI(IBM624_CURS3R, 0xff);
719				OUTREGPI(IBM624_CURS3G, 0xff);
720				OUTREGPI(IBM624_CURS3B, 0xff);
721				OUTREGPI(IBM624_BORDR, 0xff);
722				OUTREGPI(IBM624_BORDG, 0xff);
723				OUTREGPI(IBM624_BORDB, 0xff);
724				OUTREGPI(IBM624_MISCTL1, 0x01);
725				OUTREGPI(IBM624_MISCTL2, 0x45);
726				OUTREGPI(IBM624_MISCTL3, 0x00);
727				OUTREGPI(IBM624_KEYCTL, 0x00);
728			} else {
729				OUTREGPT(TVP_IRICC, 0x00);
730				OUTREGPT(TVP_IRBRC, 0xe4);
731				OUTREGPT(TVP_IRLAC, 0x06);
732				OUTREGPT(TVP_IRTCC, 0x80);
733				OUTREGPT(TVP_IRMXC, 0x4d);
734				OUTREGPT(TVP_IRCLS, 0x05);
735				OUTREGPT(TVP_IRPPG, 0x00);
736				OUTREGPT(TVP_IRGEC, 0x00);
737				OUTREGPT(TVP_IRMIC, 0x08);
738				OUTREGPT(TVP_IRCKL, 0xff);
739				OUTREGPT(TVP_IRCKH, 0xff);
740				OUTREGPT(TVP_IRCRL, 0xff);
741				OUTREGPT(TVP_IRCRH, 0xff);
742				OUTREGPT(TVP_IRCGL, 0xff);
743				OUTREGPT(TVP_IRCGH, 0xff);
744				OUTREGPT(TVP_IRCBL, 0xff);
745				OUTREGPT(TVP_IRCBH, 0xff);
746				OUTREGPT(TVP_IRCKC, 0x00);
747				OUTREGPT(TVP_IRPLA, 0x00);
748				OUTREGPT(TVP_IRPPD, 0xc0);
749				OUTREGPT(TVP_IRPPD, 0xd5);
750				OUTREGPT(TVP_IRPPD, 0xea);
751				OUTREGPT(TVP_IRPLA, 0x00);
752				OUTREGPT(TVP_IRMPD, 0xb9);
753				OUTREGPT(TVP_IRMPD, 0x3a);
754				OUTREGPT(TVP_IRMPD, 0xb1);
755				OUTREGPT(TVP_IRPLA, 0x00);
756				OUTREGPT(TVP_IRLPD, 0xc1);
757				OUTREGPT(TVP_IRLPD, 0x3d);
758				OUTREGPT(TVP_IRLPD, 0xf3);
759			}
760		}
761	}
762
763	iptr->pitch = pScrn->displayWidth;
764
765	if (iptr->FBDev) {
766		if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
767			return FALSE;
768	} else {
769		if (!IMSTTModeInit(pScrn, pScrn->currentMode))
770			return FALSE;
771	}
772
773	pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
774
775	miClearVisualTypes();
776
777	if (pScrn->bitsPerPixel > 8) {
778		if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
779				      pScrn->rgbBits, TrueColor))
780			return FALSE;
781	} else {
782		if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
783				      pScrn->rgbBits, pScrn->defaultVisual))
784			return FALSE;
785	}
786
787	miSetPixmapDepths ();
788
789	r = fbScreenInit(pScreen, iptr->FBBase, pScrn->virtualX,
790			 pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
791			 pScrn->displayWidth, pScrn->bitsPerPixel);
792
793	if (!r) {
794		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ScreenInit failed\n");
795		return FALSE;
796	}
797
798	if (pScrn->bitsPerPixel > 8) {
799		visual = pScreen->visuals + pScreen->numVisuals;
800		while (--visual >= pScreen->visuals) {
801			if ((visual->class | DynamicClass) == DirectColor) {
802				visual->offsetRed = pScrn->offset.red;
803				visual->offsetGreen = pScrn->offset.green;
804				visual->offsetBlue = pScrn->offset.blue;
805				visual->redMask = pScrn->mask.red;
806				visual->greenMask = pScrn->mask.green;
807				visual->blueMask = pScrn->mask.blue;
808			}
809		}
810	}
811
812	fbPictureInit (pScreen, 0, 0);
813
814	xf86SetBlackWhitePixels(pScreen);
815	miInitializeBackingStore(pScreen);
816	xf86SetBackingStore(pScreen);
817
818	if (!iptr->NoAccel) {
819		if (IMSTTAccelInit(pScreen)) {
820			xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n");
821		} else {
822			xf86DrvMsg(scrnIndex, X_ERROR, "Acceleration initailizatino failed\n");
823			xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
824		}
825	} else {
826		xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
827	}
828
829	miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
830
831	if (!miCreateDefColormap(pScreen))
832		return FALSE;
833
834	if (!xf86HandleColormaps(pScreen, 256, 8, fbdevHWLoadPaletteWeak(),
835				 NULL, CMAP_PALETTED_TRUECOLOR))
836		return FALSE;
837
838	if (serverGeneration == 1)
839		xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
840
841	pScreen->SaveScreen = IMSTTSaveScreen;
842	pScreen->CloseScreen = IMSTTCloseScreen;
843
844	IMSTTTRACE("ScreenInit -- End\n");
845
846
847	return TRUE;
848}
849
850
851
852
853static Bool IMSTTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
854{
855	IMSTTPtr iptr;
856	unsigned long mhz;
857	unsigned short hes, heb, veb, htp, vtp;
858
859	iptr = IMSTTPTR(pScrn);
860
861	if (iptr->ramdac == RAMDAC_IBM) {
862		switch (pScrn->displayWidth) {
863			case 640:
864				hes = 0x0008;
865				heb = 0x0012;
866				veb = 0x002a;
867				htp = 10;
868				vtp = 2;
869				mhz = 30;
870				break;
871			case 832:
872				hes = 0x0005;
873				heb = 0x0020;
874				veb = 0x0028;
875				htp = 8;
876				vtp = 3;
877				mhz = 57;
878				break;
879			case 1024:
880				hes = 0x000a;
881				heb = 0x001c;
882				veb = 0x0020;
883				htp = 8;
884				vtp = 3;
885				mhz = 80;
886				break;
887			case 1152:
888				hes = 0x0012;
889				heb = 0x0022;
890				veb = 0x0031;
891				htp = 4;
892				vtp = 3;
893				mhz = 101;
894				break;
895			case 1280:
896				hes = 0x0012;
897				heb = 0x002f;
898				veb = 0x0029;
899				htp = 4;
900				vtp = 1;
901				mhz = 135;	/* XXX check for 1280x960 */
902				break;
903			case 1600:
904				hes = 0x0018;
905				heb = 0x0040;
906				veb = 0x002a;
907				htp = 4;
908				vtp = 3;
909				mhz = 200;
910				break;
911			default:
912				return FALSE;
913		}
914
915		IMSTTSetClock(pScrn, mhz);
916
917		iptr->hes = hes;
918		iptr->heb = heb;
919		iptr->hsb = heb + (pScrn->displayWidth >> 3);
920		iptr->ht = iptr->hsb + htp;
921		iptr->ves = 0x0003;
922		iptr->veb = veb;
923		iptr->vsb = veb + pScrn->virtualY;
924		iptr->vt = iptr->vsb + vtp;
925		iptr->vil = iptr->vsb;
926		iptr->pitch = pScrn->displayWidth;
927	} else {
928		iptr->pitch = pScrn->displayWidth;
929		switch (pScrn->displayWidth) {
930			case 640:
931				iptr->hes = 0x0004;
932				iptr->heb = 0x0009;
933				iptr->hsb = 0x0031;
934				iptr->ht = 0x0036;
935				iptr->ves = 0x0003;
936				iptr->veb = 0x002a;
937				iptr->vsb = 0x020a;
938				iptr->vt = 0x020d;
939				iptr->vil = 0x020a;
940				iptr->pclk_m = 0xef;
941				iptr->pclk_n = 0x2e;
942				iptr->pclk_p = 0xb2;
943				iptr->mlc[0] = 0x39;
944				iptr->mlc[1] = 0x39;
945				iptr->mlc[2] = 0x38;
946				iptr->lckl_p[0] = 0xf3;
947				iptr->lckl_p[1] = 0xf3;
948				iptr->lckl_p[2] = 0xf3;
949			case 800:
950				iptr->hes = 0x0005;
951				iptr->heb = 0x000e;
952				iptr->hsb = 0x0040;
953				iptr->ht = 0x0042;
954				iptr->ves = 0x0003;
955				iptr->veb = 0x0018;
956				iptr->vsb = 0x0270;
957				iptr->vt = 0x0271;
958				iptr->vil = 0x0270;
959				iptr->pclk_m = 0xf6;
960				iptr->pclk_n = 0x2e;
961				iptr->pclk_p = 0xf2;
962				iptr->mlc[0] = 0x3a;
963				iptr->mlc[1] = 0x39;
964				iptr->mlc[2] = 0x38;
965				iptr->lckl_p[0] = 0xf3;
966				iptr->lckl_p[1] = 0xf3;
967				iptr->lckl_p[2] = 0xf3;
968			case 832:
969				iptr->hes = 0x0004;
970				iptr->heb = 0x0011;
971				iptr->hsb = 0x0045;
972				iptr->ht = 0x0048;
973				iptr->ves = 0x0003;
974				iptr->veb = 0x002a;
975				iptr->vsb = 0x029a;
976				iptr->vt = 0x029b;
977				iptr->vil = 0x0000;
978				iptr->pclk_m = 0xfe;
979				iptr->pclk_n = 0x3e;
980				iptr->pclk_p = 0xf1;
981				iptr->mlc[0] = 0x39;
982				iptr->mlc[1] = 0x38;
983				iptr->mlc[2] = 0x38;
984				iptr->lckl_p[0] = 0xf3;
985				iptr->lckl_p[1] = 0xf3;
986				iptr->lckl_p[2] = 0xf2;
987			case 1024:
988				iptr->hes = 0x0006;
989				iptr->heb = 0x0210;
990				iptr->hsb = 0x0250;
991				iptr->ht = 0x0053;
992				iptr->ves = 0x1003;
993				iptr->veb = 0x0021;
994				iptr->vsb = 0x0321;
995				iptr->vt = 0x0324;
996				iptr->vil = 0x0000;
997				iptr->pclk_m = 0xfc;
998				iptr->pclk_n = 0x3a;
999				iptr->pclk_p = 0xf1;
1000				iptr->mlc[0] = 0x39;
1001				iptr->mlc[1] = 0x38;
1002				iptr->mlc[2] = 0x38;
1003				iptr->lckl_p[0] = 0xf3;
1004				iptr->lckl_p[1] = 0xf3;
1005				iptr->lckl_p[2] = 0xf2;
1006			case 1152:
1007				iptr->hes = 0x0009;
1008				iptr->heb = 0x0011;
1009				iptr->hsb = 0x0059;
1010				iptr->ht = 0x005b;
1011				iptr->ves = 0x0003;
1012				iptr->veb = 0x0031;
1013				iptr->vsb = 0x0397;
1014				iptr->vt = 0x039a;
1015				iptr->vil = 0x0000;
1016				iptr->pclk_m = 0xfd;
1017				iptr->pclk_n = 0x3a;
1018				iptr->pclk_p = 0xf1;
1019				iptr->mlc[0] = 0x39;
1020				iptr->mlc[1] = 0x38;
1021				iptr->mlc[2] = 0x38;
1022				iptr->lckl_p[0] = 0xf3;
1023				iptr->lckl_p[1] = 0xf3;
1024				iptr->lckl_p[2] = 0xf2;
1025			case 1280:
1026				iptr->hes = 0x0009;
1027				iptr->heb = 0x0018;
1028				iptr->hsb = 0x0068;
1029				iptr->ht = 0x006a;
1030				iptr->ves = 0x0003;
1031				iptr->veb = 0x0029;
1032				iptr->vsb = 0x0429;
1033				iptr->vt = 0x042a;
1034				iptr->vil = 0x0000;
1035				iptr->pclk_m = 0xf0;
1036				iptr->pclk_n = 0x2d;
1037				iptr->pclk_p = 0xf0;
1038				iptr->mlc[0] = 0x38;
1039				iptr->mlc[1] = 0x38;
1040				iptr->mlc[2] = 0x38;
1041				iptr->lckl_p[0] = 0xf3;
1042				iptr->lckl_p[1] = 0xf2;
1043				iptr->lckl_p[2] = 0xf1;
1044			default:
1045				return FALSE;
1046		}
1047	}
1048
1049	/* do it! */
1050	IMSTTWriteMode(pScrn);
1051	IMSTTAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
1052
1053	return TRUE;
1054}
1055
1056
1057
1058
1059static void IMSTTSetClock(ScrnInfoPtr pScrn, unsigned long mhz)
1060{
1061	IMSTTPtr iptr;
1062	unsigned long clk_m, clk_n, clk_p, x, stage, spilled;
1063
1064	iptr = IMSTTPTR(pScrn);
1065	clk_m = clk_n = clk_p = 0;
1066	stage = spilled = 0;
1067
1068	for (;;) {
1069		switch (stage) {
1070			case 0:
1071				clk_m++;
1072				break;
1073			case 1:
1074				clk_n++;
1075				break;
1076		}
1077		x = 20 * (clk_m + 1) / ((clk_n + 1) * (clk_p ? 2 * clk_p : 1));
1078		if (x == mhz)
1079			break;
1080		if (x > mhz) {
1081			spilled = 1;
1082			stage = 1;
1083		} else if (spilled && x < mhz) {
1084			stage = 0;
1085		}
1086	}
1087
1088	iptr->pclk_m = clk_m;
1089	iptr->pclk_n = clk_n;
1090	iptr->pclk_p = clk_p;
1091}
1092
1093
1094static void IMSTTWriteMode(ScrnInfoPtr pScrn)
1095{
1096	IMSTTPtr iptr;
1097	unsigned char pixformat;
1098	unsigned long ctl = 0, pitch = 0, byteswap = 0, scr = 0;
1099	unsigned char tcc = 0, mxc = 0, lckl_n = 0, mic, mlc = 0, lckl_p = 0;
1100
1101	iptr = IMSTTPTR(pScrn);
1102
1103	pixformat = (pScrn->bitsPerPixel >> 3) + 2;
1104
1105	if (iptr->InitDAC && (pScrn->bitsPerPixel == 16)) {
1106		if (iptr->ramdac == RAMDAC_IBM) {
1107			iptr->CMAPBase[IBM624_PIDXHI] = 0;		eieio();
1108			iptr->CMAPBase[IBM624_PIDXLO] = IBM624_BPP16;	eieio();
1109			iptr->CMAPBase[IBM624_PIDXDATA] = 0x03;		eieio();
1110		} else {
1111			iptr->CMAPBase[TVP_ADDRW] = TVP_IRTCC;		eieio();
1112			iptr->CMAPBase[TVP_IDATA] = 0x45;		eieio();
1113		}
1114	}
1115
1116	/* XXX do for 15bpp */
1117
1118	if ((iptr->ramdac == RAMDAC_IBM) && (iptr->InitDAC)) {
1119		iptr->CMAPBase[IBM624_PIDXHI] = 0;			eieio();
1120		iptr->CMAPBase[IBM624_PIDXLO] = IBM624_PIXM0;		eieio();
1121		iptr->CMAPBase[IBM624_PIDXDATA] = iptr->pclk_m;		eieio();
1122		iptr->CMAPBase[IBM624_PIDXLO] = IBM624_PIXN0;		eieio();
1123		iptr->CMAPBase[IBM624_PIDXDATA] = iptr->pclk_n;		eieio();
1124		iptr->CMAPBase[IBM624_PIDXLO] = IBM624_PIXP0;		eieio();
1125		iptr->CMAPBase[IBM624_PIDXDATA] = iptr->pclk_p;		eieio();
1126		iptr->CMAPBase[IBM624_PIDXLO] = IBM624_PIXC0;		eieio();
1127		iptr->CMAPBase[IBM624_PIDXDATA] = 0x02;			eieio();
1128		iptr->CMAPBase[IBM624_PIDXLO] = IBM624_PIXFMT;		eieio();
1129		iptr->CMAPBase[IBM624_PIDXDATA] = pixformat;		eieio();
1130	}
1131
1132	if ((iptr->ramdac == RAMDAC_TVP) && (iptr->InitDAC)) {
1133		switch (pScrn->bitsPerPixel) {
1134			case 8:
1135				tcc = 0x80;
1136				mxc = 0x4d;
1137				lckl_n = 0xc1;
1138				mlc = iptr->mlc[0];
1139				lckl_p = iptr->lckl_p[0];
1140				break;
1141			case 16:
1142				tcc = 0x44;
1143				mxc = 0x55;
1144				lckl_n = 0xe1;
1145				mlc = iptr->mlc[1];
1146				lckl_p = iptr->lckl_p[1];
1147				break;
1148			case 24:
1149				tcc = 0x5e;
1150				mxc = 0x5d;
1151				lckl_n = 0xf1;
1152				mlc = iptr->mlc[2];
1153				lckl_p = iptr->lckl_p[2];
1154				break;
1155			case 32:
1156				tcc = 0x46;
1157				mxc = 0x5d;
1158				lckl_n = 0xf1;
1159				mlc = iptr->mlc[2];
1160				lckl_p = iptr->lckl_p[2];
1161				break;
1162		}
1163
1164		mic = 0x08;
1165
1166		iptr->CMAPBase[TVP_ADDRW] = TVP_IRPLA;			eieio();
1167		iptr->CMAPBase[TVP_IDATA] = 0x00;			eieio();
1168		iptr->CMAPBase[TVP_ADDRW] = TVP_IRPPD;			eieio();
1169		iptr->CMAPBase[TVP_IDATA] = iptr->pclk_m;		eieio();
1170		iptr->CMAPBase[TVP_ADDRW] = TVP_IRPPD;			eieio();
1171		iptr->CMAPBase[TVP_IDATA] = iptr->pclk_n;		eieio();
1172		iptr->CMAPBase[TVP_ADDRW] = TVP_IRPPD;			eieio();
1173		iptr->CMAPBase[TVP_IDATA] = iptr->pclk_p;		eieio();
1174		iptr->CMAPBase[TVP_ADDRW] = TVP_IRTCC;			eieio();
1175		iptr->CMAPBase[TVP_IDATA] = tcc;			eieio();
1176		iptr->CMAPBase[TVP_ADDRW] = TVP_IRMXC;			eieio();
1177		iptr->CMAPBase[TVP_IDATA] = mxc;			eieio();
1178		iptr->CMAPBase[TVP_ADDRW] = TVP_IRMIC;			eieio();
1179		iptr->CMAPBase[TVP_IDATA] = mic;			eieio();
1180		iptr->CMAPBase[TVP_ADDRW] = TVP_IRPLA;			eieio();
1181		iptr->CMAPBase[TVP_IDATA] = 0x00;			eieio();
1182		iptr->CMAPBase[TVP_ADDRW] = TVP_IRLPD;			eieio();
1183		iptr->CMAPBase[TVP_IDATA] = lckl_n;			eieio();
1184		iptr->CMAPBase[TVP_ADDRW] = TVP_IRPLA;			eieio();
1185		iptr->CMAPBase[TVP_IDATA] = 0x15;			eieio();
1186		iptr->CMAPBase[TVP_ADDRW] = TVP_IRMLC;			eieio();
1187		iptr->CMAPBase[TVP_IDATA] = mlc;			eieio();
1188		iptr->CMAPBase[TVP_ADDRW] = TVP_IRPLA;			eieio();
1189		iptr->CMAPBase[TVP_IDATA] = 0x2a;			eieio();
1190		iptr->CMAPBase[TVP_ADDRW] = TVP_IRLPD;			eieio();
1191		iptr->CMAPBase[TVP_IDATA] = lckl_p;			eieio();
1192	}
1193
1194	switch (pScrn->bitsPerPixel) {
1195		case 8:
1196			ctl = 0x17b1;
1197			pitch = iptr->pitch >> 2;
1198			byteswap = 0x000;
1199			break;
1200		case 16:
1201			ctl = 0x17b3;
1202			pitch = iptr->pitch >> 1;
1203			byteswap = 0x100;
1204			break;
1205		case 24:
1206			ctl = 0x17b9;
1207			pitch = iptr->pitch - (iptr->pitch >> 2);
1208			byteswap = 0x200;
1209			break;
1210		case 32:
1211			ctl = 0x17b5;
1212			pitch = iptr->pitch;
1213			byteswap = 0x300;
1214			break;
1215	}
1216
1217	if (iptr->ramdac == RAMDAC_TVP)
1218		ctl -= 0x30;
1219
1220	OUTREG(IMSTT_HES, iptr->hes);
1221	OUTREG(IMSTT_HEB, iptr->heb);
1222	OUTREG(IMSTT_HSB, iptr->hsb);
1223	OUTREG(IMSTT_HT, iptr->ht);
1224	OUTREG(IMSTT_VES, iptr->ves);
1225	OUTREG(IMSTT_VEB, iptr->veb);
1226	OUTREG(IMSTT_VSB, iptr->vsb);
1227	OUTREG(IMSTT_VT, iptr->vt);
1228	OUTREG(IMSTT_VIL, iptr->vil);
1229	OUTREG(IMSTT_HCIV, 1);
1230	OUTREG(IMSTT_VCIV, 1);
1231	OUTREG(IMSTT_TCDR, 4);
1232	OUTREG(IMSTT_RRCIV, 1);
1233	OUTREG(IMSTT_RRSC, 0x980);
1234	OUTREG(IMSTT_RRCR, 0x11);
1235
1236	if (iptr->ramdac == RAMDAC_IBM) {
1237		OUTREG(IMSTT_HRIR, 0x0100);
1238		OUTREG(IMSTT_CMR, 0x00ff);
1239		OUTREG(IMSTT_SRGCTL, 0x0073);
1240	} else {
1241		OUTREG(IMSTT_HRIR, 0x0200);
1242		OUTREG(IMSTT_CMR, 0x01ff);
1243		OUTREG(IMSTT_SRGCTL, 0x0003);
1244	}
1245
1246	switch (iptr->videoRam) {
1247		case 0x200000:
1248			scr = 0x059d | byteswap;
1249			break;
1250		default:
1251			/* 0x400000 and 0x800000 */
1252			pitch >>= 1;
1253			scr = 0x150dd | byteswap;
1254			break;
1255	}
1256
1257	OUTREG(IMSTT_SCR, scr);
1258	OUTREG(IMSTT_SPR, pitch);
1259	OUTREG(IMSTT_STGCTL, ctl);
1260
1261	return;
1262}
1263
1264
1265
1266static void IMSTTAdjustFrame(int scrnIndex, int x, int y, int flags)
1267{
1268	ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1269	IMSTTPtr iptr;
1270	unsigned long offset;
1271
1272	iptr = IMSTTPTR(pScrn);
1273
1274	offset = y * pScrn->displayWidth + x;
1275	offset &= ~7;
1276
1277	OUTREG(IMSTT_SSR, offset);
1278
1279	return;
1280}
1281
1282
1283Bool IMSTTCloseScreen(int scrnIndex, ScreenPtr pScreen)
1284{
1285	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1286	IMSTTPtr iptr = IMSTTPTR(pScrn);
1287
1288	if (iptr->FBDev)
1289		fbdevHWSave(pScrn);
1290
1291	return TRUE;
1292}
1293
1294
1295Bool IMSTTSaveScreen(ScreenPtr pScreen, int mode)
1296{
1297	return TRUE;
1298}
1299