aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/mgag200
diff options
context:
space:
mode:
authorMathieu Larouche <mathieu.larouche@matrox.com>2015-08-21 09:24:05 -0400
committerDave Airlie <airlied@redhat.com>2015-08-23 23:46:52 -0400
commit6d857c18aefdec782ba1db578a390fbac5145107 (patch)
treeb2ba2b7beeaa19c2773b6487c252ab50706927f3 /drivers/gpu/drm/mgag200
parent44790462d041d3037d60b3bf88f30837a72006ff (diff)
drm/mgag200: Add support for a new G200eW3 chipset
- 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 <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_main.c9
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c100
5 files changed, 85 insertions, 27 deletions
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 97745991544d..b0af77454d52 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[] = {
35 { PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB }, 35 { PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB },
36 { PCI_VENDOR_ID_MATROX, 0x533, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EH }, 36 { PCI_VENDOR_ID_MATROX, 0x533, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EH },
37 { PCI_VENDOR_ID_MATROX, 0x534, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_ER }, 37 { PCI_VENDOR_ID_MATROX, 0x534, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_ER },
38 { PCI_VENDOR_ID_MATROX, 0x536, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EW3 },
38 {0,} 39 {0,}
39}; 40};
40 41
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index e9eea1d4e7c3..912151c36d59 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -180,6 +180,7 @@ enum mga_type {
180 G200_EV, 180 G200_EV,
181 G200_EH, 181 G200_EH,
182 G200_ER, 182 G200_ER,
183 G200_EW3,
183}; 184};
184 185
185#define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B) 186#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 d3dcf54e6233..10535e3b75f2 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)
101 case G200_SE_B: 101 case G200_SE_B:
102 case G200_EV: 102 case G200_EV:
103 case G200_WB: 103 case G200_WB:
104 case G200_EW3:
104 data = 1; 105 data = 1;
105 clock = 2; 106 clock = 2;
106 break; 107 break;
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
index c99c2cb28939..de06388069e7 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)
82 int orig; 82 int orig;
83 int test1, test2; 83 int test1, test2;
84 int orig1, orig2; 84 int orig1, orig2;
85 unsigned int vram_size;
85 86
86 /* Probe */ 87 /* Probe */
87 orig = ioread16(mem); 88 orig = ioread16(mem);
88 iowrite16(0, mem); 89 iowrite16(0, mem);
89 90
90 for (offset = 0x100000; offset < mdev->mc.vram_window; offset += 0x4000) { 91 vram_size = mdev->mc.vram_window;
92
93 if ((mdev->type == G200_EW3) && (vram_size >= 0x1000000)) {
94 vram_size = vram_size - 0x400000;
95 }
96
97 for (offset = 0x100000; offset < vram_size; offset += 0x4000) {
91 orig1 = ioread8(mem + offset); 98 orig1 = ioread8(mem + offset);
92 orig2 = ioread8(mem + offset + 0x100); 99 orig2 = ioread8(mem + offset + 0x100);
93 100
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index cd75cff096e1..8f7a3a16c92a 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)
159{ 159{
160 unsigned int vcomax, vcomin, pllreffreq; 160 unsigned int vcomax, vcomin, pllreffreq;
161 unsigned int delta, tmpdelta; 161 unsigned int delta, tmpdelta;
162 unsigned int testp, testm, testn; 162 unsigned int testp, testm, testn, testp2;
163 unsigned int p, m, n; 163 unsigned int p, m, n;
164 unsigned int computed; 164 unsigned int computed;
165 int i, j, tmpcount, vcount; 165 int i, j, tmpcount, vcount;
@@ -167,31 +167,71 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
167 u8 tmp; 167 u8 tmp;
168 168
169 m = n = p = 0; 169 m = n = p = 0;
170 vcomax = 550000;
171 vcomin = 150000;
172 pllreffreq = 48000;
173 170
174 delta = 0xffffffff; 171 delta = 0xffffffff;
175 172
176 for (testp = 1; testp < 9; testp++) { 173 if (mdev->type == G200_EW3) {
177 if (clock * testp > vcomax) 174
178 continue; 175 vcomax = 800000;
179 if (clock * testp < vcomin) 176 vcomin = 400000;
180 continue; 177 pllreffreq = 25000;
178
179 for (testp = 1; testp < 8; testp++) {
180 for (testp2 = 1; testp2 < 8; testp2++) {
181 if (testp < testp2)
182 continue;
183 if ((clock * testp * testp2) > vcomax)
184 continue;
185 if ((clock * testp * testp2) < vcomin)
186 continue;
187 for (testm = 1; testm < 26; testm++) {
188 for (testn = 32; testn < 2048 ; testn++) {
189 computed = (pllreffreq * testn) /
190 (testm * testp * testp2);
191 if (computed > clock)
192 tmpdelta = computed - clock;
193 else
194 tmpdelta = clock - computed;
195 if (tmpdelta < delta) {
196 delta = tmpdelta;
197 m = ((testn & 0x100) >> 1) |
198 (testm);
199 n = (testn & 0xFF);
200 p = ((testn & 0x600) >> 3) |
201 (testp2 << 3) |
202 (testp);
203 }
204 }
205 }
206 }
207 }
208 } else {
181 209
182 for (testm = 1; testm < 17; testm++) { 210 vcomax = 550000;
183 for (testn = 1; testn < 151; testn++) { 211 vcomin = 150000;
184 computed = (pllreffreq * testn) / 212 pllreffreq = 48000;
185 (testm * testp); 213
186 if (computed > clock) 214 for (testp = 1; testp < 9; testp++) {
187 tmpdelta = computed - clock; 215 if (clock * testp > vcomax)
188 else 216 continue;
189 tmpdelta = clock - computed; 217 if (clock * testp < vcomin)
190 if (tmpdelta < delta) { 218 continue;
191 delta = tmpdelta; 219
192 n = testn - 1; 220 for (testm = 1; testm < 17; testm++) {
193 m = (testm - 1) | ((n >> 1) & 0x80); 221 for (testn = 1; testn < 151; testn++) {
194 p = testp - 1; 222 computed = (pllreffreq * testn) /
223 (testm * testp);
224 if (computed > clock)
225 tmpdelta = computed - clock;
226 else
227 tmpdelta = clock - computed;
228 if (tmpdelta < delta) {
229 delta = tmpdelta;
230 n = testn - 1;
231 m = (testm - 1) |
232 ((n >> 1) & 0x80);
233 p = testp - 1;
234 }
195 } 235 }
196 } 236 }
197 } 237 }
@@ -569,6 +609,7 @@ static int mga_crtc_set_plls(struct mga_device *mdev, long clock)
569 return mga_g200se_set_plls(mdev, clock); 609 return mga_g200se_set_plls(mdev, clock);
570 break; 610 break;
571 case G200_WB: 611 case G200_WB:
612 case G200_EW3:
572 return mga_g200wb_set_plls(mdev, clock); 613 return mga_g200wb_set_plls(mdev, clock);
573 break; 614 break;
574 case G200_EV: 615 case G200_EV:
@@ -820,6 +861,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
820 option2 = 0x00008000; 861 option2 = 0x00008000;
821 break; 862 break;
822 case G200_WB: 863 case G200_WB:
864 case G200_EW3:
823 dacvalue[MGA1064_VREF_CTL] = 0x07; 865 dacvalue[MGA1064_VREF_CTL] = 0x07;
824 option = 0x41049120; 866 option = 0x41049120;
825 option2 = 0x0000b000; 867 option2 = 0x0000b000;
@@ -875,7 +917,10 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
875 if (IS_G200_SE(mdev) && 917 if (IS_G200_SE(mdev) &&
876 ((i == 0x2c) || (i == 0x2d) || (i == 0x2e))) 918 ((i == 0x2c) || (i == 0x2d) || (i == 0x2e)))
877 continue; 919 continue;
878 if ((mdev->type == G200_EV || mdev->type == G200_WB || mdev->type == G200_EH) && 920 if ((mdev->type == G200_EV ||
921 mdev->type == G200_WB ||
922 mdev->type == G200_EH ||
923 mdev->type == G200_EW3) &&
879 (i >= 0x44) && (i <= 0x4e)) 924 (i >= 0x44) && (i <= 0x4e))
880 continue; 925 continue;
881 926
@@ -977,7 +1022,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
977 else 1022 else
978 ext_vga[3] = ((1 << bppshift) - 1) | 0x80; 1023 ext_vga[3] = ((1 << bppshift) - 1) | 0x80;
979 ext_vga[4] = 0; 1024 ext_vga[4] = 0;
980 if (mdev->type == G200_WB) 1025 if (mdev->type == G200_WB || mdev->type == G200_EW3)
981 ext_vga[1] |= 0x88; 1026 ext_vga[1] |= 0x88;
982 1027
983 /* Set pixel clocks */ 1028 /* Set pixel clocks */
@@ -993,6 +1038,9 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
993 if (mdev->type == G200_ER) 1038 if (mdev->type == G200_ER)
994 WREG_ECRT(0x24, 0x5); 1039 WREG_ECRT(0x24, 0x5);
995 1040
1041 if (mdev->type == G200_EW3)
1042 WREG_ECRT(0x34, 0x5);
1043
996 if (mdev->type == G200_EV) { 1044 if (mdev->type == G200_EV) {
997 WREG_ECRT(6, 0); 1045 WREG_ECRT(6, 0);
998 } 1046 }
@@ -1205,7 +1253,7 @@ static void mga_crtc_prepare(struct drm_crtc *crtc)
1205 WREG_SEQ(1, tmp | 0x20); 1253 WREG_SEQ(1, tmp | 0x20);
1206 } 1254 }
1207 1255
1208 if (mdev->type == G200_WB) 1256 if (mdev->type == G200_WB || mdev->type == G200_EW3)
1209 mga_g200wb_prepare(crtc); 1257 mga_g200wb_prepare(crtc);
1210 1258
1211 WREG_CRT(17, 0); 1259 WREG_CRT(17, 0);
@@ -1222,7 +1270,7 @@ static void mga_crtc_commit(struct drm_crtc *crtc)
1222 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 1270 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1223 u8 tmp; 1271 u8 tmp;
1224 1272
1225 if (mdev->type == G200_WB) 1273 if (mdev->type == G200_WB || mdev->type == G200_EW3)
1226 mga_g200wb_commit(crtc); 1274 mga_g200wb_commit(crtc);
1227 1275
1228 if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) { 1276 if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) {