[PATCH 1/1] drm/mgag200: Added support for the new device G200eH3

2016-10-21 Thread mathieu.larou...@matrox.com
From: Mathieu Larouche 

- Added the new device ID
- Added new pll algorithm

Signed-off-by: Mathieu Larouche 
---
 drivers/gpu/drm/mgag200/mgag200_drv.c  |  1 +
 drivers/gpu/drm/mgag200/mgag200_drv.h  |  1 +
 drivers/gpu/drm/mgag200/mgag200_i2c.c  |  1 +
 drivers/gpu/drm/mgag200/mgag200_mode.c | 77 +-
 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 2b4b125..dc60e1b 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 3e02ac2..128cf9d 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -179,6 +179,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 10535e3..77d1c47 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 6b21cb2..5fd4467 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 = 80;
-   vcomin = 40;
-   pllreffreq = 3;

-   delta = 0x;
+   if (mdev->type == G200_EH3) {
+   vcomax = 300;
+   vcomin = 150;
+   pllreffreq = 25000;

-   for (testp = 16; testp > 0; testp >>= 1) {
-   if (clock * testp > vcomax)
-   continue;
-   if (clock * testp < vcomin)
-   continue;
+   delta = 0x;

-   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 = 80;
+   vcomin = 40;
+   pllreffreq = 3;
+
+   delta = 0x;
+
+   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)

[PATCH 1/1] drm/mgag200: Black screen fix for G200e rev 4

2016-05-27 Thread mathieu.larou...@matrox.com
From: Mathieu Larouche 

- Fixed black screen for some resolutions of G200e rev4
- Fixed testm & testn which had predetermined value.

Reported-by: Jan Beulich 

Signed-off-by: Mathieu Larouche 
---
 drivers/gpu/drm/mgag200/mgag200_mode.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c 
b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 14e64e0..9baee8b 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -182,7 +182,7 @@ static int mga_g200se_set_plls(struct mga_device *mdev, 
long clock)
}
}

-   fvv = pllreffreq * testn / testm;
+   fvv = pllreffreq * (n + 1) / (m + 1);
fvv = (fvv - 80) / 5;

if (fvv > 15)
@@ -202,6 +202,14 @@ static int mga_g200se_set_plls(struct mga_device *mdev, 
long clock)
WREG_DAC(MGA1064_PIX_PLLC_M, m);
WREG_DAC(MGA1064_PIX_PLLC_N, n);
WREG_DAC(MGA1064_PIX_PLLC_P, p);
+
+   if (mdev->unique_rev_id >= 0x04) {
+   WREG_DAC(0x1a, 0x09);
+   msleep(20);
+   WREG_DAC(0x1a, 0x01);
+
+   }
+
return 0;
 }

-- 
1.8.3.1



[PATCH 0/2] Add support for two new chipset in mgag200 drv

2015-08-21 Thread mathieu.larou...@matrox.com
From: Mathieu Larouche 

Added the deviceId, PLL algorithm and initialization code for two new
chipset in the G200 Server family.

Mathieu Larouche (2):
  drm/mgag200: Add support for a new G200eW3 chipset
  drm/mgag200: Add support for a new rev of G200e

 drivers/gpu/drm/mgag200/mgag200_drv.c  |   1 +
 drivers/gpu/drm/mgag200/mgag200_drv.h  |   1 +
 drivers/gpu/drm/mgag200/mgag200_i2c.c  |   1 +
 drivers/gpu/drm/mgag200/mgag200_main.c |  15 ++-
 drivers/gpu/drm/mgag200/mgag200_mode.c | 235 -
 5 files changed, 185 insertions(+), 68 deletions(-)

-- 
1.8.3.1



[PATCH 1/2] drm/mgag200: Add support for a new G200eW3 chipset

2015-08-21 Thread mathieu.larou...@matrox.com
From: Mathieu Larouche 

- Added support for the new deviceID for G200eW3
- Added PLL algorithm for the G200eW3
- Added some initialization code for G200eW3

Signed-off-by: Mathieu Larouche 
---
 drivers/gpu/drm/mgag200/mgag200_drv.c  |   1 +
 drivers/gpu/drm/mgag200/mgag200_drv.h  |   1 +
 drivers/gpu/drm/mgag200/mgag200_i2c.c  |   1 +
 drivers/gpu/drm/mgag200/mgag200_main.c |  15 +++--
 drivers/gpu/drm/mgag200/mgag200_mode.c | 108 +++--
 5 files changed, 91 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c 
b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 9774599..b0af774 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -35,6 +35,7 @@ static const struct pci_device_id pciidlist[] = {
{ PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB },
{ 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 },
{0,}
 };

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h 
b/drivers/gpu/drm/mgag200/mgag200_drv.h
index e9eea1d..912151c 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_EV,
G200_EH,
G200_ER,
+   G200_EW3,
 };

 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c 
b/drivers/gpu/drm/mgag200/mgag200_i2c.c
index d3dcf54..10535e3 100644
--- a/drivers/gpu/drm/mgag200/mgag200_i2c.c
+++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c
@@ -101,6 +101,7 @@ struct mga_i2c_chan *mgag200_i2c_create(struct drm_device 
*dev)
case G200_SE_B:
case G200_EV:
case G200_WB:
+   case G200_EW3:
data = 1;
clock = 2;
break;
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c 
b/drivers/gpu/drm/mgag200/mgag200_main.c
index f6b283b..4281cc8 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -82,12 +82,19 @@ static int mga_probe_vram(struct mga_device *mdev, void 
__iomem *mem)
int orig;
int test1, test2;
int orig1, orig2;
+   unsigned int vram_size;

