drm/mgag200: Added support for the new device G200eH3
authorMathieu Larouche <mathieu.larouche@matrox.com>
Fri, 21 Oct 2016 16:47:07 +0000 (12:47 -0400)
committerDave Airlie <airlied@redhat.com>
Mon, 23 Jan 2017 01:57:08 +0000 (11:57 +1000)
- Added the new device ID
- Added new pll algorithm

Signed-off-by: Mathieu Larouche <mathieu.larouche@matrox.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/mgag200/mgag200_drv.c
drivers/gpu/drm/mgag200/mgag200_drv.h
drivers/gpu/drm/mgag200/mgag200_i2c.c
drivers/gpu/drm/mgag200/mgag200_mode.c

index b0b8742..9ac0078 100644 (file)
@@ -36,6 +36,7 @@ static const struct pci_device_id pciidlist[] = {
        { PCI_VENDOR_ID_MATROX, 0x533, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EH },
        { PCI_VENDOR_ID_MATROX, 0x534, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_ER },
        { PCI_VENDOR_ID_MATROX, 0x536, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EW3 },
+       { PCI_VENDOR_ID_MATROX, 0x538, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EH3 },
        {0,}
 };
 
index 0d6e998..c88b6ec 100644 (file)
@@ -180,6 +180,7 @@ enum mga_type {
        G200_WB,
        G200_EV,
        G200_EH,
+       G200_EH3,
        G200_ER,
        G200_EW3,
 };
index 10535e3..77d1c47 100644 (file)
@@ -106,6 +106,7 @@ struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev)
                clock = 2;
                break;
        case G200_EH:
+       case G200_EH3:
        case G200_ER:
                data = 2;
                clock = 1;
index 067dfbc..3938120 100644 (file)
@@ -497,34 +497,70 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
        bool pll_locked = false;
 
        m = n = p = 0;
-       vcomax = 800000;
-       vcomin = 400000;
-       pllreffreq = 33333;
 
-       delta = 0xffffffff;
+       if (mdev->type == G200_EH3) {
+               vcomax = 3000000;
+               vcomin = 1500000;
+               pllreffreq = 25000;
 
-       for (testp = 16; testp > 0; testp >>= 1) {
-               if (clock * testp > vcomax)
-                       continue;
-               if (clock * testp < vcomin)
-                       continue;
+               delta = 0xffffffff;
 
-               for (testm = 1; testm < 33; testm++) {
-                       for (testn = 17; testn < 257; testn++) {
-                               computed = (pllreffreq * testn) /
-                                       (testm * testp);
+               testp = 0;
+
+               for (testm = 150; testm >= 6; testm--) {
+                       if (clock * testm > vcomax)
+                               continue;
+                       if (clock * testm < vcomin)
+                               continue;
+                       for (testn = 120; testn >= 60; testn--) {
+                               computed = (pllreffreq * testn) / testm;
                                if (computed > clock)
                                        tmpdelta = computed - clock;
                                else
                                        tmpdelta = clock - computed;
                                if (tmpdelta < delta) {
                                        delta = tmpdelta;
-                                       n = testn - 1;
-                                       m = (testm - 1);
-                                       p = testp - 1;
+                                       n = testn;
+                                       m = testm;
+                                       p = testp;
+                               }
+                               if (delta == 0)
+                                       break;
+                       }
+                       if (delta == 0)
+                               break;
+               }
+       } else {
+
+               vcomax = 800000;
+               vcomin = 400000;
+               pllreffreq = 33333;
+
+               delta = 0xffffffff;
+
+               for (testp = 16; testp > 0; testp >>= 1) {
+                       if (clock * testp > vcomax)
+                               continue;
+                       if (clock * testp < vcomin)
+                               continue;
+
+                       for (testm = 1; testm < 33; testm++) {
+                               for (testn = 17; testn < 257; testn++) {
+                                       computed = (pllreffreq * testn) /
+                                               (testm * testp);
+                                       if (computed > clock)
+                                               tmpdelta = computed - clock;
+                                       else
+                                               tmpdelta = clock - computed;
+                                       if (tmpdelta < delta) {
+                                               delta = tmpdelta;
+                                               n = testn - 1;
+                                               m = (testm - 1);
+                                               p = testp - 1;
+                                       }
+                                       if ((clock * testp) >= 600000)
+                                               p |= 0x80;
                                }
-                               if ((clock * testp) >= 600000)
-                                       p |= 0x80;
                        }
                }
        }
@@ -674,6 +710,7 @@ static int mga_crtc_set_plls(struct mga_device *mdev, long clock)
                return mga_g200ev_set_plls(mdev, clock);
                break;
        case G200_EH:
+       case G200_EH3:
                return mga_g200eh_set_plls(mdev, clock);
                break;
        case G200_ER:
@@ -933,6 +970,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
                option2 = 0x0000b000;
                break;
        case G200_EH:
+       case G200_EH3:
                dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 |
                                             MGA1064_MISC_CTL_DAC_RAM_CS;
                option = 0x00000120;
@@ -979,7 +1017,8 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
                if ((mdev->type == G200_EV ||
                    mdev->type == G200_WB ||
                    mdev->type == G200_EH ||
-                   mdev->type == G200_EW3) &&
+                   mdev->type == G200_EW3 ||
+                   mdev->type == G200_EH3) &&
                    (i >= 0x44) && (i <= 0x4e))
                        continue;