ast_driver.c revision 621ff18c
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   /* Suport 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       /* Init VGA Adapter */
627       if (!xf86IsPrimaryPci(pAST->PciInfo))
628       {
629           ASTInitVGA(pScrn, 0);
630       }
631
632       vASTOpenKey(pScrn);
633       bASTRegInit(pScrn);
634
635       /* Get Chip Type */
636       if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x30)
637           pAST->jChipType = AST2400;
638       else if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x20)
639           pAST->jChipType = AST2300;
640       else if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x10)
641           ASTGetChipType(pScrn);
642       else
643           pAST->jChipType = AST2000;
644
645       /* Get Options from Scratch */
646       ASTGetScratchOptions(pScrn);
647
648       /* Get DRAM Info */
649       ASTGetDRAMInfo(pScrn);
650       pAST->ulVRAMSize = ASTGetVRAMInfo(pScrn);
651       pScrn->videoRam  = pAST->ulVRAMSize / 1024;
652   }
653
654   /* Map Framebuffer */
655   from = X_DEFAULT;
656   if (pAST->pEnt->device->videoRam) {
657      pScrn->videoRam = pAST->pEnt->device->videoRam;
658      from = X_CONFIG;
659   }
660
661   pAST->FbMapSize = pScrn->videoRam * 1024;
662
663#if 0
664   if (!ASTMapMem(pScrn)) {
665      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n");
666      return FALSE;
667   }
668#endif
669
670   pScrn->memPhysBase = (ULONG)pAST->FBPhysAddr;
671   pScrn->fbOffset = 0;
672
673   /* Do DDC
674    * should be done after xf86CollectOptions
675    */
676   pScrn->monitor->DDC = ASTDoDDC(pScrn, pAST->pEnt->index);
677
678   /* Mode Valid */
679   clockRanges = xnfcalloc(sizeof(ClockRange), 1);
680   clockRanges->next = NULL;
681   clockRanges->minClock = 9500;
682   clockRanges->maxClock = ASTGetMaxDCLK(pScrn) * 1000;
683   clockRanges->clockIndex = -1;
684   clockRanges->interlaceAllowed = FALSE;
685   clockRanges->doubleScanAllowed = FALSE;
686
687   /* Add for AST2100, ycchen@061807 */
688   if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST1180))
689   {
690       maxPitch  = 1920;
691       maxHeight = 1200;
692   }
693   else
694   {
695       maxPitch  = 1600;
696       maxHeight = 1200;
697   }
698
699   i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
700			 pScrn->display->modes, clockRanges,
701			 0, 320, maxPitch, 8 * pScrn->bitsPerPixel,
702			 200, maxHeight,
703			 pScrn->display->virtualX, pScrn->display->virtualY,
704			 pAST->FbMapSize, LOOKUP_BEST_REFRESH);
705
706   /* fixed some monitors can't get propery validate modes using estimated ratio modes */
707   if (i < 2)		/* validate modes are too few */
708   {
709       i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
710			     pScrn->display->modes, clockRanges,
711			     0, 320, maxPitch, 8 * pScrn->bitsPerPixel,
712			     200, maxHeight,
713			     pAST->mon_h_active, pAST->mon_v_active,
714			     pAST->FbMapSize, LOOKUP_BEST_REFRESH);
715   }
716
717   if (i == -1) {
718      ASTFreeRec(pScrn);
719      return FALSE;
720   }
721
722   xf86PruneDriverModes(pScrn);
723
724   if (!i || !pScrn->modes) {
725      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
726      ASTFreeRec(pScrn);
727      return FALSE;
728   }
729
730   xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
731
732   pScrn->currentMode = pScrn->modes;
733
734   xf86PrintModes(pScrn);
735
736   xf86SetDpi(pScrn, 0, 0);
737
738   /* Accelaration Check */
739   pAST->noAccel = TRUE;
740   pAST->pCMDQPtr = NULL;
741   pAST->CMDQInfo.ulCMDQSize 		= 0;
742   pAST->CMDQInfo.pjCmdQBasePort    = pAST->MMIOVirtualAddr+ 0x8044;
743   pAST->CMDQInfo.pjWritePort       = pAST->MMIOVirtualAddr+ 0x8048;
744   pAST->CMDQInfo.pjReadPort        = pAST->MMIOVirtualAddr+ 0x804C;
745   pAST->CMDQInfo.pjEngStatePort    = pAST->MMIOVirtualAddr+ 0x804C;
746#ifdef HAVE_XAA_H
747   pAST->AccelInfoPtr = NULL;
748#ifdef	Accel_2D
749   if (!xf86ReturnOptValBool(pAST->Options, OPTION_NOACCEL, FALSE))
750   {
751       if (xf86LoadSubModule(pScrn, "xaa")) {
752
753           pAST->noAccel = FALSE;
754           pAST->MMIO2D  = TRUE;
755#ifndef	MMIO_2D
756           if (!xf86ReturnOptValBool(pAST->Options, OPTION_MMIO2D, FALSE)) {
757	       pAST->CMDQInfo.ulCMDQSize = DEFAULT_CMDQ_SIZE;
758	       pAST->MMIO2D = FALSE;
759           }
760#endif
761
762           pAST->ENGCaps = ENG_CAP_ALL;
763           if (!xf86GetOptValInteger(pAST->Options, OPTION_ENG_CAPS, &pAST->ENGCaps)) {
764	       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No ENG Capability options found\n");
765           }
766
767           pAST->DBGSelect = 0;
768           if (!xf86GetOptValInteger(pAST->Options, OPTION_DBG_SELECT, &pAST->DBGSelect)) {
769	       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No DBG Seleclt options found\n");
770           }
771       }
772   }
773#endif
774#endif /* HAVE_XAA_H */
775
776   /* HW Cursor Check */
777   pAST->noHWC = TRUE;
778   pAST->HWCInfoPtr = NULL;
779   pAST->pHWCPtr = NULL;
780#ifdef	HWC
781   if (!xf86ReturnOptValBool(pAST->Options, OPTION_SW_CURSOR, FALSE)) {
782      if (!xf86LoadSubModule(pScrn, "ramdac")) {
783	 ASTFreeRec(pScrn);
784	 return FALSE;
785      }
786
787      pAST->noHWC = FALSE;
788      pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM;
789      if (!xf86GetOptValInteger(pAST->Options, OPTION_HWC_NUM, &pAST->HWCInfo.HWC_NUM)) {
790          xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No HWC_NUM options found\n");
791      }
792
793   }
794#endif
795
796   /* ShadowFB */
797#ifdef	Support_ShadowFB
798   pAST->shadowFB = FALSE;
799   if (pAST->noAccel == TRUE)	/* enable shadowFB only noAccel */
800   {
801       if (xf86ReturnOptValBool(pAST->Options, OPTION_SHADOW_FB, TRUE))
802       {
803	       if (xf86LoadSubModule(pScrn, "shadow")) {
804	          xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using \"Shadow Framebuffer\"\n");
805	          pAST->shadowFB = TRUE;
806	       }
807       }
808   }
809#endif
810
811#ifndef XSERVER_LIBPCIACCESS
812   /*  We won't be using the VGA access after the probe */
813   xf86SetOperatingState(resVgaIo, pAST->pEnt->index, ResUnusedOpr);
814   xf86SetOperatingState(resVgaMem, pAST->pEnt->index, ResDisableOpr);
815#endif
816
817   return TRUE;
818}
819
820
821static Bool
822ASTScreenInit(SCREEN_INIT_ARGS_DECL)
823{
824   ScrnInfoPtr pScrn;
825   ASTRecPtr pAST;
826   VisualPtr visual;
827   /* for FB Manager */
828   BoxRec FBMemBox;
829   int    AvailFBSize;
830
831   pScrn = xf86ScreenToScrn(pScreen);
832   pAST = ASTPTR(pScrn);
833
834   if (!ASTMapMem(pScrn)) {
835      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n");
836      return FALSE;
837   }
838
839/*   if (!pAST->noAccel) */
840   {
841       /* AvailFBSize = pAST->FbMapSize - pAST->CMDQInfo.ulCMDQSize; */
842       AvailFBSize = pAST->FbMapSize;
843
844       FBMemBox.x1 = 0;
845       FBMemBox.y1 = 0;
846       FBMemBox.x2 = pScrn->displayWidth;
847       FBMemBox.y2 = (AvailFBSize / (pScrn->displayWidth * ((pScrn->bitsPerPixel+1)/8))) - 1;
848
849       if (FBMemBox.y2 < 0)
850           FBMemBox.y2 = 32767;
851       if (FBMemBox.y2 < pScrn->virtualY)
852           return FALSE;
853
854       if (!xf86InitFBManager(pScreen, &FBMemBox)) {
855          xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n");
856          return FALSE;
857       }
858
859   }
860
861#if	!(defined(__sparc__)) && !(defined(__mips__))
862   vgaHWPtr hwp;
863   hwp = VGAHWPTR(pScrn);
864   vgaHWSetMmioFuncs(hwp, pAST->MMIOVirtualAddr, 0);
865#endif
866
867   vFillASTModeInfo (pScrn);
868
869   ASTSave(pScrn);
870   if (!ASTModeInit(pScrn, pScrn->currentMode)) {
871      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Mode Init Failed \n");
872      return FALSE;
873   }
874
875   ASTSaveScreen(pScreen, FALSE);
876   ASTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
877
878   miClearVisualTypes();
879
880   /* Re-implemented Direct Color support, -jens */
881   if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
882			 pScrn->rgbBits, pScrn->defaultVisual))
883      return FALSE;
884
885   if (!miSetPixmapDepths())
886   {
887       ASTSaveScreen(pScreen, SCREEN_SAVER_OFF);
888       return FALSE;
889   }
890
891   /* allocate shadowFB */
892#ifdef	Support_ShadowFB
893   pAST->shadowFB_validation = FALSE;
894   if (pAST->shadowFB) {
895      pAST->shadow = calloc(1, pScrn->displayWidth * pScrn->virtualY *
896				     ((pScrn->bitsPerPixel + 7) / 8));
897	  if (!pAST->shadow) {
898	     xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate shadow buffer\n");
899	  }
900	  else
901	     pAST->shadowFB_validation = TRUE;
902   }
903#endif
904
905   switch(pScrn->bitsPerPixel) {
906       case 8:
907       case 16:
908       case 32:
909#ifdef	Support_ShadowFB
910           if (!fbScreenInit(pScreen, pAST->shadowFB_validation ? pAST->shadow : (pAST->FBVirtualAddr + pScrn->fbOffset),
911  	                         pScrn->virtualX, pScrn->virtualY,
912		                     pScrn->xDpi, pScrn->yDpi,
913		                     pScrn->displayWidth, pScrn->bitsPerPixel))
914#else
915	       if (!fbScreenInit(pScreen, pAST->FBVirtualAddr + pScrn->fbOffset,
916			                 pScrn->virtualX, pScrn->virtualY,
917			                 pScrn->xDpi, pScrn->yDpi,
918			                 pScrn->displayWidth, pScrn->bitsPerPixel))
919#endif
920               return FALSE;
921           break;
922       default:
923           return FALSE;
924
925   }
926
927   if (pScrn->bitsPerPixel > 8) {
928      /* Fixup RGB ordering */
929      visual = pScreen->visuals + pScreen->numVisuals;
930      while (--visual >= pScreen->visuals) {
931	 if ((visual->class | DynamicClass) == DirectColor) {
932	    visual->offsetRed = pScrn->offset.red;
933	    visual->offsetGreen = pScrn->offset.green;
934	    visual->offsetBlue = pScrn->offset.blue;
935	    visual->redMask = pScrn->mask.red;
936	    visual->greenMask = pScrn->mask.green;
937	    visual->blueMask = pScrn->mask.blue;
938	 }
939      }
940   }
941
942   /* Must be after RGB order fixed */
943   fbPictureInit(pScreen, 0, 0);
944
945   /* shadowFB setup */
946#ifdef	Support_ShadowFB
947   if (pAST->shadowFB_validation) {
948      pAST->update = ASTUpdatePacked;
949	  pAST->window = ASTWindowLinear;
950
951      if (!shadowSetup(pScreen))
952      {
953	     xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to setup shadow buffer\n");
954	     return FALSE;
955      }
956
957	  pAST->CreateScreenResources = pScreen->CreateScreenResources;
958	  pScreen->CreateScreenResources = ASTCreateScreenResources;
959   }
960#endif
961
962   xf86SetBlackWhitePixels(pScreen);
963
964#ifdef HAVE_XAA_H
965#ifdef Accel_2D
966   if (!pAST->noAccel)
967   {
968       if (!ASTAccelInit(pScreen)) {
969           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware acceleration initialization failed\n");
970           pAST->noAccel = TRUE;
971       }
972   }
973#endif /* end of Accel_2D */
974#endif
975
976   xf86SetBackingStore(pScreen);
977   xf86SetSilkenMouse(pScreen);
978
979   miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
980
981   if (!pAST->noHWC)
982   {
983       if (!ASTCursorInit(pScreen)) {
984           xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware cursor initialization failed\n");
985           pAST->noHWC = TRUE;
986       }
987   }
988
989   if (!miCreateDefColormap(pScreen))
990      return FALSE;
991
992   if (pAST->jChipType != AST1180)
993   {
994       if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits,
995                               vASTLoadPalette, NULL,
996                               CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) {
997           return FALSE;
998       }
999   }
1000
1001   xf86DPMSInit(pScreen, ASTDisplayPowerManagementSet, 0);
1002
1003#ifdef AstVideo
1004   if ( (pAST->jChipType == AST1180) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) )
1005   {
1006       xf86DrvMsg(pScrn->scrnIndex, X_INFO,"AST Initial Video()\n");
1007       ASTInitVideo(pScreen);
1008   }
1009#endif
1010
1011   pScreen->SaveScreen = ASTSaveScreen;
1012   pAST->CloseScreen = pScreen->CloseScreen;
1013   pScreen->CloseScreen = ASTCloseScreen;
1014
1015   if (serverGeneration == 1)
1016      xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
1017
1018   return TRUE;
1019
1020} /* ASTScreenInit */
1021
1022
1023Bool
1024ASTSwitchMode(SWITCH_MODE_ARGS_DECL)
1025{
1026   SCRN_INFO_PTR(arg);
1027   ASTRecPtr pAST = ASTPTR(pScrn);
1028
1029   /* VideoMode validate */
1030   if (mode->CrtcHDisplay > pScrn->displayWidth)
1031       return FALSE;
1032   if ((pAST->VideoModeInfo.ScreenPitch * mode->CrtcVDisplay) > pAST->ulVRAMSize)
1033       return FALSE;
1034
1035   /* VideModeInfo Update */
1036   pAST->VideoModeInfo.ScreenWidth  = mode->CrtcHDisplay;
1037   pAST->VideoModeInfo.ScreenHeight = mode->CrtcVDisplay;
1038   pAST->VideoModeInfo.ScreenPitch  = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8) ;
1039
1040#ifdef	HWC
1041   if (pAST->pHWCPtr) {
1042       xf86FreeOffscreenLinear(pAST->pHWCPtr);		/* free HWC Cache */
1043       pAST->pHWCPtr = NULL;
1044   }
1045   ASTDisableHWC(pScrn);
1046#endif
1047
1048#ifdef Accel_2D
1049   if (pAST->pCMDQPtr) {
1050       xf86FreeOffscreenLinear(pAST->pCMDQPtr);		/* free CMDQ */
1051       pAST->pCMDQPtr = NULL;
1052   }
1053   vASTDisable2D(pScrn, pAST);
1054#endif
1055
1056   /* Fixed display abnormal on the of the screen if run xvidtune, ycchen@122909 */
1057   /* ASTRestore(pScrn); */
1058
1059   return ASTModeInit(pScrn, mode);
1060
1061}
1062
1063void
1064ASTAdjustFrame(ADJUST_FRAME_ARGS_DECL)
1065{
1066   SCRN_INFO_PTR(arg);
1067   ASTRecPtr   pAST  = ASTPTR(pScrn);
1068   ULONG base;
1069
1070   base = y * pAST->VideoModeInfo.ScreenPitch + x * ((pAST->VideoModeInfo.bitsPerPixel + 1) / 8);
1071   /* base = base >> 2; */			/* DW unit */
1072
1073   vASTSetStartAddressCRT1(pAST, base);
1074
1075}
1076
1077/* enter into X Server */
1078static Bool
1079ASTEnterVT(VT_FUNC_ARGS_DECL)
1080{
1081   SCRN_INFO_PTR(arg);
1082   ASTRecPtr pAST = ASTPTR(pScrn);
1083
1084   /* Fixed suspend can't resume issue */
1085   if (!bASTIsVGAEnabled(pScrn))
1086   {
1087       if (pAST->jChipType == AST1180)
1088           bASTInitAST1180(pScrn);
1089       else
1090       {
1091           vASTEnableVGAMMIO(pScrn);
1092           ASTInitVGA(pScrn, 1);
1093       }
1094       ASTRestore(pScrn);
1095   }
1096
1097   if (!ASTModeInit(pScrn, pScrn->currentMode))
1098      return FALSE;
1099   ASTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
1100
1101   return TRUE;
1102
1103}
1104
1105/* leave X server */
1106static void
1107ASTLeaveVT(VT_FUNC_ARGS_DECL)
1108{
1109
1110   SCRN_INFO_PTR(arg);
1111   ASTRecPtr pAST = ASTPTR(pScrn);
1112#if	!(defined(__sparc__)) && !(defined(__mips__))
1113   vgaHWPtr hwp = VGAHWPTR(pScrn);
1114#endif
1115
1116#ifdef	HWC
1117   if (pAST->pHWCPtr) {
1118       xf86FreeOffscreenLinear(pAST->pHWCPtr);		/* free HWC Cache */
1119       pAST->pHWCPtr = NULL;
1120   }
1121   ASTDisableHWC(pScrn);
1122#endif
1123
1124#ifdef Accel_2D
1125   if (pAST->pCMDQPtr) {
1126       xf86FreeOffscreenLinear(pAST->pCMDQPtr);		/* free CMDQ */
1127       pAST->pCMDQPtr = NULL;
1128   }
1129   vASTDisable2D(pScrn, pAST);
1130#endif
1131
1132   ASTRestore(pScrn);
1133
1134   if (pAST->jChipType == AST1180)
1135       ASTBlankScreen(pScrn, 0);
1136
1137#if	!(defined(__sparc__)) && !(defined(__mips__))
1138   vgaHWLock(hwp);
1139#endif
1140
1141}
1142
1143static void
1144ASTFreeScreen(FREE_SCREEN_ARGS_DECL)
1145{
1146   SCRN_INFO_PTR(arg);
1147   ASTFreeRec(pScrn);
1148#if	!(defined(__sparc__)) && !(defined(__mips__))
1149   if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
1150      vgaHWFreeHWRec(pScrn);
1151#endif
1152}
1153
1154static ModeStatus
1155ASTValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
1156{
1157   SCRN_INFO_PTR(arg);
1158   ASTRecPtr   pAST  = ASTPTR(pScrn);
1159   ModeStatus Flags = MODE_NOMODE;
1160   UCHAR jReg;
1161   ULONG RequestBufferSize;
1162
1163   if (mode->Flags & V_INTERLACE) {
1164      if (verbose) {
1165	 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1166		    "Removing interlaced mode \"%s\"\n", mode->name);
1167      }
1168      return MODE_NO_INTERLACE;
1169   }
1170
1171   if ((mode->CrtcHDisplay > MAX_HResolution) || (mode->CrtcVDisplay > MAX_VResolution)) {
1172      if (verbose) {
1173	 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
1174		    "Removing the mode \"%s\"\n", mode->name);
1175      }
1176      return Flags;
1177   }
1178
1179   /* Valid Framebuffer size */
1180   RequestBufferSize = mode->CrtcHDisplay * ((pScrn->bitsPerPixel + 1) / 8) * mode->CrtcVDisplay;
1181   if (RequestBufferSize > pAST->ulVRAMSize)
1182      return Flags;
1183
1184   /* Valid Wide Screen Mode */
1185   if (pAST->SupportWideScreen)
1186   {
1187      if ( (mode->CrtcHDisplay == 1680) && (mode->CrtcVDisplay == 1050) )
1188          return MODE_OK;
1189      if ( (mode->CrtcHDisplay == 1280) && (mode->CrtcVDisplay == 800) )
1190          return MODE_OK;
1191      if ( (mode->CrtcHDisplay == 1440) && (mode->CrtcVDisplay == 900) )
1192          return MODE_OK;
1193      if ( (mode->CrtcHDisplay == 1360) && (mode->CrtcVDisplay == 768) )
1194          return MODE_OK;
1195      if ( (mode->CrtcHDisplay == 1600) && (mode->CrtcVDisplay == 900) )
1196          return MODE_OK;
1197
1198      if ( (pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST1180) )
1199      {
1200          if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1080) )
1201              return MODE_OK;
1202
1203          if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1200) )
1204          {
1205             GetIndexRegMask(CRTC_PORT, 0xD1, 0xFF, jReg);
1206	     if (jReg & 0x01)
1207	        return MODE_NOMODE;
1208	     else
1209                return MODE_OK;
1210          }
1211      }
1212   }
1213
1214   switch (mode->CrtcHDisplay)
1215   {
1216   case 640:
1217       if (mode->CrtcVDisplay == 480) Flags=MODE_OK;
1218       break;
1219   case 800:
1220       if (mode->CrtcVDisplay == 600) Flags=MODE_OK;
1221       break;
1222   case 1024:
1223       if (mode->CrtcVDisplay == 768) Flags=MODE_OK;
1224       break;
1225   case 1280:
1226       if (mode->CrtcVDisplay == 1024) Flags=MODE_OK;
1227       break;
1228   case 1600:
1229       if (mode->CrtcVDisplay == 1200) Flags=MODE_OK;
1230       break;
1231   default:
1232       return Flags;
1233   }
1234
1235   return Flags;
1236}
1237
1238/* Internal used modules */
1239/*
1240 * ASTGetRec and ASTFreeRec --
1241 *
1242 * Private data for the driver is stored in the screen structure.
1243 * These two functions create and destroy that private data.
1244 *
1245 */
1246static Bool
1247ASTGetRec(ScrnInfoPtr pScrn)
1248{
1249   if (pScrn->driverPrivate)
1250      return TRUE;
1251
1252   pScrn->driverPrivate = xnfcalloc(sizeof(ASTRec), 1);
1253   return TRUE;
1254}
1255
1256static void
1257ASTFreeRec(ScrnInfoPtr pScrn)
1258{
1259   ASTRecPtr pAST = ASTPTR(pScrn);
1260
1261   if (!pScrn)
1262      return;
1263   if (!pScrn->driverPrivate)
1264      return;
1265   if (pAST->pDP501FWBufferVirtualAddress)
1266       free(pAST->pDP501FWBufferVirtualAddress);
1267   free(pScrn->driverPrivate);
1268   pScrn->driverPrivate = 0;
1269}
1270
1271static Bool
1272ASTSaveScreen(ScreenPtr pScreen, Bool unblack)
1273{
1274#if	!(defined(__sparc__)) && !(defined(__mips__))
1275   /* replacement of vgaHWBlankScreen(pScrn, unblank) without seq reset */
1276   /* return vgaHWSaveScreen(pScreen, unblack); */
1277   ScrnInfoPtr pScrn = NULL;
1278
1279   if (pScreen != NULL)
1280      pScrn = xf86ScreenToScrn(pScreen);
1281
1282   if ((pScrn != NULL) && pScrn->vtSema) {
1283     ASTBlankScreen(pScrn, unblack);
1284   }
1285   return (TRUE);
1286#endif
1287}
1288
1289static Bool
1290ASTCloseScreen(CLOSE_SCREEN_ARGS_DECL)
1291{
1292   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1293   ASTRecPtr pAST = ASTPTR(pScrn);
1294#if	!(defined(__sparc__)) && !(defined(__mips__))
1295   vgaHWPtr hwp = VGAHWPTR(pScrn);
1296#endif
1297
1298   if (pScrn->vtSema == TRUE)
1299   {
1300#ifdef	HWC
1301       if (pAST->pHWCPtr) {
1302           xf86FreeOffscreenLinear(pAST->pHWCPtr);		/* free HWC Cache */
1303           pAST->pHWCPtr = NULL;
1304       }
1305       ASTDisableHWC(pScrn);
1306#endif
1307
1308#ifdef Accel_2D
1309       if (pAST->pCMDQPtr) {
1310           xf86FreeOffscreenLinear(pAST->pCMDQPtr);		/* free CMDQ */
1311           pAST->pCMDQPtr = NULL;
1312       }
1313       vASTDisable2D(pScrn, pAST);
1314#endif
1315
1316       ASTRestore(pScrn);
1317
1318       if (pAST->jChipType == AST1180)
1319           ASTBlankScreen(pScrn, 0);
1320
1321#if	!(defined(__sparc__)) && !(defined(__mips__))
1322       vgaHWLock(hwp);
1323#endif
1324   }
1325
1326   ASTUnmapMem(pScrn);
1327#if	!(defined(__sparc__)) && !(defined(__mips__))
1328   vgaHWUnmapMem(pScrn);
1329#endif
1330
1331#ifdef HAVE_XAA_H
1332   if(pAST->AccelInfoPtr) {
1333       XAADestroyInfoRec(pAST->AccelInfoPtr);
1334       pAST->AccelInfoPtr = NULL;
1335   }
1336#endif
1337   if(pAST->HWCInfoPtr) {
1338       xf86DestroyCursorInfoRec(pAST->HWCInfoPtr);
1339       pAST->HWCInfoPtr = NULL;
1340   }
1341
1342#ifdef	Support_ShadowFB
1343   if (pAST->shadowFB_validation) {
1344      shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen));
1345	  free(pAST->shadow);
1346      pScreen->CreateScreenResources = pAST->CreateScreenResources;
1347   }
1348#endif
1349
1350   pScrn->vtSema = FALSE;
1351   pScreen->CloseScreen = pAST->CloseScreen;
1352   return (*pScreen->CloseScreen) (CLOSE_SCREEN_ARGS);
1353}
1354
1355static void
1356ASTSave(ScrnInfoPtr pScrn)
1357{
1358   ASTRecPtr pAST;
1359   ASTRegPtr astReg;
1360   int i, icount=0;
1361   ULONG ulData;
1362
1363   pAST = ASTPTR(pScrn);
1364   astReg = &pAST->SavedReg;
1365
1366   if (pAST->jChipType == AST1180)
1367   {
1368       for (i=0; i<12; i++)
1369       {
1370           ReadAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL+i*4, ulData);
1371           astReg->GFX[i] = ulData;
1372       }
1373   }
1374   else
1375   {
1376#if	defined(__sparc__) || defined(__mips__)
1377       UCHAR jReg;
1378
1379       /* Save Misc */
1380       astReg->MISC = GetReg(MISC_PORT_READ);
1381
1382       /* Save SR */
1383       for (i=0; i<4; i++)
1384           GetIndexReg(SEQ_PORT, (UCHAR) (i), astReg->SEQ[i]);
1385
1386       /* Save CR */
1387       for (i=0; i<25; i++)
1388           GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->CRTC[i]);
1389
1390       /* Save GR */
1391       for (i=0; i<9; i++)
1392           GetIndexReg(GR_PORT, (UCHAR) (i), astReg->GR[i]);
1393
1394       /* Save AR */
1395       jReg = GetReg(INPUT_STATUS1_READ);
1396       for (i=0; i<20; i++)
1397           GetIndexReg(AR_PORT_WRITE, (UCHAR) (i), astReg->AR[i]);
1398       jReg = GetReg(INPUT_STATUS1_READ);
1399       SetReg (AR_PORT_WRITE, 0x20);		/* set POS */
1400#else
1401       vgaRegPtr vgaReg;
1402       vgaReg = &VGAHWPTR(pScrn)->SavedReg;
1403
1404       /* do save */
1405       if (xf86IsPrimaryPci(pAST->PciInfo)) {
1406           vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_FONTS);
1407       }
1408       else {
1409           vgaHWSave(pScrn, vgaReg, VGA_SR_MODE);
1410       }
1411#endif
1412
1413       /* Save Ext. */
1414       vASTOpenKey(pScrn);
1415
1416       /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */
1417       for (i=0x81; i<=0xB6; i++)
1418           GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]);
1419       for (i=0xBC; i<=0xC1; i++)
1420           GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]);
1421       GetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]);
1422
1423       /* Save DAC */
1424       for (i=0; i<256; i++)
1425           VGA_GET_PALETTE_INDEX (i, astReg->DAC[i][0], astReg->DAC[i][1], astReg->DAC[i][2]);
1426
1427       /* Save 2D */
1428       astReg->ENG8044 = 0;
1429       GetIndexReg(CRTC_PORT, 0xA4, astReg->REGA4);
1430       if (astReg->REGA4 & 0x01)	/* 2D enabled */
1431           astReg->ENG8044 = *(ULONG *) (pAST->MMIOVirtualAddr + 0x8044);
1432   }
1433
1434}
1435
1436static void
1437ASTRestore(ScrnInfoPtr pScrn)
1438{
1439   ASTRecPtr pAST;
1440   ASTRegPtr astReg;
1441   int i, icount=0;
1442   ULONG ulData;
1443
1444   pAST = ASTPTR(pScrn);
1445   astReg = &pAST->SavedReg;
1446
1447   ASTDisplayPowerManagementSet(pScrn, DPMSModeOff, 0);
1448
1449   if (pAST->jChipType == AST1180)
1450   {
1451       for (i=0; i<12; i++)
1452       {
1453           ulData = astReg->GFX[i];
1454           WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL+i*4, ulData);
1455       }
1456   }
1457   else
1458   {
1459#if	defined(__sparc__) || defined(__mips__)
1460       UCHAR jReg;
1461
1462       /* Restore Misc */
1463       SetReg(MISC_PORT_WRITE, astReg->MISC);
1464
1465       /* Restore SR */
1466       for (i=0; i<4; i++)
1467           SetIndexReg(SEQ_PORT, (UCHAR) (i), astReg->SEQ[i]);
1468
1469       /* Restore CR */
1470       SetIndexRegMask(CRTC_PORT,0x11, 0x7F, 0x00);
1471       for (i=0; i<25; i++)
1472           SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->CRTC[i]);
1473
1474       /* Restore GR */
1475       for (i=0; i<9; i++)
1476           SetIndexReg(GR_PORT, (UCHAR) (i), astReg->GR[i]);
1477
1478       /* Restore AR */
1479       jReg = GetReg(INPUT_STATUS1_READ);
1480       for (i=0; i<20; i++)
1481       {
1482           SetReg(AR_PORT_WRITE, (UCHAR) i);
1483           SetReg(AR_PORT_WRITE, astReg->AR[i]);
1484       }
1485       SetReg(AR_PORT_WRITE, 0x14);
1486       SetReg(AR_PORT_WRITE, 0x00);
1487
1488       jReg = GetReg(INPUT_STATUS1_READ);
1489       SetReg (AR_PORT_WRITE, 0x20);		/* set POS */
1490#else
1491       vgaRegPtr vgaReg;
1492       vgaReg = &VGAHWPTR(pScrn)->SavedReg;
1493
1494       /* do restore */
1495       vgaHWProtect(pScrn, TRUE);
1496       if (xf86IsPrimaryPci(pAST->PciInfo))
1497           vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_FONTS);
1498       else
1499           vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
1500       vgaHWProtect(pScrn, FALSE);
1501#endif
1502
1503      /* Ext. restore */
1504      vASTOpenKey(pScrn);
1505
1506       /* Restore DAC */
1507       for (i=0; i<256; i++)
1508          VGA_LOAD_PALETTE_INDEX (i, astReg->DAC[i][0], astReg->DAC[i][1], astReg->DAC[i][2]);
1509
1510      /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */
1511      for (i=0x81; i<=0xB6; i++)
1512          SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]);
1513      for (i=0xBC; i<=0xC1; i++)
1514          SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]);
1515      SetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]);
1516   }
1517
1518}
1519
1520static void
1521ASTProbeDDC(ScrnInfoPtr pScrn, int index)
1522{
1523   ASTRecPtr pAST = ASTPTR(pScrn);
1524   unsigned char DDC_data[128];
1525   Bool Flags;
1526
1527   if (xf86LoadSubModule(pScrn, "ddc"))
1528   {
1529      if (pAST->jChipType == AST1180)
1530          Flags = ASTGetVGA2EDID(pScrn, DDC_data);
1531      else if (pAST->jTxChipType == Tx_DP501)
1532      {
1533          Flags = ASTReadEDID_M68K(pScrn, DDC_data);
1534          if (Flags == FALSE)
1535              Flags = ASTGetVGAEDID(pScrn, DDC_data);
1536      }
1537      else
1538          Flags = ASTGetVGAEDID(pScrn, DDC_data);
1539
1540      if (Flags)
1541      {
1542          ConfiguredMonitor = xf86InterpretEDID(pScrn->scrnIndex, DDC_data);
1543      }
1544      else
1545          xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTProbeDDC] Can't Get EDID Properly \n");
1546   }
1547   else
1548   {
1549      xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTProbeDDC] Can't Load DDC Sub-Modules or Read EDID Failed \n");
1550   }
1551
1552}
1553
1554#define SkipDT	0x00
1555#define DT1	0x01
1556#define DT2 	0x02
1557
1558static xf86MonPtr
1559ASTDoDDC(ScrnInfoPtr pScrn, int index)
1560{
1561   xf86MonPtr MonInfo = NULL;
1562   ASTRecPtr pAST = ASTPTR(pScrn);
1563   unsigned char DDC_data[128];
1564   Bool Flags;
1565
1566   xf86MonPtr MonInfo1 = NULL, MonInfo2 = NULL;
1567   unsigned long i, j, k;
1568   struct monitor_ranges ranges, ranges1, ranges2;
1569   int DTSelect, dclock1=0, h_active1=0, v_active1=0, dclock2=0, h_active2=0, v_active2=0;
1570   struct std_timings stdtiming, *stdtiming1, *stdtiming2;
1571
1572   /* Honour Option "noDDC" */
1573   if (xf86ReturnOptValBool(pAST->Options, OPTION_NO_DDC, FALSE)) {
1574      return MonInfo;
1575   }
1576
1577   if (xf86LoadSubModule(pScrn, "ddc"))
1578   {
1579      if (pAST->jChipType == AST1180)
1580          Flags = ASTGetVGA2EDID(pScrn, DDC_data);
1581      else if (pAST->jTxChipType == Tx_DP501)
1582      {
1583	      pAST->DP501_MaxVCLK = 0xFF;
1584          Flags = ASTReadEDID_M68K(pScrn, DDC_data);
1585          if (Flags) pAST->DP501_MaxVCLK = ASTGetLinkMaxCLK(pScrn);
1586          else
1587              Flags = ASTGetVGAEDID(pScrn, DDC_data);
1588      }
1589      else
1590          Flags = ASTGetVGAEDID(pScrn, DDC_data);
1591
1592      if (Flags)
1593      {
1594          MonInfo = MonInfo1 = xf86InterpretEDID(pScrn->scrnIndex, DDC_data);
1595
1596          /* Valid Wide Screen Support */
1597          if ( (MonInfo) && (MonInfo->det_mon[0].type == 0x00) )
1598          {
1599	          if ( (MonInfo->det_mon[0].section.d_timings.h_active * 10 / MonInfo->det_mon[0].section.d_timings.v_active) < 14 )
1600                  pAST->SupportWideScreen = FALSE;
1601          }
1602      }
1603
1604      /* For VGA2 CLONE Support, ycchen@012508 */
1605      if ((xf86ReturnOptValBool(pAST->Options, OPTION_VGA2_CLONE, FALSE)) || pAST->VGA2Clone) {
1606          if (ASTGetVGA2EDID(pScrn, DDC_data) == TRUE) {
1607              xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Get VGA2 EDID Correctly!! \n");
1608              MonInfo2 = xf86InterpretEDID(pScrn->scrnIndex, DDC_data);
1609              if (MonInfo1 == NULL)	/* No DDC1 EDID */
1610                  MonInfo = MonInfo2;
1611              else {			/* Check with VGA1 & VGA2 EDID */
1612                   /* Update establishment timing */
1613                   MonInfo->timings1.t1 = MonInfo1->timings1.t1 & MonInfo2->timings1.t1;
1614                   MonInfo->timings1.t2 = MonInfo1->timings1.t2 & MonInfo2->timings1.t2;
1615                   MonInfo->timings1.t_manu = MonInfo1->timings1.t_manu & MonInfo2->timings1.t_manu;
1616
1617                   /* Update Std. Timing */
1618                   for (i=0; i<8; i++) {
1619                       stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0;
1620                       for (j=0; j<8; j++) {
1621                           if ((MonInfo1->timings2[i].hsize == MonInfo2->timings2[j].hsize) && \
1622                               (MonInfo1->timings2[i].vsize == MonInfo2->timings2[j].vsize) && \
1623                               (MonInfo1->timings2[i].refresh == MonInfo2->timings2[j].refresh)) {
1624                                stdtiming = MonInfo1->timings2[i];
1625                                break;
1626                           }
1627                       }
1628
1629                       MonInfo->timings2[i] = stdtiming;
1630                   } /* Std. Timing */
1631
1632                   /* Get Detailed Timing */
1633                   for (i=0;i<4;i++) {
1634                      if (MonInfo1->det_mon[i].type == 0xFD)
1635                         ranges1 = MonInfo1->det_mon[i].section.ranges;
1636                      else if (MonInfo1->det_mon[i].type == 0xFA)
1637                         stdtiming1 = MonInfo1->det_mon[i].section.std_t;
1638                      else if (MonInfo1->det_mon[i].type == 0x00) {
1639                         if (MonInfo1->det_mon[i].section.d_timings.clock > dclock1)
1640                             dclock1 = MonInfo1->det_mon[i].section.d_timings.clock;
1641                         if (MonInfo1->det_mon[i].section.d_timings.h_active > h_active1)
1642                             h_active1 = MonInfo1->det_mon[i].section.d_timings.h_active;
1643                         if (MonInfo1->det_mon[i].section.d_timings.v_active > v_active1)
1644                             v_active1 = MonInfo1->det_mon[i].section.d_timings.v_active;
1645                      }
1646                      if (MonInfo2->det_mon[i].type == 0xFD)
1647                         ranges2 = MonInfo2->det_mon[i].section.ranges;
1648                      else if (MonInfo1->det_mon[i].type == 0xFA)
1649                         stdtiming2 = MonInfo2->det_mon[i].section.std_t;
1650                      else if (MonInfo2->det_mon[i].type == 0x00) {
1651                         if (MonInfo2->det_mon[i].section.d_timings.clock > dclock2)
1652                             dclock2 = MonInfo2->det_mon[i].section.d_timings.clock;
1653                         if (MonInfo2->det_mon[i].section.d_timings.h_active > h_active2)
1654                             h_active2 = MonInfo2->det_mon[i].section.d_timings.h_active;
1655                         if (MonInfo2->det_mon[i].section.d_timings.v_active > v_active2)
1656                             v_active2 = MonInfo2->det_mon[i].section.d_timings.v_active;
1657                      }
1658                   } /* Get Detailed Timing */
1659
1660                   /* Chk Detailed Timing */
1661                   if ((dclock1 >= dclock2) && (h_active1 >= h_active2) && (v_active1 >= v_active2))
1662                       DTSelect = DT2;
1663                   else if ((dclock2 >= dclock1) && (h_active2 >= h_active1) && (v_active2 >= v_active1))
1664                       DTSelect = DT1;
1665                   else
1666                       DTSelect = SkipDT;
1667
1668                   /* Chk Monitor Descriptor */
1669                   ranges = ranges1;
1670                   ranges.min_h = ranges1.min_h > ranges2.min_h ? ranges1.min_h:ranges2.min_h;
1671                   ranges.min_v = ranges1.min_v > ranges2.min_v ? ranges1.min_v:ranges2.min_v;
1672                   ranges.max_h = ranges1.max_h < ranges2.max_h ? ranges1.max_h:ranges2.max_h;
1673                   ranges.max_v = ranges1.max_v < ranges2.max_v ? ranges1.max_v:ranges2.max_v;
1674                   ranges.max_clock = ranges1.max_clock < ranges2.max_clock ? ranges1.max_clock:ranges2.max_clock;
1675
1676                   /* Update Detailed Timing */
1677                   for (i=0; i<4; i++)
1678                   {
1679                       if (MonInfo->det_mon[i].type == 0xFD) {
1680                           MonInfo->det_mon[i].section.ranges = ranges;
1681                       }
1682                       else if (MonInfo->det_mon[i].type == 0xFA) {
1683                           for (j=0; j<5; j++) {
1684         	                  stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0;
1685                               for (k=0; k<5; k++) {
1686                                   if ((stdtiming1[j].hsize == stdtiming2[k].hsize) && \
1687                                       (stdtiming1[j].vsize == stdtiming2[k].vsize) && \
1688                                       (stdtiming1[j].refresh == stdtiming2[k].refresh)) {
1689                                        stdtiming = stdtiming1[j];
1690                                        break;
1691                                   }
1692                               }
1693                               stdtiming1[j] = stdtiming;
1694                           } /* Std. Timing */
1695                       } /* FA */
1696                       else if (MonInfo->det_mon[i].type == 0x00) {
1697                           if (DTSelect == DT2)
1698                               MonInfo->det_mon[i] = MonInfo2->det_mon[i];
1699                           else if (DTSelect == DT1)
1700                               MonInfo->det_mon[i] = MonInfo1->det_mon[i];
1701                           else /* SkipDT */
1702                           {   /* use 1024x768 as default */
1703                               MonInfo->det_mon[i] = MonInfo1->det_mon[i];
1704                               MonInfo->det_mon[i].section.d_timings.clock = 65000000;
1705                               MonInfo->det_mon[i].section.d_timings.h_active = 1024;
1706                               MonInfo->det_mon[i].section.d_timings.h_blanking = 320;
1707                               MonInfo->det_mon[i].section.d_timings.v_active = 768;
1708                               MonInfo->det_mon[i].section.d_timings.v_blanking = 38;
1709                               MonInfo->det_mon[i].section.d_timings.h_sync_off = 24;
1710                               MonInfo->det_mon[i].section.d_timings.h_sync_width = 136;
1711                               MonInfo->det_mon[i].section.d_timings.v_sync_off = 3;
1712                               MonInfo->det_mon[i].section.d_timings.v_sync_width = 6;
1713                           }
1714                       } /* 00 */
1715                       else { /* use Monitor 1 as default */
1716                           MonInfo->det_mon[i] = MonInfo1->det_mon[i];
1717                       }
1718
1719                   } /* Update Detailed Timing */
1720
1721                   /* set feature size */
1722                   if (DTSelect == DT2)  {
1723                       MonInfo->features.hsize = MonInfo2->features.hsize;
1724                       MonInfo->features.vsize = MonInfo2->features.vsize;
1725                   }
1726                   else if (DTSelect == DT1)  {
1727                       MonInfo->features.hsize = MonInfo1->features.hsize;
1728                       MonInfo->features.vsize = MonInfo1->features.vsize;
1729                   }
1730                   else	/* Skip DT */
1731                   {   /* use 1024x768 as default */
1732                       MonInfo->features.hsize = 0x20;
1733                       MonInfo->features.vsize = 0x18;
1734                   }
1735
1736               } /* Check with VGA1 & VGA2 EDID */
1737
1738           } /* ASTGetVGA2EDID */
1739           else {
1740               xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Can't Get VGA2 EDID Correctly!! \n");
1741           }
1742      } /* VGA2Clone */
1743
1744      xf86PrintEDID(MonInfo);
1745      xf86SetDDCproperties(pScrn, MonInfo);
1746   }
1747   else
1748   {
1749      xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTDoDDC] Can't Load DDC Sub-Modules or Read EDID Failed \n");
1750   }
1751
1752   /* Fill pAST Monitor Info */
1753   if (MonInfo == NULL)
1754   {	/* default for Non-EDID */
1755       pAST->mon_h_active = 1024;
1756       pAST->mon_v_active = 768;
1757   }
1758   else
1759   {	/* save MonInfo to Private */
1760       pAST->mon_h_active = MonInfo->det_mon[0].section.d_timings.h_active;
1761       pAST->mon_v_active = MonInfo->det_mon[0].section.d_timings.v_active;
1762   }
1763
1764   return MonInfo;
1765}
1766
1767static void
1768vFillASTModeInfo (ScrnInfoPtr pScrn)
1769{
1770    ASTRecPtr pAST;
1771
1772    pAST = ASTPTR(pScrn);
1773
1774    pAST->VideoModeInfo.ScreenWidth = pScrn->virtualX;
1775    pAST->VideoModeInfo.ScreenHeight = pScrn->virtualY;
1776    pAST->VideoModeInfo.bitsPerPixel = pScrn->bitsPerPixel;
1777    /* Fixed screen pitch incorrect in some specific monitor, ycchen@071707 */
1778    pAST->VideoModeInfo.ScreenPitch = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8) ;
1779
1780}
1781
1782static Bool
1783ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
1784{
1785    ASTRecPtr pAST;
1786
1787    pAST = ASTPTR(pScrn);
1788
1789    pScrn->vtSema = TRUE;
1790    pAST->ModePtr = mode;
1791
1792#if	defined(__sparc__) || defined(__mips__)
1793    if (!ASTSetMode(pScrn, mode))
1794      return FALSE;
1795#else
1796    vgaHWPtr hwp;
1797
1798    hwp = VGAHWPTR(pScrn);
1799
1800    vgaHWUnlock(hwp);
1801
1802    if (!vgaHWInit(pScrn, mode))
1803      return FALSE;
1804
1805    pScrn->vtSema = TRUE;
1806    pAST->ModePtr = mode;
1807
1808    if (!ASTSetMode(pScrn, mode))
1809      return FALSE;
1810
1811    vgaHWProtect(pScrn, FALSE);
1812#endif
1813
1814    return TRUE;
1815}
1816
1817#ifdef AstVideo
1818/*
1819 * Video Part by ic_yang
1820 */
1821#include "fourcc.h"
1822
1823#define NUM_ATTRIBUTES  	8
1824#define NUM_IMAGES 		8
1825#define NUM_FORMATS     	3
1826
1827#define IMAGE_MIN_WIDTH         32
1828#define IMAGE_MIN_HEIGHT        24
1829#define IMAGE_MAX_WIDTH         1920
1830#define IMAGE_MAX_HEIGHT        1080
1831
1832#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
1833
1834static XF86ImageRec ASTImages[NUM_IMAGES] =
1835{
1836    XVIMAGE_YUY2, /* If order is changed, ASTOffscreenImages must be adapted */
1837};
1838
1839static XF86VideoFormatRec ASTFormats[NUM_FORMATS] =
1840{
1841   { 8, PseudoColor},
1842   {16, TrueColor},
1843   {24, TrueColor}
1844};
1845
1846/* client libraries expect an encoding */
1847static XF86VideoEncodingRec DummyEncoding =
1848{
1849   0,
1850   "XV_IMAGE",
1851   0, 0,                /* Will be filled in */
1852   {1, 1}
1853};
1854
1855static char astxvcolorkey[] 				= "XV_COLORKEY";
1856static char astxvbrightness[] 				= "XV_BRIGHTNESS";
1857static char astxvcontrast[] 				= "XV_CONTRAST";
1858static char astxvsaturation[] 				= "XV_SATURATION";
1859static char astxvhue[] 				        = "XV_HUE";
1860static char astxvgammared[] 				= "XV_GAMMA_RED";
1861static char astxvgammagreen[] 				= "XV_GAMMA_GREEN";
1862static char astxvgammablue[] 				= "XV_GAMMA_BLUE";
1863
1864static XF86AttributeRec ASTAttributes[NUM_ATTRIBUTES] =
1865{
1866   {XvSettable | XvGettable, 0, (1 << 24) - 1, astxvcolorkey},
1867   {XvSettable | XvGettable, -128, 127, astxvbrightness},
1868   {XvSettable | XvGettable, 0, 255, astxvcontrast},
1869   {XvSettable | XvGettable, -180, 180, astxvsaturation},
1870   {XvSettable | XvGettable, -180, 180, astxvhue},
1871   {XvSettable | XvGettable, 100, 10000, astxvgammared},
1872   {XvSettable | XvGettable, 100, 10000, astxvgammagreen},
1873   {XvSettable | XvGettable, 100, 10000, astxvgammablue},
1874};
1875
1876static void ASTStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit)
1877{
1878    ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data;
1879    ASTPtr pAST = ASTPTR(pScrn);
1880
1881    REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
1882
1883    if(exit)
1884    {
1885        if(pPriv->fbAreaPtr)
1886        {
1887            xf86FreeOffscreenArea(pPriv->fbAreaPtr);
1888            pPriv->fbAreaPtr = NULL;
1889            pPriv->fbSize = 0;
1890        }
1891        /* clear all flag */
1892        pPriv->videoStatus = 0;
1893    }
1894    else
1895    {
1896#if 0
1897        if(pPriv->videoStatus & CLIENT_VIDEO_ON)
1898        {
1899            pPriv->videoStatus |= OFF_TIMER;
1900
1901        }
1902#endif
1903    }
1904}
1905
1906static int ASTSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data)
1907{
1908    ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data;
1909    ASTPtr pAST = ASTPTR(pScrn);
1910
1911    xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTSetPortAttribute(),attribute=%x\n", attribute);
1912
1913    if (attribute == pAST->xvBrightness)
1914    {
1915        if((value < -128) || (value > 127))
1916         return BadValue;
1917
1918        pPriv->brightness = value;
1919    }
1920    else if (attribute == pAST->xvContrast)
1921    {
1922        if ((value < 0) || (value > 255))
1923         return BadValue;
1924
1925        pPriv->contrast = value;
1926    }
1927    else if (attribute == pAST->xvSaturation)
1928    {
1929        if ((value < -180) || (value > 180))
1930         return BadValue;
1931
1932        pPriv->saturation = value;
1933    }
1934    else if (attribute == pAST->xvHue)
1935    {
1936        if ((value < -180) || (value > 180))
1937         return BadValue;
1938
1939        pPriv->hue = value;
1940    }
1941    else if (attribute == pAST->xvColorKey)
1942    {
1943          pPriv->colorKey = value;
1944          REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
1945    }
1946    else if(attribute == pAST->xvGammaRed)
1947    {
1948        if((value < 100) || (value > 10000))
1949            return BadValue;
1950        pPriv->gammaR = value;
1951    }
1952    else if(attribute == pAST->xvGammaGreen)
1953    {
1954        if((value < 100) || (value > 10000))
1955            return BadValue;
1956        pPriv->gammaG = value;
1957    }
1958    else if(attribute == pAST->xvGammaBlue)
1959    {
1960        if((value < 100) || (value > 10000))
1961            return BadValue;
1962        pPriv->gammaB = value;
1963    }
1964    else
1965    {
1966        return BadMatch;
1967    }
1968
1969    return Success;
1970}
1971
1972static int ASTGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, pointer data)
1973{
1974    ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data;
1975    ASTPtr pAST = ASTPTR(pScrn);
1976
1977    xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTGetPortAttribute(),attribute=%x\n", attribute);
1978
1979    if (attribute == pAST->xvBrightness)
1980    {
1981        *value = pPriv->brightness;
1982    }
1983    else if (attribute == pAST->xvContrast)
1984    {
1985        *value = pPriv->contrast;
1986    }
1987    else if (attribute == pAST->xvSaturation)
1988    {
1989        *value = pPriv->saturation;
1990    }
1991    else if (attribute == pAST->xvHue)
1992    {
1993        *value = pPriv->hue;
1994    }
1995    else if(attribute == pAST->xvGammaRed)
1996    {
1997        *value = pPriv->gammaR;
1998
1999    }
2000    else if(attribute == pAST->xvGammaGreen)
2001    {
2002        *value = pPriv->gammaG;
2003    }
2004    else if(attribute == pAST->xvGammaBlue)
2005    {
2006        *value = pPriv->gammaB;
2007    }
2008    else if (attribute == pAST->xvColorKey)
2009    {
2010        *value = pPriv->colorKey;
2011    }
2012    else
2013        return BadMatch;
2014
2015    return Success;
2016}
2017
2018static void ASTQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
2019                                short vid_w, short vid_h,
2020                                short drw_w, short drw_h,
2021                                unsigned int *p_w, unsigned int *p_h,
2022                                pointer data)
2023{
2024    *p_w = drw_w;
2025    *p_h = drw_h;
2026    xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTQueryBestSize()\n");
2027  /* TODO: report the HW limitation */
2028}
2029
2030static int ASTQueryImageAttributes(ScrnInfoPtr pScrn, int id,
2031                                    unsigned short *w, unsigned short *h,
2032                                    int *pitches, int *offsets)
2033{
2034    int pitchY, pitchUV;
2035    int size, sizeY, sizeUV;
2036
2037    xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTQueryImageAttributes()\n");
2038
2039    if(*w < IMAGE_MIN_WIDTH) *w = IMAGE_MIN_WIDTH;
2040    if(*h < IMAGE_MIN_HEIGHT) *h = IMAGE_MIN_HEIGHT;
2041
2042    switch(id) {
2043    case PIXEL_FMT_YV12:
2044        *w = (*w + 7) & ~7;
2045        *h = (*h + 1) & ~1;
2046        pitchY = *w;
2047        pitchUV = *w >> 1;
2048        if(pitches) {
2049          pitches[0] = pitchY;
2050          pitches[1] = pitches[2] = pitchUV;
2051        }
2052        sizeY = pitchY * (*h);
2053        sizeUV = pitchUV * ((*h) >> 1);
2054        if(offsets) {
2055          offsets[0] = 0;
2056          offsets[1] = sizeY;
2057          offsets[2] = sizeY + sizeUV;
2058        }
2059        size = sizeY + (sizeUV << 1);
2060        break;
2061    case PIXEL_FMT_NV12:
2062    case PIXEL_FMT_NV21:
2063        *w = (*w + 7) & ~7;
2064        *h = (*h + 1) & ~1;
2065		pitchY = *w;
2066    	pitchUV = *w;
2067    	if(pitches) {
2068      	    pitches[0] = pitchY;
2069            pitches[1] = pitchUV;
2070        }
2071    	sizeY = pitchY * (*h);
2072    	sizeUV = pitchUV * ((*h) >> 1);
2073    	if(offsets) {
2074          offsets[0] = 0;
2075          offsets[1] = sizeY;
2076        }
2077        size = sizeY + (sizeUV << 1);
2078        break;
2079    case PIXEL_FMT_YUY2:
2080    case PIXEL_FMT_UYVY:
2081    case PIXEL_FMT_YVYU:
2082    case PIXEL_FMT_RGB6:
2083    case PIXEL_FMT_RGB5:
2084    default:
2085        *w = (*w + 1) & ~1;
2086        pitchY = *w << 1;
2087        if(pitches) pitches[0] = pitchY;
2088        if(offsets) offsets[0] = 0;
2089        size = pitchY * (*h);
2090        break;
2091    }
2092
2093    return size;
2094}
2095
2096static int ASTPutImage(ScrnInfoPtr pScrn,
2097                          short src_x, short src_y,
2098                          short drw_x, short drw_y,
2099                          short src_w, short src_h,
2100                          short drw_w, short drw_h,
2101                          int id, unsigned char* buf,
2102                          short width, short height,
2103                          Bool sync,
2104                          RegionPtr clipBoxes, pointer data
2105#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1
2106		          , DrawablePtr pDraw
2107#endif
2108)
2109{
2110    ASTPtr pAST = ASTPTR(pScrn);
2111    ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data;
2112    int i;
2113    int totalSize=0;
2114
2115    xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTPutImage()\n");
2116    /*   int depth = pAST->CurrentLayout.bitsPerPixel >> 3; */
2117
2118    pPriv->drw_x = drw_x;
2119    pPriv->drw_y = drw_y;
2120    pPriv->drw_w = drw_w;
2121    pPriv->drw_h = drw_h;
2122    pPriv->src_x = src_x;
2123    pPriv->src_y = src_y;
2124    pPriv->src_w = src_w;
2125    pPriv->src_h = src_h;
2126    pPriv->id = id;
2127    pPriv->height = height;
2128
2129    switch(id)
2130    {
2131    case PIXEL_FMT_YV12:
2132    case PIXEL_FMT_NV12:
2133    case PIXEL_FMT_NV21:
2134        pPriv->srcPitch = (width + 7) & ~7;
2135        totalSize = (pPriv->srcPitch * height * 3) >> 1; /* Verified */
2136    break;
2137    case PIXEL_FMT_YUY2:
2138    case PIXEL_FMT_UYVY:
2139    case PIXEL_FMT_YVYU:
2140    case PIXEL_FMT_RGB6:
2141    case PIXEL_FMT_RGB5:
2142    default:
2143        pPriv->srcPitch = ((width << 1) + 3) & ~3;	/* Verified */
2144        totalSize = pPriv->srcPitch * height;
2145    }
2146
2147    totalSize += 15;
2148    totalSize &= ~15;
2149    /* allocate memory */
2150
2151    if(totalSize == pPriv->fbSize)
2152    {
2153        ;
2154    }
2155    else
2156    {
2157        int lines, pitch, depth;
2158        BoxPtr pBox = NULL;
2159
2160        pPriv->fbSize = totalSize;
2161
2162        if(pPriv->fbAreaPtr)
2163        {
2164             xf86FreeOffscreenArea(pPriv->fbAreaPtr);
2165        }
2166
2167        depth = (pScrn->bitsPerPixel + 7 ) / 8;
2168        pitch = pScrn->displayWidth * depth;
2169        lines = ((totalSize * 2) / pitch) + 1;
2170        xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTPutImagelines=%x, pitch=%x, displayWidth=%x\n", lines, pitch, pScrn->displayWidth);
2171
2172
2173        pPriv->fbAreaPtr = xf86AllocateOffscreenArea(pScrn->pScreen,
2174                                 pScrn->displayWidth,
2175                                lines, 0, NULL, NULL, NULL);
2176
2177        if(!pPriv->fbAreaPtr)
2178        {
2179            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Allocate video memory fails\n");
2180            return BadAlloc;
2181        }
2182
2183        pBox = &(pPriv->fbAreaPtr->box);
2184        pPriv->bufAddr[0] = (pBox->y1 * pitch) + (pBox->x1 * depth);
2185        pPriv->bufAddr[1] = pPriv->bufAddr[0] + totalSize;
2186        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Put Image, pPriv->bufAddr[0]=0x%08X\n", pPriv->bufAddr[0]);
2187
2188    }
2189
2190    /* copy data */
2191    if(totalSize < 16)
2192    {
2193      #ifdef NewPath
2194        memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize);
2195      #else /* NewPath */
2196        switch(id)
2197        {
2198        case PIXEL_FMT_YUY2:
2199        case PIXEL_FMT_UYVY:
2200        case PIXEL_FMT_YVYU:
2201        {
2202             BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]);
2203             for(i=0; i<height; i++)
2204                  memcpy( Base + i * pPriv->srcPitch, buf + i*width*2, width*2);
2205             break;
2206        }
2207        default:
2208            memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize);
2209            break;
2210        } /* switch */
2211      #endif /* NewPath */
2212    }
2213    else
2214    {
2215        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Put Image, copy buf\n");
2216
2217      #ifdef NewPath
2218       	memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize);
2219      #else     /* NewPath */
2220        switch(id)
2221        {
2222        case PIXEL_FMT_YUY2:
2223        case PIXEL_FMT_UYVY:
2224        case PIXEL_FMT_YVYU:
2225        {
2226            BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]);
2227            for(i=0; i<height; i++)
2228                  memcpy( Base + i * pPriv->srcPitch, buf + i*width*2, width*2);
2229
2230            /*for(i=0; i<height; i++)
2231                for(j=0; j<width*2; j++)
2232                    *(Base+i*pPriv->srcPitch+j) = *(buf + width*i + j);*/
2233            break;
2234        }
2235        default:
2236        {    BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]);
2237            int j;
2238            for(i=0; i<height; i++)
2239                for(j=0; j<width; j++)
2240                   *(Base + width*i + j) = *(buf + width * i + j);
2241        break;
2242        }
2243        } /* end of switch */
2244      #endif    /* NewPath */
2245    }
2246
2247    ASTDisplayVideo(pScrn, pPriv, clipBoxes, id);
2248
2249    /* update cliplist
2250    if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))
2251    {
2252        REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
2253    }
2254    else
2255    {
2256        xf86XVFillKeyHelper(pScrn->pScreen, 0xFFFFFFFF, clipBoxes);
2257    }
2258    */
2259    pPriv->currentBuf ^= 1;
2260
2261    return Success;
2262}
2263
2264static XF86VideoAdaptorPtr ASTSetupImageVideo(ScreenPtr pScreen)
2265{
2266    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
2267    ASTPtr pAST = ASTPTR(pScrn);
2268    XF86VideoAdaptorPtr adapt;
2269    ASTPortPrivPtr pPriv;
2270
2271
2272    if(!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) +
2273                            sizeof(DevUnion) +
2274                            sizeof(ASTPortPrivRec))))
2275        return NULL;
2276
2277    adapt->type = XvWindowMask | XvInputMask | XvImageMask | XvVideoMask;
2278    adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
2279    adapt->name = "AST Video";
2280
2281    adapt->nEncodings = 1;
2282    adapt->pEncodings = &DummyEncoding;
2283
2284    adapt->nFormats = NUM_FORMATS;
2285    adapt->pFormats = ASTFormats;
2286    adapt->nPorts = 1;
2287    adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
2288
2289    pPriv = (ASTPortPrivPtr)(&adapt->pPortPrivates[1]);
2290
2291    adapt->pPortPrivates->ptr = (pointer)(pPriv);
2292    adapt->pAttributes = ASTAttributes;
2293    adapt->nAttributes = NUM_ATTRIBUTES;
2294	adapt->nImages = NUM_IMAGES;
2295    adapt->pImages = ASTImages;
2296
2297    adapt->PutVideo = NULL;
2298
2299    adapt->PutStill = NULL;
2300    adapt->GetVideo = NULL;
2301    adapt->GetStill = NULL;
2302    adapt->StopVideo = ASTStopVideo;
2303    adapt->SetPortAttribute = ASTSetPortAttribute;
2304    adapt->GetPortAttribute = ASTGetPortAttribute;
2305    adapt->QueryBestSize = ASTQueryBestSize;
2306    adapt->PutImage = ASTPutImage;
2307    adapt->QueryImageAttributes = ASTQueryImageAttributes;
2308
2309
2310    pPriv->currentBuf   = 0;
2311    pPriv->linear       = NULL;
2312    pPriv->fbAreaPtr    = NULL;
2313    pPriv->fbSize = 0;
2314	pPriv->videoStatus  = 0;
2315
2316    pPriv->colorKey     = 0x000101fe;
2317    pPriv->brightness   = 0;
2318    pPriv->contrast     = 128;
2319    pPriv->saturation   = 0;
2320    pPriv->hue          = 0;
2321
2322    /* gotta uninit this someplace */
2323#if defined(REGION_NULL)
2324    REGION_NULL(pScreen, &pPriv->clip);
2325#else
2326    REGION_INIT(pScreen, &pPriv->clip, NullBox, 0);
2327#endif
2328
2329	pAST->adaptor = adapt;
2330
2331	pAST->xvBrightness = MAKE_ATOM(astxvbrightness);
2332	pAST->xvContrast   = MAKE_ATOM(astxvcontrast);
2333	pAST->xvColorKey   = MAKE_ATOM(astxvcolorkey);
2334	pAST->xvSaturation = MAKE_ATOM(astxvsaturation);
2335	pAST->xvHue 	   = MAKE_ATOM(astxvhue);
2336	pAST->xvGammaRed   = MAKE_ATOM(astxvgammared);
2337    pAST->xvGammaGreen = MAKE_ATOM(astxvgammagreen);
2338    pAST->xvGammaBlue  = MAKE_ATOM(astxvgammablue);
2339
2340    return adapt;
2341}
2342
2343void ASTInitVideo(ScreenPtr pScreen)
2344{
2345    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
2346    XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
2347    XF86VideoAdaptorPtr ASTAdaptor = NULL;
2348    int num_adaptors;
2349
2350    ASTAdaptor = ASTSetupImageVideo(pScreen);
2351
2352    num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
2353
2354    if(ASTAdaptor)
2355    {
2356        if(!num_adaptors)
2357        {
2358            num_adaptors = 1;
2359            adaptors = &ASTAdaptor;
2360        }
2361        else
2362        {
2363            newAdaptors = malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));
2364            if(newAdaptors)
2365            {
2366                memcpy(newAdaptors, adaptors, num_adaptors *
2367                                        sizeof(XF86VideoAdaptorPtr));
2368                newAdaptors[num_adaptors] = ASTAdaptor;
2369                adaptors = newAdaptors;
2370                num_adaptors++;
2371            }
2372        }
2373    }
2374
2375    if(num_adaptors)
2376        xf86XVScreenInit(pScreen, adaptors, num_adaptors);
2377
2378    if(newAdaptors)
2379        free(newAdaptors);
2380
2381}
2382#endif /* AstVideo */
2383