diff options
author | Mathieu Larouche <mathieu.larouche@matrox.com> | 2016-07-20 09:18:49 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-07-28 05:35:38 +1000 |
commit | fc5d7acc23fcec9d87ca26fadf466fcf107671c0 (patch) | |
tree | be86cc6820e6bec8ae3e115e0447ee06cf2a7a78 | |
parent | 12781f2e3deb7f6d86fde53134384996a6004894 (diff) |
xf86-video-mga: Add support for the new G200e chipset -- V2
- Added PLL algorithm for a new rev of G200e
- Removed the bandwidth limitation for the new G200e
Fixes : https://bugs.freedesktop.org/show_bug.cgi?id=92540
Change from V1 :
- Make sure we don't cause issue on previous chips. (Dave Airlie review)
Signed-off-by: Mathieu Larouche <mathieu.larouche@matrox.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | src/mga_dacG.c | 82 | ||||
-rw-r--r-- | src/mga_driver.c | 6 |
2 files changed, 83 insertions, 5 deletions
diff --git a/src/mga_dacG.c b/src/mga_dacG.c index 2be0bb7..73d0d9d 100644 --- a/src/mga_dacG.c +++ b/src/mga_dacG.c @@ -51,6 +51,75 @@ static Bool MGAGInit(ScrnInfoPtr, DisplayModePtr); static void MGAGLoadPalette(ScrnInfoPtr, int, int*, LOCO*, VisualPtr); static Bool MGAG_i2cInit(ScrnInfoPtr pScrn); +#define P_ARRAY_SIZE 9 + +void +MGAG200E4ComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P) +{ + unsigned int ulComputedFo; + unsigned int ulFDelta; + unsigned int ulFPermitedDelta; + unsigned int ulFTmpDelta; + unsigned int ulVCOMax, ulVCOMin; + unsigned int ulTestP; + unsigned int ulTestM; + unsigned int ulTestN; + unsigned int ulFoInternal; + unsigned int ulPLLFreqRef; + unsigned int pulPValues[P_ARRAY_SIZE] = {16, 14, 12, 10, 8, 6, 4, 2, 1}; + unsigned int i; + unsigned int ulVCO; + unsigned int ulFVV; + + ulVCOMax = 1600000; + ulVCOMin = 800000; + ulPLLFreqRef = 25000; + + if(lFo < 25000) + lFo = 25000; + + ulFoInternal = lFo * 2; + + ulFDelta = 0xFFFFFFFF; + /* Permited delta is 0.5% as VESA Specification */ + ulFPermitedDelta = ulFoInternal * 5 / 1000; + + for (i = 0 ; i < P_ARRAY_SIZE ; i++) + { + ulTestP = pulPValues[i]; + + if ((ulFoInternal * ulTestP) > ulVCOMax) continue; + if ((ulFoInternal * ulTestP) < ulVCOMin) continue; + + for (ulTestN = 50; ulTestN <= 256; ulTestN++) { + for (ulTestM = 1; ulTestM <= 32; ulTestM++) { + ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP); + if (ulComputedFo > ulFoInternal) + ulFTmpDelta = ulComputedFo - ulFoInternal; + else + ulFTmpDelta = ulFoInternal - ulComputedFo; + + if (ulFTmpDelta < ulFDelta) { + ulFDelta = ulFTmpDelta; + *M = ulTestM - 1; + *N = ulTestN - 1; + *P = ulTestP - 1; + } + } + } + } + + ulVCO = ulPLLFreqRef * ((*N)+1) / ((*M)+1); + ulFVV = (ulVCO - 800000) / 50000; + + if (ulFVV > 15) + ulFVV = 15; + + *P |= (ulFVV << 4); + + *M |= 0x80; +} + static void MGAG200SEComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P) { @@ -958,7 +1027,11 @@ MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out ) } if (pMga->is_G200SE) { - MGAG200SEComputePLLParam(pScrn, f_out, &m, &n, &p); + if (pMga->reg_1e24 >= 0x04) { + MGAG200E4ComputePLLParam(pScrn, f_out, &m, &n, &p); + } else { + MGAG200SEComputePLLParam(pScrn, f_out, &m, &n, &p); + } pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m; pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n; @@ -1557,7 +1630,12 @@ MGA_NOT_HAL( { outMGAdac(0x90, mgaReg->Dac_Index90); } - + if (pMga->is_G200SE && (pMga->reg_1e24 >= 0x04)) { + outMGAdac( 0x1a, 0x09); + usleep(500); + outMGAdac( 0x1a, 0x01); + } + if (!MGAISGx50(pMga)) { /* restore pci_option register */ #ifdef XSERVER_LIBPCIACCESS diff --git a/src/mga_driver.c b/src/mga_driver.c index 96d1d7a..7b46561 100644 --- a/src/mga_driver.c +++ b/src/mga_driver.c @@ -315,7 +315,7 @@ static const struct mga_device_attributes attribs[] = { }, /* G200SE A PCI */ - [10] = { 0, 1, 0, 0, 1, 0, 0, 1, new_BARs, + [10] = { 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 */ @@ -331,7 +331,7 @@ static const struct mga_device_attributes attribs[] = { }, /* G200SE B PCI */ - [11] = { 0, 1, 0, 0, 1, 0, 0, 1, new_BARs, + [11] = { 0, 1, 0, 0, 1, 0, 0, 0, new_BARs, (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION), { { 50000, 114000 }, /* System VCO frequencies */ @@ -3854,7 +3854,7 @@ MGAValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) if (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 244) return MODE_BANDWIDTH; } else { - if (pMga->reg_1e24 >= 0x02) { + if (pMga->reg_1e24 == 0x02) { if (mode->HDisplay > 1920) return MODE_VIRTUAL_X; if (mode->VDisplay > 1200) |