[PATCH video-mga 1/2] xf86-video-mga: Add support for a new G200eW3 chipset
mathieu.larouche at matrox.com
mathieu.larouche at matrox.com
Fri Jun 17 14:52:42 UTC 2016
From: Mathieu Larouche <mathieu.larouche at matrox.com>
- Added support for the new deviceID for G200eW3
- Added PLL algorithm for the G200eW3
- Added some initialization code for G200eW3
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=92541
Signed-off-by: Mathieu Larouche <mathieu.larouche at matrox.com>
---
src/mga.h | 10 ++++--
src/mga_dacG.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
src/mga_driver.c | 49 +++++++++++++++++++++-----
src/mga_merge.c | 4 ++-
src/mga_storm.c | 1 +
5 files changed, 149 insertions(+), 17 deletions(-)
diff --git a/src/mga.h b/src/mga.h
index e87932f..04f6bfd 100644
--- a/src/mga.h
+++ b/src/mga.h
@@ -146,6 +146,12 @@ void MGAdbg_outreg32(ScrnInfoPtr, int,int, char*);
#define PCI_CHIP_MGAG400 0x0525
#define PCI_CHIP_MGAG550 0x2527
+#ifndef PCI_CHIP_MGAG200_EW3_PCI
+#define PCI_CHIP_MGAG200_EW3_PCI 0x0536
+#endif
+
+
+
/*
* Read/write to the DAC via MMIO
*/
@@ -209,9 +215,9 @@ void MGAdbg_outreg32(ScrnInfoPtr, int,int, char*);
typedef struct {
unsigned char ExtVga[6];
unsigned char DacClk[6];
- unsigned char ExtVga_Index24;
+ unsigned char ExtVga_MgaReq;
unsigned char Dac_Index90;
- unsigned char * DacRegs;
+ unsigned char * DacRegs;
unsigned long crtc2[0x58];
unsigned char dac2[0x21];
CARD32 Option;
diff --git a/src/mga_dacG.c b/src/mga_dacG.c
index f307488..2be0bb7 100644
--- a/src/mga_dacG.c
+++ b/src/mga_dacG.c
@@ -207,6 +207,74 @@ MGAG200WBComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
#endif
}
+void
+MGAG200EW3ComputePLLParam(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 ulTestP1;
+ unsigned int ulTestP2;
+ unsigned int ulTestM;
+ unsigned int ulTestN;
+ unsigned int ulPLLFreqRef;
+ unsigned int ulTestP1Start;
+ unsigned int ulTestP1End;
+ unsigned int ulTestP2Start;
+ unsigned int ulTestP2End;
+ unsigned int ulTestMStart;
+ unsigned int ulTestMEnd;
+ unsigned int ulTestNStart;
+ unsigned int ulTestNEnd;
+
+ ulVCOMax = 800000;
+ ulVCOMin = 400000;
+ ulPLLFreqRef = 25000;
+ ulTestP1Start = 1;
+ ulTestP1End = 8;
+ ulTestP2Start = 1;
+ ulTestP2End = 8;
+ ulTestMStart = 1;
+ ulTestMEnd = 26;
+ ulTestNStart = 32;
+ ulTestNEnd = 2048;
+
+ 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 (ulTestP1 = ulTestP1Start; ulTestP1 < ulTestP1End; ulTestP1++) {
+ for (ulTestP2 = ulTestP2Start; ulTestP2 < ulTestP2End; ulTestP2++) {
+ if (ulTestP1 < ulTestP2) continue;
+ if ((lFo * ulTestP1 * ulTestP2) > ulVCOMax) continue;
+ if ((lFo * ulTestP1 * ulTestP2) < ulVCOMin) continue;
+
+ for (ulTestM = ulTestMStart; ulTestM < ulTestMEnd; ulTestM++) {
+ for (ulTestN = ulTestNStart; ulTestN < ulTestNEnd; ulTestN++) {
+ ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP1 * ulTestP2);
+ if (ulComputedFo > lFo)
+ ulFTmpDelta = ulComputedFo - lFo;
+ else
+ ulFTmpDelta = lFo - ulComputedFo;
+
+ if (ulFTmpDelta < ulFDelta) {
+ ulFDelta = ulFTmpDelta;
+ *M = (CARD8)((ulTestN & 0x100) >> 1) |
+ (CARD8)(ulTestM);
+ *N = (CARD8)(ulTestN & 0xFF);
+ *P = (CARD8)((ulTestN & 0x600) >> 3) |
+ (CARD8)(ulTestP2 << 3) |
+ (CARD8)ulTestP1;
+ }
+ }
+ }
+ }
+ }
+}
+
static void
MGAG200EHComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
{
@@ -902,7 +970,14 @@ MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out )
pReg->PllN = n;
pReg->PllP = p;
} else if (pMga->is_G200WB) {
- MGAG200WBComputePLLParam(pScrn, f_out, &m, &n, &p);
+ if (pMga->Chipset == PCI_CHIP_MGAG200_EW3_PCI)
+ {
+ MGAG200EW3ComputePLLParam(pScrn, f_out, &m, &n, &p);
+ }
+ else
+ {
+ MGAG200WBComputePLLParam(pScrn, f_out, &m, &n, &p);
+ }
pReg->PllM = m;
pReg->PllN = n;
@@ -1092,6 +1167,7 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
break;
case PCI_CHIP_MGAG200_WINBOND_PCI:
+ case PCI_CHIP_MGAG200_EW3_PCI:
pReg->DacRegs[MGA1064_VREF_CTL] = 0x07;
pReg->Option = 0x41049120;
pReg->Option2 = 0x0000b000;
@@ -1232,7 +1308,7 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
if (pMga->is_G200WB){
pReg->ExtVga[1] |= 0x88;
}
- pReg->ExtVga_Index24 = 0x05;
+ pReg->ExtVga_MgaReq = 0x05;
pVga->CRTC[0] = ht - 4;
pVga->CRTC[1] = hd;
@@ -1528,7 +1604,15 @@ MGA_NOT_HAL(
if (pMga->is_G200ER) {
OUTREG8(MGAREG_CRTCEXT_INDEX, 0x24);
- OUTREG8(MGAREG_CRTCEXT_DATA, mgaReg->ExtVga_Index24);
+ OUTREG8(MGAREG_CRTCEXT_DATA, mgaReg->ExtVga_MgaReq);
+ }
+
+ if (pMga->is_G200WB) {
+ if(pMga->Chipset == PCI_CHIP_MGAG200_EW3_PCI)
+ {
+ OUTREG8(MGAREG_CRTCEXT_INDEX, 0x34);
+ OUTREG8(MGAREG_CRTCEXT_DATA, mgaReg->ExtVga_MgaReq);
+ }
}
/* This handles restoring the generic VGA registers. */
@@ -1717,8 +1801,16 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
if (pMga->is_G200ER)
{
OUTREG8(MGAREG_CRTCEXT_INDEX, 0x24);
- mgaReg->ExtVga_Index24 = INREG8(MGAREG_CRTCEXT_DATA);
- }
+ mgaReg->ExtVga_MgaReq = INREG8(MGAREG_CRTCEXT_DATA);
+ }
+ if (pMga->is_G200WB)
+ {
+ if(pMga->Chipset == PCI_CHIP_MGAG200_EW3_PCI)
+ {
+ OUTREG8(MGAREG_CRTCEXT_INDEX, 0x34);
+ mgaReg->ExtVga_MgaReq = INREG8(MGAREG_CRTCEXT_DATA);
+ }
+ }
#ifdef DEBUG
ErrorF("Saved values:\nDAC:");
diff --git a/src/mga_driver.c b/src/mga_driver.c
index 8a7186f..96d1d7a 100644
--- a/src/mga_driver.c
+++ b/src/mga_driver.c
@@ -408,6 +408,22 @@ static const struct mga_device_attributes attribs[] = {
},
16384, 0x4000, /* Memory probe size & offset values */
+ },
+
+ /* G200WB */
+ [16] = { 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, 203400 }, /* Pixel VCO frequencies */
+ { 0, 0 }, /* Video VCO frequencies */
+ 45000, /* Memory clock */
+ 27050, /* PLL reference frequency */
+ 0, /* Supports fast bitblt? */
+ MGA_HOST_PCI /* Host interface */
+ },
+
+ 16384, 0x4000, /* Memory probe size & offset values */
}
};
@@ -438,7 +454,9 @@ static const struct pci_id_match mga_device_match[] = {
MGA_DEVICE_MATCH( PCI_CHIP_MGAG200_EH_PCI, 14 ),
- MGA_DEVICE_MATCH(PCI_CHIP_MGAG200_ER_PCI, 15 ),
+ MGA_DEVICE_MATCH(PCI_CHIP_MGAG200_ER_PCI, 15 ),
+
+ MGA_DEVICE_MATCH( PCI_CHIP_MGAG200_EW3_PCI, 16 ),
{ 0, 0, 0 },
};
@@ -459,6 +477,7 @@ static SymTabRec MGAChipsets[] = {
{ PCI_CHIP_MGAG200_EV_PCI, "mgag200 EV Maxim" },
{ PCI_CHIP_MGAG200_ER_PCI, "mgag200 ER SH7757" },
{ PCI_CHIP_MGAG200_WINBOND_PCI, "mgag200 eW Nuvoton" },
+ { PCI_CHIP_MGAG200_EW3_PCI, "mgag200 eW3 Nuvoton" },
{ PCI_CHIP_MGAG200_EH_PCI, "mgag200eH" },
{ PCI_CHIP_MGAG400, "mgag400" },
{ PCI_CHIP_MGAG550, "mgag550" },
@@ -484,6 +503,8 @@ static PciChipsets MGAPciChipsets[] = {
RES_SHARED_VGA },
{ PCI_CHIP_MGAG200_WINBOND_PCI, PCI_CHIP_MGAG200_WINBOND_PCI,
RES_SHARED_VGA },
+ { PCI_CHIP_MGAG200_EW3_PCI, PCI_CHIP_MGAG200_EW3_PCI,
+ RES_SHARED_VGA },
{ PCI_CHIP_MGAG200_EH_PCI, PCI_CHIP_MGAG200_EH_PCI,
RES_SHARED_VGA },
{ PCI_CHIP_MGAG400, PCI_CHIP_MGAG400, RES_SHARED_VGA },
@@ -923,6 +944,9 @@ MGAProbe(DriverPtr drv, int flags)
attrib_no = 15;
break;
+ case PCI_CHIP_MGAG200_EW3_PCI:
+ attrib_no = 16;
+ break;
default:
return FALSE;
@@ -1541,7 +1565,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
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);
- pMga->is_G200WB = (pMga->Chipset == PCI_CHIP_MGAG200_WINBOND_PCI);
+ pMga->is_G200WB = (pMga->Chipset == PCI_CHIP_MGAG200_WINBOND_PCI)
+ || (pMga->Chipset == PCI_CHIP_MGAG200_EW3_PCI);
pMga->is_G200EH = (pMga->Chipset == PCI_CHIP_MGAG200_EH_PCI);
pMga->is_G200ER = (pMga->Chipset == PCI_CHIP_MGAG200_ER_PCI);
@@ -2049,6 +2074,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
case PCI_CHIP_MGAG200_WINBOND_PCI:
+ case PCI_CHIP_MGAG200_EW3_PCI:
case PCI_CHIP_MGAG200_EV_PCI:
case PCI_CHIP_MGAG200_EH_PCI:
case PCI_CHIP_MGAG200_ER_PCI:
@@ -2163,8 +2189,9 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
case PCI_CHIP_MGAG200_WINBOND_PCI:
+ case PCI_CHIP_MGAG200_EW3_PCI:
case PCI_CHIP_MGAG200_EV_PCI:
- case PCI_CHIP_MGAG200_EH_PCI:
+ case PCI_CHIP_MGAG200_EH_PCI:
case PCI_CHIP_MGAG200_ER_PCI:
pMga->SrcOrg = 0;
pMga->DstOrg = 0;
@@ -2347,6 +2374,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_MGAG200_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
case PCI_CHIP_MGAG200_WINBOND_PCI:
+ case PCI_CHIP_MGAG200_EW3_PCI:
case PCI_CHIP_MGAG200_EV_PCI:
case PCI_CHIP_MGAG200_EH_PCI:
case PCI_CHIP_MGAG200_ER_PCI:
@@ -3838,12 +3866,15 @@ MGAValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
} else if (pMga->is_G200WB){
if (mode->Flags & V_DBLSCAN)
return MODE_NO_DBLESCAN;
- if (pMga->KVM && mode->HDisplay > 1280)
- return MODE_VIRTUAL_X;
- if (pMga->KVM && mode->VDisplay > 1024)
- return MODE_VIRTUAL_Y;
- if (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 318.77)
- return MODE_BANDWIDTH;
+ if (pMga->Chipset != PCI_CHIP_MGAG200_EW3_PCI)
+ {
+ if (pMga->KVM && mode->HDisplay > 1280)
+ return MODE_VIRTUAL_X;
+ if (pMga->KVM && mode->VDisplay > 1024)
+ return MODE_VIRTUAL_Y;
+ if (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 318.77)
+ return MODE_BANDWIDTH;
+ }
} else if (pMga->is_G200EV
&& (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 327)) {
return MODE_BANDWIDTH;
diff --git a/src/mga_merge.c b/src/mga_merge.c
index 6d7b71e..a257306 100644
--- a/src/mga_merge.c
+++ b/src/mga_merge.c
@@ -353,9 +353,10 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags)
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
case PCI_CHIP_MGAG200_WINBOND_PCI:
+ case PCI_CHIP_MGAG200_EW3_PCI:
case PCI_CHIP_MGAG200_EV_PCI:
case PCI_CHIP_MGAG200_EH_PCI:
- case PCI_CHIP_MGAG200_ER_PCI:
+ case PCI_CHIP_MGAG200_ER_PCI:
case PCI_CHIP_MGAG400:
case PCI_CHIP_MGAG550:
MGAGSetupFuncs(pScrn);
@@ -505,6 +506,7 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags)
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
case PCI_CHIP_MGAG200_WINBOND_PCI:
+ case PCI_CHIP_MGAG200_EW3_PCI:
case PCI_CHIP_MGAG200_EV_PCI:
case PCI_CHIP_MGAG200_EH_PCI:
case PCI_CHIP_MGAG200_ER_PCI:
diff --git a/src/mga_storm.c b/src/mga_storm.c
index 84a4c8c..4ef655b 100644
--- a/src/mga_storm.c
+++ b/src/mga_storm.c
@@ -1148,6 +1148,7 @@ void MGAStormEngineInit( ScrnInfoPtr pScrn )
case PCI_CHIP_MGAG200_SE_A_PCI:
case PCI_CHIP_MGAG200_SE_B_PCI:
case PCI_CHIP_MGAG200_WINBOND_PCI:
+ case PCI_CHIP_MGAG200_EW3_PCI:
case PCI_CHIP_MGAG200_EV_PCI:
case PCI_CHIP_MGAG200_EH_PCI:
case PCI_CHIP_MGAG200_ER_PCI:
--
1.8.3.1
More information about the xorg-devel
mailing list