alp_driver.c revision 9586ba5a
1/*
2 * Driver for CL-GD5480.
3 * Itai Nahshon.
4 *
5 * Support for the CL-GD7548: David Monniaux
6 *
7 * This is mainly a cut & paste from the MGA driver.
8 * Original autors and contributors list include:
9 *    Radoslaw Kapitan, Andrew Vanderstock, Dirk Hohndel,
10 *    David Dawes, Andrew E. Mileski, Leonard N. Zubkoff,
11 *    Guy DESBIEF
12 */
13
14#ifdef HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18/* All drivers should typically include these */
19#include "xf86.h"
20#include "xf86_OSproc.h"
21
22/* All drivers need this */
23
24/* Everything using inb/outb, etc needs "compiler.h" */
25#include "compiler.h"
26
27/* Drivers that need to access the PCI config space directly need this */
28#include "xf86Pci.h"
29
30/* All drivers using the vgahw module need this */
31/* This driver needs to be modified to not use vgaHW for multihead operation */
32#include "vgaHW.h"
33
34#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
35#include "xf86RAC.h"
36#include "xf86Resources.h"
37#endif
38
39/* All drivers initialising the SW cursor need this */
40#include "mipointer.h"
41
42#include "micmap.h"
43
44/* Needed by the Shadow Framebuffer */
45#include "shadowfb.h"
46
47/* Note: can HWCUR64 be set even though the hw cursor is disabled for
48   want of memory ? */
49
50/* Framebuffer memory manager */
51#include "xf86fbman.h"
52
53#if HAVE_XF4BPP
54#include "xf4bpp.h"
55#endif
56#if HAVE_XF1BPP
57#include "xf1bpp.h"
58#endif
59
60#include "fb.h"
61
62
63#include "xf86DDC.h"
64#include "xf86int10.h"
65
66#include "cir.h"
67#define _ALP_PRIVATE_
68#include "alp.h"
69
70#include "xf86xv.h"
71#include <X11/extensions/Xv.h>
72
73#ifdef ALPPROBEI2C
74/* For debugging... should go away. */
75static void AlpProbeI2C(int scrnIndex);
76#endif
77
78/*
79 * Forward definitions for the functions that make up the driver.
80 */
81
82/* Mandatory functions */
83
84Bool AlpPreInit(ScrnInfoPtr pScrn, int flags);
85Bool AlpScreenInit(SCREEN_INIT_ARGS_DECL);
86Bool AlpEnterVT(VT_FUNC_ARGS_DECL);
87void AlpLeaveVT(VT_FUNC_ARGS_DECL);
88static Bool	AlpCloseScreen(CLOSE_SCREEN_ARGS_DECL);
89static Bool	AlpSaveScreen(ScreenPtr pScreen, int mode);
90
91/* Required if the driver supports mode switching */
92Bool AlpSwitchMode(SWITCH_MODE_ARGS_DECL);
93/* Required if the driver supports moving the viewport */
94void AlpAdjustFrame(ADJUST_FRAME_ARGS_DECL);
95
96/* Optional functions */
97void AlpFreeScreen(FREE_SCREEN_ARGS_DECL);
98ModeStatus AlpValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
99			Bool verbose, int flags);
100/* Internally used functions */
101static void	AlpSave(ScrnInfoPtr pScrn);
102static void	AlpRestore(ScrnInfoPtr pScrn);
103static Bool	AlpModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
104
105static void AlpProbeLCD(ScrnInfoPtr pScrn);
106
107static void AlpSetClock(CirPtr pCir, vgaHWPtr hwp, int freq);
108
109static void AlpOffscreenAccelInit(ScrnInfoPtr pScrn);
110
111static void	AlpDisplayPowerManagementSet(ScrnInfoPtr pScrn,
112											int PowerManagementMode, int flags);
113
114#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
115static void PC98CIRRUS755xEnable(ScrnInfoPtr pScrn);
116static void PC98CIRRUS755xDisable(ScrnInfoPtr pScrn);
117#endif
118
119/*
120 * This is intentionally screen-independent.  It indicates the binding
121 * choice made in the first PreInit.
122 */
123static int pix24bpp = 0;
124
125typedef enum {
126	OPTION_HW_CURSOR,
127	OPTION_PCI_RETRY,
128	OPTION_NOACCEL,
129	OPTION_MMIO,
130	OPTION_ROTATE,
131	OPTION_SHADOW_FB,
132	OPTION_MEMCFG1,
133	OPTION_MEMCFG2
134} CirOpts;
135
136static const OptionInfoRec CirOptions[] = {
137	{ OPTION_HW_CURSOR,	"HWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
138	{ OPTION_NOACCEL,	"NoAccel",	OPTV_BOOLEAN,	{0}, FALSE },
139	{ OPTION_MMIO,		"MMIO",		OPTV_BOOLEAN,	{0}, FALSE },
140	{ OPTION_SHADOW_FB,	"ShadowFB",	OPTV_BOOLEAN,	{0}, FALSE },
141	{ OPTION_ROTATE, 	 "Rotate",	OPTV_ANYSTR,	{0}, FALSE },
142	{ OPTION_MEMCFG1,	"MemCFG1",	OPTV_INTEGER,	{0}, -1 },
143	{ OPTION_MEMCFG2,	"MemCFG2",	OPTV_INTEGER,	{0}, -1 },
144	{ -1,				NULL,		OPTV_NONE,		{0}, FALSE }
145};
146
147/*                                1/4bpp   8bpp   15/16bpp  24bpp  32bpp
148static int unsupp_MaxClocks[] = {      0,      0,      0,      0,      0 }; */
149static int gd5430_MaxClocks[] = {  85500,  85500,  50000,  28500,      0 };
150static int gd5446_MaxClocks[] = { 135100, 135100,  85500,  85500,      0 };
151static int gd5480_MaxClocks[] = { 135100, 200000, 200000, 135100, 135100 };
152static int gd7548_MaxClocks[] = {  80100,  80100,  80100,  80100,  80100 };
153static int gd7555_MaxClocks[] = {  80100,  80100,  80100,  80100,  80100 };
154static int gd7556_MaxClocks[] = {  80100,  80100,  80100,  80100,  80100 };
155
156#ifdef XFree86LOADER
157
158#define ALP_MAJOR_VERSION 1
159#define ALP_MINOR_VERSION 0
160#define ALP_PATCHLEVEL 0
161
162static MODULESETUPPROTO(alpSetup);
163
164static XF86ModuleVersionInfo alpVersRec =
165{
166	"cirrus_alpine",
167	MODULEVENDORSTRING,
168	MODINFOSTRING1,
169	MODINFOSTRING2,
170	XORG_VERSION_CURRENT,
171	ALP_MAJOR_VERSION, ALP_MINOR_VERSION, ALP_PATCHLEVEL,
172	ABI_CLASS_VIDEODRV,			/* This is a video driver */
173	ABI_VIDEODRV_VERSION,
174	MOD_CLASS_NONE,
175	{0,0,0,0}
176};
177
178/*
179 * This is the module init data.
180 * Its name has to be the driver name followed by ModuleData.
181 */
182_X_EXPORT XF86ModuleData cirrus_alpineModuleData = {
183    &alpVersRec,
184    alpSetup,
185    NULL
186};
187
188static pointer
189alpSetup(pointer module, pointer opts, int *errmaj, int *errmin)
190{
191	static Bool setupDone = FALSE;
192	if (!setupDone) {
193		setupDone = TRUE;
194	}
195	return (pointer)1;
196}
197
198#endif /* XFree86LOADER */
199
200_X_EXPORT const OptionInfoRec *
201AlpAvailableOptions(int chipid)
202{
203    return CirOptions;
204}
205
206_X_EXPORT ScrnInfoPtr
207AlpProbe(int entity)
208{
209    ScrnInfoPtr pScrn = NULL;
210
211    if ((pScrn = xf86ConfigPciEntity(pScrn, 0, entity, CIRPciChipsets,
212					   NULL,NULL, NULL, NULL, NULL))) {
213	pScrn->PreInit		= AlpPreInit;
214	pScrn->ScreenInit	= AlpScreenInit;
215	pScrn->SwitchMode	= AlpSwitchMode;
216	pScrn->AdjustFrame	= AlpAdjustFrame;
217	pScrn->EnterVT		= AlpEnterVT;
218	pScrn->LeaveVT		= AlpLeaveVT;
219	pScrn->FreeScreen	= AlpFreeScreen;
220	pScrn->ValidMode	= AlpValidMode;
221    }
222
223    return pScrn;
224}
225
226
227static Bool
228AlpGetRec(ScrnInfoPtr pScrn)
229{
230#ifdef ALP_DEBUG
231	ErrorF("AlpGetRec\n");
232#endif
233	if (pScrn->driverPrivate != NULL)
234		return TRUE;
235
236	pScrn->driverPrivate = xnfcalloc(sizeof(CirRec), 1);
237	((CirPtr)pScrn->driverPrivate)->chip.alp = xnfcalloc(sizeof(AlpRec),1);
238
239#ifdef ALP_DEBUG
240	ErrorF("AlpGetRec 0x%x\n", CIRPTR(pScrn));
241#endif
242	return TRUE;
243}
244
245static void
246AlpFreeRec(ScrnInfoPtr pScrn)
247{
248	if (pScrn->driverPrivate == NULL)
249		return;
250	free(pScrn->driverPrivate);
251	pScrn->driverPrivate = NULL;
252}
253
254
255/*
256 * AlpCountRAM --
257 *
258 * Counts amount of installed RAM
259 *
260 * XXX Can use options to configure memory on non-primary cards.
261 */
262static int
263AlpCountRam(ScrnInfoPtr pScrn)
264{
265    CirPtr pCir = CIRPTR(pScrn);
266    vgaHWPtr hwp = VGAHWPTR(pScrn);
267    MessageType from;
268    int videoram = 0;
269
270    /* Map the Alp memory and MMIO areas */
271    pCir->FbMapSize = 1024*1024; /* XX temp */
272    if (!pCir->IoMapSize)
273    	pCir->IoMapSize = 0x4000;	/* 16K for moment */
274    if (!CirMapMem(pCir, pScrn->scrnIndex))
275	return 0;
276
277    /* The 754x supports MMIO for the BitBlt engine but
278       not for the VGA registers */
279    switch (pCir->Chipset)
280    {
281    case PCI_CHIP_GD7548:
282      break;
283    default:
284      if (pCir->UseMMIO)
285	vgaHWSetMmioFuncs(hwp, pCir->IOBase, -0x3C0);
286    }
287
288    if (pCir->chip.alp->sr0f != (CARD32)-1) {
289	from = X_CONFIG;
290	hwp->writeSeq(hwp, 0x0F, pCir->chip.alp->sr0f);
291    } else {
292	from = X_PROBED;
293	pCir->chip.alp->sr0f = hwp->readSeq(hwp, 0x0F);
294    }
295    xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 1 is 0x%02X\n",
296	       (unsigned int)pCir->chip.alp->sr0f);
297
298    switch (pCir->Chipset) {
299    case PCI_CHIP_GD5430:
300/*  case PCI_CHIP_GD5440: */
301	switch (pCir->chip.alp->sr0f & 0x18) {
302	case 0x08:
303	    videoram =  512;
304	    break;
305	case 0x10:
306	    videoram = 1024;
307	    break;
308	case 0x18:
309	    videoram = 2048;
310	    break;
311	}
312	break;
313
314    case PCI_CHIP_GD5434_4:
315    case PCI_CHIP_GD5434_8:
316    case PCI_CHIP_GD5436:
317	switch (pCir->chip.alp->sr0f & 0x18) {
318	case 0x10:
319	    videoram = 1024;
320	    break;
321	case 0x18:
322	    videoram = 2048;
323	    if (pCir->chip.alp->sr0f & 0x80)
324		videoram = 4096;
325	    break;
326	}
327
328    case PCI_CHIP_GD5446:
329	videoram = 1024;
330
331	if (pCir->chip.alp->sr17 != (CARD32)-1) {
332	    from = X_CONFIG;
333	    hwp->writeSeq(hwp, 0x17, pCir->chip.alp->sr17);
334	} else {
335	    from = X_PROBED;
336	    pCir->chip.alp->sr17 = hwp->readSeq(hwp, 0x17);
337	}
338	xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 2 is 0x%02X\n",
339		   (unsigned int)pCir->chip.alp->sr17);
340
341	if ((pCir->chip.alp->sr0f & 0x18) == 0x18) {
342	    if (pCir->chip.alp->sr0f & 0x80) {
343		if (pCir->chip.alp->sr17 & 0x80)
344		    videoram = 2048;
345		else if (pCir->chip.alp->sr17 & 0x02)
346		    videoram = 3072;
347		else
348		    videoram = 4096;
349	    } else {
350		if ((pCir->chip.alp->sr17 & 80) == 0)
351		    videoram = 2048;
352	    }
353	}
354	break;
355
356    case PCI_CHIP_GD5480:
357	if (pCir->chip.alp->sr17 != (CARD32)-1) {
358	    from = X_CONFIG;
359	    hwp->writeSeq(hwp, 0x17, pCir->chip.alp->sr17);
360	} else {
361	    from = X_PROBED;
362	    pCir->chip.alp->sr17 = hwp->readSeq(hwp, 0x17);
363	}
364	xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 2 is 0x%02X\n",
365		   (unsigned int)pCir->chip.alp->sr17);
366	videoram = 1024;
367	if ((pCir->chip.alp->sr0f & 0x18) == 0x18) {	/* 2 or 4 MB */
368	    videoram = 2048;
369	    if (pCir->chip.alp->sr0f & 0x80)	/* Second bank enable */
370		videoram = 4096;
371	}
372	if (pCir->chip.alp->sr17 & 0x80)
373	    videoram <<= 1;
374	break;
375
376    case PCI_CHIP_GD7548:
377	videoram = 1024;
378	switch (pCir->chip.alp->sr0f & 0x90) {
379		case 0x10:
380			/* TODO: 2 256K X 16 DRAMs (1024) or 4 512K X 8 DRAMs (2048)? */
381			break;
382		case 0x90:
383			videoram <<= 1;
384			break;
385	}
386	break;
387
388    case PCI_CHIP_GD7555:
389    case PCI_CHIP_GD7556:
390	videoram = 2048;   /*  for PC-9821 La13 etc.  */
391	break;
392    }
393
394    /* UNMap the Alp memory and MMIO areas */
395    if (!CirUnmapMem(pCir, pScrn->scrnIndex))
396	return 0;
397    vgaHWSetStdFuncs(hwp);
398
399    return videoram;
400}
401
402
403/*
404 * GetAccelPitchValues -
405 *
406 * This function returns a list of display width (pitch) values that can
407 * be used in accelerated mode.
408 */
409static int *
410GetAccelPitchValues(ScrnInfoPtr pScrn)
411{
412	int *linePitches = NULL;
413	int i, n = 0;
414	int max_pitch;
415
416	CirPtr pCir = CIRPTR(pScrn);
417
418	/* XXX ajv - 512, 576, and 1536 may not be supported
419	   line pitches. see sdk pp 4-59 for more
420	   details. Why anyone would want less than 640 is
421	   bizarre. (maybe lots of pixels tall?) */
422
423	/* The only line pitches the accelerator supports */
424#if 1
425	int accelWidths[] = { 640, 768, 800, 960, 1024, 1152, 1280,
426							1600, 1920, 2048, 0 };
427#else
428	int accelWidths[] = { 512, 576, 640, 768, 800, 960, 1024, 1152,
429							1280, 1536, 1600, 1920, 2048, 0 };
430#endif
431
432	switch (pCir->Chipset) {
433	case PCI_CHIP_GD5436:
434	case PCI_CHIP_GD5446:
435		max_pitch = 0x1ff << 3;
436		break;
437
438	default:
439		/* FIXME max_pitch for other chipsets? */
440		max_pitch = (pScrn->bitsPerPixel / 8) * 2048;
441		break;
442	}
443
444	for (i = 0; accelWidths[i] != 0; i++) {
445		if ((accelWidths[i] % pCir->Rounding == 0)
446		 && ((accelWidths[i] * pScrn->bitsPerPixel / 8) <= max_pitch)) {
447			n++;
448			linePitches = xnfrealloc(linePitches, n * sizeof(int));
449			linePitches[n - 1] = accelWidths[i];
450		}
451	}
452	/* Mark the end of the list */
453	if (n > 0) {
454		linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
455		linePitches[n] = 0;
456	}
457	return linePitches;
458}
459
460
461/* Mandatory */
462Bool
463AlpPreInit(ScrnInfoPtr pScrn, int flags)
464{
465	CirPtr pCir;
466	vgaHWPtr hwp;
467	MessageType from, from1;
468	int i;
469	int depth_flags;
470	ClockRangePtr clockRanges;
471	char *s;
472 	xf86Int10InfoPtr pInt = NULL;
473
474	if (flags & PROBE_DETECT)  {
475	  cirProbeDDC( pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index );
476	  return TRUE;
477	}
478
479#ifdef ALP_DEBUG
480	ErrorF("AlpPreInit\n");
481#endif
482
483	/* Check the number of entities, and fail if it isn't one. */
484	if (pScrn->numEntities != 1)
485		return FALSE;
486
487	if (!xf86LoadSubModule(pScrn, "vgahw"))
488		return FALSE;
489
490	/*
491	 * Allocate a vgaHWRec
492	 */
493	if (!vgaHWGetHWRec(pScrn))
494		return FALSE;
495	hwp = VGAHWPTR(pScrn);
496	vgaHWSetStdFuncs(hwp);
497	vgaHWGetIOBase(hwp);
498
499	/* Allocate the AlpRec driverPrivate */
500	if (!AlpGetRec(pScrn))
501		return FALSE;
502
503	pCir = CIRPTR(pScrn);
504	pCir->pScrn = pScrn;
505
506#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
507	pCir->PIOReg = hwp->PIOOffset + 0x3CE;
508#else
509	pCir->PIOReg = 0x3CE;
510#endif
511
512	/* Get the entity, and make sure it is PCI. */
513	pCir->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
514	if (pCir->pEnt->location.type != BUS_PCI) {
515		free(pCir->pEnt);
516		return FALSE;
517	}
518
519	pCir->Chipset = pCir->pEnt->chipset;
520	/* Find the PCI info for this screen */
521	pCir->PciInfo = xf86GetPciInfoForEntity(pCir->pEnt->index);
522#ifndef XSERVER_LIBPCIACCESS
523	pCir->PciTag = pciTag(PCI_DEV_BUS(pCir->PciInfo),
524			      PCI_DEV_DEV(pCir->PciInfo),
525			      PCI_DEV_FUNC(pCir->PciInfo));
526#endif
527
528#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
529    if (!xf86IsPc98())
530#endif
531    if (xf86LoadSubModule(pScrn, "int10"))
532    {
533	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n");
534	pInt = xf86InitInt10(pCir->pEnt->index);
535	xf86FreeInt10(pInt);
536	/*
537	 * This is a hack: We restore the PCI base regs as some Colorgraphic
538	 * BIOSes tend to mess them up
539	 */
540
541	PCI_WRITE_LONG(pCir->PciInfo, PCI_REGION_BASE(pCir->PciInfo, 0, REGION_MEM), 0x10);
542	PCI_WRITE_LONG(pCir->PciInfo, PCI_REGION_BASE(pCir->PciInfo, 1, REGION_MEM), 0x14);
543    }
544
545    /* Set pScrn->monitor */
546	pScrn->monitor = pScrn->confScreen->monitor;
547
548	/* 32bpp only works on 5480 and 7548 */
549	depth_flags = Support24bppFb;
550	if (pCir->Chipset == PCI_CHIP_GD5480 || pCir->Chipset ==PCI_CHIP_GD7548)
551	    depth_flags |= Support32bppFb |
552			   SupportConvert32to24 |
553			   PreferConvert32to24;
554	/*
555	 * The first thing we should figure out is the depth, bpp, etc.
556	 * We support both 24bpp and 32bpp layouts, so indicate that.
557	 */
558	if (!xf86SetDepthBpp(pScrn, 0, 0, 24, depth_flags)) {
559		return FALSE;
560	} else {
561		/* Check that the returned depth is one we support */
562		switch (pScrn->depth) {
563		case 1:
564		case 4:
565		case 8:
566		case 15:
567		case 16:
568		case 24:
569			/* OK */
570			break;
571		default:
572			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
573				"Given depth (%d) is not supported by this driver\n",
574				pScrn->depth);
575			return FALSE;
576		}
577	}
578	xf86PrintDepthBpp(pScrn);
579
580	/* Get the depth24 pixmap format */
581	if (pScrn->depth == 24 && pix24bpp == 0)
582		pix24bpp = xf86GetBppFromDepth(pScrn, 24);
583
584	/*
585	 * This must happen after pScrn->display has been set because
586	 * xf86SetWeight references it.
587	 */
588	if (pScrn->depth > 8) {
589		/* The defaults are OK for us */
590		rgb zeros = {0, 0, 0};
591
592		if (!xf86SetWeight(pScrn, zeros, zeros)) {
593			return FALSE;
594		} else {
595			/* XXX check that weight returned is supported */
596			;
597		}
598	}
599
600	if (!xf86SetDefaultVisual(pScrn, -1)) {
601		return FALSE;
602	}
603	/* Collect all of the relevant option flags (fill in pScrn->options) */
604	xf86CollectOptions(pScrn, NULL);
605
606	/* Process the options */
607	if (!(pCir->Options = malloc(sizeof(CirOptions))))
608		return FALSE;
609	memcpy(pCir->Options, CirOptions, sizeof(CirOptions));
610	xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCir->Options);
611
612	if (!xf86IsPrimaryPci(pCir->PciInfo)
613	    && !(pInt || (xf86IsOptionSet(pCir->Options,OPTION_MEMCFG1)
614			   && xf86IsOptionSet(pCir->Options,OPTION_MEMCFG2))))
615	    return FALSE;
616
617	if (pScrn->depth == 8)
618	    pScrn->rgbBits = 6;
619
620	from = X_DEFAULT;
621	pCir->HWCursor = FALSE;
622
623	switch (pCir->Chipset) {
624	case PCI_CHIP_GD7555:
625	case PCI_CHIP_GD7556:
626	  pCir->HWCursor = TRUE;
627	  break;
628	default:
629	  break;
630	}
631
632	if (xf86GetOptValBool(pCir->Options, OPTION_HW_CURSOR, &pCir->HWCursor))
633		from = X_CONFIG;
634
635	xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
636		pCir->HWCursor ? "HW" : "SW");
637	if (xf86ReturnOptValBool(pCir->Options, OPTION_NOACCEL, FALSE)) {
638		pCir->NoAccel = TRUE;
639		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
640	}
641	if(pScrn->bitsPerPixel < 8) {
642		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
643			"Cannot use accelerations in less than 8 bpp\n");
644		pCir->NoAccel = TRUE;
645	}
646
647	/*
648	 * Set the ChipRev, allowing config file entries to
649	 * override.
650	 */
651	if (pCir->pEnt->device->chipRev >= 0) {
652		pCir->ChipRev = pCir->pEnt->device->chipRev;
653		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
654			pCir->ChipRev);
655	} else {
656 	        pCir->ChipRev = PCI_DEV_REVISION(pCir->PciInfo);
657	}
658
659	/* Find the frame buffer base address */
660	if (pCir->pEnt->device->MemBase != 0) {
661	    if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->MemBase)) {
662		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
663			   "MemBase 0x%08lX doesn't match any PCI base register.\n",
664			   pCir->pEnt->device->MemBase);
665		return FALSE;
666		}
667		pCir->FbAddress = pCir->pEnt->device->MemBase;
668		from = X_CONFIG;
669	} else {
670		if (PCI_REGION_BASE(pCir->PciInfo, 0, REGION_MEM) != 0) {
671			/* 5446B and 5480 use mask of 0xfe000000.
672			   5446A uses 0xff000000. */
673			pCir->FbAddress = PCI_REGION_BASE(pCir->PciInfo, 0, REGION_MEM) & 0xff000000;
674			from = X_PROBED;
675		} else {
676			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
677				"No valid FB address in PCI config space\n");
678			AlpFreeRec(pScrn);
679			return FALSE;
680		}
681	}
682	xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
683		(unsigned long)pCir->FbAddress);
684
685	if (pCir->pEnt->device->IOBase != 0) {
686	    /* Require that the config file value matches one of the PCI values. */
687	    if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->IOBase)) {
688		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
689			   "IOBase 0x%08lX doesn't match any PCI base register.\n",
690			   pCir->pEnt->device->IOBase);
691		return FALSE;
692	    }
693	    pCir->IOAddress = pCir->pEnt->device->IOBase;
694		from = X_CONFIG;
695	} else {
696		if (PCI_REGION_BASE(pCir->PciInfo, 1, REGION_MEM) != 0) {
697			pCir->IOAddress = PCI_REGION_BASE(pCir->PciInfo, 1, REGION_MEM) & 0xfffff000;
698			pCir->IoMapSize = PCI_REGION_SIZE(pCir->PciInfo, 1);
699			from = X_PROBED;
700		} else {
701			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
702				"No valid MMIO address in PCI config space\n");
703			/* 5446 rev A do not use a separate MMIO segment */
704			/* We do not really need that YET. */
705		}
706	}
707
708	/* User options can override the MMIO default */
709#if 0
710	/* Will we ever support MMIO on 5446A or older? */
711	if (xf86ReturnOptValBool(pCir->Options, OPTION_MMIO, FALSE)) {
712		pCir->UseMMIO = TRUE;
713		from = X_CONFIG;
714	}
715#endif
716	if (!xf86ReturnOptValBool(pCir->Options, OPTION_MMIO, TRUE)) {
717		pCir->UseMMIO = FALSE;
718		from1 = X_CONFIG;
719 	} else if (pCir->IOAddress) {
720 	  /* Default to MMIO if we have a separate IOAddress and
721 	       not in monochrome mode (IO 0x3Bx is not relocated!) */
722 	    if (pScrn->bitsPerPixel != 1) {
723 	        pCir->UseMMIO = TRUE;
724 		from1 = X_PROBED;
725 	    } else {
726 	        pCir->UseMMIO = FALSE;
727 	        from1 = X_PROBED;
728 	    }
729 	} else {
730 	    pCir->UseMMIO = FALSE;
731 	    from1 = X_PROBED;
732 	}
733
734 	if (pCir->UseMMIO) {
735 		xf86DrvMsg(pScrn->scrnIndex, from1, "Using MMIO\n");
736 		xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
737 			(unsigned long)pCir->IOAddress);
738 	} else
739 	    xf86DrvMsg(pScrn->scrnIndex, from1, "Not Using MMIO\n");
740
741#ifndef XSERVER_LIBPCIACCESS
742     /*
743      * XXX Check if this is correct
744      */
745     if (!pCir->UseMMIO) {
746         pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT | RAC_FB;
747         xf86SetOperatingState(resVgaMem, pCir->pEnt->index, ResUnusedOpr);
748     } else {
749         xf86SetOperatingState(resVga, pCir->pEnt->index, ResUnusedOpr);
750     }
751
752     /* Register the PCI-assigned resources. */
753     if (xf86RegisterResources(pCir->pEnt->index, NULL, ResExclusive)) {
754	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
755		    "xf86RegisterResources() found resource conflicts\n");
756	 return FALSE;
757     }
758#endif
759
760     if (!xf86LoadSubModule(pScrn, "i2c")) {
761	 AlpFreeRec(pScrn);
762 	return FALSE;
763     }
764
765     if (!xf86LoadSubModule(pScrn, "ddc")) {
766 	AlpFreeRec(pScrn);
767 	return FALSE;
768     }
769
770     if(!AlpI2CInit(pScrn)) {
771         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
772             "I2C initialization failed\n");
773     }
774     else
775 	xf86SetDDCproperties(pScrn,xf86PrintEDID(
776		 xf86DoEDID_DDC2(XF86_SCRN_ARG(pScrn),pCir->I2CPtr1)));
777
778     /* Probe the possible LCD display */
779     AlpProbeLCD(pScrn);
780
781#ifdef CIRPROBEI2C
782     CirProbeI2C(pScrn->scrnIndex);
783#endif
784
785     /* The gamma fields must be initialised when using the new cmap code */
786     if (pScrn->depth > 1) {
787 	Gamma zeros = {0.0, 0.0, 0.0};
788
789 	if (!xf86SetGamma(pScrn, zeros))
790 	    return FALSE;
791     }
792
793	/* XXX If UseMMIO == TRUE and for any reason we cannot do MMIO,
794	   abort here */
795
796	if (xf86GetOptValBool(pCir->Options,
797			      OPTION_SHADOW_FB,&pCir->shadowFB))
798	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB %s.\n",
799		       pCir->shadowFB ? "enabled" : "disabled");
800
801	if ((s = xf86GetOptValString(pCir->Options, OPTION_ROTATE))) {
802	    if(!xf86NameCmp(s, "CW")) {
803		/* accel is disabled below for shadowFB */
804		pCir->shadowFB = TRUE;
805		pCir->rotate = 1;
806		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
807			   "Rotating screen clockwise - acceleration disabled\n");
808	    } else if(!xf86NameCmp(s, "CCW")) {
809		pCir->shadowFB = TRUE;
810		pCir->rotate = -1;
811		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,  "Rotating screen"
812			   "counter clockwise - acceleration disabled\n");
813	    } else {
814		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
815			   "value for Option \"Rotate\"\n", s);
816		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
817			   "Valid options are \"CW\" or \"CCW\"\n");
818	    }
819	}
820	if (pCir->shadowFB && (pScrn->depth < 8)) {
821	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
822		       "shadowFB not supported at this depth.\n");
823	    pCir->shadowFB = FALSE;
824	    pCir->rotate = 0;
825	}
826
827	if (pCir->shadowFB && !pCir->NoAccel) {
828	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
829		       "HW acceleration not supported with \"shadowFB\".\n");
830	    pCir->NoAccel = TRUE;
831	}
832
833	if (pCir->rotate && pCir->HWCursor) {
834	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
835		       "HW cursor not supported with \"rotate\".\n");
836	    pCir->HWCursor = FALSE;
837	}
838
839	/* XXX We do not know yet how to configure memory on this card.
840	   Use options MemCFG1 and MemCFG2 to set registers SR0F and
841	   SR17 before trying to count ram size. */
842
843	pCir->chip.alp->sr0f = (CARD32)-1;
844	pCir->chip.alp->sr17 = (CARD32)-1;
845
846	(void) xf86GetOptValULong(pCir->Options, OPTION_MEMCFG1, (unsigned long *)&pCir->chip.alp->sr0f);
847	(void) xf86GetOptValULong(pCir->Options, OPTION_MEMCFG2, (unsigned long *)&pCir->chip.alp->sr17);
848	/*
849	 * If the user has specified the amount of memory in the XF86Config
850	 * file, we respect that setting.
851	 */
852	if (pCir->pEnt->device->videoRam != 0) {
853		pScrn->videoRam = pCir->pEnt->device->videoRam;
854		pCir->IoMapSize = 0x4000;	/* 16K for moment */
855		from = X_CONFIG;
856	} else {
857		pScrn->videoRam = AlpCountRam(pScrn);
858		from = X_PROBED;
859	}
860	xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", pScrn->videoRam);
861
862	pCir->FbMapSize = pScrn->videoRam * 1024;
863
864	/* properties */
865	pCir->properties = 0;
866
867	if ((pCir->chip.alp->sr0f & 0x18) > 0x8)
868	  pCir->properties |= HWCUR64;
869
870	switch (pCir->Chipset) {
871        case PCI_CHIP_GD7548:
872	  pCir->properties |= HWCUR64;
873	  pCir->properties |= ACCEL_AUTOSTART;
874	  break;
875	case PCI_CHIP_GD5436:
876	case PCI_CHIP_GD5480:
877	  pCir->properties |= ACCEL_AUTOSTART;
878	  break;
879	default:
880	  break;
881	}
882
883     /* We use a programmable clock */
884     pScrn->progClock = TRUE;
885
886	/* XXX Set HW cursor use */
887
888	/* Set the min pixel clock */
889	pCir->MinClock = 12000;	/* XXX Guess, need to check this */
890	xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
891		pCir->MinClock / 1000);
892	/*
893	 * If the user has specified ramdac speed in the XF86Config
894	 * file, we respect that setting.
895	 */
896	if (pCir->pEnt->device->dacSpeeds[0]) {
897		ErrorF("Do not specily a Clocks line for Cirrus chips\n");
898		return FALSE;
899	} else {
900		int speed;
901		int *p = NULL;
902		switch (pCir->Chipset) {
903		case PCI_CHIP_GD5430:
904		case PCI_CHIP_GD5434_4:
905		case PCI_CHIP_GD5434_8:
906	/*	case PCI_CHIP_GD5440: */
907			p = gd5430_MaxClocks;
908			break;
909		case PCI_CHIP_GD5436:
910		case PCI_CHIP_GD5446:
911			p = gd5446_MaxClocks;
912			break;
913		case PCI_CHIP_GD5480:
914			p = gd5480_MaxClocks;
915			break;
916		case PCI_CHIP_GD7548:
917		        p = gd7548_MaxClocks;
918                        break;
919		case PCI_CHIP_GD7555:
920		        p = gd7555_MaxClocks;
921                        break;
922		case PCI_CHIP_GD7556:
923		        p = gd7556_MaxClocks;
924                        break;
925		}
926		if (!p)
927			return FALSE;
928		switch(pScrn->bitsPerPixel) {
929		case 1:
930		case 4:
931			speed = p[0];
932			break;
933		case 8:
934			speed = p[1];
935			break;
936		case 15:
937		case 16:
938			speed = p[2];
939			break;
940		case 24:
941			speed = p[3];
942			break;
943		case 32:
944			speed = p[4];
945			break;
946		default:
947			/* Should not get here */
948			speed = 0;
949			break;
950		}
951		pCir->MaxClock = speed;
952		from = X_PROBED;
953	}
954	xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
955	pCir->MaxClock / 1000);
956
957	/*
958	 * Setup the ClockRanges, which describe what clock ranges are available,
959	 * and what sort of modes they can be used for.
960	 */
961	clockRanges = xnfcalloc(sizeof(ClockRange), 1);
962	clockRanges->next = NULL;
963	clockRanges->minClock = pCir->MinClock;
964	clockRanges->maxClock = pCir->MaxClock;
965	clockRanges->clockIndex = -1;		/* programmable */
966	clockRanges->interlaceAllowed = FALSE;	/* XXX check this */
967	clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
968	clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
969	clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
970	clockRanges->ClockMulFactor = 1;
971	clockRanges->ClockDivFactor = 1;
972	clockRanges->PrivFlags = 0;
973
974	switch (pCir->Chipset)
975	{
976	case PCI_CHIP_GD7548:
977	  pCir->Rounding = 1;
978	  break;
979
980	default:
981	  pCir->Rounding = 128 >> pCir->BppShift;
982        }
983
984#if 0
985	if (pCir->Chipset != PCI_CHIP_GD5446 &&
986		pCir->Chipset != PCI_CHIP_GD5480) {
987		/* XXX Kludge */
988		pCir->NoAccel = TRUE;
989	}
990#endif
991
992	/*
993	 * xf86ValidateModes will check that the mode HTotal and VTotal values
994	 * don't exceed the chipset's limit if pScrn->maxHValue and
995	 * pScrn->maxVValue are set.  Since our AlpValidMode() already takes
996	 * care of this, we don't worry about setting them here.
997	 */
998
999	/* Select valid modes from those available */
1000	if (pCir->NoAccel) {
1001		/*
1002		 * XXX Assuming min pitch 256, max 2048
1003		 * XXX Assuming min height 128, max 2048
1004		 */
1005		i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
1006						pScrn->display->modes, clockRanges,
1007						NULL, 256, 2048,
1008						pCir->Rounding * pScrn->bitsPerPixel, 128, 2048,
1009						pScrn->display->virtualX,
1010						pScrn->display->virtualY,
1011						pCir->FbMapSize,
1012						LOOKUP_BEST_REFRESH);
1013	} else {
1014		/*
1015		 * XXX Assuming min height 128, max 2048
1016		 */
1017		i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
1018						pScrn->display->modes, clockRanges,
1019						GetAccelPitchValues(pScrn), 0, 0,
1020						pCir->Rounding * pScrn->bitsPerPixel, 128, 2048,
1021						pScrn->display->virtualX,
1022						pScrn->display->virtualY,
1023						pCir->FbMapSize,
1024						LOOKUP_BEST_REFRESH);
1025	}
1026	if (i == -1) {
1027		AlpFreeRec(pScrn);
1028		return FALSE;
1029	}
1030
1031	/* Prune the modes marked as invalid */
1032	xf86PruneDriverModes(pScrn);
1033
1034	if (i == 0 || pScrn->modes == NULL) {
1035		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
1036		AlpFreeRec(pScrn);
1037		return FALSE;
1038	}
1039
1040	/*
1041	 * Set the CRTC parameters for all of the modes based on the type
1042	 * of mode, and the chipset's interlace requirements.
1043	 *
1044	 * Calling this is required if the mode->Crtc* values are used by the
1045	 * driver and if the driver doesn't provide code to set them.  They
1046	 * are not pre-initialised at all.
1047	 */
1048	xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
1049
1050	/* Set the current mode to the first in the list */
1051	pScrn->currentMode = pScrn->modes;
1052
1053	/* Print the list of modes being used */
1054	xf86PrintModes(pScrn);
1055
1056	/* Set display resolution */
1057	xf86SetDpi(pScrn, 0, 0);
1058
1059	/* Load bpp-specific modules */
1060	switch (pScrn->bitsPerPixel) {
1061#ifdef HAVE_XF1BPP
1062	case 1:
1063	    if (xf86LoadSubModule(pScrn, "xf1bpp") == NULL) {
1064	        AlpFreeRec(pScrn);
1065		return FALSE;
1066	    }
1067	    break;
1068#endif
1069#ifdef HAVE_XF4BPP
1070	case 4:
1071	    if (xf86LoadSubModule(pScrn, "xf4bpp") == NULL) {
1072	        AlpFreeRec(pScrn);
1073		return FALSE;
1074	    }
1075	    break;
1076#endif
1077	case 8:
1078	case 16:
1079	case 24:
1080	case 32:
1081	    if (xf86LoadSubModule(pScrn, "fb") == NULL) {
1082	        AlpFreeRec(pScrn);
1083		return FALSE;
1084	    }
1085	    break;
1086	}
1087
1088	/* Load XAA if needed */
1089	if (!pCir->NoAccel) {
1090#ifdef HAVE_XAA_H
1091		if (!xf86LoadSubModule(pScrn, "xaa"))
1092#else
1093		if (1)
1094#endif
1095                {
1096			xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1097				   "Falling back to shadowfb\n");
1098			pCir->NoAccel = TRUE;
1099			pCir->shadowFB = TRUE;
1100		}
1101	}
1102
1103
1104	/* Load ramdac if needed */
1105	if (pCir->HWCursor) {
1106		if (!xf86LoadSubModule(pScrn, "ramdac")) {
1107			AlpFreeRec(pScrn);
1108			return FALSE;
1109		}
1110	}
1111
1112	if (pCir->shadowFB) {
1113	    if (!xf86LoadSubModule(pScrn, "shadowfb")) {
1114		AlpFreeRec(pScrn);
1115		return FALSE;
1116	    }
1117	}
1118
1119	return TRUE;
1120}
1121
1122/*
1123 * This function saves the video state.
1124 */
1125static void
1126AlpSave(ScrnInfoPtr pScrn)
1127{
1128	CirPtr pCir = CIRPTR(pScrn);
1129	vgaHWPtr hwp = VGAHWPTR(pScrn);
1130
1131#ifdef ALP_DEBUG
1132	ErrorF("AlpSave\n");
1133#endif
1134	vgaHWSave(pScrn, &VGAHWPTR(pScrn)->SavedReg, VGA_SR_ALL);
1135
1136	pCir->chip.alp->ModeReg.ExtVga[CR1A] = pCir->chip.alp->SavedReg.ExtVga[CR1A] = hwp->readCrtc(hwp, 0x1A);
1137	pCir->chip.alp->ModeReg.ExtVga[CR1B] = pCir->chip.alp->SavedReg.ExtVga[CR1B] = hwp->readCrtc(hwp, 0x1B);
1138	pCir->chip.alp->ModeReg.ExtVga[CR1D] = pCir->chip.alp->SavedReg.ExtVga[CR1D] = hwp->readCrtc(hwp, 0x1D);
1139	pCir->chip.alp->ModeReg.ExtVga[SR07] = pCir->chip.alp->SavedReg.ExtVga[SR07] = hwp->readSeq(hwp, 0x07);
1140	pCir->chip.alp->ModeReg.ExtVga[SR0E] = pCir->chip.alp->SavedReg.ExtVga[SR0E] = hwp->readSeq(hwp, 0x0E);
1141	pCir->chip.alp->ModeReg.ExtVga[SR12] = pCir->chip.alp->SavedReg.ExtVga[SR12] = hwp->readSeq(hwp, 0x12);
1142	pCir->chip.alp->ModeReg.ExtVga[SR13] = pCir->chip.alp->SavedReg.ExtVga[SR13] = hwp->readSeq(hwp, 0x13);
1143	pCir->chip.alp->ModeReg.ExtVga[SR17] = pCir->chip.alp->SavedReg.ExtVga[SR17] = hwp->readSeq(hwp, 0x17);
1144	pCir->chip.alp->ModeReg.ExtVga[SR1E] = pCir->chip.alp->SavedReg.ExtVga[SR1E] = hwp->readSeq(hwp, 0x1E);
1145	pCir->chip.alp->ModeReg.ExtVga[SR21] = pCir->chip.alp->SavedReg.ExtVga[SR21] = hwp->readSeq(hwp, 0x21);
1146	pCir->chip.alp->ModeReg.ExtVga[SR2D] = pCir->chip.alp->SavedReg.ExtVga[SR2D] = hwp->readSeq(hwp, 0x2D);
1147	pCir->chip.alp->ModeReg.ExtVga[GR17] = pCir->chip.alp->SavedReg.ExtVga[GR17] = hwp->readGr(hwp, 0x17);
1148	pCir->chip.alp->ModeReg.ExtVga[GR18] = pCir->chip.alp->SavedReg.ExtVga[GR18] = hwp->readGr(hwp, 0x18);
1149	/* The first 4 reads are for the pixel mask register. After 4 times that
1150	   this register is accessed in succession reading/writing this address
1151	   accesses the HDR. */
1152	hwp->readDacMask(hwp);
1153	hwp->readDacMask(hwp);
1154	hwp->readDacMask(hwp);
1155	hwp->readDacMask(hwp);
1156	pCir->chip.alp->ModeReg.ExtVga[HDR] = pCir->chip.alp->SavedReg.ExtVga[HDR] = hwp->readDacMask(hwp);
1157}
1158
1159/* XXX */
1160static void
1161AlpFix1bppColorMap(ScrnInfoPtr pScrn)
1162{
1163	vgaHWPtr hwp = VGAHWPTR(pScrn);
1164/* In 1 bpp we have color 0 at LUT 0 and color 1 at LUT 0x3f.
1165   This makes white and black look right (otherwise they were both
1166   black. I'm sure there's a better way to do that, just lazy to
1167   search the docs.  */
1168
1169	hwp->writeDacWriteAddr(hwp, 0x00);
1170	hwp->writeDacData(hwp, 0x00); hwp->writeDacData(hwp, 0x00); hwp->writeDacData(hwp, 0x00);
1171	hwp->writeDacWriteAddr(hwp, 0x3F);
1172	hwp->writeDacData(hwp, 0x3F); hwp->writeDacData(hwp, 0x3F); hwp->writeDacData(hwp, 0x3F);
1173}
1174
1175static void
1176alpRestore(vgaHWPtr hwp, AlpRegPtr cirReg)
1177{
1178    hwp->writeCrtc(hwp, 0x1A, cirReg->ExtVga[CR1A]);
1179    hwp->writeCrtc(hwp, 0x1B, cirReg->ExtVga[CR1B]);
1180    hwp->writeCrtc(hwp, 0x1D, cirReg->ExtVga[CR1D]);
1181    hwp->writeSeq(hwp, 0x07, cirReg->ExtVga[SR07]);
1182    hwp->writeSeq(hwp, 0x0E, cirReg->ExtVga[SR0E]);
1183    hwp->writeSeq(hwp, 0x12, cirReg->ExtVga[SR12]);
1184    hwp->writeSeq(hwp, 0x13, cirReg->ExtVga[SR13]);
1185    hwp->writeSeq(hwp, 0x17, cirReg->ExtVga[SR17]);
1186    hwp->writeSeq(hwp, 0x1E, cirReg->ExtVga[SR1E]);
1187    hwp->writeSeq(hwp, 0x21, cirReg->ExtVga[SR21]);
1188    hwp->writeSeq(hwp, 0x2D, cirReg->ExtVga[SR2D]);
1189    hwp->writeGr(hwp, 0x17, cirReg->ExtVga[GR17]);
1190    hwp->writeGr(hwp, 0x18, cirReg->ExtVga[GR18]);
1191    /* The first 4 reads are for the pixel mask register. After 4 times that
1192       this register is accessed in succession reading/writing this address
1193       accesses the HDR. */
1194    hwp->readDacMask(hwp);
1195    hwp->readDacMask(hwp);
1196    hwp->readDacMask(hwp);
1197    hwp->readDacMask(hwp);
1198    hwp->writeDacMask(hwp, cirReg->ExtVga[HDR ]);
1199}
1200
1201
1202/*
1203 * Initialise a new mode.  This is currently still using the old
1204 * "initialise struct, restore/write struct to HW" model.  That could
1205 * be changed.
1206 * Why?? (EE)
1207 */
1208
1209static Bool
1210AlpModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
1211{
1212	vgaHWPtr hwp;
1213	CirPtr pCir;
1214	int depthcode;
1215	int width;
1216	Bool HDiv2 = FALSE, VDiv2 = FALSE;
1217
1218#ifdef ALP_DEBUG
1219	ErrorF("AlpModeInit %d bpp,   %d   %d %d %d %d   %d %d %d %d\n",
1220		pScrn->bitsPerPixel,
1221		mode->Clock,
1222		mode->HDisplay,
1223		mode->HSyncStart,
1224		mode->HSyncEnd,
1225		mode->HTotal,
1226		mode->VDisplay,
1227		mode->VSyncStart,
1228		mode->VSyncEnd,
1229		mode->VTotal);
1230
1231	ErrorF("AlpModeInit: depth %d bits\n", pScrn->depth);
1232#endif
1233
1234	pCir = CIRPTR(pScrn);
1235	hwp = VGAHWPTR(pScrn);
1236	vgaHWUnlock(hwp);
1237
1238	pCir->pitch = pScrn->displayWidth * pScrn->bitsPerPixel >> 3;
1239
1240	depthcode = pScrn->depth;
1241	if (pScrn->bitsPerPixel == 32)
1242		depthcode = 32;
1243
1244	if ((pCir->Chipset == PCI_CHIP_GD5480 && mode->Clock > 135100) ||
1245		(pCir->Chipset == PCI_CHIP_GD5446 && mode->Clock >  85500)) {
1246		/* The actual DAC register value is set later. */
1247		/* The CRTC is clocked at VCLK / 2, so we must half the */
1248		/* horizontal timings. */
1249		if (!mode->CrtcHAdjusted) {
1250			mode->CrtcHDisplay >>= 1;
1251			mode->CrtcHSyncStart >>= 1;
1252			mode->CrtcHTotal >>= 1;
1253			mode->CrtcHSyncEnd >>= 1;
1254			mode->SynthClock >>= 1;
1255			mode->CrtcHAdjusted = TRUE;
1256		}
1257		depthcode += 64;
1258		HDiv2 = TRUE;
1259	}
1260
1261	if (mode->VTotal >= 1024 && !(mode->Flags & V_INTERLACE)) {
1262		/* For non-interlaced vertical timing >= 1024, the vertical timings */
1263		/* are divided by 2 and VGA CRTC 0x17 bit 2 is set. */
1264		if (!mode->CrtcVAdjusted) {
1265			mode->CrtcVDisplay >>= 1;
1266			mode->CrtcVSyncStart >>= 1;
1267			mode->CrtcVSyncEnd >>= 1;
1268			mode->CrtcVTotal >>= 1;
1269			mode->CrtcVAdjusted = TRUE;
1270		}
1271		VDiv2 = TRUE;
1272	}
1273
1274	/* Initialise the ModeReg values */
1275	if (!vgaHWInit(pScrn, mode))
1276		return FALSE;
1277	pScrn->vtSema = TRUE;
1278
1279	/* Turn off HW cursor, gamma correction, overscan color protect.  */
1280	pCir->chip.alp->ModeReg.ExtVga[SR12] = 0;
1281	if ((pCir->properties & HWCUR64) == HWCUR64)
1282	{
1283            pCir->chip.alp->ModeReg.ExtVga[SR12] = 0x4;
1284            switch (pCir->Chipset)
1285	    {
1286            case PCI_CHIP_GD7548:
1287	      pCir->chip.alp->ModeReg.ExtVga[SR21] |= 0x10;
1288	      break;
1289	    }
1290
1291	}
1292	else
1293	    pCir->chip.alp->ModeReg.ExtVga[SR12] = 0;
1294
1295
1296	if(VDiv2)
1297		hwp->ModeReg.CRTC[0x17] |= 0x04;
1298
1299#ifdef ALP_DEBUG
1300	ErrorF("SynthClock = %d\n", mode->SynthClock);
1301#endif
1302
1303	/* Disable DCLK pin driver, interrupts. */
1304	pCir->chip.alp->ModeReg.ExtVga[GR17] |= 0x08;
1305	pCir->chip.alp->ModeReg.ExtVga[GR17] &= ~0x04;
1306
1307	pCir->chip.alp->ModeReg.ExtVga[HDR] = 0;
1308	/* Enable linear mode and high-res packed pixel mode */
1309	pCir->chip.alp->ModeReg.ExtVga[SR07] &= 0xe0;
1310#ifdef ALP_DEBUG
1311	ErrorF("depthcode = %d\n", depthcode);
1312#endif
1313
1314	if (pScrn->bitsPerPixel == 1) {
1315		hwp->IOBase = 0x3B0;
1316		hwp->ModeReg.MiscOutReg &= ~0x01;
1317	} else {
1318		hwp->IOBase = 0x3D0;
1319		hwp->ModeReg.MiscOutReg |= 0x01;
1320	}
1321
1322	switch (depthcode) {
1323	case 1:
1324	case 4:
1325		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x10;
1326		break;
1327	case 8:
1328		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x11;
1329		break;
1330	case 64+8:
1331		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x17;
1332		break;
1333	case 15:
1334		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x17;
1335		pCir->chip.alp->ModeReg.ExtVga[HDR ]  = 0xC0;
1336		break;
1337	case 64+15:
1338		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x19;
1339		pCir->chip.alp->ModeReg.ExtVga[HDR ]  = 0xC0;
1340		break;
1341	case 16:
1342		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x17;
1343		pCir->chip.alp->ModeReg.ExtVga[HDR ]  = 0xC1;
1344		break;
1345	case 64+16:
1346		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x19;
1347		pCir->chip.alp->ModeReg.ExtVga[HDR ]  = 0xC1;
1348		break;
1349	case 24:
1350		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x15;
1351		pCir->chip.alp->ModeReg.ExtVga[HDR ]  = 0xC5;
1352		break;
1353	case 32:
1354		pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x19;
1355		pCir->chip.alp->ModeReg.ExtVga[HDR ]  = 0xC5;
1356		break;
1357	default:
1358		ErrorF("X11: Internal error: AlpModeInit: Cannot Initialize display to requested mode\n");
1359#ifdef ALP_DEBUG
1360		ErrorF("AlpModeInit returning FALSE on depthcode %d\n", depthcode);
1361#endif
1362		return FALSE;
1363	}
1364	if (HDiv2)
1365		pCir->chip.alp->ModeReg.ExtVga[GR18] |= 0x20;
1366	else
1367		pCir->chip.alp->ModeReg.ExtVga[GR18] &= ~0x20;
1368
1369
1370	/* Some extra init stuff */
1371	switch (pCir->Chipset)
1372        {
1373          case PCI_CHIP_GD7548:
1374	    /* Do we use MMIO ?
1375	       If we do and we are on a 7548, we need to tell the board
1376	       that we want MMIO. */
1377	    if (pCir->UseMMIO)
1378	    {
1379	      pCir->chip.alp->ModeReg.ExtVga[SR17] =
1380		(pCir->chip.alp->ModeReg.ExtVga[SR17] & ~0x40) | 4;
1381	      ErrorF("UseMMIO: SR17=%2X\n", (int) (pCir->chip.alp->ModeReg.ExtVga[SR17]));
1382	    }
1383#ifdef ALP_SETUP
1384	    ErrorF("SR2D=%2X\n", (int) (pCir->chip.alp->ModeReg.ExtVga[SR17]));
1385#endif
1386	    pCir->chip.alp->ModeReg.ExtVga[SR2D] |= 0xC0;
1387	    break;
1388	}
1389
1390	/* No support for interlace (yet) */
1391	pCir->chip.alp->ModeReg.ExtVga[CR1A] = 0x00;
1392
1393	width = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
1394	if (pScrn->bitsPerPixel == 1)
1395		width <<= 2;
1396	hwp->ModeReg.CRTC[0x13] = width >> 3;
1397	/* Offset extension (see CR13) */
1398	pCir->chip.alp->ModeReg.ExtVga[CR1B] &= 0xAF;
1399	pCir->chip.alp->ModeReg.ExtVga[CR1B] |= (width >> (3+4)) & 0x10;
1400	pCir->chip.alp->ModeReg.ExtVga[CR1B] |= (width >> (3+3)) & 0x40;
1401	pCir->chip.alp->ModeReg.ExtVga[CR1B] |= 0x22;
1402
1403	/* Programme the registers */
1404	vgaHWProtect(pScrn, TRUE);
1405	hwp->writeMiscOut(hwp, hwp->ModeReg.MiscOutReg);
1406	alpRestore(hwp,&pCir->chip.alp->ModeReg);
1407	AlpSetClock(pCir, hwp, mode->SynthClock);
1408
1409	vgaHWRestore(pScrn, &hwp->ModeReg, VGA_SR_MODE | VGA_SR_CMAP);
1410
1411	/* XXX */
1412	if (pScrn->bitsPerPixel == 1)
1413		AlpFix1bppColorMap(pScrn);
1414
1415	vgaHWProtect(pScrn, FALSE);
1416
1417#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
1418	if (xf86IsPc98())
1419		PC98CIRRUS755xEnable(pScrn);
1420#endif
1421
1422	return TRUE;
1423}
1424
1425/*
1426 * Restore the initial (text) mode.
1427 */
1428static void
1429AlpRestore(ScrnInfoPtr pScrn)
1430{
1431	vgaHWPtr hwp;
1432	vgaRegPtr vgaReg;
1433	CirPtr pCir;
1434	AlpRegPtr alpReg;
1435
1436#ifdef ALP_DEBUG
1437	ErrorF("AlpRestore\n");
1438#endif
1439
1440	hwp = VGAHWPTR(pScrn);
1441	pCir = CIRPTR(pScrn);
1442	vgaReg = &hwp->SavedReg;
1443	alpReg = &pCir->chip.alp->SavedReg;
1444
1445	vgaHWProtect(pScrn, TRUE);
1446
1447	alpRestore(hwp,alpReg);
1448
1449	vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
1450	vgaHWProtect(pScrn, FALSE);
1451}
1452
1453/* Mandatory */
1454
1455/* This gets called at the start of each server generation */
1456
1457Bool
1458AlpScreenInit(SCREEN_INIT_ARGS_DECL)
1459{
1460	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1461	vgaHWPtr hwp;
1462	CirPtr pCir;
1463	int i, ret;
1464	int init_picture = 0;
1465	VisualPtr visual;
1466	int displayWidth,width,height;
1467	unsigned char * FbBase = NULL;
1468	int cursor_size = 0;
1469
1470#ifdef ALP_DEBUG
1471	ErrorF("AlpScreenInit\n");
1472#endif
1473
1474	hwp = VGAHWPTR(pScrn);
1475	pCir = CIRPTR(pScrn);
1476
1477	/* Map the VGA memory when the primary video */
1478	if (!vgaHWMapMem(pScrn))
1479	    return FALSE;
1480
1481	/* Map the Alp memory and MMIO areas */
1482	if (!CirMapMem(pCir, pScrn->scrnIndex))
1483		return FALSE;
1484
1485	/* The 754x supports MMIO for the BitBlt engine but
1486	   not for the VGA registers */
1487	switch (pCir->Chipset)
1488	{
1489	case PCI_CHIP_GD7548:
1490	  break;
1491	default:
1492	  if(pCir->UseMMIO)
1493		vgaHWSetMmioFuncs(hwp, pCir->IOBase, -0x3C0);
1494        }
1495
1496	vgaHWGetIOBase(hwp);
1497
1498	/* Save the current state */
1499	AlpSave(pScrn);
1500
1501	/* Initialise the first mode */
1502	if (!AlpModeInit(pScrn, pScrn->currentMode))
1503		return FALSE;
1504
1505	/* Make things beautiful */
1506	AlpSaveScreen(pScreen, SCREEN_SAVER_ON);
1507
1508	/* Set the viewport */
1509	AlpAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
1510
1511	/*
1512	 * The next step is to setup the screen's visuals, and initialise the
1513	 * framebuffer code.  In cases where the framebuffer's default
1514	 * choices for things like visual layouts and bits per RGB are OK,
1515	 * this may be as simple as calling the framebuffer's ScreenInit()
1516	 * function.  If not, the visuals will need to be setup before calling
1517	 * a fb ScreenInit() function and fixed up after.
1518	 *
1519	 */
1520
1521	/*
1522	 * Reset the visual list.
1523	 */
1524	miClearVisualTypes();
1525
1526	/* Setup the visuals we support. */
1527
1528	if (!miSetVisualTypes(pScrn->depth,
1529			      miGetDefaultVisualMask(pScrn->depth),
1530			      pScrn->rgbBits, pScrn->defaultVisual))
1531			return FALSE;
1532
1533	miSetPixmapDepths ();
1534
1535	displayWidth = pScrn->displayWidth;
1536	if (pCir->rotate) {
1537	    height = pScrn->virtualX;
1538	    width = pScrn->virtualY;
1539	} else {
1540	    width = pScrn->virtualX;
1541	    height = pScrn->virtualY;
1542	}
1543
1544	if(pCir->shadowFB) {
1545	    pCir->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
1546	    pCir->ShadowPtr = malloc(pCir->ShadowPitch * height);
1547	    displayWidth = pCir->ShadowPitch / (pScrn->bitsPerPixel >> 3);
1548	    FbBase = pCir->ShadowPtr;
1549	} else {
1550	    pCir->ShadowPtr = NULL;
1551	    FbBase = pCir->FbBase;
1552	}
1553
1554	/*
1555	 * Call the framebuffer layer's ScreenInit function, and fill in other
1556	 * pScreen fields.
1557	 */
1558
1559	switch (pScrn->bitsPerPixel) {
1560#ifdef HAVE_XF1BPP
1561	case 1:
1562	    ret = xf1bppScreenInit(pScreen, FbBase,
1563				   width, height,
1564				   pScrn->xDpi, pScrn->yDpi,
1565				   displayWidth);
1566	    break;
1567#endif
1568#ifdef HAVE_XF4BPP
1569	case 4:
1570	    ret = xf4bppScreenInit(pScreen, FbBase,
1571				   width, height,
1572				   pScrn->xDpi, pScrn->yDpi,
1573				   displayWidth);
1574	    break;
1575#endif
1576	case 8:
1577	case 16:
1578	case 24:
1579	case 32:
1580	    ret = fbScreenInit(pScreen, FbBase,
1581				width,height,
1582				pScrn->xDpi, pScrn->yDpi,
1583				displayWidth,pScrn->bitsPerPixel);
1584	    init_picture = 1;
1585	    break;
1586	default:
1587	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1588		       "X11: Internal error: invalid bpp (%d) in AlpScreenInit\n",
1589		       pScrn->bitsPerPixel);
1590	    ret = FALSE;
1591	    break;
1592	}
1593	if (!ret)
1594		return FALSE;
1595
1596#ifdef ALP_DEBUG
1597	ErrorF("AlpScreenInit after depth dependent init\n");
1598#endif
1599
1600	/* Override the default mask/offset settings */
1601	if (pScrn->bitsPerPixel > 8) {
1602		for (i = 0; i < pScreen->numVisuals; i++) {
1603			visual = &pScreen->visuals[i];
1604			if ((visual->class | DynamicClass) == DirectColor) {
1605				visual->offsetRed = pScrn->offset.red;
1606				visual->offsetGreen = pScrn->offset.green;
1607				visual->offsetBlue = pScrn->offset.blue;
1608				visual->redMask = pScrn->mask.red;
1609				visual->greenMask = pScrn->mask.green;
1610				visual->blueMask = pScrn->mask.blue;
1611			}
1612		}
1613	}
1614
1615	/* must be after RGB ordering fixed */
1616	if (init_picture)
1617		fbPictureInit (pScreen, 0, 0);
1618
1619	/*
1620	 * Set initial black & white colourmap indices.
1621	 */
1622	xf86SetBlackWhitePixels(pScreen);
1623
1624	/*
1625	   Allocation of off-screen memory to various stuff
1626	   (hardware cursor, 8x8 mono pattern...)
1627	   Allocation goes top-down in memory, since the cursor
1628	   *must* be in the last videoram locations
1629	*/
1630	pCir->offscreen_offset = pScrn->videoRam*1024;
1631	pCir->offscreen_size = pScrn->videoRam * 1024 - pScrn->virtualY *
1632	    (BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel));
1633
1634#ifdef ALP_DEBUG
1635	ErrorF("offscreen_offset=%d, offscreen_size=%d\n",
1636	       pCir->offscreen_offset, pCir->offscreen_size);
1637#endif
1638
1639	/* Initialise cursor functions */
1640	if (pCir->HWCursor) { /* Initialize HW cursor layer */
1641
1642	    if ((pCir->properties & HWCUR64)
1643		&& (pCir->offscreen_size >= 64*8*2)) {
1644	        cursor_size = 64;
1645	        pCir->offscreen_size -= 64*8*2;
1646	        pCir->offscreen_offset -= 64*8*2;
1647	    } else if (pCir->offscreen_size >= 32*4*2) {
1648	        cursor_size = 32;
1649		pCir->offscreen_size -= 32*8*2;
1650		pCir->offscreen_offset -= 32*8*2;
1651	    }
1652	}
1653
1654	if (!pCir->NoAccel) { /* Initialize XAA functions */
1655	    AlpOffscreenAccelInit(pScrn);
1656#ifdef HAVE_XAA_H
1657	    if (!(pCir->UseMMIO ? AlpXAAInitMMIO(pScreen) :
1658		  AlpXAAInit(pScreen)))
1659	      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1660			 "Could not initialize XAA\n");
1661#endif
1662	}
1663
1664#if 1
1665	pCir->DGAModeInit = AlpModeInit;
1666	if (!CirDGAInit(pScreen))
1667	  xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1668		     "DGA initialization failed\n");
1669#endif
1670        xf86SetSilkenMouse(pScreen);
1671
1672	/* Initialise cursor functions */
1673	miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
1674
1675	if (pCir->HWCursor) {
1676	    if (!AlpHWCursorInit(pScreen, cursor_size))
1677	        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1678			   "Hardware cursor initialization failed\n");
1679#ifdef ALP_DEBUG
1680	    ErrorF("AlpHWCursorInit() complete\n");
1681#endif
1682	}
1683
1684	if (pCir->shadowFB) {
1685	    RefreshAreaFuncPtr refreshArea = cirRefreshArea;
1686
1687	    if(pCir->rotate) {
1688		if (!pCir->PointerMoved) {
1689		    pCir->PointerMoved = pScrn->PointerMoved;
1690		    pScrn->PointerMoved = cirPointerMoved;
1691		}
1692
1693		switch(pScrn->bitsPerPixel) {
1694		case 8:	refreshArea = cirRefreshArea8;	break;
1695		case 16:	refreshArea = cirRefreshArea16;	break;
1696		case 24:	refreshArea = cirRefreshArea24;	break;
1697		case 32:	refreshArea = cirRefreshArea32;	break;
1698		}
1699	    }
1700
1701	    ShadowFBInit(pScreen, refreshArea);
1702	}
1703
1704	/* Initialise default colourmap */
1705	if (!miCreateDefColormap(pScreen))
1706		return FALSE;
1707
1708	if (pScrn->bitsPerPixel > 1 && pScrn->bitsPerPixel <= 8)
1709		vgaHWHandleColormaps(pScreen);
1710
1711	xf86DPMSInit(pScreen, AlpDisplayPowerManagementSet, 0);
1712
1713	pScrn->memPhysBase = pCir->FbAddress;
1714	pScrn->fbOffset = 0;
1715
1716	{
1717		XF86VideoAdaptorPtr *ptr;
1718		int n;
1719
1720		n = xf86XVListGenericAdaptors(pScrn,&ptr);
1721		if (n)
1722			xf86XVScreenInit(pScreen, ptr, n);
1723	}
1724
1725	/*
1726	 * Wrap the CloseScreen vector and set SaveScreen.
1727	 */
1728	pScreen->SaveScreen = AlpSaveScreen;
1729	pCir->CloseScreen = pScreen->CloseScreen;
1730	pScreen->CloseScreen = AlpCloseScreen;
1731
1732	/* Report any unused options (only for the first generation) */
1733	if (serverGeneration == 1)
1734		xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
1735
1736	/* Done */
1737	return TRUE;
1738}
1739
1740
1741/* Usually mandatory */
1742Bool
1743AlpSwitchMode(SWITCH_MODE_ARGS_DECL)
1744{
1745	SCRN_INFO_PTR(arg);
1746	return AlpModeInit(pScrn, mode);
1747}
1748
1749
1750/*
1751 * This function is used to initialize the Start Address - the first
1752 * displayed location in the video memory.
1753 */
1754/* Usually mandatory */
1755void
1756AlpAdjustFrame(ADJUST_FRAME_ARGS_DECL)
1757{
1758	SCRN_INFO_PTR(arg);
1759	int Base, tmp;
1760	vgaHWPtr hwp;
1761
1762	hwp = VGAHWPTR(pScrn);
1763
1764	Base = ((y * pScrn->displayWidth + x) / 8);
1765	if (pScrn->bitsPerPixel != 1)
1766		Base *= (pScrn->bitsPerPixel/4);
1767
1768#ifdef ALP_DEBUG
1769	ErrorF("AlpAdjustFrame %d %d 0x%x %d %x\n", x, y, flags, Base, Base);
1770#endif
1771
1772	if ((Base & ~0x000FFFFF) != 0) {
1773		ErrorF("X11: Internal error: AlpAdjustFrame: cannot handle overflow\n");
1774		return;
1775	}
1776
1777	hwp->writeCrtc(hwp, 0x0C, (Base >> 8) & 0xff);
1778	hwp->writeCrtc(hwp, 0x0D, Base & 0xff);
1779	tmp = hwp->readCrtc(hwp, 0x1B);
1780	tmp &= 0xF2;
1781	tmp |= (Base >> 16) & 0x01;
1782	tmp |= (Base >> 15) & 0x0C;
1783	hwp->writeCrtc(hwp, 0x1B, tmp);
1784	tmp = hwp->readCrtc(hwp, 0x1D);
1785	tmp &= 0x7F;
1786	tmp |= (Base >> 12) & 0x80;
1787	hwp->writeCrtc(hwp, 0x1D, tmp);
1788}
1789
1790/*
1791 * This is called when VT switching back to the X server.  Its job is
1792 * to reinitialise the video mode.
1793 *
1794 * We may wish to unmap video/MMIO memory too.
1795 */
1796
1797/* Mandatory */
1798Bool
1799AlpEnterVT(VT_FUNC_ARGS_DECL)
1800{
1801	SCRN_INFO_PTR(arg);
1802	CirPtr pCir = CIRPTR(pScrn);
1803	Bool ret;
1804
1805#ifdef ALP_DEBUG
1806	ErrorF("AlpEnterVT\n");
1807#endif
1808
1809	/* Should we re-save the text mode on each VT enter? */
1810	if (!(ret = AlpModeInit(pScrn, pScrn->currentMode)))
1811		return FALSE;
1812
1813	if (!pCir->NoAccel)
1814		pCir->InitAccel(pScrn);
1815
1816	return ret;
1817}
1818
1819
1820/*
1821 * This is called when VT switching away from the X server.  Its job is
1822 * to restore the previous (text) mode.
1823 *
1824 * We may wish to remap video/MMIO memory too.
1825 */
1826
1827/* Mandatory */
1828void
1829AlpLeaveVT(VT_FUNC_ARGS_DECL)
1830{
1831	SCRN_INFO_PTR(arg);
1832	vgaHWPtr hwp = VGAHWPTR(pScrn);
1833#ifdef ALP_DEBUG
1834	ErrorF("AlpLeaveVT\n");
1835#endif
1836
1837	AlpRestore(pScrn);
1838	vgaHWLock(hwp);
1839
1840#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
1841	if (xf86IsPc98())
1842		PC98CIRRUS755xDisable(pScrn);
1843#endif
1844}
1845
1846
1847/*
1848 * This is called at the end of each server generation.  It restores the
1849 * original (text) mode.  It should also unmap the video memory, and free
1850 * any per-generation data allocated by the driver.  It should finish
1851 * by unwrapping and calling the saved CloseScreen function.
1852 */
1853
1854/* Mandatory */
1855static Bool
1856AlpCloseScreen(CLOSE_SCREEN_ARGS_DECL)
1857{
1858	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1859	vgaHWPtr hwp = VGAHWPTR(pScrn);
1860	CirPtr pCir = CIRPTR(pScrn);
1861
1862	if(pScrn->vtSema) {
1863	    AlpRestore(pScrn);
1864	    vgaHWLock(hwp);
1865	    CirUnmapMem(pCir, pScrn->scrnIndex);
1866	}
1867
1868#ifdef HAVE_XAA_H
1869	if (pCir->AccelInfoRec)
1870		XAADestroyInfoRec(pCir->AccelInfoRec);
1871	pCir->AccelInfoRec = NULL;
1872#endif
1873	if (pCir->CursorInfoRec)
1874		xf86DestroyCursorInfoRec(pCir->CursorInfoRec);
1875	pCir->CursorInfoRec = NULL;
1876	if (pCir->DGAModes)
1877		free(pCir->DGAModes);
1878	pCir->DGAnumModes = 0;
1879	pCir->DGAModes = NULL;
1880
1881	pScrn->vtSema = FALSE;
1882
1883#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
1884	if (xf86IsPc98())
1885		PC98CIRRUS755xDisable(pScrn);
1886#endif
1887
1888	pScreen->CloseScreen = pCir->CloseScreen;
1889	return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
1890}
1891
1892
1893/* Free up any persistent data structures */
1894
1895/* Optional */
1896void
1897AlpFreeScreen(FREE_SCREEN_ARGS_DECL)
1898{
1899	SCRN_INFO_PTR(arg);
1900#ifdef ALP_DEBUG
1901	ErrorF("AlpFreeScreen\n");
1902#endif
1903	/*
1904	 * This only gets called when a screen is being deleted.  It does not
1905	 * get called routinely at the end of a server generation.
1906	 */
1907	if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
1908		vgaHWFreeHWRec(pScrn);
1909	AlpFreeRec(pScrn);
1910}
1911
1912
1913/* Checks if a mode is suitable for the selected chipset. */
1914
1915/* Optional */
1916ModeStatus
1917AlpValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
1918{
1919	int lace;
1920
1921	lace = 1 + ((mode->Flags & V_INTERLACE) != 0);
1922
1923	if ((mode->CrtcHDisplay <= 2048) &&
1924		(mode->CrtcHSyncStart <= 4096) &&
1925		(mode->CrtcHSyncEnd <= 4096) &&
1926		(mode->CrtcHTotal <= 4096) &&
1927		(mode->CrtcVDisplay <= 2048 * lace) &&
1928		(mode->CrtcVSyncStart <= 4096 * lace) &&
1929		(mode->CrtcVSyncEnd <= 4096 * lace) &&
1930		(mode->CrtcVTotal <= 4096 * lace)) {
1931		return(MODE_OK);
1932	} else {
1933		return(MODE_BAD);
1934	}
1935}
1936
1937/* Do screen blanking */
1938
1939/* Mandatory */
1940static Bool
1941AlpSaveScreen(ScreenPtr pScreen, int mode)
1942{
1943	return vgaHWSaveScreen(pScreen, mode);
1944}
1945
1946/*
1947 * Set the clock to the requested frequency.  If the MCLK is very close
1948 * to the requested frequency, it sets a flag so that the MCLK can be used
1949 * as VCLK.  However this flag is not yet acted upon.
1950 */
1951static void
1952AlpSetClock(CirPtr pCir, vgaHWPtr hwp, int freq)
1953{
1954	int num, den, ffreq;
1955	CARD8 tmp;
1956
1957#ifdef ALP_DEBUG
1958	ErrorF("AlpSetClock freq=%d.%03dMHz\n", freq / 1000, freq % 1000);
1959#endif
1960
1961	ffreq = freq;
1962	if (!CirrusFindClock(&ffreq, pCir->MaxClock, &num, &den))
1963		return;
1964
1965#ifdef ALP_DEBUG
1966	ErrorF("AlpSetClock: nom=%x den=%x ffreq=%d.%03dMHz\n",
1967		num, den, ffreq / 1000, ffreq % 1000);
1968#endif
1969	/* So - how do we use MCLK here for the VCLK ? */
1970
1971	/* Set VCLK3. */
1972	tmp = hwp->readSeq(hwp, 0x0E);
1973	hwp->writeSeq(hwp, 0x0E, (tmp & 0x80) | num);
1974	hwp->writeSeq(hwp, 0x1E, den);
1975}
1976
1977/*
1978 * AlpDisplayPowerManagementSet --
1979 *
1980 * Sets VESA Display Power Management Signaling (DPMS) Mode.
1981 */
1982static void
1983AlpDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
1984			     int flags)
1985{
1986	unsigned char sr01, gr0e;
1987	vgaHWPtr hwp;
1988
1989#ifdef ALP_DEBUG
1990	ErrorF("AlpDisplayPowerManagementSet\n");
1991#endif
1992
1993	hwp = VGAHWPTR(pScrn);
1994
1995#ifdef ALP_DEBUG
1996	ErrorF("AlpDisplayPowerManagementSet: %d\n", PowerManagementMode);
1997#endif
1998
1999	switch (PowerManagementMode) {
2000	case DPMSModeOn:
2001		/* Screen: On; HSync: On, VSync: On */
2002		sr01 = 0x00;
2003		gr0e = 0x00;
2004		break;
2005	case DPMSModeStandby:
2006		/* Screen: Off; HSync: Off, VSync: On */
2007		sr01 = 0x20;
2008		gr0e = 0x02;
2009		break;
2010	case DPMSModeSuspend:
2011		/* Screen: Off; HSync: On, VSync: Off */
2012		sr01 = 0x20;
2013		gr0e = 0x04;
2014		break;
2015	case DPMSModeOff:
2016		/* Screen: Off; HSync: Off, VSync: Off */
2017		sr01 = 0x20;
2018		gr0e = 0x06;
2019		break;
2020	default:
2021		return;
2022	}
2023
2024	sr01 |= hwp->readSeq(hwp, 0x01) & ~0x20;
2025	hwp->writeSeq(hwp, 0x01, sr01);
2026	gr0e |= hwp->readGr(hwp, 0x0E) & ~0x06;
2027	hwp->writeGr(hwp, 0x0E, gr0e);
2028}
2029
2030#ifdef ALPPROBEI2C
2031static void AlpProbeI2C(int scrnIndex)
2032{
2033	int i;
2034	I2CBusPtr b;
2035
2036	b = xf86I2CFindBus(scrnIndex, "I2C bus 1");
2037	if (b == NULL)
2038		ErrorF("Could not find I2C bus \"%s\"\n", "I2C bus 1");
2039	else {
2040		for (i = 2; i < 256; i += 2)
2041			if (xf86I2CProbeAddress(b, i))
2042				ErrorF("Found device 0x%02x on bus \"%s\"\n", i, b->BusName);
2043	}
2044	b = xf86I2CFindBus(scrnIndex, "I2C bus 2");
2045	if (b == NULL)
2046		ErrorF("Could not find I2C bus \"%s\"\n", "I2C bus 2");
2047	else {
2048		for (i = 2; i < 256; i += 2)
2049			if (xf86I2CProbeAddress(b, i))
2050				ErrorF("Found device 0x%02x on bus \"%s\"\n", i, b->BusName);
2051	}
2052}
2053#endif
2054
2055static void
2056AlpProbeLCD(ScrnInfoPtr pScrn)
2057{
2058    CirPtr pCir = CIRPTR(pScrn);
2059    AlpPtr pAlp = ALPPTR(pCir);
2060
2061    vgaHWPtr hwp = VGAHWPTR(pScrn);
2062    CARD8 lcdCrtl;
2063
2064    static const char* lcd_type_names[] =
2065    {
2066        "none",
2067	"dual-scan monochrome",
2068	"unknown",
2069	"DSTN (dual scan color)",
2070	"TFT (active matrix)"
2071    };
2072
2073
2074    pAlp->lcdType = LCD_NONE;
2075
2076    switch (pCir->Chipset)  {
2077    case PCI_CHIP_GD7548:
2078        switch (hwp->readCrtc(hwp, 0x2C) >> 6) {
2079	case 0: pAlp->lcdType = LCD_DUAL_MONO; break;
2080	case 1: pAlp->lcdType = LCD_UNKNOWN; break;
2081	case 2: pAlp->lcdType = LCD_DSTN; break;
2082	case 3: pAlp->lcdType = LCD_TFT; break;
2083	}
2084
2085	/* Enable LCD control registers instead of normal CRTC registers */
2086	lcdCrtl = hwp->readCrtc(hwp, 0x2D);
2087	hwp->writeCrtc(hwp, 0x2D, lcdCrtl | 0x80);
2088
2089	switch ((hwp->readCrtc(hwp, 0x9) >> 2) & 3)  {
2090	  case 0:
2091	      pAlp->lcdWidth = 640;
2092	      pAlp->lcdHeight = 480;
2093	      break;
2094
2095	 case 1:
2096	      pAlp->lcdWidth = 800;
2097	      pAlp->lcdHeight = 600;
2098	      break;
2099
2100	  case 2:
2101	      pAlp->lcdWidth = 1024;
2102	      pAlp->lcdHeight = 768;
2103	      break;
2104
2105	  case 3:
2106	      pAlp->lcdWidth = 0;
2107	      pAlp->lcdHeight = 0;
2108	      break;
2109	}
2110
2111	/* Disable LCD control registers */
2112	hwp->writeCrtc(hwp, 0x2D, lcdCrtl);
2113	break;
2114    }
2115
2116    if (pAlp->lcdType != LCD_NONE) {
2117      xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2118		 "LCD display: %dx%d %s\n",
2119		 pAlp->lcdWidth, pAlp->lcdHeight,
2120		 lcd_type_names[pAlp->lcdType]);
2121    }
2122}
2123
2124static void
2125AlpOffscreenAccelInit(ScrnInfoPtr pScrn)
2126{
2127    CirPtr pCir = CIRPTR(pScrn);
2128    AlpPtr pAlp = ALPPTR(pCir);
2129
2130    if (pCir->offscreen_size >= 8  && pCir->Chipset == PCI_CHIP_GD7548) {
2131        pCir->offscreen_offset -= 8;
2132	pCir->offscreen_size -= 8;
2133	pAlp->monoPattern8x8 = pCir->offscreen_offset;
2134#ifdef ALP_DEBUG
2135	ErrorF("monoPattern8x8=%d\n", pAlp->monoPattern8x8);
2136#endif
2137    }  else pAlp->monoPattern8x8 = 0;
2138
2139    {
2140    /* TODO: probably not correct if rotated */
2141        BoxRec box;
2142	box.x1=0;
2143	box.y1=0;
2144	box.x2=pScrn->virtualX;
2145	box.y2= pCir->offscreen_offset / pCir->pitch;
2146	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2147		   "Using %d lines for offscreen memory\n",
2148		   box.y2 - pScrn->virtualY);
2149    }
2150}
2151
2152#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
2153static void
2154PC98CIRRUS755xEnable(ScrnInfoPtr pScrn)  /*  enter_aile()  */
2155{
2156   unsigned int  index,data;
2157   vgaHWPtr hwp = VGAHWPTR(pScrn);
2158
2159   outb(0xfac, 0x02);
2160
2161   outb(0x68, 0x0e);
2162   outb(0x6a, 0x07);
2163   outb(0x6a, 0x8f);
2164   outb(0x6a, 0x06);
2165
2166   outw(VGA_SEQ_INDEX, 0x1206);         /*  unlock cirrus special  */
2167
2168   index = hwp->IOBase + VGA_CRTC_INDEX_OFFSET;
2169   data  = hwp->IOBase + VGA_CRTC_DATA_OFFSET;
2170   outb(index, 0x3c);
2171   outb(data,  inb(data) & 0xef);
2172   outb(index, 0x1a);
2173   outb(data,  inb(data) & 0xf3);
2174}
2175
2176static void
2177PC98CIRRUS755xDisable(ScrnInfoPtr pScrn)  /*  leave_aile()  */
2178{
2179   unsigned int  index,data;
2180   vgaHWPtr hwp = VGAHWPTR(pScrn);
2181
2182   outw(VGA_SEQ_INDEX, 0x1206);         /*  unlock cirrus special  */
2183
2184   index = hwp->IOBase + VGA_CRTC_INDEX_OFFSET;
2185   data  = hwp->IOBase + VGA_CRTC_DATA_OFFSET;
2186   outb(index, 0x3c);
2187   outb(data,  0x71);
2188   outb(index, 0x1a);
2189   outb(data,  inb(data) | 0x0c);
2190
2191   outb(0xfac,0x00);
2192
2193   outb(0x68, 0x0f);
2194   outb(0x6a, 0x07);
2195   outb(0x6a, 0x8e);
2196   outb(0x6a, 0x21);
2197   outb(0x6a, 0x69);
2198   outb(0x6a, 0x06);
2199}
2200#endif
2201