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