[PATCH mga] xf86-video-mga: Add support for a new G200eH3 device

mathieu.larouche at matrox.com mathieu.larouche at matrox.com
Tue Feb 7 16:12:14 UTC 2017


From: Mathieu Larouche <mathieu.larouche at matrox.com>

- Added support for the new deviceID for G200eH3
- Added PLL algorithm for the G200eH3
- Removed the bandwidth limitation for the G200eH3

Signed-off-by: Mathieu Larouche <mathieu.larouche at matrox.com>
---
 src/mga.h        |  4 +++-
 src/mga_dacG.c   | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/mga_driver.c | 36 +++++++++++++++++++++++++++++++++---
 src/mga_merge.c  |  2 ++
 src/mga_storm.c  |  1 +
 5 files changed, 94 insertions(+), 5 deletions(-)

diff --git a/src/mga.h b/src/mga.h
index 04f6bfd..0df16e9 100644
--- a/src/mga.h
+++ b/src/mga.h
@@ -150,7 +150,9 @@ void MGAdbg_outreg32(ScrnInfoPtr, int,int, char*);
 #define PCI_CHIP_MGAG200_EW3_PCI 0x0536
 #endif
 
-
+#ifndef PCI_CHIP_MGAG200_EH3_PCI
+#define PCI_CHIP_MGAG200_EH3_PCI 0x0538
+#endif
 
 /*
  * Read/write to the DAC via MMIO 
diff --git a/src/mga_dacG.c b/src/mga_dacG.c
index 73d0d9d..7ff030e 100644
--- a/src/mga_dacG.c
+++ b/src/mga_dacG.c
@@ -393,6 +393,52 @@ MGAG200EHComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
     }
 }
 
+void
+MGAG200EH3ComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
+{
+    unsigned int ulComputedFo;
+    unsigned int ulFDelta;
+    unsigned int ulFPermitedDelta;
+    unsigned int ulFTmpDelta;
+    unsigned int ulTestP;
+    unsigned int ulTestM;
+    unsigned int ulTestN;
+    unsigned int ulVCOMax;
+    unsigned int ulVCOMin;
+    unsigned int ulPLLFreqRef;
+
+    ulVCOMax        = 3000000;
+    ulVCOMin        = 1500000;
+    ulPLLFreqRef    = 25000;
+
+    ulTestP         = 0;
+
+    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 (ulTestM = 150; ulTestM >= 6; ulTestM--) {
+        if ((lFo * ulTestM) > ulVCOMax) continue;
+        if ((lFo * ulTestM) < ulVCOMin) continue;
+
+        for (ulTestN = 120; ulTestN >= 60; ulTestN--) {
+            ulComputedFo = (ulPLLFreqRef * ulTestN) / ulTestM;
+            if (ulComputedFo > lFo)
+	        ulFTmpDelta = ulComputedFo - lFo;
+            else
+                ulFTmpDelta = lFo - ulComputedFo;
+
+            if (ulFTmpDelta < ulFDelta) {
+                ulFDelta = ulFTmpDelta;
+                *M = (CARD8)(ulTestM);
+                *N = (CARD8)(ulTestN);
+                *P = (CARD8)(ulTestP);
+            }
+        }
+    }
+}
+
 static void
 MGAG200EVPIXPLLSET(ScrnInfoPtr pScrn, MGARegPtr mgaReg)
 {
@@ -1056,7 +1102,14 @@ MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out )
 	    pReg->PllN = n;
 	    pReg->PllP = p;
     } else if (pMga->is_G200EH) {
-	    MGAG200EHComputePLLParam(pScrn, f_out, &m, &n, &p);
+            if (pMga->Chipset == PCI_CHIP_MGAG200_EH3_PCI)
+            {
+                 MGAG200EH3ComputePLLParam(pScrn, f_out, &m, &n, &p);
+            }
+            else
+            {
+                 MGAG200EHComputePLLParam(pScrn, f_out, &m, &n, &p);
+            }
 
 	    pReg->PllM = m;
 	    pReg->PllN = n;
@@ -1263,6 +1316,7 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
 			break;
 
         case PCI_CHIP_MGAG200_EH_PCI:
+        case PCI_CHIP_MGAG200_EH3_PCI:
                 pReg->DacRegs[MGA1064_MISC_CTL] =
                     MGA1064_MISC_CTL_VGA8 |
                     MGA1064_MISC_CTL_DAC_RAM_CS;
diff --git a/src/mga_driver.c b/src/mga_driver.c
index 7b46561..3b4d01e 100644
--- a/src/mga_driver.c
+++ b/src/mga_driver.c
@@ -424,6 +424,21 @@ static const struct mga_device_attributes attribs[] = {
 	},
 
 	16384, 0x4000,          /* Memory probe size & offset values */
