summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/mgag200
diff options
context:
space:
mode:
authorMathieu Larouche <mathieu.larouche@matrox.com>2016-10-21 12:47:07 -0400
committerDave Airlie <airlied@redhat.com>2017-01-23 11:57:08 +1000
commitf0493e653f9679114d1dfd54ab88b54ce95576e1 (patch)
tree9e62b605733cd83add1d3dbf3c691494d87ac06b /drivers/gpu/drm/mgag200
parent618a6109ecb7fccba155f59675ee7092b2e338a2 (diff)
downloadlinux-stable-f0493e653f9679114d1dfd54ab88b54ce95576e1.tar.gz
linux-stable-f0493e653f9679114d1dfd54ab88b54ce95576e1.tar.bz2
linux-stable-f0493e653f9679114d1dfd54ab88b54ce95576e1.zip
drm/mgag200: Added support for the new device G200eH3
- 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>
Diffstat (limited to 'drivers/gpu/drm/mgag200')
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.c1
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.h1
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_i2c.c1
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c77
4 files changed, 61 insertions, 19 deletions
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index b0b874264f9d..9ac007880328 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -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,}
};
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 0d6e998d63e6..c88b6ec88dd2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -180,6 +180,7 @@ enum mga_type {
G200_WB,
G200_EV,
G200_EH,
+ G200_EH3,
G200_ER,
G200_EW3,
};
diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c
index 10535e3b75f2..77d1c4771786 100644
--- a/drivers/gpu/drm/mgag200/mgag200_i2c.c
+++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c
@@ -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;
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 067dfbc91b1c..3938120e5051 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -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;