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