-   /* Probe */
-   orig = ioread16(mem);
-   iowrite16(0, mem);
+   /* Probe */
+   orig = ioread16(mem);
+   iowrite16(0, mem);

-   for (offset = 0x10; offset < mdev->mc.vram_window; offset += 
0x4000) {
+   vram_size = mdev->mc.vram_window;
+
+   if ((mdev->type == G200_EW3) && (vram_size >= 0x100)) {
+   vram_size = vram_size - 0x40;
+   }
+
+   for (offset = 0x10; offset < vram_size; offset += 0x4000) {
orig1 = ioread8(mem + offset);
orig2 = ioread8(mem + offset + 0x100);

diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c 
b/drivers/gpu/drm/mgag200/mgag200_mode.c
index ad4b901..9abc06f 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -159,7 +159,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, 
long clock)
 {
unsigned int vcomax, vcomin, pllreffreq;
unsigned int delta, tmpdelta, permitteddelta;
-   unsigned int testp, testm, testn;
+   unsigned int testp, testm, testn, testp2;
unsigned int p, m, n;
unsigned int computed;
int i, j, tmpcount, vcount;
@@ -167,36 +167,76 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, 
long clock)
u8 tmp;

m = n = p = 0;
-   vcomax = 55;
-   vcomin = 15;
-   pllreffreq = 48000;

delta = 0x;
permitteddelta = clock * 5 / 1000;

-   for (testp = 1; testp < 9; testp++) {
-   if (clock * testp > vcomax)
-   continue;
-   if (clock * testp < vcomin)
-   continue;
-
-   for (testm = 1; testm < 17; testm++) {
-   for (testn = 1; testn < 151; 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) | ((n >> 1) & 0x80);
-   p = testp - 1;
-   }
-   }
-   }
-   }
+   if (mdev->type == G200_EW3) {
+
+   v

[PATCH 2/2] drm/mgag200: Add support for a new rev of G200e

2015-08-21 Thread mathieu.larou...@matrox.com
From: Mathieu Larouche 

- Added PLL algorithm for a new rev of G200e
- Removed the bandwidth limitation for the new G200e

Signed-off-by: Mathieu Larouche 
---
 drivers/gpu/drm/mgag200/mgag200_mode.c | 119 +
 1 file changed, 90 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c 
b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 9abc06f..870ea35 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -104,6 +104,8 @@ static bool mga_crtc_mode_fixup(struct drm_crtc *crtc,
return true;
 }

+#define P_ARRAY_SIZE 9
+
 static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
 {
unsigned int vcomax, vcomin, pllreffreq;
@@ -111,38 +113,98 @@ static int mga_g200se_set_plls(struct mga_device *mdev, 
long clock)
unsigned int testp, testm, testn;
unsigned int p, m, n;
unsigned int computed;
+   unsigned int pvalues_e4[P_ARRAY_SIZE] = {16, 14, 12, 10, 8, 6, 4, 2, 1};
+   unsigned int fvv;
+   unsigned int i;
+
+   if (mdev->unique_rev_id <= 0x03) {
+
+   m = n = p = 0;
+   vcomax = 32;
+   vcomin = 16;
+   pllreffreq = 25000;
+
+   delta = 0x;
+   permitteddelta = clock * 5 / 1000;
+
+   for (testp = 8; testp > 0; testp /= 2) {
+   if (clock * testp > vcomax)
+   continue;
+   if (clock * testp < vcomin)
+   continue;
+
+   for (testn = 17; testn < 256; testn++) {
+   for (testm = 1; testm < 32; testm++) {
+   computed = (pllreffreq * testn) /
+   (testm * testp);
+   if (computed > clock)
+   tmpdelta = computed - clock;
+   else
+   tmpdelta = clock - computed;
+   if (tmpdelta < delta) {
+   delta = tmpdelta;
+   m = testm - 1;
+   n = testn - 1;
+   p = testp - 1;
+   }
+   }
+   }
+   }
+   } else {
+

-   m = n = p = 0;
-   vcomax = 32;
-   vcomin = 16;
-   pllreffreq = 25000;
+   m = n = p = 0;
+   vcomax= 160;
+   vcomin= 80;
+   pllreffreq= 25000;
+
+   if (clock < 25000)
+   clock = 25000;
+
+   clock = clock * 2;
+
+   delta = 0x;
+   /* Permited delta is 0.5% as VESA Specification */
+   permitteddelta = clock * 5 / 1000;
+
+   for (i = 0 ; i < P_ARRAY_SIZE ; i++) {
+   testp = pvalues_e4[i];
+
+   if ((clock * testp) > vcomax)
+   continue;
+   if ((clock * testp) < vcomin)
+   continue;
+
+   for (testn = 50; testn <= 256; testn++) {
+   for (testm = 1; testm <= 32; testm++) {
+   computed = (pllreffreq * testn) /
+   (testm * testp);
+   if (computed > clock)
+   tmpdelta = computed - clock;
+   else
+   tmpdelta = clock - computed;
+
+   if (tmpdelta < delta) {
+   delta = tmpdelta;
+   m = testm - 1;
+   n = testn - 1;
+   p = testp - 1;
+   }
+   }
+   }
+   }

-   delta = 0x;
-   permitteddelta = clock * 5 / 1000;
+   fvv = pllreffreq * testn / testm;
+   fvv = (fvv - 80) / 5;

-   for (testp = 8; testp > 0; testp /= 2) {
-   if (clock * testp > vcomax)
-   continue;
-   if (clock * testp < vcomin)
-   continue;
+   if (fvv > 15)
+   fvv = 15;

-   for (testn = 17; testn < 256; testn++) {
-   for (testm = 1; testm < 32; testm++) {
-   computed = (pllr