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