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