summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <idr@us.ibm.com>2008-06-09 11:36:46 -0700
committerIan Romanick <idr@us.ibm.com>2008-06-09 11:36:46 -0700
commit9e2ee9403c198da5d79dfb2f4fcafe9b381afd3d (patch)
tree779fedbf272279e387d49a46e1df2db19db3e944
parentfd9732800687b96caa9f81c0cc4b24c6aad04e78 (diff)
G200EV: Enable support for G200EV
-rw-r--r--src/mga.h8
-rw-r--r--src/mga_dacG.c155
-rw-r--r--src/mga_driver.c34
-rw-r--r--src/mga_merge.c2
-rw-r--r--src/mga_reg.h9
-rw-r--r--src/mga_storm.c1
6 files changed, 197 insertions, 12 deletions
diff --git a/src/mga.h b/src/mga.h
index c7fd93d..2469554 100644
--- a/src/mga.h
+++ b/src/mga.h
@@ -124,6 +124,10 @@ void MGAdbg_outreg32(ScrnInfoPtr, int,int, char*);
#define PCI_CHIP_MGAG200_SE_B_PCI 0x0524
#endif
+#ifndef PCI_CHIP_MGAG200_EV_PCI
+#define PCI_CHIP_MGAG200_EV_PCI 0x0530
+#endif
+
/*
* Read/write to the DAC via MMIO
*/
@@ -195,6 +199,9 @@ typedef struct {
CARD32 Option3;
long Clock;
Bool PIXPLLCSaved;
+ unsigned char PllM;
+ unsigned char PllN;
+ unsigned char PllP;
} MGARegRec, *MGARegPtr;
/* For programming the second CRTC */
@@ -460,6 +467,7 @@ typedef struct {
int is_Gx50:1;
int is_G200SE:1;
+ int is_G200EV:1;
CARD32 reg_1e24; /* model revision on g200se */
Bool Primary;
diff --git a/src/mga_dacG.c b/src/mga_dacG.c
index eb16d7e..c3f75b9 100644
--- a/src/mga_dacG.c
+++ b/src/mga_dacG.c
@@ -62,8 +62,9 @@ static void MGAGLoadPalette(ScrnInfoPtr, int, int*, LOCO*, VisualPtr);
static Bool MGAG_i2cInit(ScrnInfoPtr pScrn);
static void
-MGAG200SEComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
+MGAG200IPComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
{
+ MGAPtr pMga = MGAPTR(pScrn);
unsigned int ulComputedFo;
unsigned int ulFDelta;
unsigned int ulFPermitedDelta;
@@ -73,22 +74,41 @@ MGAG200SEComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
unsigned int ulTestM;
unsigned int ulTestN;
unsigned int ulPLLFreqRef;
-
- ulVCOMax = 320000;
- ulVCOMin = 160000;
- ulPLLFreqRef = 25000;
+ unsigned int ulTestPStart;
+ unsigned int ulTestNStart;
+ unsigned int ulTestNEnd;
+ unsigned int ulTestMEnd;
+
+ if (pMga->is_G200SE) {
+ ulVCOMax = 320000;
+ ulVCOMin = 160000;
+ ulPLLFreqRef = 25000;
+ ulTestPStart = 8;
+ ulTestNStart = 17;
+ ulTestNEnd = 32;
+ ulTestMEnd = 32;
+
+ } else if (pMga->is_G200EV) {
+ ulVCOMax = 550000;
+ ulVCOMin = 150000;
+ ulPLLFreqRef = 50000;
+ ulTestPStart = 16;
+ ulTestNStart = 1;
+ ulTestNEnd = 256;
+ ulTestMEnd = 16;
+ }
ulFDelta = 0xFFFFFFFF;
/* Permited delta is 0.5% as VESA Specification */
ulFPermitedDelta = lFo * 5 / 1000;
/* Then we need to minimize the M while staying within 0.5% */
- for (ulTestP = 8; ulTestP > 0; ulTestP >>= 1) {
+ for (ulTestP = ulTestPStart; ulTestP > 0; ulTestP--) {
if ((lFo * ulTestP) > ulVCOMax) continue;
if ((lFo * ulTestP) < ulVCOMin) continue;
- for (ulTestN = 17; ulTestN <= 256; ulTestN++) {
- for (ulTestM = 1; ulTestM <= 32; ulTestM++) {
+ for (ulTestN = ulTestNStart; ulTestN <= ulTestNEnd; ulTestN++) {
+ for (ulTestM = 1; ulTestM <= ulTestMEnd; ulTestM++) {
ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP);
if (ulComputedFo > lFo)
ulFTmpDelta = ulComputedFo - lFo;
@@ -104,8 +124,82 @@ MGAG200SEComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
}
}
}
+#if DEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "lFo=%ld n=0x%x m=0x%x p=0x%x \n",
+ lFo, *N, *M, *P );
+#endif
}
+static void
+MGAG200EVPIXPLLSET(ScrnInfoPtr pScrn, MGARegPtr mgaReg)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ unsigned long ulFallBackCounter;
+ unsigned char ucTempByte, ucPixCtrl;
+ unsigned char ucM;
+ unsigned char ucN;
+ unsigned char ucP;
+ unsigned char ucS;
+
+ // Set pixclkdis to 1
+ ucPixCtrl = inMGAdac(MGA1064_PIX_CLK_CTL);
+ ucPixCtrl |= MGA1064_PIX_CLK_CTL_CLK_DIS;
+ outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
+
+ // Select PLL Set C
+ ucTempByte = INREG8(MGAREG_MISC_READ);
+ ucTempByte |= 0x3<<2; //select MGA pixel clock
+ OUTREG8(MGAREG_MISC_WRITE, ucTempByte);
+
+ // Set pixlock to 0
+ ucTempByte = inMGAdac(MGA1064_PIX_PLL_STAT);
+ outMGAdac(MGA1064_PIX_PLL_STAT, ucTempByte & ~0x40);
+
+ // Set pix_stby to 1
+ ucPixCtrl |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
+ outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
+
+ // Program the Pixel PLL Register
+ outMGAdac(MGA1064_EV_PIX_PLLC_M, mgaReg->PllM);
+ outMGAdac(MGA1064_EV_PIX_PLLC_N, mgaReg->PllN);
+ outMGAdac(MGA1064_EV_PIX_PLLC_P, mgaReg->PllP);
+
+ // Wait 50 us
+ usleep(50);
+
+ // Set pix_stby to 0
+ ucPixCtrl &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
+ outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
+
+ // Wait 500 us
+ usleep(500);
+
+ // Select the pixel PLL by setting pixclksel to 1
+ ucTempByte = inMGAdac(MGA1064_PIX_CLK_CTL);
+ ucTempByte &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
+ ucTempByte |= MGA1064_PIX_CLK_CTL_SEL_PLL;
+ outMGAdac(MGA1064_PIX_CLK_CTL, ucTempByte);
+
+ // Set pixlock to 1
+ ucTempByte = inMGAdac(MGA1064_PIX_PLL_STAT);
+ outMGAdac(MGA1064_PIX_CLK_CTL, ucTempByte | 0x40);
+
+ // Reset dotclock rate bit.
+ ucTempByte = INREG8(MGAREG_MEM_MISC_READ);
+ ucTempByte |= 0x3<<2; //select MGA pixel clock
+ OUTREG8(MGAREG_MEM_MISC_WRITE, ucTempByte);
+
+ OUTREG8(MGAREG_SEQ_INDEX, 1);
+ ucTempByte = INREG8(MGAREG_SEQ_DATA);
+ OUTREG8(MGAREG_SEQ_DATA, ucTempByte & ~0x8);
+
+ // Set pixclkdis to 0
+ ucTempByte = inMGAdac(MGA1064_PIX_CLK_CTL);
+ ucTempByte &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
+ outMGAdac(MGA1064_PIX_CLK_CTL, ucTempByte);
+}
/**
* Calculate the PLL settings (m, n, p, s).
@@ -237,12 +331,17 @@ MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out )
}
if (pMga->is_G200SE) {
- MGAG200SEComputePLLParam(pScrn, f_out, &m, &n, &p);
+ MGAG200IPComputePLLParam(pScrn, f_out, &m, &n, &p);
pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m;
pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n;
pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = p;
- } else {
+ } else if (pMga->is_G200EV) {
+ MGAG200IPComputePLLParam(pScrn, f_out, &m, &n, &p);
+ pReg->PllM = m;
+ pReg->PllN = n;
+ pReg->PllP = p;
+ } else {
/* Do the calculations for m, n, p and s */
MGAGCalcClock( pScrn, f_out, &m, &n, &p, &s );
@@ -420,6 +519,17 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
pReg->Option = 0x40049120;
pReg->Option2 = 0x00008000;
break;
+ case PCI_CHIP_MGAG200_EV_PCI:
+ pReg->DacRegs[MGA1064_PIX_CLK_CTL] =
+ MGA1064_PIX_CLK_CTL_SEL_PLL;
+
+ pReg->DacRegs[MGA1064_MISC_CTL] =
+ MGA1064_MISC_CTL_VGA8 |
+ MGA1064_MISC_CTL_DAC_RAM_CS;
+
+ pReg->Option = 0x00000120;
+ pReg->Option2 = 0x0000b000;
+ break;
case PCI_CHIP_MGAG200:
case PCI_CHIP_MGAG200_PCI:
default:
@@ -758,6 +868,10 @@ MGA_NOT_HAL(
if (pMga->is_G200SE
&& ((i == 0x2C) || (i == 0x2D) || (i == 0x2E)))
continue;
+ if ( (pMga->is_G200EV) &&
+ (i >= 0x44) && (i <= 0x4E))
+ continue;
+
outMGAdac(i, mgaReg->DacRegs[i]);
}
@@ -790,6 +904,10 @@ MGA_NOT_HAL(
mgaReg->Option3);
#endif
}
+
+ if (pMga->is_G200EV) {
+ MGAG200EVPIXPLLSET(pScrn, mgaReg);
+ }
); /* MGA_NOT_HAL */
#ifdef USEMGAHAL
/*
@@ -821,6 +939,12 @@ MGA_NOT_HAL(
}
MGAGRestorePalette(pScrn, vgaReg->DAC);
+
+ if (pMga->is_G200EV) {
+ OUTREG16(MGAREG_CRTCEXT_INDEX, 6);
+ OUTREG16(MGAREG_CRTCEXT_DATA, 0);
+ }
+
/*
* this is needed to properly restore start address
*/
@@ -950,6 +1074,12 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
for (i = 0; i < DACREGSIZE; i++)
mgaReg->DacRegs[i] = inMGAdac(i);
+ if (pMga->is_G200EV) {
+ mgaReg->PllM = inMGAdac(MGA1064_EV_PIX_PLLC_M);
+ mgaReg->PllN = inMGAdac(MGA1064_EV_PIX_PLLC_N);
+ mgaReg->PllP = inMGAdac(MGA1064_EV_PIX_PLLC_P);
+ }
+
mgaReg->PIXPLLCSaved = TRUE;
#ifdef XSERVER_LIBPCIACCESS
@@ -1129,6 +1259,7 @@ static const struct mgag_i2c_private {
{ (1 << 1), (1 << 3) },
{ (1 << 0), (1 << 2) },
{ (1 << 4), (1 << 5) },
+ { (1 << 0), (1 << 1) }, /* G200EV I2C bits */
};
@@ -1229,7 +1360,9 @@ MGAG_i2cInit(ScrnInfoPtr pScrn)
I2CBusPtr I2CPtr;
if (pMga->SecondCrtc == FALSE) {
- pMga->DDC_Bus1 = mgag_create_i2c_bus("DDC P1", 0, pScrn->scrnIndex);
+ pMga->DDC_Bus1 = mgag_create_i2c_bus("DDC P1",
+ pMga->is_G200EV ? 3 : 0,
+ pScrn->scrnIndex);
return (pMga->DDC_Bus1 != NULL);
} else {
/* We have a dual head setup on G-series, set up DDC #2. */
diff --git a/src/mga_driver.c b/src/mga_driver.c
index 8f057a2..0f36970 100644
--- a/src/mga_driver.c
+++ b/src/mga_driver.c
@@ -353,6 +353,22 @@ static const struct mga_device_attributes attribs[] = {
4096, 0x800, /* Memory probe size & offset values */
},
+
+ /* G200EV */
+ [12] = { 0, 1, 0, 0, 1, 0, 0, 0, new_BARs,
+ (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION),
+ {
+ { 50000, 230000 }, /* System VCO frequencies */
+ { 50000, 230000 }, /* Pixel VCO frequencies */
+ { 0, 0 }, /* Video VCO frequencies */
+ 45000, /* Memory clock */
+ 27050, /* PLL reference frequency */
+ 0, /* Supports fast bitblt? */
+ MGA_HOST_PCI /* Host interface */
+ },
+
+ 8192, 0x4000, /* Memory probe size & offset values */
+ },
};
#ifdef XSERVER_LIBPCIACCESS
@@ -376,6 +392,8 @@ static const struct pci_id_match mga_device_match[] = {
MGA_DEVICE_MATCH(PCI_CHIP_MGAG200_SE_A_PCI, 10),
MGA_DEVICE_MATCH(PCI_CHIP_MGAG200_SE_B_PCI, 11),
+ MGA_DEVICE_MATCH(PCI_CHIP_MGAG200_EV_PCI, 12),
+
{ 0, 0, 0 },
};
#endif
@@ -392,6 +410,7 @@ static SymTabRec MGAChipsets[] = {
{ PCI_CHIP_MGAG200_PCI, "mgag200 PCI" },
{ PCI_CHIP_MGAG200_SE_A_PCI, "mgag200 SE A PCI" },
{ PCI_CHIP_MGAG200_SE_B_PCI, "mgag200 SE B PCI" },
+ { PCI_CHIP_MGAG200_EV_PCI, "mgag200 Maxim" },
{ PCI_CHIP_MGAG400, "mgag400" },
{ PCI_CHIP_MGAG550, "mgag550" },
{-1, NULL }
@@ -410,6 +429,8 @@ static PciChipsets MGAPciChipsets[] = {
(resRange*)RES_SHARED_VGA },
{ PCI_CHIP_MGAG200_SE_A_PCI, PCI_CHIP_MGAG200_SE_A_PCI,
(resRange*)RES_SHARED_VGA },
+ { PCI_CHIP_MGAG200_EV_PCI, PCI_CHIP_MGAG200_EV_PCI,
+ (resRange*)RES_SHARED_VGA },
{ PCI_CHIP_MGAG400, PCI_CHIP_MGAG400, (resRange*)RES_SHARED_VGA },
{ PCI_CHIP_MGAG550, PCI_CHIP_MGAG550, (resRange*)RES_SHARED_VGA },
{ -1, -1, (resRange*)RES_UNDEFINED }
@@ -1048,6 +1069,10 @@ MGAProbe(DriverPtr drv, int flags)
attrib_no = 11;
break;
+ case PCI_CHIP_MGAG200_EV_PCI:
+ attrib_no = 12;
+ break;
+
default:
return FALSE;
}
@@ -1240,7 +1265,7 @@ MGACountRam(ScrnInfoPtr pScrn)
OUTREG8(MGAREG_CRTCEXT_DATA, tmp | 0x80);
/* apparently the G200SE doesn't have a BIOS to read */
- if (pMga->is_G200SE) {
+ if (pMga->is_G200SE || pMga->is_G200EV) {
CARD32 MemoryAt0, MemoryAt1, Offset;
CARD32 FirstMemoryVal1, FirstMemoryVal2;
CARD32 SecondMemoryVal1, SecondMemoryVal2;
@@ -1736,6 +1761,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
|| (pMga->Chipset == PCI_CHIP_MGAG550);
pMga->is_G200SE = (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI)
|| (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI);
+ pMga->is_G200EV = (pMga->Chipset == PCI_CHIP_MGAG200_EV_PCI);
#ifdef USEMGAHAL
if (pMga->chip_attribs->HAL_chipset) {
@@ -2150,6 +2176,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_MGAG200_PCI:
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
+ case PCI_CHIP_MGAG200_EV_PCI:
case PCI_CHIP_MGAG400:
case PCI_CHIP_MGAG550:
MGAGSetupFuncs(pScrn);
@@ -2373,6 +2400,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_MGAG200_PCI:
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
+ case PCI_CHIP_MGAG200_EV_PCI:
pMga->SrcOrg = 0;
pMga->DstOrg = 0;
break;
@@ -2550,6 +2578,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_MGAG200_PCI:
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
+ case PCI_CHIP_MGAG200_EV_PCI:
case PCI_CHIP_MGAG400:
case PCI_CHIP_MGAG550:
maxPitch = 4096;
@@ -4444,6 +4473,9 @@ MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
if (pMga->reg_1e24 == 0x01 &&
xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 256)
return MODE_BANDWIDTH;
+ } else if (pMga->is_G200EV
+ && (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 327)) {
+ return MODE_BANDWIDTH;
}
lace = 1 + ((mode->Flags & V_INTERLACE) != 0);
diff --git a/src/mga_merge.c b/src/mga_merge.c
index 6ebbebb..0cb2b74 100644
--- a/src/mga_merge.c
+++ b/src/mga_merge.c
@@ -363,6 +363,7 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags)
case PCI_CHIP_MGAG200_PCI:
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
+ case PCI_CHIP_MGAG200_EV_PCI:
case PCI_CHIP_MGAG400:
case PCI_CHIP_MGAG550:
MGAGSetupFuncs(pScrn);
@@ -515,6 +516,7 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags)
case PCI_CHIP_MGAG200_PCI:
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
+ case PCI_CHIP_MGAG200_EV_PCI:
case PCI_CHIP_MGAG400:
case PCI_CHIP_MGAG550:
maxPitch = 4096;
diff --git a/src/mga_reg.h b/src/mga_reg.h
index 020bb0d..16df6c1 100644
--- a/src/mga_reg.h
+++ b/src/mga_reg.h
@@ -221,6 +221,9 @@
#define MGADWG_TRANSC ( 0x01 << 30 )
#define MGAREG_MISC_WRITE 0x3c2
#define MGAREG_MISC_READ 0x3cc
+#define MGAREG_MEM_MISC_WRITE 0x1fc2
+#define MGAREG_MEM_MISC_READ 0x1fcc
+
#define MGAREG_MISC_IOADSEL (0x1 << 0)
#define MGAREG_MISC_RAMMAPEN (0x1 << 1)
#define MGAREG_MISC_CLK_SEL_VGA25 (0x0 << 2)
@@ -408,6 +411,12 @@
#define MGA1064_VID_PLL_M 0x8E
#define MGA1064_VID_PLL_N 0x8F
+/* Modified for G200 Maxim (G200EV) */
+#define MGA1064_EV_PIX_PLLC_M 0xb6
+#define MGA1064_EV_PIX_PLLC_N 0xb7
+#define MGA1064_EV_PIX_PLLC_P 0xb8
+
+
#define MGA1064_DISP_CTL 0x8a
#define MGA1064_DISP_CTL_DAC1OUTSEL_MASK 0x01
#define MGA1064_DISP_CTL_DAC1OUTSEL_DIS 0x00
diff --git a/src/mga_storm.c b/src/mga_storm.c
index fa2a6ba..5a9a0fa 100644
--- a/src/mga_storm.c
+++ b/src/mga_storm.c
@@ -1130,6 +1130,7 @@ void MGAStormEngineInit( ScrnInfoPtr pScrn )
case PCI_CHIP_MGAG200_PCI:
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
+ case PCI_CHIP_MGAG200_EV_PCI:
pMga->SrcOrg = 0;
OUTREG(MGAREG_SRCORG, pMga->realSrcOrg);
OUTREG(MGAREG_DSTORG, pMga->DstOrg);