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