diff options
author | Y.C. Chen <yc_chen@aspeedtech.com> | 2010-11-10 14:08:55 +0800 |
---|---|---|
committer | Y.C. Chen <yc_chen@aspeedtech.com> | 2010-11-10 14:08:55 +0800 |
commit | b4466dad5d60c4a79b775c6e6de989563f7eac45 (patch) | |
tree | 68d39683838a699f942eb53a367809f701a4156f /src/ast_vgatool.c | |
parent | e387e54fd65b7db984975bf7a97cf30b5f1b9b9e (diff) |
xf86-video-ast-0.92.02
Diffstat (limited to 'src/ast_vgatool.c')
-rw-r--r-- | src/ast_vgatool.c | 1785 |
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(¶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 */ |