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