diff options
author | Ma Ling <ling.ma@intel.com> | 2009-03-18 08:13:23 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-03-27 17:45:11 -0400 |
commit | 044c7c415a68077b7c444c753aa03a35149e881a (patch) | |
tree | c8da161ad9f396773d05028b9e63e0faa62d701b /drivers | |
parent | 568d9a8f6d4bf81e0672c74573dc02981d31e3ea (diff) |
drm/i915: Use documented PLL timing limits for G4X platform
The values come from the internal reference spreadsheet on PLL
timing limits for the G4X chipsets.
Part of fixing fd.o bug #17508
Signed-off-by: Ma Ling <ling.ma@intel.com>
[anholt: Cleaned up some whitespace]
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 187 |
1 files changed, 186 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a2834276cb38..89f7af0bdb12 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -115,6 +115,89 @@ typedef struct { | |||
115 | #define INTEL_LIMIT_I8XX_LVDS 1 | 115 | #define INTEL_LIMIT_I8XX_LVDS 1 |
116 | #define INTEL_LIMIT_I9XX_SDVO_DAC 2 | 116 | #define INTEL_LIMIT_I9XX_SDVO_DAC 2 |
117 | #define INTEL_LIMIT_I9XX_LVDS 3 | 117 | #define INTEL_LIMIT_I9XX_LVDS 3 |
118 | #define INTEL_LIMIT_G4X_SDVO 4 | ||
119 | #define INTEL_LIMIT_G4X_HDMI_DAC 5 | ||
120 | #define INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS 6 | ||
121 | #define INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS 7 | ||
122 | |||
123 | /*The parameter is for SDVO on G4x platform*/ | ||
124 | #define G4X_DOT_SDVO_MIN 25000 | ||
125 | #define G4X_DOT_SDVO_MAX 270000 | ||
126 | #define G4X_VCO_MIN 1750000 | ||
127 | #define G4X_VCO_MAX 3500000 | ||
128 | #define G4X_N_SDVO_MIN 1 | ||
129 | #define G4X_N_SDVO_MAX 4 | ||
130 | #define G4X_M_SDVO_MIN 104 | ||
131 | #define G4X_M_SDVO_MAX 138 | ||
132 | #define G4X_M1_SDVO_MIN 17 | ||
133 | #define G4X_M1_SDVO_MAX 23 | ||
134 | #define G4X_M2_SDVO_MIN 5 | ||
135 | #define G4X_M2_SDVO_MAX 11 | ||
136 | #define G4X_P_SDVO_MIN 10 | ||
137 | #define G4X_P_SDVO_MAX 30 | ||
138 | #define G4X_P1_SDVO_MIN 1 | ||
139 | #define G4X_P1_SDVO_MAX 3 | ||
140 | #define G4X_P2_SDVO_SLOW 10 | ||
141 | #define G4X_P2_SDVO_FAST 10 | ||
142 | #define G4X_P2_SDVO_LIMIT 270000 | ||
143 | |||
144 | /*The parameter is for HDMI_DAC on G4x platform*/ | ||
145 | #define G4X_DOT_HDMI_DAC_MIN 22000 | ||
146 | #define G4X_DOT_HDMI_DAC_MAX 400000 | ||
147 | #define G4X_N_HDMI_DAC_MIN 1 | ||
148 | #define G4X_N_HDMI_DAC_MAX 4 | ||
149 | #define G4X_M_HDMI_DAC_MIN 104 | ||
150 | #define G4X_M_HDMI_DAC_MAX 138 | ||
151 | #define G4X_M1_HDMI_DAC_MIN 16 | ||
152 | #define G4X_M1_HDMI_DAC_MAX 23 | ||
153 | #define G4X_M2_HDMI_DAC_MIN 5 | ||
154 | #define G4X_M2_HDMI_DAC_MAX 11 | ||
155 | #define G4X_P_HDMI_DAC_MIN 5 | ||
156 | #define G4X_P_HDMI_DAC_MAX 80 | ||
157 | #define G4X_P1_HDMI_DAC_MIN 1 | ||
158 | #define G4X_P1_HDMI_DAC_MAX 8 | ||
159 | #define G4X_P2_HDMI_DAC_SLOW 10 | ||
160 | #define G4X_P2_HDMI_DAC_FAST 5 | ||
161 | #define G4X_P2_HDMI_DAC_LIMIT 165000 | ||
162 | |||
163 | /*The parameter is for SINGLE_CHANNEL_LVDS on G4x platform*/ | ||
164 | #define G4X_DOT_SINGLE_CHANNEL_LVDS_MIN 20000 | ||
165 | #define G4X_DOT_SINGLE_CHANNEL_LVDS_MAX 115000 | ||
166 | #define G4X_N_SINGLE_CHANNEL_LVDS_MIN 1 | ||
167 | #define G4X_N_SINGLE_CHANNEL_LVDS_MAX 3 | ||
168 | #define G4X_M_SINGLE_CHANNEL_LVDS_MIN 104 | ||
169 | #define G4X_M_SINGLE_CHANNEL_LVDS_MAX 138 | ||
170 | #define G4X_M1_SINGLE_CHANNEL_LVDS_MIN 17 | ||
171 | #define G4X_M1_SINGLE_CHANNEL_LVDS_MAX 23 | ||
172 | #define G4X_M2_SINGLE_CHANNEL_LVDS_MIN 5 | ||
173 | #define G4X_M2_SINGLE_CHANNEL_LVDS_MAX 11 | ||
174 | #define G4X_P_SINGLE_CHANNEL_LVDS_MIN 28 | ||
175 | #define G4X_P_SINGLE_CHANNEL_LVDS_MAX 112 | ||
176 | #define G4X_P1_SINGLE_CHANNEL_LVDS_MIN 2 | ||
177 | #define G4X_P1_SINGLE_CHANNEL_LVDS_MAX 8 | ||
178 | #define G4X_P2_SINGLE_CHANNEL_LVDS_SLOW 14 | ||
179 | #define G4X_P2_SINGLE_CHANNEL_LVDS_FAST 14 | ||
180 | #define G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT 0 | ||
181 | |||
182 | /*The parameter is for DUAL_CHANNEL_LVDS on G4x platform*/ | ||
183 | #define G4X_DOT_DUAL_CHANNEL_LVDS_MIN 80000 | ||
184 | #define G4X_DOT_DUAL_CHANNEL_LVDS_MAX 224000 | ||
185 | #define G4X_N_DUAL_CHANNEL_LVDS_MIN 1 | ||
186 | #define G4X_N_DUAL_CHANNEL_LVDS_MAX 3 | ||
187 | #define G4X_M_DUAL_CHANNEL_LVDS_MIN 104 | ||
188 | #define G4X_M_DUAL_CHANNEL_LVDS_MAX 138 | ||
189 | #define G4X_M1_DUAL_CHANNEL_LVDS_MIN 17 | ||
190 | #define G4X_M1_DUAL_CHANNEL_LVDS_MAX 23 | ||
191 | #define G4X_M2_DUAL_CHANNEL_LVDS_MIN 5 | ||
192 | #define G4X_M2_DUAL_CHANNEL_LVDS_MAX 11 | ||
193 | #define G4X_P_DUAL_CHANNEL_LVDS_MIN 14 | ||
194 | #define G4X_P_DUAL_CHANNEL_LVDS_MAX 42 | ||
195 | #define G4X_P1_DUAL_CHANNEL_LVDS_MIN 2 | ||
196 | #define G4X_P1_DUAL_CHANNEL_LVDS_MAX 6 | ||
197 | #define G4X_P2_DUAL_CHANNEL_LVDS_SLOW 7 | ||
198 | #define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7 | ||
199 | #define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0 | ||
200 | |||
118 | 201 | ||
119 | static const intel_limit_t intel_limits[] = { | 202 | static const intel_limit_t intel_limits[] = { |
120 | { /* INTEL_LIMIT_I8XX_DVO_DAC */ | 203 | { /* INTEL_LIMIT_I8XX_DVO_DAC */ |
@@ -168,14 +251,116 @@ static const intel_limit_t intel_limits[] = { | |||
168 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 251 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
169 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, | 252 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, |
170 | }, | 253 | }, |
254 | /* below parameter and function is for G4X Chipset Family*/ | ||
255 | { /* INTEL_LIMIT_G4X_SDVO */ | ||
256 | .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX }, | ||
257 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, | ||
258 | .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX }, | ||
259 | .m = { .min = G4X_M_SDVO_MIN, .max = G4X_M_SDVO_MAX }, | ||
260 | .m1 = { .min = G4X_M1_SDVO_MIN, .max = G4X_M1_SDVO_MAX }, | ||
261 | .m2 = { .min = G4X_M2_SDVO_MIN, .max = G4X_M2_SDVO_MAX }, | ||
262 | .p = { .min = G4X_P_SDVO_MIN, .max = G4X_P_SDVO_MAX }, | ||
263 | .p1 = { .min = G4X_P1_SDVO_MIN, .max = G4X_P1_SDVO_MAX}, | ||
264 | .p2 = { .dot_limit = G4X_P2_SDVO_LIMIT, | ||
265 | .p2_slow = G4X_P2_SDVO_SLOW, | ||
266 | .p2_fast = G4X_P2_SDVO_FAST | ||
267 | }, | ||
268 | }, | ||
269 | { /* INTEL_LIMIT_G4X_HDMI_DAC */ | ||
270 | .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX }, | ||
271 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, | ||
272 | .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX }, | ||
273 | .m = { .min = G4X_M_HDMI_DAC_MIN, .max = G4X_M_HDMI_DAC_MAX }, | ||
274 | .m1 = { .min = G4X_M1_HDMI_DAC_MIN, .max = G4X_M1_HDMI_DAC_MAX }, | ||
275 | .m2 = { .min = G4X_M2_HDMI_DAC_MIN, .max = G4X_M2_HDMI_DAC_MAX }, | ||
276 | .p = { .min = G4X_P_HDMI_DAC_MIN, .max = G4X_P_HDMI_DAC_MAX }, | ||
277 | .p1 = { .min = G4X_P1_HDMI_DAC_MIN, .max = G4X_P1_HDMI_DAC_MAX}, | ||
278 | .p2 = { .dot_limit = G4X_P2_HDMI_DAC_LIMIT, | ||
279 | .p2_slow = G4X_P2_HDMI_DAC_SLOW, | ||
280 | .p2_fast = G4X_P2_HDMI_DAC_FAST | ||
281 | }, | ||
282 | }, | ||
283 | { /* INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS */ | ||
284 | .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN, | ||
285 | .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX }, | ||
286 | .vco = { .min = G4X_VCO_MIN, | ||
287 | .max = G4X_VCO_MAX }, | ||
288 | .n = { .min = G4X_N_SINGLE_CHANNEL_LVDS_MIN, | ||
289 | .max = G4X_N_SINGLE_CHANNEL_LVDS_MAX }, | ||
290 | .m = { .min = G4X_M_SINGLE_CHANNEL_LVDS_MIN, | ||
291 | .max = G4X_M_SINGLE_CHANNEL_LVDS_MAX }, | ||
292 | .m1 = { .min = G4X_M1_SINGLE_CHANNEL_LVDS_MIN, | ||
293 | .max = G4X_M1_SINGLE_CHANNEL_LVDS_MAX }, | ||
294 | .m2 = { .min = G4X_M2_SINGLE_CHANNEL_LVDS_MIN, | ||
295 | .max = G4X_M2_SINGLE_CHANNEL_LVDS_MAX }, | ||
296 | .p = { .min = G4X_P_SINGLE_CHANNEL_LVDS_MIN, | ||
297 | .max = G4X_P_SINGLE_CHANNEL_LVDS_MAX }, | ||
298 | .p1 = { .min = G4X_P1_SINGLE_CHANNEL_LVDS_MIN, | ||
299 | .max = G4X_P1_SINGLE_CHANNEL_LVDS_MAX }, | ||
300 | .p2 = { .dot_limit = G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT, | ||
301 | .p2_slow = G4X_P2_SINGLE_CHANNEL_LVDS_SLOW, | ||
302 | .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST | ||
303 | }, | ||
304 | }, | ||
305 | { /* INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS */ | ||
306 | .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN, | ||
307 | .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX }, | ||
308 | .vco = { .min = G4X_VCO_MIN, | ||
309 | .max = G4X_VCO_MAX }, | ||
310 | .n = { .min = G4X_N_DUAL_CHANNEL_LVDS_MIN, | ||
311 | .max = G4X_N_DUAL_CHANNEL_LVDS_MAX }, | ||
312 | .m = { .min = G4X_M_DUAL_CHANNEL_LVDS_MIN, | ||
313 | .max = G4X_M_DUAL_CHANNEL_LVDS_MAX }, | ||
314 | .m1 = { .min = G4X_M1_DUAL_CHANNEL_LVDS_MIN, | ||
315 | .max = G4X_M1_DUAL_CHANNEL_LVDS_MAX }, | ||
316 | .m2 = { .min = G4X_M2_DUAL_CHANNEL_LVDS_MIN, | ||
317 | .max = G4X_M2_DUAL_CHANNEL_LVDS_MAX }, | ||
318 | .p = { .min = G4X_P_DUAL_CHANNEL_LVDS_MIN, | ||
319 | .max = G4X_P_DUAL_CHANNEL_LVDS_MAX }, | ||
320 | .p1 = { .min = G4X_P1_DUAL_CHANNEL_LVDS_MIN, | ||
321 | .max = G4X_P1_DUAL_CHANNEL_LVDS_MAX }, | ||
322 | .p2 = { .dot_limit = G4X_P2_DUAL_CHANNEL_LVDS_LIMIT, | ||
323 | .p2_slow = G4X_P2_DUAL_CHANNEL_LVDS_SLOW, | ||
324 | .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST | ||
325 | }, | ||
326 | }, | ||
171 | }; | 327 | }; |
172 | 328 | ||
329 | static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) | ||
330 | { | ||
331 | struct drm_device *dev = crtc->dev; | ||
332 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
333 | const intel_limit_t *limit; | ||
334 | |||
335 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | ||
336 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == | ||
337 | LVDS_CLKB_POWER_UP) | ||
338 | /* LVDS with dual channel */ | ||
339 | limit = &intel_limits | ||
340 | [INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS]; | ||
341 | else | ||
342 | /* LVDS with dual channel */ | ||
343 | limit = &intel_limits | ||
344 | [INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS]; | ||
345 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || | ||
346 | intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { | ||
347 | limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC]; | ||
348 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { | ||
349 | limit = &intel_limits[INTEL_LIMIT_G4X_SDVO]; | ||
350 | } else /* The option is for other outputs */ | ||
351 | limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; | ||
352 | |||
353 | return limit; | ||
354 | } | ||
355 | |||
173 | static const intel_limit_t *intel_limit(struct drm_crtc *crtc) | 356 | static const intel_limit_t *intel_limit(struct drm_crtc *crtc) |
174 | { | 357 | { |
175 | struct drm_device *dev = crtc->dev; | 358 | struct drm_device *dev = crtc->dev; |
176 | const intel_limit_t *limit; | 359 | const intel_limit_t *limit; |
177 | 360 | ||
178 | if (IS_I9XX(dev)) { | 361 | if (IS_G4X(dev)) { |
362 | limit = intel_g4x_limit(crtc); | ||
363 | } else if (IS_I9XX(dev)) { | ||
179 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 364 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
180 | limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; | 365 | limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; |
181 | else | 366 | else |