+    },
+
+    [17] = { 0, 1, 0, 0, 1, 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 */
     }
 };
 
@@ -458,6 +473,8 @@ static const struct pci_id_match mga_device_match[] = {
 
     MGA_DEVICE_MATCH( PCI_CHIP_MGAG200_EW3_PCI, 16 ),
 
+    MGA_DEVICE_MATCH( PCI_CHIP_MGAG200_EH3_PCI, 17 ),
+
     { 0, 0, 0 },
 };
 #endif
@@ -479,6 +496,7 @@ static SymTabRec MGAChipsets[] = {
     { PCI_CHIP_MGAG200_WINBOND_PCI,	"mgag200 eW Nuvoton" },
     { PCI_CHIP_MGAG200_EW3_PCI,	"mgag200 eW3 Nuvoton" },
     { PCI_CHIP_MGAG200_EH_PCI,	"mgag200eH" },
+     { PCI_CHIP_MGAG200_EH3_PCI,	"mgag200eH3" },
     { PCI_CHIP_MGAG400,		"mgag400" },
     { PCI_CHIP_MGAG550,		"mgag550" },
     {-1,			NULL }
@@ -507,6 +525,8 @@ static PciChipsets MGAPciChipsets[] = {
 	RES_SHARED_VGA },
     { PCI_CHIP_MGAG200_EH_PCI, PCI_CHIP_MGAG200_EH_PCI,
 	RES_SHARED_VGA },
+    { PCI_CHIP_MGAG200_EH3_PCI, PCI_CHIP_MGAG200_EH3_PCI,
+	RES_SHARED_VGA },
     { PCI_CHIP_MGAG400,	    PCI_CHIP_MGAG400,	RES_SHARED_VGA },
     { PCI_CHIP_MGAG550,	    PCI_CHIP_MGAG550,	RES_SHARED_VGA },
     { -1,			-1,		RES_UNDEFINED }
@@ -693,6 +713,7 @@ MGAPciProbe(DriverPtr drv, int entity_num, struct pci_device * dev,
 	    case PCI_CHIP_MGAG200_ER_PCI:
 	    case PCI_CHIP_MGAG200_WINBOND_PCI:
 	    case PCI_CHIP_MGAG200_EH_PCI:
+       	    case PCI_CHIP_MGAG200_EH3_PCI:
 		xf86DrvMsg(0, X_ERROR,
 	                   "mga: The PCI device 0x%x at %2.2d@%2.2d:%2.2d:%1.1d has a kernel module claiming it.\n",
 	                   dev->device_id, dev->bus, dev->domain, dev->dev, dev->func);
@@ -948,6 +969,10 @@ MGAProbe(DriverPtr drv, int flags)
                 attrib_no = 16;
                 break;
 
+            case PCI_CHIP_MGAG200_EH3_PCI:
+                attrib_no = 17;
+                break;
+
 	    default:
 		return FALSE;
             }
@@ -1567,7 +1592,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
     pMga->is_G200EV = (pMga->Chipset == PCI_CHIP_MGAG200_EV_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_G200EH = (pMga->Chipset == PCI_CHIP_MGAG200_EH_PCI)
+        ||  (pMga->Chipset ==  PCI_CHIP_MGAG200_EH3_PCI);
     pMga->is_G200ER = (pMga->Chipset == PCI_CHIP_MGAG200_ER_PCI);
 
     pMga->DualHeadEnabled = FALSE;
@@ -1594,6 +1620,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
     case PCI_CHIP_MGAG200_ER_PCI:
     case PCI_CHIP_MGAG200_WINBOND_PCI:
     case PCI_CHIP_MGAG200_EH_PCI:
+    case PCI_CHIP_MGAG200_EH3_PCI:
 	pMga->HWCursor = FALSE;
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		   "HW cursor is not supported with video redirection on"
@@ -2078,6 +2105,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
     case PCI_CHIP_MGAG200_EV_PCI:
     case PCI_CHIP_MGAG200_EH_PCI:
     case PCI_CHIP_MGAG200_ER_PCI:	
+    case PCI_CHIP_MGAG200_EH3_PCI:
     case PCI_CHIP_MGAG400:
     case PCI_CHIP_MGAG550:
 	MGAGSetupFuncs(pScrn);
@@ -2192,6 +2220,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
 	  case PCI_CHIP_MGAG200_EW3_PCI:
 	  case PCI_CHIP_MGAG200_EV_PCI:
 	  case PCI_CHIP_MGAG200_EH_PCI:
+	  case PCI_CHIP_MGAG200_EH3_PCI:
 	  case PCI_CHIP_MGAG200_ER_PCI:	  
 	    pMga->SrcOrg = 0;
 	    pMga->DstOrg = 0;
@@ -2376,7 +2405,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
         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_EH3_PCI:
 	case PCI_CHIP_MGAG200_ER_PCI:	
 	case PCI_CHIP_MGAG400:
 	case PCI_CHIP_MGAG550:
@@ -3878,7 +3908,7 @@ MGAValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
     } else if (pMga->is_G200EV
 	       && (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 327)) {
 	return MODE_BANDWIDTH;
-    } else if (pMga->is_G200EH
+    } else if (pMga->is_G200EH && (pMga->Chipset != PCI_CHIP_MGAG200_EH3_PCI)
                && (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 375)) {
         return MODE_BANDWIDTH;
     } else if (pMga->is_G200ER
diff --git a/src/mga_merge.c b/src/mga_merge.c
index a257306..faa9277 100644
--- a/src/mga_merge.c
+++ b/src/mga_merge.c
@@ -357,6 +357,7 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags)
     case PCI_CHIP_MGAG200_EV_PCI:
     case PCI_CHIP_MGAG200_EH_PCI:
     case PCI_CHIP_MGAG200_ER_PCI:
+    case PCI_CHIP_MGAG200_EH3_PCI:
     case PCI_CHIP_MGAG400:
     case PCI_CHIP_MGAG550:
 	MGAGSetupFuncs(pScrn);
@@ -510,6 +511,7 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags)
         case PCI_CHIP_MGAG200_EV_PCI:
         case PCI_CHIP_MGAG200_EH_PCI:
 	case PCI_CHIP_MGAG200_ER_PCI:		
+	case PCI_CHIP_MGAG200_EH3_PCI:		
 	case PCI_CHIP_MGAG400:
 	case PCI_CHIP_MGAG550:
 	   maxPitch = 4096;
diff --git a/src/mga_storm.c b/src/mga_storm.c
index 4ef655b..c945971 100644
--- a/src/mga_storm.c
+++ b/src/mga_storm.c
@@ -1152,6 +1152,7 @@ void MGAStormEngineInit( ScrnInfoPtr pScrn )
     case PCI_CHIP_MGAG200_EV_PCI:
     case PCI_CHIP_MGAG200_EH_PCI:
     case PCI_CHIP_MGAG200_ER_PCI:	
+    case PCI_CHIP_MGAG200_EH3_PCI:
 	pMga->SrcOrg = 0;
 	OUTREG(MGAREG_SRCORG, pMga->realSrcOrg);
 	OUTREG(MGAREG_DSTORG, pMga->DstOrg);
-- 
1.8.3.1



More information about the xorg-devel mailing list