summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathieu Larouche <mathieu.larouche@matrox.com>2016-07-20 09:18:49 -0400
committerDave Airlie <airlied@redhat.com>2016-07-28 05:35:38 +1000
commitfc5d7acc23fcec9d87ca26fadf466fcf107671c0 (patch)
treebe86cc6820e6bec8ae3e115e0447ee06cf2a7a78
parent12781f2e3deb7f6d86fde53134384996a6004894 (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.c82
-rw-r--r--src/mga_driver.c6
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)