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