[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