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