i128_driver.c revision 7965d9ac
1/*
2 * Copyright 1995-2000 by Robin Cutshaw <robin@XFree86.Org>
3 * Copyright 1998 by Number Nine Visual Technology, Inc.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Robin Cutshaw not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission.  Robin Cutshaw and Number Nine make no
12 * representations about the suitability of this software for any purpose.  It
13 * is provided "as is" without express or implied warranty.
14 *
15 * ROBIN CUTSHAW AND NUMBER NINE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 * FITNESS, IN NO EVENT SHALL ROBIN CUTSHAW OR NUMBER NINE BE LIABLE FOR
18 * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
20 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
21 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 */
24
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29
30
31/* All drivers should typically include these */
32#include "xf86.h"
33#include "xf86_OSproc.h"
34#include "xf86Resources.h"
35
36#include "compiler.h"
37
38/* Drivers for PCI hardware need this */
39#include "xf86PciInfo.h"
40
41/* Drivers that need to access the PCI config space directly need this */
42#include "xf86Pci.h"
43
44/* vgaHW module is only used to save/restore fonts by this driver */
45#include "vgaHW.h"
46
47/* All drivers initialising the SW cursor need this */
48#include "mipointer.h"
49
50/* All drivers implementing backing store need this */
51#include "mibstore.h"
52#include "micmap.h"
53
54#include "xf86DDC.h"
55#include "xf86RAC.h"
56#include "vbe.h"
57
58#include "xaa.h"
59#include "xf86cmap.h"
60#include "fb.h"
61
62#include "xf86xv.h"
63#include <X11/extensions/Xv.h>
64
65/* driver specific includes */
66#include "i128.h"
67#include "i128reg.h"
68
69#include <unistd.h>
70
71/*
72 * Forward definitions for the functions that make up the driver.
73 */
74
75/* Mandatory functions */
76static const OptionInfoRec *	I128AvailableOptions(int chipid, int busid);
77static void	I128Identify(int flags);
78static Bool	I128Probe(DriverPtr drv, int flags);
79static Bool	I128PreInit(ScrnInfoPtr pScrn, int flags);
80static Bool	I128ScreenInit(int Index, ScreenPtr pScreen, int argc,
81			      char **argv);
82static Bool	I128EnterVT(int scrnIndex, int flags);
83static void	I128LeaveVT(int scrnIndex, int flags);
84static Bool	I128CloseScreen(int scrnIndex, ScreenPtr pScreen);
85static Bool	I128SaveScreen(ScreenPtr pScreen, int mode);
86
87static void I128DumpBaseRegisters(ScrnInfoPtr pScrn);
88static void I128DumpIBMDACRegisters(ScrnInfoPtr pScrn, volatile CARD32 *vrbg);
89
90/* Optional functions */
91static void	I128FreeScreen(int scrnIndex, int flags);
92static ModeStatus I128ValidMode(int scrnIndex, DisplayModePtr mode,
93				Bool verbose, int flags);
94static void	I128DisplayPowerManagementSet(ScrnInfoPtr pScrn,
95					     int PowerManagementMode,
96					     int flags);
97
98/* Internally used functions */
99static Bool	I128GetRec(ScrnInfoPtr pScrn);
100static void	I128FreeRec(ScrnInfoPtr pScrn);
101static Bool	I128MapMem(ScrnInfoPtr pScrn);
102static Bool	I128UnmapMem(ScrnInfoPtr pScrn);
103static void	I128Save(ScrnInfoPtr pScrn);
104static void	I128Restore(ScrnInfoPtr pScrn);
105static Bool	I128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
106static int	I128CountRam(ScrnInfoPtr pScrn);
107static void	I128SoftReset(ScrnInfoPtr pScrn);
108static Bool     I128I2CInit(ScrnInfoPtr pScrn);
109static xf86MonPtr I128getDDC(ScrnInfoPtr pScrn);
110#if 0
111static unsigned int I128DDC1Read(ScrnInfoPtr pScrn);
112#endif
113
114#define I128_VERSION 4000
115#define I128_NAME "I128"
116#define I128_DRIVER_NAME "i128"
117#define I128_MAJOR_VERSION PACKAGE_VERSION_MAJOR
118#define I128_MINOR_VERSION PACKAGE_VERSION_MINOR
119#define I128_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL
120
121/*
122 * This contains the functions needed by the server after loading the
123 * driver module.  It must be supplied, and gets added the driver list by
124 * the Module Setup funtion in the dynamic case.  In the static case a
125 * reference to this is compiled in, and this requires that the name of
126 * this DriverRec be an upper-case version of the driver name.
127 */
128
129_X_EXPORT DriverRec I128 = {
130    I128_VERSION,
131    I128_DRIVER_NAME,
132    I128Identify,
133    I128Probe,
134    I128AvailableOptions,
135    NULL,
136    0
137};
138
139#ifdef XFree86LOADER
140
141static MODULESETUPPROTO(i128Setup);
142
143static XF86ModuleVersionInfo i128VersRec =
144{
145	"i128",
146	MODULEVENDORSTRING,
147	MODINFOSTRING1,
148	MODINFOSTRING2,
149	XORG_VERSION_CURRENT,
150	I128_MAJOR_VERSION, I128_MINOR_VERSION, I128_PATCHLEVEL,
151	ABI_CLASS_VIDEODRV,			/* This is a video driver */
152	ABI_VIDEODRV_VERSION,
153	MOD_CLASS_VIDEODRV,
154	{0,0,0,0}
155};
156
157/*
158 * XF86ModuleData structure is the first part of the driver that is used
159 * by the module loader.  It provides the XF86ModuleVersionInfo structure
160 * used to verify that the module version is compatable with the loader
161 * version.  It also provides a pointer to the module specific
162 * ModuleSetupProc() and ModuleTearDownProc() functions.
163 */
164
165_X_EXPORT XF86ModuleData i128ModuleData = { &i128VersRec, i128Setup, NULL };
166
167#endif
168
169
170/*
171 * List of symbols from other modules that this module references.  This
172 * list is used to tell the loader that it is OK for symbols here to be
173 * unresolved providing that it hasn't been told that they haven't been
174 * told that they are essential via a call to xf86LoaderReqSymbols() or
175 * xf86LoaderReqSymLists().  The purpose is this is to avoid warnings about
176 * unresolved symbols that are not required.  These are provided to the
177 * LoaderRefSymLists() function in the module specific Setup() function.
178 */
179
180static const char *vgahwSymbols[] = {
181    "vgaHWFreeHWRec",
182    "vgaHWGetHWRec",
183    "vgaHWGetIOBase",
184    "vgaHWGetIndex",
185    "vgaHWProtect",
186    "vgaHWRestore",
187    "vgaHWSave",
188    NULL
189};
190
191static const char *fbSymbols[] = {
192    "fbScreenInit",
193    "fbPictureInit",
194    NULL
195};
196
197static const char *exaSymbols[] = {
198    "exaDriverAlloc",
199    "exaDriverInit",
200    "exaDriverFini",
201    "exaGetPixmapOffset",
202    NULL
203};
204
205static const char *xaaSymbols[] = {
206    "XAACreateInfoRec",
207    "XAADestroyInfoRec",
208    "XAAInit",
209    NULL
210};
211
212static const char *ramdacSymbols[] = {
213    "xf86CreateCursorInfoRec",
214    "xf86DestroyCursorInfoRec",
215    "xf86InitCursor",
216    NULL
217};
218
219static const char *ddcSymbols[] = {
220    "xf86DoEDID_DDC1",
221    "xf86DoEDID_DDC2",
222    "xf86PrintEDID",
223    "xf86SetDDCproperties",
224    NULL
225};
226
227static const char *i2cSymbols[] = {
228    "xf86CreateI2CBusRec",
229    "xf86I2CBusInit",
230    NULL
231};
232
233#ifdef XFree86LOADER
234/* XXX The vbe module isn't currently loaded. */
235static const char *vbeSymbols[] = {
236    "VBEInit",
237    "vbeDoEDID",
238    NULL
239};
240
241/* XXX The int10 module isn't currently loaded. */
242static const char *int10Symbols[] = {
243    "xf86InitInt10",
244    "xf86FreeInt10",
245    NULL
246};
247#endif
248
249
250#ifdef XFree86LOADER
251
252/* Mandatory
253 *
254 * The Setup() function is the first entry point called once that the
255 * module has been linked into the server.  It adds this driver to
256 * the driver list and lets the server know which symbols it might use.
257 * This is only called once, not called with each server generation.
258 *
259 * Arguments:
260 *		pointer module - module being loaded, passed to xf86AddDriver()
261 *		pointer opts   - unused but contains options from config file
262 *		int *errmaj    - if function error returns major error value
263 *		int *errmin    - if function error returns minor error value
264 * Returns:
265 *		pointer to TearDownData which is passed to TearDownProc()
266 *		or NULL for failure.
267 */
268
269static pointer
270i128Setup(pointer module, pointer opts, int *errmaj, int *errmin)
271{
272    static Bool setupDone = FALSE;
273
274    /* This module should be loaded only once, but check to be sure. */
275
276    if (!setupDone) {
277	setupDone = TRUE;
278	xf86AddDriver(&I128, module, 0);
279
280	/*
281	 * Modules that this driver always requires may be loaded here
282	 * by calling LoadSubModule().
283	 */
284
285	/*
286	 * Tell the loader about symbols from other modules that this module
287	 * might refer to.
288	 */
289	LoaderRefSymLists(fbSymbols,
290			  exaSymbols,
291			  xaaSymbols,
292			  ramdacSymbols,
293			  ddcSymbols,
294			  ddcSymbols,
295			  i2cSymbols,
296			  vbeSymbols,
297			  int10Symbols,
298			  vgahwSymbols,
299			  NULL);
300
301	/*
302	 * The return value must be non-NULL on success even though there
303	 * is no TearDownProc.
304	 */
305	return (pointer)1;
306    } else {
307	if (errmaj) *errmaj = LDR_ONCEONLY;
308	return NULL;
309    }
310}
311
312#endif /* XFree86LOADER */
313
314
315/* Define supported chipsets.  Used by Probe(). */
316
317static SymTabRec I128Chipsets[] = {
318    { PCI_CHIP_I128,		"i128" },
319    { PCI_CHIP_I128_2,		"i128v2" },
320    { PCI_CHIP_I128_T2R,	"i128t2r" },
321    { PCI_CHIP_I128_T2R4,	"i128t2r4" },
322    {-1,			NULL }
323};
324
325static PciChipsets I128PciChipsets[] = {
326    { PCI_CHIP_I128,		PCI_CHIP_I128,		NULL },
327    { PCI_CHIP_I128_2,		PCI_CHIP_I128_2,	NULL },
328    { PCI_CHIP_I128_T2R,	PCI_CHIP_I128_T2R,	NULL },
329    { PCI_CHIP_I128_T2R4,	PCI_CHIP_I128_T2R4,	NULL },
330    { -1,			-1,			RES_UNDEFINED }
331};
332
333/* Mandatory
334 *
335 * The Probe() function is the second entry point called once that the
336 * module has been linked into the server.  This function finds all
337 * instances of hardware that it supports and allocates a ScrnInfoRec
338 * using xf86ConfigPciEntity() for each unclaimed slot.  This should be
339 * a minimal probe and under no circumstances should it leave the hardware
340 * state changed.  No initialisations other than the required ScrnInfoRec
341 * should be done and no data structures should be allocated.
342 *
343 * Arguments:
344 *		DriverPtr drv - pointer to the driver structure
345 *		int flags     - PROBE_DEFAULT for normal function
346 *		                PROBE_DETECT for use with "-config" and "-probe"
347 * Returns:
348 *		Bool TRUE if a screen was allocated, FALSE otherwise
349 */
350
351static Bool
352I128Probe(DriverPtr drv, int flags)
353{
354    int i;
355    GDevPtr *devSections;
356    int *usedChips;
357    int numDevSections;
358    int numUsed;
359    Bool foundScreen = FALSE;
360
361    /*
362     * Check if there has been a chipset override in the config file.
363     * For this we must find out if there is an active device section which
364     * is relevant, i.e., which has no driver specified or has THIS driver
365     * specified.
366     */
367
368    if ((numDevSections = xf86MatchDevice(I128_DRIVER_NAME,
369					  &devSections)) <= 0) {
370	/*
371	 * There's no matching device section in the config file, so quit
372	 * now.
373	 */
374	return FALSE;
375    }
376
377    /*
378     * We need to probe the hardware first.  We then need to see how this
379     * fits in with what is given in the config file, and allow the config
380     * file info to override any contradictions.
381     */
382
383    /*
384     * All of the cards this driver supports are PCI, so the "probing" just
385     * amounts to checking the PCI data that the server has already collected.
386     */
387#ifndef XSERVER_LIBPCIACCESS
388    if (xf86GetPciVideoInfo() == NULL) {
389	/*
390	 * We won't let anything in the config file override finding no
391	 * PCI video cards at all.  This seems reasonable now, but we'll see.
392	 */
393	return FALSE;
394    }
395#endif
396
397    numUsed = xf86MatchPciInstances(I128_NAME, PCI_VENDOR_NUMNINE,
398			I128Chipsets, I128PciChipsets, devSections,
399			numDevSections, drv, &usedChips);
400
401    /* Free it since we don't need that list after this */
402    xfree(devSections);
403
404    if (numUsed <= 0)
405	return FALSE;
406
407    if (flags & PROBE_DETECT) {
408	xfree(usedChips);
409	return FALSE;
410    }
411
412    for (i = 0; i < numUsed; i++) {
413	ScrnInfoPtr pScrn = NULL;
414
415	/* Allocate a ScrnInfoRec and claim the slot */
416        if ((pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i],
417                                         I128PciChipsets, NULL, NULL,
418                                         NULL, NULL, NULL)) == NULL)
419		continue;
420
421
422	/* Fill in what we can of the ScrnInfoRec */
423	pScrn->driverVersion	= I128_VERSION;
424	pScrn->driverName	= I128_DRIVER_NAME;
425	pScrn->name		= I128_NAME;
426	pScrn->Probe		= I128Probe;
427	pScrn->PreInit		= I128PreInit;
428	pScrn->ScreenInit	= I128ScreenInit;
429	pScrn->SwitchMode	= I128SwitchMode;
430	pScrn->AdjustFrame	= I128AdjustFrame;
431	pScrn->EnterVT		= I128EnterVT;
432	pScrn->LeaveVT		= I128LeaveVT;
433	pScrn->FreeScreen	= I128FreeScreen;
434	pScrn->ValidMode	= I128ValidMode;
435	foundScreen = TRUE;
436    }
437
438    xfree(usedChips);
439
440    return foundScreen;
441}
442
443
444/* Mandatory
445 *
446 * The Identify() function is the third entry point called once that the
447 * module has been linked into the server.  This function prints driver
448 * identity information.
449 *
450 * Arguments:
451 *		int flags     - currently unused
452 * Returns:
453 *		no return
454 */
455
456static void
457I128Identify(int flags)
458{
459    xf86PrintChipsets(I128_NAME, "driver for Number Nine I128 chipsets",
460	I128Chipsets);
461}
462
463
464/*
465 * Define options that this driver will accept.  Used by AvailableOptions().
466 */
467
468typedef enum {
469    OPTION_FLATPANEL,
470    OPTION_SW_CURSOR,
471    OPTION_HW_CURSOR,
472    OPTION_SYNC_ON_GREEN,
473    OPTION_NOACCEL,
474    OPTION_SHOWCACHE,
475    OPTION_DAC6BIT,
476    OPTION_DEBUG,
477    OPTION_ACCELMETHOD
478} I128Opts;
479
480static const OptionInfoRec I128Options[] = {
481    { OPTION_FLATPANEL,		"FlatPanel",	OPTV_BOOLEAN,	{0}, FALSE },
482    { OPTION_SW_CURSOR,		"SWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
483    { OPTION_HW_CURSOR,		"HWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
484    { OPTION_SYNC_ON_GREEN,	"SyncOnGreen",	OPTV_BOOLEAN,	{0}, FALSE },
485    { OPTION_NOACCEL,		"NoAccel",	OPTV_BOOLEAN,	{0}, FALSE },
486    { OPTION_SHOWCACHE,		"ShowCache",	OPTV_BOOLEAN,	{0}, FALSE },
487    { OPTION_DAC6BIT,		"Dac6Bit",	OPTV_BOOLEAN,	{0}, FALSE },
488    { OPTION_DEBUG,		"Debug",	OPTV_BOOLEAN,	{0}, FALSE },
489    { OPTION_ACCELMETHOD,       "AccelMethod",  OPTV_STRING,    {0}, FALSE },
490    { -1,			NULL,		OPTV_NONE,	{0}, FALSE }
491};
492
493
494/* Mandatory
495 *
496 * The AvailableOptions() function is called to provide the options that
497 * this driver will accept.  This is used with the "-configure" server option.
498 *
499 * Arguments:
500 *		int chipid  - currently unused
501 *		int busid   - currently unused
502 * Returns:
503 *		const OptionInfoRec * - all accepted options
504 */
505
506static const OptionInfoRec *
507I128AvailableOptions(int chipid, int busid)
508{
509    return I128Options;
510}
511
512
513/* Mandatory
514 *
515 * The PreInit() function called after the Probe() function once at
516 * server startup and not at each server generation.  Only things that
517 * are persistent across server generations can be initialized here.
518 * This function determines if the configuration is usable and, if so,
519 * initializes those parts of the ScrnInfoRec that can be set at the
520 * beginning of the first server generation.  This should be done in
521 * the least intrusive way possible.  Note that although the ScrnInfoRec
522 * has been allocated, the ScreenRec has not.
523 *
524 * Use xf86AllocateScrnInfoPrivateIndex() for persistent data across
525 * screen generations and AllocateScreenprivateIndex() in ScreenInit()
526 * for per-generation data.
527 *
528 * Arguments:
529 *		ScrnInfoPtr pScrn -
530 *		int flags     - PROBE_DEFAULT for normal function
531 *		                PROBE_DETECT for use with "-config" and "-probe"
532 * Returns:
533 *		Bool TRUE if ScrnInfoRec was initialized, FALSE otherwise
534 */
535
536static Bool
537I128PreInit(ScrnInfoPtr pScrn, int flags)
538{
539    I128Ptr pI128;
540    vgaHWPtr hwp;
541    int i;
542    ClockRangePtr clockRanges;
543    MessageType from;
544    IOADDRESS iobase;
545    char *ramdac = NULL;
546    CARD32 tmpl, tmph, tmp;
547    unsigned char n, m, p, mdc, df;
548    float mclk;
549    xf86MonPtr mon;
550
551    /* Check the number of entities, and fail if it isn't one. */
552    if (pScrn->numEntities != 1)
553	return FALSE;
554
555    /* Allocate the I128Rec driverPrivate */
556    I128GetRec(pScrn);
557
558    pI128 = I128PTR(pScrn);
559
560    /* Get the entity, and make sure it is PCI. */
561    pI128->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
562    if (pI128->pEnt->location.type != BUS_PCI)
563	return FALSE;
564
565    if (flags & PROBE_DETECT) {
566	/* I128ProbeDDC(pScrn, pI128->pEnt->index); */
567	return TRUE;
568    }
569
570    /* Find the PCI info for this screen */
571    pI128->PciInfo = xf86GetPciInfoForEntity(pI128->pEnt->index);
572#ifndef XSERVER_LIBPCIACCESS
573    pI128->PciTag = pciTag(pI128->PciInfo->bus, pI128->PciInfo->device,
574			  pI128->PciInfo->func);
575#endif
576
577    pI128->Primary = xf86IsPrimaryPci(pI128->PciInfo);
578
579    /* The vgahw module should be allocated here when needed */
580    if (!xf86LoadSubModule(pScrn, "vgahw"))
581        return FALSE;
582
583    xf86LoaderReqSymLists(vgahwSymbols, NULL);
584
585    /*
586     * Allocate a vgaHWRec
587     */
588    if (!vgaHWGetHWRec(pScrn))
589        return FALSE;
590
591    hwp = VGAHWPTR(pScrn);
592    vgaHWGetIOBase(hwp);
593
594    /* Set pScrn->monitor */
595    pScrn->monitor = pScrn->confScreen->monitor;
596
597    /*
598     * The first thing we should figure out is the depth, bpp, etc.
599     * Our default depth is 8, so pass it to the helper function.
600     * We support both 24bpp and 32bpp layouts, so indicate that.
601     */
602
603    if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) {
604	return FALSE;
605    } else {
606	/* Check that the returned depth is one we support */
607	switch (pScrn->depth) {
608	case 8:
609	case 15:
610	case 16:
611	case 24:
612	    /* OK */
613	    break;
614	default:
615	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
616		       "Given depth (%d) is not supported by this driver\n",
617		       pScrn->depth);
618	    return FALSE;
619	}
620    }
621    xf86PrintDepthBpp(pScrn);
622
623    /*
624     * This must happen after pScrn->display has been set because
625     * xf86SetWeight references it.
626     */
627    if (pScrn->depth > 8) {
628	/* The defaults are OK for us */
629	rgb zeros = {0, 0, 0};
630
631	if (!xf86SetWeight(pScrn, zeros, zeros)) {
632	    return FALSE;
633	} else {
634	    /* XXX check that weight returned is supported */
635            ;
636        }
637    }
638
639    if (!xf86SetDefaultVisual(pScrn, -1)) {
640	return FALSE;
641    } else {
642	/* We don't currently support DirectColor at > 8bpp */
643	if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
644	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
645		       " (%s) is not supported at depth %d\n",
646		       xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
647	    return FALSE;
648	}
649    }
650
651    /* We use a programmable clock */
652    pScrn->progClock = TRUE;
653
654    /* Collect all of the relevant option flags (fill in pScrn->options) */
655    xf86CollectOptions(pScrn, NULL);
656
657    /* Process the options */
658    if (!(pI128->Options = xalloc(sizeof(I128Options))))
659	return FALSE;
660    memcpy(pI128->Options, I128Options, sizeof(I128Options));
661    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI128->Options);
662
663    if (pScrn->depth == 8)
664	pScrn->rgbBits = 8;
665
666    /*
667     * The preferred method is to use the "hw cursor" option as a tri-state
668     * option, with the default set above.
669     */
670    from = X_DEFAULT;
671    pI128->HWCursor = TRUE;
672    if (xf86GetOptValBool(pI128->Options, OPTION_HW_CURSOR, &pI128->HWCursor)) {
673	from = X_CONFIG;
674    }
675    /* For compatibility, accept this too (as an override) */
676    if (xf86ReturnOptValBool(pI128->Options, OPTION_SW_CURSOR, FALSE)) {
677	from = X_CONFIG;
678	pI128->HWCursor = FALSE;
679    }
680    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
681		pI128->HWCursor ? "HW" : "SW");
682    if (xf86ReturnOptValBool(pI128->Options, OPTION_NOACCEL, FALSE)) {
683	pI128->NoAccel = TRUE;
684	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
685    } else {
686        int from = X_DEFAULT;
687        char *s = xf86GetOptValString(pI128->Options, OPTION_ACCELMETHOD);
688        pI128->NoAccel = FALSE;
689        if (!xf86NameCmp(s, "EXA")) {
690            pI128->exa = TRUE;
691            from = X_CONFIG;
692        }
693        xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration\n",
694                   pI128->exa ? "EXA" : "XAA");
695    }
696    if (xf86ReturnOptValBool(pI128->Options, OPTION_SYNC_ON_GREEN, FALSE)) {
697	pI128->DACSyncOnGreen = TRUE;
698	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Sync-on-Green enabled\n");
699    } else pI128->DACSyncOnGreen = FALSE;
700    if (xf86ReturnOptValBool(pI128->Options, OPTION_SHOWCACHE, FALSE)) {
701	pI128->ShowCache = TRUE;
702	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n");
703    } else pI128->ShowCache = FALSE;
704    if (xf86ReturnOptValBool(pI128->Options, OPTION_DAC6BIT, FALSE)) {
705	pI128->DAC8Bit = FALSE;
706	pScrn->rgbBits = 6;
707	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Dac6Bit enabled\n");
708    } else pI128->DAC8Bit = TRUE;
709    if (xf86ReturnOptValBool(pI128->Options, OPTION_DEBUG, FALSE)) {
710	pI128->Debug = TRUE;
711	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Debug enabled\n");
712    } else pI128->Debug = FALSE;
713    if (xf86ReturnOptValBool(pI128->Options, OPTION_FLATPANEL, FALSE)) {
714	pI128->FlatPanel = TRUE;
715	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "FlatPanel forced\n");
716    } else pI128->FlatPanel = FALSE;
717
718    /*
719     * Set the Chipset and ChipRev.
720     */
721    from = X_PROBED;
722    pI128->Chipset = PCI_DEV_DEVICE_ID(pI128->PciInfo);
723    pScrn->chipset = (char *)xf86TokenToString(I128Chipsets, pI128->Chipset);
724    pI128->ChipRev = PCI_DEV_REVISION(pI128->PciInfo);
725
726    /*
727     * This shouldn't happen because such problems should be caught in
728     * I128Probe(), but check it just in case.
729     */
730    if (pScrn->chipset == NULL) {
731	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
732		   "ChipID 0x%04X is not recognised\n", pI128->Chipset);
733	return FALSE;
734    }
735    if (pI128->Chipset < 0) {
736	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
737		   "Chipset \"%s\" is not recognised\n", pScrn->chipset);
738	return FALSE;
739    }
740
741    xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
742    if (PCI_SUB_VENDOR_ID(pI128->PciInfo) == 0x105D)
743        xf86DrvMsg(pScrn->scrnIndex, from, "Subsystem Vendor: \"Number Nine\"\n");
744    else if (PCI_SUB_VENDOR_ID(pI128->PciInfo) == 0x10F0)
745        xf86DrvMsg(pScrn->scrnIndex, from, "Subsystem Vendor: \"Peritek\"\n");
746    else
747        xf86DrvMsg(pScrn->scrnIndex, from, "Subsystem Vendor: \"%x\"\n",
748    	    PCI_SUB_VENDOR_ID(pI128->PciInfo));
749
750    iobase = (PCI_REGION_BASE(pI128->PciInfo, 5, REGION_IO) & 0xFFFFFF00) + hwp->PIOOffset;
751    pI128->RegRec.iobase = iobase;
752
753    pI128->io.rbase_g = inl(iobase)        & 0xFFFFFF00;
754    pI128->io.rbase_w = inl(iobase + 0x04) & 0xFFFFFF00;
755    pI128->io.rbase_a = inl(iobase + 0x08) & 0xFFFFFF00;
756    pI128->io.rbase_b = inl(iobase + 0x0C) & 0xFFFFFF00;
757    pI128->io.rbase_i = inl(iobase + 0x10) & 0xFFFFFF00;
758    pI128->io.rbase_e = inl(iobase + 0x14) & 0xFFFF8003;
759    pI128->io.id =      inl(iobase + 0x18) & /* 0x7FFFFFFF */ 0xFFFFFFFF;
760    pI128->io.config1 = inl(iobase + 0x1C) & /* 0xF3333F1F */ 0xFF133706;
761    pI128->io.config2 = inl(iobase + 0x20) & 0xC1F70FFF;
762    pI128->io.sgram   = inl(iobase + 0x24) & 0xFFFFFFFF;
763    pI128->io.soft_sw = inl(iobase + 0x28) & 0x0000FFFF;
764    pI128->io.vga_ctl = inl(iobase + 0x30) & 0x0000FFFF;
765
766    if (pI128->Debug)
767	I128DumpBaseRegisters(pScrn);
768
769    pI128->RegRec.config1 = pI128->io.config1;
770    pI128->RegRec.config2 = pI128->io.config2;
771    pI128->RegRec.sgram = pI128->io.sgram;
772    if (pI128->Chipset == PCI_CHIP_I128_T2R4)
773	pI128->io.sgram = 0x211BF030;
774    else
775	pI128->io.sgram = 0x21089030;
776    /* vga_ctl is saved later */
777
778    /* enable all of the memory mapped windows */
779
780    pI128->io.config1 &= 0x3300001F;
781    pI128->io.config1 |= 0x00331F10;
782    outl(iobase + 0x1C, pI128->io.config1);
783
784    pI128->MemoryType = I128_MEMORY_UNKNOWN;
785
786    if (pI128->Chipset == PCI_CHIP_I128_T2R4)
787	pI128->MemoryType = I128_MEMORY_SGRAM;
788    else if (pI128->Chipset == PCI_CHIP_I128_T2R) {
789	if ((pI128->io.config2&6) == 2)
790		pI128->MemoryType = I128_MEMORY_SGRAM;
791	else
792		pI128->MemoryType = I128_MEMORY_WRAM;
793    } else if (pI128->Chipset == PCI_CHIP_I128_2) {
794#ifndef XSERVER_LIBPCIACCESS
795   	if (((((pciConfigPtr)pI128->PciInfo->thisCard)->pci_command & 0x03)
796	    == 0x03) && (PCI_SUB_DEVICE_ID(pI128->PciInfo) == 0x08))
797   	   pI128->MemoryType = I128_MEMORY_DRAM;
798#else
799	{
800	    unsigned short temp;
801	    pci_device_cfg_read_u16(pI128->PciInfo, &temp, 0x4);
802	    if (((temp & 0x03) == 0x03) && (PCI_SUB_DEVICE_ID(pI128->PciInfo) == 0x08))
803		pI128->MemoryType = I128_MEMORY_DRAM;
804	}
805#endif
806    }
807
808    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory type %s\n",
809	pI128->MemoryType == I128_MEMORY_SGRAM ? "SGRAM" :
810	pI128->MemoryType == I128_MEMORY_DRAM ? "DRAM" :
811	pI128->MemoryType == I128_MEMORY_WRAM ? "WRAM" : "UNKNOWN");
812
813    pI128->io.config2 &= 0xFF0FFF7F;
814    pI128->io.config2 |= 0x00100000;
815    if (pI128->MemoryType != I128_MEMORY_SGRAM)
816   	pI128->io.config2 |= 0x00400000;
817    outl(pI128->RegRec.iobase + 0x20, pI128->io.config2);
818
819    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Linear framebuffer at 0x%lX\n",
820	       (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 0, REGION_MEM));
821
822    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MMIO registers at 0x%lX\n",
823	       (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 5, REGION_IO));
824
825    if (xf86RegisterResources(pI128->pEnt->index, NULL, ResExclusive)) {
826	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
827		"xf86RegisterResources() found resource conflicts\n");
828	I128FreeRec(pScrn);
829	return FALSE;
830    }
831
832    /* HW bpp matches reported bpp */
833    pI128->bitsPerPixel = pScrn->bitsPerPixel;
834    pI128->depth = pScrn->depth;
835    pI128->weight.red =  pScrn->weight.red;
836    pI128->weight.green =  pScrn->weight.green;
837    pI128->weight.blue =  pScrn->weight.blue;
838    pI128->mode = pScrn->modes;
839
840    pScrn->videoRam = I128CountRam(pScrn);
841    pI128->MemorySize = pScrn->videoRam;
842
843    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n",
844               pScrn->videoRam);
845
846
847    /*
848     * If the driver can do gamma correction, it should call xf86SetGamma()
849     * here.
850     */
851
852    {
853	Gamma zeros = {0.0, 0.0, 0.0};
854
855	if (!xf86SetGamma(pScrn, zeros)) {
856	    return FALSE;
857	}
858    }
859
860    if (!I128MapMem(pScrn))
861	return FALSE;
862
863    /*
864     * Reset card if it isn't primary one (must be done after config1 is set)
865     */
866    if (!pI128->Primary)
867        I128SoftReset(pScrn);
868
869    if (pI128->Chipset != PCI_CHIP_I128) {
870	pI128->ddc1Read = NULL /*I128DDC1Read*/;
871	pI128->i2cInit = I128I2CInit;
872    }
873
874    /* Load DDC if we have the code to use it */
875    /* This gives us DDC1 */
876    if (pI128->ddc1Read || pI128->i2cInit) {
877        if (xf86LoadSubModule(pScrn, "ddc")) {
878          xf86LoaderReqSymLists(ddcSymbols, NULL);
879        } else {
880          /* ddc module not found, we can do without it */
881          pI128->ddc1Read = NULL;
882
883          /* Without DDC, we have no use for the I2C bus */
884          pI128->i2cInit = NULL;
885        }
886    }
887    /* - DDC can use I2C bus */
888    /* Load I2C if we have the code to use it */
889    if (pI128->i2cInit) {
890      if ( xf86LoadSubModule(pScrn, "i2c") ) {
891        xf86LoaderReqSymLists(i2cSymbols,NULL);
892      } else {
893        /* i2c module not found, we can do without it */
894        pI128->i2cInit = NULL;
895        pI128->I2C = NULL;
896      }
897    }
898
899    /* Read and print the Monitor DDC info */
900    mon = I128getDDC(pScrn);
901
902    /* see if we can find a flatpanel */
903    if (!pI128->FlatPanel && mon) {
904        for (i=0; i<4; i++)
905    	    if (mon->det_mon[i].type == DS_NAME) {
906		if (strncmp((char *)mon->det_mon[i].section.name,
907			    "SGI 1600SW FP", 13) == 0) {
908			pI128->FlatPanel = TRUE;
909    			xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
910				"Found FlatPanel via DDC2\n");
911		}
912		break;
913	    }
914    }
915
916    pI128->maxClock = 175000;
917
918    switch (pI128->Chipset) {
919    	case PCI_CHIP_I128:
920	    if (pI128->io.id & 0x0400)       /* 2 banks VRAM   */
921		pI128->RamdacType = IBM528_DAC;
922	    else
923		pI128->RamdacType = TI3025_DAC;
924	    break;
925    	case PCI_CHIP_I128_2:
926	    if (pI128->io.id & 0x0400)       /* 2 banks VRAM   */
927		pI128->RamdacType = IBM528_DAC;
928	    else
929		pI128->RamdacType = IBM526_DAC;
930	    pI128->maxClock = 220000;
931	    break;
932    	case PCI_CHIP_I128_T2R:
933	    pI128->RamdacType = IBM526_DAC;
934	    pI128->maxClock = 220000;
935	    break;
936    	case PCI_CHIP_I128_T2R4:
937	    pI128->RamdacType = SILVER_HAMMER_DAC;
938	    pI128->maxClock = 270000;
939	    break;
940	default:
941    	    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
942			"Unknown I128 chipset: %d\n",
943               		pI128->Chipset);
944            return(FALSE);
945    }
946
947    if ((pI128->maxClock == 175000) && (pI128->MemorySize == 8192))
948	pI128->maxClock = 220000;
949
950    switch(pI128->RamdacType) {
951       case TI3025_DAC:
952          /* verify that the ramdac is a TVP3025 */
953
954          pI128->mem.rbase_g[INDEX_TI] = TI_ID;				MB;
955          if ((pI128->mem.rbase_g[DATA_TI]&0xFF) != TI_VIEWPOINT25_ID) {
956    	     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
957			"Ti3025 Ramdac not found\n");
958             return(FALSE);
959          }
960          ramdac = "TI3025";
961
962          pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
963          pI128->mem.rbase_g[DATA_TI] = 0x00;				MB;
964          pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA;		MB;
965          n = pI128->mem.rbase_g[DATA_TI]&0x7f;
966          pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
967          pI128->mem.rbase_g[DATA_TI] = 0x01;				MB;
968          pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA;		MB;
969          m = pI128->mem.rbase_g[DATA_TI]&0x7f;
970          pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
971          pI128->mem.rbase_g[DATA_TI] = 0x02;				MB;
972          pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA;		MB;
973          p = pI128->mem.rbase_g[DATA_TI]&0x03;
974          pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_DCLK_CONTROL;		MB;
975          mdc = pI128->mem.rbase_g[DATA_TI]&0xFF;
976          if (mdc&0x08)
977	    mdc = (mdc&0x07)*2 + 2;
978          else
979	    mdc = 1;
980          mclk = ((1431818 * ((m+2) * 8)) / (n+2) / (1 << p) / mdc + 50) / 100;
981
982    	  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
983			"Using TI 3025 programmable clock (MCLK %1.3f MHz)\n",
984			mclk / 1000.0);
985	  pI128->minClock = 20000;
986	  pI128->ProgramDAC = I128ProgramTi3025;
987	  break;
988
989       case IBM524_DAC:
990    	  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
991			"IBM524 Ramdac not supported\n");
992          return(FALSE);
993
994       case IBM526_DAC:
995          /* verify that the ramdac is an IBM526 */
996
997          ramdac = "IBM526";
998	  tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
999	  tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
1000          pI128->mem.rbase_g[IDXH_I] = 0;				MB;
1001          pI128->mem.rbase_g[IDXL_I] = IBMRGB_id;			MB;
1002	  tmp = pI128->mem.rbase_g[DATA_I] & 0xFF;
1003
1004          pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div;		MB;
1005	  n = pI128->mem.rbase_g[DATA_I] & 0x1f;
1006          pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div;		MB;
1007	  m = pI128->mem.rbase_g[DATA_I];
1008	  df = m>>6;
1009	  m &= 0x3f;
1010	  if (n == 0) { m=0; n=1; }
1011	  mclk = ((2517500 * (m+65)) / n / (8>>df) + 50) / 100;
1012
1013	  pI128->mem.rbase_g[IDXL_I] = tmpl;				MB;
1014	  pI128->mem.rbase_g[IDXH_I] = tmph;				MB;
1015          if (tmp != 2) {
1016    	     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1017			"IBM526 Ramdac not found\n");
1018             return(FALSE);
1019          }
1020
1021    	  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1022			"Using IBM 526 programmable clock (MCLK %1.3f MHz)\n",
1023			mclk / 1000.0);
1024	  pI128->minClock = 25000;
1025	  pI128->ProgramDAC = I128ProgramIBMRGB;
1026          break;
1027
1028       case IBM528_DAC:
1029          /* verify that the ramdac is an IBM528 */
1030
1031          ramdac = "IBM528";
1032	  tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
1033	  tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
1034          pI128->mem.rbase_g[IDXH_I] = 0;				MB;
1035          pI128->mem.rbase_g[IDXL_I] = IBMRGB_id;			MB;
1036	  tmp = pI128->mem.rbase_g[DATA_I] & 0xFF;
1037
1038          pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div;		MB;
1039	  n = pI128->mem.rbase_g[DATA_I] & 0x1f;
1040          pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div;		MB;
1041	  m = pI128->mem.rbase_g[DATA_I] & 0xFF;
1042	  df = m>>6;
1043	  m &= 0x3f;
1044	  if (n == 0) { m=0; n=1; }
1045	  mclk = ((2517500 * (m+65)) / n / (8>>df) + 50) / 100;
1046
1047	  pI128->mem.rbase_g[IDXL_I] = tmpl;				MB;
1048	  pI128->mem.rbase_g[IDXH_I] = tmph;				MB;
1049          if (tmp != 2) {
1050    	     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1051			"IBM528 Ramdac not found\n");
1052             return(FALSE);
1053          }
1054
1055    	  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1056			"Using IBM 528 programmable clock (MCLK %1.3f MHz)\n",
1057			mclk / 1000.0);
1058	  pI128->minClock = 25000;
1059	  pI128->ProgramDAC = I128ProgramIBMRGB;
1060          break;
1061
1062       case SILVER_HAMMER_DAC:
1063          /* verify that the ramdac is a Silver Hammer */
1064
1065          ramdac = "SilverHammer";
1066	  tmph = pI128->mem.rbase_g[IDXH_I] & 0xFF;
1067	  tmpl = pI128->mem.rbase_g[IDXL_I] & 0xFF;
1068	  tmp = pI128->mem.rbase_g[DATA_I] & 0xFF;
1069
1070          pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div;		MB;
1071	  n = pI128->mem.rbase_g[DATA_I] & 0x1f;
1072          pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div;		MB;
1073	  m = pI128->mem.rbase_g[DATA_I];
1074	  df = m>>6;
1075	  m &= 0x3f;
1076	  if (n == 0) { m=0; n=1; }
1077	  mclk = ((3750000 * (m+65)) / n / (8>>df) + 50) / 100;
1078
1079	  pI128->mem.rbase_g[IDXL_I] = tmpl;				MB;
1080	  pI128->mem.rbase_g[IDXH_I] = tmph;				MB;
1081          if (pI128->Chipset != PCI_CHIP_I128_T2R4) {
1082    	     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1083			"SilverHammer Ramdac not found\n");
1084             return(FALSE);
1085          }
1086
1087	  if (pI128->mem.rbase_g[CRT_1CON] & 0x00000100) {
1088             pI128->FlatPanel = TRUE;
1089    	     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1090			"Digital flat panel detected\n");
1091          } else if (pI128->FlatPanel)
1092    	     xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1093			"Digital flat panel forced\n");
1094
1095    	  xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1096			"Using SilverHammer programmable clock (MCLK %1.3f MHz)\n",
1097			mclk / 1000.0);
1098	  pI128->minClock = 25000;
1099	  pI128->ProgramDAC = I128ProgramSilverHammer;
1100          break;
1101
1102       default:
1103    	 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1104		"Ramdac Unknown\n");
1105          return(FALSE);
1106     }
1107
1108    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1109		"Ramdac Type min/max speed: %s %d/%d MHz\n",
1110		ramdac, pI128->minClock/1000, pI128->maxClock/1000);
1111
1112    /*
1113     * Setup the ClockRanges, which describe what clock ranges are available,
1114     * and what sort of modes they can be used for.
1115     */
1116    clockRanges = xnfcalloc(sizeof(ClockRange),1);
1117    clockRanges->next = NULL;
1118    clockRanges->minClock = pI128->minClock;
1119    clockRanges->maxClock = pI128->maxClock;
1120    clockRanges->clockIndex = -1;		/* programmable */
1121    clockRanges->interlaceAllowed = TRUE;
1122    clockRanges->doubleScanAllowed = TRUE;
1123    clockRanges->ClockMulFactor = 1;
1124    clockRanges->ClockDivFactor = 1;
1125
1126    /*
1127     * xf86ValidateModes will check that the mode HTotal and VTotal values
1128     * don't exceed the chipset's limit if pScrn->maxHValue and
1129     * pScrn->maxVValue are set.  Since our I128ValidMode() already takes
1130     * care of this, we don't worry about setting them here.
1131     */
1132    {
1133	int *linePitches = NULL;
1134	int minPitch = 256;
1135	int maxPitch = 2048;
1136	int pitchAlignment = 256;
1137
1138	if (pI128->MemoryType == I128_MEMORY_WRAM)
1139	   pitchAlignment = (128 * 8);
1140	pitchAlignment /= pI128->bitsPerPixel;
1141
1142	i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
1143			      pScrn->display->modes, clockRanges,
1144			      linePitches, minPitch, maxPitch,
1145			      pitchAlignment * pI128->bitsPerPixel,
1146			      128, 2048,
1147			      pScrn->display->virtualX,
1148			      pScrn->display->virtualY,
1149			      pI128->MemorySize,
1150			      LOOKUP_BEST_REFRESH);
1151
1152	pI128->displayWidth = pScrn->virtualX;
1153
1154	if ((pScrn->virtualX % pitchAlignment) != 0)
1155	   pI128->displayWidth += pitchAlignment -
1156				  (pScrn->virtualX % pitchAlignment);
1157    }
1158
1159    if (i == -1) {
1160	I128FreeRec(pScrn);
1161	return FALSE;
1162    }
1163
1164    /* Prune the modes marked as invalid */
1165    xf86PruneDriverModes(pScrn);
1166
1167    if (i == 0 || pScrn->modes == NULL) {
1168	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
1169	I128FreeRec(pScrn);
1170	return FALSE;
1171    }
1172
1173    if ((pI128->MemorySize > 4096) &&
1174        (pI128->MemoryType != I128_MEMORY_DRAM) &&
1175        (pI128->MemoryType != I128_MEMORY_SGRAM))
1176        pI128->displayOffset = 0x400000L %
1177		          (pI128->displayWidth * (pI128->bitsPerPixel/8));
1178    else
1179        pI128->displayOffset = 0;
1180
1181    pI128->MemoryPtr =
1182	    (pointer)&((char *)pI128->MemoryPtr)[pI128->displayOffset];
1183
1184    /* Set the current mode to the first in the list */
1185    pScrn->currentMode = pScrn->modes;
1186
1187    /* Print the list of modes being used */
1188    xf86PrintModes(pScrn);
1189
1190    /* Set display resolution */
1191    xf86SetDpi(pScrn, 0, 0);
1192
1193    if (!xf86LoadSubModule(pScrn, "fb")) {
1194	I128FreeRec(pScrn);
1195	return FALSE;
1196    }
1197    xf86LoaderReqSymLists(fbSymbols, NULL);
1198
1199    /* Load the acceleration engine */
1200    if (!pI128->NoAccel) {
1201	if (pI128->exa) {
1202	    XF86ModReqInfo req;
1203	    int errmaj, errmin;
1204
1205	    memset(&req, 0, sizeof(req));
1206	    req.majorversion = 2;
1207	    req.minorversion = 0;
1208            if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
1209		&errmaj, &errmin))
1210	    {
1211		LoaderErrorMsg(NULL, "exa", errmaj, errmin);
1212                I128FreeRec(pScrn);
1213                return FALSE;
1214            } else xf86LoaderReqSymLists(exaSymbols, NULL);
1215        } else {
1216            if (!xf86LoadSubModule(pScrn, "xaa")) {
1217	        I128FreeRec(pScrn);
1218	        return FALSE;
1219	    } else xf86LoaderReqSymLists(xaaSymbols, NULL);
1220        }
1221    }
1222
1223    /* Load ramdac if needed */
1224    if (pI128->HWCursor) {
1225	if (!xf86LoadSubModule(pScrn, "ramdac")) {
1226	    I128FreeRec(pScrn);
1227	    return FALSE;
1228	}
1229	xf86LoaderReqSymLists(ramdacSymbols, NULL);
1230    }
1231
1232    I128UnmapMem(pScrn);
1233
1234    if (pI128->Debug)
1235    	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PreInit complete\n");
1236    return TRUE;
1237}
1238
1239
1240static Bool
1241I128GetRec(ScrnInfoPtr pScrn)
1242{
1243    /*
1244     * Allocate an I128Rec, and hook it into pScrn->driverPrivate.
1245     * pScrn->driverPrivate is initialised to NULL, so we can check if
1246     * the allocation has already been done.
1247     */
1248    if (pScrn->driverPrivate != NULL)
1249	return TRUE;
1250
1251    pScrn->driverPrivate = xnfcalloc(sizeof(I128Rec), 1);
1252
1253    return TRUE;
1254}
1255
1256static void
1257I128FreeRec(ScrnInfoPtr pScrn)
1258{
1259    if (pScrn->driverPrivate == NULL)
1260	return;
1261    xfree(pScrn->driverPrivate);
1262    pScrn->driverPrivate = NULL;
1263}
1264
1265
1266
1267/*
1268 * I128SoftReset --
1269 *
1270 * Resets drawing engine
1271 */
1272static void
1273I128SoftReset(ScrnInfoPtr pScrn)
1274{
1275    I128Ptr pI128 = I128PTR(pScrn);
1276
1277    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Performing soft reset\n");
1278    pI128->io.config1 |= 0x00000002;
1279    outl(pI128->RegRec.iobase + 0x1C, pI128->io.config1);
1280    usleep(10000);
1281    pI128->io.config1 &= 0xFFFFFFFD;
1282    outl(pI128->RegRec.iobase + 0x1C, pI128->io.config1);
1283}
1284
1285/*
1286 * I128CountRAM --
1287 *
1288 * Counts amount of installed RAM
1289 */
1290static int
1291I128CountRam(ScrnInfoPtr pScrn)
1292{
1293    I128Ptr pI128 = I128PTR(pScrn);
1294    int SizeFound = 0;
1295
1296    SizeFound = 0;
1297
1298    switch(pI128->Chipset) {
1299    case PCI_CHIP_I128_T2R4:
1300      /* Use the subsystem ID to determine the memory size */
1301      switch ((PCI_SUB_DEVICE_ID(pI128->PciInfo)) & 0x0007) {
1302         case 0x00:      /* 4MB card */
1303	    SizeFound = 4 * 1024; break;
1304         case 0x01:      /* 8MB card */
1305	    SizeFound = 8 * 1024; break;
1306         case 0x02:      /* 12MB card */
1307            SizeFound = 12 * 1024; break;
1308         case 0x03:      /* 16MB card */
1309	    SizeFound = 16 * 1024; break;
1310         case 0x04:      /* 20MB card */
1311	    SizeFound = 20 * 1024; break;
1312         case 0x05:      /* 24MB card */
1313	    SizeFound = 24 * 1024; break;
1314         case 0x06:      /* 28MB card */
1315	    SizeFound = 28 * 1024; break;
1316         case 0x07:      /* 32MB card */
1317	    SizeFound = 32 * 1024; break;
1318         default: /* Unknown board... */
1319            break;
1320      }
1321      break;
1322    case PCI_CHIP_I128_T2R:
1323      switch ((PCI_SUB_DEVICE_ID(pI128->PciInfo)) & 0xFFF7) {
1324	 case 0x00:	/* 4MB card, no daughtercard */
1325	    SizeFound = 4 * 1024; break;
1326	 case 0x01:	/* 4MB card, 4MB daughtercard */
1327	 case 0x04:	/* 8MB card, no daughtercard */
1328	    SizeFound = 8 * 1024; break;
1329	 case 0x02:	/* 4MB card, 8MB daughtercard */
1330	 case 0x05:	/* 8MB card, 4MB daughtercard */
1331	    SizeFound = 12 * 1024; break;
1332	 case 0x06:	/* 8MB card, 8MB daughtercard */
1333	    SizeFound = 16 * 1024; break;
1334	 case 0x03:	/* 4MB card, 16 daughtercard */
1335	    SizeFound = 20 * 1024; break;
1336	 case 0x07:	/* 8MB card, 16MB daughtercard */
1337	    SizeFound = 24 * 1024; break;
1338	 default:
1339	    break;
1340      }
1341    }
1342
1343    if (SizeFound == 0) {
1344      SizeFound = 2048;  /* default to 2MB */
1345      if (pI128->io.config1 & 0x04)    /* 128 bit mode   */
1346         SizeFound <<= 1;
1347      if (pI128->io.id & 0x0400)       /* 2 banks VRAM   */
1348         SizeFound <<= 1;
1349    }
1350    return SizeFound;
1351}
1352
1353
1354/*
1355 * Map the framebuffer and MMIO memory.
1356 */
1357
1358static Bool
1359I128MapMem(ScrnInfoPtr pScrn)
1360{
1361    I128Ptr pI128;
1362
1363    pI128 = I128PTR(pScrn);
1364
1365    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Mapping memory\n");
1366
1367    if (pI128->mem.rbase_g != NULL)
1368	return TRUE;
1369
1370    /*
1371     * Map IO registers to virtual address space
1372     */
1373#ifndef XSERVER_LIBPCIACCESS
1374    pI128->mem.mw0_ad = (unsigned char *)xf86MapPciMem(pScrn->scrnIndex,
1375				VIDMEM_FRAMEBUFFER,
1376				pI128->PciTag,
1377				pI128->PciInfo->memBase[0] & 0xFFC00000,
1378				pI128->MemorySize*1024);
1379#else
1380    {
1381	void** result = (void**)&pI128->mem.mw0_ad;
1382	int err = pci_device_map_range(pI128->PciInfo,
1383				       PCI_REGION_BASE(pI128->PciInfo, 0, REGION_MEM) & 0xffc00000,
1384				       pI128->MemorySize * 1024,
1385				       PCI_DEV_MAP_FLAG_WRITABLE |
1386				       PCI_DEV_MAP_FLAG_WRITE_COMBINE,
1387				       result);
1388	if (err)
1389	    return FALSE;
1390    }
1391#endif
1392
1393    if (pI128->mem.mw0_ad == NULL)
1394	return FALSE;
1395
1396    pI128->MemoryPtr = pI128->mem.mw0_ad;
1397
1398#ifndef XSERVER_LIBPCIACCESS
1399    pI128->mem.rbase_g = (CARD32 *)xf86MapPciMem(pScrn->scrnIndex,
1400				VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
1401				pI128->PciTag,
1402				pI128->PciInfo->memBase[4] & 0xFFFF0000,
1403				64*1024);
1404#else
1405    {
1406	void** result = (void**)&pI128->mem.rbase_g;
1407	int err = pci_device_map_range(pI128->PciInfo,
1408				       PCI_REGION_BASE(pI128->PciInfo, 4, REGION_MEM) & 0xffff0000,
1409				       64 * 1024,
1410				       PCI_DEV_MAP_FLAG_WRITABLE,
1411				       result);
1412	if (err)
1413	    return FALSE;
1414    }
1415#endif
1416    if (pI128->mem.rbase_g == NULL)
1417	return FALSE;
1418
1419    pI128->mem.rbase_w = pI128->mem.rbase_g + ( 8 * 1024)/4;
1420    pI128->mem.rbase_a = pI128->mem.rbase_g + (16 * 1024)/4;
1421    pI128->mem.rbase_b = pI128->mem.rbase_g + (24 * 1024)/4;
1422    pI128->mem.rbase_i = pI128->mem.rbase_g + (32 * 1024)/4;
1423
1424    return TRUE;
1425}
1426
1427
1428/*
1429 * Unmap the framebuffer and MMIO memory.
1430 */
1431
1432static Bool
1433I128UnmapMem(ScrnInfoPtr pScrn)
1434{
1435    I128Ptr pI128 = I128PTR(pScrn);
1436
1437    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unmapping memory\n");
1438
1439    if (pI128->mem.rbase_g == NULL)
1440	return TRUE;
1441
1442    /*
1443     * Unmap IO registers to virtual address space
1444     */
1445    xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pI128->mem.mw0_ad,
1446	pI128->MemorySize*1024);
1447    pI128->mem.mw0_ad = NULL;
1448    pI128->MemoryPtr = NULL;
1449
1450    xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pI128->mem.rbase_g, 64*1024);
1451    pI128->mem.rbase_g = NULL;
1452    pI128->mem.rbase_w = NULL;
1453    pI128->mem.rbase_a = NULL;
1454    pI128->mem.rbase_b = NULL;
1455    pI128->mem.rbase_i = NULL;
1456
1457    return TRUE;
1458}
1459
1460
1461/*
1462 * This function saves the video state.
1463 */
1464static void
1465I128Save(ScrnInfoPtr pScrn)
1466{
1467    I128Ptr pI128 = I128PTR(pScrn);
1468    vgaHWPtr vgaHWP = VGAHWPTR(pScrn);
1469
1470    if (pI128->Primary)
1471	vgaHWSave(pScrn, &vgaHWP->SavedReg, VGA_SR_ALL);
1472
1473    I128SaveState(pScrn);
1474}
1475
1476/*
1477 * Restore the initial (text) mode.
1478 */
1479static void
1480I128Restore(ScrnInfoPtr pScrn)
1481{
1482    I128Ptr pI128 = I128PTR(pScrn);
1483    vgaHWPtr vgaHWP = VGAHWPTR(pScrn);
1484
1485    I128RestoreState(pScrn);
1486
1487    if (pI128->Primary) {
1488	vgaHWProtect(pScrn, TRUE);
1489	vgaHWRestore(pScrn, &vgaHWP->SavedReg, VGA_SR_ALL);
1490	vgaHWProtect(pScrn, FALSE);
1491    }
1492}
1493
1494/* Usually mandatory */
1495Bool
1496I128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
1497{
1498    return I128ModeInit(xf86Screens[scrnIndex], mode);
1499}
1500
1501
1502static Bool
1503I128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
1504{
1505    I128Ptr pI128 = I128PTR(pScrn);
1506
1507    if (pI128->Debug)
1508    	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ModeInit start\n");
1509
1510    /* Initialise the ModeReg values */
1511    pScrn->vtSema = TRUE;
1512
1513    if (!I128Init(pScrn, mode))
1514	return FALSE;
1515
1516    pI128->ModeSwitched = TRUE;
1517
1518    pI128->mode = mode;
1519
1520    if (pI128->Debug)
1521    	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ModeInit complete\n");
1522
1523    return TRUE;
1524}
1525
1526
1527/* Mandatory */
1528
1529/* This gets called at the start of each server generation */
1530
1531static Bool
1532I128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
1533{
1534    ScrnInfoPtr pScrn;
1535    I128Ptr pI128;
1536    int ret;
1537    VisualPtr visual;
1538    unsigned char *FBStart;
1539    int width, height, displayWidth;
1540
1541    /*
1542     * First get the ScrnInfoRec
1543     */
1544    pScrn = xf86Screens[pScreen->myNum];
1545
1546    pI128 = I128PTR(pScrn);
1547
1548    if (pI128->Debug)
1549    	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ScreenInit start\n");
1550
1551    /* Map the I128 memory and MMIO areas */
1552    if (!I128MapMem(pScrn))
1553        return FALSE;
1554
1555    pI128->MemoryPtr =
1556	    (pointer)&((char *)pI128->MemoryPtr)[pI128->displayOffset];
1557
1558    /* Save the current state */
1559    I128Save(pScrn);
1560
1561    /* Initialise the first mode */
1562    if (!I128ModeInit(pScrn, pScrn->currentMode))
1563        return FALSE;
1564
1565    /* Darken the screen for aesthetic reasons and set the viewport */
1566    I128SaveScreen(pScreen, SCREEN_SAVER_ON);
1567    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
1568
1569    /*
1570     * The next step is to setup the screen's visuals, and initialise the
1571     * framebuffer code.  In cases where the framebuffer's default
1572     * choices for things like visual layouts and bits per RGB are OK,
1573     * this may be as simple as calling the framebuffer's ScreenInit()
1574     * function.  If not, the visuals will need to be setup before calling
1575     * a fb ScreenInit() function and fixed up after.
1576     *
1577     * For most PC hardware at depths >= 8, the defaults that fb uses
1578     * are not appropriate.  In this driver, we fixup the visuals after.
1579     */
1580
1581    /*
1582     * Reset the visual list.
1583     */
1584    miClearVisualTypes();
1585
1586    /* Setup the visuals we support. */
1587
1588    if (!miSetVisualTypes(pScrn->depth,
1589			  miGetDefaultVisualMask(pScrn->depth),
1590			  pScrn->rgbBits, pScrn->defaultVisual))
1591	return FALSE;
1592
1593    if (!miSetPixmapDepths())
1594	return FALSE;
1595
1596
1597    /*
1598     * Call the framebuffer layer's ScreenInit function, and fill in other
1599     * pScreen fields.
1600     */
1601
1602    width = pScrn->virtualX;
1603    height = pScrn->virtualY;
1604    displayWidth = pScrn->displayWidth;
1605
1606    FBStart = pI128->MemoryPtr;
1607
1608    ret = fbScreenInit(pScreen, FBStart,
1609			width, height,
1610			pScrn->xDpi, pScrn->yDpi,
1611			displayWidth, pScrn->bitsPerPixel);
1612    if (!ret)
1613	return FALSE;
1614
1615    fbPictureInit(pScreen, 0, 0);
1616
1617    if (pScrn->bitsPerPixel > 8) {
1618        /* Fixup RGB ordering */
1619        visual = pScreen->visuals + pScreen->numVisuals;
1620        while (--visual >= pScreen->visuals) {
1621	    if ((visual->class | DynamicClass) == DirectColor) {
1622		visual->offsetRed = pScrn->offset.red;
1623		visual->offsetGreen = pScrn->offset.green;
1624		visual->offsetBlue = pScrn->offset.blue;
1625		visual->redMask = pScrn->mask.red;
1626		visual->greenMask = pScrn->mask.green;
1627		visual->blueMask = pScrn->mask.blue;
1628	    }
1629	}
1630    }
1631
1632    xf86SetBlackWhitePixels(pScreen);
1633
1634    if (!pI128->NoAccel) {
1635	if (pI128->exa)
1636            ret = I128ExaInit(pScreen);
1637        else {
1638            I128DGAInit(pScreen);
1639            ret = I128XaaInit(pScreen);
1640        }
1641    }
1642
1643    if (!ret) {
1644        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Acceleration setup failed\n");
1645        return FALSE;
1646    }
1647
1648    miInitializeBackingStore(pScreen);
1649    xf86SetBackingStore(pScreen);
1650    xf86SetSilkenMouse(pScreen);
1651
1652    /* Initialize software cursor.
1653	Must precede creation of the default colormap */
1654    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
1655
1656    /* Initialize HW cursor layer.
1657	Must follow software cursor initialization*/
1658    if (pI128->HWCursor) {
1659	ret = TRUE;
1660    	switch(pI128->RamdacType) {
1661	       case TI3025_DAC:
1662		  ret = I128TIHWCursorInit(pScrn); break;
1663	       case IBM524_DAC:
1664	       case IBM526_DAC:
1665	       case IBM528_DAC:
1666		  ret = I128IBMHWCursorInit(pScrn); break;
1667	       case SILVER_HAMMER_DAC:
1668		  ret = I128IBMHWCursorInit(pScrn); break;
1669	       default:
1670		  break;
1671	    }
1672	if(!ret)
1673	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1674		"Hardware cursor initialization failed\n");
1675    }
1676
1677    /* Initialise default colourmap */
1678    if (!miCreateDefColormap(pScreen))
1679	return FALSE;
1680
1681    /* Initialize colormap layer.
1682	Must follow initialization of the default colormap */
1683    if(!xf86HandleColormaps(pScreen, 256, 8,
1684	I128LoadPalette, NULL,
1685	CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH))
1686	return FALSE;
1687
1688    xf86DPMSInit(pScreen, I128DisplayPowerManagementSet, 0);
1689
1690    pScrn->memPhysBase = (unsigned long)pI128->MemoryPtr;
1691    pScrn->fbOffset = 0;
1692
1693    pScreen->SaveScreen = I128SaveScreen;
1694
1695    /* Wrap the current CloseScreen function */
1696    pI128->CloseScreen = pScreen->CloseScreen;
1697    pScreen->CloseScreen = I128CloseScreen;
1698
1699    /* Report any unused options (only for the first generation) */
1700    if (serverGeneration == 1) {
1701	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
1702    }
1703
1704    if (pI128->Debug)
1705    	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ScreenInit complete\n");
1706
1707    /* Done */
1708    return TRUE;
1709}
1710
1711
1712/*
1713 * This function is used to initialize the Start Address - the first
1714 * displayed location in the video memory.
1715 */
1716/* Usually mandatory */
1717void
1718I128AdjustFrame(int scrnIndex, int x, int y, int flags)
1719{
1720    ScrnInfoPtr pScrn;
1721    int   Base;
1722    I128Ptr pI128;
1723#define I128_PAN_MASK 0x01FFFFE0
1724
1725    pScrn = xf86Screens[scrnIndex];
1726    pI128 = I128PTR(pScrn);
1727
1728    if (pI128->ShowCache && y && pScrn->vtSema)
1729        y += pScrn->virtualY - 1;
1730
1731    if (x > (pI128->displayWidth - pI128->mode->HDisplay))
1732        x = pI128->displayWidth - pI128->mode->HDisplay;
1733
1734    Base = ((y*pI128->displayWidth + x) * (pI128->bitsPerPixel/8));
1735    pI128->mem.rbase_g[DB_ADR] =
1736	(Base & I128_PAN_MASK) + pI128->displayOffset; MB;
1737
1738    /* now warp the cursor after the screen move */
1739    pI128->AdjustCursorXPos = (Base - (Base & I128_PAN_MASK))
1740                             / (pI128->bitsPerPixel/8);
1741}
1742
1743/*
1744 * This is called when VT switching back to the X server.  Its job is
1745 * to reinitialise the video mode.
1746 *
1747 */
1748
1749/* Mandatory */
1750static Bool
1751I128EnterVT(int scrnIndex, int flags)
1752{
1753    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1754
1755    if (!I128ModeInit(pScrn, pScrn->currentMode))
1756	return FALSE;
1757    I128AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
1758    return TRUE;
1759}
1760
1761/*
1762 * This is called when VT switching away from the X server.  Its job is
1763 * to restore the previous (text) mode.
1764 *
1765 */
1766
1767/* Mandatory */
1768static void
1769I128LeaveVT(int scrnIndex, int flags)
1770{
1771    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1772
1773    I128Restore(pScrn);
1774}
1775
1776
1777/*
1778 * This is called at the end of each server generation.  It restores the
1779 * original (text) mode.  It should also unmap the video memory, and free
1780 * any per-generation data allocated by the driver.  It should finish
1781 * by unwrapping and calling the saved CloseScreen function.
1782 */
1783
1784/* Mandatory */
1785static Bool
1786I128CloseScreen(int scrnIndex, ScreenPtr pScreen)
1787{
1788    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1789    I128Ptr pI128 = I128PTR(pScrn);
1790
1791    if (pScrn->vtSema) {
1792	I128Restore(pScrn);
1793	I128UnmapMem(pScrn);
1794    }
1795    if (pI128->XaaInfoRec)
1796	XAADestroyInfoRec(pI128->XaaInfoRec);
1797    if (pI128->ExaDriver) {
1798        exaDriverFini(pScreen);
1799        xfree(pI128->ExaDriver);
1800    }
1801    if (pI128->CursorInfoRec)
1802    	xf86DestroyCursorInfoRec(pI128->CursorInfoRec);
1803    if (pI128->DGAModes)
1804    	xfree(pI128->DGAModes);
1805    pScrn->vtSema = FALSE;
1806
1807    pScreen->CloseScreen = pI128->CloseScreen;
1808    return (*pScreen->CloseScreen)(scrnIndex, pScreen);
1809}
1810
1811
1812/* Free up any persistent data structures */
1813
1814/* Optional */
1815static void
1816I128FreeScreen(int scrnIndex, int flags)
1817{
1818    /*
1819     * This only gets called when a screen is being deleted.  It does not
1820     * get called routinely at the end of a server generation.
1821     */
1822    if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
1823        vgaHWFreeHWRec(xf86Screens[scrnIndex]);
1824
1825    I128FreeRec(xf86Screens[scrnIndex]);
1826}
1827
1828
1829/* Checks if a mode is suitable for the selected chipset. */
1830
1831/* Optional */
1832static ModeStatus
1833I128ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
1834{
1835    int lace;
1836
1837    lace = 1 + ((mode->Flags & V_INTERLACE) != 0);
1838
1839    if ((mode->CrtcHDisplay <= 2048) &&
1840	(mode->CrtcHSyncStart <= 4096) &&
1841	(mode->CrtcHSyncEnd <= 4096) &&
1842	(mode->CrtcHTotal <= 4096) &&
1843	(mode->CrtcVDisplay <= 2048 * lace) &&
1844	(mode->CrtcVSyncStart <= 4096 * lace) &&
1845	(mode->CrtcVSyncEnd <= 4096 * lace) &&
1846	(mode->CrtcVTotal <= 4096 * lace)) {
1847	return(MODE_OK);
1848    } else {
1849	return(MODE_BAD);
1850    }
1851}
1852
1853
1854/* Do screen blanking */
1855
1856/* Mandatory */
1857static Bool
1858I128SaveScreen(ScreenPtr pScreen, int mode)
1859{
1860    ScrnInfoPtr pScrn = NULL;
1861    I128Ptr pI128;
1862    Bool on;
1863
1864    if (pScreen != NULL)
1865	pScrn = xf86Screens[pScreen->myNum];
1866
1867    on = xf86IsUnblank(mode);
1868
1869    if ((pScrn != NULL) && pScrn->vtSema) {
1870        pI128 = I128PTR(pScrn);
1871        if (on) {
1872	    pI128->mem.rbase_g[CRT_1CON] |= 0x40;                           MB;
1873	} else {
1874	    pI128->mem.rbase_g[CRT_1CON] &= ~0x40;                          MB;
1875	}
1876    }
1877    return TRUE;
1878}
1879
1880
1881static const int DDC_SDA_IN_MASK = 1 << 1;
1882static const int DDC_SDA_OUT_MASK = 1 << 2;
1883static const int DDC_SCL_IN_MASK = 1 << 3;
1884static const int DDC_SCL_OUT_MASK = 1 << 0;
1885
1886static const int DDC_MODE_MASK = 3 << 8;
1887#if 0
1888static const int DDC_MODE_DDC1 = 1 << 8;
1889#endif
1890static const int DDC_MODE_DDC2 = 2 << 8;
1891
1892#if 0
1893static unsigned int
1894I128DDC1Read(ScrnInfoPtr pScrn)
1895{
1896  I128Ptr pI128 = I128PTR(pScrn);
1897  unsigned char val;
1898  unsigned long tmp, ddc;
1899  IOADDRESS iobase;
1900
1901  iobase = pI128->RegRec.iobase;
1902  ddc = inl(iobase + 0x2C);
1903  if ((ddc & DDC_MODE_MASK) != DDC_MODE_DDC1) {
1904      outl(iobase + 0x2C, DDC_MODE_DDC1);
1905      usleep(40);
1906  }
1907
1908  /* wait for Vsync */
1909  do {
1910      tmp = inl(iobase + 0x2C);
1911  } while (tmp & 1);
1912  do {
1913      tmp = inl(iobase + 0x2C);
1914  } while (!(tmp & 1));
1915
1916  /* Get the result */
1917  tmp = inl(iobase + 0x2C);
1918  val = tmp & DDC_SDA_IN_MASK;
1919
1920  if ((ddc & DDC_MODE_MASK) != DDC_MODE_DDC1) {
1921      outl(iobase + 0x2C, ~DDC_MODE_MASK & ddc);
1922      usleep(40);
1923  }
1924
1925  return val;
1926}
1927#endif
1928
1929static void
1930I128I2CGetBits(I2CBusPtr b, int *clock, int *data)
1931{
1932  I128Ptr pI128 = I128PTR(xf86Screens[b->scrnIndex]);
1933  unsigned long ddc;
1934  IOADDRESS iobase;
1935#if 0
1936  static int lastclock = -1, lastdata = -1;
1937#endif
1938
1939  /* Get the result. */
1940  iobase = pI128->RegRec.iobase;
1941  ddc = inl(iobase + 0x2C);
1942
1943  *clock = (ddc & DDC_SCL_IN_MASK) != 0;
1944  *data  = (ddc & DDC_SDA_IN_MASK) != 0;
1945
1946#if 0
1947  if (pI128->Debug && ((lastclock != *clock) || (lastdata != *data))) {
1948    xf86DrvMsg(b->scrnIndex, X_INFO, "i2c> c %d d %d\n", *clock, *data);
1949    lastclock = *clock;
1950    lastdata = *data;
1951  }
1952#endif
1953}
1954
1955static void
1956I128I2CPutBits(I2CBusPtr b, int clock, int data)
1957{
1958  I128Ptr pI128 = I128PTR(xf86Screens[b->scrnIndex]);
1959  unsigned char drv, val;
1960  unsigned long ddc;
1961  unsigned long tmp;
1962  IOADDRESS iobase;
1963
1964  iobase = pI128->RegRec.iobase;
1965  ddc = inl(iobase + 0x2C);
1966
1967  val = (clock ? DDC_SCL_IN_MASK : 0) | (data ? DDC_SDA_IN_MASK : 0);
1968  drv = ((clock) ? DDC_SCL_OUT_MASK : 0) | ((data) ? DDC_SDA_OUT_MASK : 0);
1969
1970  tmp = (DDC_MODE_MASK & ddc) | val | drv;
1971  outl(iobase + 0x2C, tmp);
1972#if 0
1973  if (pI128->Debug)
1974    xf86DrvMsg(b->scrnIndex, X_INFO, "i2c> 0x%x\n", tmp);
1975#endif
1976}
1977
1978
1979static Bool
1980I128I2CInit(ScrnInfoPtr pScrn)
1981{
1982    I128Ptr pI128 = I128PTR(pScrn);
1983    I2CBusPtr I2CPtr;
1984    IOADDRESS iobase;
1985    unsigned long soft_sw, ddc;
1986
1987    I2CPtr = xf86CreateI2CBusRec();
1988    if(!I2CPtr) return FALSE;
1989
1990    pI128->I2C = I2CPtr;
1991
1992    I2CPtr->BusName    = "DDC";
1993    I2CPtr->scrnIndex  = pScrn->scrnIndex;
1994    I2CPtr->I2CPutBits = I128I2CPutBits;
1995    I2CPtr->I2CGetBits = I128I2CGetBits;
1996    I2CPtr->BitTimeout = 4;
1997    I2CPtr->ByteTimeout = 4;
1998    I2CPtr->AcknTimeout = 4;
1999    I2CPtr->StartTimeout = 4;
2000
2001    /* soft switch register bits 1,0 control I2C channel */
2002    iobase = pI128->RegRec.iobase;
2003    soft_sw = inl(iobase + 0x28);
2004    soft_sw &= 0xfffffffc;
2005    soft_sw |= 0x00000001;
2006    outl(iobase + 0x28, soft_sw);
2007    usleep(1000);
2008
2009    /* set default as ddc2 mode */
2010    ddc = inl(iobase + 0x2C);
2011    ddc &= ~DDC_MODE_MASK;
2012    ddc |= DDC_MODE_DDC2;
2013    outl(iobase + 0x2C, ddc);
2014    usleep(40);
2015
2016    if (!xf86I2CBusInit(I2CPtr)) {
2017        return FALSE;
2018    }
2019    return TRUE;
2020}
2021
2022
2023static xf86MonPtr
2024I128getDDC(ScrnInfoPtr pScrn)
2025{
2026  I128Ptr pI128 = I128PTR(pScrn);
2027  xf86MonPtr MonInfo = NULL;
2028
2029  /* Initialize I2C bus - used by DDC if available */
2030  if (pI128->i2cInit) {
2031    pI128->i2cInit(pScrn);
2032  }
2033  /* Read and output monitor info using DDC2 over I2C bus */
2034  if (pI128->I2C) {
2035    MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pI128->I2C);
2036    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I2C Monitor info: %p\n",
2037	       (void *)MonInfo);
2038    xf86PrintEDID(MonInfo);
2039    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of I2C Monitor info\n");
2040  }
2041  if (!MonInfo) {
2042    /* Read and output monitor info using DDC1 */
2043    if (pI128->ddc1Read) {
2044      MonInfo = xf86DoEDID_DDC1(pScrn->scrnIndex, NULL, pI128->ddc1Read ) ;
2045      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Monitor info: %p\n",
2046		 (void *)MonInfo);
2047      xf86PrintEDID(MonInfo);
2048      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of DDC Monitor info\n");
2049    }
2050  }
2051
2052  if (MonInfo)
2053    xf86SetDDCproperties(pScrn, MonInfo);
2054
2055  return MonInfo;
2056}
2057
2058
2059/*
2060 * I128DisplayPowerManagementSet --
2061 *
2062 * Sets VESA Display Power Management Signaling (DPMS) Mode.
2063 */
2064void
2065I128DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
2066			     int flags)
2067{
2068    I128Ptr pI128 = I128PTR(pScrn);
2069    CARD32 snc;
2070
2071    if (pI128->Debug)
2072	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128DisplayPowerManagementSet: %d\n", PowerManagementMode);
2073
2074    if (pI128->RamdacType == TI3025_DAC) return;
2075
2076    snc = pI128->mem.rbase_g[CRT_1CON];
2077
2078    switch (PowerManagementMode)
2079    {
2080    case DPMSModeOn:
2081	/* HSync: On, VSync: On */
2082	snc |= 0x30;
2083	break;
2084    case DPMSModeStandby:
2085	/* HSync: Off, VSync: On */
2086	snc = (snc & ~0x10) | 0x20;
2087	break;
2088    case DPMSModeSuspend:
2089	/* HSync: On, VSync: Off */
2090	snc = (snc & ~0x20) | 0x10;
2091	break;
2092    case DPMSModeOff:
2093	/* HSync: Off, VSync: Off */
2094	snc &= ~0x30;
2095	break;
2096    }
2097    pI128->mem.rbase_g[CRT_1CON] = snc;					MB;
2098}
2099
2100static void
2101I128DumpBaseRegisters(ScrnInfoPtr pScrn)
2102{
2103    I128Ptr pI128 = I128PTR(pScrn);
2104
2105    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2106	"  PCI Registers\n");
2107    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2108	"    MW0_AD    0x%08lx  addr 0x%08lx  %spre-fetchable\n",
2109	    (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 0, REGION_MEM),
2110	    (unsigned long)(PCI_REGION_BASE(pI128->PciInfo, 0, REGION_MEM) & 0xFFC00000),
2111	    PCI_REGION_BASE(pI128->PciInfo, 0, REGION_MEM) & 0x8 ? "" : "not-");
2112    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2113	"    MW1_AD    0x%08lx  addr 0x%08lx  %spre-fetchable\n",
2114	    (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 1, REGION_MEM),
2115	    (unsigned long)(PCI_REGION_BASE(pI128->PciInfo, 1, REGION_MEM) & 0xFFC00000),
2116	    PCI_REGION_BASE(pI128->PciInfo, 1, REGION_MEM) & 0x8 ? "" : "not-");
2117    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2118	"    XYW_AD(A) 0x%08lx  addr 0x%08lx\n",
2119	    (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 2, REGION_MEM),
2120	    (unsigned long)(PCI_REGION_BASE(pI128->PciInfo, 2, REGION_MEM) & 0xFFC00000));
2121    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2122	"    XYW_AD(B) 0x%08lx  addr 0x%08lx\n",
2123	    (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 3, REGION_MEM),
2124	    (unsigned long)(PCI_REGION_BASE(pI128->PciInfo, 3, REGION_MEM) & 0xFFC00000));
2125    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2126	"    RBASE_G   0x%08lx  addr 0x%08lx\n",
2127	    (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 4, REGION_MEM),
2128	    (unsigned long)(PCI_REGION_BASE(pI128->PciInfo, 4, REGION_MEM) & 0xFFFF0000));
2129    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2130	"    IO        0x%08lx  addr 0x%08lx\n",
2131	    (unsigned long)PCI_REGION_BASE(pI128->PciInfo, 5, REGION_IO),
2132	    (unsigned long)(PCI_REGION_BASE(pI128->PciInfo, 5, REGION_IO) & 0xFFFFFF00));
2133    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2134	"    SSC       0x%08x  addr 0x%08x\n",
2135    	    (unsigned int)PCI_SUB_DEVICE_ID(pI128->PciInfo),
2136	    (unsigned int)(PCI_SUB_DEVICE_ID(pI128->PciInfo) & 0xFFFFFF00));
2137    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2138	"    SSV       0x%08x  addr 0x%08x\n",
2139    	    (unsigned int)PCI_SUB_VENDOR_ID(pI128->PciInfo),
2140	    (unsigned int)(PCI_SUB_VENDOR_ID(pI128->PciInfo) & 0xFFFFFF00));
2141#ifndef XSERVER_LIBPCIACCESS
2142    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2143	"    RBASE_E   0x%08lx  addr 0x%08lx  %sdecode-enabled\n\n",
2144    	    pI128->PciInfo->biosBase,
2145	    pI128->PciInfo->biosBase & 0xFFFF8000,
2146	    pI128->PciInfo->biosBase & 0x1 ? "" : "not-");
2147
2148    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2149	"    PCICMDST  0x%08x       0x%08x\n",
2150   	    ((pciConfigPtr)pI128->PciInfo->thisCard)->pci_command,
2151   	    ((pciConfigPtr)pI128->PciInfo->thisCard)->pci_status);
2152#endif
2153
2154    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2155	"  IO Mapped Registers\n");
2156    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2157	"    RBASE_G   0x%08lx  addr 0x%08lx\n",
2158	    (unsigned long)pI128->io.rbase_g, pI128->io.rbase_g & 0xFFFFFF00UL);
2159    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2160	"    RBASE_W   0x%08lx  addr 0x%08lx\n",
2161	    (unsigned long)pI128->io.rbase_w, pI128->io.rbase_w & 0xFFFFFF00UL);
2162    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2163	"    RBASE_A   0x%08lx  addr 0x%08lx\n",
2164	    (unsigned long)pI128->io.rbase_a, pI128->io.rbase_a & 0xFFFFFF00UL);
2165    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2166	"    RBASE_B   0x%08lx  addr 0x%08lx\n",
2167	    (unsigned long)pI128->io.rbase_b, pI128->io.rbase_b & 0xFFFFFF00UL);
2168    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2169	"    RBASE_I   0x%08lx  addr 0x%08lx\n",
2170	    (unsigned long)pI128->io.rbase_i, pI128->io.rbase_i & 0xFFFFFF00UL);
2171    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2172	"    RBASE_E   0x%08lx  addr 0x%08lx  size 0x%lx\n\n",
2173	    (unsigned long)pI128->io.rbase_e, pI128->io.rbase_e & 0xFFFF8000UL,
2174	    pI128->io.rbase_e & 0x7UL);
2175
2176    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2177	"  Miscellaneous IO Registers\n");
2178    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2179	"    ID        0x%08lx\n", (unsigned long)pI128->io.id);
2180    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2181	"    CONFIG1   0x%08lx\n", (unsigned long)pI128->io.config1);
2182    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2183	"    CONFIG2   0x%08lx\n", (unsigned long)pI128->io.config2);
2184    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2185	"    SGRAM     0x%08lx\n", (unsigned long)pI128->io.sgram);
2186    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2187	"    SOFT_SW   0x%08lx\n", (unsigned long)pI128->io.soft_sw);
2188    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2189	"    VGA_CTL   0x%08lx\n", (unsigned long)pI128->io.vga_ctl);
2190}
2191
2192
2193void
2194I128DumpActiveRegisters(ScrnInfoPtr pScrn)
2195{
2196    I128Ptr pI128 = I128PTR(pScrn);
2197    IOADDRESS iobase;
2198    unsigned long rbase_g, rbase_w, rbase_a, rbase_b, rbase_i, rbase_e;
2199    unsigned long id, config1, config2, sgram, soft_sw, ddc, vga_ctl;
2200    volatile CARD32 *vrba, *vrbg, *vrbw;
2201
2202    vrba = pI128->mem.rbase_a;
2203    vrbg = pI128->mem.rbase_g;
2204    vrbw = pI128->mem.rbase_w;
2205
2206    iobase = pI128->RegRec.iobase;
2207    rbase_g = inl(iobase);
2208    rbase_w = inl(iobase + 0x04);
2209    rbase_a = inl(iobase + 0x08);
2210    rbase_b = inl(iobase + 0x0C);
2211    rbase_i = inl(iobase + 0x10);
2212    rbase_e = inl(iobase + 0x14);
2213    id = inl(iobase + 0x18);
2214    config1 = inl(iobase + 0x1C);
2215    config2 = inl(iobase + 0x20);
2216    sgram = inl(iobase + 0x24);
2217    soft_sw = inl(iobase + 0x28);
2218    ddc = inl(iobase + 0x2C);
2219    vga_ctl = inl(iobase + 0x30);
2220
2221    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "IO Mapped Registers\n");
2222    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2223		"  RBASE_G   0x%08lx  addr 0x%08lx\n",
2224       		rbase_g, rbase_g & 0xFFFFFF00);
2225    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2226		"  RBASE_W   0x%08lx  addr 0x%08lx\n",
2227       		rbase_w, rbase_w & 0xFFFFFF00);
2228    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2229		"  RBASE_A   0x%08lx  addr 0x%08lx\n",
2230       		rbase_a, rbase_a & 0xFFFFFF00);
2231    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2232		"  RBASE_B   0x%08lx  addr 0x%08lx\n",
2233       		rbase_b, rbase_b & 0xFFFFFF00);
2234    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2235		"  RBASE_I   0x%08lx  addr 0x%08lx\n",
2236       		rbase_i, rbase_i & 0xFFFFFF00);
2237    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2238		"  RBASE_E   0x%08lx  addr 0x%08lx  size 0x%lx\n",
2239       		rbase_e, rbase_e & 0xFFFF8000, rbase_e & 0x7);
2240
2241    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Miscellaneous IO Registers\n");
2242    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  ID        0x%08lx\n", id);
2243    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    REV  %ld  HBT %ld  BASE0 %ld  VDEN %ld  VB %ld  BASE1 %ld  BASE2 %ld  DS %ld\n",
2244    	id&7, (id>>3)&3, (id>>6)&3, (id>>8)&3, (id>>10)&1,
2245    	(id>>11)&3, (id>>13)&3, (id>>15)&1);
2246    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    DDEN %ld  DB  %ld  BASE3 %ld  BASER %ld  MDEN %ld  TR %ld  VS    %ld\n",
2247    	(id>>16)&3, (id>>18)&1, (id>>19)&3, (id>>21)&7, (id>>24)&3,
2248	(id>>26)&1, (id>>27)&1);
2249    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    CLASS %ld  EE %ld\n",
2250	(id>>28)&3, (id>>30)&1);
2251    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CONFIG1   0x%08lx\n", config1);
2252    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    VE %ld  SFT_RST %ld  ONE28 %ld  VS %ld\n",
2253    	config1&1, (config1>>1)&1,
2254    	(config1>>2)&1, (config1>>3)&1);
2255    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    G %ld  W %ld  A %ld  B %ld  I %ld  E %ld  W0 %ld  W1 %ld  XA %ld  XB %ld\n",
2256    	(config1>>8)&1, (config1>>9)&1,
2257    	(config1>>10)&1, (config1>>11)&1,
2258    	(config1>>12)&1, (config1>>13)&1,
2259    	(config1>>16)&1, (config1>>17)&1,
2260    	(config1>>20)&1, (config1>>21)&1);
2261    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    HBPRI %ld  VBPRI %ld  DE1PRI %ld  ISAPRI %ld\n",
2262    	(config1>>24)&3, (config1>>26)&3,
2263    	(config1>>28)&3, (config1>>30)&3);
2264    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CONFIG2   0x%08lx\n", config2);
2265    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    DWT %lx  EWS %lx  DWS %lx  MC %lx  FBB %ld  IOB %ld  FST %ld  CNT %ld  DEC %ld\n",
2266    	config2&0x3, (config2>>8)&0xF,
2267    	(config2>>16)&0x7, (config2>>20)&0xF,
2268    	(config2>>24)&1, (config2>>25)&1,
2269    	(config2>>26)&1, (config2>>27)&1,
2270    	(config2>>28)&1);
2271    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    PRE %ld  RVD %ld  SDAC %ld\n",
2272	(config2>>29)&1, (config2>>30)&1, (config2>>31)&1);
2273    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  SGRAM     0x%08lx\n", sgram);
2274    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  SOFT_SW   0x%08lx\n", soft_sw);
2275    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DDC       0x%08lx\n", ddc);
2276    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  VGA_CTL   0x%08lx\n", vga_ctl);
2277    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    MEMMUX %ld  VGADEC %ld  VIDMUX %ld  ENA %ld  BUFSEL %ld  STR %ld\n",
2278    	vga_ctl&1, (vga_ctl>>1)&1,
2279    	(vga_ctl>>2)&1, (vga_ctl>>3)&1,
2280    	(vga_ctl>>4)&1, (vga_ctl>>5)&1);
2281    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    3C2 %ld  DACDEC %ld  MSK 0x%02lx\n",
2282    	(vga_ctl>>6)&1,
2283    	(vga_ctl>>7)&1,
2284    	(vga_ctl>>8)&0xff);
2285
2286    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT Registers\n");
2287    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  INT_VCNT 0x%08lx  (%ld)\n",
2288    	vrbg[0x20/4]&0x000000FFUL, vrbg[0x20/4]&0x000000FFUL);
2289    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  INT_HCNT 0x%08lx  (%ld)\n",
2290    	vrbg[0x24/4]&0x00000FFFUL, vrbg[0x24/4]&0x00000FFFUL);
2291    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DB_ADR   0x%08lx  (%ld)\n",
2292    	vrbg[0x28/4]&0x01FFFFF0UL, vrbg[0x28/4]&0x01FFFFF0UL);
2293    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DB_PTCH  0x%08lx  (%ld)\n",
2294    	vrbg[0x2C/4]&0x0000FFF0UL, vrbg[0x2C/4]&0x0000FFF0UL);
2295    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_HAC  0x%08lx  (%ld)\n",
2296    	vrbg[0x30/4]&0x00003FFFUL, vrbg[0x30/4]&0x00003FFFUL);
2297    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_HBL  0x%08lx  (%ld)\n",
2298    	vrbg[0x34/4]&0x00003FFFUL, vrbg[0x34/4]&0x00003FFFUL);
2299    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_HFP  0x%08lx  (%ld)\n",
2300    	vrbg[0x38/4]&0x00003FFFUL, vrbg[0x38/4]&0x00003FFFUL);
2301    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_HS   0x%08lx  (%ld)\n",
2302    	vrbg[0x3C/4]&0x00003FFFUL, vrbg[0x3C/4]&0x00003FFFUL);
2303    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_VAC  0x%08lx  (%ld)\n",
2304    	vrbg[0x40/4]&0x00000FFFUL, vrbg[0x40/4]&0x00000FFFUL);
2305    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_VBL  0x%08lx  (%ld)\n",
2306    	vrbg[0x44/4]&0x00000FFFUL, vrbg[0x44/4]&0x00000FFFUL);
2307    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_VFP  0x%08lx  (%ld)\n",
2308    	vrbg[0x48/4]&0x00000FFFUL, vrbg[0x48/4]&0x00000FFFUL);
2309    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_VS   0x%08lx  (%ld)\n",
2310    	vrbg[0x4C/4]&0x00000FFFUL, vrbg[0x4C/4]&0x00000FFFUL);
2311    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_LCNT 0x%08lx\n",
2312	vrbg[0x50/4]&0x00000FFFUL);
2313    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_ZOOM 0x%08lx\n",
2314	vrbg[0x54/4]&0x0000000FUL);
2315    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_1CON 0x%08lx  PH %ld  PV %ld  CS %ld INL %ld H/VSE %ld/%ld VE %ld BTS %ld\n",
2316        (unsigned long)vrbg[0x58/4],
2317    	vrbg[0x58/4]&1UL, (vrbg[0x58/4]>>1)&1UL, (vrbg[0x58/4]>>2)&1UL,
2318    	(vrbg[0x58/4]>>3)&1UL, (vrbg[0x58/4]>>4)&1UL, (vrbg[0x58/4]>>5)&1UL,
2319    	(vrbg[0x58/4]>>6)&1UL, (vrbg[0x58/4]>>8)&1UL);
2320
2321    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CRT_2CON 0x%08lx  MEM %ld  RFR %ld  TRD %ld  SPL %ld\n",
2322        (unsigned long)vrbg[0x5C/4],
2323    	vrbg[0x5C/4]&7UL, (vrbg[0x5C/4]>>8)&1UL,
2324    	(vrbg[0x5C/4]>>16)&7UL, (vrbg[0x5C/4]>>24)&1UL);
2325
2326    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory Windows Registers\n");
2327    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW0_CTRL 0x%08lx\n",
2328	(unsigned long)vrbw[0x00]);
2329    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    AMV %ld  MP %ld  AMD %ld  SEN %ld  BSY %ld  MDM %ld  DEN %ld  PSZ %ld\n",
2330    	(vrbw[0x00]>>1)&1UL, (vrbw[0x00]>>2)&1UL, (vrbw[0x00]>>3)&1UL,
2331    	(vrbw[0x00]>>4)&3UL, (vrbw[0x00]>>8)&1UL, (vrbw[0x00]>>21)&3UL,
2332    	(vrbw[0x00]>>24)&3UL, (vrbw[0x00]>>26)&3UL);
2333    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "M/V/DSE %ld/%ld/%ld\n",
2334	(vrbw[0x00]>>28)&1UL, (vrbw[0x00]>>29)&1UL, (vrbw[0x00]>>30)&1UL);
2335    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW0_AD    0x%08lx  MW0_SZ    0x%08lx  MW0_PGE   0x%08lx\n",
2336    	vrbw[0x04/4]&0xFFFFF000UL, vrbw[0x08/4]&0x0000000FUL,
2337    	vrbw[0x0C/4]&0x000F001FUL);
2338    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW0_ORG10 0x%08lx  MW0_ORG14 0x%08lx  MW0_MSRC  0x%08lx\n",
2339    	vrbw[0x10/4]&0x01FFF000UL, vrbw[0x14/4]&0x01FFF000UL,
2340    	vrbw[0x18/4]&0x00FFFF00UL);
2341    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW0_WKEY  0x%08lx  MW0_KYDAT 0x%08lx  MW0_MASK  0x%08lx\n",
2342    	(unsigned long)vrbw[0x1C/4], vrbw[0x20/4]&0x000F000FUL,
2343	(unsigned long)vrbw[0x24/4]);
2344    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW1_CTRL 0x%08lx\n",
2345	(unsigned long)vrbw[0x28/4]);
2346    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    AMV %ld  MP %ld  AMD %ld  SEN %ld  BSY %ld  MDM %ld  DEN %ld  PSZ %ld\n",
2347    	(vrbw[0x28/4]>>1)&1UL, (vrbw[0x28/4]>>2)&1UL, (vrbw[0x28/4]>>3)&1UL,
2348    	(vrbw[0x28/4]>>4)&3UL, (vrbw[0x28/4]>>8)&1UL, (vrbw[0x28/4]>>21)&3UL,
2349    	(vrbw[0x28/4]>>24)&3UL, (vrbw[0x28/4]>>26)&3UL);
2350    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "M/V/DSE %ld/%ld/%ld\n",
2351	(vrbw[0x28/4]>>28)&1UL, (vrbw[0x28/4]>>29)&1UL, (vrbw[0x28/4]>>30)&1UL);
2352    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW1_AD    0x%08lx  MW1_SZ    0x%08lx  MW1_PGE   0x%08lx\n",
2353    	vrbw[0x2C/4]&0xFFFFF000UL, vrbw[0x30/4]&0x0000000FUL,
2354    	vrbw[0x34/4]&0x000F001FUL);
2355    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW1_ORG10 0x%08lx  MW1_ORG14 0x%08lx  MW1_MSRC  0x%08lx\n",
2356    	vrbw[0x38/4]&0x01FFF000UL, vrbw[0x3c/4]&0x01FFF000UL,
2357    	vrbw[0x40/4]&0x00FFFF00UL);
2358    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MW1_WKEY  0x%08lx  MW1_KYDAT 0x%08lx  MW1_MASK  0x%08lx\n",
2359    	(unsigned long)vrbw[0x44/4], vrbw[0x48/4]&0x000F000FUL,
2360	(unsigned long)vrbw[0x4C/4]);
2361
2362    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Engine A Registers\n");
2363    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  INTP      0x%08lx\n",
2364	vrba[0x00/4]&0x03UL);
2365    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  INTM      0x%08lx\n",
2366	vrba[0x04/4]&0x03UL);
2367    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  FLOW      0x%08lx\n",
2368	vrba[0x08/4]&0x0FUL);
2369    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  BUSY      0x%08lx\n",
2370	vrba[0x0C/4]&0x01UL);
2371    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XYW_AD    0x%08lx  SIZE 0x%lx  ADDR 0x%lx\n",
2372    	vrba[0x10/4]&0xFFFFFF00UL, (vrba[0x10/4]>>8)&0x0000000FUL,
2373    	vrba[0x10/4]&0xFFFFF000UL);
2374    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  ZCTL      0x%08lx\n",
2375	(unsigned long)vrba[0x18/4]);
2376    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  BUF_CTRL  0x%08lx\n",
2377	(unsigned long)vrba[0x20/4]);
2378    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    AMV %ld  MP %ld  AMD %ld  SEN %ld  DEN %ld  DSE %ld  VSE %ld  MSE %ld\n",
2379    	(vrba[0x20/4]>>1)&1UL, (vrba[0x20/4]>>2)&1UL, (vrba[0x20/4]>>3)&1UL,
2380    	(vrba[0x20/4]>>8)&3UL, (vrba[0x20/4]>>10)&3UL, (vrba[0x20/4]>>12)&1UL,
2381    	(vrba[0x20/4]>>13)&1UL, (vrba[0x20/4]>>14)&1UL);
2382    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    PS %ld  MDM %ld  PSIZE %ld  CRCO %ld\n",
2383	(vrba[0x20/4]>>16)&0x1FUL,
2384    	(vrba[0x20/4]>>21)&3UL, (vrba[0x20/4]>>24)&3UL, (vrba[0x20/4]>>30)&3UL);
2385    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_PGE    0x%08lx  DVPGE 0x%lx  MPGE 0x%lx\n",
2386    	vrba[0x24/4]&0x000F001FUL, (vrba[0x24/4]>>8)&0x01FUL,
2387    	(vrba[0x24/4]&0x000F0000UL)>>16);
2388    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_SORG   0x%08lx\n",
2389	vrba[0x28/4]&0x0FFFFFFFUL);
2390    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_DORG   0x%08lx\n",
2391	vrba[0x2C/4]&0x0FFFFFFFUL);
2392    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_MSRC   0x%08lx\n",
2393	vrba[0x30/4]&0x03FFFFF0UL);
2394    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_WKEY   0x%08lx\n",
2395	(unsigned long)vrba[0x38/4]);
2396    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_ZPTCH  0x%08lx\n",
2397	vrba[0x3C/4]&0x000FFFF0UL);
2398    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_SPTCH  0x%08lx\n",
2399	vrba[0x40/4]&0x0000FFF0UL);
2400    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  DE_DPTCH  0x%08lx\n",
2401	vrba[0x44/4]&0x0000FFF0UL);
2402    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD       0x%08lx\n",
2403	vrba[0x48/4]&0x7FFFFFFFUL);
2404    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    OPC 0x%02lx  ROP 0x%02lx  STYLE 0x%02lx  CLP 0x%lx  PATRN 0x%lx  HDF %ld\n",
2405    	vrba[0x48/4]&0x00FFUL, (vrba[0x48/4]>>8)&0x00FFUL, (vrba[0x48/4]>>16)&0x001FUL,
2406    	(vrba[0x48/4]>>21)&7UL, (vrba[0x48/4]>>24)&0x0FUL, (vrba[0x48/4]>>28)&7UL);
2407    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_SHADE 0x%02lx\n",
2408	vrba[0x4C/4]&0x00FFUL);
2409    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_OPC   0x%02lx\n",
2410	vrba[0x50/4]&0x00FFUL);
2411    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_ROP   0x%02lx\n",
2412	vrba[0x54/4]&0x00FFUL);
2413    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_STYLE 0x%02lx\n",
2414	vrba[0x58/4]&0x001FUL);
2415    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_PATRN 0x%02lx\n",
2416	vrba[0x5C/4]&0x000FUL);
2417    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_CLP   0x%02lx\n",
2418	vrba[0x60/4]&0x0007UL);
2419    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CMD_HDF   0x%02lx\n",
2420	vrba[0x64/4]&0x0007UL);
2421    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  FORE      0x%08lx\n",
2422	(unsigned long)vrba[0x68/4]);
2423    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  BACK      0x%08lx\n",
2424	(unsigned long)vrba[0x6C/4]);
2425    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  MASK      0x%08lx\n",
2426	(unsigned long)vrba[0x70/4]);
2427    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  RMSK      0x%08lx\n",
2428	(unsigned long)vrba[0x74/4]);
2429    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  LPAT      0x%08lx\n",
2430	(unsigned long)vrba[0x78/4]);
2431    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  PCTRL     0x%08lx\n",
2432	(unsigned long)vrba[0x7C/4]);
2433    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "    PLEN 0x%02ld  PSCL 0x%02ld  SPTR 0x%02ld  SSCL 0x%lx  STATE 0x%04lx\n",
2434    	vrba[0x7C/4]&0x1FUL, (vrba[0x7C/4]>>5)&7UL, (vrba[0x7C/4]>>8)&0x1FUL,
2435    	(vrba[0x7C/4]>>13)&7UL, (vrba[0x7C/4]>>16)&0xFFFFUL);
2436    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CLPTL     0x%08lx  CLPTLY 0x%04lx  CLPTLX 0x%04lx\n",
2437    	(unsigned long)vrba[0x80/4], vrba[0x80/4]&0x00FFFFUL, (vrba[0x80/4]>>16)&0x00FFFFUL);
2438    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  CLPBR     0x%08lx  CLPBRY 0x%04lx  CLPBRX 0x%04lx\n",
2439    	(unsigned long)vrba[0x84/4],
2440	vrba[0x84/4]&0x00FFFFUL, (vrba[0x84/4]>>16)&0x00FFFFUL);
2441    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY0       0x%08lx\n",
2442	(unsigned long)vrba[0x88/4]);
2443    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY1       0x%08lx\n",
2444	(unsigned long)vrba[0x8C/4]);
2445    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY2       0x%08lx\n",
2446	(unsigned long)vrba[0x90/4]);
2447    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY3       0x%08lx\n",
2448	(unsigned long)vrba[0x94/4]);
2449    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY4       0x%08lx\n",
2450	(unsigned long)vrba[0x98/4]);
2451    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY5       0x%08lx\n",
2452	(unsigned long)vrba[0x9C/4]);
2453    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY6       0x%08lx\n",
2454	(unsigned long)vrba[0xA0/4]);
2455    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY7       0x%08lx\n",
2456	(unsigned long)vrba[0xA4/4]);
2457    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "  XY8       0x%08lx\n",
2458	(unsigned long)vrba[0xA8/4]);
2459    if (pI128->RamdacType != TI3025_DAC)
2460	I128DumpIBMDACRegisters(pScrn, vrbg);
2461}
2462
2463static const unsigned char ibm52Xmask[0xA0] = {
24640xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   /* 00-07 */
24650xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,   /* 08-0F */
24660xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00,   /* 10-17 */
24670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 18-1F */
24680xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,   /* 20-27 */
24690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 28-2F */
24700xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,   /* 30-37 */
24710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 38-3F */
24720xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   /* 40-47 */
24730xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 48-4F */
24740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 58-5F */
24750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 58-5F */
24760xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 60-67 */
24770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 68-6F */
24780xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,   /* 70-77 */
24790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 78-7F */
24800x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,   /* 80-87 */
24810xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,   /* 88-8F */
24820xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,   /* 90-97 */
24830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 98-9F */
2484};
2485
2486static void
2487I128DumpIBMDACRegisters(ScrnInfoPtr pScrn, volatile CARD32 *vrbg)
2488{
2489	unsigned char ibmr[0x100];
2490	char buf[128], tbuf[10];
2491	int i;
2492
2493	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "IBM52X Registers\n");
2494
2495	vrbg[IDXH_I] = 0x00;
2496	vrbg[IDXH_I] = 0x00;
2497	vrbg[IDXCTL_I] = 0x01;
2498	buf[0] = '\0';
2499
2500	for (i=0; i<0xA0; i++) {
2501		if ((i%16 == 0) && (i != 0)) {
2502			xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%s\n", buf);
2503			buf[0] = '\0';
2504		}
2505		if (ibm52Xmask[i] == 0x00) {
2506			strcat(buf, " ..");
2507		} else {
2508			vrbg[IDXL_I] = i;
2509			ibmr[i] = vrbg[DATA_I] & 0xFF;
2510			ibmr[i] &= ibm52Xmask[i];
2511			sprintf(tbuf, " %02x", ibmr[i]);
2512			strcat(buf, tbuf);
2513		}
2514	}
2515	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%s\n", buf);
2516}
2517
2518