ast_driver.c revision a0e1ef58
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 "vgaHW.h"
35#include "mipointer.h"
36#include "micmap.h"
37
38#include "fb.h"
39#include "regionstr.h"
40#include "xf86xv.h"
41#include <X11/extensions/Xv.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#ifdef HAVE_XAA_H
51#include "xaa.h"
52#include "xaarop.h"
53#endif
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 GetScratchOptions(ScrnInfoPtr pScrn);
74extern void vASTLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual);
75extern void ASTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
76extern void vSetStartAddressCRT1(ASTRecPtr pAST, ULONG base);
77extern Bool ASTSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode);
78extern Bool GetVGA2EDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer);
79extern void vInitDRAMReg(ScrnInfoPtr pScrn);
80extern Bool bIsVGAEnabled(ScrnInfoPtr pScrn);
81extern void ASTBlankScreen(ScrnInfoPtr pScreen, Bool unblack);
82extern Bool InitVGA(ScrnInfoPtr pScrn, ULONG Flags);
83extern Bool GetVGAEDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer);
84extern Bool bInitAST1180(ScrnInfoPtr pScrn);
85extern void GetAST1180DRAMInfo(ScrnInfoPtr pScrn);
86extern void vEnableASTVGAMMIO(ScrnInfoPtr pScrn);
87
88extern Bool bInitCMDQInfo(ScrnInfoPtr pScrn, ASTRecPtr pAST);
89extern Bool bEnableCMDQ(ScrnInfoPtr pScrn, ASTRecPtr pAST);
90extern void vDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST);
91
92#ifdef HAVE_XAA_H
93extern Bool ASTAccelInit(ScreenPtr pScreen);
94#endif
95
96extern Bool ASTCursorInit(ScreenPtr pScreen);
97extern void ASTDisableHWC(ScrnInfoPtr pScrn);
98
99/* Mandatory functions */
100static void ASTIdentify(int flags);
101const OptionInfoRec *ASTAvailableOptions(int chipid, int busid);
102static Bool ASTProbe(DriverPtr drv, int flags);
103static Bool ASTPreInit(ScrnInfoPtr pScrn, int flags);
104static Bool ASTScreenInit(SCREEN_INIT_ARGS_DECL);
105Bool ASTSwitchMode(SWITCH_MODE_ARGS_DECL);
106void ASTAdjustFrame(ADJUST_FRAME_ARGS_DECL);
107static Bool ASTEnterVT(VT_FUNC_ARGS_DECL);
108static void ASTLeaveVT(VT_FUNC_ARGS_DECL);
109static void ASTFreeScreen(FREE_SCREEN_ARGS_DECL);
110static ModeStatus ASTValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags);
111
112/* Internally used functions */
113static Bool ASTGetRec(ScrnInfoPtr pScrn);
114static void ASTFreeRec(ScrnInfoPtr pScrn);
115static Bool ASTSaveScreen(ScreenPtr pScreen, Bool unblack);
116static Bool ASTCloseScreen(CLOSE_SCREEN_ARGS_DECL);
117static void ASTSave(ScrnInfoPtr pScrn);
118static void ASTRestore(ScrnInfoPtr pScrn);
119static void ASTProbeDDC(ScrnInfoPtr pScrn, int index);
120static xf86MonPtr ASTDoDDC(ScrnInfoPtr pScrn, int index);
121static void vFillASTModeInfo (ScrnInfoPtr pScrn);
122static Bool ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
123
124#ifdef AstVideo
125/* video function */
126static void ASTInitVideo(ScreenPtr pScreen);
127static int  ASTPutImage( ScrnInfoPtr,
128        short, short, short, short, short, short, short, short,
129        int, unsigned char*, short, short, Bool, RegionPtr, pointer,
130	DrawablePtr);
131#endif
132
133/*
134 * This is intentionally screen-independent.  It indicates the binding
135 * choice made in the first PreInit.
136 */
137_X_EXPORT DriverRec AST = {
138   AST_VERSION,
139   AST_DRIVER_NAME,
140   ASTIdentify,
141   ASTProbe,
142   ASTAvailableOptions,
143   NULL,
144   0
145};
146
147/* Chipsets */
148static SymTabRec ASTChipsets[] = {
149   {PCI_CHIP_AST2000,	"ASPEED Graphics Family"},
150   {PCI_CHIP_AST2100,	"ASPEED Graphics Family"},
151   {PCI_CHIP_AST1180,	"ASPEED AST1180 Graphics"},
152   {-1,			NULL}
153};
154
155static PciChipsets ASTPciChipsets[] = {
156   {PCI_CHIP_AST2000,		PCI_CHIP_AST2000,	RES_SHARED_VGA},
157   {PCI_CHIP_AST2100,		PCI_CHIP_AST2100,	RES_SHARED_VGA},
158   {PCI_CHIP_AST1180,		PCI_CHIP_AST1180,	RES_SHARED_VGA},
159   {-1,				-1, 			RES_UNDEFINED }
160};
161
162typedef enum {
163   OPTION_NOACCEL,
164   OPTION_MMIO2D,
165   OPTION_SW_CURSOR,
166   OPTION_HWC_NUM,
167   OPTION_ENG_CAPS,
168   OPTION_DBG_SELECT,
169   OPTION_NO_DDC,
170   OPTION_VGA2_CLONE,
171   OPTION_SHADOW_FB
172} ASTOpts;
173
174static const OptionInfoRec ASTOptions[] = {
175   {OPTION_NOACCEL,	      "NoAccel",	OPTV_BOOLEAN,	{0},	FALSE},
176   {OPTION_MMIO2D,	       "MMIO2D",	OPTV_BOOLEAN,	{0},	FALSE},
177   {OPTION_SW_CURSOR,	 "SWCursor",	OPTV_BOOLEAN,	{0},	FALSE},
178   {OPTION_HWC_NUM,	    "HWCNumber",	OPTV_INTEGER,	{0},	FALSE},
179   {OPTION_ENG_CAPS,	  "ENGCaps",	OPTV_INTEGER,	{0},	FALSE},
180   {OPTION_DBG_SELECT,	"DBGSelect",	OPTV_INTEGER,	{0},	FALSE},
181   {OPTION_NO_DDC,	        "NoDDC",	OPTV_BOOLEAN,	{0}, 	FALSE},
182   {OPTION_VGA2_CLONE,	"VGA2Clone",	OPTV_BOOLEAN,	{0}, 	FALSE},
183   {OPTION_SHADOW_FB,    "ShadowFB",	OPTV_BOOLEAN,	{0},	FALSE},
184   {-1,			               NULL,	   OPTV_NONE,	{0}, 	FALSE}
185};
186
187#ifdef XFree86LOADER
188
189static MODULESETUPPROTO(astSetup);
190
191static XF86ModuleVersionInfo astVersRec = {
192   AST_DRIVER_NAME,
193   MODULEVENDORSTRING,
194   MODINFOSTRING1,
195   MODINFOSTRING2,
196   XORG_VERSION_CURRENT,
197   AST_MAJOR_VERSION, AST_MINOR_VERSION, AST_PATCH_VERSION,
198   ABI_CLASS_VIDEODRV,
199#ifdef PATCH_ABI_VERSION
200   ABI_VIDEODRV_VERSION_PATCH,
201#else
202   ABI_VIDEODRV_VERSION,
203#endif
204   MOD_CLASS_VIDEODRV,
205   {0, 0, 0, 0}
206};
207
208_X_EXPORT XF86ModuleData astModuleData = { &astVersRec, astSetup, NULL };
209
210static pointer
211astSetup(pointer module, pointer opts, int *errmaj, int *errmin)
212{
213   static Bool setupDone = FALSE;
214
215   /* This module should be loaded only once, but check to be sure.
216    */
217   if (!setupDone) {
218      setupDone = TRUE;
219      xf86AddDriver(&AST, module, 0);
220
221      /*
222       * The return value must be non-NULL on success even though there
223       * is no TearDownProc.
224       */
225      return (pointer) TRUE;
226   } else {
227      if (errmaj)
228	 *errmaj = LDR_ONCEONLY;
229      return NULL;
230   }
231}
232
233#endif	/* XFree86LOADER */
234
235/*
236 * ASTIdentify --
237 *
238 * Returns the string name for the driver based on the chipset. In this
239 * case it will always be an AST, so we can return a static string.
240 *
241 */
242static void
243ASTIdentify(int flags)
244{
245   xf86PrintChipsets(AST_NAME, "Driver for ASPEED Graphics Chipsets",
246		     ASTChipsets);
247}
248
249const OptionInfoRec *
250ASTAvailableOptions(int chipid, int busid)
251{
252
253   return ASTOptions;
254
255}
256
257/*
258 * ASTProbe --
259 *
260 * Look through the PCI bus to find cards that are AST boards.
261 * Setup the dispatch table for the rest of the driver functions.
262 *
263 */
264static Bool
265ASTProbe(DriverPtr drv, int flags)
266{
267    int i, numUsed, numDevSections, *usedChips;
268    Bool foundScreen = FALSE;
269    GDevPtr *devSections;
270
271   /*
272    * Find the config file Device sections that match this
273    * driver, and return if there are none.
274    */
275    if ((numDevSections =
276	xf86MatchDevice(AST_DRIVER_NAME, &devSections)) <= 0) {
277      return FALSE;
278    }
279
280#ifndef XSERVER_LIBPCIACCESS
281   /*
282    * This probing is just checking the PCI data the server already
283    * collected.
284    */
285    if (xf86GetPciVideoInfo() == NULL) {
286	return FALSE;
287    }
288#endif
289
290    numUsed = xf86MatchPciInstances(AST_NAME, PCI_VENDOR_AST,
291				   ASTChipsets, ASTPciChipsets,
292				   devSections, numDevSections,
293				   drv, &usedChips);
294
295    free(devSections);
296
297    if (flags & PROBE_DETECT) {
298        if (numUsed > 0)
299	    foundScreen = TRUE;
300    } else {
301        for (i = 0; i < numUsed; i++) {
302	    ScrnInfoPtr pScrn = NULL;
303
304#ifdef XSERVER_LIBPCIACCESS
305            {
306                struct pci_device *pPci = xf86GetPciInfoForEntity(usedChips[i]);
307
308                if (pci_device_has_kernel_driver(pPci)) {
309                    xf86DrvMsg(0, X_ERROR,
310                               "ast: The PCI device 0x%x at %2.2d@%2.2d:%2.2d:%1.1d has a kernel module claiming it.\n",
311                               pPci->device_id, pPci->bus, pPci->domain, pPci->dev, pPci->func);
312                    xf86DrvMsg(0, X_ERROR,
313                               "cirrus: This driver cannot operate until it has been unloaded.\n");
314                    return FALSE;
315                }
316            }
317#endif
318
319	    /* Allocate new ScrnInfoRec and claim the slot */
320	    if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
321					     ASTPciChipsets, 0, 0, 0, 0, 0)))
322            {
323	        EntityInfoPtr pEnt;
324
325	        pEnt = xf86GetEntityInfo(usedChips[i]);
326
327	        pScrn->driverVersion = AST_VERSION;
328	        pScrn->driverName = AST_DRIVER_NAME;
329	        pScrn->name = AST_NAME;
330
331	        pScrn->Probe = ASTProbe;
332	        pScrn->PreInit = ASTPreInit;
333	        pScrn->ScreenInit = ASTScreenInit;
334	        pScrn->SwitchMode = ASTSwitchMode;
335	        pScrn->AdjustFrame = ASTAdjustFrame;
336	        pScrn->EnterVT = ASTEnterVT;
337	        pScrn->LeaveVT = ASTLeaveVT;
338	        pScrn->FreeScreen = ASTFreeScreen;
339	        pScrn->ValidMode = ASTValidMode;
340
341	        foundScreen = TRUE;
342
343	    } /* end of if */
344        }  /* end of for-loop */
345    } /* end of if flags */
346
347    free(usedChips);
348
349    return foundScreen;
350}
351
352#ifdef	Support_ShadowFB
353static void *
354ASTWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode,
355		        CARD32 *size, void *closure)
356{
357    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
358    ASTPtr pAST = ASTPTR(pScrn);
359    int stride = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8);
360
361    *size =  stride;
362    return ((uint8_t *)pAST->FBVirtualAddr + pScrn->fbOffset + row * stride + offset);
363
364}
365
366static void
367ASTUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
368{
369    shadowUpdatePacked(pScreen, pBuf);
370}
371
372static Bool
373ASTCreateScreenResources(ScreenPtr pScreen)
374{
375    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
376    ASTPtr pAST = ASTPTR(pScrn);
377    Bool ret;
378
379    pScreen->CreateScreenResources = pAST->CreateScreenResources;
380    ret = pScreen->CreateScreenResources(pScreen);
381    pScreen->CreateScreenResources = ASTCreateScreenResources;
382    shadowAdd(pScreen, pScreen->GetScreenPixmap(pScreen), pAST->update,
383	          pAST->window, 0, 0);
384
385    return ret;
386}
387#endif	/* Support_ShadowFB */
388
389/*
390 * ASTPreInit --
391 *
392 * Do initial setup of the board before we know what resolution we will
393 * be running at.
394 *
395 */
396static Bool
397ASTPreInit(ScrnInfoPtr pScrn, int flags)
398{
399   EntityInfoPtr pEnt;
400   int flags24;
401   rgb defaultWeight = { 0, 0, 0 };
402#if	!(defined(__sparc__)) && !(defined(__mips__))
403   vgaHWPtr hwp;
404#endif
405
406   ASTRecPtr pAST;
407
408   ClockRangePtr clockRanges;
409   int i;
410   MessageType from;
411   int maxPitch, maxHeight;
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#ifndef XSERVER_LIBPCIACCESS
428   if (xf86RegisterResources(pEnt->index, 0, ResExclusive))
429       return FALSE;
430#endif
431
432#if	!(defined(__sparc__)) && !(defined(__mips__))
433   /* The vgahw module should be loaded here when needed */
434   if (!xf86LoadSubModule(pScrn, "vgahw"))
435      return FALSE;
436#endif
437
438   /* The fb module should be loaded here when needed */
439   if (!xf86LoadSubModule(pScrn, "fb"))
440      return FALSE;
441
442#if	!(defined(__sparc__)) && !(defined(__mips__))
443   /* Allocate a vgaHWRec */
444   if (!vgaHWGetHWRec(pScrn))
445       return FALSE;
446   hwp = VGAHWPTR(pScrn);
447   vgaHWSetStdFuncs(hwp);
448#endif
449
450   /* Color Depth Check */
451   flags24 = Support32bppFb;
452   if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) {
453      return FALSE;
454   } else {
455      switch (pScrn->depth) {
456      case 8:
457      case 16:
458      case 24:
459	 break;
460      default:
461	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
462		    "Given depth (%d) is not supported by ast driver\n",
463		    pScrn->depth);
464	 return FALSE;
465      }
466   }
467   xf86PrintDepthBpp(pScrn);
468
469   switch (pScrn->bitsPerPixel) {
470   case 8:
471   case 16:
472   case 32:
473      break;
474   default:
475      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
476		 "Given bpp (%d) is not supported by ast driver\n",
477		 pScrn->bitsPerPixel);
478      return FALSE;
479   }
480
481   /* fill pScrn misc. */
482   pScrn->progClock = TRUE;
483   pScrn->rgbBits = 6;
484   pScrn->monitor = pScrn->confScreen->monitor; /* should be initialized before set gamma */
485#ifndef XSERVER_LIBPCIACCESS
486   pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
487   pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
488#endif
489
490   /*
491    * If the driver can do gamma correction, it should call xf86SetGamma()
492    * here.
493    */
494   {
495      Gamma zeros = { 0.0, 0.0, 0.0 };
496
497      if (!xf86SetGamma(pScrn, zeros)) {
498         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "call xf86SetGamma failed \n");
499	 return FALSE;
500      }
501   }
502
503
504   if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) {
505       return FALSE;
506   }
507
508   if (!xf86SetDefaultVisual(pScrn, -1)) {
509       return FALSE;
510   }
511
512   /* Allocate driverPrivate */
513   if (!ASTGetRec(pScrn)) {
514       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "call ASTGetRec failed \n");
515       return FALSE;
516   }
517
518   /* Fill AST Info */
519   pAST = ASTPTR(pScrn);
520   pAST->pEnt    = xf86GetEntityInfo(pScrn->entityList[0]);
521   pAST->PciInfo = xf86GetPciInfoForEntity(pAST->pEnt->index);
522#ifndef XSERVER_LIBPCIACCESS
523   pAST->PciTag  = pciTag(pAST->PciInfo->bus, pAST->PciInfo->device,
524			  pAST->PciInfo->func);
525#endif
526
527   /* Process the options
528    * pScrn->confScreen, pScrn->display, pScrn->monitor, pScrn->numEntities,
529    * and pScrn->entityList should be initialized before
530    */
531   xf86CollectOptions(pScrn, NULL);
532   if (!(pAST->Options = malloc(sizeof(ASTOptions))))
533   {
534      ASTFreeRec(pScrn);
535      return FALSE;
536   }
537   memcpy(pAST->Options, ASTOptions, sizeof(ASTOptions));
538   xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pAST->Options);
539
540   /*
541    * Set the Chipset and ChipRev, allowing config file entries to
542    * override.
543    */
544   if (pAST->pEnt->device->chipset && *pAST->pEnt->device->chipset) {
545      pScrn->chipset = pAST->pEnt->device->chipset;
546      from = X_CONFIG;
547   } else if (pAST->pEnt->device->chipID >= 0) {
548      pScrn->chipset = (char *)xf86TokenToString(ASTChipsets,
549						 pAST->pEnt->device->chipID);
550      from = X_CONFIG;
551      xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
552		 pAST->pEnt->device->chipID);
553   } else {
554      from = X_PROBED;
555      pScrn->chipset = (char *)xf86TokenToString(ASTChipsets,
556						 PCI_DEV_DEVICE_ID(pAST->PciInfo));
557   }
558   if (pAST->pEnt->device->chipRev >= 0) {
559      xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
560		 pAST->pEnt->device->chipRev);
561   }
562
563   xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n",
564	      (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown ast");
565
566   /* Resource Allocation */
567#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
568    pAST->IODBase = pScrn->domainIOBase;
569#else
570    pAST->IODBase = 0;
571#endif
572    /* "Patch" the PIOOffset inside vgaHW in order to force
573     * the vgaHW module to use our relocated i/o ports.
574     */
575
576#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
577    VGAHWPTR(pScrn)->PIOOffset = /* ... */
578#endif
579       	pAST->PIOOffset =
580	pAST->IODBase + PCI_REGION_BASE(pAST->PciInfo, 2, REGION_IO) - 0x380;
581
582    pAST->RelocateIO = (IOADDRESS)(PCI_REGION_BASE(pAST->PciInfo, 2, REGION_IO) + pAST->IODBase);
583
584   if (pAST->pEnt->device->MemBase != 0) {
585      pAST->FBPhysAddr = pAST->pEnt->device->MemBase;
586      from = X_CONFIG;
587   } else {
588      if (PCI_REGION_BASE(pAST->PciInfo, 0, REGION_MEM) != 0) {
589	 pAST->FBPhysAddr = PCI_REGION_BASE(pAST->PciInfo, 0, REGION_MEM) & 0xFFF00000;
590	 from = X_PROBED;
591      } else {
592	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
593		    "No valid FB address in PCI config space\n");
594	 ASTFreeRec(pScrn);
595	 return FALSE;
596      }
597   }
598   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Linear framebuffer at 0x%lX\n",
599	      (unsigned long) pAST->FBPhysAddr);
600
601   if (pAST->pEnt->device->IOBase != 0) {
602      pAST->MMIOPhysAddr = pAST->pEnt->device->IOBase;
603      from = X_CONFIG;
604   } else {
605      if (PCI_REGION_BASE(pAST->PciInfo, 1, REGION_MEM)) {
606	 pAST->MMIOPhysAddr = PCI_REGION_BASE(pAST->PciInfo, 1, REGION_MEM) & 0xFFFF0000;
607	 from = X_PROBED;
608      } else {
609	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
610		    "No valid MMIO address in PCI config space\n");
611	 ASTFreeRec(pScrn);
612	 return FALSE;
613      }
614   }
615   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "IO registers at addr 0x%lX\n",
616	      (unsigned long) pAST->MMIOPhysAddr);
617
618   /* Map MMIO */
619   pAST->MMIOMapSize = DEFAULT_MMIO_SIZE;
620   if (!ASTMapMMIO(pScrn)) {
621      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map Memory Map IO Failed \n");
622      return FALSE;
623   }
624
625   if (PCI_DEV_DEVICE_ID(pAST->PciInfo) == PCI_CHIP_AST1180)
626   {
627       pAST->jChipType = AST1180;
628
629       /* validate mode */
630       if ( (pScrn->bitsPerPixel == 8) || (pScrn->depth == 8) )
631       {
632           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
633		      "Given bpp (%d) is not supported by ast driver\n",
634		      pScrn->bitsPerPixel);
635           return FALSE;
636       }
637
638       /* Init AST1180 */
639       bInitAST1180(pScrn);
640
641       /* Get AST1180 Information */
642       GetAST1180DRAMInfo(pScrn);
643       pScrn->videoRam = pAST->ulVRAMSize / 1024;
644
645   }
646   else
647   {
648       /* Enable VGA MMIO Access */
649       vEnableASTVGAMMIO(pScrn);
650
651       /* Init VGA Adapter */
652       if (!xf86IsPrimaryPci(pAST->PciInfo))
653       {
654           InitVGA(pScrn, 0);
655       }
656
657       vASTOpenKey(pScrn);
658       bASTRegInit(pScrn);
659
660       /* Get Chip Type */
661       if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x20)
662           pAST->jChipType = AST2300;
663       else if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x10)
664           GetChipType(pScrn);
665       else
666           pAST->jChipType = AST2000;
667
668       /* Get Options from Scratch */
669       GetScratchOptions(pScrn);
670
671       /* Get DRAM Info */
672       GetDRAMInfo(pScrn);
673       pAST->ulVRAMSize = GetVRAMInfo(pScrn);
674       pScrn->videoRam  = pAST->ulVRAMSize / 1024;
675   }
676
677   /* Map Framebuffer */
678   from = X_DEFAULT;
679   if (pAST->pEnt->device->videoRam) {
680      pScrn->videoRam = pAST->pEnt->device->videoRam;
681      from = X_CONFIG;
682   }
683
684   pAST->FbMapSize = pScrn->videoRam * 1024;
685
686#if 0
687   if (!ASTMapMem(pScrn)) {
688      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n");
689      return FALSE;
690   }
691#endif
692
693   pScrn->memPhysBase = (ULONG)pAST->FBPhysAddr;
694   pScrn->fbOffset = 0;
695
696   /* Do DDC
697    * should be done after xf86CollectOptions
698    */
699   pScrn->monitor->DDC = ASTDoDDC(pScrn, pAST->pEnt->index);
700
701   /* Mode Valid */
702   clockRanges = xnfcalloc(sizeof(ClockRange), 1);
703   clockRanges->next = NULL;
704   clockRanges->minClock = 9500;
705   clockRanges->maxClock = GetMaxDCLK(pScrn) * 1000;
706   clockRanges->clockIndex = -1;
707   clockRanges->interlaceAllowed = FALSE;
708   clockRanges->doubleScanAllowed = FALSE;
709
710   /* Add for AST2100, ycchen@061807 */
711   if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST1180))
712   {
713       maxPitch  = 1920;
714       maxHeight = 1200;
715   }
716   else
717   {
718       maxPitch  = 1600;
719       maxHeight = 1200;
720   }
721
722   i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
723			 pScrn->display->modes, clockRanges,
724			 0, 320, maxPitch, 8 * pScrn->bitsPerPixel,
725			 200, maxHeight,
726			 pScrn->display->virtualX, pScrn->display->virtualY,
727			 pAST->FbMapSize, LOOKUP_BEST_REFRESH);
728
729   /* fixed some monitors can't get propery validate modes using estimated ratio modes */
730   if (i < 2)		/* validate modes are too few */
731   {
732       i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
733			     pScrn->display->modes, clockRanges,
734			     0, 320, maxPitch, 8 * pScrn->bitsPerPixel,
735			     200, maxHeight,
736			     pAST->mon_h_active, pAST->mon_v_active,
737			     pAST->FbMapSize, LOOKUP_BEST_REFRESH);
738   }
739
740   if (i == -1) {
741      ASTFreeRec(pScrn);
742      return FALSE;
743   }
744
745   xf86PruneDriverModes(pScrn);
746
747   if (!i || !pScrn->modes) {
748      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
749      ASTFreeRec(pScrn);
750      return FALSE;
751   }
752
753   xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
754
755   pScrn->currentMode = pScrn->modes;
756
757   xf86PrintModes(pScrn);
758
759   xf86SetDpi(pScrn, 0, 0);
760
761   /* Accelaration Check */
762   pAST->noAccel = TRUE;
763   pAST->pCMDQPtr = NULL;
764   pAST->CMDQInfo.ulCMDQSize 		= 0;
765   pAST->CMDQInfo.pjCmdQBasePort    = pAST->MMIOVirtualAddr+ 0x8044;
766   pAST->CMDQInfo.pjWritePort       = pAST->MMIOVirtualAddr+ 0x8048;
767   pAST->CMDQInfo.pjReadPort        = pAST->MMIOVirtualAddr+ 0x804C;
768   pAST->CMDQInfo.pjEngStatePort    = pAST->MMIOVirtualAddr+ 0x804C;
769#ifdef HAVE_XAA_H
770   pAST->AccelInfoPtr = NULL;
771#ifdef	Accel_2D
772   if (!xf86ReturnOptValBool(pAST->Options, OPTION_NOACCEL, FALSE))
773   {
774       if (xf86LoadSubModule(pScrn, "xaa")) {
775
776           pAST->noAccel = FALSE;
777           pAST->MMIO2D  = TRUE;
778#ifndef	MMIO_2D
779           if (!xf86ReturnOptValBool(pAST->Options, OPTION_MMIO2D, FALSE)) {
780	       pAST->CMDQInfo.ulCMDQSize = DEFAULT_CMDQ_SIZE;
781	       pAST->MMIO2D = FALSE;
782           }
783#endif
784
785           pAST->ENGCaps = ENG_CAP_ALL;
786           if (!xf86GetOptValInteger(pAST->Options, OPTION_ENG_CAPS, &pAST->ENGCaps)) {
787	       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No ENG Capability options found\n");
788           }
789
790           pAST->DBGSelect = 0;
791           if (!xf86GetOptValInteger(pAST->Options, OPTION_DBG_SELECT, &pAST->DBGSelect)) {
792	       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No DBG Seleclt options found\n");
793           }
794       }
795   }
796#endif
797#endif /* HAVE_XAA_H */
798
799   /* HW Cursor Check */
800   pAST->noHWC = TRUE;
801   pAST->HWCInfoPtr = NULL;
802   pAST->pHWCPtr = NULL;
803#ifdef	HWC
804   if (!xf86ReturnOptValBool(pAST->Options, OPTION_SW_CURSOR, FALSE)) {
805      if (!xf86LoadSubModule(pScrn, "ramdac")) {
806	 ASTFreeRec(pScrn);
807	 return FALSE;
808      }
809
810      pAST->noHWC = FALSE;
811      pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM;
812      if (!xf86GetOptValInteger(pAST->Options, OPTION_HWC_NUM, &pAST->HWCInfo.HWC_NUM)) {
813          xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No HWC_NUM options found\n");
814      }
815
816   }
817#endif
818
819   /* ShadowFB */
820#ifdef	Support_ShadowFB
821   pAST->shadowFB = FALSE;
822   if (pAST->noAccel == TRUE)	/* enable shadowFB only noAccel */
823   {
824       if (xf86ReturnOptValBool(pAST->Options, OPTION_SHADOW_FB, TRUE))
825       {
826	       if (xf86LoadSubModule(pScrn, "shadow")) {
827	          xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using \"Shadow Framebuffer\"\n");
828	          pAST->shadowFB = TRUE;
829	       }
830       }
831   }
832#endif
833
834#ifndef XSERVER_LIBPCIACCESS
835   /*  We won't be using the VGA access after the probe */
836   xf86SetOperatingState(resVgaIo, pAST->pEnt->index, ResUnusedOpr);
837   xf86SetOperatingState(resVgaMem, pAST->pEnt->index, ResDisableOpr);
838#endif
839
840   return TRUE;
841}
842
843
844static Bool
845ASTScreenInit(SCREEN_INIT_ARGS_DECL)
846{
847   ScrnInfoPtr pScrn;
848   ASTRecPtr pAST;
849   VisualPtr visual;
850   /* for FB Manager */
851   BoxRec FBMemBox;
852   int    AvailFBSize;
853
854   pScrn = xf86ScreenToScrn(pScreen);
855   pAST = ASTPTR(pScrn);
856
857   if (!ASTMapMem(pScrn)) {
858      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n");
859      return FALSE;
860   }
861
862/*   if (!pAST->noAccel) */
863   {
864       /* AvailFBSize = pAST->FbMapSize - pAST->CMDQInfo.ulCMDQSize; */
865       AvailFBSize = pAST->FbMapSize;
866
867       FBMemBox.x1 = 0;
868       FBMemBox.y1 = 0;
869       FBMemBox.x2 = pScrn->displayWidth;
870       FBMemBox.y2 = (AvailFBSize / (pScrn->displayWidth * ((pScrn->bitsPerPixel+1)/8))) - 1;
871
872       if (FBMemBox.y2 < 0)
873           FBMemBox.y2 = 32767;
874       if (FBMemBox.y2 < pScrn->virtualY)
875           return FALSE;
876
877       if (!xf86InitFBManager(pScreen, &FBMemBox)) {
878          xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n");
879          return FALSE;
880       }
881
882   }
883
884#if	!(defined(__sparc__)) && !(defined(__mips__))
885   vgaHWPtr hwp;
886   hwp = VGAHWPTR(pScrn);
887   vgaHWSetMmioFuncs(hwp, pAST->MMIOVirtualAddr, 0);
888#endif
889
890   vFillASTModeInfo (pScrn);
891
892   ASTSave(pScrn);
893   if (!ASTModeInit(pScrn, pScrn->currentMode)) {
894      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Mode Init Failed \n");
895      return FALSE;
896   }
897
898   ASTSaveScreen(pScreen, FALSE);
899   ASTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
900
901   miClearVisualTypes();
902
903   /* Re-implemented Direct Color support, -jens */
904   if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
905			 pScrn->rgbBits, pScrn->defaultVisual))
906      return FALSE;
907
908   if (!miSetPixmapDepths())
909   {
910       ASTSaveScreen(pScreen, SCREEN_SAVER_OFF);
911       return FALSE;
912   }
913
914   /* allocate shadowFB */
915#ifdef	Support_ShadowFB
916   pAST->shadowFB_validation = FALSE;
917   if (pAST->shadowFB) {
918      pAST->shadow = calloc(1, pScrn->displayWidth * pScrn->virtualY *
919				     ((pScrn->bitsPerPixel + 7) / 8));
920	  if (!pAST->shadow) {
921	     xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate shadow buffer\n");
922	  }
923	  else
924	     pAST->shadowFB_validation = TRUE;
925   }
926#endif
927
928   switch(pScrn->bitsPerPixel) {
929       case 8:
930       case 16:
931       case 32:
932#ifdef	Support_ShadowFB
933           if (!fbScreenInit(pScreen, pAST->shadowFB_validation ? pAST->shadow : (pAST->FBVirtualAddr + pScrn->fbOffset),
934  	                         pScrn->virtualX, pScrn->virtualY,
935		                     pScrn->xDpi, pScrn->yDpi,
936		                     pScrn->displayWidth, pScrn->bitsPerPixel))
937#else
938	       if (!fbScreenInit(pScreen, pAST->FBVirtualAddr + pScrn->fbOffset,
939			                 pScrn->virtualX, pScrn->virtualY,
940			                 pScrn->xDpi, pScrn->yDpi,
941			                 pScrn->displayWidth, pScrn->bitsPerPixel))
942#endif
943               return FALSE;
944           break;
945       default:
946           return FALSE;
947
948   }
949
950   if (pScrn->bitsPerPixel > 8) {
951      /* Fixup RGB ordering */
952      visual = pScreen->visuals + pScreen->numVisuals;
953      while (--visual >= pScreen->visuals) {
954	 if ((visual->class | DynamicClass) == DirectColor) {
955	    visual->offsetRed = pScrn->offset.red;
956	    visual->offsetGreen = pScrn->offset.green;
957	    visual->offsetBlue = pScrn->offset.blue;
958	    visual->redMask = pScrn->mask.red;
959	    visual->greenMask = pScrn->mask.green;
960	    visual->blueMask = pScrn->mask.blue;
961	 }
962      }
963   }
964
965   /* Must be after RGB order fixed */
966   fbPictureInit(pScreen, 0, 0);
967
968   /* shadowFB setup */
969#ifdef	Support_ShadowFB
970   if (pAST->shadowFB_validation) {
971      pAST->update = ASTUpdatePacked;
972	  pAST->window = ASTWindowLinear;
973
974      if (!shadowSetup(pScreen))
975      {
976	     xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to setup shadow buffer\n");
977	     return FALSE;
978      }
979
980	  pAST->CreateScreenResources = pScreen->CreateScreenResources;
981	  pScreen->CreateScreenResources = ASTCreateScreenResources;
982   }
983#endif
984
985   xf86SetBlackWhitePixels(pScreen);
986
987#ifdef HAVE_XAA_H
988#ifdef Accel_2D
989   if (!pAST->noAccel)
990   {
991       if (!ASTAccelInit(pScreen)) {
992           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware acceleration initialization failed\n");
993           pAST->noAccel = TRUE;
994       }
995   }
996#endif /* end of Accel_2D */
997#endif
998
999   xf86SetBackingStore(pScreen);
1000   xf86SetSilkenMouse(pScreen);
1001
1002   miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
1003
1004   if (!pAST->noHWC)
1005   {
1006       if (!ASTCursorInit(pScreen)) {
1007           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware cursor initialization failed\n");
1008           pAST->noHWC = TRUE;
1009       }
1010   }
1011
1012   if (!miCreateDefColormap(pScreen))
1013      return FALSE;
1014
1015   if (pAST->jChipType != AST1180)
1016   {
1017       if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits,
1018                               vASTLoadPalette, NULL,
1019                               CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) {
1020           return FALSE;
1021       }
1022   }
1023
1024   xf86DPMSInit(pScreen, ASTDisplayPowerManagementSet, 0);
1025
1026#ifdef AstVideo
1027   if ( (pAST->jChipType == AST1180) || (pAST->jChipType == AST2300) )
1028   {
1029       xf86DrvMsg(pScrn->scrnIndex, X_INFO,"AST Initial Video()\n");
1030       ASTInitVideo(pScreen);
1031   }
1032#endif
1033
1034   pScreen->SaveScreen = ASTSaveScreen;
1035   pAST->CloseScreen = pScreen->CloseScreen;
1036   pScreen->CloseScreen = ASTCloseScreen;
1037
1038   if (serverGeneration == 1)
1039      xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
1040
1041   return TRUE;
1042
1043} /* ASTScreenInit */
1044
1045
1046Bool
1047ASTSwitchMode(SWITCH_MODE_ARGS_DECL)
1048{
1049   SCRN_INFO_PTR(arg);
1050   ASTRecPtr pAST = ASTPTR(pScrn);
1051
1052   /* VideoMode validate */
1053   if (mode->CrtcHDisplay > pScrn->displayWidth)
1054       return FALSE;
1055   if ((pAST->VideoModeInfo.ScreenPitch * mode->CrtcVDisplay) > pAST->ulVRAMSize)
1056       return FALSE;
1057
1058   /* VideModeInfo Update */
1059   pAST->VideoModeInfo.ScreenWidth  = mode->CrtcHDisplay;
1060   pAST->VideoModeInfo.ScreenHeight = mode->CrtcVDisplay;
1061   pAST->VideoModeInfo.ScreenPitch  = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8) ;
1062
1063#ifdef	HWC
1064   if (pAST->pHWCPtr) {
1065       xf86FreeOffscreenLinear(pAST->pHWCPtr);		/* free HWC Cache */
1066       pAST->pHWCPtr = NULL;
1067   }
1068   ASTDisableHWC(pScrn);
1069#endif
1070
1071#ifdef Accel_2D
1072   if (pAST->pCMDQPtr) {
1073       xf86FreeOffscreenLinear(pAST->pCMDQPtr);		/* free CMDQ */
1074       pAST->pCMDQPtr = NULL;
1075   }
1076   vDisable2D(pScrn, pAST);
1077#endif
1078
1079   /* Fixed display abnormal on the of the screen if run xvidtune, ycchen@122909 */
1080   /* ASTRestore(pScrn); */
1081
1082   return ASTModeInit(pScrn, mode);
1083
1084}
1085
1086void
1087ASTAdjustFrame(ADJUST_FRAME_ARGS_DECL)
1088{
1089   SCRN_INFO_PTR(arg);
1090   ASTRecPtr   pAST  = ASTPTR(pScrn);
1091   ULONG base;
1092
1093   base = y * pAST->VideoModeInfo.ScreenPitch + x * ((pAST->VideoModeInfo.bitsPerPixel + 1) / 8);
1094   /* base = base >> 2; */			/* DW unit */
1095
1096   vSetStartAddressCRT1(pAST, base);
1097
1098}
1099
1100/* enter into X Server */
1101static Bool
1102ASTEnterVT(VT_FUNC_ARGS_DECL)
1103{
1104   SCRN_INFO_PTR(arg);
1105   ASTRecPtr pAST = ASTPTR(pScrn);
1106
1107   /* Fixed suspend can't resume issue */
1108   if (!bIsVGAEnabled(pScrn))
1109   {
1110       if (pAST->jChipType == AST1180)
1111           bInitAST1180(pScrn);
1112       else
1113       {
1114           vEnableASTVGAMMIO(pScrn);
1115           InitVGA(pScrn, 1);
1116       }
1117       ASTRestore(pScrn);
1118   }
1119
1120   if (!ASTModeInit(pScrn, pScrn->currentMode))
1121      return FALSE;
1122   ASTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
1123
1124   return TRUE;
1125
1126}
1127
1128/* leave X server */
1129static void
1130ASTLeaveVT(VT_FUNC_ARGS_DECL)
1131{
1132
1133   SCRN_INFO_PTR(arg);
1134   ASTRecPtr pAST = ASTPTR(pScrn);
1135#if	!(defined(__sparc__)) && !(defined(__mips__))
1136   vgaHWPtr hwp = VGAHWPTR(pScrn);
1137#endif
1138
1139#ifdef	HWC
1140   if (pAST->pHWCPtr) {
1141       xf86FreeOffscreenLinear(pAST->pHWCPtr);		/* free HWC Cache */
1142       pAST->pHWCPtr = NULL;
1143   }
1144   ASTDisableHWC(pScrn);
1145#endif
1146
1147#ifdef Accel_2D
1148   if (pAST->pCMDQPtr) {
1149       xf86FreeOffscreenLinear(pAST->pCMDQPtr);		/* free CMDQ */
1150       pAST->pCMDQPtr = NULL;
1151   }
1152   vDisable2D(pScrn, pAST);
1153#endif
1154
1155   ASTRestore(pScrn);
1156
1157   if (pAST->jChipType == AST1180)
1158       ASTBlankScreen(pScrn, 0);
1159
1160#if	!(defined(__sparc__)) && !(defined(__mips__))
1161   vgaHWLock(hwp);
1162#endif
1163
1164}
1165
1166static void
1167ASTFreeScreen(FREE_SCREEN_ARGS_DECL)
1168{
1169   SCRN_INFO_PTR(arg);
1170   ASTFreeRec(pScrn);
1171#if	!(defined(__sparc__)) && !(defined(__mips__))
1172   if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
1173      vgaHWFreeHWRec(pScrn);
1174#endif
1175}
1176
1177static ModeStatus
1178ASTValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
1179{
1180   SCRN_INFO_PTR(arg);
1181   ASTRecPtr   pAST  = ASTPTR(pScrn);
1182   ModeStatus Flags = MODE_NOMODE;
1183   UCHAR jReg;
1184   ULONG RequestBufferSize;
1185
1186   if (mode->Flags & V_INTERLACE) {
1187      if (verbose) {
1188	 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1189		    "Removing interlaced mode \"%s\"\n", mode->name);
1190      }
1191      return MODE_NO_INTERLACE;
1192   }
1193
1194   if ((mode->CrtcHDisplay > MAX_HResolution) || (mode->CrtcVDisplay > MAX_VResolution)) {
1195      if (verbose) {
1196	 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1197		    "Removing the mode \"%s\"\n", mode->name);
1198      }
1199      return Flags;
1200   }
1201
1202   /* Valid Framebuffer size */
1203   RequestBufferSize = mode->CrtcHDisplay * ((pScrn->bitsPerPixel + 1) / 8) * mode->CrtcVDisplay;
1204   if (RequestBufferSize > pAST->ulVRAMSize)
1205      return Flags;
1206
1207   /* Valid Wide Screen Mode */
1208   if (pAST->SupportWideScreen)
1209   {
1210      if ( (mode->CrtcHDisplay == 1680) && (mode->CrtcVDisplay == 1050) )
1211          return MODE_OK;
1212      if ( (mode->CrtcHDisplay == 1280) && (mode->CrtcVDisplay == 800) )
1213          return MODE_OK;
1214      if ( (mode->CrtcHDisplay == 1440) && (mode->CrtcVDisplay == 900) )
1215          return MODE_OK;
1216      if ( (mode->CrtcHDisplay == 1360) && (mode->CrtcVDisplay == 768) )
1217          return MODE_OK;
1218      if ( (mode->CrtcHDisplay == 1600) && (mode->CrtcVDisplay == 900) )
1219          return MODE_OK;
1220
1221      if ( (pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST1180) )
1222      {
1223          if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1080) )
1224              return MODE_OK;
1225
1226          if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1200) )
1227          {
1228             GetIndexRegMask(CRTC_PORT, 0xD1, 0xFF, jReg);
1229	     if (jReg & 0x01)
1230	        return MODE_NOMODE;
1231	     else
1232                return MODE_OK;
1233          }
1234      }
1235   }
1236
1237   switch (mode->CrtcHDisplay)
1238   {
1239   case 640:
1240       if (mode->CrtcVDisplay == 480) Flags=MODE_OK;
1241       break;
1242   case 800:
1243       if (mode->CrtcVDisplay == 600) Flags=MODE_OK;
1244       break;
1245   case 1024:
1246       if (mode->CrtcVDisplay == 768) Flags=MODE_OK;
1247       break;
1248   case 1280:
1249       if (mode->CrtcVDisplay == 1024) Flags=MODE_OK;
1250       break;
1251   case 1600:
1252       if (mode->CrtcVDisplay == 1200) Flags=MODE_OK;
1253       break;
1254   default:
1255       return Flags;
1256   }
1257
1258   return Flags;
1259}
1260
1261/* Internal used modules */
1262/*
1263 * ASTGetRec and ASTFreeRec --
1264 *
1265 * Private data for the driver is stored in the screen structure.
1266 * These two functions create and destroy that private data.
1267 *
1268 */
1269static Bool
1270ASTGetRec(ScrnInfoPtr pScrn)
1271{
1272   if (pScrn->driverPrivate)
1273      return TRUE;
1274
1275   pScrn->driverPrivate = xnfcalloc(sizeof(ASTRec), 1);
1276   return TRUE;
1277}
1278
1279static void
1280ASTFreeRec(ScrnInfoPtr pScrn)
1281{
1282   if (!pScrn)
1283      return;
1284   if (!pScrn->driverPrivate)
1285      return;
1286   free(pScrn->driverPrivate);
1287   pScrn->driverPrivate = 0;
1288}
1289
1290static Bool
1291ASTSaveScreen(ScreenPtr pScreen, Bool unblack)
1292{
1293#if	!(defined(__sparc__)) && !(defined(__mips__))
1294   /* replacement of vgaHWBlankScreen(pScrn, unblank) without seq reset */
1295   /* return vgaHWSaveScreen(pScreen, unblack); */
1296   ScrnInfoPtr pScrn = NULL;
1297
1298   if (pScreen != NULL)
1299      pScrn = xf86ScreenToScrn(pScreen);
1300
1301   if ((pScrn != NULL) && pScrn->vtSema) {
1302     ASTBlankScreen(pScrn, unblack);
1303   }
1304   return (TRUE);
1305#endif
1306}
1307
1308static Bool
1309ASTCloseScreen(CLOSE_SCREEN_ARGS_DECL)
1310{
1311   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1312   ASTRecPtr pAST = ASTPTR(pScrn);
1313#if	!(defined(__sparc__)) && !(defined(__mips__))
1314   vgaHWPtr hwp = VGAHWPTR(pScrn);
1315#endif
1316
1317   if (pScrn->vtSema == TRUE)
1318   {
1319#ifdef	HWC
1320       if (pAST->pHWCPtr) {
1321           xf86FreeOffscreenLinear(pAST->pHWCPtr);		/* free HWC Cache */
1322           pAST->pHWCPtr = NULL;
1323       }
1324       ASTDisableHWC(pScrn);
1325#endif
1326
1327#ifdef Accel_2D
1328       if (pAST->pCMDQPtr) {
1329           xf86FreeOffscreenLinear(pAST->pCMDQPtr);		/* free CMDQ */
1330           pAST->pCMDQPtr = NULL;
1331       }
1332       vDisable2D(pScrn, pAST);
1333#endif
1334
1335       ASTRestore(pScrn);
1336
1337       if (pAST->jChipType == AST1180)
1338           ASTBlankScreen(pScrn, 0);
1339
1340#if	!(defined(__sparc__)) && !(defined(__mips__))
1341       vgaHWLock(hwp);
1342#endif
1343   }
1344
1345   ASTUnmapMem(pScrn);
1346#if	!(defined(__sparc__)) && !(defined(__mips__))
1347   vgaHWUnmapMem(pScrn);
1348#endif
1349
1350#ifdef HAVE_XAA_H
1351   if(pAST->AccelInfoPtr) {
1352       XAADestroyInfoRec(pAST->AccelInfoPtr);
1353       pAST->AccelInfoPtr = NULL;
1354   }
1355#endif
1356   if(pAST->HWCInfoPtr) {
1357       xf86DestroyCursorInfoRec(pAST->HWCInfoPtr);
1358       pAST->HWCInfoPtr = NULL;
1359   }
1360
1361#ifdef	Support_ShadowFB
1362   if (pAST->shadowFB_validation) {
1363      shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen));
1364	  free(pAST->shadow);
1365      pScreen->CreateScreenResources = pAST->CreateScreenResources;
1366   }
1367#endif
1368
1369   pScrn->vtSema = FALSE;
1370   pScreen->CloseScreen = pAST->CloseScreen;
1371   return (*pScreen->CloseScreen) (CLOSE_SCREEN_ARGS);
1372}
1373
1374static void
1375ASTSave(ScrnInfoPtr pScrn)
1376{
1377   ASTRecPtr pAST;
1378   ASTRegPtr astReg;
1379   int i, icount=0;
1380   ULONG ulData;
1381
1382   pAST = ASTPTR(pScrn);
1383   astReg = &pAST->SavedReg;
1384
1385   if (pAST->jChipType == AST1180)
1386   {
1387       for (i=0; i<12; i++)
1388       {
1389           ReadAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL+i*4, ulData);
1390           astReg->GFX[i] = ulData;
1391       }
1392   }
1393   else
1394   {
1395#if	defined(__sparc__) || defined(__mips__)
1396       UCHAR jReg;
1397
1398       /* Save Misc */
1399       astReg->MISC = GetReg(MISC_PORT_READ);
1400
1401       /* Save SR */
1402       for (i=0; i<4; i++)
1403           GetIndexReg(SEQ_PORT, (UCHAR) (i), astReg->SEQ[i]);
1404
1405       /* Save CR */
1406       for (i=0; i<25; i++)
1407           GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->CRTC[i]);
1408
1409       /* Save GR */
1410       for (i=0; i<9; i++)
1411           GetIndexReg(GR_PORT, (UCHAR) (i), astReg->GR[i]);
1412
1413       /* Save AR */
1414       jReg = GetReg(INPUT_STATUS1_READ);
1415       for (i=0; i<20; i++)
1416           GetIndexReg(AR_PORT_WRITE, (UCHAR) (i), astReg->AR[i]);
1417       jReg = GetReg(INPUT_STATUS1_READ);
1418       SetReg (AR_PORT_WRITE, 0x20);		/* set POS */
1419#else
1420       vgaRegPtr vgaReg;
1421       vgaReg = &VGAHWPTR(pScrn)->SavedReg;
1422
1423       /* do save */
1424       if (xf86IsPrimaryPci(pAST->PciInfo)) {
1425           vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_FONTS);
1426       }
1427       else {
1428           vgaHWSave(pScrn, vgaReg, VGA_SR_MODE);
1429       }
1430#endif
1431
1432       /* Save Ext. */
1433       vASTOpenKey(pScrn);
1434
1435       /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */
1436       for (i=0x81; i<=0xB6; i++)
1437           GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]);
1438       for (i=0xBC; i<=0xC1; i++)
1439           GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]);
1440       GetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]);
1441
1442       /* Save DAC */
1443       for (i=0; i<256; i++)
1444           VGA_GET_PALETTE_INDEX (i, astReg->DAC[i][0], astReg->DAC[i][1], astReg->DAC[i][2]);
1445
1446       /* Save 2D */
1447       astReg->ENG8044 = 0;
1448       GetIndexReg(CRTC_PORT, 0xA4, astReg->REGA4);
1449       if (astReg->REGA4 & 0x01)	/* 2D enabled */
1450           astReg->ENG8044 = *(ULONG *) (pAST->MMIOVirtualAddr + 0x8044);
1451   }
1452
1453}
1454
1455static void
1456ASTRestore(ScrnInfoPtr pScrn)
1457{
1458   ASTRecPtr pAST;
1459   ASTRegPtr astReg;
1460   int i, icount=0;
1461   ULONG ulData;
1462
1463   pAST = ASTPTR(pScrn);
1464   astReg = &pAST->SavedReg;
1465
1466   ASTDisplayPowerManagementSet(pScrn, DPMSModeOff, 0);
1467
1468   if (pAST->jChipType == AST1180)
1469   {
1470       for (i=0; i<12; i++)
1471       {
1472           ulData = astReg->GFX[i];
1473           WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL+i*4, ulData);
1474       }
1475   }
1476   else
1477   {
1478#if	defined(__sparc__) || defined(__mips__)
1479       UCHAR jReg;
1480
1481       /* Restore Misc */
1482       SetReg(MISC_PORT_WRITE, astReg->MISC);
1483
1484       /* Restore SR */
1485       for (i=0; i<4; i++)
1486           SetIndexReg(SEQ_PORT, (UCHAR) (i), astReg->SEQ[i]);
1487
1488       /* Restore CR */
1489       SetIndexRegMask(CRTC_PORT,0x11, 0x7F, 0x00);
1490       for (i=0; i<25; i++)
1491           SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->CRTC[i]);
1492
1493       /* Restore GR */
1494       for (i=0; i<9; i++)
1495           SetIndexReg(GR_PORT, (UCHAR) (i), astReg->GR[i]);
1496
1497       /* Restore AR */
1498       jReg = GetReg(INPUT_STATUS1_READ);
1499       for (i=0; i<20; i++)
1500       {
1501           SetReg(AR_PORT_WRITE, (UCHAR) i);
1502           SetReg(AR_PORT_WRITE, astReg->AR[i]);
1503       }
1504       SetReg(AR_PORT_WRITE, 0x14);
1505       SetReg(AR_PORT_WRITE, 0x00);
1506
1507       jReg = GetReg(INPUT_STATUS1_READ);
1508       SetReg (AR_PORT_WRITE, 0x20);		/* set POS */
1509#else
1510       vgaRegPtr vgaReg;
1511       vgaReg = &VGAHWPTR(pScrn)->SavedReg;
1512
1513       /* do restore */
1514       vgaHWProtect(pScrn, TRUE);
1515       if (xf86IsPrimaryPci(pAST->PciInfo))
1516           vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_FONTS);
1517       else
1518           vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
1519       vgaHWProtect(pScrn, FALSE);
1520#endif
1521
1522      /* Ext. restore */
1523      vASTOpenKey(pScrn);
1524
1525       /* Restore DAC */
1526       for (i=0; i<256; i++)
1527          VGA_LOAD_PALETTE_INDEX (i, astReg->DAC[i][0], astReg->DAC[i][1], astReg->DAC[i][2]);
1528
1529      /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */
1530      for (i=0x81; i<=0xB6; i++)
1531          SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]);
1532      for (i=0xBC; i<=0xC1; i++)
1533          SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]);
1534      SetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]);
1535   }
1536
1537}
1538
1539static void
1540ASTProbeDDC(ScrnInfoPtr pScrn, int index)
1541{
1542   ASTRecPtr pAST = ASTPTR(pScrn);
1543   unsigned char DDC_data[128];
1544   Bool Flags;
1545
1546   if (xf86LoadSubModule(pScrn, "ddc"))
1547   {
1548      if (pAST->jChipType == AST1180)
1549          Flags = GetVGA2EDID(pScrn, DDC_data);
1550      else
1551          Flags = GetVGAEDID(pScrn, DDC_data);
1552
1553      if (Flags)
1554      {
1555          ConfiguredMonitor = xf86InterpretEDID(pScrn->scrnIndex, DDC_data);
1556      }
1557      else
1558          xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTProbeDDC] Can't Get EDID Properly \n");
1559   }
1560   else
1561   {
1562      xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTProbeDDC] Can't Load DDC Sub-Modules or Read EDID Failed \n");
1563   }
1564
1565}
1566
1567#define SkipDT	0x00
1568#define DT1	0x01
1569#define DT2 	0x02
1570
1571static xf86MonPtr
1572ASTDoDDC(ScrnInfoPtr pScrn, int index)
1573{
1574   xf86MonPtr MonInfo = NULL;
1575   ASTRecPtr pAST = ASTPTR(pScrn);
1576   unsigned char DDC_data[128];
1577   Bool Flags;
1578
1579   xf86MonPtr MonInfo1 = NULL, MonInfo2 = NULL;
1580   unsigned long i, j, k;
1581   struct monitor_ranges ranges, ranges1, ranges2;
1582   int DTSelect, dclock1=0, h_active1=0, v_active1=0, dclock2=0, h_active2=0, v_active2=0;
1583   struct std_timings stdtiming, *stdtiming1, *stdtiming2;
1584
1585   /* Honour Option "noDDC" */
1586   if (xf86ReturnOptValBool(pAST->Options, OPTION_NO_DDC, FALSE)) {
1587      return MonInfo;
1588   }
1589
1590   if (xf86LoadSubModule(pScrn, "ddc"))
1591   {
1592      if (pAST->jChipType == AST1180)
1593          Flags = GetVGA2EDID(pScrn, DDC_data);
1594      else
1595          Flags = GetVGAEDID(pScrn, DDC_data);
1596
1597      if (Flags)
1598      {
1599          MonInfo = MonInfo1 = xf86InterpretEDID(pScrn->scrnIndex, DDC_data);
1600
1601          /* Valid Wide Screen Support */
1602          if ( (MonInfo) && (MonInfo->det_mon[0].type == 0x00) )
1603          {
1604	          if ( (MonInfo->det_mon[0].section.d_timings.h_active * 10 / MonInfo->det_mon[0].section.d_timings.v_active) < 14 )
1605                  pAST->SupportWideScreen = FALSE;
1606          }
1607      }
1608
1609      /* For VGA2 CLONE Support, ycchen@012508 */
1610      if ((xf86ReturnOptValBool(pAST->Options, OPTION_VGA2_CLONE, FALSE)) || pAST->VGA2Clone) {
1611          if (GetVGA2EDID(pScrn, DDC_data) == TRUE) {
1612              xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Get VGA2 EDID Correctly!! \n");
1613              MonInfo2 = xf86InterpretEDID(pScrn->scrnIndex, DDC_data);
1614              if (MonInfo1 == NULL)	/* No DDC1 EDID */
1615                  MonInfo = MonInfo2;
1616              else {			/* Check with VGA1 & VGA2 EDID */
1617                   /* Update establishment timing */
1618                   MonInfo->timings1.t1 = MonInfo1->timings1.t1 & MonInfo2->timings1.t1;
1619                   MonInfo->timings1.t2 = MonInfo1->timings1.t2 & MonInfo2->timings1.t2;
1620                   MonInfo->timings1.t_manu = MonInfo1->timings1.t_manu & MonInfo2->timings1.t_manu;
1621
1622                   /* Update Std. Timing */
1623                   for (i=0; i<8; i++) {
1624                       stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0;
1625                       for (j=0; j<8; j++) {
1626                           if ((MonInfo1->timings2[i].hsize == MonInfo2->timings2[j].hsize) && \
1627                               (MonInfo1->timings2[i].vsize == MonInfo2->timings2[j].vsize) && \
1628                               (MonInfo1->timings2[i].refresh == MonInfo2->timings2[j].refresh)) {
1629                                stdtiming = MonInfo1->timings2[i];
1630                                break;
1631                           }
1632                       }
1633
1634                       MonInfo->timings2[i] = stdtiming;
1635                   } /* Std. Timing */
1636
1637                   /* Get Detailed Timing */
1638                   for (i=0;i<4;i++) {
1639                      if (MonInfo1->det_mon[i].type == 0xFD)
1640                         ranges1 = MonInfo1->det_mon[i].section.ranges;
1641                      else if (MonInfo1->det_mon[i].type == 0xFA)
1642                         stdtiming1 = MonInfo1->det_mon[i].section.std_t;
1643                      else if (MonInfo1->det_mon[i].type == 0x00) {
1644                         if (MonInfo1->det_mon[i].section.d_timings.clock > dclock1)
1645                             dclock1 = MonInfo1->det_mon[i].section.d_timings.clock;
1646                         if (MonInfo1->det_mon[i].section.d_timings.h_active > h_active1)
1647                             h_active1 = MonInfo1->det_mon[i].section.d_timings.h_active;
1648                         if (MonInfo1->det_mon[i].section.d_timings.v_active > v_active1)
1649                             v_active1 = MonInfo1->det_mon[i].section.d_timings.v_active;
1650                      }
1651                      if (MonInfo2->det_mon[i].type == 0xFD)
1652                         ranges2 = MonInfo2->det_mon[i].section.ranges;
1653                      else if (MonInfo1->det_mon[i].type == 0xFA)
1654                         stdtiming2 = MonInfo2->det_mon[i].section.std_t;
1655                      else if (MonInfo2->det_mon[i].type == 0x00) {
1656                         if (MonInfo2->det_mon[i].section.d_timings.clock > dclock2)
1657                             dclock2 = MonInfo2->det_mon[i].section.d_timings.clock;
1658                         if (MonInfo2->det_mon[i].section.d_timings.h_active > h_active2)
1659                             h_active2 = MonInfo2->det_mon[i].section.d_timings.h_active;
1660                         if (MonInfo2->det_mon[i].section.d_timings.v_active > v_active2)
1661                             v_active2 = MonInfo2->det_mon[i].section.d_timings.v_active;
1662                      }
1663                   } /* Get Detailed Timing */
1664
1665                   /* Chk Detailed Timing */
1666                   if ((dclock1 >= dclock2) && (h_active1 >= h_active2) && (v_active1 >= v_active2))
1667                       DTSelect = DT2;
1668                   else if ((dclock2 >= dclock1) && (h_active2 >= h_active1) && (v_active2 >= v_active1))
1669                       DTSelect = DT1;
1670                   else
1671                       DTSelect = SkipDT;
1672
1673                   /* Chk Monitor Descriptor */
1674                   ranges = ranges1;
1675                   ranges.min_h = ranges1.min_h > ranges2.min_h ? ranges1.min_h:ranges2.min_h;
1676                   ranges.min_v = ranges1.min_v > ranges2.min_v ? ranges1.min_v:ranges2.min_v;
1677                   ranges.max_h = ranges1.max_h < ranges2.max_h ? ranges1.max_h:ranges2.max_h;
1678                   ranges.max_v = ranges1.max_v < ranges2.max_v ? ranges1.max_v:ranges2.max_v;
1679                   ranges.max_clock = ranges1.max_clock < ranges2.max_clock ? ranges1.max_clock:ranges2.max_clock;
1680
1681                   /* Update Detailed Timing */
1682                   for (i=0; i<4; i++)
1683                   {
1684                       if (MonInfo->det_mon[i].type == 0xFD) {
1685                           MonInfo->det_mon[i].section.ranges = ranges;
1686                       }
1687                       else if (MonInfo->det_mon[i].type == 0xFA) {
1688                           for (j=0; j<5; j++) {
1689         	                  stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0;
1690                               for (k=0; k<5; k++) {
1691                                   if ((stdtiming1[j].hsize == stdtiming2[k].hsize) && \
1692                                       (stdtiming1[j].vsize == stdtiming2[k].vsize) && \
1693                                       (stdtiming1[j].refresh == stdtiming2[k].refresh)) {
1694                                        stdtiming = stdtiming1[j];
1695                                        break;
1696                                   }
1697                               }
1698                               stdtiming1[j] = stdtiming;
1699                           } /* Std. Timing */
1700                       } /* FA */
1701                       else if (MonInfo->det_mon[i].type == 0x00) {
1702                           if (DTSelect == DT2)
1703                               MonInfo->det_mon[i] = MonInfo2->det_mon[i];
1704                           else if (DTSelect == DT1)
1705                               MonInfo->det_mon[i] = MonInfo1->det_mon[i];
1706                           else /* SkipDT */
1707                           {   /* use 1024x768 as default */
1708                               MonInfo->det_mon[i] = MonInfo1->det_mon[i];
1709                               MonInfo->det_mon[i].section.d_timings.clock = 65000000;
1710                               MonInfo->det_mon[i].section.d_timings.h_active = 1024;
1711                               MonInfo->det_mon[i].section.d_timings.h_blanking = 320;
1712                               MonInfo->det_mon[i].section.d_timings.v_active = 768;
1713                               MonInfo->det_mon[i].section.d_timings.v_blanking = 38;
1714                               MonInfo->det_mon[i].section.d_timings.h_sync_off = 24;
1715                               MonInfo->det_mon[i].section.d_timings.h_sync_width = 136;
1716                               MonInfo->det_mon[i].section.d_timings.v_sync_off = 3;
1717                               MonInfo->det_mon[i].section.d_timings.v_sync_width = 6;
1718                           }
1719                       } /* 00 */
1720                       else { /* use Monitor 1 as default */
1721                           MonInfo->det_mon[i] = MonInfo1->det_mon[i];
1722                       }
1723
1724                   } /* Update Detailed Timing */
1725
1726                   /* set feature size */
1727                   if (DTSelect == DT2)  {
1728                       MonInfo->features.hsize = MonInfo2->features.hsize;
1729                       MonInfo->features.vsize = MonInfo2->features.vsize;
1730                   }
1731                   else if (DTSelect == DT1)  {
1732                       MonInfo->features.hsize = MonInfo1->features.hsize;
1733                       MonInfo->features.vsize = MonInfo1->features.vsize;
1734                   }
1735                   else	/* Skip DT */
1736                   {   /* use 1024x768 as default */
1737                       MonInfo->features.hsize = 0x20;
1738                       MonInfo->features.vsize = 0x18;
1739                   }
1740
1741               } /* Check with VGA1 & VGA2 EDID */
1742
1743           } /* GetVGA2EDID */
1744           else {
1745               xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Can't Get VGA2 EDID Correctly!! \n");
1746           }
1747      } /* VGA2Clone */
1748
1749      xf86PrintEDID(MonInfo);
1750      xf86SetDDCproperties(pScrn, MonInfo);
1751   }
1752   else
1753   {
1754      xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTDoDDC] Can't Load DDC Sub-Modules or Read EDID Failed \n");
1755   }
1756
1757   /* Fill pAST Monitor Info */
1758   if (MonInfo == NULL)
1759   {	/* default for Non-EDID */
1760       pAST->mon_h_active = 1024;
1761       pAST->mon_v_active = 768;
1762   }
1763   else
1764   {	/* save MonInfo to Private */
1765       pAST->mon_h_active = MonInfo->det_mon[0].section.d_timings.h_active;
1766       pAST->mon_v_active = MonInfo->det_mon[0].section.d_timings.v_active;
1767   }
1768
1769   return MonInfo;
1770}
1771
1772static void
1773vFillASTModeInfo (ScrnInfoPtr pScrn)
1774{
1775    ASTRecPtr pAST;
1776
1777    pAST = ASTPTR(pScrn);
1778
1779    pAST->VideoModeInfo.ScreenWidth = pScrn->virtualX;
1780    pAST->VideoModeInfo.ScreenHeight = pScrn->virtualY;
1781    pAST->VideoModeInfo.bitsPerPixel = pScrn->bitsPerPixel;
1782    /* Fixed screen pitch incorrect in some specific monitor, ycchen@071707 */
1783    pAST->VideoModeInfo.ScreenPitch = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8) ;
1784
1785}
1786
1787static Bool
1788ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
1789{
1790    ASTRecPtr pAST;
1791
1792    pAST = ASTPTR(pScrn);
1793
1794    pScrn->vtSema = TRUE;
1795    pAST->ModePtr = mode;
1796
1797#if	defined(__sparc__) || defined(__mips__)
1798    if (!ASTSetMode(pScrn, mode))
1799      return FALSE;
1800#else
1801    vgaHWPtr hwp;
1802
1803    hwp = VGAHWPTR(pScrn);
1804
1805    vgaHWUnlock(hwp);
1806
1807    if (!vgaHWInit(pScrn, mode))
1808      return FALSE;
1809
1810    pScrn->vtSema = TRUE;
1811    pAST->ModePtr = mode;
1812
1813    if (!ASTSetMode(pScrn, mode))
1814      return FALSE;
1815
1816    vgaHWProtect(pScrn, FALSE);
1817#endif
1818
1819    return TRUE;
1820}
1821
1822#ifdef AstVideo
1823/*
1824 * Video Part by ic_yang
1825 */
1826#include "fourcc.h"
1827
1828#define NUM_ATTRIBUTES  	8
1829#define NUM_IMAGES 		8
1830#define NUM_FORMATS     	3
1831
1832#define IMAGE_MIN_WIDTH         32
1833#define IMAGE_MIN_HEIGHT        24
1834#define IMAGE_MAX_WIDTH         1920
1835#define IMAGE_MAX_HEIGHT        1080
1836
1837#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
1838
1839static XF86ImageRec ASTImages[NUM_IMAGES] =
1840{
1841    XVIMAGE_YUY2, /* If order is changed, ASTOffscreenImages must be adapted */
1842};
1843
1844static XF86VideoFormatRec ASTFormats[NUM_FORMATS] =
1845{
1846   { 8, PseudoColor},
1847   {16, TrueColor},
1848   {24, TrueColor}
1849};
1850
1851/* client libraries expect an encoding */
1852static XF86VideoEncodingRec DummyEncoding =
1853{
1854   0,
1855   "XV_IMAGE",
1856   0, 0,                /* Will be filled in */
1857   {1, 1}
1858};
1859
1860static char astxvcolorkey[] 				= "XV_COLORKEY";
1861static char astxvbrightness[] 				= "XV_BRIGHTNESS";
1862static char astxvcontrast[] 				= "XV_CONTRAST";
1863static char astxvsaturation[] 				= "XV_SATURATION";
1864static char astxvhue[] 				        = "XV_HUE";
1865static char astxvgammared[] 				= "XV_GAMMA_RED";
1866static char astxvgammagreen[] 				= "XV_GAMMA_GREEN";
1867static char astxvgammablue[] 				= "XV_GAMMA_BLUE";
1868
1869static XF86AttributeRec ASTAttributes[NUM_ATTRIBUTES] =
1870{
1871   {XvSettable | XvGettable, 0, (1 << 24) - 1, astxvcolorkey},
1872   {XvSettable | XvGettable, -128, 127, astxvbrightness},
1873   {XvSettable | XvGettable, 0, 255, astxvcontrast},
1874   {XvSettable | XvGettable, -180, 180, astxvsaturation},
1875   {XvSettable | XvGettable, -180, 180, astxvhue},
1876   {XvSettable | XvGettable, 100, 10000, astxvgammared},
1877   {XvSettable | XvGettable, 100, 10000, astxvgammagreen},
1878   {XvSettable | XvGettable, 100, 10000, astxvgammablue},
1879};
1880
1881static void ASTStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit)
1882{
1883    ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data;
1884    ASTPtr pAST = ASTPTR(pScrn);
1885
1886    REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
1887
1888    if(exit)
1889    {
1890        if(pPriv->fbAreaPtr)
1891        {
1892            xf86FreeOffscreenArea(pPriv->fbAreaPtr);
1893            pPriv->fbAreaPtr = NULL;
1894            pPriv->fbSize = 0;
1895        }
1896        /* clear all flag */
1897        pPriv->videoStatus = 0;
1898    }
1899    else
1900    {
1901#if 0
1902        if(pPriv->videoStatus & CLIENT_VIDEO_ON)
1903        {
1904            pPriv->videoStatus |= OFF_TIMER;
1905
1906        }
1907#endif
1908    }
1909}
1910
1911static int ASTSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data)
1912{
1913    ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data;
1914    ASTPtr pAST = ASTPTR(pScrn);
1915
1916    xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTSetPortAttribute(),attribute=%x\n", attribute);
1917
1918    if (attribute == pAST->xvBrightness)
1919    {
1920        if((value < -128) || (value > 127))
1921         return BadValue;
1922
1923        pPriv->brightness = value;
1924    }
1925    else if (attribute == pAST->xvContrast)
1926    {
1927        if ((value < 0) || (value > 255))
1928         return BadValue;
1929
1930        pPriv->contrast = value;
1931    }
1932    else if (attribute == pAST->xvSaturation)
1933    {
1934        if ((value < -180) || (value > 180))
1935         return BadValue;
1936
1937        pPriv->saturation = value;
1938    }
1939    else if (attribute == pAST->xvHue)
1940    {
1941        if ((value < -180) || (value > 180))
1942         return BadValue;
1943
1944        pPriv->hue = value;
1945    }
1946    else if (attribute == pAST->xvColorKey)
1947    {
1948          pPriv->colorKey = value;
1949          REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
1950    }
1951    else if(attribute == pAST->xvGammaRed)
1952    {
1953        if((value < 100) || (value > 10000))
1954            return BadValue;
1955        pPriv->gammaR = value;
1956    }
1957    else if(attribute == pAST->xvGammaGreen)
1958    {
1959        if((value < 100) || (value > 10000))
1960            return BadValue;
1961        pPriv->gammaG = value;
1962    }
1963    else if(attribute == pAST->xvGammaBlue)
1964    {
1965        if((value < 100) || (value > 10000))
1966            return BadValue;
1967        pPriv->gammaB = value;
1968    }
1969    else
1970    {
1971        return BadMatch;
1972    }
1973
1974    return Success;
1975}
1976
1977static int ASTGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, pointer data)
1978{
1979    ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data;
1980    ASTPtr pAST = ASTPTR(pScrn);
1981
1982    xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTGetPortAttribute(),attribute=%x\n", attribute);
1983
1984    if (attribute == pAST->xvBrightness)
1985    {
1986        *value = pPriv->brightness;
1987    }
1988    else if (attribute == pAST->xvContrast)
1989    {
1990        *value = pPriv->contrast;
1991    }
1992    else if (attribute == pAST->xvSaturation)
1993    {
1994        *value = pPriv->saturation;
1995    }
1996    else if (attribute == pAST->xvHue)
1997    {
1998        *value = pPriv->hue;
1999    }
2000    else if(attribute == pAST->xvGammaRed)
2001    {
2002        *value = pPriv->gammaR;
2003
2004    }
2005    else if(attribute == pAST->xvGammaGreen)
2006    {
2007        *value = pPriv->gammaG;
2008    }
2009    else if(attribute == pAST->xvGammaBlue)
2010    {
2011        *value = pPriv->gammaB;
2012    }
2013    else if (attribute == pAST->xvColorKey)
2014    {
2015        *value = pPriv->colorKey;
2016    }
2017    else
2018        return BadMatch;
2019
2020    return Success;
2021}
2022
2023static void ASTQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
2024                                short vid_w, short vid_h,
2025                                short drw_w, short drw_h,
2026                                unsigned int *p_w, unsigned int *p_h,
2027                                pointer data)
2028{
2029    *p_w = drw_w;
2030    *p_h = drw_h;
2031    xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTQueryBestSize()\n");
2032  /* TODO: report the HW limitation */
2033}
2034
2035static int ASTQueryImageAttributes(ScrnInfoPtr pScrn, int id,
2036                                    unsigned short *w, unsigned short *h,
2037                                    int *pitches, int *offsets)
2038{
2039    int pitchY, pitchUV;
2040    int size, sizeY, sizeUV;
2041
2042    xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTQueryImageAttributes()\n");
2043
2044    if(*w < IMAGE_MIN_WIDTH) *w = IMAGE_MIN_WIDTH;
2045    if(*h < IMAGE_MIN_HEIGHT) *h = IMAGE_MIN_HEIGHT;
2046
2047    switch(id) {
2048    case PIXEL_FMT_YV12:
2049        *w = (*w + 7) & ~7;
2050        *h = (*h + 1) & ~1;
2051        pitchY = *w;
2052        pitchUV = *w >> 1;
2053        if(pitches) {
2054          pitches[0] = pitchY;
2055          pitches[1] = pitches[2] = pitchUV;
2056        }
2057        sizeY = pitchY * (*h);
2058        sizeUV = pitchUV * ((*h) >> 1);
2059        if(offsets) {
2060          offsets[0] = 0;
2061          offsets[1] = sizeY;
2062          offsets[2] = sizeY + sizeUV;
2063        }
2064        size = sizeY + (sizeUV << 1);
2065        break;
2066    case PIXEL_FMT_NV12:
2067    case PIXEL_FMT_NV21:
2068        *w = (*w + 7) & ~7;
2069        *h = (*h + 1) & ~1;
2070		pitchY = *w;
2071    	pitchUV = *w;
2072    	if(pitches) {
2073      	    pitches[0] = pitchY;
2074            pitches[1] = pitchUV;
2075        }
2076    	sizeY = pitchY * (*h);
2077    	sizeUV = pitchUV * ((*h) >> 1);
2078    	if(offsets) {
2079          offsets[0] = 0;
2080          offsets[1] = sizeY;
2081        }
2082        size = sizeY + (sizeUV << 1);
2083        break;
2084    case PIXEL_FMT_YUY2:
2085    case PIXEL_FMT_UYVY:
2086    case PIXEL_FMT_YVYU:
2087    case PIXEL_FMT_RGB6:
2088    case PIXEL_FMT_RGB5:
2089    default:
2090        *w = (*w + 1) & ~1;
2091        pitchY = *w << 1;
2092        if(pitches) pitches[0] = pitchY;
2093        if(offsets) offsets[0] = 0;
2094        size = pitchY * (*h);
2095        break;
2096    }
2097
2098    return size;
2099}
2100
2101extern void ASTDisplayVideo(ScrnInfoPtr pScrn, ASTPortPrivPtr pPriv, RegionPtr clipBoxes, int id);
2102
2103static int ASTPutImage(ScrnInfoPtr pScrn,
2104                          short src_x, short src_y,
2105                          short drw_x, short drw_y,
2106                          short src_w, short src_h,
2107                          short drw_w, short drw_h,
2108                          int id, unsigned char* buf,
2109                          short width, short height,
2110                          Bool sync,
2111                          RegionPtr clipBoxes, pointer data,
2112			  DrawablePtr pDraw
2113)
2114{
2115    ASTPtr pAST = ASTPTR(pScrn);
2116    ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data;
2117    int i;
2118    int totalSize=0;
2119
2120    xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTPutImage()\n");
2121    /*   int depth = pAST->CurrentLayout.bitsPerPixel >> 3; */
2122
2123    pPriv->drw_x = drw_x;
2124    pPriv->drw_y = drw_y;
2125    pPriv->drw_w = drw_w;
2126    pPriv->drw_h = drw_h;
2127    pPriv->src_x = src_x;
2128    pPriv->src_y = src_y;
2129    pPriv->src_w = src_w;
2130    pPriv->src_h = src_h;
2131    pPriv->id = id;
2132    pPriv->height = height;
2133
2134    switch(id)
2135    {
2136    case PIXEL_FMT_YV12:
2137    case PIXEL_FMT_NV12:
2138    case PIXEL_FMT_NV21:
2139        pPriv->srcPitch = (width + 7) & ~7;
2140        totalSize = (pPriv->srcPitch * height * 3) >> 1; /* Verified */
2141    break;
2142    case PIXEL_FMT_YUY2:
2143    case PIXEL_FMT_UYVY:
2144    case PIXEL_FMT_YVYU:
2145    case PIXEL_FMT_RGB6:
2146    case PIXEL_FMT_RGB5:
2147    default:
2148        pPriv->srcPitch = ((width << 1) + 3) & ~3;	/* Verified */
2149        totalSize = pPriv->srcPitch * height;
2150    }
2151
2152    totalSize += 15;
2153    totalSize &= ~15;
2154    /* allocate memory */
2155
2156    if(totalSize == pPriv->fbSize)
2157    {
2158        ;
2159    }
2160    else
2161    {
2162        int lines, pitch, depth;
2163        BoxPtr pBox = NULL;
2164
2165        pPriv->fbSize = totalSize;
2166
2167        if(pPriv->fbAreaPtr)
2168        {
2169             xf86FreeOffscreenArea(pPriv->fbAreaPtr);
2170        }
2171
2172        depth = (pScrn->bitsPerPixel + 7 ) / 8;
2173        pitch = pScrn->displayWidth * depth;
2174        lines = ((totalSize * 2) / pitch) + 1;
2175        xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTPutImagelines=%x, pitch=%x, displayWidth=%x\n", lines, pitch, pScrn->displayWidth);
2176
2177
2178        pPriv->fbAreaPtr = xf86AllocateOffscreenArea(pScrn->pScreen,
2179                                 pScrn->displayWidth,
2180                                lines, 0, NULL, NULL, NULL);
2181
2182        if(!pPriv->fbAreaPtr)
2183        {
2184            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Allocate video memory fails\n");
2185            return BadAlloc;
2186        }
2187
2188        pBox = &(pPriv->fbAreaPtr->box);
2189        pPriv->bufAddr[0] = (pBox->y1 * pitch) + (pBox->x1 * depth);
2190        pPriv->bufAddr[1] = pPriv->bufAddr[0] + totalSize;
2191        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Put Image, pPriv->bufAddr[0]=0x%08X\n", pPriv->bufAddr[0]);
2192
2193    }
2194
2195    /* copy data */
2196    if(totalSize < 16)
2197    {
2198      #ifdef NewPath
2199        memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize);
2200      #else /* NewPath */
2201        switch(id)
2202        {
2203        case PIXEL_FMT_YUY2:
2204        case PIXEL_FMT_UYVY:
2205        case PIXEL_FMT_YVYU:
2206        {
2207             BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]);
2208             for(i=0; i<height; i++)
2209                  memcpy( Base + i * pPriv->srcPitch, buf + i*width*2, width*2);
2210             break;
2211        }
2212        default:
2213            memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize);
2214            break;
2215        } /* switch */
2216      #endif /* NewPath */
2217    }
2218    else
2219    {
2220        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Put Image, copy buf\n");
2221
2222      #ifdef NewPath
2223       	memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize);
2224      #else     /* NewPath */
2225        switch(id)
2226        {
2227        case PIXEL_FMT_YUY2:
2228        case PIXEL_FMT_UYVY:
2229        case PIXEL_FMT_YVYU:
2230        {
2231            BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]);
2232            for(i=0; i<height; i++)
2233                  memcpy( Base + i * pPriv->srcPitch, buf + i*width*2, width*2);
2234
2235            /*for(i=0; i<height; i++)
2236                for(j=0; j<width*2; j++)
2237                    *(Base+i*pPriv->srcPitch+j) = *(buf + width*i + j);*/
2238            break;
2239        }
2240        default:
2241        {    BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]);
2242            int j;
2243            for(i=0; i<height; i++)
2244                for(j=0; j<width; j++)
2245                   *(Base + width*i + j) = *(buf + width * i + j);
2246        break;
2247        }
2248        } /* end of switch */
2249      #endif    /* NewPath */
2250    }
2251
2252    ASTDisplayVideo(pScrn, pPriv, clipBoxes, id);
2253
2254    /* update cliplist
2255    if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))
2256    {
2257        REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
2258    }
2259    else
2260    {
2261        xf86XVFillKeyHelper(pScrn->pScreen, 0xFFFFFFFF, clipBoxes);
2262    }
2263    */
2264    pPriv->currentBuf ^= 1;
2265
2266    return Success;
2267}
2268
2269static XF86VideoAdaptorPtr ASTSetupImageVideo(ScreenPtr pScreen)
2270{
2271    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
2272    ASTPtr pAST = ASTPTR(pScrn);
2273    XF86VideoAdaptorPtr adapt;
2274    ASTPortPrivPtr pPriv;
2275
2276
2277    if(!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) +
2278                            sizeof(DevUnion) +
2279                            sizeof(ASTPortPrivRec))))
2280        return NULL;
2281
2282    adapt->type = XvWindowMask | XvInputMask | XvImageMask | XvVideoMask;
2283    adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
2284    adapt->name = "AST Video";
2285
2286    adapt->nEncodings = 1;
2287    adapt->pEncodings = &DummyEncoding;
2288
2289    adapt->nFormats = NUM_FORMATS;
2290    adapt->pFormats = ASTFormats;
2291    adapt->nPorts = 1;
2292    adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
2293
2294    pPriv = (ASTPortPrivPtr)(&adapt->pPortPrivates[1]);
2295
2296    adapt->pPortPrivates->ptr = (pointer)(pPriv);
2297    adapt->pAttributes = ASTAttributes;
2298    adapt->nAttributes = NUM_ATTRIBUTES;
2299	adapt->nImages = NUM_IMAGES;
2300    adapt->pImages = ASTImages;
2301
2302    adapt->PutVideo = NULL;
2303
2304    adapt->PutStill = NULL;
2305    adapt->GetVideo = NULL;
2306    adapt->GetStill = NULL;
2307    adapt->StopVideo = ASTStopVideo;
2308    adapt->SetPortAttribute = ASTSetPortAttribute;
2309    adapt->GetPortAttribute = ASTGetPortAttribute;
2310    adapt->QueryBestSize = ASTQueryBestSize;
2311    adapt->PutImage = ASTPutImage;
2312    adapt->QueryImageAttributes = ASTQueryImageAttributes;
2313
2314
2315    pPriv->currentBuf   = 0;
2316    pPriv->linear       = NULL;
2317    pPriv->fbAreaPtr    = NULL;
2318    pPriv->fbSize = 0;
2319	pPriv->videoStatus  = 0;
2320
2321    pPriv->colorKey     = 0x000101fe;
2322    pPriv->brightness   = 0;
2323    pPriv->contrast     = 128;
2324    pPriv->saturation   = 0;
2325    pPriv->hue          = 0;
2326
2327    /* gotta uninit this someplace */
2328#if defined(REGION_NULL)
2329    REGION_NULL(pScreen, &pPriv->clip);
2330#else
2331    REGION_INIT(pScreen, &pPriv->clip, NullBox, 0);
2332#endif
2333
2334	pAST->adaptor = adapt;
2335
2336	pAST->xvBrightness = MAKE_ATOM(astxvbrightness);
2337	pAST->xvContrast   = MAKE_ATOM(astxvcontrast);
2338	pAST->xvColorKey   = MAKE_ATOM(astxvcolorkey);
2339	pAST->xvSaturation = MAKE_ATOM(astxvsaturation);
2340	pAST->xvHue 	   = MAKE_ATOM(astxvhue);
2341	pAST->xvGammaRed   = MAKE_ATOM(astxvgammared);
2342    pAST->xvGammaGreen = MAKE_ATOM(astxvgammagreen);
2343    pAST->xvGammaBlue  = MAKE_ATOM(astxvgammablue);
2344
2345    return adapt;
2346}
2347
2348void ASTInitVideo(ScreenPtr pScreen)
2349{
2350    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
2351    XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
2352    XF86VideoAdaptorPtr ASTAdaptor = NULL;
2353    int num_adaptors;
2354
2355    ASTAdaptor = ASTSetupImageVideo(pScreen);
2356
2357    num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
2358
2359    if(ASTAdaptor)
2360    {
2361        if(!num_adaptors)
2362        {
2363            num_adaptors = 1;
2364            adaptors = &ASTAdaptor;
2365        }
2366        else
2367        {
2368            newAdaptors = malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));
2369            if(newAdaptors)
2370            {
2371                memcpy(newAdaptors, adaptors, num_adaptors *
2372                                        sizeof(XF86VideoAdaptorPtr));
2373                newAdaptors[num_adaptors] = ASTAdaptor;
2374                adaptors = newAdaptors;
2375                num_adaptors++;
2376            }
2377        }
2378    }
2379
2380    if(num_adaptors)
2381        xf86XVScreenInit(pScreen, adaptors, num_adaptors);
2382
2383    if(newAdaptors)
2384        free(newAdaptors);
2385
2386}
2387#endif /* AstVideo */
2388