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