aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathieu Larouche <mathieu.larouche@matrox.com>2015-08-21 09:24:13 -0400
committerDave Airlie <airlied@redhat.com>2015-08-23 23:47:16 -0400
commite829d7ef9f17d7b84d4c3d110ecd4b7b2bcba865 (patch)
tree1962b449d342bf0d29d05f35685694e32ed715bb
parent6d857c18aefdec782ba1db578a390fbac5145107 (diff)
drm/mgag200: Add support for a new rev of G200e
- Added PLL algorithm for a new rev of G200e - Removed the bandwidth limitation for the new G200e Signed-off-by: Mathieu Larouche <mathieu.larouche@matrox.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c112
1 files changed, 87 insertions, 25 deletions
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 8f7a3a16c92a..c99d3fe12881 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,
104 return true; 104 return true;
105} 105}
106 106
107#define P_ARRAY_SIZE 9
108
107static int mga_g200se_set_plls(struct mga_device *mdev, long clock) 109static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
108{ 110{
109 unsigned int vcomax, vcomin, pllreffreq; 111 unsigned int vcomax, vcomin, pllreffreq;
@@ -111,37 +113,97 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
111 unsigned int testp, testm, testn; 113 unsigned int testp, testm, testn;
112 unsigned int p, m, n; 114 unsigned int p, m, n;
113 unsigned int computed; 115 unsigned int computed;
116 unsigned int pvalues_e4[P_ARRAY_SIZE] = {16, 14, 12, 10, 8, 6, 4, 2, 1};
117 unsigned int fvv;
118 unsigned int i;
114 119
115 m = n = p = 0; 120 if (mdev->unique_rev_id <= 0x03) {
116 vcomax = 320000;
117 vcomin = 160000;
118 pllreffreq = 25000;
119 121
120 delta = 0xffffffff; 122 m = n = p = 0;
121 permitteddelta = clock * 5 / 1000; 123 vcomax = 320000;
124 vcomin = 160000;
125 pllreffreq = 25000;
122 126
123 for (testp = 8; testp > 0; testp /= 2) { 127 delta = 0xffffffff;
124 if (clock * testp > vcomax) 128 permitteddelta = clock * 5 / 1000;
125 continue;
126 if (clock * testp < vcomin)
127 continue;
128 129
129 for (testn = 17; testn < 256; testn++) { 130 for (testp = 8; testp > 0; testp /= 2) {
130 for (testm = 1; testm < 32; testm++) { 131 if (clock * testp > vcomax)
131 computed = (pllreffreq * testn) / 132 continue;
132 (testm * testp); 133 if (clock * testp < vcomin)
133 if (computed > clock) 134 continue;
134 tmpdelta = computed - clock; 135
135 else 136 for (testn = 17; testn < 256; testn++) {
136 tmpdelta = clock - computed; 137 for (testm = 1; testm < 32; testm++) {
137 if (tmpdelta < delta) { 138 computed = (pllreffreq * testn) /
138 delta = tmpdelta; 139 (testm * testp);
139 m = testm - 1; 140 if (computed > clock)
140 n = testn - 1; 141 tmpdelta = computed - clock;
141 p = testp - 1; 142 else
143 tmpdelta = clock - computed;
144 if (tmpdelta < delta) {
145 delta = tmpdelta;
146 m = testm - 1;
147 n = testn - 1;
148 p = testp - 1;
149 }
150 }
151 }
152 }
153 } else {
154
155
156 m = n = p = 0;
157 vcomax = 1600000;
158 vcomin = 800000;
159 pllreffreq = 25000;
160
161 if (clock < 25000)
162 clock = 25000;
163
164 clock = clock * 2;
165
166 delta = 0xFFFFFFFF;
167 /* Permited delta is 0.5% as VESA Specification */
168 permitteddelta = clock * 5 / 1000;
169
170 for (i = 0 ; i < P_ARRAY_SIZE ; i++) {
171 testp = pvalues_e4[i];
172
173 if ((clock * testp) > vcomax)
174 continue;
175 if ((clock * testp) < vcomin)
176 continue;
177
178 for (testn = 50; testn <= 256; testn++) {
179 for (testm = 1; testm <= 32; testm++) {
180 computed = (pllreffreq * testn) /
181 (testm * testp);
182 if (computed > clock)
183 tmpdelta = computed - clock;
184 else
185 tmpdelta = clock - computed;
186
187 if (tmpdelta < delta) {
188 delta = tmpdelta;
189 m = testm - 1;
190 n = testn - 1;
191 p = testp - 1;
192 }
142 } 193 }
143 } 194 }
144 } 195 }
196
197 fvv = pllreffreq * testn / testm;
198 fvv = (fvv - 800000) / 50000;
199
200 if (fvv > 15)
201 fvv = 15;
202
203 p |= (fvv << 4);
204 m |= 0x80;
205
206 clock = clock / 2;
145 } 207 }
146 208
147 if (delta > permitteddelta) { 209 if (delta > permitteddelta) {
@@ -1540,7 +1602,7 @@ static int mga_vga_mode_valid(struct drm_connector *connector,
1540 if (mga_vga_calculate_mode_bandwidth(mode, bpp) 1602 if (mga_vga_calculate_mode_bandwidth(mode, bpp)
1541 > (24400 * 1024)) 1603 > (24400 * 1024))
1542 return MODE_BANDWIDTH; 1604 return MODE_BANDWIDTH;
1543 } else if (mdev->unique_rev_id >= 0x02) { 1605 } else if (mdev->unique_rev_id == 0x02) {
1544 if (mode->hdisplay > 1920) 1606 if (mode->hdisplay > 1920)
1545 return MODE_VIRTUAL_X; 1607 return MODE_VIRTUAL_X;
1546 if (mode->vdisplay > 1200) 1608 if (mode->vdisplay > 1200)