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