diff options
| author | Mathieu Larouche <mathieu.larouche@matrox.com> | 2015-08-21 09:24:05 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2015-08-23 23:46:52 -0400 |
| commit | 6d857c18aefdec782ba1db578a390fbac5145107 (patch) | |
| tree | b2ba2b7beeaa19c2773b6487c252ab50706927f3 /drivers/gpu/drm/mgag200 | |
| parent | 44790462d041d3037d60b3bf88f30837a72006ff (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.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_drv.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_i2c.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_main.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_mode.c | 100 |
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) { |
