summaryrefslogtreecommitdiff
path: root/src/ast_vgatool.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast_vgatool.c')
-rw-r--r--src/ast_vgatool.c1785
1 files changed, 1627 insertions, 158 deletions
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(&param);
+ DDR3_Init(&param);
+ }
+ else
+ {
+ GetDDR2Info(&param);
+ DDR2_Init(&param);
+ }
+
+ 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 */