summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast.h7
-rw-r--r--src/ast_2dtool.c2
-rw-r--r--src/ast_driver.c182
-rw-r--r--src/ast_mode.c32
-rw-r--r--src/ast_mode.h3
-rw-r--r--src/ast_vgatool.c125
-rw-r--r--src/ast_vgatool.h2
7 files changed, 327 insertions, 26 deletions
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,13 +188,34 @@ 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)
{
SetIndexReg(CRTC_PORT,0x0D, (UCHAR) (base & 0xFF));
@@ -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)