ast_driver.c revision b410ddbe
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#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
29#include "xf86Resources.h"
30#include "xf86RAC.h"
31#endif
32#include "xf86cmap.h"
33#include "compiler.h"
34#include "mibstore.h"
35#include "vgaHW.h"
36#include "mipointer.h"
37#include "micmap.h"
38
39#include "fb.h"
40#include "regionstr.h"
41#include "xf86xv.h"
42#include <X11/extensions/Xv.h>
43#include "vbe.h"
44
45#include "xf86PciInfo.h"
46#include "xf86Pci.h"
47
48/* framebuffer offscreen manager */
49#include "xf86fbman.h"
50
51/* include xaa includes */
52#include "xaa.h"
53#include "xaarop.h"
54
55/* H/W cursor support */
56#include "xf86Cursor.h"
57
58/* Driver specific headers */
59#include "ast.h"
60
61/* external reference fucntion */
62extern Bool ASTMapMem(ScrnInfoPtr pScrn);
63extern Bool ASTUnmapMem(ScrnInfoPtr pScrn);
64extern Bool ASTMapMMIO(ScrnInfoPtr pScrn);
65extern void ASTUnmapMMIO(ScrnInfoPtr pScrn);
66
67extern void vASTOpenKey(ScrnInfoPtr pScrn);
68extern Bool bASTRegInit(ScrnInfoPtr pScrn);
69extern void GetDRAMInfo(ScrnInfoPtr pScrn);
70extern ULONG GetVRAMInfo(ScrnInfoPtr pScrn);
71extern ULONG GetMaxDCLK(ScrnInfoPtr pScrn);
72extern void GetChipType(ScrnInfoPtr pScrn);
73extern void vASTLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual);
74extern void ASTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
75extern void vSetStartAddressCRT1(ASTRecPtr pAST, ULONG base);
76extern Bool ASTSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode);
77extern Bool GetVGA2EDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer);
78extern void vInitDRAMReg(ScrnInfoPtr pScrn);
79extern Bool bIsVGAEnabled(ScrnInfoPtr pScrn);
80extern void ASTBlankScreen(ScrnInfoPtr pScreen, Bool unblack);
81extern Bool InitVGA(ScrnInfoPtr pScrn);
82
83extern Bool bInitCMDQInfo(ScrnInfoPtr pScrn, ASTRecPtr pAST);
84extern Bool bEnableCMDQ(ScrnInfoPtr pScrn, ASTRecPtr pAST);
85extern void vDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST);
86
87extern Bool ASTAccelInit(ScreenPtr pScreen);
88
89extern Bool ASTCursorInit(ScreenPtr pScreen);
90extern void ASTHideCursor(ScrnInfoPtr pScrn);
91
92/* Mandatory functions */
93static void ASTIdentify(int flags);
94const OptionInfoRec *ASTAvailableOptions(int chipid, int busid);
95static Bool ASTProbe(DriverPtr drv, int flags);
96static Bool ASTPreInit(ScrnInfoPtr pScrn, int flags);
97static Bool ASTScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv);
98Bool ASTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
99void ASTAdjustFrame(int scrnIndex, int x, int y, int flags);
100static Bool ASTEnterVT(int scrnIndex, int flags);
101static void ASTLeaveVT(int scrnIndex, int flags);
102static void ASTFreeScreen(int scrnIndex, int flags);
103static ModeStatus ASTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags);
104
105/* Internally used functions */
106static Bool ASTGetRec(ScrnInfoPtr pScrn);
107static void ASTFreeRec(ScrnInfoPtr pScrn);
108static Bool ASTSaveScreen(ScreenPtr pScreen, Bool unblack);
109static Bool ASTCloseScreen(int scrnIndex, ScreenPtr pScreen);
110static void ASTSave(ScrnInfoPtr pScrn);
111static void ASTRestore(ScrnInfoPtr pScrn);
112static void ASTProbeDDC(ScrnInfoPtr pScrn, int index);
113static xf86MonPtr ASTDoDDC(ScrnInfoPtr pScrn, int index);
114static void vFillASTModeInfo (ScrnInfoPtr pScrn);
115static Bool ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
116
117/*
118 * This is intentionally screen-independent.  It indicates the binding
119 * choice made in the first PreInit.
120 */
121_X_EXPORT DriverRec AST = {
122   AST_VERSION,
123   AST_DRIVER_NAME,
124   ASTIdentify,
125   ASTProbe,
126   ASTAvailableOptions,
127   NULL,
128   0
129};
130
131/* Chipsets */
132static SymTabRec ASTChipsets[] = {
133   {PCI_CHIP_AST2000,	"ASPEED Graphics Family"},
134   {PCI_CHIP_AST2100,	"ASPEED Graphics Family"},
135   {-1,			NULL}
136};
137
138static PciChipsets ASTPciChipsets[] = {
139   {PCI_CHIP_AST2000,		PCI_CHIP_AST2000,	RES_SHARED_VGA},
140   {PCI_CHIP_AST2100,		PCI_CHIP_AST2100,	RES_SHARED_VGA},
141   {-1,				-1, 			RES_UNDEFINED }
142};
143
144typedef enum {
145   OPTION_NOACCEL,
146   OPTION_MMIO2D,
147   OPTION_SW_CURSOR,
148   OPTION_HWC_NUM,
149   OPTION_ENG_CAPS,
150   OPTION_DBG_SELECT,
151   OPTION_NO_DDC,
152   OPTION_VGA2_CLONE
153} ASTOpts;
154
155static const OptionInfoRec ASTOptions[] = {
156   {OPTION_NOACCEL,	"NoAccel",	OPTV_BOOLEAN,	{0},	FALSE},
157   {OPTION_MMIO2D,	"MMIO2D",	OPTV_BOOLEAN,	{0},	FALSE},
158   {OPTION_SW_CURSOR,	"SWCursor",	OPTV_BOOLEAN,	{0},	FALSE},
159   {OPTION_HWC_NUM,	"HWCNumber",	OPTV_INTEGER,	{0},	FALSE},
160   {OPTION_ENG_CAPS,	"ENGCaps",	OPTV_INTEGER,	{0},	FALSE},
161   {OPTION_DBG_SELECT,	"DBGSelect",	OPTV_INTEGER,	{0},	FALSE},
162   {OPTION_NO_DDC,	"NoDDC",	OPTV_BOOLEAN,	{0}, 	FALSE},
163   {OPTION_VGA2_CLONE,	"VGA2Clone",	OPTV_BOOLEAN,	{0}, 	FALSE},
164   {-1,			NULL,		OPTV_NONE,	{0}, 	FALSE}
165};
166
167#ifdef XFree86LOADER
168
169static MODULESETUPPROTO(astSetup);
170
171static XF86ModuleVersionInfo astVersRec = {
172   AST_DRIVER_NAME,
173   MODULEVENDORSTRING,
174   MODINFOSTRING1,
175   MODINFOSTRING2,
176   XORG_VERSION_CURRENT,
177   AST_MAJOR_VERSION, AST_MINOR_VERSION, AST_PATCH_VERSION,
178   ABI_CLASS_VIDEODRV,
179#ifdef PATCH_ABI_VERSION
180   ABI_VIDEODRV_VERSION_PATCH,
181#else
182   ABI_VIDEODRV_VERSION,
183#endif
184   MOD_CLASS_VIDEODRV,
185   {0, 0, 0, 0}
186};
187
188_X_EXPORT XF86ModuleData astModuleData = { &astVersRec, astSetup, NULL };
189
190static pointer
191astSetup(pointer module, pointer opts, int *errmaj, int *errmin)
192{
193   static Bool setupDone = FALSE;
194
195   /* This module should be loaded only once, but check to be sure.
196    */
197   if (!setupDone) {
198      setupDone = TRUE;
199      xf86AddDriver(&AST, module, 0);
200
201      /*
202       * The return value must be non-NULL on success even though there
203       * is no TearDownProc.
204       */
205      return (pointer) TRUE;
206   } else {
207      if (errmaj)
208	 *errmaj = LDR_ONCEONLY;
209      return NULL;
210   }
211}
212
213#endif	/* XFree86LOADER */
214
215/*
216 * ASTIdentify --
217 *
218 * Returns the string name for the driver based on the chipset. In this
219 * case it will always be an AST, so we can return a static string.
220 *
221 */
222static void
223ASTIdentify(int flags)
224{
225   xf86PrintChipsets(AST_NAME, "Driver for ASPEED Graphics Chipsets",
226		     ASTChipsets);
227}
228
229const OptionInfoRec *
230ASTAvailableOptions(int chipid, int busid)
231{
232
233   return ASTOptions;
234
235}
236
237/*
238 * ASTProbe --
239 *
240 * Look through the PCI bus to find cards that are AST boards.
241 * Setup the dispatch table for the rest of the driver functions.
242 *
243 */
244static Bool
245ASTProbe(DriverPtr drv, int flags)
246{
247    int i, numUsed, numDevSections, *usedChips;
248    Bool foundScreen = FALSE;
249    GDevPtr *devSections;
250
251   /*
252    * Find the config file Device sections that match this
253    * driver, and return if there are none.
254    */
255    if ((numDevSections =
256	xf86MatchDevice(AST_DRIVER_NAME, &devSections)) <= 0) {
257      return FALSE;
258    }
259
260#ifndef XSERVER_LIBPCIACCESS
261   /*
262    * This probing is just checking the PCI data the server already
263    * collected.
264    */
265    if (xf86GetPciVideoInfo() == NULL) {
266	return FALSE;
267    }
268#endif
269
270    numUsed = xf86MatchPciInstances(AST_NAME, PCI_VENDOR_AST,
271				   ASTChipsets, ASTPciChipsets,
272				   devSections, numDevSections,
273				   drv, &usedChips);
274
275    xfree(devSections);
276
277    if (flags & PROBE_DETECT) {
278        if (numUsed > 0)
279	    foundScreen = TRUE;
280    } else {
281        for (i = 0; i < numUsed; i++) {
282	    ScrnInfoPtr pScrn = NULL;
283
284	    /* Allocate new ScrnInfoRec and claim the slot */
285	    if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
286					     ASTPciChipsets, 0, 0, 0, 0, 0)))
287            {
288	        EntityInfoPtr pEnt;
289
290	        pEnt = xf86GetEntityInfo(usedChips[i]);
291
292	        pScrn->driverVersion = AST_VERSION;
293	        pScrn->driverName = AST_DRIVER_NAME;
294	        pScrn->name = AST_NAME;
295
296	        pScrn->Probe = ASTProbe;
297	        pScrn->PreInit = ASTPreInit;
298	        pScrn->ScreenInit = ASTScreenInit;
299	        pScrn->SwitchMode = ASTSwitchMode;
300	        pScrn->AdjustFrame = ASTAdjustFrame;
301	        pScrn->EnterVT = ASTEnterVT;
302	        pScrn->LeaveVT = ASTLeaveVT;
303	        pScrn->FreeScreen = ASTFreeScreen;
304	        pScrn->ValidMode = ASTValidMode;
305
306	        foundScreen = TRUE;
307
308	    } /* end of if */
309        }  /* end of for-loop */
310    } /* end of if flags */
311
312    xfree(usedChips);
313
314    return foundScreen;
315}
316
317/*
318 * ASTPreInit --
319 *
320 * Do initial setup of the board before we know what resolution we will
321 * be running at.
322 *
323 */
324static Bool
325ASTPreInit(ScrnInfoPtr pScrn, int flags)
326{
327   EntityInfoPtr pEnt;
328   vgaHWPtr hwp;
329   int flags24;
330   rgb defaultWeight = { 0, 0, 0 };
331
332   ASTRecPtr pAST;
333
334   ClockRangePtr clockRanges;
335   int i;
336   MessageType from;
337
338   /* Suport one adapter only now */
339   if (pScrn->numEntities != 1)
340       return FALSE;
341
342   pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
343
344   if (flags & PROBE_DETECT) {
345       ASTProbeDDC(pScrn, pEnt->index);
346       return TRUE;
347   }
348
349   if (pEnt->location.type != BUS_PCI)
350       return FALSE;
351
352#ifndef XSERVER_LIBPCIACCESS
353   if (xf86RegisterResources(pEnt->index, 0, ResExclusive))
354       return FALSE;
355#endif
356
357   /* The vgahw module should be loaded here when needed */
358   if (!xf86LoadSubModule(pScrn, "vgahw"))
359      return FALSE;
360
361   /* The fb module should be loaded here when needed */
362   if (!xf86LoadSubModule(pScrn, "fb"))
363      return FALSE;
364
365   /* Allocate a vgaHWRec */
366   if (!vgaHWGetHWRec(pScrn))
367       return FALSE;
368   hwp = VGAHWPTR(pScrn);
369
370   /* Color Depth Check */
371   flags24 = Support32bppFb;
372   if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) {
373      return FALSE;
374   } else {
375      switch (pScrn->depth) {
376      case 8:
377      case 16:
378      case 24:
379	 break;
380      default:
381	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
382		    "Given depth (%d) is not supported by ast driver\n",
383		    pScrn->depth);
384	 return FALSE;
385      }
386   }
387   xf86PrintDepthBpp(pScrn);
388
389   switch (pScrn->bitsPerPixel) {
390   case 8:
391   case 16:
392   case 32:
393      break;
394   default:
395      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
396		 "Given bpp (%d) is not supported by ast driver\n",
397		 pScrn->bitsPerPixel);
398      return FALSE;
399   }
400
401   /* fill pScrn misc. */
402   pScrn->progClock = TRUE;
403   pScrn->rgbBits = 6;
404   pScrn->monitor = pScrn->confScreen->monitor; /* should be initialized before set gamma */
405#ifndef XSERVER_LIBPCIACCESS
406   pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
407   pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
408#endif
409
410   /*
411    * If the driver can do gamma correction, it should call xf86SetGamma()
412    * here.
413    */
414   {
415      Gamma zeros = { 0.0, 0.0, 0.0 };
416
417      if (!xf86SetGamma(pScrn, zeros)) {
418         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "call xf86SetGamma failed \n");
419	 return FALSE;
420      }
421   }
422
423
424   if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) {
425       return FALSE;
426   }
427
428   if (!xf86SetDefaultVisual(pScrn, -1)) {
429       return FALSE;
430   }
431
432   /* Allocate driverPrivate */
433   if (!ASTGetRec(pScrn)) {
434       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "call ASTGetRec failed \n");
435       return FALSE;
436   }
437
438   /* Fill AST Info */
439   pAST = ASTPTR(pScrn);
440   pAST->pEnt    = xf86GetEntityInfo(pScrn->entityList[0]);
441   pAST->PciInfo = xf86GetPciInfoForEntity(pAST->pEnt->index);
442#ifndef XSERVER_LIBPCIACCESS
443   pAST->PciTag  = pciTag(pAST->PciInfo->bus, pAST->PciInfo->device,
444			  pAST->PciInfo->func);
445#endif
446
447   /* Process the options
448    * pScrn->confScreen, pScrn->display, pScrn->monitor, pScrn->numEntities,
449    * and pScrn->entityList should be initialized before
450    */
451   xf86CollectOptions(pScrn, NULL);
452   if (!(pAST->Options = xalloc(sizeof(ASTOptions))))
453   {
454      ASTFreeRec(pScrn);
455      return FALSE;
456   }
457   memcpy(pAST->Options, ASTOptions, sizeof(ASTOptions));
458   xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pAST->Options);
459
460   /*
461    * Set the Chipset and ChipRev, allowing config file entries to
462    * override.
463    */
464   if (pAST->pEnt->device->chipset && *pAST->pEnt->device->chipset) {
465      pScrn->chipset = pAST->pEnt->device->chipset;
466      from = X_CONFIG;
467   } else if (pAST->pEnt->device->chipID >= 0) {
468      pScrn->chipset = (char *)xf86TokenToString(ASTChipsets,
469						 pAST->pEnt->device->chipID);
470      from = X_CONFIG;
471      xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
472		 pAST->pEnt->device->chipID);
473   } else {
474      from = X_PROBED;
475      pScrn->chipset = (char *)xf86TokenToString(ASTChipsets,
476						 PCI_DEV_DEVICE_ID(pAST->PciInfo));
477   }
478   if (pAST->pEnt->device->chipRev >= 0) {
479      xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
480		 pAST->pEnt->device->chipRev);
481   }
482
483   xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n",
484	      (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown ast");
485
486   /* Resource Allocation */
487    pAST->IODBase = pScrn->domainIOBase;
488    /* "Patch" the PIOOffset inside vgaHW in order to force
489     * the vgaHW module to use our relocated i/o ports.
490     */
491    VGAHWPTR(pScrn)->PIOOffset = pAST->PIOOffset = pAST->IODBase + PCI_REGION_BASE(pAST->PciInfo, 2, REGION_IO) - 0x380;
492
493    pAST->RelocateIO = (IOADDRESS)(PCI_REGION_BASE(pAST->PciInfo, 2, REGION_IO) + pAST->IODBase);
494
495   if (pAST->pEnt->device->MemBase != 0) {
496      pAST->FBPhysAddr = pAST->pEnt->device->MemBase;
497      from = X_CONFIG;
498   } else {
499      if (PCI_REGION_BASE(pAST->PciInfo, 0, REGION_MEM) != 0) {
500	 pAST->FBPhysAddr = PCI_REGION_BASE(pAST->PciInfo, 0, REGION_MEM) & 0xFFF00000;
501	 from = X_PROBED;
502      } else {
503	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
504		    "No valid FB address in PCI config space\n");
505	 ASTFreeRec(pScrn);
506	 return FALSE;
507      }
508   }
509   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Linear framebuffer at 0x%lX\n",
510	      (unsigned long) pAST->FBPhysAddr);
511
512   if (pAST->pEnt->device->IOBase != 0) {
513      pAST->MMIOPhysAddr = pAST->pEnt->device->IOBase;
514      from = X_CONFIG;
515   } else {
516      if (PCI_REGION_BASE(pAST->PciInfo, 1, REGION_MEM)) {
517	 pAST->MMIOPhysAddr = PCI_REGION_BASE(pAST->PciInfo, 1, REGION_MEM) & 0xFFFF0000;
518	 from = X_PROBED;
519      } else {
520	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
521		    "No valid MMIO address in PCI config space\n");
522	 ASTFreeRec(pScrn);
523	 return FALSE;
524      }
525   }
526   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "IO registers at addr 0x%lX\n",
527	      (unsigned long) pAST->MMIOPhysAddr);
528
529   /* Map MMIO */
530   pAST->MMIOMapSize = DEFAULT_MMIO_SIZE;
531   if (!ASTMapMMIO(pScrn)) {
532      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map Memory Map IO Failed \n");
533      return FALSE;
534   }
535
536   /* Init VGA Adapter */
537   if (!xf86IsPrimaryPci(pAST->PciInfo))
538   {
539       InitVGA(pScrn);
540   }
541
542   vASTOpenKey(pScrn);
543   bASTRegInit(pScrn);
544
545   /* Get Chip Type */
546   if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x20)
547       pAST->jChipType = AST2300;
548   else if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x10)
549       GetChipType(pScrn);
550   else
551       pAST->jChipType = AST2000;
552
553   /* Get DRAM Info */
554   GetDRAMInfo(pScrn);
555
556   /* Map Framebuffer */
557   pScrn->videoRam = GetVRAMInfo(pScrn) / 1024;
558   from = X_DEFAULT;
559
560   if (pAST->pEnt->device->videoRam) {
561      pScrn->videoRam = pAST->pEnt->device->videoRam;
562      from = X_CONFIG;
563   }
564
565   pAST->FbMapSize = pScrn->videoRam * 1024;
566
567#if 0
568   if (!ASTMapMem(pScrn)) {
569      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n");
570      return FALSE;
571   }
572#endif
573
574   pScrn->memPhysBase = (ULONG)pAST->FBPhysAddr;
575   pScrn->fbOffset = 0;
576
577   /* Do DDC
578    * should be done after xf86CollectOptions
579    */
580   pScrn->monitor->DDC = ASTDoDDC(pScrn, pAST->pEnt->index);
581
582   /* Mode Valid */
583   clockRanges = xnfcalloc(sizeof(ClockRange), 1);
584   clockRanges->next = NULL;
585   clockRanges->minClock = 9500;
586   clockRanges->maxClock = GetMaxDCLK(pScrn) * 1000;
587   clockRanges->clockIndex = -1;
588   clockRanges->interlaceAllowed = FALSE;
589   clockRanges->doubleScanAllowed = FALSE;
590
591   /* Add for AST2100, ycchen@061807 */
592   if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300))
593       i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
594			 pScrn->display->modes, clockRanges,
595			 0, 320, 1920, 8 * pScrn->bitsPerPixel,
596			 200, 1200,
597			 pScrn->display->virtualX, pScrn->display->virtualY,
598			 pAST->FbMapSize, LOOKUP_BEST_REFRESH);
599   else
600       i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
601			 pScrn->display->modes, clockRanges,
602			 0, 320, 1600, 8 * pScrn->bitsPerPixel,
603			 200, 1200,
604			 pScrn->display->virtualX, pScrn->display->virtualY,
605			 pAST->FbMapSize, LOOKUP_BEST_REFRESH);
606
607   if (i == -1) {
608      ASTFreeRec(pScrn);
609      return FALSE;
610   }
611
612   xf86PruneDriverModes(pScrn);
613
614   if (!i || !pScrn->modes) {
615      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
616      ASTFreeRec(pScrn);
617      return FALSE;
618   }
619
620   xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
621
622   pScrn->currentMode = pScrn->modes;
623
624   xf86PrintModes(pScrn);
625
626   xf86SetDpi(pScrn, 0, 0);
627
628   /* Accelaration Check */
629   pAST->noAccel = TRUE;
630   pAST->AccelInfoPtr = NULL;
631   pAST->pCMDQPtr = NULL;
632   pAST->CMDQInfo.ulCMDQSize = 0;
633#ifdef	Accel_2D
634   if (!xf86ReturnOptValBool(pAST->Options, OPTION_NOACCEL, FALSE))
635   {
636       if (!xf86LoadSubModule(pScrn, "xaa")) {
637	   ASTFreeRec(pScrn);
638	   return FALSE;
639       }
640
641       pAST->noAccel = FALSE;
642
643       pAST->MMIO2D = TRUE;
644#ifndef	MMIO_2D
645       if (!xf86ReturnOptValBool(pAST->Options, OPTION_MMIO2D, FALSE)) {
646           pAST->CMDQInfo.ulCMDQSize = DEFAULT_CMDQ_SIZE;
647           pAST->MMIO2D = FALSE;
648       }
649#endif
650
651       pAST->ENGCaps = ENG_CAP_ALL;
652       if (!xf86GetOptValInteger(pAST->Options, OPTION_ENG_CAPS, &pAST->ENGCaps)) {
653           xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No ENG Capability options found\n");
654       }
655
656       pAST->DBGSelect = 0;
657       if (!xf86GetOptValInteger(pAST->Options, OPTION_DBG_SELECT, &pAST->DBGSelect)) {
658           xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No DBG Seleclt options found\n");
659       }
660   }
661#endif
662
663   /* HW Cursor Check */
664   pAST->noHWC = TRUE;
665   pAST->HWCInfoPtr = NULL;
666   pAST->pHWCPtr = NULL;
667#ifdef	HWC
668   if (!xf86ReturnOptValBool(pAST->Options, OPTION_SW_CURSOR, FALSE)) {
669      if (!xf86LoadSubModule(pScrn, "ramdac")) {
670	 ASTFreeRec(pScrn);
671	 return FALSE;
672      }
673
674      pAST->noHWC = FALSE;
675      pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM;
676      if (!xf86GetOptValInteger(pAST->Options, OPTION_HWC_NUM, &pAST->HWCInfo.HWC_NUM)) {
677          xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No HWC_NUM options found\n");
678      }
679
680   }
681#endif
682
683#ifndef XSERVER_LIBPCIACCESS
684   /*  We won't be using the VGA access after the probe */
685   xf86SetOperatingState(resVgaIo, pAST->pEnt->index, ResUnusedOpr);
686   xf86SetOperatingState(resVgaMem, pAST->pEnt->index, ResDisableOpr);
687#endif
688
689   return TRUE;
690}
691
692
693static Bool
694ASTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
695{
696   ScrnInfoPtr pScrn;
697   ASTRecPtr pAST;
698   vgaHWPtr hwp;
699   VisualPtr visual;
700
701   /* for FB Manager */
702   BoxRec FBMemBox;
703   int    AvailFBSize;
704
705   pScrn = xf86Screens[pScreen->myNum];
706   pAST = ASTPTR(pScrn);
707   hwp = VGAHWPTR(pScrn);
708
709   if (!ASTMapMem(pScrn)) {
710      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n");
711      return FALSE;
712   }
713
714/*   if (!pAST->noAccel) */
715   {
716       /* AvailFBSize = pAST->FbMapSize - pAST->CMDQInfo.ulCMDQSize; */
717       AvailFBSize = pAST->FbMapSize;
718
719       FBMemBox.x1 = 0;
720       FBMemBox.y1 = 0;
721       FBMemBox.x2 = pScrn->displayWidth;
722       FBMemBox.y2 = (AvailFBSize / (pScrn->displayWidth * ((pScrn->bitsPerPixel+1)/8))) - 1;
723
724       if (!xf86InitFBManager(pScreen, &FBMemBox)) {
725          xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n");
726          return FALSE;
727       }
728
729   }
730
731   vgaHWGetIOBase(hwp);
732
733   vFillASTModeInfo (pScrn);
734
735   ASTSave(pScrn);
736   if (!ASTModeInit(pScrn, pScrn->currentMode)) {
737      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Mode Init Failed \n");
738      return FALSE;
739   }
740
741   ASTSaveScreen(pScreen, FALSE);
742   ASTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
743
744   miClearVisualTypes();
745
746   /* Re-implemented Direct Color support, -jens */
747   if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
748			 pScrn->rgbBits, pScrn->defaultVisual))
749      return FALSE;
750
751   if (!miSetPixmapDepths())
752   {
753       ASTSaveScreen(pScreen, SCREEN_SAVER_OFF);
754       return FALSE;
755   }
756
757   switch(pScrn->bitsPerPixel) {
758       case 8:
759       case 16:
760       case 32:
761           if (!fbScreenInit(pScreen, pAST->FBVirtualAddr + pScrn->fbOffset,
762  	                     pScrn->virtualX, pScrn->virtualY,
763		             pScrn->xDpi, pScrn->yDpi,
764		             pScrn->displayWidth, pScrn->bitsPerPixel))
765               return FALSE;
766           break;
767       default:
768           return FALSE;
769
770   }
771
772   if (pScrn->bitsPerPixel > 8) {
773      /* Fixup RGB ordering */
774      visual = pScreen->visuals + pScreen->numVisuals;
775      while (--visual >= pScreen->visuals) {
776	 if ((visual->class | DynamicClass) == DirectColor) {
777	    visual->offsetRed = pScrn->offset.red;
778	    visual->offsetGreen = pScrn->offset.green;
779	    visual->offsetBlue = pScrn->offset.blue;
780	    visual->redMask = pScrn->mask.red;
781	    visual->greenMask = pScrn->mask.green;
782	    visual->blueMask = pScrn->mask.blue;
783	 }
784      }
785   }
786
787   fbPictureInit(pScreen, 0, 0);
788
789   xf86SetBlackWhitePixels(pScreen);
790
791#ifdef Accel_2D
792   if (!pAST->noAccel)
793   {
794       if (!ASTAccelInit(pScreen)) {
795           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware acceleration initialization failed\n");
796           pAST->noAccel = TRUE;
797       }
798   }
799#endif /* end of Accel_2D */
800
801   miInitializeBackingStore(pScreen);
802   xf86SetBackingStore(pScreen);
803   xf86SetSilkenMouse(pScreen);
804
805   miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
806
807   if (!pAST->noHWC)
808   {
809       if (!ASTCursorInit(pScreen)) {
810           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware cursor initialization failed\n");
811           pAST->noHWC = TRUE;
812       }
813   }
814
815   if (!miCreateDefColormap(pScreen))
816      return FALSE;
817
818   if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits,
819                    vASTLoadPalette, NULL,
820                    CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) {
821       return FALSE;
822   }
823
824   xf86DPMSInit(pScreen, ASTDisplayPowerManagementSet, 0);
825
826   pScreen->SaveScreen = ASTSaveScreen;
827   pAST->CloseScreen = pScreen->CloseScreen;
828   pScreen->CloseScreen = ASTCloseScreen;
829
830   if (serverGeneration == 1)
831      xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
832
833   return TRUE;
834
835} /* ASTScreenInit */
836
837
838Bool
839ASTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
840{
841   ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
842   ASTRecPtr pAST = ASTPTR(pScrn);
843
844#ifdef	HWC
845   if (pAST->pHWCPtr) {
846       xf86FreeOffscreenLinear(pAST->pHWCPtr);		/* free HWC Cache */
847       pAST->pHWCPtr = NULL;
848   }
849   ASTHideCursor(pScrn);
850#endif
851
852#ifdef Accel_2D
853   if (pAST->pCMDQPtr) {
854       xf86FreeOffscreenLinear(pAST->pCMDQPtr);		/* free CMDQ */
855       pAST->pCMDQPtr = NULL;
856   }
857   vDisable2D(pScrn, pAST);
858#endif
859
860   /* Fixed display abnormal on the of the screen if run xvidtune, ycchen@122909 */
861   /* ASTRestore(pScrn); */
862
863   return ASTModeInit(pScrn, mode);
864
865}
866
867void
868ASTAdjustFrame(int scrnIndex, int x, int y, int flags)
869{
870   ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
871   ASTRecPtr   pAST  = ASTPTR(pScrn);
872   ULONG base;
873
874   base = y * pAST->VideoModeInfo.ScreenWidth + x * ((pAST->VideoModeInfo.bitsPerPixel + 1) / 8);
875   base = base >> 2;				/* DW unit */
876
877   vSetStartAddressCRT1(pAST, base);
878
879}
880
881/* enter into X Server */
882static Bool
883ASTEnterVT(int scrnIndex, int flags)
884{
885   ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
886
887   /* Fixed suspend can't resume issue */
888   if (!bIsVGAEnabled(pScrn))
889   {
890       InitVGA(pScrn);
891       ASTRestore(pScrn);
892   }
893
894   if (!ASTModeInit(pScrn, pScrn->currentMode))
895      return FALSE;
896   ASTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
897
898   return TRUE;
899
900}
901
902/* leave X server */
903static void
904ASTLeaveVT(int scrnIndex, int flags)
905{
906
907   ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
908   vgaHWPtr hwp = VGAHWPTR(pScrn);
909   ASTRecPtr pAST = ASTPTR(pScrn);
910
911#ifdef	HWC
912   if (pAST->pHWCPtr) {
913       xf86FreeOffscreenLinear(pAST->pHWCPtr);		/* free HWC Cache */
914       pAST->pHWCPtr = NULL;
915   }
916   ASTHideCursor(pScrn);
917#endif
918
919#ifdef Accel_2D
920   if (pAST->pCMDQPtr) {
921       xf86FreeOffscreenLinear(pAST->pCMDQPtr);		/* free CMDQ */
922       pAST->pCMDQPtr = NULL;
923   }
924   vDisable2D(pScrn, pAST);
925#endif
926
927   ASTRestore(pScrn);
928   vgaHWLock(hwp);
929
930}
931
932static void
933ASTFreeScreen(int scrnIndex, int flags)
934{
935   ASTFreeRec(xf86Screens[scrnIndex]);
936   if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
937      vgaHWFreeHWRec(xf86Screens[scrnIndex]);
938}
939
940
941static ModeStatus
942ASTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
943{
944
945   ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
946   ASTRecPtr   pAST  = ASTPTR(pScrn);
947   Bool Flags = MODE_NOMODE;
948
949   if (mode->Flags & V_INTERLACE) {
950      if (verbose) {
951	 xf86DrvMsg(scrnIndex, X_PROBED,
952		    "Removing interlaced mode \"%s\"\n", mode->name);
953      }
954      return MODE_NO_INTERLACE;
955   }
956
957   if ((mode->CrtcHDisplay > MAX_HResolution) || (mode->CrtcVDisplay > MAX_VResolution)) {
958      if (verbose) {
959	 xf86DrvMsg(scrnIndex, X_PROBED,
960		    "Removing the mode \"%s\"\n", mode->name);
961      }
962      return Flags;
963   }
964
965   /* Add for AST2100, ycchen@061807 */
966   if ( (pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) )
967   {
968       if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1200) )
969           return MODE_OK;
970       if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1080) )
971           return MODE_OK;
972   }
973
974   if ((pAST->jChipType == AST1100) || (pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2150) || (pAST->jChipType == AST2300))
975   {
976
977       if ( (mode->CrtcHDisplay == 1680) && (mode->CrtcVDisplay == 1050) )
978           return MODE_OK;
979       if ( (mode->CrtcHDisplay == 1440) && (mode->CrtcVDisplay == 900) )
980           return MODE_OK;
981       if ( (mode->CrtcHDisplay == 1280) && (mode->CrtcVDisplay == 800) )
982           return MODE_OK;
983
984   }
985
986   switch (mode->CrtcHDisplay)
987   {
988   case 640:
989       if (mode->CrtcVDisplay == 480) Flags=MODE_OK;
990       break;
991   case 800:
992       if (mode->CrtcVDisplay == 600) Flags=MODE_OK;
993       break;
994   case 1024:
995       if (mode->CrtcVDisplay == 768) Flags=MODE_OK;
996       break;
997   case 1280:
998       if (mode->CrtcVDisplay == 1024) Flags=MODE_OK;
999       break;
1000   case 1600:
1001       if (mode->CrtcVDisplay == 1200) Flags=MODE_OK;
1002       break;
1003   default:
1004       return Flags;
1005   }
1006
1007   return Flags;
1008
1009}
1010
1011
1012/* Internal used modules */
1013/*
1014 * ASTGetRec and ASTFreeRec --
1015 *
1016 * Private data for the driver is stored in the screen structure.
1017 * These two functions create and destroy that private data.
1018 *
1019 */
1020static Bool
1021ASTGetRec(ScrnInfoPtr pScrn)
1022{
1023   if (pScrn->driverPrivate)
1024      return TRUE;
1025
1026   pScrn->driverPrivate = xnfcalloc(sizeof(ASTRec), 1);
1027   return TRUE;
1028}
1029
1030static void
1031ASTFreeRec(ScrnInfoPtr pScrn)
1032{
1033   if (!pScrn)
1034      return;
1035   if (!pScrn->driverPrivate)
1036      return;
1037   xfree(pScrn->driverPrivate);
1038   pScrn->driverPrivate = 0;
1039}
1040
1041static Bool
1042ASTSaveScreen(ScreenPtr pScreen, Bool unblack)
1043{
1044   /* replacement of vgaHWBlankScreen(pScrn, unblank) without seq reset */
1045   /* return vgaHWSaveScreen(pScreen, unblack); */
1046   ScrnInfoPtr pScrn = NULL;
1047
1048   if (pScreen != NULL)
1049      pScrn = xf86Screens[pScreen->myNum];
1050
1051   if ((pScrn != NULL) && pScrn->vtSema) {
1052     ASTBlankScreen(pScrn, unblack);
1053   }
1054   return (TRUE);
1055}
1056
1057static Bool
1058ASTCloseScreen(int scrnIndex, ScreenPtr pScreen)
1059{
1060   ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1061   vgaHWPtr hwp = VGAHWPTR(pScrn);
1062   ASTRecPtr pAST = ASTPTR(pScrn);
1063
1064   if (pScrn->vtSema == TRUE)
1065   {
1066#ifdef	HWC
1067   if (pAST->pHWCPtr) {
1068       xf86FreeOffscreenLinear(pAST->pHWCPtr);		/* free HWC Cache */
1069       pAST->pHWCPtr = NULL;
1070   }
1071   ASTHideCursor(pScrn);
1072#endif
1073
1074#ifdef Accel_2D
1075   if (pAST->pCMDQPtr) {
1076       xf86FreeOffscreenLinear(pAST->pCMDQPtr);		/* free CMDQ */
1077       pAST->pCMDQPtr = NULL;
1078   }
1079   vDisable2D(pScrn, pAST);
1080#endif
1081
1082      ASTRestore(pScrn);
1083      vgaHWLock(hwp);
1084   }
1085
1086   ASTUnmapMem(pScrn);
1087   vgaHWUnmapMem(pScrn);
1088
1089   if(pAST->AccelInfoPtr) {
1090       XAADestroyInfoRec(pAST->AccelInfoPtr);
1091       pAST->AccelInfoPtr = NULL;
1092   }
1093
1094   if(pAST->HWCInfoPtr) {
1095       xf86DestroyCursorInfoRec(pAST->HWCInfoPtr);
1096       pAST->HWCInfoPtr = NULL;
1097   }
1098
1099   pScrn->vtSema = FALSE;
1100   pScreen->CloseScreen = pAST->CloseScreen;
1101   return (*pScreen->CloseScreen) (scrnIndex, pScreen);
1102}
1103
1104static void
1105ASTSave(ScrnInfoPtr pScrn)
1106{
1107   ASTRecPtr pAST;
1108   vgaRegPtr vgaReg;
1109   ASTRegPtr astReg;
1110   int i, icount=0;
1111
1112   pAST = ASTPTR(pScrn);
1113   vgaReg = &VGAHWPTR(pScrn)->SavedReg;
1114   astReg = &pAST->SavedReg;
1115
1116   /* do save */
1117   if (xf86IsPrimaryPci(pAST->PciInfo)) {
1118       vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
1119   }
1120   else {
1121       vgaHWSave(pScrn, vgaReg, VGA_SR_MODE);
1122   }
1123
1124   /* Ext. Save */
1125   vASTOpenKey(pScrn);
1126
1127   /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */
1128   for (i=0x81; i<=0xB6; i++)
1129       GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]);
1130   for (i=0xBC; i<=0xC1; i++)
1131       GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]);
1132   GetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]);
1133
1134}
1135
1136static void
1137ASTRestore(ScrnInfoPtr pScrn)
1138{
1139   ASTRecPtr pAST;
1140   vgaRegPtr vgaReg;
1141   ASTRegPtr astReg;
1142   int i, icount=0;
1143
1144   pAST = ASTPTR(pScrn);
1145   vgaReg = &VGAHWPTR(pScrn)->SavedReg;
1146   astReg = &pAST->SavedReg;
1147
1148   /* do restore */
1149   vgaHWProtect(pScrn, TRUE);
1150   if (xf86IsPrimaryPci(pAST->PciInfo))
1151       vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
1152   else
1153       vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
1154   vgaHWProtect(pScrn, FALSE);
1155
1156   /* Ext. restore */
1157   vASTOpenKey(pScrn);
1158
1159   /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */
1160   for (i=0x81; i<=0xB6; i++)
1161       SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]);
1162   for (i=0xBC; i<=0xC1; i++)
1163       SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]);
1164   SetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]);
1165
1166}
1167
1168static void
1169ASTProbeDDC(ScrnInfoPtr pScrn, int index)
1170{
1171   vbeInfoPtr pVbe;
1172
1173   if (xf86LoadSubModule(pScrn, "vbe")) {
1174      pVbe = VBEInit(NULL, index);
1175      ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
1176      vbeFree(pVbe);
1177   }
1178}
1179
1180#define SkipDT	0x00
1181#define DT1	0x01
1182#define DT2 	0x02
1183
1184static xf86MonPtr
1185ASTDoDDC(ScrnInfoPtr pScrn, int index)
1186{
1187   vbeInfoPtr pVbe;
1188   xf86MonPtr MonInfo = NULL, MonInfo1 = NULL, MonInfo2 = NULL;
1189   ASTRecPtr pAST = ASTPTR(pScrn);
1190   unsigned long i, j, k;
1191   unsigned char DDC_data[128];
1192   struct monitor_ranges ranges, ranges1, ranges2;
1193   int DTSelect, dclock1=0, h_active1=0, v_active1=0, dclock2=0, h_active2=0, v_active2=0;
1194   struct std_timings stdtiming, *stdtiming1, *stdtiming2;
1195
1196   /* Honour Option "noDDC" */
1197   if (xf86ReturnOptValBool(pAST->Options, OPTION_NO_DDC, FALSE)) {
1198      return MonInfo;
1199   }
1200
1201   if (xf86LoadSubModule(pScrn, "vbe") && (pVbe = VBEInit(NULL, index))) {
1202      MonInfo1 = vbeDoEDID(pVbe, NULL);
1203      MonInfo = MonInfo1;
1204
1205      /* For VGA2 CLONE Support, ycchen@012508 */
1206      if ((xf86ReturnOptValBool(pAST->Options, OPTION_VGA2_CLONE, FALSE)) || pAST->VGA2Clone) {
1207          if (GetVGA2EDID(pScrn, DDC_data) == TRUE) {
1208              xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Get VGA2 EDID Correctly!! \n");
1209              MonInfo2 = xf86InterpretEDID(pScrn->scrnIndex, DDC_data);
1210              if (MonInfo1 == NULL)	/* No DDC1 EDID */
1211                  MonInfo = MonInfo2;
1212              else {			/* Check with VGA1 & VGA2 EDID */
1213                  /* Update establishment timing */
1214                  MonInfo->timings1.t1 = MonInfo1->timings1.t1 & MonInfo2->timings1.t1;
1215                  MonInfo->timings1.t2 = MonInfo1->timings1.t2 & MonInfo2->timings1.t2;
1216                  MonInfo->timings1.t_manu = MonInfo1->timings1.t_manu & MonInfo2->timings1.t_manu;
1217
1218                  /* Update Std. Timing */
1219                  for (i=0; i<8; i++) {
1220	              stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0;
1221                      for (j=0; j<8; j++) {
1222                          if ((MonInfo1->timings2[i].hsize == MonInfo2->timings2[j].hsize) && \
1223                              (MonInfo1->timings2[i].vsize == MonInfo2->timings2[j].vsize) && \
1224                              (MonInfo1->timings2[i].refresh == MonInfo2->timings2[j].refresh)) {
1225                               stdtiming = MonInfo1->timings2[i];
1226                               break;
1227                          }
1228                      }
1229
1230                      MonInfo->timings2[i] = stdtiming;
1231                  } /* Std. Timing */
1232
1233                  /* Get Detailed Timing */
1234                  for (i=0;i<4;i++) {
1235                    if (MonInfo1->det_mon[i].type == 0xFD)
1236                        ranges1 = MonInfo1->det_mon[i].section.ranges;
1237                    else if (MonInfo1->det_mon[i].type == 0xFA)
1238                        stdtiming1 = MonInfo1->det_mon[i].section.std_t;
1239                    else if (MonInfo1->det_mon[i].type == 0x00) {
1240                        if (MonInfo1->det_mon[i].section.d_timings.clock > dclock1)
1241                            dclock1 = MonInfo1->det_mon[i].section.d_timings.clock;
1242                        if (MonInfo1->det_mon[i].section.d_timings.h_active > h_active1)
1243                            h_active1 = MonInfo1->det_mon[i].section.d_timings.h_active;
1244                        if (MonInfo1->det_mon[i].section.d_timings.v_active > v_active1)
1245                            v_active1 = MonInfo1->det_mon[i].section.d_timings.v_active;
1246                    }
1247                    if (MonInfo2->det_mon[i].type == 0xFD)
1248                        ranges2 = MonInfo2->det_mon[i].section.ranges;
1249                    else if (MonInfo1->det_mon[i].type == 0xFA)
1250                        stdtiming2 = MonInfo2->det_mon[i].section.std_t;
1251                    else if (MonInfo2->det_mon[i].type == 0x00) {
1252                        if (MonInfo2->det_mon[i].section.d_timings.clock > dclock2)
1253                            dclock2 = MonInfo2->det_mon[i].section.d_timings.clock;
1254                        if (MonInfo2->det_mon[i].section.d_timings.h_active > h_active2)
1255                            h_active2 = MonInfo2->det_mon[i].section.d_timings.h_active;
1256                        if (MonInfo2->det_mon[i].section.d_timings.v_active > v_active2)
1257                            v_active2 = MonInfo2->det_mon[i].section.d_timings.v_active;
1258                    }
1259                  } /* Get Detailed Timing */
1260
1261                  /* Chk Detailed Timing */
1262                  if ((dclock1 >= dclock2) && (h_active1 >= h_active2) && (v_active1 >= v_active2))
1263                      DTSelect = DT2;
1264                  else if ((dclock2 >= dclock1) && (h_active2 >= h_active1) && (v_active2 >= v_active1))
1265                      DTSelect = DT1;
1266                  else
1267                      DTSelect = SkipDT;
1268
1269                  /* Chk Monitor Descriptor */
1270                  ranges = ranges1;
1271                  ranges.min_h = ranges1.min_h > ranges2.min_h ? ranges1.min_h:ranges2.min_h;
1272                  ranges.min_v = ranges1.min_v > ranges2.min_v ? ranges1.min_v:ranges2.min_v;
1273                  ranges.max_h = ranges1.max_h < ranges2.max_h ? ranges1.max_h:ranges2.max_h;
1274                  ranges.max_v = ranges1.max_v < ranges2.max_v ? ranges1.max_v:ranges2.max_v;
1275                  ranges.max_clock = ranges1.max_clock < ranges2.max_clock ? ranges1.max_clock:ranges2.max_clock;
1276
1277                  /* Update Detailed Timing */
1278                  for (i=0; i<4; i++)
1279                  {
1280                      if (MonInfo->det_mon[i].type == 0xFD) {
1281                          MonInfo->det_mon[i].section.ranges = ranges;
1282                      }
1283                      else if (MonInfo->det_mon[i].type == 0xFA) {
1284                         for (j=0; j<5; j++) {
1285            	             stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0;
1286                             for (k=0; k<5; k++) {
1287                                 if ((stdtiming1[j].hsize == stdtiming2[k].hsize) && \
1288                                     (stdtiming1[j].vsize == stdtiming2[k].vsize) && \
1289                                     (stdtiming1[j].refresh == stdtiming2[k].refresh)) {
1290                                      stdtiming = stdtiming1[j];
1291                                      break;
1292                                 }
1293                             }
1294                             stdtiming1[j] = stdtiming;
1295                         } /* Std. Timing */
1296                      } /* FA */
1297                      else if (MonInfo->det_mon[i].type == 0x00) {
1298                          if (DTSelect == DT2)
1299                              MonInfo->det_mon[i] = MonInfo2->det_mon[i];
1300                          else if (DTSelect == DT1)
1301                              MonInfo->det_mon[i] = MonInfo1->det_mon[i];
1302                          else /* SkipDT */
1303                          {   /* use 1024x768 as default */
1304                              MonInfo->det_mon[i] = MonInfo1->det_mon[i];
1305                              MonInfo->det_mon[i].section.d_timings.clock = 65000000;
1306                              MonInfo->det_mon[i].section.d_timings.h_active = 1024;
1307                              MonInfo->det_mon[i].section.d_timings.h_blanking = 320;
1308                              MonInfo->det_mon[i].section.d_timings.v_active = 768;
1309                              MonInfo->det_mon[i].section.d_timings.v_blanking = 38;
1310                              MonInfo->det_mon[i].section.d_timings.h_sync_off = 24;
1311                              MonInfo->det_mon[i].section.d_timings.h_sync_width = 136;
1312                              MonInfo->det_mon[i].section.d_timings.v_sync_off = 3;
1313                              MonInfo->det_mon[i].section.d_timings.v_sync_width = 6;
1314                          }
1315                      } /* 00 */
1316                      else { /* use Monitor 1 as default */
1317                          MonInfo->det_mon[i] = MonInfo1->det_mon[i];
1318                      }
1319
1320                  } /* Update Detailed Timing */
1321
1322                  /* set feature size */
1323                  if (DTSelect == DT2)  {
1324                      MonInfo->features.hsize = MonInfo2->features.hsize;
1325                      MonInfo->features.vsize = MonInfo2->features.vsize;
1326                  }
1327                  else if (DTSelect == DT1)  {
1328                      MonInfo->features.hsize = MonInfo1->features.hsize;
1329                      MonInfo->features.vsize = MonInfo1->features.vsize;
1330                  }
1331                  else	/* Skip DT */
1332                  {   /* use 1024x768 as default */
1333                      MonInfo->features.hsize = 0x20;
1334                      MonInfo->features.vsize = 0x18;
1335                  }
1336
1337              } /* Check with VGA1 & VGA2 EDID */
1338
1339          } /* GetVGA2EDID */
1340          else {
1341              xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Can't Get VGA2 EDID Correctly!! \n");
1342          }
1343
1344      }
1345
1346      xf86PrintEDID(MonInfo);
1347      xf86SetDDCproperties(pScrn, MonInfo);
1348      vbeFree(pVbe);
1349   } else {
1350      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1351		 "this driver cannot do DDC without VBE\n");
1352   }
1353
1354   return MonInfo;
1355}
1356
1357static void
1358vFillASTModeInfo (ScrnInfoPtr pScrn)
1359{
1360    ASTRecPtr pAST;
1361
1362    pAST = ASTPTR(pScrn);
1363
1364    pAST->VideoModeInfo.ScreenWidth = pScrn->virtualX;
1365    pAST->VideoModeInfo.ScreenHeight = pScrn->virtualY;
1366    pAST->VideoModeInfo.bitsPerPixel = pScrn->bitsPerPixel;
1367    /* Fixed screen pitch incorrect in some specific monitor, ycchen@071707 */
1368    pAST->VideoModeInfo.ScreenPitch = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8) ;
1369
1370}
1371
1372static Bool
1373ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
1374{
1375    vgaHWPtr hwp;
1376    ASTRecPtr pAST;
1377
1378    hwp = VGAHWPTR(pScrn);
1379    pAST = ASTPTR(pScrn);
1380
1381    vgaHWUnlock(hwp);
1382
1383    if (!vgaHWInit(pScrn, mode))
1384      return FALSE;
1385
1386    pScrn->vtSema = TRUE;
1387    pAST->ModePtr = mode;
1388
1389    if (!ASTSetMode(pScrn, mode))
1390      return FALSE;
1391
1392    vgaHWProtect(pScrn, FALSE);
1393
1394    return TRUE;
1395}
1396