From 241d411e770c36b725cc72c1cd5e52932a8cf460 Mon Sep 17 00:00:00 2001 From: "Y.C. Chen" Date: Fri, 22 Aug 2008 12:01:18 +0800 Subject: Support AST1100/2050/2100 --- src/ast.h | 7 ++- src/ast_2dtool.c | 2 +- src/ast_driver.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++---- src/ast_mode.c | 32 +++++++--- src/ast_mode.h | 3 +- src/ast_vgatool.c | 125 ++++++++++++++++++++++++++++++++++++- src/ast_vgatool.h | 2 + 7 files changed, 327 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/ast.h b/src/ast.h index cc878e9..7cd51c0 100644 --- a/src/ast.h +++ b/src/ast.h @@ -40,10 +40,15 @@ #define PCI_CHIP_AST2000 0x2000 #endif +#ifndef PCI_CHIP_AST2100 +#define PCI_CHIP_AST2100 0x2010 +#endif + typedef enum _CHIP_ID { VGALegacy, AST2000, - AST2100 + AST2100, + AST1100 } CHIP_ID; /* AST REC Info */ diff --git a/src/ast_2dtool.c b/src/ast_2dtool.c index a8b5838..39fa46c 100644 --- a/src/ast_2dtool.c +++ b/src/ast_2dtool.c @@ -167,7 +167,7 @@ bEnableCMDQ(ScrnInfoPtr pScrn, ASTRecPtr pAST) } *(ULONG *) (pAST->CMDQInfo.pjCmdQBasePort) = ulVMCmdQBasePort; - pAST->CMDQInfo.ulWritePointer = *(ULONG *) (pAST->CMDQInfo.pjWritePort); + pAST->CMDQInfo.ulWritePointer = *(ULONG *) (pAST->CMDQInfo.pjWritePort) << 3; break; case VM_CMD_MMIO: diff --git a/src/ast_driver.c b/src/ast_driver.c index a018964..0cd991f 100644 --- a/src/ast_driver.c +++ b/src/ast_driver.c @@ -66,10 +66,12 @@ extern void vASTOpenKey(ScrnInfoPtr pScrn); extern Bool bASTRegInit(ScrnInfoPtr pScrn); extern ULONG GetVRAMInfo(ScrnInfoPtr pScrn); extern ULONG GetMaxDCLK(ScrnInfoPtr pScrn); +extern void GetChipType(ScrnInfoPtr pScrn); extern void vASTLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual); extern void ASTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); extern void vSetStartAddressCRT1(ASTRecPtr pAST, ULONG base); extern Bool ASTSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode); +extern Bool GetVGA2EDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer); extern Bool bInitCMDQInfo(ScrnInfoPtr pScrn, ASTRecPtr pAST); extern Bool bEnableCMDQ(ScrnInfoPtr pScrn, ASTRecPtr pAST); @@ -121,12 +123,14 @@ _X_EXPORT DriverRec AST = { /* Chipsets */ static SymTabRec ASTChipsets[] = { - {PCI_CHIP_AST2000, "AST2000"}, + {PCI_CHIP_AST2000, "AST2000 Family"}, + {PCI_CHIP_AST2100, "AST1100_2050_2100"}, {-1, NULL} }; static PciChipsets ASTPciChipsets[] = { {PCI_CHIP_AST2000, PCI_CHIP_AST2000, RES_SHARED_VGA}, + {PCI_CHIP_AST2100, PCI_CHIP_AST2100, RES_SHARED_VGA}, {-1, -1, RES_UNDEFINED } }; @@ -137,17 +141,19 @@ typedef enum { OPTION_HWC_NUM, OPTION_ENG_CAPS, OPTION_DBG_SELECT, - OPTION_NO_DDC + OPTION_NO_DDC, + OPTION_VGA2_CLONE } ASTOpts; static const OptionInfoRec ASTOptions[] = { {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_MMIO2D, "MMIO2D", OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_SW_CURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_MMIO2D, "MMIO2D", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_SW_CURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_HWC_NUM, "HWCNumber", OPTV_INTEGER, {0}, FALSE}, - {OPTION_ENG_CAPS, "ENGCaps", OPTV_INTEGER, {0}, FALSE}, - {OPTION_DBG_SELECT, "DBGSelect", OPTV_INTEGER, {0}, FALSE}, - {OPTION_NO_DDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_ENG_CAPS, "ENGCaps", OPTV_INTEGER, {0}, FALSE}, + {OPTION_DBG_SELECT, "DBGSelect", OPTV_INTEGER, {0}, FALSE}, + {OPTION_NO_DDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_VGA2_CLONE, "VGA2Clone", OPTV_BOOLEAN, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; @@ -634,7 +640,7 @@ ASTPreInit(ScrnInfoPtr pScrn, int flags) /* Get Revision */ if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x10) - pAST->jChipType = AST2100; + GetChipType(pScrn); else pAST->jChipType = AST2000; @@ -1197,13 +1203,22 @@ ASTProbeDDC(ScrnInfoPtr pScrn, int index) } } +#define SkipDT 0x00 +#define DT1 0x01 +#define DT2 0x02 + static xf86MonPtr ASTDoDDC(ScrnInfoPtr pScrn, int index) { vbeInfoPtr pVbe; - xf86MonPtr MonInfo = NULL; + xf86MonPtr MonInfo = NULL, MonInfo1 = NULL, MonInfo2 = NULL; ASTRecPtr pAST = ASTPTR(pScrn); - + unsigned long i, j, k; + unsigned char DDC_data[128]; + struct monitor_ranges ranges, ranges1, ranges2; + int DTSelect, dclock1=0, h_active1=0, v_active1=0, dclock2=0, h_active2=0, v_active2=0; + struct std_timings stdtiming, *stdtiming1, *stdtiming2; + /* Honour Option "noDDC" */ if (xf86ReturnOptValBool(pAST->Options, OPTION_NO_DDC, FALSE)) { return MonInfo; @@ -1211,7 +1226,150 @@ ASTDoDDC(ScrnInfoPtr pScrn, int index) if (xf86LoadSubModule(pScrn, "vbe") && (pVbe = VBEInit(NULL, index))) { xf86LoaderReqSymLists(vbeSymbols, NULL); - MonInfo = vbeDoEDID(pVbe, NULL); + MonInfo1 = vbeDoEDID(pVbe, NULL); + MonInfo = MonInfo1; + + /* For VGA2 CLONE Support, ycchen@012508 */ + if (xf86ReturnOptValBool(pAST->Options, OPTION_VGA2_CLONE, FALSE)) { + if (GetVGA2EDID(pScrn, DDC_data) == TRUE) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Get VGA2 EDID Correctly!! \n"); + MonInfo2 = xf86InterpretEDID(pScrn->scrnIndex, DDC_data); + if (MonInfo1 == NULL) /* No DDC1 EDID */ + MonInfo = MonInfo2; + else { /* Check with VGA1 & VGA2 EDID */ + /* Update establishment timing */ + MonInfo->timings1.t1 = MonInfo1->timings1.t1 & MonInfo2->timings1.t1; + MonInfo->timings1.t2 = MonInfo1->timings1.t2 & MonInfo2->timings1.t2; + MonInfo->timings1.t_manu = MonInfo1->timings1.t_manu & MonInfo2->timings1.t_manu; + + /* Update Std. Timing */ + for (i=0; i<8; i++) { + stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0; + for (j=0; j<8; j++) { + if ((MonInfo1->timings2[i].hsize == MonInfo2->timings2[j].hsize) && \ + (MonInfo1->timings2[i].vsize == MonInfo2->timings2[j].vsize) && \ + (MonInfo1->timings2[i].refresh == MonInfo2->timings2[j].refresh)) { + stdtiming = MonInfo1->timings2[i]; + break; + } + } + + MonInfo->timings2[i] = stdtiming; + } /* Std. Timing */ + + /* Get Detailed Timing */ + for (i=0;i<4;i++) { + if (MonInfo1->det_mon[i].type == 0xFD) + ranges1 = MonInfo1->det_mon[i].section.ranges; + else if (MonInfo1->det_mon[i].type == 0xFA) + stdtiming1 = MonInfo1->det_mon[i].section.std_t; + else if (MonInfo1->det_mon[i].type == 0x00) { + if (MonInfo1->det_mon[i].section.d_timings.clock > dclock1) + dclock1 = MonInfo1->det_mon[i].section.d_timings.clock; + if (MonInfo1->det_mon[i].section.d_timings.h_active > h_active1) + h_active1 = MonInfo1->det_mon[i].section.d_timings.h_active; + if (MonInfo1->det_mon[i].section.d_timings.v_active > v_active1) + v_active1 = MonInfo1->det_mon[i].section.d_timings.v_active; + } + if (MonInfo2->det_mon[i].type == 0xFD) + ranges2 = MonInfo2->det_mon[i].section.ranges; + else if (MonInfo1->det_mon[i].type == 0xFA) + stdtiming2 = MonInfo2->det_mon[i].section.std_t; + else if (MonInfo2->det_mon[i].type == 0x00) { + if (MonInfo2->det_mon[i].section.d_timings.clock > dclock2) + dclock2 = MonInfo2->det_mon[i].section.d_timings.clock; + if (MonInfo2->det_mon[i].section.d_timings.h_active > h_active2) + h_active2 = MonInfo2->det_mon[i].section.d_timings.h_active; + if (MonInfo2->det_mon[i].section.d_timings.v_active > v_active2) + v_active2 = MonInfo2->det_mon[i].section.d_timings.v_active; + } + } /* Get Detailed Timing */ + + /* Chk Detailed Timing */ + if ((dclock1 >= dclock2) && (h_active1 >= h_active2) && (v_active1 >= v_active2)) + DTSelect = DT2; + else if ((dclock2 >= dclock1) && (h_active2 >= h_active1) && (v_active2 >= v_active1)) + DTSelect = DT1; + else + DTSelect = SkipDT; + + /* Chk Monitor Descriptor */ + ranges = ranges1; + ranges.min_h = ranges1.min_h > ranges2.min_h ? ranges1.min_h:ranges2.min_h; + ranges.min_v = ranges1.min_v > ranges2.min_v ? ranges1.min_v:ranges2.min_v; + ranges.max_h = ranges1.max_h < ranges2.max_h ? ranges1.max_h:ranges2.max_h; + ranges.max_v = ranges1.max_v < ranges2.max_v ? ranges1.max_v:ranges2.max_v; + ranges.max_clock = ranges1.max_clock < ranges2.max_clock ? ranges1.max_clock:ranges2.max_clock; + + /* Update Detailed Timing */ + for (i=0; i<4; i++) + { + if (MonInfo->det_mon[i].type == 0xFD) { + MonInfo->det_mon[i].section.ranges = ranges; + } + else if (MonInfo->det_mon[i].type == 0xFA) { + for (j=0; j<5; j++) { + stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0; + for (k=0; k<5; k++) { + if ((stdtiming1[j].hsize == stdtiming2[k].hsize) && \ + (stdtiming1[j].vsize == stdtiming2[k].vsize) && \ + (stdtiming1[j].refresh == stdtiming2[k].refresh)) { + stdtiming = stdtiming1[j]; + break; + } + } + stdtiming1[j] = stdtiming; + } /* Std. Timing */ + } /* FA */ + else if (MonInfo->det_mon[i].type == 0x00) { + if (DTSelect == DT2) + MonInfo->det_mon[i] = MonInfo2->det_mon[i]; + else if (DTSelect == DT1) + MonInfo->det_mon[i] = MonInfo1->det_mon[i]; + else /* SkipDT */ + { /* use 1024x768 as default */ + MonInfo->det_mon[i] = MonInfo1->det_mon[i]; + MonInfo->det_mon[i].section.d_timings.clock = 65000000; + MonInfo->det_mon[i].section.d_timings.h_active = 1024; + MonInfo->det_mon[i].section.d_timings.h_blanking = 320; + MonInfo->det_mon[i].section.d_timings.v_active = 768; + MonInfo->det_mon[i].section.d_timings.v_blanking = 38; + MonInfo->det_mon[i].section.d_timings.h_sync_off = 24; + MonInfo->det_mon[i].section.d_timings.h_sync_width = 136; + MonInfo->det_mon[i].section.d_timings.v_sync_off = 3; + MonInfo->det_mon[i].section.d_timings.v_sync_width = 6; + } + } /* 00 */ + else { /* use Monitor 1 as default */ + MonInfo->det_mon[i] = MonInfo1->det_mon[i]; + } + + } /* Update Detailed Timing */ + + /* set feature size */ + if (DTSelect == DT2) { + MonInfo->features.hsize = MonInfo2->features.hsize; + MonInfo->features.vsize = MonInfo2->features.vsize; + } + else if (DTSelect == DT1) { + MonInfo->features.hsize = MonInfo1->features.hsize; + MonInfo->features.vsize = MonInfo1->features.vsize; + } + else /* Skip DT */ + { /* use 1024x768 as default */ + MonInfo->features.hsize = 0x20; + MonInfo->features.vsize = 0x18; + } + + } /* Check with VGA1 & VGA2 EDID */ + + } /* GetVGA2EDID */ + else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Can't Get VGA2 EDID Correctly!! \n"); + } + + } + xf86PrintEDID(MonInfo); xf86SetDDCproperties(pScrn, MonInfo); vbeFree(pVbe); @@ -1219,7 +1377,7 @@ ASTDoDDC(ScrnInfoPtr pScrn, int index) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "this driver cannot do DDC without VBE\n"); } - + return MonInfo; } diff --git a/src/ast_mode.c b/src/ast_mode.c index d142ba7..50a8a69 100644 --- a/src/ast_mode.c +++ b/src/ast_mode.c @@ -190,11 +190,11 @@ VBIOS_ENHTABLE_STRUCT Res1600x1200Table[] = { (SyncPP | Charx8Dot), 0xFF, 1, 0x33 }, }; -VBIOS_ENHTABLE_STRUCT Res1920x1200Table[] = { - {2592, 1920,136, 200, 1245, 1200, 3, 6, VCLK193_25, /* 60Hz */ - (SyncPP | Charx8Dot), 60, 1, 0x33 }, - {2592, 1920,136, 200, 1245, 1200, 3, 6, VCLK193_25, /* end */ - (SyncPP | Charx8Dot), 0xFF, 1, 0x33 }, +VBIOS_ENHTABLE_STRUCT Res1920x1200Table[] = { + {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz */ + (SyncNP | Charx8Dot), 60, 1, 0x34 }, + {2080, 1920, 48, 32, 1235, 1200, 3, 6, VCLK154, /* 60Hz */ + (SyncNP | Charx8Dot), 0xFF, 1, 0x34 }, }; VBIOS_DCLK_INFO DCLKTable [] = { @@ -214,7 +214,7 @@ VBIOS_DCLK_INFO DCLKTable [] = { {0x85, 0x24, 0x00}, /* 0D: VCLK135 */ {0x67, 0x22, 0x00}, /* 0E: VCLK157_5 */ {0x6A, 0x22, 0x00}, /* 0F: VCLK162 */ - {0x61, 0x2C, 0x81}, /* 10: VCLK193_25 */ + {0x4d, 0x4c, 0x80}, /* 10: VCLK193_25 */ }; VBIOS_DAC_INFO DAC_TEXT[] = { @@ -341,6 +341,7 @@ void vSetCRTCReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAMo void vSetOffsetReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo); void vSetDCLKReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo); void vSetExtReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo); +void vSetSyncReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo); Bool bSetDACReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo); Bool @@ -363,6 +364,7 @@ ASTSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) vSetOffsetReg(pScrn, mode, &vgamodeinfo); vSetDCLKReg(pScrn, mode, &vgamodeinfo); vSetExtReg(pScrn, mode, &vgamodeinfo); + vSetSyncReg(pScrn, mode, &vgamodeinfo); bSetDACReg(pScrn, mode, &vgamodeinfo); /* post set mode */ @@ -569,10 +571,10 @@ vSetCRTCReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInf if (usTemp & 0x20) jReg05 |= 0x80; /* HBE D[5] */ if (usTemp & 0x40) jRegAD |= 0x01; /* HBE D[6] */ SetIndexRegMask(CRTC_PORT,0x03, 0xE0, (UCHAR) (usTemp & 0x1F)); - usTemp = (mode->CrtcHSyncStart >> 3 ); + usTemp = (mode->CrtcHSyncStart >> 3 ) + 2; if (usTemp & 0x100) jRegAC |= 0x40; /* HRS D[5] */ SetIndexRegMask(CRTC_PORT,0x04, 0x00, (UCHAR) (usTemp)); - usTemp = (mode->CrtcHSyncEnd >> 3 ) & 0x3F; + usTemp = ((mode->CrtcHSyncEnd >> 3 ) + 2) & 0x3F; if (usTemp & 0x20) jRegAD |= 0x04; /* HRE D[5] */ SetIndexRegMask(CRTC_PORT,0x05, 0x60, (UCHAR) ((usTemp & 0x1F) | jReg05)); @@ -687,6 +689,20 @@ void vSetExtReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAMod } +void vSetSyncReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo) +{ + PVBIOS_ENHTABLE_STRUCT pEnhModePtr; + ASTRecPtr pAST; + UCHAR jReg; + + pAST = ASTPTR(pScrn); + pEnhModePtr = pVGAModeInfo->pEnhTableEntry; + + jReg = GetReg(MISC_PORT_READ); + jReg |= (UCHAR) (pEnhModePtr->Flags & SyncNN); + SetReg(MISC_PORT_WRITE,jReg); + +} Bool bSetDACReg(ScrnInfoPtr pScrn, DisplayModePtr mode, PVBIOS_MODE_INFO pVGAModeInfo) { diff --git a/src/ast_mode.h b/src/ast_mode.h index b1926a3..054d414 100644 --- a/src/ast_mode.h +++ b/src/ast_mode.h @@ -48,7 +48,8 @@ #define VCLK135 0x0D #define VCLK157_5 0x0E #define VCLK162 0x0F -#define VCLK193_25 0x10 +/* #define VCLK193_25 0x10 */ +#define VCLK154 0x10 /* Flags Definition */ #define Charx8Dot 0x00000001 diff --git a/src/ast_vgatool.c b/src/ast_vgatool.c index a833b3b..91a6a1d 100644 --- a/src/ast_vgatool.c +++ b/src/ast_vgatool.c @@ -61,11 +61,13 @@ void vASTOpenKey(ScrnInfoPtr pScrn); Bool bASTRegInit(ScrnInfoPtr pScrn); ULONG GetVRAMInfo(ScrnInfoPtr pScrn); ULONG GetMaxDCLK(ScrnInfoPtr pScrn); +void GetChipType(ScrnInfoPtr pScrn); void vAST1000DisplayOn(ASTRecPtr pAST); void vAST1000DisplayOff(ASTRecPtr pAST); void vSetStartAddressCRT1(ASTRecPtr pAST, ULONG base); void vASTLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual); void ASTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); +Bool GetVGA2EDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer); void vASTOpenKey(ScrnInfoPtr pScrn) @@ -172,7 +174,10 @@ GetMaxDCLK(ScrnInfoPtr pScrn) } - /* Get Bandwidth */ + /* Get Bandwidth */ + /* Modify DARM utilization to 60% for AST1100/2100 16bits DRAM, ycchen@032508 */ + if ( ((pAST->jChipType == AST2100) || (pAST->jChipType == AST1100)) && (ulDRAMBusWidth == 16) ) + DRAMEfficiency = 600; ulDRAMBandwidth = ulMCLK * ulDRAMBusWidth * 2 / 8; ActualDRAMBandwidth = ulDRAMBandwidth * DRAMEfficiency / 1000; @@ -183,12 +188,33 @@ GetMaxDCLK(ScrnInfoPtr pScrn) else ulDCLK = ActualDRAMBandwidth / ((pScrn->bitsPerPixel+1) / 8); - if (ulDCLK > 165) ulDCLK = 165; - + /* Add for AST2100, ycchen@061807 */ + if (pAST->jChipType == AST2100) + if (ulDCLK > 200) ulDCLK = 200; + else + if (ulDCLK > 165) ulDCLK = 165; + return(ulDCLK); } +void +GetChipType(ScrnInfoPtr pScrn) +{ + ASTRecPtr pAST = ASTPTR(pScrn); + ULONG ulData; + + pAST->jChipType = AST2100; + + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000; + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; + + ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x1207c); + + if ((ulData & 0x0300) == 0x0200) + pAST->jChipType = AST1100; +} + void vSetStartAddressCRT1(ASTRecPtr pAST, ULONG base) { @@ -319,3 +345,96 @@ ASTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int fla } + +#define I2C_BASE 0x1e780000 +#define I2C_OFFSET (0xA000 + 0x40 * 4) /* port4 */ +#define I2C_DEVICEADDR 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; + + pjEDID = pEDIDBuffer; + + /* SCU settings */ + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = 0x1e6e0000; + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; + xf86UDelay(10000); + + *(ULONG *) (pAST->MMIOVirtualAddr + 0x12000) = 0x1688A8A8; + ulData = *(ULONG *) (pAST->MMIOVirtualAddr + 0x12004); + ulData &= 0xfffffffb; + *(ULONG *) (pAST->MMIOVirtualAddr + 0x12004) = ulData; + xf86UDelay(10000); + + /* I2C settings */ + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF004) = I2C_BASE; + *(ULONG *) (pAST->MMIOVirtualAddr + 0xF000) = 0x1; + xf86UDelay(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; + do { + ulData = *(volatile ULONG *) (ulI2CBase + 0x10); + } while (!(ulData & 0x03)); + if (ulData & 0x02) /* NACK */ + return (FALSE); + *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; + *(ULONG *) (ulI2CBase + 0x20) = (ULONG) 0; /* Offset */ + *(ULONG *) (ulI2CBase + 0x14) = 0x02; + do { + ulData = *(volatile ULONG *) (ulI2CBase + 0x10); + } while (!(ulData & 0x01)); + *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; + *(ULONG *) (ulI2CBase + 0x20) = I2C_DEVICEADDR + 1; + *(ULONG *) (ulI2CBase + 0x14) = 0x03; + do { + ulData = *(volatile ULONG *) (ulI2CBase + 0x10); + } while (!(ulData & 0x01)); + + /* I2C Read */ + for (i=0; i<127; i++) + { + *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; + *(ULONG *) (ulI2CBase + 0x0C) |= 0x10; + *(ULONG *) (ulI2CBase + 0x14) = 0x08; + do { + ulData = *(volatile ULONG *) (ulI2CBase + 0x10); + } while (!(ulData & 0x04)); + *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; + *(UCHAR *) (pjEDID++) = (UCHAR) ((*(ULONG *) (ulI2CBase + 0x20) & 0xFF00) >> 8); + } + + /* Read Last Byte */ + *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; + *(ULONG *) (ulI2CBase + 0x0C) |= 0x10; + *(ULONG *) (ulI2CBase + 0x14) = 0x18; + do { + ulData = *(volatile ULONG *) (ulI2CBase + 0x10); + } while (!(ulData & 0x04)); + *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; + *(UCHAR *) (pjEDID++) = (UCHAR) ((*(ULONG *) (ulI2CBase + 0x20) & 0xFF00) >> 8); + + /* I2C Stop */ + *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; + *(ULONG *) (ulI2CBase + 0x14) = 0x20; + do { + ulData = *(volatile ULONG *) (ulI2CBase + 0x10); + } while (!(ulData & 0x10)); + *(ULONG *) (ulI2CBase + 0x0C) &= 0xffffffef; + *(ULONG *) (ulI2CBase + 0x10) = 0xffffffff; + + return (TRUE); + +} /* GetVGA2EDID */ diff --git a/src/ast_vgatool.h b/src/ast_vgatool.h index 8a4f683..9ce00fb 100644 --- a/src/ast_vgatool.h +++ b/src/ast_vgatool.h @@ -25,6 +25,7 @@ #define VIDEOMEM_SIZE_16M 0x01000000 #define VIDEOMEM_SIZE_32M 0x02000000 #define VIDEOMEM_SIZE_64M 0x04000000 +#define VIDEOMEM_SIZE_128M 0x08000000 #define AR_PORT_WRITE (pAST->RelocateIO + 0x40) #define MISC_PORT_WRITE (pAST->RelocateIO + 0x42) @@ -34,6 +35,7 @@ #define GR_PORT (pAST->RelocateIO + 0x4E) #define CRTC_PORT (pAST->RelocateIO + 0x54) #define INPUT_STATUS1_READ (pAST->RelocateIO + 0x5A) +#define MISC_PORT_READ (pAST->RelocateIO + 0x4C) #define GetReg(base) inb(base) #define SetReg(base,val) outb(base,val) -- cgit v1.2.3