diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast.h | 62 | ||||
-rw-r--r-- | src/ast_2dtool.c | 27 | ||||
-rw-r--r-- | src/ast_2dtool.h | 88 | ||||
-rw-r--r-- | src/ast_accel.c | 171 | ||||
-rw-r--r-- | src/ast_cursor.c | 170 | ||||
-rw-r--r-- | src/ast_driver.c | 1179 | ||||
-rw-r--r-- | src/ast_mode.c | 424 | ||||
-rw-r--r-- | src/ast_mode.h | 1 | ||||
-rw-r--r-- | src/ast_vgatool.c | 1785 | ||||
-rw-r--r-- | src/ast_vgatool.h | 88 |
10 files changed, 3534 insertions, 461 deletions
@@ -29,6 +29,7 @@ #define Accel_2D /* #define MMIO_2D */ #define HWC +#define AstVideo /* #define PATCH_ABI_VERSION */ /* Vendor & Device Info */ @@ -44,6 +45,10 @@ #define PCI_CHIP_AST2100 0x2010 #endif +#ifndef PCI_CHIP_AST1180 +#define PCI_CHIP_AST1180 0x1180 +#endif + typedef enum _CHIP_ID { VGALegacy, AST2000, @@ -51,7 +56,8 @@ typedef enum _CHIP_ID { AST1100, AST2200, AST2150, - AST2300 + AST2300, + AST1180 } CHIP_ID; /* AST REC Info */ @@ -83,7 +89,7 @@ typedef CARD32 ULONG; /* Data Structure Definition */ typedef struct _ASTRegRec { UCHAR ExtCRTC[0x50]; - + ULONG GFX[12]; } ASTRegRec, *ASTRegPtr; typedef struct _VIDEOMODE { @@ -138,6 +144,41 @@ typedef struct { } HWCINFO, *PHWCINFO; +typedef struct _ASTPortPrivRec{ + FBLinearPtr linear; + FBAreaPtr fbAreaPtr; + int fbSize; + CARD32 bufAddr[2]; + + unsigned char currentBuf; + + short drw_x, drw_y, drw_w, drw_h; + short src_x, src_y, src_w, src_h; + int id; + short srcPitch, height; + + INT32 brightness; + INT32 contrast; + INT32 saturation; + INT32 hue; + + INT32 gammaR; + INT32 gammaG; + INT32 gammaB; + + RegionRec clip; + CARD32 colorKey; + + CARD32 videoStatus; + Time offTime; + Time freeTime; + + CARD32 displayMode; + + int pitch; + int offset; +} ASTPortPrivRec, *ASTPortPrivPtr; + typedef struct _ASTRec { EntityInfoPtr pEnt; @@ -160,6 +201,11 @@ typedef struct _ASTRec { UCHAR jChipType; UCHAR jDRAMType; + ULONG ulDRAMBusWidth ; + ULONG ulDRAMSize; + ULONG ulVRAMSize; + ULONG ulVRAMBase; + ULONG ulMCLK; Bool noAccel; Bool noHWC; @@ -193,9 +239,15 @@ typedef struct _ASTRec { int clip_top; int clip_right; int clip_bottom; - -} ASTRec, *ASTRecPtr; - + +#ifdef AstVideo + XF86VideoAdaptorPtr adaptor; + Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation; + Atom xvGammaRed, xvGammaGreen, xvGammaBlue; +#endif + +} ASTRec, *ASTRecPtr, *ASTPtr; + #define ASTPTR(p) ((ASTRecPtr)((p)->driverPrivate)) /* Include Files */ diff --git a/src/ast_2dtool.c b/src/ast_2dtool.c index 61f549c..7e54370 100644 --- a/src/ast_2dtool.c +++ b/src/ast_2dtool.c @@ -272,10 +272,12 @@ bEnable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST) ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x1200c); *(ULONG *) (pAST->MMIOVirtualAddr + 0x1200c) = (ulData & 0xFFFFFFFD); + + case AST2000: + SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x01); /* enable 2D */ + break; } - - SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x01); /* enable 2D */ if (!bInitCMDQInfo(pScrn, pAST)) { @@ -299,7 +301,8 @@ vDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST) vWaitEngIdle(pScrn, pAST); vWaitEngIdle(pScrn, pAST); - SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x00); + if (pAST->jChipType != AST1180) + SetIndexRegMask(CRTC_PORT, 0xA4, 0xFE, 0x00); } @@ -315,14 +318,18 @@ vWaitEngIdle(ScrnInfoPtr pScrn, ASTRecPtr pAST) ulEngCheckSetting = 0x10000000; else ulEngCheckSetting = 0x80000000; + + if (pAST->jChipType != AST1180) + { + + /* 2D disable if 0xA4 D[0] = 1 */ + GetIndexRegMask(CRTC_PORT, 0xA4, 0x01, jReg); + if (!jReg) goto Exit_vWaitEngIdle; - /* 2D disable if 0xA4 D[0] = 1 */ - GetIndexRegMask(CRTC_PORT, 0xA4, 0x01, jReg); - if (!jReg) goto Exit_vWaitEngIdle; - - /* 2D not work if in std. mode */ - GetIndexRegMask(CRTC_PORT, 0xA3, 0x0F, jReg); - if (!jReg) goto Exit_vWaitEngIdle; + /* 2D not work if in std. mode */ + GetIndexRegMask(CRTC_PORT, 0xA3, 0x0F, jReg); + if (!jReg) goto Exit_vWaitEngIdle; + } do { diff --git a/src/ast_2dtool.h b/src/ast_2dtool.h index 9af388b..5bc437f 100644 --- a/src/ast_2dtool.h +++ b/src/ast_2dtool.h @@ -47,8 +47,18 @@ #define CMD_QUEUE_SIZE_2M 0x00200000 #define CMD_QUEUE_SIZE_4M 0x00400000 +#define PIXEL_FMT_YV12 FOURCC_YV12 /* 0x32315659 */ +#define PIXEL_FMT_UYVY FOURCC_UYVY /* 0x59565955 */ +#define PIXEL_FMT_YUY2 FOURCC_YUY2 /* 0x32595559 */ +#define PIXEL_FMT_RGB5 0x35315652 +#define PIXEL_FMT_RGB6 0x36315652 +#define PIXEL_FMT_YVYU 0x55595659 +#define PIXEL_FMT_NV12 0x3231564e +#define PIXEL_FMT_NV21 0x3132564e + /* CMD Type Info */ #define PKT_NULL_CMD 0x00009561 +#define PKT_BURST_CMD_HEADER0 0x00009564 #define PKT_SINGLE_LENGTH 8 #define PKT_SINGLE_CMD_HEADER 0x00009562 @@ -60,6 +70,70 @@ typedef struct _PKT_SC } PKT_SC, *PPKT_SC; +/* Packet CMD Scale */ +#define PKT_TYPESCALE_LENGTH 56 +#define PKT_TYPESCALE_DATALENGTH (0xC<<16) +#define PKT_TYPESCALE_ADDRSTART 0x00000000 + +typedef struct _BURSTSCALECMD +{ + ULONG dwHeader0; + ULONG dwSrcBaseAddr; /* 8000 */ + union + { + struct + { + USHORT wSrcDummy; /* 8004 */ + USHORT wSrcPitch; /* 8006 */ + }; + ULONG dwSrcPitch; /* 8004 */ + }; + ULONG dwDstBaseAddr; /* 8008 */ + union + { + struct + { + USHORT wDstHeight; /* 800C */ + USHORT wDstPitch; /* 800E */ + }; + ULONG dwDstHeightPitch; /* 800C */ + }; + union + { + struct + { + short wDstY; /* 8010 */ + short wDstX; /* 8012 */ + }; + ULONG dwDstXY; /* 8010 */ + }; + union + { + struct + { + short wSrcY; /* 8014 */ + short wSrcX; /* 8016 */ + }; + ULONG dwSrcXY; /* 8014 */ + }; + union + { + struct + { + USHORT wRecHeight; /* 8018 */ + USHORT wRecWidth; /* 801A */ + }; + ULONG dwRecHeightWidth; /* 8018 */ + }; + ULONG dwInitScaleFactorH; /* 801C */ + ULONG dwInitScaleFactorV; /* 8020 */ + ULONG dwScaleFactorH; /* 8024 */ + ULONG dwScaleFactorV; /* 8028 */ + + ULONG dwCmd; /* 823C */ + ULONG NullData[1]; +} BURSTSCALECMD, *PBURSTSCALECMD; + /* Eng Reg. Limitation */ #define MAX_SRC_X 0x7FF #define MAX_SRC_Y 0x7FF @@ -153,6 +227,7 @@ typedef struct _PKT_SC #define CMD_COLOREXP 0x00000002 #define CMD_ENHCOLOREXP 0x00000003 #define CMD_TRANSPARENTBLT 0x00000004 +#define CMD_TYPE_SCALE 0x00000005 #define CMD_MASK 0x00000007 #define CMD_DISABLE_CLIP 0x00000000 @@ -193,6 +268,19 @@ typedef struct _PKT_SC #define BURST_FORCE_CMD 0x80000000 +#define YUV_FORMAT_YUYV (0UL<<12) +#define YUV_FORMAT_YVYU (1UL<<12) +#define YUV_FORMAT_UYVY (2UL<<12) +#define YUV_FORMAT_VYUY (3UL<<12) + +#define SCALE_FORMAT_RGB2RGB (0UL<<14) +#define SCALE_FORMAT_YUV2RGB (1UL<<14) +#define SCALE_FORMAT_RGB2RGB_DOWN (2UL<<14) /* RGB32 to RGB16 */ +#define SCALE_FORMAT_RGB2RGB_UP (3UL<<14) /* RGB16 to RGB32 */ +#define SCALE_SEG_NUM_1 (0x3FUL<<24) /* DstWi >= SrcWi */ +#define SCALE_SEG_NUM_2 (0x1FUL<<24) /* DstWi < SrcWi */ +#define SCALE_EQUAL_VER (0x1UL<<23) + /* Line */ #define LINEPARAM_XM 0x00000001 #define LINEPARAM_X_DEC 0x00000002 diff --git a/src/ast_accel.c b/src/ast_accel.c index ad8f1b1..2d3dab3 100644 --- a/src/ast_accel.c +++ b/src/ast_accel.c @@ -195,7 +195,7 @@ ASTAccelInit(ScreenPtr pScreen) /* Solid Lines */ if (pAST->ENGCaps & ENG_CAP_SolidLine) { - if (pAST->jChipType == AST2300) + if ( (pAST->jChipType == AST2300) || (pAST->jChipType == AST1180) ) { infoPtr->SubsequentSolidTwoPointLine = AIPSubsequentSolidTwoPointLine; } @@ -212,7 +212,7 @@ ASTAccelInit(ScreenPtr pScreen) /* Dashed Lines */ if (pAST->ENGCaps & ENG_CAP_DashedLine) { - if (pAST->jChipType == AST2300) + if ( (pAST->jChipType == AST2300) || (pAST->jChipType == AST1180) ) { infoPtr->SubsequentDashedTwoPointLine = AIPSubsequentDashedTwoPointLine; } @@ -1127,7 +1127,7 @@ ASTSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, pAST->ulCMDReg = cmdreg; cpp = (pScrn->bitsPerPixel + 1) / 8; pataddr = (CARD32 *)(pAST->FBVirtualAddr + - (paty * pAST->VideoModeInfo.ScreenWidth) + (patx * cpp)); + (paty * pAST->VideoModeInfo.ScreenPitch) + (patx * cpp)); ulPatSize = 8*8*cpp; if (!pAST->MMIO2D) @@ -1685,4 +1685,169 @@ AIPSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, } +#ifdef AstVideo +/* + * Video Part + * by ic_yang + */ +#include "fourcc.h" + +void ASTDisplayVideo(ScrnInfoPtr pScrn, ASTPortPrivPtr pPriv, RegionPtr clipBoxes, int id) +{ + ASTPtr pAST = ASTPTR(pScrn); + int nBoxs; + int ScaleFactorH, ScaleFactorV; + ULONG InitScaleFactorH, InitScaleFactorV; + BURSTSCALECMD CopyCmd = {0}; + PBURSTSCALECMD pCopyCmd = NULL; + float fScaleX = 0, fScaleY = 0; + xRectangle rect; + BoxPtr pBox = NULL; + short lSrcX, lSrcY; + ULONG dwCmd = 0; + int i; + + pBox = REGION_RECTS(clipBoxes); + nBoxs = REGION_NUM_RECTS(clipBoxes); + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MMIO=%x,pBox=%x, nBoxs=%x\n", pAST->MMIO2D, pBox, nBoxs); + + if(0==pPriv->drw_w || 0==pPriv->drw_h) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drwx=%x, drwy=%x\n", pPriv->drw_w, pPriv->drw_h); + return; + } + + /* calc scaling factor */ + fScaleX = (float)pPriv->src_w /(float)pPriv->drw_w; + fScaleY = (float)pPriv->src_h /(float)pPriv->drw_h; + + if (pPriv->src_w == pPriv->drw_w) + ScaleFactorH = 0x8000; + else + ScaleFactorH = (ULONG)((pPriv->src_w-1)*0x8000)/pPriv->drw_w; + + if (pPriv->src_h == pPriv->drw_h) + { + ScaleFactorV = 0x8000; + dwCmd |= SCALE_EQUAL_VER; /* Setting it save the bandwidtch */ + } + else + { + ScaleFactorV = (ULONG)((pPriv->src_h-1)*0x8000)/pPriv->drw_h; + } + + if (pPriv->drw_w >= pPriv->src_w) + InitScaleFactorH = 0; + else + InitScaleFactorH = 0x4000; + + if (pPriv->drw_h >= pPriv->src_h) + InitScaleFactorV = 0; + else + InitScaleFactorV = 0x4000; + + switch(pScrn->bitsPerPixel) + { + case 32: + dwCmd = CMD_COLOR_32; + break; + case 16: + dwCmd = CMD_COLOR_16; + break; + case 8: + dwCmd = CMD_COLOR_08; + break; + } + + dwCmd |= CMD_TYPE_SCALE; + if (pPriv->drw_w >= pPriv->src_w) + dwCmd |= SCALE_SEG_NUM_1; + else + dwCmd |= SCALE_SEG_NUM_2; + + dwCmd |= SCALE_FORMAT_YUV2RGB; + switch(id) + { + case PIXEL_FMT_YUY2: + dwCmd |= YUV_FORMAT_YUYV; + break; + case PIXEL_FMT_UYVY: + dwCmd |= YUV_FORMAT_UYVY; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Other pix format:%x\n", id); + break; + } + + for(i = 0; i < nBoxs; i++, pBox++) + { + rect.x = pBox->x1 - pPriv->drw_x; + rect.y = pBox->y1 - pPriv->drw_y; + rect.width = pBox->x2 - pBox->x1; + rect.height = pBox->y2 - pBox->y1; + + lSrcX = (ULONG)((float)rect.x * fScaleX + pPriv->src_x + 0.5f); + lSrcY = (ULONG)((float)rect.y * fScaleY + pPriv->src_y + 0.5f); + + pCopyCmd = (BURSTSCALECMD*)pjRequestCMDQ(pAST, PKT_TYPESCALE_LENGTH); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "pCopyCmd=%p, pBox=%x,%x,%x,%x\n", pCopyCmd, pBox->x1, pBox->y1, pBox->x2, pBox->y2); + + CopyCmd.dwHeader0 = (ULONG) PKT_BURST_CMD_HEADER0 | + PKT_TYPESCALE_DATALENGTH | + PKT_TYPESCALE_ADDRSTART | + BURST_FORCE_CMD; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CopyCmd.dwHeader0=%x\n", CopyCmd.dwHeader0); + + CopyCmd.dwSrcPitch = (ULONG)(pPriv->srcPitch << 16); + + CopyCmd.dwDstHeightPitch = (ULONG) ((pAST->VideoModeInfo.ScreenPitch << 16) | 0xFFFF); + + CopyCmd.dwDstXY = (ULONG) ((pBox->x1 << 16) | (pBox->y1 & 0xFFFF)); + CopyCmd.dwSrcXY = (ULONG) ((lSrcX << 16) | (lSrcY & 0xFFFF)); + CopyCmd.dwRecHeightWidth = (ULONG) ((rect.width << 16) | rect.height); + + CopyCmd.dwInitScaleFactorH = InitScaleFactorH; + CopyCmd.dwInitScaleFactorV = InitScaleFactorV; + CopyCmd.dwScaleFactorH = ScaleFactorH; + CopyCmd.dwScaleFactorV = ScaleFactorV; + + CopyCmd.dwSrcBaseAddr = pPriv->bufAddr[pPriv->currentBuf]; + CopyCmd.dwDstBaseAddr = 0; + CopyCmd.dwCmd = dwCmd; + CopyCmd.NullData[0] = 0; /* for alignment */ + memcpy(pCopyCmd, &CopyCmd, sizeof(CopyCmd)); + + mUpdateWritePointer; + +#if 0 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%08x, %08x, %08x, %08x\n", + *(ULONG *)(pAST->MMIOVirtualAddr+0x8000), + *(ULONG *)(pAST->MMIOVirtualAddr+0x8004), + *(ULONG *)(pAST->MMIOVirtualAddr+0x8008), + *(ULONG *)(pAST->MMIOVirtualAddr+0x800C)); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%08x, %08x, %08x, %08x\n", + *(ULONG *)(pAST->MMIOVirtualAddr+0x8010), + *(ULONG *)(pAST->MMIOVirtualAddr+0x8014), + *(ULONG *)(pAST->MMIOVirtualAddr+0x8018), + *(ULONG *)(pAST->MMIOVirtualAddr+0x801C)); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%08x, %08x, %08x, %08x\n", + *(ULONG *)(pAST->MMIOVirtualAddr+0x8020), + *(ULONG *)(pAST->MMIOVirtualAddr+0x8024), + *(ULONG *)(pAST->MMIOVirtualAddr+0x8028), + *(ULONG *)(pAST->MMIOVirtualAddr+0x802C)); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%08x, %08x, %08x, %08x\n", + *(ULONG *)(pAST->MMIOVirtualAddr+0x8030), + *(ULONG *)(pAST->MMIOVirtualAddr+0x8034), + *(ULONG *)(pAST->MMIOVirtualAddr+0x8038), + *(ULONG *)(pAST->MMIOVirtualAddr+0x803C)); +#endif + + } /* End of for-loop */ + +} /* ASTDisplayVideo */ +#endif /* AstVideo */ + #endif /* end of Accel_2D */ diff --git a/src/ast_cursor.c b/src/ast_cursor.c index 9aa3e53..b3f2061 100644 --- a/src/ast_cursor.c +++ b/src/ast_cursor.c @@ -59,16 +59,19 @@ /* Prototype type declaration */ Bool ASTCursorInit(ScreenPtr pScreen); Bool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST); +void ASTDisableHWC(ScrnInfoPtr pScrn); static void ASTShowCursor(ScrnInfoPtr pScrn); -void ASTHideCursor(ScrnInfoPtr pScrn); +static void ASTHideCursor(ScrnInfoPtr pScrn); static void ASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y); static void ASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); static void ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src); static Bool ASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs); static void ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs); static Bool ASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs); - static void ASTFireCursor(ScrnInfoPtr pScrn); +static void ASTShowCursor_AST1180(ScrnInfoPtr pScrn); +static void ASTHideCursor_AST1180(ScrnInfoPtr pScrn); +static void ASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y); Bool ASTCursorInit(ScreenPtr pScreen) @@ -88,10 +91,19 @@ ASTCursorInit(ScreenPtr pScreen) infoPtr->MaxWidth = MAX_HWC_WIDTH; infoPtr->MaxHeight = MAX_HWC_HEIGHT; - infoPtr->ShowCursor = ASTShowCursor; - infoPtr->HideCursor = ASTHideCursor; - infoPtr->SetCursorPosition = ASTSetCursorPosition; - infoPtr->SetCursorColors = ASTSetCursorColors; + if (pAST->jChipType == AST1180) + { + infoPtr->ShowCursor = ASTShowCursor_AST1180; + infoPtr->HideCursor = ASTHideCursor_AST1180; + infoPtr->SetCursorPosition = ASTSetCursorPosition_AST1180; + } + else + { + infoPtr->ShowCursor = ASTShowCursor; + infoPtr->HideCursor = ASTHideCursor; + infoPtr->SetCursorPosition = ASTSetCursorPosition; + } + infoPtr->SetCursorColors = ASTSetCursorColors; infoPtr->LoadCursorImage = ASTLoadCursorImage; infoPtr->UseHWCursor = ASTUseHWCursor; #ifdef ARGB_CURSOR @@ -129,6 +141,15 @@ Bool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST) return (TRUE); } +void ASTDisableHWC(ScrnInfoPtr pScrn) +{ + ASTRecPtr pAST = ASTPTR(pScrn); + + if (pAST->jChipType == AST1180) + ASTHideCursor_AST1180(pScrn); + else + ASTHideCursor(pScrn); +} static void ASTShowCursor(ScrnInfoPtr pScrn) @@ -144,7 +165,7 @@ ASTShowCursor(ScrnInfoPtr pScrn) } -void +static void ASTHideCursor(ScrnInfoPtr pScrn) { ASTRecPtr pAST = ASTPTR(pScrn); @@ -271,19 +292,27 @@ ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src) } - /* Write Checksum as signature */ - pjDstData = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; - *((ULONG *) pjDstData) = ulCheckSum; - *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width; - *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height; - *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTX)) = 0; - *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTY)) = 0; - - /* set pattern offset */ - ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3); - SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF)); - SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF)); - SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF)); + if (pAST->jChipType == AST1180) + { + ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next); + WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr); + } + else + { + /* Write Checksum as signature */ + pjDstData = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; + *((ULONG *) pjDstData) = ulCheckSum; + *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width; + *((ULONG *) (pjDstData + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height; + *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTX)) = 0; + *((ULONG *) (pjDstData + HWC_SIGNATURE_HOTSPOTY)) = 0; + + /* set pattern offset */ + ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3); + SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF)); + SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF)); + SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF)); + } /* update HWC_NUM_Next */ pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM; @@ -375,19 +404,27 @@ ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs) } /* end of for-loop */ - /* Write Checksum as signature */ - pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; - *((ULONG *) pjDstXor) = ulCheckSum; - *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width; - *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height; - *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTX)) = 0; - *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTY)) = 0; - - /* set pattern offset */ - ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr +(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3); - SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF)); - SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF)); - SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF)); + if (pAST->jChipType == AST1180) + { + ulPatternAddr = pAST->ulVRAMBase + (pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next); + WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_PATTERNADDR, ulPatternAddr); + } + else + { + /* Write Checksum as signature */ + pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE; + *((ULONG *) pjDstXor) = ulCheckSum; + *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeX)) = pAST->HWCInfo.width; + *((ULONG *) (pjDstXor + HWC_SIGNATURE_SizeY)) = pAST->HWCInfo.height; + *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTX)) = 0; + *((ULONG *) (pjDstXor + HWC_SIGNATURE_HOTSPOTY)) = 0; + + /* set pattern offset */ + ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr +(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3); + SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF)); + SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF)); + SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF)); + } /* update HWC_NUM_Next */ pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM; @@ -412,4 +449,71 @@ ASTFireCursor(ScrnInfoPtr pScrn) } +/* AST1180 */ +static void +ASTShowCursor_AST1180(ScrnInfoPtr pScrn) +{ + ASTRecPtr pAST = ASTPTR(pScrn); + ULONG ulData, ulTemp; + + ReadAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp); + + ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); + ulData &= ~AST1180_ALPHAHWC; + if (pAST->HWCInfo.cursortype ==HWC_COLOR) + ulData |= AST1180_ALPHAHWC; + ulData |= AST1180_ENABLEHWC; + WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); + + /* fire cursor */ + WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulTemp); + +} /* ASTShowCursor_AST1180 */ + +static void +ASTHideCursor_AST1180(ScrnInfoPtr pScrn) +{ + ASTRecPtr pAST = ASTPTR(pScrn); + ULONG ulData; + + ReadAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); + ulData &= ~AST1180_ENABLEHWC; + WriteAST1180SOC(AST1180_GFX_BASE+AST1180_VGA1_CTRL, ulData); + + /* fire cursor */ + WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, 0x07ff07ff); + +} /* ASTHideCursor_AST1180 */ + +static void +ASTSetCursorPosition_AST1180(ScrnInfoPtr pScrn, int x, int y) +{ + ASTRecPtr pAST = ASTPTR(pScrn); + DisplayModePtr mode = pAST->ModePtr; + int x_offset, y_offset; + ULONG ulData; + + x_offset = pAST->HWCInfo.offset_x; + y_offset = pAST->HWCInfo.offset_y; + + if(x < 0) { + x_offset = (-x) + pAST->HWCInfo.offset_x; + x = 0; + } + + if(y < 0) { + y_offset = (-y) + pAST->HWCInfo.offset_y; + y = 0; + } + + if(mode->Flags & V_DBLSCAN) y *= 2; + + /* Set to Reg. */ + ulData = (x_offset) | (y_offset << 8); + WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_OFFSET, ulData); + ulData = (x) | (y << 16); + WriteAST1180SOC(AST1180_GFX_BASE+AST1180_HWC1_POSITION, ulData); + +} /* ASTSetCursorPosition_AST1180 */ + #endif /* End of HWC */ diff --git a/src/ast_driver.c b/src/ast_driver.c index bb46119..4a10e6e 100644 --- a/src/ast_driver.c +++ b/src/ast_driver.c @@ -78,7 +78,10 @@ extern Bool GetVGA2EDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer); extern void vInitDRAMReg(ScrnInfoPtr pScrn); extern Bool bIsVGAEnabled(ScrnInfoPtr pScrn); extern void ASTBlankScreen(ScrnInfoPtr pScreen, Bool unblack); -extern Bool InitVGA(ScrnInfoPtr pScrn); +extern Bool InitVGA(ScrnInfoPtr pScrn, ULONG Flags); +extern Bool GetVGAEDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer); +extern Bool bInitAST1180(ScrnInfoPtr pScrn); +extern void GetAST1180DRAMInfo(ScrnInfoPtr pScrn); extern Bool bInitCMDQInfo(ScrnInfoPtr pScrn, ASTRecPtr pAST); extern Bool bEnableCMDQ(ScrnInfoPtr pScrn, ASTRecPtr pAST); @@ -87,7 +90,7 @@ extern void vDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST); extern Bool ASTAccelInit(ScreenPtr pScreen); extern Bool ASTCursorInit(ScreenPtr pScreen); -extern void ASTHideCursor(ScrnInfoPtr pScrn); +extern void ASTDisableHWC(ScrnInfoPtr pScrn); /* Mandatory functions */ static void ASTIdentify(int flags); @@ -114,6 +117,14 @@ static xf86MonPtr ASTDoDDC(ScrnInfoPtr pScrn, int index); static void vFillASTModeInfo (ScrnInfoPtr pScrn); static Bool ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +#ifdef AstVideo +/* video function */ +static void ASTInitVideo(ScreenPtr pScreen); +static int ASTPutImage( ScrnInfoPtr, + short, short, short, short, short, short, short, short, + int, unsigned char*, short, short, Bool, RegionPtr, pointer); +#endif + /* * This is intentionally screen-independent. It indicates the binding * choice made in the first PreInit. @@ -132,12 +143,14 @@ _X_EXPORT DriverRec AST = { static SymTabRec ASTChipsets[] = { {PCI_CHIP_AST2000, "ASPEED Graphics Family"}, {PCI_CHIP_AST2100, "ASPEED Graphics Family"}, + {PCI_CHIP_AST1180, "ASPEED AST1180 Graphics"}, {-1, NULL} }; static PciChipsets ASTPciChipsets[] = { {PCI_CHIP_AST2000, PCI_CHIP_AST2000, RES_SHARED_VGA}, {PCI_CHIP_AST2100, PCI_CHIP_AST2100, RES_SHARED_VGA}, + {PCI_CHIP_AST1180, PCI_CHIP_AST1180, RES_SHARED_VGA}, {-1, -1, RES_UNDEFINED } }; @@ -533,37 +546,61 @@ ASTPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } - /* Init VGA Adapter */ - if (!xf86IsPrimaryPci(pAST->PciInfo)) - { - InitVGA(pScrn); + if (PCI_DEV_DEVICE_ID(pAST->PciInfo) == PCI_CHIP_AST1180) + { + pAST->jChipType = AST1180; + + /* validate mode */ + if ( (pScrn->bitsPerPixel == 8) || (pScrn->depth == 8) ) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given bpp (%d) is not supported by ast driver\n", + pScrn->bitsPerPixel); + return FALSE; + } + + /* Init AST1180 */ + bInitAST1180(pScrn); + + /* Get AST1180 Information */ + GetAST1180DRAMInfo(pScrn); + pScrn->videoRam = pAST->ulVRAMSize / 1024; + } + else + { + /* Init VGA Adapter */ + if (!xf86IsPrimaryPci(pAST->PciInfo)) + { + InitVGA(pScrn, 0); + } - vASTOpenKey(pScrn); - bASTRegInit(pScrn); - - /* Get Chip Type */ - if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x20) - pAST->jChipType = AST2300; - else if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x10) - GetChipType(pScrn); - else - pAST->jChipType = AST2000; - - /* Get DRAM Info */ - GetDRAMInfo(pScrn); + vASTOpenKey(pScrn); + bASTRegInit(pScrn); + + /* Get Chip Type */ + if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x20) + pAST->jChipType = AST2300; + else if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x10) + GetChipType(pScrn); + else + pAST->jChipType = AST2000; + + /* Get DRAM Info */ + GetDRAMInfo(pScrn); + pAST->ulVRAMSize = GetVRAMInfo(pScrn); + pScrn->videoRam = pAST->ulVRAMSize / 1024; + } /* Map Framebuffer */ - pScrn->videoRam = GetVRAMInfo(pScrn) / 1024; from = X_DEFAULT; - if (pAST->pEnt->device->videoRam) { pScrn->videoRam = pAST->pEnt->device->videoRam; from = X_CONFIG; } pAST->FbMapSize = pScrn->videoRam * 1024; - + #if 0 if (!ASTMapMem(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n"); @@ -589,7 +626,7 @@ ASTPreInit(ScrnInfoPtr pScrn, int flags) clockRanges->doubleScanAllowed = FALSE; /* Add for AST2100, ycchen@061807 */ - if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300)) + if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST1180)) i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, clockRanges, 0, 320, 1920, 8 * pScrn->bitsPerPixel, @@ -815,13 +852,24 @@ ASTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!miCreateDefColormap(pScreen)) return FALSE; - if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits, - vASTLoadPalette, NULL, - CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { - return FALSE; + if (pAST->jChipType != AST1180) + { + if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits, + vASTLoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { + return FALSE; + } } xf86DPMSInit(pScreen, ASTDisplayPowerManagementSet, 0); + +#ifdef AstVideo + if ( (pAST->jChipType == AST1180) || (pAST->jChipType == AST2300) ) + { + xf86DrvMsg(pScrn->scrnIndex, X_INFO,"AST Initial Video()\n"); + ASTInitVideo(pScreen); + } +#endif pScreen->SaveScreen = ASTSaveScreen; pAST->CloseScreen = pScreen->CloseScreen; @@ -840,13 +888,24 @@ ASTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; ASTRecPtr pAST = ASTPTR(pScrn); + + /* VideoMode validate */ + if (mode->CrtcHDisplay > pScrn->displayWidth) + return FALSE; + if ((pAST->VideoModeInfo.ScreenPitch * mode->CrtcVDisplay) > pAST->ulVRAMSize) + return FALSE; + + /* VideModeInfo Update */ + pAST->VideoModeInfo.ScreenWidth = mode->CrtcHDisplay; + pAST->VideoModeInfo.ScreenHeight = mode->CrtcVDisplay; + pAST->VideoModeInfo.ScreenPitch = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8) ; #ifdef HWC if (pAST->pHWCPtr) { xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ pAST->pHWCPtr = NULL; } - ASTHideCursor(pScrn); + ASTDisableHWC(pScrn); #endif #ifdef Accel_2D @@ -871,8 +930,8 @@ ASTAdjustFrame(int scrnIndex, int x, int y, int flags) ASTRecPtr pAST = ASTPTR(pScrn); ULONG base; - base = y * pAST->VideoModeInfo.ScreenWidth + x * ((pAST->VideoModeInfo.bitsPerPixel + 1) / 8); - base = base >> 2; /* DW unit */ + base = y * pAST->VideoModeInfo.ScreenPitch + x * ((pAST->VideoModeInfo.bitsPerPixel + 1) / 8); + /* base = base >> 2; */ /* DW unit */ vSetStartAddressCRT1(pAST, base); @@ -883,11 +942,15 @@ static Bool ASTEnterVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + ASTRecPtr pAST = ASTPTR(pScrn); /* Fixed suspend can't resume issue */ if (!bIsVGAEnabled(pScrn)) { - InitVGA(pScrn); + if (pAST->jChipType == AST1180) + bInitAST1180(pScrn); + else + InitVGA(pScrn, 1); ASTRestore(pScrn); } @@ -896,7 +959,7 @@ ASTEnterVT(int scrnIndex, int flags) ASTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); return TRUE; - + } /* leave X server */ @@ -905,15 +968,15 @@ ASTLeaveVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - vgaHWPtr hwp = VGAHWPTR(pScrn); ASTRecPtr pAST = ASTPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); #ifdef HWC if (pAST->pHWCPtr) { xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ pAST->pHWCPtr = NULL; } - ASTHideCursor(pScrn); + ASTDisableHWC(pScrn); #endif #ifdef Accel_2D @@ -924,7 +987,11 @@ ASTLeaveVT(int scrnIndex, int flags) vDisable2D(pScrn, pAST); #endif - ASTRestore(pScrn); + ASTRestore(pScrn); + + if (pAST->jChipType == AST1180) + ASTBlankScreen(pScrn, 0); + vgaHWLock(hwp); } @@ -937,15 +1004,16 @@ ASTFreeScreen(int scrnIndex, int flags) vgaHWFreeHWRec(xf86Screens[scrnIndex]); } - static ModeStatus ASTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; ASTRecPtr pAST = ASTPTR(pScrn); - Bool Flags = MODE_NOMODE; - + ModeStatus Flags = MODE_NOMODE; + UCHAR jReg; + ULONG RequestBufferSize; + if (mode->Flags & V_INTERLACE) { if (verbose) { xf86DrvMsg(scrnIndex, X_PROBED, @@ -958,56 +1026,71 @@ ASTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) if (verbose) { xf86DrvMsg(scrnIndex, X_PROBED, "Removing the mode \"%s\"\n", mode->name); - } - return Flags; + } + return Flags; } - /* Add for AST2100, ycchen@061807 */ - if ( (pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) ) + /* Valid Framebuffer size */ + RequestBufferSize = mode->CrtcHDisplay * ((pScrn->bitsPerPixel + 1) / 8) * mode->CrtcVDisplay; + if (RequestBufferSize > pAST->ulVRAMSize) + return Flags; + + /* Check BMC scratch for iKVM compatible */ + if (pAST->jChipType == AST2000) + jReg = 0x80; + else if (pAST->jChipType == AST1180) + jReg = 0x01; + else { - if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1200) ) - return MODE_OK; - if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1080) ) - return MODE_OK; - } + GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg); + } - if ((pAST->jChipType == AST1100) || (pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2150) || (pAST->jChipType == AST2300)) + if ( !(jReg & 0x80) || (jReg & 0x01) ) { - - if ( (mode->CrtcHDisplay == 1680) && (mode->CrtcVDisplay == 1050) ) - return MODE_OK; - if ( (mode->CrtcHDisplay == 1440) && (mode->CrtcVDisplay == 900) ) - return MODE_OK; - if ( (mode->CrtcHDisplay == 1280) && (mode->CrtcVDisplay == 800) ) + if ( (mode->CrtcHDisplay == 1680) && (mode->CrtcVDisplay == 1050) ) + return MODE_OK; + if ( (mode->CrtcHDisplay == 1280) && (mode->CrtcVDisplay == 800) ) + return MODE_OK; + if ( (mode->CrtcHDisplay == 1440) && (mode->CrtcVDisplay == 900) ) + return MODE_OK; + + if ( (pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST1180) ) + { + if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1080) ) + return MODE_OK; + } + } + + /* Add for AST2100, ycchen@061807 */ + if ( (pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST1180) ) + { + if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1200) ) return MODE_OK; - } - + switch (mode->CrtcHDisplay) { case 640: if (mode->CrtcVDisplay == 480) Flags=MODE_OK; - break; + break; case 800: if (mode->CrtcVDisplay == 600) Flags=MODE_OK; - break; + break; case 1024: if (mode->CrtcVDisplay == 768) Flags=MODE_OK; - break; + break; case 1280: if (mode->CrtcVDisplay == 1024) Flags=MODE_OK; break; case 1600: if (mode->CrtcVDisplay == 1200) Flags=MODE_OK; - break; + break; default: - return Flags; + return Flags; } - - return Flags; - -} + return Flags; +} /* Internal used modules */ /* @@ -1068,7 +1151,7 @@ ASTCloseScreen(int scrnIndex, ScreenPtr pScreen) xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ pAST->pHWCPtr = NULL; } - ASTHideCursor(pScrn); + ASTDisableHWC(pScrn); #endif #ifdef Accel_2D @@ -1080,6 +1163,10 @@ ASTCloseScreen(int scrnIndex, ScreenPtr pScreen) #endif ASTRestore(pScrn); + + if (pAST->jChipType == AST1180) + ASTBlankScreen(pScrn, 0); + vgaHWLock(hwp); } @@ -1108,6 +1195,7 @@ ASTSave(ScrnInfoPtr pScrn) vgaRegPtr vgaReg; ASTRegPtr astReg; int i, icount=0; + ULONG ulData; pAST = ASTPTR(pScrn); vgaReg = &VGAHWPTR(pScrn)->SavedReg; @@ -1122,14 +1210,25 @@ ASTSave(ScrnInfoPtr pScrn) } /* Ext. Save */ - vASTOpenKey(pScrn); + if (pAST->jChipType == AST1180) + { + for (i=0; i<12; i++) + { + ReadAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL+i*4, ulData); + astReg->GFX[i] = ulData; + } + } + else + { + vASTOpenKey(pScrn); - /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */ - for (i=0x81; i<=0xB6; i++) - GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); - for (i=0xBC; i<=0xC1; i++) - GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); - GetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]); + /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */ + for (i=0x81; i<=0xB6; i++) + GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); + for (i=0xBC; i<=0xC1; i++) + GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); + GetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]); + } } @@ -1140,6 +1239,7 @@ ASTRestore(ScrnInfoPtr pScrn) vgaRegPtr vgaReg; ASTRegPtr astReg; int i, icount=0; + ULONG ulData; pAST = ASTPTR(pScrn); vgaReg = &VGAHWPTR(pScrn)->SavedReg; @@ -1153,27 +1253,58 @@ ASTRestore(ScrnInfoPtr pScrn) vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); vgaHWProtect(pScrn, FALSE); - /* Ext. restore */ - vASTOpenKey(pScrn); - - /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */ - for (i=0x81; i<=0xB6; i++) - SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); - for (i=0xBC; i<=0xC1; i++) - SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); - SetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]); + if (pAST->jChipType == AST1180) + { + for (i=0; i<12; i++) + { + ulData = astReg->GFX[i]; + WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL+i*4, ulData); + } + } + else + { + /* Ext. restore */ + vASTOpenKey(pScrn); + + /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */ + for (i=0x81; i<=0xB6; i++) + SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); + for (i=0xBC; i<=0xC1; i++) + SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); + SetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]); + } } static void ASTProbeDDC(ScrnInfoPtr pScrn, int index) { - vbeInfoPtr pVbe; + vbeInfoPtr pVbe; + ASTRecPtr pAST = ASTPTR(pScrn); + unsigned char DDC_data[128]; + Bool Flags; - if (xf86LoadSubModule(pScrn, "vbe")) { - pVbe = VBEInit(NULL, index); - ConfiguredMonitor = vbeDoEDID(pVbe, NULL); - vbeFree(pVbe); + if ( (pAST->jChipType == AST1180) || (!xf86IsPrimaryPci(pAST->PciInfo)) ) + { + if (pAST->jChipType == AST1180) + Flags = GetVGA2EDID(pScrn, DDC_data); + else + Flags = GetVGAEDID(pScrn, DDC_data); + + if (Flags) + { + ConfiguredMonitor = xf86InterpretEDID(pScrn->scrnIndex, DDC_data); + } + else + xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTProbeDDC] Can't Get EDID Properly \n"); + } + else + { + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL, index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } } } @@ -1192,165 +1323,189 @@ ASTDoDDC(ScrnInfoPtr pScrn, int index) struct monitor_ranges ranges, ranges1, ranges2; int DTSelect, dclock1=0, h_active1=0, v_active1=0, dclock2=0, h_active2=0, v_active2=0; struct std_timings stdtiming, *stdtiming1, *stdtiming2; + Bool Flags; /* Honour Option "noDDC" */ if (xf86ReturnOptValBool(pAST->Options, OPTION_NO_DDC, FALSE)) { return MonInfo; } - if (xf86LoadSubModule(pScrn, "vbe") && (pVbe = VBEInit(NULL, index))) { - MonInfo1 = vbeDoEDID(pVbe, NULL); - MonInfo = MonInfo1; + if ( (pAST->jChipType == AST1180) || (!xf86IsPrimaryPci(pAST->PciInfo)) ) + { + + if (pAST->jChipType == AST1180) + Flags = GetVGA2EDID(pScrn, DDC_data); + else + Flags = GetVGAEDID(pScrn, DDC_data); + + if (Flags) + { + MonInfo = xf86InterpretEDID(pScrn->scrnIndex, DDC_data); + xf86PrintEDID(MonInfo); + xf86SetDDCproperties(pScrn, MonInfo); + } + else + xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTDoDDC] Can't Get EDID Properly \n"); + + } + else + { + + if (xf86LoadSubModule(pScrn, "vbe") && (pVbe = VBEInit(NULL, index))) { + MonInfo1 = vbeDoEDID(pVbe, NULL); + MonInfo = MonInfo1; - /* For VGA2 CLONE Support, ycchen@012508 */ - if ((xf86ReturnOptValBool(pAST->Options, OPTION_VGA2_CLONE, FALSE)) || pAST->VGA2Clone) { - if (GetVGA2EDID(pScrn, DDC_data) == TRUE) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Get VGA2 EDID Correctly!! \n"); - MonInfo2 = xf86InterpretEDID(pScrn->scrnIndex, DDC_data); - if (MonInfo1 == NULL) /* No DDC1 EDID */ - MonInfo = MonInfo2; - else { /* Check with VGA1 & VGA2 EDID */ - /* Update establishment timing */ - MonInfo->timings1.t1 = MonInfo1->timings1.t1 & MonInfo2->timings1.t1; - MonInfo->timings1.t2 = MonInfo1->timings1.t2 & MonInfo2->timings1.t2; - MonInfo->timings1.t_manu = MonInfo1->timings1.t_manu & MonInfo2->timings1.t_manu; + /* For VGA2 CLONE Support, ycchen@012508 */ + if ((xf86ReturnOptValBool(pAST->Options, OPTION_VGA2_CLONE, FALSE)) || pAST->VGA2Clone) { + if (GetVGA2EDID(pScrn, DDC_data) == TRUE) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Get VGA2 EDID Correctly!! \n"); + MonInfo2 = xf86InterpretEDID(pScrn->scrnIndex, DDC_data); + if (MonInfo1 == NULL) /* No DDC1 EDID */ + MonInfo = MonInfo2; + else { /* Check with VGA1 & VGA2 EDID */ + /* Update establishment timing */ + MonInfo->timings1.t1 = MonInfo1->timings1.t1 & MonInfo2->timings1.t1; + MonInfo->timings1.t2 = MonInfo1->timings1.t2 & MonInfo2->timings1.t2; + MonInfo->timings1.t_manu = MonInfo1->timings1.t_manu & MonInfo2->timings1.t_manu; - /* Update Std. Timing */ - for (i=0; i<8; i++) { - stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0; - for (j=0; j<8; j++) { - if ((MonInfo1->timings2[i].hsize == MonInfo2->timings2[j].hsize) && \ - (MonInfo1->timings2[i].vsize == MonInfo2->timings2[j].vsize) && \ - (MonInfo1->timings2[i].refresh == MonInfo2->timings2[j].refresh)) { - stdtiming = MonInfo1->timings2[i]; - break; - } - } + /* Update Std. Timing */ + for (i=0; i<8; i++) { + stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0; + for (j=0; j<8; j++) { + if ((MonInfo1->timings2[i].hsize == MonInfo2->timings2[j].hsize) && \ + (MonInfo1->timings2[i].vsize == MonInfo2->timings2[j].vsize) && \ + (MonInfo1->timings2[i].refresh == MonInfo2->timings2[j].refresh)) { + stdtiming = MonInfo1->timings2[i]; + break; + } + } - MonInfo->timings2[i] = stdtiming; - } /* Std. Timing */ + MonInfo->timings2[i] = stdtiming; + } /* Std. Timing */ - /* Get Detailed Timing */ - for (i=0;i<4;i++) { - if (MonInfo1->det_mon[i].type == 0xFD) - ranges1 = MonInfo1->det_mon[i].section.ranges; - else if (MonInfo1->det_mon[i].type == 0xFA) - stdtiming1 = MonInfo1->det_mon[i].section.std_t; - else if (MonInfo1->det_mon[i].type == 0x00) { - if (MonInfo1->det_mon[i].section.d_timings.clock > dclock1) - dclock1 = MonInfo1->det_mon[i].section.d_timings.clock; - if (MonInfo1->det_mon[i].section.d_timings.h_active > h_active1) - h_active1 = MonInfo1->det_mon[i].section.d_timings.h_active; - if (MonInfo1->det_mon[i].section.d_timings.v_active > v_active1) - v_active1 = MonInfo1->det_mon[i].section.d_timings.v_active; - } - if (MonInfo2->det_mon[i].type == 0xFD) - ranges2 = MonInfo2->det_mon[i].section.ranges; - else if (MonInfo1->det_mon[i].type == 0xFA) - stdtiming2 = MonInfo2->det_mon[i].section.std_t; - else if (MonInfo2->det_mon[i].type == 0x00) { - if (MonInfo2->det_mon[i].section.d_timings.clock > dclock2) - dclock2 = MonInfo2->det_mon[i].section.d_timings.clock; - if (MonInfo2->det_mon[i].section.d_timings.h_active > h_active2) - h_active2 = MonInfo2->det_mon[i].section.d_timings.h_active; - if (MonInfo2->det_mon[i].section.d_timings.v_active > v_active2) - v_active2 = MonInfo2->det_mon[i].section.d_timings.v_active; - } - } /* Get Detailed Timing */ - - /* Chk Detailed Timing */ - if ((dclock1 >= dclock2) && (h_active1 >= h_active2) && (v_active1 >= v_active2)) - DTSelect = DT2; - else if ((dclock2 >= dclock1) && (h_active2 >= h_active1) && (v_active2 >= v_active1)) - DTSelect = DT1; - else - DTSelect = SkipDT; - - /* Chk Monitor Descriptor */ - ranges = ranges1; - ranges.min_h = ranges1.min_h > ranges2.min_h ? ranges1.min_h:ranges2.min_h; - ranges.min_v = ranges1.min_v > ranges2.min_v ? ranges1.min_v:ranges2.min_v; - ranges.max_h = ranges1.max_h < ranges2.max_h ? ranges1.max_h:ranges2.max_h; - ranges.max_v = ranges1.max_v < ranges2.max_v ? ranges1.max_v:ranges2.max_v; - ranges.max_clock = ranges1.max_clock < ranges2.max_clock ? ranges1.max_clock:ranges2.max_clock; + /* Get Detailed Timing */ + for (i=0;i<4;i++) { + if (MonInfo1->det_mon[i].type == 0xFD) + ranges1 = MonInfo1->det_mon[i].section.ranges; + else if (MonInfo1->det_mon[i].type == 0xFA) + stdtiming1 = MonInfo1->det_mon[i].section.std_t; + else if (MonInfo1->det_mon[i].type == 0x00) { + if (MonInfo1->det_mon[i].section.d_timings.clock > dclock1) + dclock1 = MonInfo1->det_mon[i].section.d_timings.clock; + if (MonInfo1->det_mon[i].section.d_timings.h_active > h_active1) + h_active1 = MonInfo1->det_mon[i].section.d_timings.h_active; + if (MonInfo1->det_mon[i].section.d_timings.v_active > v_active1) + v_active1 = MonInfo1->det_mon[i].section.d_timings.v_active; + } + if (MonInfo2->det_mon[i].type == 0xFD) + ranges2 = MonInfo2->det_mon[i].section.ranges; + else if (MonInfo1->det_mon[i].type == 0xFA) + stdtiming2 = MonInfo2->det_mon[i].section.std_t; + else if (MonInfo2->det_mon[i].type == 0x00) { + if (MonInfo2->det_mon[i].section.d_timings.clock > dclock2) + dclock2 = MonInfo2->det_mon[i].section.d_timings.clock; + if (MonInfo2->det_mon[i].section.d_timings.h_active > h_active2) + h_active2 = MonInfo2->det_mon[i].section.d_timings.h_active; + if (MonInfo2->det_mon[i].section.d_timings.v_active > v_active2) + v_active2 = MonInfo2->det_mon[i].section.d_timings.v_active; + } + } /* Get Detailed Timing */ + + /* Chk Detailed Timing */ + if ((dclock1 >= dclock2) && (h_active1 >= h_active2) && (v_active1 >= v_active2)) + DTSelect = DT2; + else if ((dclock2 >= dclock1) && (h_active2 >= h_active1) && (v_active2 >= v_active1)) + DTSelect = DT1; + else + DTSelect = SkipDT; + + /* Chk Monitor Descriptor */ + ranges = ranges1; + ranges.min_h = ranges1.min_h > ranges2.min_h ? ranges1.min_h:ranges2.min_h; + ranges.min_v = ranges1.min_v > ranges2.min_v ? ranges1.min_v:ranges2.min_v; + ranges.max_h = ranges1.max_h < ranges2.max_h ? ranges1.max_h:ranges2.max_h; + ranges.max_v = ranges1.max_v < ranges2.max_v ? ranges1.max_v:ranges2.max_v; + ranges.max_clock = ranges1.max_clock < ranges2.max_clock ? ranges1.max_clock:ranges2.max_clock; - /* Update Detailed Timing */ - for (i=0; i<4; i++) - { - if (MonInfo->det_mon[i].type == 0xFD) { - MonInfo->det_mon[i].section.ranges = ranges; - } - else if (MonInfo->det_mon[i].type == 0xFA) { - for (j=0; j<5; j++) { - stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0; - for (k=0; k<5; k++) { - if ((stdtiming1[j].hsize == stdtiming2[k].hsize) && \ - (stdtiming1[j].vsize == stdtiming2[k].vsize) && \ - (stdtiming1[j].refresh == stdtiming2[k].refresh)) { - stdtiming = stdtiming1[j]; - break; - } - } - stdtiming1[j] = stdtiming; - } /* Std. Timing */ - } /* FA */ - else if (MonInfo->det_mon[i].type == 0x00) { - if (DTSelect == DT2) - MonInfo->det_mon[i] = MonInfo2->det_mon[i]; - else if (DTSelect == DT1) - MonInfo->det_mon[i] = MonInfo1->det_mon[i]; - else /* SkipDT */ - { /* use 1024x768 as default */ - MonInfo->det_mon[i] = MonInfo1->det_mon[i]; - MonInfo->det_mon[i].section.d_timings.clock = 65000000; - MonInfo->det_mon[i].section.d_timings.h_active = 1024; - MonInfo->det_mon[i].section.d_timings.h_blanking = 320; - MonInfo->det_mon[i].section.d_timings.v_active = 768; - MonInfo->det_mon[i].section.d_timings.v_blanking = 38; - MonInfo->det_mon[i].section.d_timings.h_sync_off = 24; - MonInfo->det_mon[i].section.d_timings.h_sync_width = 136; - MonInfo->det_mon[i].section.d_timings.v_sync_off = 3; - MonInfo->det_mon[i].section.d_timings.v_sync_width = 6; - } - } /* 00 */ - else { /* use Monitor 1 as default */ - MonInfo->det_mon[i] = MonInfo1->det_mon[i]; - } + /* Update Detailed Timing */ + for (i=0; i<4; i++) + { + if (MonInfo->det_mon[i].type == 0xFD) { + MonInfo->det_mon[i].section.ranges = ranges; + } + else if (MonInfo->det_mon[i].type == 0xFA) { + for (j=0; j<5; j++) { + stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0; + for (k=0; k<5; k++) { + if ((stdtiming1[j].hsize == stdtiming2[k].hsize) && \ + (stdtiming1[j].vsize == stdtiming2[k].vsize) && \ + (stdtiming1[j].refresh == stdtiming2[k].refresh)) { + stdtiming = stdtiming1[j]; + break; + } + } + stdtiming1[j] = stdtiming; + } /* Std. Timing */ + } /* FA */ + else if (MonInfo->det_mon[i].type == 0x00) { + if (DTSelect == DT2) + MonInfo->det_mon[i] = MonInfo2->det_mon[i]; + else if (DTSelect == DT1) + MonInfo->det_mon[i] = MonInfo1->det_mon[i]; + else /* SkipDT */ + { /* use 1024x768 as default */ + MonInfo->det_mon[i] = MonInfo1->det_mon[i]; + MonInfo->det_mon[i].section.d_timings.clock = 65000000; + MonInfo->det_mon[i].section.d_timings.h_active = 1024; + MonInfo->det_mon[i].section.d_timings.h_blanking = 320; + MonInfo->det_mon[i].section.d_timings.v_active = 768; + MonInfo->det_mon[i].section.d_timings.v_blanking = 38; + MonInfo->det_mon[i].section.d_timings.h_sync_off = 24; + MonInfo->det_mon[i].section.d_timings.h_sync_width = 136; + MonInfo->det_mon[i].section.d_timings.v_sync_off = 3; + MonInfo->det_mon[i].section.d_timings.v_sync_width = 6; + } + } /* 00 */ + else { /* use Monitor 1 as default */ + MonInfo->det_mon[i] = MonInfo1->det_mon[i]; + } - } /* Update Detailed Timing */ + } /* Update Detailed Timing */ - /* set feature size */ - if (DTSelect == DT2) { - MonInfo->features.hsize = MonInfo2->features.hsize; - MonInfo->features.vsize = MonInfo2->features.vsize; - } - else if (DTSelect == DT1) { - MonInfo->features.hsize = MonInfo1->features.hsize; - MonInfo->features.vsize = MonInfo1->features.vsize; - } - else /* Skip DT */ - { /* use 1024x768 as default */ - MonInfo->features.hsize = 0x20; - MonInfo->features.vsize = 0x18; - } + /* set feature size */ + if (DTSelect == DT2) { + MonInfo->features.hsize = MonInfo2->features.hsize; + MonInfo->features.vsize = MonInfo2->features.vsize; + } + else if (DTSelect == DT1) { + MonInfo->features.hsize = MonInfo1->features.hsize; + MonInfo->features.vsize = MonInfo1->features.vsize; + } + else /* Skip DT */ + { /* use 1024x768 as default */ + MonInfo->features.hsize = 0x20; + MonInfo->features.vsize = 0x18; + } - } /* Check with VGA1 & VGA2 EDID */ + } /* Check with VGA1 & VGA2 EDID */ - } /* GetVGA2EDID */ - else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Can't Get VGA2 EDID Correctly!! \n"); - } + } /* GetVGA2EDID */ + else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Can't Get VGA2 EDID Correctly!! \n"); + } - } + } - xf86PrintEDID(MonInfo); - xf86SetDDCproperties(pScrn, MonInfo); - vbeFree(pVbe); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "this driver cannot do DDC without VBE\n"); - } - + xf86PrintEDID(MonInfo); + xf86SetDDCproperties(pScrn, MonInfo); + vbeFree(pVbe); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "this driver cannot do DDC without VBE\n"); + } + + } /* AST1180 */ + return MonInfo; } @@ -1393,3 +1548,569 @@ ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) return TRUE; } + +#ifdef AstVideo +/* + * Video Part by ic_yang + */ +#include "fourcc.h" + +#define NUM_ATTRIBUTES 8 +#define NUM_IMAGES 8 +#define NUM_FORMATS 3 + +#define IMAGE_MIN_WIDTH 32 +#define IMAGE_MIN_HEIGHT 24 +#define IMAGE_MAX_WIDTH 1920 +#define IMAGE_MAX_HEIGHT 1080 + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +static XF86ImageRec ASTImages[NUM_IMAGES] = +{ + XVIMAGE_YUY2, /* If order is changed, ASTOffscreenImages must be adapted */ +}; + +static XF86VideoFormatRec ASTFormats[NUM_FORMATS] = +{ + { 8, PseudoColor}, + {16, TrueColor}, + {24, TrueColor} +}; + +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding = +{ + 0, + "XV_IMAGE", + 0, 0, /* Will be filled in */ + {1, 1} +}; + +static char astxvcolorkey[] = "XV_COLORKEY"; +static char astxvbrightness[] = "XV_BRIGHTNESS"; +static char astxvcontrast[] = "XV_CONTRAST"; +static char astxvsaturation[] = "XV_SATURATION"; +static char astxvhue[] = "XV_HUE"; +static char astxvgammared[] = "XV_GAMMA_RED"; +static char astxvgammagreen[] = "XV_GAMMA_GREEN"; +static char astxvgammablue[] = "XV_GAMMA_BLUE"; + +static XF86AttributeRec ASTAttributes[NUM_ATTRIBUTES] = +{ + {XvSettable | XvGettable, 0, (1 << 24) - 1, astxvcolorkey}, + {XvSettable | XvGettable, -128, 127, astxvbrightness}, + {XvSettable | XvGettable, 0, 255, astxvcontrast}, + {XvSettable | XvGettable, -180, 180, astxvsaturation}, + {XvSettable | XvGettable, -180, 180, astxvhue}, + {XvSettable | XvGettable, 100, 10000, astxvgammared}, + {XvSettable | XvGettable, 100, 10000, astxvgammagreen}, + {XvSettable | XvGettable, 100, 10000, astxvgammablue}, +}; + +static void ASTStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) +{ + ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data; + ASTPtr pAST = ASTPTR(pScrn); + + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + + if(exit) + { + if(pPriv->fbAreaPtr) + { + xf86FreeOffscreenArea(pPriv->fbAreaPtr); + pPriv->fbAreaPtr = NULL; + pPriv->fbSize = 0; + } + /* clear all flag */ + pPriv->videoStatus = 0; + } + else + { +#if 0 + if(pPriv->videoStatus & CLIENT_VIDEO_ON) + { + pPriv->videoStatus |= OFF_TIMER; + + } +#endif + } +} + +static int ASTSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data) +{ + ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data; + ASTPtr pAST = ASTPTR(pScrn); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTSetPortAttribute(),attribute=%x\n", attribute); + + if (attribute == pAST->xvBrightness) + { + if((value < -128) || (value > 127)) + return BadValue; + + pPriv->brightness = value; + } + else if (attribute == pAST->xvContrast) + { + if ((value < 0) || (value > 255)) + return BadValue; + + pPriv->contrast = value; + } + else if (attribute == pAST->xvSaturation) + { + if ((value < -180) || (value > 180)) + return BadValue; + + pPriv->saturation = value; + } + else if (attribute == pAST->xvHue) + { + if ((value < -180) || (value > 180)) + return BadValue; + + pPriv->hue = value; + } + else if (attribute == pAST->xvColorKey) + { + pPriv->colorKey = value; + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + } + else if(attribute == pAST->xvGammaRed) + { + if((value < 100) || (value > 10000)) + return BadValue; + pPriv->gammaR = value; + } + else if(attribute == pAST->xvGammaGreen) + { + if((value < 100) || (value > 10000)) + return BadValue; + pPriv->gammaG = value; + } + else if(attribute == pAST->xvGammaBlue) + { + if((value < 100) || (value > 10000)) + return BadValue; + pPriv->gammaB = value; + } + else + { + return BadMatch; + } + + return Success; +} + +static int ASTGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, pointer data) +{ + ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data; + ASTPtr pAST = ASTPTR(pScrn); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTGetPortAttribute(),attribute=%x\n", attribute); + + if (attribute == pAST->xvBrightness) + { + *value = pPriv->brightness; + } + else if (attribute == pAST->xvContrast) + { + *value = pPriv->contrast; + } + else if (attribute == pAST->xvSaturation) + { + *value = pPriv->saturation; + } + else if (attribute == pAST->xvHue) + { + *value = pPriv->hue; + } + else if(attribute == pAST->xvGammaRed) + { + *value = pPriv->gammaR; + + } + else if(attribute == pAST->xvGammaGreen) + { + *value = pPriv->gammaG; + } + else if(attribute == pAST->xvGammaBlue) + { + *value = pPriv->gammaB; + } + else if (attribute == pAST->xvColorKey) + { + *value = pPriv->colorKey; + } + else + return BadMatch; + + return Success; +} + +static void ASTQueryBestSize(ScrnInfoPtr pScrn, Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + pointer data) +{ + *p_w = drw_w; + *p_h = drw_h; + xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTQueryBestSize()\n"); + /* TODO: report the HW limitation */ +} + +static int ASTQueryImageAttributes(ScrnInfoPtr pScrn, int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets) +{ + int pitchY, pitchUV; + int size, sizeY, sizeUV; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTQueryImageAttributes()\n"); + + if(*w < IMAGE_MIN_WIDTH) *w = IMAGE_MIN_WIDTH; + if(*h < IMAGE_MIN_HEIGHT) *h = IMAGE_MIN_HEIGHT; + + switch(id) { + case PIXEL_FMT_YV12: + *w = (*w + 7) & ~7; + *h = (*h + 1) & ~1; + pitchY = *w; + pitchUV = *w >> 1; + if(pitches) { + pitches[0] = pitchY; + pitches[1] = pitches[2] = pitchUV; + } + sizeY = pitchY * (*h); + sizeUV = pitchUV * ((*h) >> 1); + if(offsets) { + offsets[0] = 0; + offsets[1] = sizeY; + offsets[2] = sizeY + sizeUV; + } + size = sizeY + (sizeUV << 1); + break; + case PIXEL_FMT_NV12: + case PIXEL_FMT_NV21: + *w = (*w + 7) & ~7; + *h = (*h + 1) & ~1; + pitchY = *w; + pitchUV = *w; + if(pitches) { + pitches[0] = pitchY; + pitches[1] = pitchUV; + } + sizeY = pitchY * (*h); + sizeUV = pitchUV * ((*h) >> 1); + if(offsets) { + offsets[0] = 0; + offsets[1] = sizeY; + } + size = sizeY + (sizeUV << 1); + break; + case PIXEL_FMT_YUY2: + case PIXEL_FMT_UYVY: + case PIXEL_FMT_YVYU: + case PIXEL_FMT_RGB6: + case PIXEL_FMT_RGB5: + default: + *w = (*w + 1) & ~1; + pitchY = *w << 1; + if(pitches) pitches[0] = pitchY; + if(offsets) offsets[0] = 0; + size = pitchY * (*h); + break; + } + + return size; +} + +extern void ASTDisplayVideo(ScrnInfoPtr pScrn, ASTPortPrivPtr pPriv, RegionPtr clipBoxes, int id); + +static int ASTPutImage(ScrnInfoPtr pScrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, unsigned char* buf, + short width, short height, + Bool sync, + RegionPtr clipBoxes, pointer data +) +{ + ASTPtr pAST = ASTPTR(pScrn); + ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data; + int i; + int totalSize=0; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTPutImage()\n"); + /* int depth = pAST->CurrentLayout.bitsPerPixel >> 3; */ + + pPriv->drw_x = drw_x; + pPriv->drw_y = drw_y; + pPriv->drw_w = drw_w; + pPriv->drw_h = drw_h; + pPriv->src_x = src_x; + pPriv->src_y = src_y; + pPriv->src_w = src_w; + pPriv->src_h = src_h; + pPriv->id = id; + pPriv->height = height; + + switch(id) + { + case PIXEL_FMT_YV12: + case PIXEL_FMT_NV12: + case PIXEL_FMT_NV21: + pPriv->srcPitch = (width + 7) & ~7; + totalSize = (pPriv->srcPitch * height * 3) >> 1; /* Verified */ + break; + case PIXEL_FMT_YUY2: + case PIXEL_FMT_UYVY: + case PIXEL_FMT_YVYU: + case PIXEL_FMT_RGB6: + case PIXEL_FMT_RGB5: + default: + pPriv->srcPitch = ((width << 1) + 3) & ~3; /* Verified */ + totalSize = pPriv->srcPitch * height; + } + + totalSize += 15; + totalSize &= ~15; + /* allocate memory */ + + if(totalSize == pPriv->fbSize) + { + ; + } + else + { + int lines, pitch, depth; + BoxPtr pBox = NULL; + + pPriv->fbSize = totalSize; + + if(pPriv->fbAreaPtr) + { + xf86FreeOffscreenArea(pPriv->fbAreaPtr); + } + + depth = (pScrn->bitsPerPixel + 7 ) / 8; + pitch = pScrn->displayWidth * depth; + lines = ((totalSize * 2) / pitch) + 1; + xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTPutImagelines=%x, pitch=%x, displayWidth=%x\n", lines, pitch, pScrn->displayWidth); + + + pPriv->fbAreaPtr = xf86AllocateOffscreenArea(pScrn->pScreen, + pScrn->displayWidth, + lines, 0, NULL, NULL, NULL); + + if(!pPriv->fbAreaPtr) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Allocate video memory fails\n"); + return BadAlloc; + } + + pBox = &(pPriv->fbAreaPtr->box); + pPriv->bufAddr[0] = (pBox->y1 * pitch) + (pBox->x1 * depth); + pPriv->bufAddr[1] = pPriv->bufAddr[0] + totalSize; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Put Image, pPriv->bufAddr[0]=0x%08X\n", pPriv->bufAddr[0]); + + } + + /* copy data */ + if(totalSize < 16) + { + #ifdef NewPath + memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); + #else /* NewPath */ + switch(id) + { + case PIXEL_FMT_YUY2: + case PIXEL_FMT_UYVY: + case PIXEL_FMT_YVYU: + { + BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]); + for(i=0; i<height; i++) + memcpy( Base + i * pPriv->srcPitch, buf + i*width*2, width*2); + break; + } + default: + memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); + break; + } /* switch */ + #endif /* NewPath */ + } + else + { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Put Image, copy buf\n"); + + #ifdef NewPath + memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); + #else /* NewPath */ + switch(id) + { + case PIXEL_FMT_YUY2: + case PIXEL_FMT_UYVY: + case PIXEL_FMT_YVYU: + { + BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]); + for(i=0; i<height; i++) + memcpy( Base + i * pPriv->srcPitch, buf + i*width*2, width*2); + + /*for(i=0; i<height; i++) + for(j=0; j<width*2; j++) + *(Base+i*pPriv->srcPitch+j) = *(buf + width*i + j);*/ + break; + } + default: + { BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]); + int j; + for(i=0; i<height; i++) + for(j=0; j<width; j++) + *(Base + width*i + j) = *(buf + width * i + j); + break; + } + } /* end of switch */ + #endif /* NewPath */ + } + + ASTDisplayVideo(pScrn, pPriv, clipBoxes, id); + + /* update cliplist + if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) + { + REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); + } + else + { + xf86XVFillKeyHelper(pScrn->pScreen, 0xFFFFFFFF, clipBoxes); + } + */ + pPriv->currentBuf ^= 1; + + return Success; +} + +static XF86VideoAdaptorPtr ASTSetupImageVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + ASTPtr pAST = ASTPTR(pScrn); + XF86VideoAdaptorPtr adapt; + ASTPortPrivPtr pPriv; + + + if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(DevUnion) + + sizeof(ASTPortPrivRec)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask | XvVideoMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "AST Video"; + + adapt->nEncodings = 1; + adapt->pEncodings = &DummyEncoding; + + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = ASTFormats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion*)(&adapt[1]); + + pPriv = (ASTPortPrivPtr)(&adapt->pPortPrivates[1]); + + adapt->pPortPrivates->ptr = (pointer)(pPriv); + adapt->pAttributes = ASTAttributes; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->nImages = NUM_IMAGES; + adapt->pImages = ASTImages; + + adapt->PutVideo = NULL; + + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = ASTStopVideo; + adapt->SetPortAttribute = ASTSetPortAttribute; + adapt->GetPortAttribute = ASTGetPortAttribute; + adapt->QueryBestSize = ASTQueryBestSize; + adapt->PutImage = ASTPutImage; + adapt->QueryImageAttributes = ASTQueryImageAttributes; + + + pPriv->currentBuf = 0; + pPriv->linear = NULL; + pPriv->fbAreaPtr = NULL; + pPriv->fbSize = 0; + pPriv->videoStatus = 0; + + pPriv->colorKey = 0x000101fe; + pPriv->brightness = 0; + pPriv->contrast = 128; + pPriv->saturation = 0; + pPriv->hue = 0; + + /* gotta uninit this someplace */ +#if defined(REGION_NULL) + REGION_NULL(pScreen, &pPriv->clip); +#else + REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); +#endif + + pAST->adaptor = adapt; + + pAST->xvBrightness = MAKE_ATOM(astxvbrightness); + pAST->xvContrast = MAKE_ATOM(astxvcontrast); + pAST->xvColorKey = MAKE_ATOM(astxvcolorkey); + pAST->xvSaturation = MAKE_ATOM(astxvsaturation); + pAST->xvHue = MAKE_ATOM(astxvhue); + pAST->xvGammaRed = MAKE_ATOM(astxvgammared); + pAST->xvGammaGreen = MAKE_ATOM(astxvgammagreen); + pAST->xvGammaBlue = MAKE_ATOM(astxvgammablue); + + return adapt; +} + +void ASTInitVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr ASTAdaptor = NULL; + int num_adaptors; + + ASTAdaptor = ASTSetupImageVideo(pScreen); + + num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); + + if(ASTAdaptor) + { + if(!num_adaptors) + { + num_adaptors = 1; + adaptors = &ASTAdaptor; + } + else + { + newAdaptors = xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); + if(newAdaptors) + { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = ASTAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } + } + + if(num_adaptors) + xf86XVScreenInit(pScreen, adaptors, num_adaptors); + + if(newAdaptors) + xfree(newAdaptors); + +} +#endif /* AstVideo */ diff --git a/src/ast_mode.c b/src/ast_mode.c index ed24c54..f971ff2 100644 --- a/src/ast_mode.c +++ b/src/ast_mode.c @@ -198,32 +198,32 @@ VBIOS_ENHTABLE_STRUCT Res1920x1200Table[] = { /* 16:10 */ VBIOS_ENHTABLE_STRUCT Res1280x800Table[] = { {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */ - (SyncPN | Charx8Dot | LineCompareOff), 60, 1, 0x35 }, + (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x35 }, {1680, 1280, 72,128, 831, 800, 3, 6, VCLK83_5, /* 60Hz */ - (SyncPN | Charx8Dot | LineCompareOff), 0xFF, 1, 0x35 }, + (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x35 }, }; VBIOS_ENHTABLE_STRUCT Res1440x900Table[] = { {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */ - (SyncPN | Charx8Dot | LineCompareOff), 60, 1, 0x36 }, + (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x36 }, {1904, 1440, 80,152, 934, 900, 3, 6, VCLK106_5, /* 60Hz */ - (SyncPN | Charx8Dot | LineCompareOff), 0xFF, 1, 0x36 }, + (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x36 }, }; VBIOS_ENHTABLE_STRUCT Res1680x1050Table[] = { {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */ - (SyncPN | Charx8Dot | LineCompareOff), 60, 1, 0x37 }, + (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x37 }, {2240, 1680,104,176, 1089, 1050, 3, 6, VCLK146_25, /* 60Hz */ - (SyncPN | Charx8Dot | LineCompareOff), 0xFF, 1, 0x37 }, + (SyncPN | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x37 }, }; /* HDTV */ VBIOS_ENHTABLE_STRUCT Res1920x1080Table[] = { {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ - (SyncNP | Charx8Dot | LineCompareOff), 60, 1, 0x38 }, + (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode), 60, 1, 0x38 }, {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ - (SyncNP | Charx8Dot | LineCompareOff), 0xFF, 1, 0x38 }, + (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode), 0xFF, 1, 0x38 }, }; VBIOS_DCLK_INFO DCLKTable [] = { @@ -250,6 +250,30 @@ VBIOS_DCLK_INFO DCLKTable [] = { {0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */ }; +VBIOS_DCLK_INFO DCLKTable_AST2100 [] = { + {0x2C, 0xE7, 0x03}, /* 00: VCLK25_175 */ + {0x95, 0x62, 0x03}, /* 01: VCLK28_322 */ + {0x67, 0x63, 0x01}, /* 02: VCLK31_5 */ + {0x76, 0x63, 0x01}, /* 03: VCLK36 */ + {0xEE, 0x67, 0x01}, /* 04: VCLK40 */ + {0x82, 0x62, 0x01}, /* 05: VCLK49_5 */ + {0xC6, 0x64, 0x01}, /* 06: VCLK50 */ + {0x94, 0x62, 0x01}, /* 07: VCLK56_25 */ + {0x80, 0x64, 0x00}, /* 08: VCLK65 */ + {0x7B, 0x63, 0x00}, /* 09: VCLK75 */ + {0x67, 0x62, 0x00}, /* 0A: VCLK78_75 */ + {0x7C, 0x62, 0x00}, /* 0B: VCLK94_5 */ + {0x8E, 0x62, 0x00}, /* 0C: VCLK108 */ + {0x85, 0x24, 0x00}, /* 0D: VCLK135 */ + {0x67, 0x22, 0x00}, /* 0E: VCLK157_5 */ + {0x6A, 0x22, 0x00}, /* 0F: VCLK162 */ + {0x4d, 0x4c, 0x80}, /* 10: VCLK154 */ + {0x68, 0x6f, 0x80}, /* 11: VCLK83.5 */ + {0x28, 0x49, 0x80}, /* 12: VCLK106.5 */ + {0x37, 0x49, 0x80}, /* 13: VCLK146.25 */ + {0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */ +}; + VBIOS_DAC_INFO DAC_TEXT[] = { { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x2a }, { 0x00, 0x2a, 0x00 }, { 0x00, 0x2a, 0x2a }, { 0x2a, 0x00, 0x00 }, { 0x2a, 0x00, 0x2a }, { 0x2a, 0x2a, 0x00 }, { 0x2a, 0x2a, 0x2a }, @@ -376,6 +400,11 @@ void vSetDCLKReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAMo void vSetExtReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo); void vSetSyncReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo); Bool bSetDACReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo); +BOOL bSetAST1180CRTCReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo); +BOOL bSetAST1180OffsetReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo); +BOOL bSetAST1180DCLKReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo); +BOOL bSetAST1180ExtReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo); +void vInitChontelReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo); Bool ASTSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) @@ -385,20 +414,34 @@ ASTSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) pAST = ASTPTR(pScrn); - vASTOpenKey(pScrn); - bASTRegInit(pScrn); - /* pre set mode */ bGetAST1000VGAModeInfo(pScrn, mode, &vgamodeinfo); - + /* set mode */ - vSetStdReg(pScrn, mode, &vgamodeinfo); - vSetCRTCReg(pScrn, mode, &vgamodeinfo); - vSetOffsetReg(pScrn, mode, &vgamodeinfo); - vSetDCLKReg(pScrn, mode, &vgamodeinfo); - vSetExtReg(pScrn, mode, &vgamodeinfo); - vSetSyncReg(pScrn, mode, &vgamodeinfo); - bSetDACReg(pScrn, mode, &vgamodeinfo); + if (pAST->jChipType == AST1180) + { + bInitAST1180(pScrn); + + bSetAST1180CRTCReg(pScrn, mode, &vgamodeinfo); + bSetAST1180OffsetReg(pScrn, mode, &vgamodeinfo); + bSetAST1180DCLKReg(pScrn, mode, &vgamodeinfo); + bSetAST1180ExtReg(pScrn, mode, &vgamodeinfo); + + vInitChontelReg(pScrn, mode, &vgamodeinfo); + } + else + { + vASTOpenKey(pScrn); + bASTRegInit(pScrn); + + vSetStdReg(pScrn, mode, &vgamodeinfo); + vSetCRTCReg(pScrn, mode, &vgamodeinfo); + vSetOffsetReg(pScrn, mode, &vgamodeinfo); + vSetDCLKReg(pScrn, mode, &vgamodeinfo); + vSetExtReg(pScrn, mode, &vgamodeinfo); + vSetSyncReg(pScrn, mode, &vgamodeinfo); + bSetDACReg(pScrn, mode, &vgamodeinfo); + } /* post set mode */ #ifdef Accel_2D @@ -526,9 +569,26 @@ Bool bGetAST1000VGAModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_ ulRefreshRateIndex = pVGAModeInfo->pEnhTableEntry->ulRefreshRateIndex; ulModeID = pVGAModeInfo->pEnhTableEntry->ulModeID; - SetIndexReg(CRTC_PORT, 0x8C, (UCHAR) ((ulColorIndex & 0x0F) << 4)); - SetIndexReg(CRTC_PORT, 0x8D, (UCHAR) (ulRefreshRateIndex & 0xFF)); - SetIndexReg(CRTC_PORT, 0x8E, (UCHAR) (ulModeID & 0xFF)); + if (pAST->jChipType == AST1180) + { + /* TODO */ + } + else + { + SetIndexReg(CRTC_PORT, 0x8C, (UCHAR) ((ulColorIndex & 0x0F) << 4)); + SetIndexReg(CRTC_PORT, 0x8D, (UCHAR) (ulRefreshRateIndex & 0xFF)); + SetIndexReg(CRTC_PORT, 0x8E, (UCHAR) (ulModeID & 0xFF)); + + /* NewModeInfo */ + SetIndexReg(CRTC_PORT, 0x91, 0xA8); /* signature */ + SetIndexReg(CRTC_PORT, 0x92, (UCHAR) (pScrn->bitsPerPixel) ); + SetIndexReg(CRTC_PORT, 0x93, (UCHAR) (mode->Clock / 1000) ); + SetIndexReg(CRTC_PORT, 0x94, (UCHAR) (mode->CrtcHDisplay) ); + SetIndexReg(CRTC_PORT, 0x95, (UCHAR) (mode->CrtcHDisplay >> 8) ); /* color depth */ + SetIndexReg(CRTC_PORT, 0x96, (UCHAR) (mode->CrtcVDisplay) ); + SetIndexReg(CRTC_PORT, 0x97, (UCHAR) (mode->CrtcVDisplay >> 8) ); /* color depth */ + + } return (TRUE); } @@ -688,7 +748,10 @@ void vSetDCLKReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAMo pAST = ASTPTR(pScrn); pEnhModePtr = pVGAModeInfo->pEnhTableEntry; - pDCLKPtr = &DCLKTable[pEnhModePtr->DCLKIndex]; + if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST1100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2150) || (pAST->jChipType == AST2300)) + pDCLKPtr = &DCLKTable_AST2100[pEnhModePtr->DCLKIndex]; + else + pDCLKPtr = &DCLKTable[pEnhModePtr->DCLKIndex]; SetIndexRegMask(CRTC_PORT,0xC0, 0x00, pDCLKPtr->Param1); SetIndexRegMask(CRTC_PORT,0xC1, 0x00, pDCLKPtr->Param2); @@ -797,4 +860,319 @@ Bool bSetDACReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAMod } +ULONG AST1180DCLKTable [] = { + 0x0008676b, /* 00: VCLK25_175 */ + 0x00086342, /* 01: VCLK28_322 */ + 0x00086568, /* 02: VCLK31_5 */ + 0x00082118, /* 03: VCLK36 */ + 0x0008232e, /* 04: VCLK40 */ + 0x000c256d, /* 05: VCLK49_5 */ + 0x00082016, /* 06: VCLK50 */ + 0x000c0010, /* 07: VCLK56_25 */ + 0x000c0332, /* 08: VCLK65 */ + 0x00080010, /* 09: VCLK75 */ + 0x000c033d, /* 0A: VCLK78_75 */ + 0x000c0568, /* 0B: VCLK94_5 */ + 0x00040118, /* 0C: VCLK108 */ + 0x00040334, /* 0D: VCLK135 */ + 0x0004033d, /* 0E: VCLK157_5 */ + 0x00040018, /* 0F: VCLK162 */ + 0x00040123, /* 10: VCLK154 */ + 0x000c0669, /* 11: VCLK83_5 */ + 0x0004074b, /* 12: VCLK106_5 */ + 0x0004022d, /* 13: VCLK146_25 */ + 0x00040769, /* 14: VCLK148_5 */ +}; + +BOOL bSetAST1180CRTCReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo) +{ + ASTRecPtr pAST = ASTPTR(pScrn); + + ULONG HTIndex, HRIndex, VTIndex, VRIndex; + ULONG HT, HDE, HBS, HBE, HRS, HRE; + ULONG VT, VDE, VBS, VBE, VRS, VRE; + ULONG HT2, HDE2, HRS2, HRE2; + ULONG VT2, VDE2, VRS2, VRE2; + + /* Reg. Index Select */ + { + HTIndex = AST1180_VGA1_HTREG; + HRIndex = AST1180_VGA1_HRREG; + VTIndex = AST1180_VGA1_VTREG; + VRIndex = AST1180_VGA1_VRREG; + } + + /* Get CRTC Info */ + HT = mode->CrtcHTotal; + HDE= mode->CrtcHDisplay; + HBS= mode->CrtcHBlankStart; + HBE= mode->CrtcHBlankEnd; + HRS= mode->CrtcHSyncStart; + HRE= mode->CrtcHSyncEnd; + VT = mode->CrtcVTotal; + VDE= mode->CrtcVDisplay; + VBS= mode->CrtcVBlankStart; + VBE= mode->CrtcVBlankEnd; + VRS= mode->CrtcVSyncStart; + VRE= mode->CrtcVSyncEnd; + + /* Calculate CRTC Reg Setting */ + HT2 = HT - 1; + HDE2 = HDE - 1; + HRS2 = HRS - 1; + HRE2 = HRE - 1; + VT2 = VT - 1; + VDE2 = VDE - 1; + VRS2 = VRS - 1; + VRE2 = VRE - 1; + + /* Write Reg */ + WriteAST1180SOC(AST1180_GFX_BASE + HTIndex, (ULONG)(HDE2 << 16) | (ULONG) (HT2)); + WriteAST1180SOC(AST1180_GFX_BASE + HRIndex, (ULONG)(HRE2 << 16) | (ULONG) (HRS2)); + WriteAST1180SOC(AST1180_GFX_BASE + VTIndex, (ULONG)(VDE2 << 16) | (ULONG) (VT2)); + WriteAST1180SOC(AST1180_GFX_BASE + VRIndex, (ULONG)(VRE2 << 16) | (ULONG) (VRS2)); + + return (TRUE); + +} /* bSetAST1180CRTCReg */ + +BOOL bSetAST1180OffsetReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo) +{ + ASTRecPtr pAST = ASTPTR(pScrn); + ULONG ulOffset, ulTermalCount; + + ulOffset = pAST->VideoModeInfo.ScreenPitch; + ulTermalCount = (pAST->VideoModeInfo.ScreenPitch + 7) >> 3; + + /* Write Reg */ + WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_OFFSET, (ULONG) (ulTermalCount << 16) | (ULONG) (ulOffset)); + + return (TRUE); + +} /* bSetAST1180OffsetReg */ + +BOOL bSetAST1180DCLKReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo) +{ + PVBIOS_ENHTABLE_STRUCT pEnhModePtr; + ASTRecPtr pAST = ASTPTR(pScrn); + ULONG ulDCLK; + + pEnhModePtr = pVGAModeInfo->pEnhTableEntry; + ulDCLK = AST1180DCLKTable[pEnhModePtr->DCLKIndex]; + if (pEnhModePtr->Flags & HalfDCLK) + ulDCLK |= 0x00400000; /* D[22]: div by 2 */ + WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_PLL, ulDCLK); + + return (TRUE); +} + +BOOL bSetAST1180ExtReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo) +{ + PVBIOS_ENHTABLE_STRUCT pEnhModePtr; + ASTRecPtr pAST = ASTPTR(pScrn); + + ULONG ulCtlRegIndex, ulCtlReg; /* enable display */ + ULONG ulCtlReg2Index, ulCtlReg2 = 0x80; /* single edge */ + ULONG ulThresholdRegIndex ; /* Threshold */ + ULONG ulStartAddressIndex; /* ulStartAddress */ + ULONG ulStartAddress = pAST->ulVRAMBase; + + /* Reg. Index Select */ + { + ulCtlRegIndex = AST1180_VGA1_CTRL; + ulCtlReg2Index = AST1180_VGA1_CTRL2; + ulThresholdRegIndex = AST1180_VGA1_THRESHOLD; + ulStartAddressIndex = AST1180_VGA1_STARTADDR; + } + + /* Mode Type Setting */ + ulCtlReg = 0x30000000; + { + switch (pScrn->bitsPerPixel) { + case 15: + case 16: + ulCtlReg |= 0x100001; /* RGB565, SCREEN OFF, ENABLE */ + break; + case 32: + ulCtlReg |= 0x100101; /* XRGB8888, SCREEN OFF, ENABLE */ + break; + } + } + + /* Polarity */ + pEnhModePtr = pVGAModeInfo->pEnhTableEntry; + ulCtlReg |= (ULONG) (pEnhModePtr->Flags & SyncNN) << 10; + + /* Single/Dual Edge */ + ulCtlReg2 |= 0x40; /* dual-edge */ + + /* Write Reg */ + WriteAST1180SOC(AST1180_GFX_BASE + ulStartAddressIndex, ulStartAddress); + WriteAST1180SOC(AST1180_GFX_BASE + ulThresholdRegIndex, ((ULONG) CRT_HIGH_THRESHOLD_VALUE << 8) | (ULONG) (CRT_LOW_THRESHOLD_VALUE)); + WriteAST1180SOC(AST1180_GFX_BASE + ulCtlReg2Index, ulCtlReg2); + WriteAST1180SOC(AST1180_GFX_BASE + ulCtlRegIndex, ulCtlReg); + + return (TRUE); + +} /* bSetAST1180ExtReg */ + +#define I2C_BASE_AST1180 0x80fcb000 +#define I2C_DEVICEADDR_AST1180 0x0EC /* slave addr */ + +void SetChrontelReg(ASTRecPtr pAST, UCHAR jChannel, UCHAR jIndex, UCHAR jData ) +{ + ULONG ulData, ulI2CAddr, ulI2CPortBase; + ULONG retry; + + { + ulI2CPortBase = I2C_BASE_AST1180 + 0x40 * jChannel; + ulI2CAddr = I2C_DEVICEADDR_AST1180; + } + + WriteAST1180SOC(ulI2CPortBase + 0x00, 0x00); + WriteAST1180SOC(ulI2CPortBase + 0x04, 0x77743355); + WriteAST1180SOC(ulI2CPortBase + 0x08, 0x0); + WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff); + WriteAST1180SOC(ulI2CPortBase + 0x00, 0x1); + WriteAST1180SOC(ulI2CPortBase + 0x0C, 0xAF); + WriteAST1180SOC(ulI2CPortBase + 0x20, ulI2CAddr); + WriteAST1180SOC(ulI2CPortBase + 0x14, 0x03); + retry = 0; + do { + ReadAST1180SOC(ulI2CPortBase + 0x10, ulData); + usleep(10); + if (retry++ > 1000) + goto Exit_SetChrontelReg; + } while (!(ulData & 0x01)); + + WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff); + WriteAST1180SOC(ulI2CPortBase + 0x20, (ULONG) jIndex); + WriteAST1180SOC(ulI2CPortBase + 0x14, 0x02); + do { + ReadAST1180SOC(ulI2CPortBase + 0x10, ulData); + } while (!(ulData & 0x01)); + + WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff); + WriteAST1180SOC(ulI2CPortBase + 0x20, (ULONG) jData); + WriteAST1180SOC(ulI2CPortBase + 0x14, 0x02); + do { + ReadAST1180SOC(ulI2CPortBase + 0x10, ulData); + } while (!(ulData & 0x01)); + + WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff); + WriteAST1180SOC(ulI2CPortBase + 0x0C, 0xBF); + WriteAST1180SOC(ulI2CPortBase + 0x14, 0x20); + do { + ReadAST1180SOC(ulI2CPortBase + 0x10, ulData); + } while (!(ulData & 0x10)); + + ReadAST1180SOC(ulI2CPortBase + 0x0C, ulData); + ulData &= 0xffffffef; + WriteAST1180SOC(ulI2CPortBase + 0x0C, ulData); + WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff); + +Exit_SetChrontelReg: + ; +} + +UCHAR GetChrontelReg(ASTRecPtr pAST, UCHAR jChannel, UCHAR jIndex) +{ + ULONG ulData, ulI2CAddr, ulI2CPortBase; + UCHAR jData; + ULONG retry; + + { + ulI2CPortBase = I2C_BASE_AST1180 + 0x40 * jChannel; + ulI2CAddr = I2C_DEVICEADDR_AST1180; + } + + WriteAST1180SOC(ulI2CPortBase + 0x00, 0x00); + WriteAST1180SOC(ulI2CPortBase + 0x04, 0x77743355); + WriteAST1180SOC(ulI2CPortBase + 0x08, 0x0); + WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff); + WriteAST1180SOC(ulI2CPortBase + 0x00, 0x1); + WriteAST1180SOC(ulI2CPortBase + 0x0C, 0xAF); + WriteAST1180SOC(ulI2CPortBase + 0x20, ulI2CAddr); + WriteAST1180SOC(ulI2CPortBase + 0x14, 0x03); + retry = 0; + do { + ReadAST1180SOC(ulI2CPortBase + 0x10, ulData); + usleep(10); + if (retry++ > 1000) + return 0; + } while (!(ulData & 0x01)); + + WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff); + WriteAST1180SOC(ulI2CPortBase + 0x20, (ULONG) jIndex); + WriteAST1180SOC(ulI2CPortBase + 0x14, 0x02); + do { + ReadAST1180SOC(ulI2CPortBase + 0x10, ulData); + } while (!(ulData & 0x01)); + + WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff); + WriteAST1180SOC(ulI2CPortBase + 0x20, (ULONG) (ulI2CAddr + 1) ); + WriteAST1180SOC(ulI2CPortBase + 0x14, 0x1B); + do { + ReadAST1180SOC(ulI2CPortBase + 0x10, ulData); + } while (!(ulData & 0x04)); + + WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff); + WriteAST1180SOC(ulI2CPortBase + 0x0C, 0xBF); + WriteAST1180SOC(ulI2CPortBase + 0x14, 0x20); + do { + ReadAST1180SOC(ulI2CPortBase + 0x10, ulData); + } while (!(ulData & 0x10)); + + ReadAST1180SOC(ulI2CPortBase + 0x0C, ulData); + ulData &= 0xffffffef; + WriteAST1180SOC(ulI2CPortBase + 0x0C, ulData); + WriteAST1180SOC(ulI2CPortBase + 0x10, 0xffffffff); + + ReadAST1180SOC(ulI2CPortBase + 0x20, ulData); + jData = (UCHAR) ((ulData & 0xFF00) >> 8); + + return (jData); +} + +void vInitChontelReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo) +{ + + PVBIOS_ENHTABLE_STRUCT pEnhModePtr = pVGAModeInfo->pEnhTableEntry; + ASTRecPtr pAST = ASTPTR(pScrn); + ULONG ulDCLK = 65; /* todo */ + UCHAR jReg; + + jReg = GetChrontelReg(pAST, 1, 0x4A); /* get vendor id */ + if (jReg == 0x95) + { + jReg = GetChrontelReg(pAST, 1, 0x20); /* DVI/D-Sub */ + if (jReg & 0x20) /* DVI */ + { + + /* DVI PLL Filter */ + if (ulDCLK > 65) + { + SetChrontelReg(pAST, 1, 0x33, 0x06); + SetChrontelReg(pAST, 1, 0x34, 0x26); + SetChrontelReg(pAST, 1, 0x36, 0xA0); + } + else + { + SetChrontelReg(pAST, 1, 0x33, 0x08); + SetChrontelReg(pAST, 1, 0x34, 0x16); + SetChrontelReg(pAST, 1, 0x36, 0x60); + } + + SetChrontelReg(pAST, 1, 0x49, 0xc0); + } + else /* D-Sub */ + { + + SetChrontelReg(pAST, 1, 0x21, 0x09); + SetChrontelReg(pAST, 1, 0x49, 0x00); + SetChrontelReg(pAST, 1, 0x56, 0x00); + } + } + +} diff --git a/src/ast_mode.h b/src/ast_mode.h index 1b3cd66..aae1492 100644 --- a/src/ast_mode.h +++ b/src/ast_mode.h @@ -66,6 +66,7 @@ #define SyncNN 0x000000C0 #define HBorder 0x00000020 #define VBorder 0x00000010 +#define WideScreenMode 0x00000100 /* DAC Definition */ #define DAC_NUM_TEXT 64 diff --git a/src/ast_vgatool.c b/src/ast_vgatool.c index 356e7ba..763abc4 100644 --- a/src/ast_vgatool.c +++ b/src/ast_vgatool.c @@ -70,7 +70,10 @@ void ASTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, in Bool GetVGA2EDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer); void vInitDRAMReg(ScrnInfoPtr pScrn); Bool bIsVGAEnabled(ScrnInfoPtr pScrn); -Bool InitVGA(ScrnInfoPtr pScrn); +Bool InitVGA(ScrnInfoPtr pScrn, ULONG Flags); +Bool GetVGAEDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer); +Bool bInitAST1180(ScrnInfoPtr pScrn); +void GetAST1180DRAMInfo(ScrnInfoPtr pScrn); void vASTOpenKey(ScrnInfoPtr pScrn) @@ -97,40 +100,93 @@ void GetDRAMInfo(ScrnInfoPtr pScrn) { ASTRecPtr pAST = ASTPTR(pScrn); - ULONG ulData; + ULONG ulRefPLL, ulDeNumerator, ulNumerator, ulDivider; + ULONG ulData, ulData2; + + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000; + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; + + *(ULONG *) (pAST->MMIOVirtualAddr + 0x10000) = 0xFC600309; + do { + ; + } while (*(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x10000) != 0x01); + + ulData = *(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x10004); - if ( (pAST->jChipType != AST2000) ) + /* Get BusWidth */ + if (ulData & 0x40) + pAST->ulDRAMBusWidth = 16; + else + pAST->ulDRAMBusWidth = 32; + + /* Get DRAM Type */ + if (pAST->jChipType == AST2300) + { + switch (ulData & 0x03) + { + case 0x00: + pAST->jDRAMType = DRAMTYPE_512Mx16; + break; + default: + case 0x01: + pAST->jDRAMType = DRAMTYPE_1Gx16; + break; + case 0x02: + pAST->jDRAMType = DRAMTYPE_2Gx16; + break; + case 0x03: + pAST->jDRAMType = DRAMTYPE_4Gx16; + break; + } + } + else { - *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000; - *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; - - *(ULONG *) (pAST->MMIOVirtualAddr + 0x10000) = 0xFC600309; - do { - ; - } while (*(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x10000) != 0x01); - - ulData = *(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x10004); - switch (ulData & 0x0C) { case 0x00: case 0x04: pAST->jDRAMType = DRAMTYPE_512Mx16; break; - + case 0x08: if (ulData & 0x40) /* 16bits */ pAST->jDRAMType = DRAMTYPE_1Gx16; else /* 32bits */ pAST->jDRAMType = DRAMTYPE_512Mx32; break; - + case 0x0C: pAST->jDRAMType = DRAMTYPE_1Gx32; break; - } - } - + } + } + + /* Get MCLK */ + ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x10120); + ulData2 = *(ULONG *) (pAST->MMIOVirtualAddr + 0x10170); + if (ulData2 & 0x2000) + ulRefPLL = 14318; + else + ulRefPLL = 12000; + + ulDeNumerator = ulData & 0x1F; + ulNumerator = (ulData & 0x3FE0) >> 5; + + ulData = (ulData & 0xC000) >> 14; + switch (ulData) + { + case 0x03: + ulDivider = 0x04; + break; + case 0x02: + case 0x01: + ulDivider = 0x02; + break; + default: + ulDivider = 0x01; + } + pAST->ulMCLK = ulRefPLL * (ulNumerator + 2) / ((ulDeNumerator + 2) * ulDivider * 1000); + } /* GetDRAMInfo */ ULONG @@ -164,78 +220,40 @@ GetMaxDCLK(ScrnInfoPtr pScrn) { ASTRecPtr pAST = ASTPTR(pScrn); UCHAR jReg; - ULONG ulData, ulData2; - ULONG ulRefPLL, ulDeNumerator, ulNumerator, ulDivider; ULONG ulDRAMBusWidth, ulMCLK, ulDRAMBandwidth, ActualDRAMBandwidth, DRAMEfficiency = 500; ULONG ulDCLK; - - vASTOpenKey(pScrn); - *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000; - *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x00000001; - - *(ULONG *) (pAST->MMIOVirtualAddr + 0x10100) = 0x000000A8; - - do { - ; - } while (*(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x10100) != 0x000000A8); - - /* Get BusWidth */ - ulData = *(ULONG * ) (pAST->MMIOVirtualAddr + 0x10004); - if (ulData & 0x40) - ulDRAMBusWidth = 16; - else - ulDRAMBusWidth = 32; - - /* Get MCLK */ - { - ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x10120); - ulData2 = *(ULONG *) (pAST->MMIOVirtualAddr + 0x10170); - if (ulData2 & 0x2000) - ulRefPLL = 14318; - else - ulRefPLL = 12000; - - ulDeNumerator = ulData & 0x1F; - ulNumerator = (ulData & 0x3FE0) >> 5; - - ulData = (ulData & 0xC000) >> 14; - switch (ulData) - { - case 0x03: - ulDivider = 0x04; - break; - case 0x02: - case 0x01: - ulDivider = 0x02; - break; - default: - ulDivider = 0x01; - } - - ulMCLK = ulRefPLL * (ulNumerator + 2) / ((ulDeNumerator + 2) * ulDivider * 1000); - - } + ulMCLK = pAST->ulMCLK; + ulDRAMBusWidth = pAST->ulDRAMBusWidth; /* Get Bandwidth */ /* Modify DARM utilization to 60% for AST1100/2100 16bits DRAM, ycchen@032508 */ - if ( ((pAST->jChipType == AST2100) || (pAST->jChipType == AST1100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2150) || (pAST->jChipType == AST2300)) && (ulDRAMBusWidth == 16) ) - DRAMEfficiency = 600; + if ( ((pAST->jChipType == AST2100) || (pAST->jChipType == AST1100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2150)) && (ulDRAMBusWidth == 16) ) + DRAMEfficiency = 600; + else if (pAST->jChipType == AST2300) + DRAMEfficiency = 400; ulDRAMBandwidth = ulMCLK * ulDRAMBusWidth * 2 / 8; ActualDRAMBandwidth = ulDRAMBandwidth * DRAMEfficiency / 1000; /* Get Max DCLK */ - /* Fixed Fixed KVM + CRT threshold issue on AST2100 8bpp modes, ycchen@100708 */ - GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg); - if ((jReg & 0x08) && (pAST->jChipType == AST2000)) - ulDCLK = ActualDRAMBandwidth / ((pScrn->bitsPerPixel+1+16) / 8); - else if ((jReg & 0x08) && (pScrn->bitsPerPixel == 8)) - ulDCLK = ActualDRAMBandwidth / ((pScrn->bitsPerPixel+1+24) / 8); - else - ulDCLK = ActualDRAMBandwidth / ((pScrn->bitsPerPixel+1) / 8); + if (pAST->jChipType == AST1180) + { + ulDCLK = ActualDRAMBandwidth / ((pScrn->bitsPerPixel+1) / 8); + } + else + { + /* Fixed Fixed KVM + CRT threshold issue on AST2100 8bpp modes, ycchen@100708 */ + GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg); + if ((jReg & 0x08) && (pAST->jChipType == AST2000)) + ulDCLK = ActualDRAMBandwidth / ((pScrn->bitsPerPixel+1+16) / 8); + else if ((jReg & 0x08) && (pScrn->bitsPerPixel == 8)) + ulDCLK = ActualDRAMBandwidth / ((pScrn->bitsPerPixel+1+24) / 8); + else + ulDCLK = ActualDRAMBandwidth / ((pScrn->bitsPerPixel+1) / 8); + } /* Add for AST2100, ycchen@061807 */ - if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300)) + if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST1180) ) { if (ulDCLK > 200) ulDCLK = 200; } @@ -295,26 +313,53 @@ GetChipType(ScrnInfoPtr pScrn) void vSetStartAddressCRT1(ASTRecPtr pAST, ULONG base) { - SetIndexReg(CRTC_PORT,0x0D, (UCHAR) (base & 0xFF)); - SetIndexReg(CRTC_PORT,0x0C, (UCHAR) ((base >> 8) & 0xFF)); - SetIndexReg(CRTC_PORT,0xAF, (UCHAR) ((base >> 16) & 0xFF)); + ULONG addr; + if (pAST->jChipType == AST1180) + { + addr = pAST->ulVRAMBase + base; + WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_STARTADDR, addr); + } + else + { + addr = base >> 2; /* DW unit */ + + SetIndexReg(CRTC_PORT,0x0D, (UCHAR) (addr & 0xFF)); + SetIndexReg(CRTC_PORT,0x0C, (UCHAR) ((addr >> 8) & 0xFF)); + SetIndexReg(CRTC_PORT,0xAF, (UCHAR) ((addr >> 16) & 0xFF)); + } + } void vAST1000DisplayOff(ASTRecPtr pAST) { - SetIndexRegMask(SEQ_PORT,0x01, 0xDF, 0x20); - + ULONG ulData; + + if (pAST->jChipType == AST1180) + { + ReadAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL, ulData); + ulData |= 0x00100000; + WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL, ulData); + } + else + SetIndexRegMask(SEQ_PORT,0x01, 0xDF, 0x20); } void vAST1000DisplayOn(ASTRecPtr pAST) { + ULONG ulData; - SetIndexRegMask(SEQ_PORT,0x01, 0xDF, 0x00); - + if (pAST->jChipType == AST1180) + { + ReadAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL, ulData); + ulData &= 0xFFEFFFFF; + WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL, ulData); + } + else + SetIndexRegMask(SEQ_PORT,0x01, 0xDF, 0x00); } void ASTBlankScreen(ScrnInfoPtr pScrn, Bool unblack) @@ -399,129 +444,163 @@ ASTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int fla { ASTRecPtr pAST; UCHAR SEQ01, CRB6; - + ULONG ulData, ulTemp; + pAST = ASTPTR(pScrn); SEQ01=CRB6=0; - + ulData = 0; + vASTOpenKey(pScrn); - + switch (PowerManagementMode) { case DPMSModeOn: /* Screen: On; HSync: On, VSync: On */ SEQ01 = 0x00; CRB6 = 0x00; + ulData = 0x00000000; break; case DPMSModeStandby: /* Screen: Off; HSync: Off, VSync: On */ SEQ01 = 0x20; - CRB6 = 0x01; + CRB6 = 0x01; + ulData = 0x00140000; break; case DPMSModeSuspend: /* Screen: Off; HSync: On, VSync: Off */ SEQ01 = 0x20; - CRB6 = 0x02; + CRB6 = 0x02; + ulData = 0x00180000; break; case DPMSModeOff: /* Screen: Off; HSync: Off, VSync: Off */ SEQ01 = 0x20; - CRB6 = 0x03; + CRB6 = 0x03; + ulData = 0x001C0000; break; } - SetIndexRegMask(SEQ_PORT,0x01, 0xDF, SEQ01); - SetIndexRegMask(CRTC_PORT,0xB6, 0xFC, CRB6); - + if (pAST->jChipType == AST1180) + { + ReadAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL, ulTemp); + ulTemp &= 0xFFE3FFFF; + ulTemp |= ulData; + WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL, ulTemp); + } + else + { + SetIndexRegMask(SEQ_PORT,0x01, 0xDF, SEQ01); + SetIndexRegMask(CRTC_PORT,0xB6, 0xFC, CRB6); + } } -#define I2C_BASE 0x1e780000 -#define I2C_OFFSET (0xA000 + 0x40 * 4) /* port4 */ -#define I2C_DEVICEADDR 0x0A0 /* slave addr */ + +#define I2C_BASE 0x1e780000 +#define I2C_OFFSET (0xA000 + 0x40 * 4) /* port4 */ +#define I2C_DEVICEADDR 0x0A0 /* slave addr */ + +#define I2C_BASE_AST1180 0x80fc0000 +#define I2C_OFFSET_AS1180 (0xB000 + 0x40 * 2) /* port2 */ +#define I2C_DEVICEADDR_AST1180 0x0A0 /* slave addr */ Bool GetVGA2EDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer) { ASTRecPtr pAST = ASTPTR(pScrn); - UCHAR *ulI2CBase = pAST->MMIOVirtualAddr + 0x10000 + I2C_OFFSET; ULONG i, ulData; UCHAR *pjEDID; + ULONG base, deviceaddr; + UCHAR *offset; pjEDID = pEDIDBuffer; - /* SCU settings */ - *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000; - *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; - usleep(10000); + if (pAST->jChipType == AST1180) + { + base = I2C_BASE_AST1180; + offset = pAST->MMIOVirtualAddr + 0x10000 + I2C_OFFSET_AS1180; + deviceaddr = I2C_DEVICEADDR_AST1180; + } + else + { + base = I2C_BASE; + offset = pAST->MMIOVirtualAddr + 0x10000 + I2C_OFFSET; + deviceaddr = I2C_DEVICEADDR; + + /* SCU settings */ + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000; + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; + usleep(10000); + + *(ULONG *) (pAST->MMIOVirtualAddr + 0x12000) = 0x1688A8A8; + ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12004); + ulData &= 0xfffffffb; + *(ULONG *) (pAST->MMIOVirtualAddr + 0x12004) = ulData; + usleep(10000); + } - *(ULONG *) (pAST->MMIOVirtualAddr + 0x12000) = 0x1688A8A8; - ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12004); - ulData &= 0xfffffffb; - *(ULONG *) (pAST->MMIOVirtualAddr + 0x12004) = ulData; - usleep(10000); - /* I2C settings */ - *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = I2C_BASE; + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = base; *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; usleep(10000); /* I2C Start */ - *(ULONG *) (ulI2CBase + 0x00) = 0x0; - *(ULONG *) (ulI2CBase + 0x04) = 0x77777355; - *(ULONG *) (ulI2CBase + 0x08) = 0x0; - *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; - *(ULONG *) (ulI2CBase + 0x00) = 0x1; - *(ULONG *) (ulI2CBase + 0x0C) = 0xAF; - *(ULONG *) (ulI2CBase + 0x20) = I2C_DEVICEADDR; - *(ULONG *) (ulI2CBase + 0x14) = 0x03; + *(ULONG *) (offset + 0x00) = 0x0; + *(ULONG *) (offset + 0x04) = 0x77777355; + *(ULONG *) (offset + 0x08) = 0x0; + *(ULONG *) (offset + 0x10) = 0xffffffff; + *(ULONG *) (offset + 0x00) = 0x1; + *(ULONG *) (offset + 0x0C) = 0xAF; + *(ULONG *) (offset + 0x20) = deviceaddr; + *(ULONG *) (offset + 0x14) = 0x03; do { - ulData = *(volatile ULONG *) (ulI2CBase + 0x10); + ulData = *(volatile ULONG *) (offset + 0x10); } while (!(ulData & 0x03)); if (ulData & 0x02) /* NACK */ return (FALSE); - *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; - *(ULONG *) (ulI2CBase + 0x20) = (ULONG) 0; /* Offset */ - *(ULONG *) (ulI2CBase + 0x14) = 0x02; + *(ULONG *) (offset + 0x10) = 0xffffffff; + *(ULONG *) (offset + 0x20) = (ULONG) 0; /* Offset */ + *(ULONG *) (offset + 0x14) = 0x02; do { - ulData = *(volatile ULONG *) (ulI2CBase + 0x10); + ulData = *(volatile ULONG *) (offset + 0x10); } while (!(ulData & 0x01)); - *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; - *(ULONG *) (ulI2CBase + 0x20) = I2C_DEVICEADDR + 1; - *(ULONG *) (ulI2CBase + 0x14) = 0x03; + *(ULONG *) (offset + 0x10) = 0xffffffff; + *(ULONG *) (offset + 0x20) = deviceaddr + 1; + *(ULONG *) (offset + 0x14) = 0x03; do { - ulData = *(volatile ULONG *) (ulI2CBase + 0x10); + ulData = *(volatile ULONG *) (offset + 0x10); } while (!(ulData & 0x01)); /* I2C Read */ for (i=0; i<127; i++) { - *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; - *(ULONG *) (ulI2CBase + 0x0C) |= 0x10; - *(ULONG *) (ulI2CBase + 0x14) = 0x08; + *(ULONG *) (offset + 0x10) = 0xffffffff; + *(ULONG *) (offset + 0x0C) |= 0x10; + *(ULONG *) (offset + 0x14) = 0x08; do { - ulData = *(volatile ULONG *) (ulI2CBase + 0x10); + ulData = *(volatile ULONG *) (offset + 0x10); } while (!(ulData & 0x04)); - *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; - *(UCHAR *) (pjEDID++) = (UCHAR) ((*(ULONG *) (ulI2CBase + 0x20) & 0xFF00) >> 8); + *(ULONG *) (offset + 0x10) = 0xffffffff; + *(UCHAR *) (pjEDID++) = (UCHAR) ((*(ULONG *) (offset + 0x20) & 0xFF00) >> 8); } /* Read Last Byte */ - *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; - *(ULONG *) (ulI2CBase + 0x0C) |= 0x10; - *(ULONG *) (ulI2CBase + 0x14) = 0x18; + *(ULONG *) (offset + 0x10) = 0xffffffff; + *(ULONG *) (offset + 0x0C) |= 0x10; + *(ULONG *) (offset + 0x14) = 0x18; do { - ulData = *(volatile ULONG *) (ulI2CBase + 0x10); + ulData = *(volatile ULONG *) (offset + 0x10); } while (!(ulData & 0x04)); - *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; - *(UCHAR *) (pjEDID++) = (UCHAR) ((*(ULONG *) (ulI2CBase + 0x20) & 0xFF00) >> 8); + *(ULONG *) (offset + 0x10) = 0xffffffff; + *(UCHAR *) (pjEDID++) = (UCHAR) ((*(ULONG *) (offset + 0x20) & 0xFF00) >> 8); /* I2C Stop */ - *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; - *(ULONG *) (ulI2CBase + 0x14) = 0x20; + *(ULONG *) (offset + 0x10) = 0xffffffff; + *(ULONG *) (offset + 0x14) = 0x20; do { - ulData = *(volatile ULONG *) (ulI2CBase + 0x10); + ulData = *(volatile ULONG *) (offset + 0x10); } while (!(ulData & 0x10)); - *(ULONG *) (ulI2CBase + 0x0C) &= 0xffffffef; - *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; + *(ULONG *) (offset + 0x0C) &= 0xffffffef; + *(ULONG *) (offset + 0x10) = 0xffffffff; return (TRUE); @@ -532,21 +611,32 @@ Bool bIsVGAEnabled(ScrnInfoPtr pScrn) { ASTRecPtr pAST; UCHAR ch; + ULONG ulData; pAST = ASTPTR(pScrn); - ch = GetReg(pAST->RelocateIO+0x43); - - if (ch) + if (pAST->jChipType == AST1180) + { + WriteAST1180SOC(AST1180_MMC_BASE+0x00, 0xFC600309); /* unlock */ + ReadAST1180SOC(AST1180_MMC_BASE+0x08, ulData); + return (ulData); + } + else { - vASTOpenKey(pScrn); + ch = GetReg(pAST->RelocateIO+0x43); + + if (ch) + { + + vASTOpenKey(pScrn); - GetIndexRegMask(CRTC_PORT, 0xB6, 0xFF, ch); + GetIndexRegMask(CRTC_PORT, 0xB6, 0xFF, ch); - return (ch & 0x04); + return (ch & 0x04); + } } - + return (0); } @@ -568,17 +658,24 @@ UCHAR ExtRegInfo[] = { 0xFF }; +UCHAR ExtRegInfo_AST2300A0[] = { + 0x0F, + 0x04, + 0x1C, + 0xFF +}; + UCHAR ExtRegInfo_AST2300[] = { 0x0F, 0x04, - 0x1D, + 0x1F, 0xFF }; void vSetDefExtReg(ScrnInfoPtr pScrn) { ASTRecPtr pAST; - UCHAR i, jIndex, *pjExtRegInfo; + UCHAR i, jIndex, jReg, *pjExtRegInfo; pAST = ASTPTR(pScrn); @@ -590,7 +687,12 @@ void vSetDefExtReg(ScrnInfoPtr pScrn) /* Set Ext. Reg */ if (pAST->jChipType == AST2300) - pjExtRegInfo = ExtRegInfo_AST2300; + { + if (PCI_DEV_REVISION(pAST->PciInfo) > 0x20) + pjExtRegInfo = ExtRegInfo_AST2300; + else + pjExtRegInfo = ExtRegInfo_AST2300A0; + } else pjExtRegInfo = ExtRegInfo; @@ -611,9 +713,12 @@ void vSetDefExtReg(ScrnInfoPtr pScrn) SetIndexRegMask(CRTC_PORT,0xB7, 0x00, 0x00); /* Enable RAMDAC for A1, ycchen@113005 */ - SetIndexRegMask(CRTC_PORT,0xB6, 0xFF, 0x04); + jReg = 0x04; + if (pAST->jChipType == AST2300) + jReg |= 0x20; + SetIndexRegMask(CRTC_PORT,0xB6, 0xFF, jReg); -} +} typedef struct _AST_DRAMStruct { @@ -856,7 +961,1018 @@ void vInitDRAMReg(ScrnInfoPtr pScrn) } /* vInitDRAMReg */ -Bool InitVGA(ScrnInfoPtr pScrn) +/* + * AST2300 DRAM settings modules + */ +#define DDR3 0 +#define DDR2 1 + +typedef struct _AST2300DRAMParam { + UCHAR *pjMMIOVirtualAddress; + ULONG DRAM_Type; + ULONG DRAM_ChipID; + ULONG DRAM_Freq; + ULONG VRAM_Size; + ULONG ODT; /* 0/75/150 */ + ULONG WODT; /* 0/40/60/120 */ + ULONG RODT; + + ULONG DRAM_CONFIG; + ULONG REG_PERIOD; + ULONG REG_MADJ; + ULONG REG_SADJ; + ULONG REG_MRS; + ULONG REG_EMRS; + ULONG REG_AC1; + ULONG REG_AC2; + ULONG REG_DQSIC; + ULONG REG_DRV; + ULONG REG_IOZ; + ULONG REG_DQIDLY; + ULONG REG_FREQ; + +} AST2300DRAMParam, *PAST2300DRAMParam; + +__inline ULONG MIndwm(UCHAR *mmiobase, ULONG r) +{ + *(ULONG *) (mmiobase + 0xF004) = r & 0xFFFF0000; + *(ULONG *) (mmiobase + 0xF000) = 0x1; + + return ( *(volatile ULONG *) (mmiobase + 0x10000 + (r & 0x0000FFFF)) ); + +} + +__inline void MOutdwm(UCHAR *mmiobase, ULONG r, ULONG v) +{ + + *(ULONG *) (mmiobase + 0xF004) = r & 0xFFFF0000; + *(ULONG *) (mmiobase + 0xF000) = 0x1; + + *(volatile ULONG *) (mmiobase + 0x10000 + (r & 0x0000FFFF)) = v; +} + +/* + * DQSI DLL CBR Setting + */ +#define CBR_SIZE1 (256 - 1) +#define CBR_SIZE2 ((256 << 10) - 1) +#define CBR_PASSNUM 5 +#define CBR_PASSNUM2 5 +#define TIMEOUT 5000000 + +#define CBR_PATNUM 8 + +ULONG pattern[8] ={ +0xFF00FF00, +0xCC33CC33, +0xAA55AA55, +0x88778877, +0x4D8223F3, +0x7EE02E83, +0x59E21CFB, +0x6ABB60C0}; + +int MMCTestBurst(PAST2300DRAMParam param, ULONG datagen) +{ + ULONG data, timeout; + UCHAR *mmiobase; + + mmiobase = param->pjMMIOVirtualAddress; + + MOutdwm(mmiobase, 0x1E6E0070, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0070, 0x000000C1 | (datagen << 3)); + timeout = 0; + do{ + data = MIndwm(mmiobase, 0x1E6E0070) & 0x3000; + if(data & 0x2000){ + return(0); + } + if(++timeout > TIMEOUT){ + MOutdwm(mmiobase, 0x1E6E0070, 0x00000000); + return(0); + } + }while(!data); + MOutdwm(mmiobase, 0x1E6E0070, 0x00000000); + return(1); +} + +int MMCTestSingle(PAST2300DRAMParam param, ULONG datagen) +{ + ULONG data, timeout; + UCHAR *mmiobase; + + mmiobase = param->pjMMIOVirtualAddress; + + MOutdwm(mmiobase, 0x1E6E0070, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0070, 0x000000C5 | (datagen << 3)); + timeout = 0; + do{ + data = MIndwm(mmiobase, 0x1E6E0070) & 0x3000; + if(data & 0x2000){ + return(0); + } + if(++timeout > TIMEOUT){ + MOutdwm(mmiobase, 0x1E6E0070, 0x00000000); + return(0); + } + }while(!data); + MOutdwm(mmiobase, 0x1E6E0070, 0x00000000); + return(1); +} + +int CBRTest(PAST2300DRAMParam param, ULONG pattern) +{ + ULONG i,retry; + ULONG data; + UCHAR *mmiobase; + + mmiobase = param->pjMMIOVirtualAddress; + + MOutdwm(mmiobase, 0x1E6E007C, pattern); + if(!MMCTestBurst(param,0)) return(0); + if(!MMCTestSingle(param,0)) return(0); + if(!MMCTestBurst(param,1)) return(0); + if(!MMCTestBurst(param,2)) return(0); + if(!MMCTestBurst(param,3)) return(0); + if(!MMCTestBurst(param,4)) return(0); + if(!MMCTestBurst(param,5)) return(0); + if(!MMCTestBurst(param,6)) return(0); + if(!MMCTestBurst(param,7)) return(0); + return(1); +} + +int CBRScan(PAST2300DRAMParam param, ULONG testsize) +{ + ULONG patcnt, loop; + UCHAR *mmiobase; + + mmiobase = param->pjMMIOVirtualAddress; + + MOutdwm(mmiobase, 0x1E6E0074, testsize); + for(patcnt = 0;patcnt < CBR_PATNUM;patcnt++){ + for(loop = 0;loop < CBR_PASSNUM2;loop++){ + if(CBRTest(param,pattern[patcnt])){ + break; + } + } + if(loop == CBR_PASSNUM2){ + return(0); + } + } + return(1); +} + +ULONG CBRTest2(PAST2300DRAMParam param, ULONG pattern) +{ + ULONG errorbit = 0x0; + UCHAR *mmiobase; + + mmiobase = param->pjMMIOVirtualAddress; + + MOutdwm(mmiobase, 0x1E6E007C, pattern); + if(!MMCTestBurst(param,0)) errorbit |= MIndwm(mmiobase, 0x1E6E0078); + if(!MMCTestSingle(param,0)) errorbit |= MIndwm(mmiobase, 0x1E6E0078); + return(errorbit); +} + +int CBRScan2(PAST2300DRAMParam param, ULONG testsize, ULONG errormask) +{ + ULONG patcnt, loop, data; + UCHAR *mmiobase; + + mmiobase = param->pjMMIOVirtualAddress; + + MOutdwm(mmiobase, 0x1E6E0074, testsize); + for(patcnt = 0;patcnt < CBR_PATNUM;patcnt++){ + for(loop = 0;loop < CBR_PASSNUM2;loop++){ + if(!(data = CBRTest2(param, pattern[patcnt]) & errormask)){ + break; + } + } + if(loop == CBR_PASSNUM2){ + return(0); + } + } + return(1); +} + +void finetuneDQI(PAST2300DRAMParam param) +{ + ULONG gold_sadj, dqbit, dllmin, dllmax, dlli, errormask, data, cnt; + UCHAR *mmiobase; + + mmiobase = param->pjMMIOVirtualAddress; + + gold_sadj = (MIndwm(mmiobase, 0x1E6E0024) >> 16) & 0xff; + + errormask = 0x00010001; + for(dqbit = 0;dqbit < 16;dqbit++){ + dllmin = 0xff; + dllmax = 0x0; + for(dlli = 0;dlli < 76;dlli++){ + MOutdwm(mmiobase, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24)); + /* Wait DQSI latch phase calibration */ + MOutdwm(mmiobase, 0x1E6E0074, 0x00000020); + MOutdwm(mmiobase, 0x1E6E0070, 0x00000003); + do{ + data = MIndwm(mmiobase, 0x1E6E0070); + }while(!(data & 0x00001000)); + MOutdwm(mmiobase, 0x1E6E0070, 0x00000000); + + for(cnt = 0;cnt < CBR_PASSNUM;cnt++){ + if(CBRScan2(param, CBR_SIZE1,errormask)){ + break; + } + } + if(cnt < CBR_PASSNUM){ + if(dllmin > dlli){ + dllmin = dlli; + } + if(dllmax < dlli){ + dllmax = dlli; + } + }else if(dlli > dllmin){ + break; + } + } + errormask = errormask << 1; + dlli = (dllmin + dllmax) >> 1; + if(gold_sadj >= dlli){ + dlli = (gold_sadj - dlli) >> 1; + if(dlli > 3){ + dlli = 3; + }else{ + dlli &= 0x3; + } + }else{ + dlli = (dlli - gold_sadj) >> 1; + if(dlli > 4){ + dlli = 4; + }else{ + dlli &= 0x7; + } + dlli = (0-dlli) & 0x7; + } + dlli = dlli << ((dqbit & 0x7) * 3); + if(dqbit < 8){ + MOutdwm(mmiobase, 0x1E6E0080, MIndwm(mmiobase, 0x1E6E0080) | dlli); + }else{ + MOutdwm(mmiobase, 0x1E6E0084, MIndwm(mmiobase, 0x1E6E0084) | dlli); + } + } +} + +void CBRDLL2(PAST2300DRAMParam param) +{ + ULONG dllmin, dllmax, dlli, cnt, data, data2; + UCHAR *mmiobase; + + mmiobase = param->pjMMIOVirtualAddress; + + CBR_START: + dllmin = 0xff; + dllmax = 0x0; + for(dlli = 0;dlli < 76;dlli++){ + MOutdwm(mmiobase, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24)); + /* Wait DQSI latch phase calibration */ + MOutdwm(mmiobase, 0x1E6E0074, 0x00000020); + MOutdwm(mmiobase, 0x1E6E0070, 0x00000003); + do{ + data = MIndwm(mmiobase, 0x1E6E0070); + }while(!(data & 0x00001000)); + MOutdwm(mmiobase, 0x1E6E0070, 0x00000000); + + for(cnt = 0;cnt < CBR_PASSNUM;cnt++){ + if(CBRScan(param, CBR_SIZE1)){ + break; + } + } + if(cnt < CBR_PASSNUM){ + if(dllmin > dlli){ + dllmin = dlli; + } + if(dllmax < dlli){ + dllmax = dlli; + } + }else if(dlli > dllmin){ + break; + } + } + if(dllmax != 0 && (dllmax-dllmin) < 10){ + goto CBR_START; + } + /* dlli = dllmin + (int)((float)(dllmax - dllmin) * 0.5); */ + dlli = (dllmin + dllmax) >> 1; + MOutdwm(mmiobase, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24)); + + finetuneDQI(param); + + CBR_START2: + dllmin = 0xff; + dllmax = 0x0; + for(dlli = 0;dlli < 76;dlli++){ + MOutdwm(mmiobase, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24)); + /* Wait DQSI latch phase calibration */ + MOutdwm(mmiobase, 0x1E6E0074, 0x00000020); + MOutdwm(mmiobase, 0x1E6E0070, 0x00000003); + do{ + data = MIndwm(mmiobase, 0x1E6E0070); + }while(!(data & 0x00001000)); + MOutdwm(mmiobase, 0x1E6E0070, 0x00000000); + + for(cnt = 0;cnt < CBR_PASSNUM;cnt++){ + if(CBRScan(param, CBR_SIZE2)){ + break; + } + } + if(cnt < CBR_PASSNUM){ + if(dllmin > dlli){ + dllmin = dlli; + } + if(dllmax < dlli){ + dllmax = dlli; + } + }else if(dlli > dllmin){ + break; + } + } + if(dllmax != 0 && (dllmax-dllmin) < 10){ + goto CBR_START2; + } + dlli = (dllmin + dllmax) >> 1; + MOutdwm(mmiobase, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24)); + + /* Set fine tune for DLL2 */ + data = (MIndwm(mmiobase, 0x1E6E0080) >> 24) & 0x1F; + MOutdwm(mmiobase, 0x1E6E0024, 0xFF01 | (data << 1)); + data = (MIndwm(mmiobase, 0x1E6E0018) & 0xff80ffff) | (data << 16); + MOutdwm(mmiobase, 0x1E6E0018, data); + do{ + data = MIndwm(mmiobase, 0x1E6E0088); + data2 = MIndwm(mmiobase, 0x1E6E0088); + }while(data != data2); + data = (data >> 16) & 0x3FF; + data2 = 12666667 / data; + data2 += 1000000 / param->REG_PERIOD; + data *= 1000000 / param->REG_PERIOD; + data2 = (data + (data2 >> 1)) / data2; + data = MIndwm(mmiobase, 0x1E6E0024) & 0x80ff; + data |= (data2 & 0x7F) << 8; + MOutdwm(mmiobase, 0x1E6E0024, data); + + /* Wait DQSI latch phase calibration */ + MOutdwm(mmiobase, 0x1E6E0074, 0x00000020); + MOutdwm(mmiobase, 0x1E6E0070, 0x00000003); + do{ + data = MIndwm(mmiobase, 0x1E6E0070); + }while(!(data & 0x00001000)); + MOutdwm(mmiobase, 0x1E6E0070, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0070, 0x00000003); + do{ + data = MIndwm(mmiobase, 0x1E6E0070); + }while(!(data & 0x00001000)); + MOutdwm(mmiobase, 0x1E6E0070, 0x00000000); +} + +void GetDDR2Info(PAST2300DRAMParam param) +{ + UCHAR *mmiobase; + + mmiobase = param->pjMMIOVirtualAddress; + + MOutdwm(mmiobase, 0x1E6E2000, 0x1688A8A8); + + param->REG_MADJ = 0x00034C4C; + param->REG_SADJ = 0x00001400; + param->REG_DRV = 0x000000F0; + param->REG_PERIOD = param->DRAM_Freq; + param->RODT = 0; + + switch(param->DRAM_Freq){ + case 264 : MOutdwm(mmiobase, 0x1E6E2020, 0x0130); + param->WODT = 0; + param->REG_AC1 = 0x22202513; + param->REG_AC2 = 0x74117011; + param->REG_DQSIC = 0x000000B0; + param->REG_MRS = 0x00000842; + param->REG_EMRS = 0x00000000; + param->REG_DRV = 0x00000000; + param->REG_IOZ = 0x07000099; + param->REG_DQIDLY = 0x0000005C; + param->REG_FREQ = 0x00004DC0; + break; + case 336 : MOutdwm(mmiobase, 0x1E6E2020, 0x0190); + param->WODT = 0; + param->REG_AC1 = 0x23202714; + param->REG_AC2 = 0x86229016; + param->REG_DQSIC = 0x000000DF; + param->REG_MRS = 0x00000A52; + param->REG_EMRS = 0x00000000; + param->REG_DRV = 0x00000000; + param->REG_IOZ = 0x07000099; + param->REG_DQIDLY = 0x00000075; + param->REG_FREQ = 0x00004DC0; + break; + default: + case 408 : MOutdwm(mmiobase, 0x1E6E2020, 0x01F0); + param->WODT = 0; + param->RODT = 0; + param->REG_AC1 = 0x33302715; + param->REG_AC2 = 0xA722A01A; + param->REG_DQSIC = 0x0000010F; + param->REG_MRS = 0x00000A52; + param->REG_EMRS = 0x00000040; + param->REG_DRV = 0x00000000; + param->REG_IOZ = 0x07000099; + param->REG_DQIDLY = 0x0000008E; + param->REG_FREQ = 0x000050C0; + break; + case 456 : MOutdwm(mmiobase, 0x1E6E2020, 0x0230); + param->WODT = 0; + param->REG_AC1 = 0x33302816; + param->REG_AC2 = 0xB844B01D; + param->REG_DQSIC = 0x0000012F; + param->REG_MRS = 0x00000C72; + param->REG_EMRS = 0x00000000; + param->REG_DRV = 0x00000000; + param->REG_IOZ = 0x07000000; + param->REG_DQIDLY = 0x0000009F; + param->REG_FREQ = 0x000052C0; + break; + case 504 : MOutdwm(mmiobase, 0x1E6E2020, 0x0261); + param->WODT = 1; + param->RODT = 1; + param->REG_SADJ = 0x00001400; + param->REG_AC1 = 0x34302916; + param->REG_AC2 = 0xC944D01F; + param->REG_DQSIC = 0x0000014F; + param->REG_MRS = 0x00000C72; + param->REG_EMRS = 0x00000040; + param->REG_DRV = 0x00000000; + param->REG_IOZ = 0x07000000; + param->REG_DQIDLY = 0x000000B0; + param->REG_FREQ = 0x000054C0; + break; + case 528 : MOutdwm(mmiobase, 0x1E6E2020, 0x0120); + param->WODT = 1; + param->RODT = 1; + param->REG_SADJ = 0x00001400; + param->REG_AC1 = 0x44403916; + param->REG_AC2 = 0xD944D01F; + param->REG_DQSIC = 0x0000015F; + param->REG_MRS = 0x00000C72; + param->REG_EMRS = 0x00000040; + param->REG_DRV = 0x00000000; + param->REG_IOZ = 0x07000011; + param->REG_DQIDLY = 0x000000B9; + param->REG_FREQ = 0x000055C0; + break; + case 552 : MOutdwm(mmiobase, 0x1E6E2020, 0x02A1); + param->WODT = 1; + param->RODT = 1; + param->REG_SADJ = 0x00001400; + param->REG_AC1 = 0x44403916; + param->REG_AC2 = 0xD944E01F; + param->REG_DQSIC = 0x0000016F; + param->REG_MRS = 0x00000C72; + param->REG_EMRS = 0x00000040; + param->REG_DRV = 0x00000000; + param->REG_IOZ = 0x07000000; + param->REG_DQIDLY = 0x000000C1; + param->REG_FREQ = 0x000057C0; + break; + case 576 : MOutdwm(mmiobase, 0x1E6E2020, 0x0140); + param->WODT = 1; + param->RODT = 1; + param->REG_SADJ = 0x00001400; + param->REG_AC1 = 0x44403916; + param->REG_AC2 = 0xEA44E01F; + param->REG_DQSIC = 0x0000017F; + param->REG_MRS = 0x00000C72; + param->REG_EMRS = 0x00000040; + param->REG_DRV = 0x00000000; + param->REG_IOZ = 0x07000000; + param->REG_DQIDLY = 0x000000CA; + param->REG_FREQ = 0x000057C0; + break; + } + + switch (param->DRAM_ChipID) + { + case DRAMTYPE_512Mx16: + param->DRAM_CONFIG = 0x100; + break; + default: + case DRAMTYPE_1Gx16: + param->DRAM_CONFIG = 0x121; + break; + case DRAMTYPE_2Gx16: + param->DRAM_CONFIG = 0x122; + break; + case DRAMTYPE_4Gx16: + param->DRAM_CONFIG = 0x123; + break; + }; /* switch size */ + + switch (param->VRAM_Size) + { + default: + case VIDEOMEM_SIZE_08M: + param->DRAM_CONFIG |= 0x00; + break; + case VIDEOMEM_SIZE_16M: + param->DRAM_CONFIG |= 0x04; + break; + case VIDEOMEM_SIZE_32M: + param->DRAM_CONFIG |= 0x08; + break; + case VIDEOMEM_SIZE_64M: + param->DRAM_CONFIG |= 0x0c; + break; + } + +} + +void GetDDR3Info(PAST2300DRAMParam param) +{ + UCHAR *mmiobase; + + mmiobase = param->pjMMIOVirtualAddress; + + param->REG_MADJ = 0x00034C4C; + param->REG_SADJ = 0x00001600; + param->REG_DRV = 0x000000F0; + param->REG_PERIOD = param->DRAM_Freq; + param->RODT = 0; + + MOutdwm(mmiobase, 0x1E6E2000, 0x1688A8A8); + + switch(param->DRAM_Freq){ + case 336 : MOutdwm(mmiobase, 0x1E6E2020, 0x0190); + param->WODT = 0; + param->REG_SADJ = 0x00001400; + param->REG_AC1 = 0x23202826; + param->REG_AC2 = 0x85327513; + param->REG_DQSIC = 0x000000DF; + param->REG_MRS = 0x00001410; + param->REG_EMRS = 0x00000000; + param->REG_IOZ = 0x070000CC; + param->REG_DQIDLY = 0x00000075; + param->REG_FREQ = 0x00004DC0; + break; + default: + case 408 : MOutdwm(mmiobase, 0x1E6E2020, 0x01F0); + param->WODT = 0; + param->REG_SADJ = 0x00001400; + param->REG_AC1 = 0x33302826; + param->REG_AC2 = 0xA6329516; + param->REG_DQSIC = 0x0000010F; + param->REG_MRS = 0x00001610; + param->REG_EMRS = 0x00000000; + param->REG_IOZ = 0x070000CC; + param->REG_DQIDLY = 0x0000008E; + param->REG_FREQ = 0x000050C0; + break; + case 456 : MOutdwm(mmiobase, 0x1E6E2020, 0x0230); + param->WODT = 0; + param->REG_SADJ = 0x00001400; + param->REG_AC1 = 0x33302937; + param->REG_AC2 = 0xB7449519; + param->REG_DQSIC = 0x0000012F; + param->REG_MRS = 0x00081630; + param->REG_EMRS = 0x00000000; + param->REG_IOZ = 0x070000CC; + param->REG_DQIDLY = 0x0000009F; + param->REG_FREQ = 0x000052C0; + break; + case 504 : MOutdwm(mmiobase, 0x1E6E2020, 0x0270); + param->WODT = 1; + param->REG_SADJ = 0x00001400; + param->REG_AC1 = 0x33302A37; + param->REG_AC2 = 0xC744A51C; + param->REG_DQSIC = 0x0000014F; + param->REG_MRS = 0x00081830; + param->REG_IOZ = 0x070000BB; + param->REG_DQIDLY = 0x000000B0; + param->REG_FREQ = 0x000054C0; + break; + case 528 : MOutdwm(mmiobase, 0x1E6E2020, 0x0290); + param->WODT = 1; + param->RODT = 1; + param->REG_SADJ = 0x00001400; + param->REG_AC1 = 0x33303A37; + param->REG_AC2 = 0xD844B61D; + param->REG_DQSIC = 0x0000015F; + param->REG_MRS = 0x00081A30; + param->REG_EMRS = 0x00000040; + param->REG_IOZ = 0x070000BB; + param->REG_DQIDLY = 0x000000B9; + param->REG_FREQ = 0x000055C0; + break; + case 576 : MOutdwm(mmiobase, 0x1E6E2020, 0x0140); + param->WODT = 1; + param->RODT = 1; + param->REG_SADJ = 0x00001400; + param->REG_AC1 = 0x43403A27; + param->REG_AC2 = 0xC955C51F; + param->REG_DQSIC = 0x0000017F; + param->REG_MRS = 0x00101A40; + param->REG_EMRS = 0x00000040; + param->REG_IOZ = 0x070000BB; + param->REG_DQIDLY = 0x000000CA; + param->REG_FREQ = 0x000057C0; + break; + case 600 : MOutdwm(mmiobase, 0x1E6E2020, 0x02E1); + param->WODT = 1; + param->RODT = 1; + param->REG_SADJ = 0x00001400; + param->REG_AC1 = 0x43403B27; + param->REG_AC2 = 0xE955C51F; + param->REG_DQSIC = 0x0000018F; + param->REG_MRS = 0x00101C40; + param->REG_EMRS = 0x00000004; + param->REG_IOZ = 0x070000BB; + param->REG_DQIDLY = 0x000000D2; + param->REG_FREQ = 0x000058C0; + break; + case 624 : MOutdwm(mmiobase, 0x1E6E2020, 0x0160); + param->WODT = 1; + param->RODT = 1; + param->REG_SADJ = 0x00001400; + param->REG_AC1 = 0x43403B27; + param->REG_AC2 = 0xF955C51F; + param->REG_DQSIC = 0x0000019F; + param->REG_MRS = 0x04101C40; + param->REG_EMRS = 0x00000040; + param->REG_IOZ = 0x070000BB; + param->REG_DQIDLY = 0x000000DA; + param->REG_FREQ = 0x000059C0; + break; + case 648 : MOutdwm(mmiobase, 0x1E6E2020, 0x0321); + param->WODT = 1; + param->REG_SADJ = 0x00001400; + param->REG_AC1 = 0x43403B27; + param->REG_AC2 = 0xFA55D51F; + param->REG_DQSIC = 0x000001AF; + param->REG_MRS = 0x00101C40; + param->REG_IOZ = 0x070000AA; + param->REG_FREQ = 0x00005AC0; + param->REG_DQIDLY = 0x000000E3; + param->REG_SADJ = 0x00001600; + break; + } /* switch freq */ + + switch (param->DRAM_ChipID) + { + case DRAMTYPE_512Mx16: + param->DRAM_CONFIG = 0x130; + break; + default: + case DRAMTYPE_1Gx16: + param->DRAM_CONFIG = 0x131; + break; + case DRAMTYPE_2Gx16: + param->DRAM_CONFIG = 0x132; + break; + case DRAMTYPE_4Gx16: + param->DRAM_CONFIG = 0x133; + break; + }; /* switch size */ + + switch (param->VRAM_Size) + { + default: + case VIDEOMEM_SIZE_08M: + param->DRAM_CONFIG |= 0x00; + break; + case VIDEOMEM_SIZE_16M: + param->DRAM_CONFIG |= 0x04; + break; + case VIDEOMEM_SIZE_32M: + param->DRAM_CONFIG |= 0x08; + break; + case VIDEOMEM_SIZE_64M: + param->DRAM_CONFIG |= 0x0c; + break; + } + +} + +void DDR2_Init(PAST2300DRAMParam param) +{ + ULONG data; + UCHAR *mmiobase; + + mmiobase = param->pjMMIOVirtualAddress; + + MOutdwm(mmiobase, 0x1E6E0000, 0xFC600309); + MOutdwm(mmiobase, 0x1E6E0018, 0x00000100); + MOutdwm(mmiobase, 0x1E6E0024, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ); + MOutdwm(mmiobase, 0x1E6E0068, param->REG_SADJ); + usleep(10); /* Delay 2 us */ + MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ | 0x40000); + + MOutdwm(mmiobase, 0x1E6E0004, param->DRAM_CONFIG); + MOutdwm(mmiobase, 0x1E6E0008, 0x90040f); + MOutdwm(mmiobase, 0x1E6E0010, param->REG_AC1); + MOutdwm(mmiobase, 0x1E6E0014, param->REG_AC2); + MOutdwm(mmiobase, 0x1E6E0020, param->REG_DQSIC); + MOutdwm(mmiobase, 0x1E6E0080, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0084, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0088, param->REG_DQIDLY); /* fine tune required */ + MOutdwm(mmiobase, 0x1E6E0018, 0x4040C130); + MOutdwm(mmiobase, 0x1E6E0018, 0x20404330); /* fine tune required */ + MOutdwm(mmiobase, 0x1E6E0038, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0040, 0xFF808000); /* fine tune required */ + MOutdwm(mmiobase, 0x1E6E0044, 0x88848466); /* fine tune required */ + MOutdwm(mmiobase, 0x1E6E0048, 0x44440008); /* fine tune required */ + MOutdwm(mmiobase, 0x1E6E004C, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0050, 0x80000000); + MOutdwm(mmiobase, 0x1E6E0050, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0054, 0); + if(param->RODT) + { + if (param->ODT == 75) + MOutdwm(mmiobase, 0x1E6E0060, param->REG_DRV | 0x5); + else + MOutdwm(mmiobase, 0x1E6E0060, param->REG_DRV | 0xA); + }else + { + MOutdwm(mmiobase, 0x1E6E0060, param->REG_DRV); + } + /* Wait MCLK2X lock to MCLK */ + do{ + data = MIndwm(mmiobase, 0x1E6E001C); + }while(!(data & 0x08000000)); + data = (data >> 8) & 0xff; + if(data > 61 || data < 15){ + data = MIndwm(mmiobase, 0x1E6E0018) ^ 0x300; + MOutdwm(mmiobase, 0x1E6E0018, data); + MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ); + usleep(10); /* Delay 2 us */ + data = data | 0x200; + MOutdwm(mmiobase, 0x1E6E0018, data); + MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ | 0x40000); + do{ + data = MIndwm(mmiobase, 0x1E6E001C); + }while(!(data & 0x08000000)); + } + data = MIndwm(mmiobase, 0x1E6E0018) | 0xC00; + MOutdwm(mmiobase, 0x1E6E0018, data); + MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ | 0xC0000); + MOutdwm(mmiobase, 0x1E6E006C, param->REG_IOZ); /* fine tune required */ + MOutdwm(mmiobase, 0x1E6E0070, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0074, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0078, 0x00000000); + MOutdwm(mmiobase, 0x1E6E007C, 0x00000000); + /* Wait DQI delay lock */ + do{ + data = MIndwm(mmiobase, 0x1E6E0080); + }while(!(data & 0x40000000)); + MOutdwm(mmiobase, 0x1E6E0034, 0x00000001); + MOutdwm(mmiobase, 0x1E6E000C, 0x00000000); + usleep(50); /* Delay 400 us */ + /* Mode Register Setting */ + MOutdwm(mmiobase, 0x1E6E002C, param->REG_MRS | 0x100); + MOutdwm(mmiobase, 0x1E6E0030, param->REG_EMRS); + MOutdwm(mmiobase, 0x1E6E0028, 0x00000005); + MOutdwm(mmiobase, 0x1E6E0028, 0x00000007); + MOutdwm(mmiobase, 0x1E6E0028, 0x00000003); + MOutdwm(mmiobase, 0x1E6E0028, 0x00000001); + MOutdwm(mmiobase, 0x1E6E000C, 0x00005A08); + MOutdwm(mmiobase, 0x1E6E002C, param->REG_MRS); + MOutdwm(mmiobase, 0x1E6E0028, 0x00000001); + MOutdwm(mmiobase, 0x1E6E0030, param->REG_EMRS | 0x380); + MOutdwm(mmiobase, 0x1E6E0028, 0x00000003); + MOutdwm(mmiobase, 0x1E6E0030, param->REG_EMRS); + MOutdwm(mmiobase, 0x1E6E0028, 0x00000003); + + MOutdwm(mmiobase, 0x1E6E000C, 0x7FFF5A01); + data = 0; + if(param->WODT){ + data = 0x700; + } + if(param->RODT){ + data = data | 0x3000 | ((param->REG_AC2 & 0x60000) >> 3); + } + MOutdwm(mmiobase, 0x1E6E0034, data | 0x3); + MOutdwm(mmiobase, 0x1E6E0120, param->REG_FREQ); + + /* Wait DQSI delay lock */ + do{ + data = MIndwm(mmiobase, 0x1E6E0020); + }while(!(data & 0x00000800)); + /* Calibrate the DQSI delay */ + CBRDLL2(param); + +} + +void DDR3_Init(PAST2300DRAMParam param) +{ + ULONG data; + UCHAR *mmiobase; + + mmiobase = param->pjMMIOVirtualAddress; + + MOutdwm(mmiobase, 0x1E6E0000, 0xFC600309); + MOutdwm(mmiobase, 0x1E6E0018, 0x00000100); + MOutdwm(mmiobase, 0x1E6E0024, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ); + MOutdwm(mmiobase, 0x1E6E0068, param->REG_SADJ); + usleep(10); /* Delay 2 us */ + MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ | 0x40000); + + MOutdwm(mmiobase, 0x1E6E0004, param->DRAM_CONFIG); + MOutdwm(mmiobase, 0x1E6E0008, 0x90040f); + MOutdwm(mmiobase, 0x1E6E0010, param->REG_AC1); + MOutdwm(mmiobase, 0x1E6E0014, param->REG_AC2); + MOutdwm(mmiobase, 0x1E6E0020, param->REG_DQSIC); + MOutdwm(mmiobase, 0x1E6E0080, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0084, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0088, param->REG_DQIDLY); /* fine tune required */ + MOutdwm(mmiobase, 0x1E6E0018, 0x4040C170); + MOutdwm(mmiobase, 0x1E6E0018, 0x20404370); /* fine tune required */ + MOutdwm(mmiobase, 0x1E6E0038, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0040, 0xFF808000); /* fine tune required */ + MOutdwm(mmiobase, 0x1E6E0044, 0x88848466); /* fine tune required */ + MOutdwm(mmiobase, 0x1E6E0048, 0x44440008); /* fine tune required */ + MOutdwm(mmiobase, 0x1E6E004C, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0050, 0x80000000); + MOutdwm(mmiobase, 0x1E6E0050, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0054, 0); + if(param->RODT) + { + if (param->ODT == 75) + MOutdwm(mmiobase, 0x1E6E0060, param->REG_DRV | 0x5); + else + MOutdwm(mmiobase, 0x1E6E0060, param->REG_DRV | 0xA); + } + else + { + MOutdwm(mmiobase, 0x1E6E0060, param->REG_DRV); + } + /* Wait MCLK2X lock to MCLK */ + do{ + data = MIndwm(mmiobase, 0x1E6E001C); + }while(!(data & 0x08000000)); + data = (data >> 8) & 0xff; + if(data > 61 || data < 15){ + data = MIndwm(mmiobase, 0x1E6E0018) ^ 0x300; + MOutdwm(mmiobase, 0x1E6E0018, data); + MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ); + usleep(10); /* Delay 2 us */ + data = data | 0x200; + MOutdwm(mmiobase, 0x1E6E0018, data); + MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ | 0x40000); + do{ + data = MIndwm(mmiobase, 0x1E6E001C); + }while(!(data & 0x08000000)); + } + data = MIndwm(mmiobase, 0x1E6E0018) | 0xC00; + MOutdwm(mmiobase, 0x1E6E0018, data); + MOutdwm(mmiobase, 0x1E6E0064, param->REG_MADJ | 0xC0000); + MOutdwm(mmiobase, 0x1E6E006C, param->REG_IOZ); /* fine tune required */ + MOutdwm(mmiobase, 0x1E6E0070, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0074, 0x00000000); + MOutdwm(mmiobase, 0x1E6E0078, 0x00000000); + MOutdwm(mmiobase, 0x1E6E007C, 0x00000000); + /* Wait DQI delay lock */ + do{ + data = MIndwm(mmiobase, 0x1E6E0080); + }while(!(data & 0x40000000)); + MOutdwm(mmiobase, 0x1E6E0034, 0x00000001); + MOutdwm(mmiobase, 0x1E6E000C, 0x00000040); + usleep(50); /* Delay 400 us */ + /* Mode Register Setting */ + MOutdwm(mmiobase, 0x1E6E002C, param->REG_MRS | 0x100); + MOutdwm(mmiobase, 0x1E6E0030, param->REG_EMRS); + MOutdwm(mmiobase, 0x1E6E0028, 0x00000005); + MOutdwm(mmiobase, 0x1E6E0028, 0x00000007); + MOutdwm(mmiobase, 0x1E6E0028, 0x00000003); + MOutdwm(mmiobase, 0x1E6E0028, 0x00000001); + MOutdwm(mmiobase, 0x1E6E002C, param->REG_MRS); + MOutdwm(mmiobase, 0x1E6E000C, 0x00005A48); + MOutdwm(mmiobase, 0x1E6E0028, 0x00000001); + + MOutdwm(mmiobase, 0x1E6E000C, 0x7FFF5A81); + data = 0; + if(param->WODT){ + data = 0x700; + } + if(param->RODT){ + data = data | 0x3000 | ((param->REG_AC2 & 0x60000) >> 3); + } + MOutdwm(mmiobase, 0x1E6E0034, data | 0x3); + + /* Wait DQSI delay lock */ + do{ + data = MIndwm(mmiobase, 0x1E6E0020); + }while(!(data & 0x00000800)); + /* Calibrate the DQSI delay */ + CBRDLL2(param); + + MOutdwm(mmiobase, 0x1E6E0120, param->REG_FREQ); + +} + +void vInitAST2300DRAMReg(ScrnInfoPtr pScrn) +{ + ASTRecPtr pAST = ASTPTR(pScrn); + AST2300DRAMParam param; + ULONG i, ulTemp; + UCHAR jReg; + + GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg); + + if ((jReg & 0x80) == 0) /* VGA only */ + { + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000; + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; + + *(ULONG *) (pAST->MMIOVirtualAddr + 0x12000) = 0x1688A8A8; + do { + ; + } while (*(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x12000) != 0x01); + + *(ULONG *) (pAST->MMIOVirtualAddr + 0x10000) = 0xFC600309; + do { + ; + } while (*(volatile ULONG *) (pAST->MMIOVirtualAddr + 0x10000) != 0x01); + + param.pjMMIOVirtualAddress = pAST->MMIOVirtualAddr; + param.DRAM_Type = DDR3; /* DDR3 */ + ulTemp = MIndwm(param.pjMMIOVirtualAddress, 0x1E6E2070); + if (ulTemp & 0x01000000) + param.DRAM_Type = DDR2; /* DDR2 */ + param.DRAM_ChipID = (ULONG) pAST->jDRAMType; + param.DRAM_Freq = pAST->ulMCLK; + param.VRAM_Size = pAST->ulVRAMSize; + + if (param.DRAM_Type == DDR3) + { + GetDDR3Info(¶m); + DDR3_Init(¶m); + } + else + { + GetDDR2Info(¶m); + DDR2_Init(¶m); + } + + ulTemp = MIndwm(param.pjMMIOVirtualAddress, 0x1E6E2040); + MOutdwm(param.pjMMIOVirtualAddress, 0x1E6E2040, ulTemp | 0x40); + } + + /* wait ready */ + do { + GetIndexRegMask(CRTC_PORT, 0xD0, 0xFF, jReg); + } while ((jReg & 0x40) == 0); + +} /* vInitAST2300DRAMReg */ + +void vGetDefaultSettings(ScrnInfoPtr pScrn) +{ + ASTRecPtr pAST = ASTPTR(pScrn); + ULONG ulData; + + if (pAST->jChipType == AST2300) + { + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000; + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; + ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12070); + switch (ulData & 0x18000000) + { + case 0x00000000: + pAST->jDRAMType = DRAMTYPE_512Mx16; + break; + case 0x08000000: + pAST->jDRAMType = DRAMTYPE_1Gx16; + break; + case 0x10000000: + pAST->jDRAMType = DRAMTYPE_2Gx16; + break; + case 0x18000000: + pAST->jDRAMType = DRAMTYPE_4Gx16; + break; + } + } + else if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200)) + { + pAST->jDRAMType = DRAMTYPE_512Mx32; + } + else if ((pAST->jChipType == AST1100) || (pAST->jChipType == AST2150)) + { + pAST->jDRAMType = DRAMTYPE_1Gx16; + } + +} /* vGetDefaultSettings */ + +/* + * Flags: 0: POST init + * 1: resume from power management + */ +Bool InitVGA(ScrnInfoPtr pScrn, ULONG Flags) { ASTRecPtr pAST; ULONG ulData; @@ -874,10 +1990,363 @@ Bool InitVGA(ScrnInfoPtr pScrn) vASTOpenKey(pScrn); vSetDefExtReg(pScrn); - - vInitDRAMReg(pScrn); + + if (Flags == 0) + vGetDefaultSettings(pScrn); + + if (pAST->jChipType == AST2300) + vInitAST2300DRAMReg(pScrn); + else + vInitDRAMReg(pScrn); } return (TRUE); } /* Init VGA */ + +/* Get EDID */ +void +I2CWriteClock(ASTRecPtr pAST, UCHAR data) +{ + UCHAR ujCRB7, jtemp; + ULONG i; + + for (i=0;i<0x10000; i++) + { + ujCRB7 = ((data & 0x01) ? 0:1); /* low active */ + SetIndexRegMask(CRTC_PORT, 0xB7, 0xFE, ujCRB7); + GetIndexRegMask(CRTC_PORT, 0xB7, 0x01, jtemp); + if (ujCRB7 == jtemp) break; + } + +} + +void +I2CWriteData(ASTRecPtr pAST, UCHAR data) +{ + UCHAR volatile ujCRB7, jtemp; + ULONG i; + + for (i=0;i<0x1000; i++) + { + ujCRB7 = ((data & 0x01) ? 0:1) << 2; /* low active */ + SetIndexRegMask(CRTC_PORT, 0xB7, 0xFB, ujCRB7); + GetIndexRegMask(CRTC_PORT, 0xB7, 0x04, jtemp); + if (ujCRB7 == jtemp) break; + } + +} + +Bool +I2CReadClock(ASTRecPtr pAST) +{ + UCHAR volatile ujCRB7; + + GetIndexRegMask(CRTC_PORT, 0xB7, 0x10, ujCRB7); + ujCRB7 >>= 4; + + return ((ujCRB7 & 0x01) ? 1:0); +} + +Bool +I2CReadData(ASTRecPtr pAST) +{ + UCHAR volatile ujCRB7; + + GetIndexRegMask(CRTC_PORT, 0xB7, 0x20, ujCRB7); + ujCRB7 >>= 5; + + return ((ujCRB7 & 0x01) ? 1:0); + +} + + +void +I2CDelay(ASTRecPtr pAST) +{ + ULONG i; + UCHAR jtemp; + + for (i=0;i<150;i++) + jtemp = GetReg(SEQ_PORT); + +} + +void +I2CStart(ASTRecPtr pAST) +{ + I2CWriteClock(pAST, 0x00); /* Set Clk Low */ + I2CDelay(pAST); + I2CWriteData(pAST, 0x01); /* Set Data High */ + I2CDelay(pAST); + I2CWriteClock(pAST, 0x01); /* Set Clk High */ + I2CDelay(pAST); + I2CWriteData(pAST, 0x00); /* Set Data Low */ + I2CDelay(pAST); + I2CWriteClock(pAST, 0x01); /* Set Clk High */ + I2CDelay(pAST); +} + +void +I2CStop(ASTRecPtr pAST) +{ + I2CWriteClock(pAST, 0x00); /* Set Clk Low */ + I2CDelay(pAST); + I2CWriteData(pAST, 0x00); /* Set Data Low */ + I2CDelay(pAST); + I2CWriteClock(pAST, 0x01); /* Set Clk High */ + I2CDelay(pAST); + I2CWriteData(pAST, 0x01); /* Set Data High */ + I2CDelay(pAST); + I2CWriteClock(pAST, 0x01); /* Set Clk High */ + I2CDelay(pAST); + +} + +Bool +CheckACK(ASTRecPtr pAST) +{ + UCHAR Data; + + I2CWriteClock(pAST, 0x00); /* Set Clk Low */ + I2CDelay(pAST); + I2CWriteData(pAST, 0x01); /* Set Data High */ + I2CDelay(pAST); + I2CWriteClock(pAST, 0x01); /* Set Clk High */ + I2CDelay(pAST); + Data = (UCHAR) I2CReadData(pAST); /* Set Data High */ + + return ((Data & 0x01) ? 0:1); + +} + + +void +SendACK(ASTRecPtr pAST) +{ + + I2CWriteClock(pAST, 0x00); /* Set Clk Low */ + I2CDelay(pAST); + I2CWriteData(pAST, 0x00); /* Set Data low */ + I2CDelay(pAST); + I2CWriteClock(pAST, 0x01); /* Set Clk High */ + I2CDelay(pAST); + +} + +void +SendNACK(ASTRecPtr pAST) +{ + + I2CWriteClock(pAST, 0x00); /* Set Clk Low */ + I2CDelay(pAST); + I2CWriteData(pAST, 0x01); /* Set Data high */ + I2CDelay(pAST); + I2CWriteClock(pAST, 0x01); /* Set Clk High */ + I2CDelay(pAST); + +} + +void +SendI2CDataByte(ASTRecPtr pAST, UCHAR data) +{ + UCHAR jData; + LONG i; + + for (i=7;i>=0;i--) + { + I2CWriteClock(pAST, 0x00); /* Set Clk Low */ + I2CDelay(pAST); + + jData = ((data >> i) & 0x01) ? 1:0; + I2CWriteData(pAST, jData); /* Set Data Low */ + I2CDelay(pAST); + + I2CWriteClock(pAST, 0x01); /* Set Clk High */ + I2CDelay(pAST); + } +} + +UCHAR +ReceiveI2CDataByte(ASTRecPtr pAST) +{ + UCHAR jData=0, jTempData; + LONG i, j; + + for (i=7;i>=0;i--) + { + I2CWriteClock(pAST, 0x00); /* Set Clk Low */ + I2CDelay(pAST); + + I2CWriteData(pAST, 0x01); /* Set Data High */ + I2CDelay(pAST); + + I2CWriteClock(pAST, 0x01); /* Set Clk High */ + I2CDelay(pAST); + + for (j=0; j<0x1000; j++) + { + if (I2CReadClock(pAST)) break; + } + + jTempData = I2CReadData(pAST); + jData |= ((jTempData & 0x01) << i); + + I2CWriteClock(pAST, 0x0); /* Set Clk Low */ + I2CDelay(pAST); + } + + return ((UCHAR)jData); +} + +Bool +GetVGAEDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer) +{ + ASTRecPtr pAST; + UCHAR *pjDstEDID; + UCHAR jData; + ULONG i; + + pAST = ASTPTR(pScrn); + pjDstEDID = (UCHAR *) pEDIDBuffer; + + /* Force to DDC2 */ + I2CWriteClock(pAST, 0x01); /* Set Clk Low */ + I2CDelay(pAST); + I2CDelay(pAST); + I2CWriteClock(pAST, 0x00); /* Set Clk Low */ + I2CDelay(pAST); + + I2CStart(pAST); + + SendI2CDataByte(pAST, 0xA0); + if (!CheckACK(pAST)) + { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[GetVGAEDID] Check ACK Failed \n"); + return (FALSE); + } + + SendI2CDataByte(pAST, 0x00); + if (!CheckACK(pAST)) + { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[GetVGAEDID] Check ACK Failed \n"); + return (FALSE); + } + + I2CStart(pAST); + + SendI2CDataByte(pAST, 0xA1); + if (!CheckACK(pAST)) + { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[GetVGAEDID] Check ACK Failed \n"); + return (FALSE); + } + + for (i=0; i<127; i++) + { + jData = ReceiveI2CDataByte(pAST); + SendACK(pAST); + + *pjDstEDID++ = jData; + } + + jData = ReceiveI2CDataByte(pAST); + SendNACK(pAST); + *pjDstEDID = jData; + + I2CStop(pAST); + + return (TRUE); + +} /* GetVGAEDID */ + +Bool bInitAST1180(ScrnInfoPtr pScrn) +{ + ASTRecPtr pAST; + ULONG ulData; + + pAST = ASTPTR(pScrn); + + /* Enable PCI */ + PCI_READ_LONG(pAST->PciInfo, &ulData, 0x04); + ulData |= 0x03; + PCI_WRITE_LONG(pAST->PciInfo, ulData, 0x04); + + /* init DRAM if no F/W */ + /* TODO */ + + WriteAST1180SOC(AST1180_MMC_BASE+0x00, 0xFC600309); /* unlock */ + WriteAST1180SOC(AST1180_SCU_BASE+0x00, 0x1688a8a8); /* unlock */ + usleep(100); + + WriteAST1180SOC(AST1180_MMC_BASE+0x08, 0x000011e3); /* req. */ + + /* init SCU */ +#if 0 + ReadAST1180SOC(AST1180_SCU_BASE+0x08, ulData); /* delay compensation */ + ulData &= 0xFFFFE0FF; + ulData |= 0x00000C00; + WriteAST1180SOC(AST1180_SCU_BASE+0x08, ulData); +#endif + + ReadAST1180SOC(AST1180_SCU_BASE+0x0c, ulData); /* 2d clk */ + ulData &= 0xFFFFFFFD; + WriteAST1180SOC(AST1180_SCU_BASE+0x0c, ulData); + + +} /* bInitAST1180 */ + +void GetAST1180DRAMInfo(ScrnInfoPtr pScrn) +{ + ASTRecPtr pAST = ASTPTR(pScrn); + ULONG ulData; + + WriteAST1180SOC(AST1180_MMC_BASE+0x00, 0xFC600309); /* unlock */ + ReadAST1180SOC(AST1180_MMC_BASE+0x04, ulData); + pAST->ulDRAMBusWidth = 32; + if (ulData & 0x40) + pAST->ulDRAMBusWidth = 16; + + /* DRAM size */ + switch (ulData & 0x0C) + { + case 0x00: + pAST->ulDRAMSize = DRAM_SIZE_032M; + break; + case 0x04: + pAST->ulDRAMSize = DRAM_SIZE_064M; + break; + case 0x08: + pAST->ulDRAMSize = DRAM_SIZE_128M; + break; + case 0x0c: + pAST->ulDRAMSize = DRAM_SIZE_256M; + break; + } + + /* Get framebuffer size */ + switch (ulData & 0x30) + { + case 0x00: + pAST->ulVRAMSize = DRAM_SIZE_016M; + break; + case 0x10: + pAST->ulVRAMSize = DRAM_SIZE_032M; + break; + case 0x20: + pAST->ulVRAMSize = DRAM_SIZE_064M; + break; + case 0x30: + pAST->ulVRAMSize = DRAM_SIZE_128M; + break; + } + + /* VRAM base */ + if (pAST->ulVRAMSize >= pAST->ulDRAMSize) + pAST->ulVRAMSize = pAST->ulDRAMSize; + pAST->ulVRAMBase = pAST->ulDRAMSize - pAST->ulVRAMSize; + + /* MCLK */ + pAST->ulMCLK = 200; + +} /* GetAST1180DRAMInfo */ diff --git a/src/ast_vgatool.h b/src/ast_vgatool.h index 42c866a..53cb4c7 100644 --- a/src/ast_vgatool.h +++ b/src/ast_vgatool.h @@ -27,14 +27,23 @@ #define VIDEOMEM_SIZE_64M 0x04000000 #define VIDEOMEM_SIZE_128M 0x08000000 +#define DRAM_SIZE_016M 0x01000000 +#define DRAM_SIZE_032M 0x02000000 +#define DRAM_SIZE_064M 0x04000000 +#define DRAM_SIZE_128M 0x08000000 +#define DRAM_SIZE_256M 0x10000000 + #define DRAMTYPE_512Mx16 0 #define DRAMTYPE_1Gx16 1 #define DRAMTYPE_512Mx32 2 #define DRAMTYPE_1Gx32 3 +#define DRAMTYPE_2Gx16 6 +#define DRAMTYPE_4Gx16 7 #define AR_PORT_WRITE (pAST->RelocateIO + 0x40) #define MISC_PORT_WRITE (pAST->RelocateIO + 0x42) #define SEQ_PORT (pAST->RelocateIO + 0x44) +#define DAC_INDEX_READ (pAST->MMIOVirtualAddr + 0x3c7) #define DAC_INDEX_WRITE (pAST->RelocateIO + 0x48) #define DAC_DATA (pAST->RelocateIO + 0x49) #define GR_PORT (pAST->RelocateIO + 0x4E) @@ -62,6 +71,19 @@ SetIndexReg(base,index,__Temp); \ } while (0) +#define VGA_GET_PALETTE_INDEX(index, red, green, blue) \ +{ \ + UCHAR __junk; \ + SetReg(DAC_INDEX_READ,(UCHAR)(index)); \ + __junk = GetReg(SEQ_PORT); \ + red = GetReg(DAC_DATA); \ + __junk = GetReg(SEQ_PORT); \ + green = GetReg(DAC_DATA); \ + __junk = GetReg(SEQ_PORT); \ + blue = GetReg(DAC_DATA); \ + __junk = GetReg(SEQ_PORT); \ +} + #define VGA_LOAD_PALETTE_INDEX(index, red, green, blue) \ { \ UCHAR __junk; \ @@ -74,3 +96,69 @@ SetReg(DAC_DATA,(UCHAR)(blue)); \ __junk = GetReg(SEQ_PORT); \ } + +/* Reg. Definition */ +#define AST1180_MEM_BASE 0x40000000 +#define AST1180_MMC_BASE 0x80FC8000 +#define AST1180_SCU_BASE 0x80FC8200 +#define AST1180_GFX_BASE 0x80FC9000 +#define AST1180_VIDEO_BASE 0x80FCD000 + +/* AST1180 GFX */ +#define AST1180_VGA1_CTRL 0x60 +#define AST1180_VGA1_CTRL2 0x64 +#define AST1180_VGA1_STATUS 0x68 +#define AST1180_VGA1_PLL 0x6C +#define AST1180_VGA1_HTREG 0x70 +#define AST1180_VGA1_HRREG 0x74 +#define AST1180_VGA1_VTREG 0x78 +#define AST1180_VGA1_VRREG 0x7C +#define AST1180_VGA1_STARTADDR 0x80 +#define AST1180_VGA1_OFFSET 0x84 +#define AST1180_VGA1_THRESHOLD 0x88 + +#define AST1180_HWC1_OFFSET 0x90 +#define AST1180_HWC1_POSITION 0x94 +#define AST1180_HWC1_PATTERNADDR 0x98 + +#define CRT_LOW_THRESHOLD_VALUE 0x40 +#define CRT_HIGH_THRESHOLD_VALUE 0x7E + +/* GFX Ctrl Reg */ +#define AST1180_ENABLECRT 0x00000001 +#define AST1180_ENABLEHWC 0x00000002 +#define AST1180_MONOHWC 0x00000000 +#define AST1180_ALPHAHWC 0x00000400 +#define AST1180_HSYNCOFF 0x00040000 +#define AST1180_VSYNCOFF 0x00080000 +#define AST1180_VGAOFF 0x00100000 + +#define ReadAST1180SOC(addr, data) \ +{ \ + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = (addr) & 0xFFFF0000; \ + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; \ + data = (*(ULONG *) (pAST->MMIOVirtualAddr + 0x10000 + ((addr) & 0x0000FFFF))); \ +} + +#define WriteAST1180SOC(addr, data) \ +{ \ + ULONG temp; \ + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = (addr) & 0xFFFF0000; \ + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; \ + *(ULONG *) (pAST->MMIOVirtualAddr + 0x10000 + ((addr) & 0x0000FFFF)) = (data); \ + temp = *(ULONG *) (pAST->MMIOVirtualAddr + 0x10000 + ((addr) & 0x0000FFFF)); \ +} + +#define ReadAST1180MEM(addr, data) \ +{ \ + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = (addr) & 0xFFFF0000; \ + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; \ + data = (*(ULONG *) (pAST->MMIOVirtualAddr + 0x10000 + ((addr) & 0x0000FFFF))); \ +} + +#define WriteAST1180MEM(addr, data) \ +{ \ + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = (addr) & 0xFFFF0000; \ + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; \ + *(ULONG *) (pAST->MMIOVirtualAddr + 0x10000 + ((addr) & 0x0000FFFF)) = (data); \ +} |