ast_driver.c revision 15fb4814
1/*
2 * Copyright (c) 2005 ASPEED Technology Inc.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the authors not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  The authors makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as is" without express or implied warranty.
13 *
14 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26#include "xf86.h"
27#include "xf86_OSproc.h"
28#include "xf86Resources.h"
29#include "xf86RAC.h"
30#include "xf86cmap.h"
31#include "compiler.h"
32#include "mibstore.h"
33#include "vgaHW.h"
34#include "mipointer.h"
35#include "micmap.h"
36
37#include "fb.h"
38#include "regionstr.h"
39#include "xf86xv.h"
40#include <X11/extensions/Xv.h>
41#include "vbe.h"
42
43#include "xf86PciInfo.h"
44#include "xf86Pci.h"
45
46/* framebuffer offscreen manager */
47#include "xf86fbman.h"
48
49/* include xaa includes */
50#include "xaa.h"
51#include "xaarop.h"
52
53/* H/W cursor support */
54#include "xf86Cursor.h"
55
56/* Driver specific headers */
57#include "ast.h"
58
59/* external reference fucntion */
60extern Bool ASTMapMem(ScrnInfoPtr pScrn);
61extern Bool ASTUnmapMem(ScrnInfoPtr pScrn);
62extern Bool ASTMapMMIO(ScrnInfoPtr pScrn);
63extern void ASTUnmapMMIO(ScrnInfoPtr pScrn);
64
65extern void vASTOpenKey(ScrnInfoPtr pScrn);
66extern Bool bASTRegInit(ScrnInfoPtr pScrn);
67extern ULONG GetVRAMInfo(ScrnInfoPtr pScrn);
68extern ULONG GetMaxDCLK(ScrnInfoPtr pScrn);
69extern void vASTLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual);
70extern void ASTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
71extern void vSetStartAddressCRT1(ASTRecPtr pAST, ULONG base);
72extern Bool ASTSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode);
73
74extern Bool bInitCMDQInfo(ScrnInfoPtr pScrn, ASTRecPtr pAST);
75extern Bool bEnableCMDQ(ScrnInfoPtr pScrn, ASTRecPtr pAST);
76extern void vDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST);
77
78extern Bool ASTAccelInit(ScreenPtr pScreen);
79
80extern Bool ASTCursorInit(ScreenPtr pScreen);
81
82/* Mandatory functions */
83static void ASTIdentify(int flags);
84const OptionInfoRec *ASTAvailableOptions(int chipid, int busid);
85static Bool ASTProbe(DriverPtr drv, int flags);
86static Bool ASTPreInit(ScrnInfoPtr pScrn, int flags);
87static Bool ASTScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv);
88Bool ASTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
89void ASTAdjustFrame(int scrnIndex, int x, int y, int flags);
90static Bool ASTEnterVT(int scrnIndex, int flags);
91static void ASTLeaveVT(int scrnIndex, int flags);
92static void ASTFreeScreen(int scrnIndex, int flags);
93static ModeStatus ASTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags);
94
95/* Internally used functions */
96static Bool ASTGetRec(ScrnInfoPtr pScrn);
97static void ASTFreeRec(ScrnInfoPtr pScrn);
98static Bool ASTSaveScreen(ScreenPtr pScreen, Bool unblack);
99static Bool ASTCloseScreen(int scrnIndex, ScreenPtr pScreen);
100static void ASTSave(ScrnInfoPtr pScrn);
101static void ASTRestore(ScrnInfoPtr pScrn);
102static void ASTProbeDDC(ScrnInfoPtr pScrn, int index);
103static xf86MonPtr ASTDoDDC(ScrnInfoPtr pScrn, int index);
104static void vFillASTModeInfo (ScrnInfoPtr pScrn);
105static Bool ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
106
107/*
108 * This is intentionally screen-independent.  It indicates the binding
109 * choice made in the first PreInit.
110 */
111DriverRec AST = {
112   AST_VERSION,
113   AST_DRIVER_NAME,
114   ASTIdentify,
115   ASTProbe,
116   ASTAvailableOptions,
117   NULL,
118   0
119};
120
121/* Chipsets */
122static SymTabRec ASTChipsets[] = {
123   {PCI_CHIP_AST2000,	"AST2000"},
124   {-1,			NULL}
125};
126
127static PciChipsets ASTPciChipsets[] = {
128   {PCI_CHIP_AST2000,		PCI_CHIP_AST2000,	RES_SHARED_VGA},
129   {-1,				-1, 			RES_UNDEFINED }
130};
131
132typedef enum {
133   OPTION_NOACCEL,
134   OPTION_MMIO2D,
135   OPTION_SW_CURSOR,
136   OPTION_HWC_NUM,
137   OPTION_ENG_CAPS,
138   OPTION_DBG_SELECT,
139   OPTION_NO_DDC
140} ASTOpts;
141
142static const OptionInfoRec ASTOptions[] = {
143   {OPTION_NOACCEL,	"NoAccel",	OPTV_BOOLEAN,	{0},	FALSE},
144   {OPTION_MMIO2D,	"MMIO2D",	OPTV_BOOLEAN,	{0},	FALSE},
145   {OPTION_SW_CURSOR,	"SWCursor",	OPTV_BOOLEAN,	{0},	FALSE},
146   {OPTION_HWC_NUM,	"HWCNumber",	OPTV_INTEGER,	{0},	FALSE},
147   {OPTION_ENG_CAPS,	"ENGCaps",	OPTV_INTEGER,	{0},	FALSE},
148   {OPTION_DBG_SELECT,	"DBGSelect",	OPTV_INTEGER,	{0},	FALSE},
149   {OPTION_NO_DDC,	"NoDDC",	OPTV_BOOLEAN,	{0}, 	FALSE},
150   {-1,			NULL,		OPTV_NONE,	{0}, 	FALSE}
151};
152
153const char *vgahwSymbols[] = {
154   "vgaHWFreeHWRec",
155   "vgaHWGetHWRec",
156   "vgaHWGetIOBase",
157   "vgaHWGetIndex",
158   "vgaHWInit",
159   "vgaHWLock",
160   "vgaHWMapMem",
161   "vgaHWProtect",
162   "vgaHWRestore",
163   "vgaHWSave",
164   "vgaHWSaveScreen",
165   "vgaHWSetMmioFuncs",
166   "vgaHWUnlock",
167   "vgaHWUnmapMem",
168   NULL
169};
170
171const char *fbSymbols[] = {
172   "fbPictureInit",
173   "fbScreenInit",
174   NULL
175};
176
177const char *vbeSymbols[] = {
178   "VBEInit",
179   "VBEFreeModeInfo",
180   "VBEFreeVBEInfo",
181   "VBEGetModeInfo",
182   "VBEGetModePool",
183   "VBEGetVBEInfo",
184   "VBEGetVBEMode",
185   "VBEPrintModes",
186   "VBESaveRestore",
187   "VBESetDisplayStart",
188   "VBESetGetDACPaletteFormat",
189   "VBESetGetLogicalScanlineLength",
190   "VBESetGetPaletteData",
191   "VBESetModeNames",
192   "VBESetModeParameters",
193   "VBESetVBEMode",
194   "VBEValidateModes",
195   "vbeDoEDID",
196   "vbeFree",
197   NULL
198};
199
200#ifdef XFree86LOADER
201static const char *vbeOptionalSymbols[] = {
202   "VBEDPMSSet",
203   "VBEGetPixelClock",
204   NULL
205};
206#endif
207
208const char *ddcSymbols[] = {
209   "xf86PrintEDID",
210   "xf86SetDDCproperties",
211   NULL
212};
213
214const char *int10Symbols[] = {
215   "xf86ExecX86int10",
216   "xf86InitInt10",
217   "xf86Int10AllocPages",
218   "xf86int10Addr",
219   NULL
220};
221
222const char *xaaSymbols[] = {
223   "XAACreateInfoRec",
224   "XAADestroyInfoRec",
225   "XAAInit",
226   "XAACopyROP",
227   "XAAPatternROP",
228   NULL
229};
230
231const char *ramdacSymbols[] = {
232   "xf86CreateCursorInfoRec",
233   "xf86DestroyCursorInfoRec",
234   "xf86InitCursor",
235   NULL
236};
237
238
239#ifdef XFree86LOADER
240
241static MODULESETUPPROTO(astSetup);
242
243static XF86ModuleVersionInfo astVersRec = {
244   AST_DRIVER_NAME,
245   MODULEVENDORSTRING,
246   MODINFOSTRING1,
247   MODINFOSTRING2,
248   XORG_VERSION_CURRENT,
249   AST_MAJOR_VERSION, AST_MINOR_VERSION, AST_PATCH_VERSION,
250   ABI_CLASS_VIDEODRV,
251   ABI_VIDEODRV_VERSION,
252   MOD_CLASS_VIDEODRV,
253   {0, 0, 0, 0}
254};
255
256XF86ModuleData astModuleData = { &astVersRec, astSetup, NULL };
257
258static pointer
259astSetup(pointer module, pointer opts, int *errmaj, int *errmin)
260{
261   static Bool setupDone = FALSE;
262
263   /* This module should be loaded only once, but check to be sure.
264    */
265   if (!setupDone) {
266      setupDone = TRUE;
267      xf86AddDriver(&AST, module, 0);
268
269      /*
270       * Tell the loader about symbols from other modules that this module
271       * might refer to.
272       */
273      LoaderRefSymLists(vgahwSymbols,
274			fbSymbols, xaaSymbols, ramdacSymbols,
275			vbeSymbols, vbeOptionalSymbols,
276			ddcSymbols, int10Symbols, NULL);
277
278      /*
279       * The return value must be non-NULL on success even though there
280       * is no TearDownProc.
281       */
282      return (pointer) TRUE;
283   } else {
284      if (errmaj)
285	 *errmaj = LDR_ONCEONLY;
286      return NULL;
287   }
288}
289
290#endif	/* XFree86LOADER */
291
292/*
293 * ASTIdentify --
294 *
295 * Returns the string name for the driver based on the chipset. In this
296 * case it will always be an AST, so we can return a static string.
297 *
298 */
299static void
300ASTIdentify(int flags)
301{
302   xf86PrintChipsets(AST_NAME, "Driver for ASPEED Graphics Chipsets",
303		     ASTChipsets);
304}
305
306const OptionInfoRec *
307ASTAvailableOptions(int chipid, int busid)
308{
309
310   return ASTOptions;
311
312}
313
314/*
315 * ASTProbe --
316 *
317 * Look through the PCI bus to find cards that are AST boards.
318 * Setup the dispatch table for the rest of the driver functions.
319 *
320 */
321static Bool
322ASTProbe(DriverPtr drv, int flags)
323{
324    int i, numUsed, numDevSections, *usedChips;
325    Bool foundScreen = FALSE;
326    GDevPtr *devSections;
327
328   /*
329    * Find the config file Device sections that match this
330    * driver, and return if there are none.
331    */
332    if ((numDevSections =
333	xf86MatchDevice(AST_DRIVER_NAME, &devSections)) <= 0) {
334      return FALSE;
335    }
336
337   /*
338    * This probing is just checking the PCI data the server already
339    * collected.
340    */
341    if (xf86GetPciVideoInfo() == NULL) {
342	return FALSE;
343    }
344
345    numUsed = xf86MatchPciInstances(AST_NAME, PCI_VENDOR_AST,
346				   ASTChipsets, ASTPciChipsets,
347				   devSections, numDevSections,
348				   drv, &usedChips);
349
350    xfree(devSections);
351
352    if (flags & PROBE_DETECT) {
353        if (numUsed > 0)
354	    foundScreen = TRUE;
355    } else {
356        for (i = 0; i < numUsed; i++) {
357	    ScrnInfoPtr pScrn = NULL;
358
359	    /* Allocate new ScrnInfoRec and claim the slot */
360	    if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
361					     ASTPciChipsets, 0, 0, 0, 0, 0)))
362            {
363	        EntityInfoPtr pEnt;
364
365	        pEnt = xf86GetEntityInfo(usedChips[i]);
366
367	        pScrn->driverVersion = AST_VERSION;
368	        pScrn->driverName = AST_DRIVER_NAME;
369	        pScrn->name = AST_NAME;
370
371	        pScrn->Probe = ASTProbe;
372	        pScrn->PreInit = ASTPreInit;
373	        pScrn->ScreenInit = ASTScreenInit;
374	        pScrn->SwitchMode = ASTSwitchMode;
375	        pScrn->AdjustFrame = ASTAdjustFrame;
376	        pScrn->EnterVT = ASTEnterVT;
377	        pScrn->LeaveVT = ASTLeaveVT;
378	        pScrn->FreeScreen = ASTFreeScreen;
379	        pScrn->ValidMode = ASTValidMode;
380
381	        foundScreen = TRUE;
382
383	    } /* end of if */
384        }  /* end of for-loop */
385    } /* end of if flags */
386
387    xfree(usedChips);
388
389    return foundScreen;
390}
391
392/*
393 * ASTPreInit --
394 *
395 * Do initial setup of the board before we know what resolution we will
396 * be running at.
397 *
398 */
399static Bool
400ASTPreInit(ScrnInfoPtr pScrn, int flags)
401{
402   EntityInfoPtr pEnt;
403   vgaHWPtr hwp;
404   int flags24;
405   rgb defaultWeight = { 0, 0, 0 };
406
407   ASTRecPtr pAST;
408
409   ClockRangePtr clockRanges;
410   int i;
411   MessageType from;
412
413   /* Suport one adapter only now */
414   if (pScrn->numEntities != 1)
415       return FALSE;
416
417   pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
418
419   if (flags & PROBE_DETECT) {
420       ASTProbeDDC(pScrn, pEnt->index);
421       return TRUE;
422   }
423
424   if (pEnt->location.type != BUS_PCI)
425       return FALSE;
426
427   if (xf86RegisterResources(pEnt->index, 0, ResExclusive))
428       return FALSE;
429
430   /* The vgahw module should be loaded here when needed */
431   if (!xf86LoadSubModule(pScrn, "vgahw"))
432      return FALSE;
433   xf86LoaderReqSymLists(vgahwSymbols, NULL);
434
435   /* The fb module should be loaded here when needed */
436   if (!xf86LoadSubModule(pScrn, "fb"))
437      return FALSE;
438   xf86LoaderReqSymLists(fbSymbols, NULL);
439
440   /* Allocate a vgaHWRec */
441   if (!vgaHWGetHWRec(pScrn))
442       return FALSE;
443   hwp = VGAHWPTR(pScrn);
444
445   /* Color Depth Check */
446   flags24 = Support32bppFb;
447   if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) {
448      return FALSE;
449   } else {
450      switch (pScrn->depth) {
451      case 8:
452      case 16:
453      case 24:
454	 break;
455      default:
456	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
457		    "Given depth (%d) is not supported by ast driver\n",
458		    pScrn->depth);
459	 return FALSE;
460      }
461   }
462   xf86PrintDepthBpp(pScrn);
463
464   switch (pScrn->bitsPerPixel) {
465   case 8:
466   case 16:
467   case 32:
468      break;
469   default:
470      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
471		 "Given bpp (%d) is not supported by ast driver\n",
472		 pScrn->bitsPerPixel);
473      return FALSE;
474   }
475
476   /* fill pScrn misc. */
477   pScrn->progClock = TRUE;
478   pScrn->rgbBits = 6;
479   pScrn->monitor = pScrn->confScreen->monitor; /* should be initialized before set gamma */
480   pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
481   pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
482
483   /*
484    * If the driver can do gamma correction, it should call xf86SetGamma()
485    * here.
486    */
487   {
488      Gamma zeros = { 0.0, 0.0, 0.0 };
489
490      if (!xf86SetGamma(pScrn, zeros)) {
491         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "call xf86SetGamma failed \n");
492	 return FALSE;
493      }
494   }
495
496
497   if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) {
498       return FALSE;
499   }
500
501   if (!xf86SetDefaultVisual(pScrn, -1)) {
502       return FALSE;
503   }
504
505   /* Allocate driverPrivate */
506   if (!ASTGetRec(pScrn)) {
507       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "call ASTGetRec failed \n");
508       return FALSE;
509   }
510
511   /* Fill AST Info */
512   pAST = ASTPTR(pScrn);
513   pAST->pEnt    = xf86GetEntityInfo(pScrn->entityList[0]);
514   pAST->PciInfo = xf86GetPciInfoForEntity(pAST->pEnt->index);
515   pAST->PciTag  = pciTag(pAST->PciInfo->bus, pAST->PciInfo->device,
516			  pAST->PciInfo->func);
517
518   /* Process the options
519    * pScrn->confScreen, pScrn->display, pScrn->monitor, pScrn->numEntities,
520    * and pScrn->entityList should be initialized before
521    */
522   xf86CollectOptions(pScrn, NULL);
523   if (!(pAST->Options = xalloc(sizeof(ASTOptions))))
524   {
525      ASTFreeRec(pScrn);
526      return FALSE;
527   }
528   memcpy(pAST->Options, ASTOptions, sizeof(ASTOptions));
529   xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pAST->Options);
530
531   /*
532    * Set the Chipset and ChipRev, allowing config file entries to
533    * override.
534    */
535   if (pAST->pEnt->device->chipset && *pAST->pEnt->device->chipset) {
536      pScrn->chipset = pAST->pEnt->device->chipset;
537      from = X_CONFIG;
538   } else if (pAST->pEnt->device->chipID >= 0) {
539      pScrn->chipset = (char *)xf86TokenToString(ASTChipsets,
540						 pAST->pEnt->device->chipID);
541      from = X_CONFIG;
542      xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
543		 pAST->pEnt->device->chipID);
544   } else {
545      from = X_PROBED;
546      pScrn->chipset = (char *)xf86TokenToString(ASTChipsets,
547						 pAST->PciInfo->chipType);
548   }
549   if (pAST->pEnt->device->chipRev >= 0) {
550      xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
551		 pAST->pEnt->device->chipRev);
552   }
553
554   xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n",
555	      (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown ast");
556
557   /* Resource Allocation */
558#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
559    pAST->IODBase = 0;
560#else
561    pAST->IODBase = pScrn->domainIOBase;
562#endif
563    /* "Patch" the PIOOffset inside vgaHW in order to force
564     * the vgaHW module to use our relocated i/o ports.
565     */
566    VGAHWPTR(pScrn)->PIOOffset = pAST->PIOOffset = pAST->IODBase + pAST->PciInfo->ioBase[2] - 0x380;
567
568    pAST->RelocateIO = (IOADDRESS)(pAST->PciInfo->ioBase[2] + pAST->IODBase);
569
570   if (pAST->pEnt->device->MemBase != 0) {
571      pAST->FBPhysAddr = pAST->pEnt->device->MemBase;
572      from = X_CONFIG;
573   } else {
574      if (pAST->PciInfo->memBase[0] != 0) {
575	 pAST->FBPhysAddr = pAST->PciInfo->memBase[0] & 0xFFF00000;
576	 from = X_PROBED;
577      } else {
578	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
579		    "No valid FB address in PCI config space\n");
580	 ASTFreeRec(pScrn);
581	 return FALSE;
582      }
583   }
584   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Linear framebuffer at 0x%lX\n",
585	      (unsigned long) pAST->FBPhysAddr);
586
587   if (pAST->pEnt->device->IOBase != 0) {
588      pAST->MMIOPhysAddr = pAST->pEnt->device->IOBase;
589      from = X_CONFIG;
590   } else {
591      if (pAST->PciInfo->memBase[1]) {
592	 pAST->MMIOPhysAddr = pAST->PciInfo->memBase[1] & 0xFFFF0000;
593	 from = X_PROBED;
594      } else {
595	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
596		    "No valid MMIO address in PCI config space\n");
597	 ASTFreeRec(pScrn);
598	 return FALSE;
599      }
600   }
601   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "IO registers at addr 0x%lX\n",
602	      (unsigned long) pAST->MMIOPhysAddr);
603
604   pScrn->videoRam = GetVRAMInfo(pScrn) / 1024;
605   from = X_DEFAULT;
606
607
608   if (pAST->pEnt->device->videoRam) {
609      pScrn->videoRam = pAST->pEnt->device->videoRam;
610      from = X_CONFIG;
611   }
612
613   pAST->FbMapSize = pScrn->videoRam * 1024;
614   pAST->MMIOMapSize = DEFAULT_MMIO_SIZE;
615
616   /* Map resource */
617   if (!ASTMapMem(pScrn)) {
618      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n");
619      return FALSE;
620   }
621
622   if (!ASTMapMMIO(pScrn)) {
623      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map Memory Map IO Failed \n");
624      return FALSE;
625   }
626
627   pScrn->memPhysBase = (ULONG)pAST->FBPhysAddr;
628   pScrn->fbOffset = 0;
629
630   /* Do DDC
631    * should be done after xf86CollectOptions
632    */
633   pScrn->monitor->DDC = ASTDoDDC(pScrn, pAST->pEnt->index);
634
635   /* Mode Valid */
636   clockRanges = xnfcalloc(sizeof(ClockRange), 1);
637   clockRanges->next = NULL;
638   clockRanges->minClock = 9500;
639   clockRanges->maxClock = GetMaxDCLK(pScrn) * 1000;
640   clockRanges->clockIndex = -1;
641   clockRanges->interlaceAllowed = FALSE;
642   clockRanges->doubleScanAllowed = FALSE;
643
644   i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
645			 pScrn->display->modes, clockRanges,
646			 0, 320, 1600, 8 * pScrn->bitsPerPixel,
647			 200, 1200,
648			 pScrn->display->virtualX, pScrn->display->virtualY,
649			 pAST->FbMapSize, LOOKUP_BEST_REFRESH);
650
651   if (i == -1) {
652      ASTFreeRec(pScrn);
653      return FALSE;
654   }
655
656   xf86PruneDriverModes(pScrn);
657
658   if (!i || !pScrn->modes) {
659      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
660      ASTFreeRec(pScrn);
661      return FALSE;
662   }
663
664   xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
665
666   pScrn->currentMode = pScrn->modes;
667
668   xf86PrintModes(pScrn);
669
670   xf86SetDpi(pScrn, 0, 0);
671
672   /* Accelaration Check */
673   pAST->noAccel = TRUE;
674   pAST->AccelInfoPtr = NULL;
675   pAST->pCMDQPtr = NULL;
676   pAST->CMDQInfo.ulCMDQSize = 0;
677#ifdef	Accel_2D
678   if (!xf86ReturnOptValBool(pAST->Options, OPTION_NOACCEL, FALSE))
679   {
680       if (!xf86LoadSubModule(pScrn, "xaa")) {
681	   ASTFreeRec(pScrn);
682	   return FALSE;
683       }
684       xf86LoaderReqSymLists(xaaSymbols, NULL);
685
686       pAST->noAccel = FALSE;
687
688       pAST->MMIO2D = TRUE;
689#ifndef	MMIO_2D
690       if (!xf86ReturnOptValBool(pAST->Options, OPTION_MMIO2D, FALSE)) {
691           pAST->CMDQInfo.ulCMDQSize = DEFAULT_CMDQ_SIZE;
692           pAST->MMIO2D = FALSE;
693       }
694#endif
695
696       pAST->ENGCaps = ENG_CAP_ALL;
697       if (!xf86GetOptValInteger(pAST->Options, OPTION_ENG_CAPS, &pAST->ENGCaps)) {
698           xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No ENG Capability options found\n");
699       }
700
701       pAST->DBGSelect = 0;
702       if (!xf86GetOptValInteger(pAST->Options, OPTION_DBG_SELECT, &pAST->DBGSelect)) {
703           xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No DBG Seleclt options found\n");
704       }
705   }
706#endif
707
708   /* HW Cursor Check */
709   pAST->noHWC = TRUE;
710   pAST->HWCInfoPtr = NULL;
711   pAST->pHWCPtr = NULL;
712#ifdef	HWC
713   if (!xf86ReturnOptValBool(pAST->Options, OPTION_SW_CURSOR, FALSE)) {
714      if (!xf86LoadSubModule(pScrn, "ramdac")) {
715	 ASTFreeRec(pScrn);
716	 return FALSE;
717      }
718      xf86LoaderReqSymLists(ramdacSymbols, NULL);
719
720      pAST->noHWC = FALSE;
721      pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM;
722      if (!xf86GetOptValInteger(pAST->Options, OPTION_HWC_NUM, &pAST->HWCInfo.HWC_NUM)) {
723          xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No HWC_NUM options found\n");
724      }
725
726   }
727#endif
728
729   /*  We won't be using the VGA access after the probe */
730   xf86SetOperatingState(resVgaIo, pAST->pEnt->index, ResUnusedOpr);
731   xf86SetOperatingState(resVgaMem, pAST->pEnt->index, ResDisableOpr);
732
733   return TRUE;
734}
735
736
737static Bool
738ASTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
739{
740   ScrnInfoPtr pScrn;
741   ASTRecPtr pAST;
742   vgaHWPtr hwp;
743   VisualPtr visual;
744
745   /* for FB Manager */
746   BoxRec FBMemBox;
747   int    AvailFBSize;
748
749   pScrn = xf86Screens[pScreen->myNum];
750   pAST = ASTPTR(pScrn);
751   hwp = VGAHWPTR(pScrn);
752
753/*   if (!pAST->noAccel) */
754   {
755       /* AvailFBSize = pAST->FbMapSize - pAST->CMDQInfo.ulCMDQSize; */
756       AvailFBSize = pAST->FbMapSize;
757
758       FBMemBox.x1 = 0;
759       FBMemBox.y1 = 0;
760       FBMemBox.x2 = pScrn->displayWidth;
761       FBMemBox.y2 = (AvailFBSize / (pScrn->displayWidth * ((pScrn->bitsPerPixel+1)/8))) - 1;
762
763       if (!xf86InitFBManager(pScreen, &FBMemBox)) {
764          xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n");
765          return FALSE;
766       }
767
768   }
769
770   vgaHWGetIOBase(hwp);
771
772   vFillASTModeInfo (pScrn);
773
774   ASTSave(pScrn);
775   if (!ASTModeInit(pScrn, pScrn->currentMode)) {
776      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Mode Init Failed \n");
777      return FALSE;
778   }
779
780   ASTSaveScreen(pScreen, FALSE);
781   ASTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
782
783   miClearVisualTypes();
784
785   /* Re-implemented Direct Color support, -jens */
786   if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
787			 pScrn->rgbBits, pScrn->defaultVisual))
788      return FALSE;
789
790   if (!miSetPixmapDepths())
791   {
792       ASTSaveScreen(pScreen, SCREEN_SAVER_OFF);
793       return FALSE;
794   }
795
796   switch(pScrn->bitsPerPixel) {
797       case 8:
798       case 16:
799       case 32:
800           if (!fbScreenInit(pScreen, pAST->FBVirtualAddr + pScrn->fbOffset,
801  	                     pScrn->virtualX, pScrn->virtualY,
802		             pScrn->xDpi, pScrn->yDpi,
803		             pScrn->displayWidth, pScrn->bitsPerPixel))
804               return FALSE;
805           break;
806       default:
807           return FALSE;
808
809   }
810
811   if (pScrn->bitsPerPixel > 8) {
812      /* Fixup RGB ordering */
813      visual = pScreen->visuals + pScreen->numVisuals;
814      while (--visual >= pScreen->visuals) {
815	 if ((visual->class | DynamicClass) == DirectColor) {
816	    visual->offsetRed = pScrn->offset.red;
817	    visual->offsetGreen = pScrn->offset.green;
818	    visual->offsetBlue = pScrn->offset.blue;
819	    visual->redMask = pScrn->mask.red;
820	    visual->greenMask = pScrn->mask.green;
821	    visual->blueMask = pScrn->mask.blue;
822	 }
823      }
824   }
825
826   fbPictureInit(pScreen, 0, 0);
827
828   xf86SetBlackWhitePixels(pScreen);
829
830#ifdef Accel_2D
831   if (!pAST->noAccel)
832   {
833       if (!ASTAccelInit(pScreen)) {
834           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware acceleration initialization failed\n");
835           pAST->noAccel = TRUE;
836       }
837   }
838#endif /* end of Accel_2D */
839
840   miInitializeBackingStore(pScreen);
841   xf86SetBackingStore(pScreen);
842   xf86SetSilkenMouse(pScreen);
843
844   miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
845
846   if (!pAST->noHWC)
847   {
848       if (!ASTCursorInit(pScreen)) {
849           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware cursor initialization failed\n");
850           pAST->noHWC = TRUE;
851       }
852   }
853
854   if (!miCreateDefColormap(pScreen))
855      return FALSE;
856
857   if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits,
858                    vASTLoadPalette, NULL,
859                    CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) {
860       return FALSE;
861   }
862
863   xf86DPMSInit(pScreen, ASTDisplayPowerManagementSet, 0);
864
865   pScreen->SaveScreen = ASTSaveScreen;
866   pAST->CloseScreen = pScreen->CloseScreen;
867   pScreen->CloseScreen = ASTCloseScreen;
868
869   if (serverGeneration == 1)
870      xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
871
872   return TRUE;
873
874} /* ASTScreenInit */
875
876
877Bool
878ASTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
879{
880   ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
881   ASTRecPtr pAST = ASTPTR(pScrn);
882
883#ifdef	HWC
884   if (pAST->pHWCPtr) {
885       xf86FreeOffscreenLinear(pAST->pHWCPtr);		/* free HWC Cache */
886       pAST->pHWCPtr = NULL;
887   }
888#endif
889
890#ifdef Accel_2D
891   if (pAST->pCMDQPtr) {
892       xf86FreeOffscreenLinear(pAST->pCMDQPtr);		/* free CMDQ */
893       pAST->pCMDQPtr = NULL;
894   }
895   vDisable2D(pScrn, pAST);
896#endif
897
898   ASTRestore(pScrn);
899
900   return ASTModeInit(pScrn, mode);
901
902}
903
904void
905ASTAdjustFrame(int scrnIndex, int x, int y, int flags)
906{
907   ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
908   ASTRecPtr   pAST  = ASTPTR(pScrn);
909   ULONG base;
910
911   base = y * pAST->VideoModeInfo.ScreenWidth + x * ((pAST->VideoModeInfo.bitsPerPixel + 1) / 8);
912   base = base >> 2;				/* DW unit */
913
914   vSetStartAddressCRT1(pAST, base);
915
916}
917
918/* enter into X Server */
919static Bool
920ASTEnterVT(int scrnIndex, int flags)
921{
922   ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
923
924   if (!ASTModeInit(pScrn, pScrn->currentMode))
925      return FALSE;
926   ASTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
927
928   return TRUE;
929
930}
931
932/* leave X server */
933static void
934ASTLeaveVT(int scrnIndex, int flags)
935{
936
937   ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
938   vgaHWPtr hwp = VGAHWPTR(pScrn);
939   ASTRecPtr pAST = ASTPTR(pScrn);
940
941#ifdef	HWC
942   if (pAST->pHWCPtr) {
943       xf86FreeOffscreenLinear(pAST->pHWCPtr);		/* free HWC Cache */
944       pAST->pHWCPtr = NULL;
945   }
946#endif
947
948#ifdef Accel_2D
949   if (pAST->pCMDQPtr) {
950       xf86FreeOffscreenLinear(pAST->pCMDQPtr);		/* free CMDQ */
951       pAST->pCMDQPtr = NULL;
952   }
953   vDisable2D(pScrn, pAST);
954#endif
955
956   ASTRestore(pScrn);
957   vgaHWLock(hwp);
958
959}
960
961static void
962ASTFreeScreen(int scrnIndex, int flags)
963{
964   ASTFreeRec(xf86Screens[scrnIndex]);
965   if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
966      vgaHWFreeHWRec(xf86Screens[scrnIndex]);
967}
968
969
970static ModeStatus
971ASTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
972{
973
974   Bool Flags = MODE_NOMODE;
975
976   if (mode->Flags & V_INTERLACE) {
977      if (verbose) {
978	 xf86DrvMsg(scrnIndex, X_PROBED,
979		    "Removing interlaced mode \"%s\"\n", mode->name);
980      }
981      return MODE_NO_INTERLACE;
982   }
983
984   if ((mode->CrtcHDisplay > MAX_HResolution) || (mode->CrtcVDisplay > MAX_VResolution)) {
985      if (verbose) {
986	 xf86DrvMsg(scrnIndex, X_PROBED,
987		    "Removing the mode \"%s\"\n", mode->name);
988      }
989      return Flags;
990   }
991
992   switch (mode->CrtcHDisplay)
993   {
994   case 640:
995       if (mode->CrtcVDisplay == 480) Flags=MODE_OK;
996       break;
997   case 800:
998       if (mode->CrtcVDisplay == 600) Flags=MODE_OK;
999       break;
1000   case 1024:
1001       if (mode->CrtcVDisplay == 768) Flags=MODE_OK;
1002       break;
1003   case 1280:
1004       if (mode->CrtcVDisplay == 1024) Flags=MODE_OK;
1005       break;
1006   case 1600:
1007       if (mode->CrtcVDisplay == 1200) Flags=MODE_OK;
1008       break;
1009   default:
1010       return Flags;
1011   }
1012
1013   return Flags;
1014
1015}
1016
1017
1018/* Internal used modules */
1019/*
1020 * ASTGetRec and ASTFreeRec --
1021 *
1022 * Private data for the driver is stored in the screen structure.
1023 * These two functions create and destroy that private data.
1024 *
1025 */
1026static Bool
1027ASTGetRec(ScrnInfoPtr pScrn)
1028{
1029   if (pScrn->driverPrivate)
1030      return TRUE;
1031
1032   pScrn->driverPrivate = xnfcalloc(sizeof(ASTRec), 1);
1033   return TRUE;
1034}
1035
1036static void
1037ASTFreeRec(ScrnInfoPtr pScrn)
1038{
1039   if (!pScrn)
1040      return;
1041   if (!pScrn->driverPrivate)
1042      return;
1043   xfree(pScrn->driverPrivate);
1044   pScrn->driverPrivate = 0;
1045}
1046
1047static Bool
1048ASTSaveScreen(ScreenPtr pScreen, Bool unblack)
1049{
1050   /* more ref. SiS */
1051   return vgaHWSaveScreen(pScreen, unblack);
1052}
1053
1054static Bool
1055ASTCloseScreen(int scrnIndex, ScreenPtr pScreen)
1056{
1057   ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1058   vgaHWPtr hwp = VGAHWPTR(pScrn);
1059   ASTRecPtr pAST = ASTPTR(pScrn);
1060
1061   if (pScrn->vtSema == TRUE)
1062   {
1063#ifdef	HWC
1064   if (pAST->pHWCPtr) {
1065       xf86FreeOffscreenLinear(pAST->pHWCPtr);		/* free HWC Cache */
1066       pAST->pHWCPtr = NULL;
1067   }
1068#endif
1069
1070#ifdef Accel_2D
1071   if (pAST->pCMDQPtr) {
1072       xf86FreeOffscreenLinear(pAST->pCMDQPtr);		/* free CMDQ */
1073       pAST->pCMDQPtr = NULL;
1074   }
1075   vDisable2D(pScrn, pAST);
1076#endif
1077
1078      ASTRestore(pScrn);
1079      vgaHWLock(hwp);
1080   }
1081
1082   ASTUnmapMem(pScrn);
1083   vgaHWUnmapMem(pScrn);
1084
1085   if(pAST->AccelInfoPtr) {
1086       XAADestroyInfoRec(pAST->AccelInfoPtr);
1087       pAST->AccelInfoPtr = NULL;
1088   }
1089
1090   if(pAST->HWCInfoPtr) {
1091       xf86DestroyCursorInfoRec(pAST->HWCInfoPtr);
1092       pAST->HWCInfoPtr = NULL;
1093   }
1094
1095   pScrn->vtSema = FALSE;
1096   pScreen->CloseScreen = pAST->CloseScreen;
1097   return (*pScreen->CloseScreen) (scrnIndex, pScreen);
1098}
1099
1100static void
1101ASTSave(ScrnInfoPtr pScrn)
1102{
1103   ASTRecPtr pAST;
1104   vgaRegPtr vgaReg;
1105   ASTRegPtr astReg;
1106   int i;
1107
1108   pAST = ASTPTR(pScrn);
1109   vgaReg = &VGAHWPTR(pScrn)->SavedReg;
1110   astReg = &pAST->SavedReg;
1111
1112   /* do save */
1113   vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
1114
1115   /* Ext. Save */
1116   vASTOpenKey(pScrn);
1117
1118   for (i=0; i<0x50; i++)
1119       GetIndexReg(CRTC_PORT, (UCHAR) (i+0x80), astReg->ExtCRTC[i]);
1120
1121}
1122
1123static void
1124ASTRestore(ScrnInfoPtr pScrn)
1125{
1126   ASTRecPtr pAST;
1127   vgaRegPtr vgaReg;
1128   ASTRegPtr astReg;
1129   int i;
1130
1131   pAST = ASTPTR(pScrn);
1132   vgaReg = &VGAHWPTR(pScrn)->SavedReg;
1133   astReg = &pAST->SavedReg;
1134
1135   /* do restore */
1136   vgaHWProtect(pScrn, TRUE);
1137   vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
1138   vgaHWProtect(pScrn, FALSE);
1139
1140   /* Ext. restore */
1141   vASTOpenKey(pScrn);
1142
1143   for (i=0; i<0x50; i++)
1144       SetIndexReg(CRTC_PORT, (UCHAR) (i+0x80), astReg->ExtCRTC[i]);
1145
1146}
1147
1148static void
1149ASTProbeDDC(ScrnInfoPtr pScrn, int index)
1150{
1151   vbeInfoPtr pVbe;
1152
1153   if (xf86LoadSubModule(pScrn, "vbe")) {
1154      pVbe = VBEInit(NULL, index);
1155      ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
1156      vbeFree(pVbe);
1157   }
1158}
1159
1160static xf86MonPtr
1161ASTDoDDC(ScrnInfoPtr pScrn, int index)
1162{
1163   vbeInfoPtr pVbe;
1164   xf86MonPtr MonInfo = NULL;
1165   ASTRecPtr pAST = ASTPTR(pScrn);
1166
1167   /* Honour Option "noDDC" */
1168   if (xf86ReturnOptValBool(pAST->Options, OPTION_NO_DDC, FALSE)) {
1169      return MonInfo;
1170   }
1171
1172   if (xf86LoadSubModule(pScrn, "vbe") && (pVbe = VBEInit(NULL, index))) {
1173      xf86LoaderReqSymLists(vbeSymbols, NULL);
1174      MonInfo = vbeDoEDID(pVbe, NULL);
1175      xf86PrintEDID(MonInfo);
1176      xf86SetDDCproperties(pScrn, MonInfo);
1177      vbeFree(pVbe);
1178   } else {
1179      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1180		 "this driver cannot do DDC without VBE\n");
1181   }
1182
1183   return MonInfo;
1184}
1185
1186static void
1187vFillASTModeInfo (ScrnInfoPtr pScrn)
1188{
1189    ASTRecPtr pAST;
1190
1191    pAST = ASTPTR(pScrn);
1192
1193    pAST->VideoModeInfo.ScreenWidth = pScrn->virtualX;
1194    pAST->VideoModeInfo.ScreenHeight = pScrn->virtualY;
1195    pAST->VideoModeInfo.bitsPerPixel = pScrn->bitsPerPixel;
1196    pAST->VideoModeInfo.ScreenPitch = pScrn->virtualX * ((pScrn->bitsPerPixel + 1) / 8) ;
1197
1198}
1199
1200static Bool
1201ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
1202{
1203    vgaHWPtr hwp;
1204    ASTRecPtr pAST;
1205
1206    hwp = VGAHWPTR(pScrn);
1207    pAST = ASTPTR(pScrn);
1208
1209    vgaHWUnlock(hwp);
1210
1211    if (!vgaHWInit(pScrn, mode))
1212      return FALSE;
1213
1214    pScrn->vtSema = TRUE;
1215    pAST->ModePtr = mode;
1216
1217    if (!ASTSetMode(pScrn, mode))
1218      return FALSE;
1219
1220    vgaHWProtect(pScrn, FALSE);
1221
1222    return TRUE;
1223}
1224