diff options
author | Ian Romanick <idr@us.ibm.com> | 2008-06-09 11:36:46 -0700 |
---|---|---|
committer | Ian Romanick <idr@us.ibm.com> | 2008-06-09 11:36:46 -0700 |
commit | 9e2ee9403c198da5d79dfb2f4fcafe9b381afd3d (patch) | |
tree | 779fedbf272279e387d49a46e1df2db19db3e944 | |
parent | fd9732800687b96caa9f81c0cc4b24c6aad04e78 (diff) |
G200EV: Enable support for G200EV
-rw-r--r-- | src/mga.h | 8 | ||||
-rw-r--r-- | src/mga_dacG.c | 155 | ||||
-rw-r--r-- | src/mga_driver.c | 34 | ||||
-rw-r--r-- | src/mga_merge.c | 2 | ||||
-rw-r--r-- | src/mga_reg.h | 9 | ||||
-rw-r--r-- | src/mga_storm.c | 1 |
6 files changed, 197 insertions, 12 deletions
@@ -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); |