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