diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-09-07 02:19:51 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-09-07 02:19:51 -0400 |
commit | a1922ed661ab2c1637d0b10cde933bd9cd33d965 (patch) | |
tree | 0f1777542b385ebefd30b3586d830fd8ed6fda5b /drivers/gpu/drm/i915/intel_display.c | |
parent | 75e33751ca8bbb72dd6f1a74d2810ddc8cbe4bdf (diff) | |
parent | d28daf923ac5e4a0d7cecebae56f3e339189366b (diff) |
Merge branch 'tracing/core' into tracing/hw-breakpoints
Conflicts:
arch/Kconfig
kernel/trace/trace.h
Merge reason: resolve the conflicts, plus adopt to the new
ring-buffer APIs.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 1297 |
1 files changed, 1018 insertions, 279 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 028f5b66e3d..3fadb535885 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -25,14 +25,19 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/kernel.h> | ||
28 | #include "drmP.h" | 29 | #include "drmP.h" |
29 | #include "intel_drv.h" | 30 | #include "intel_drv.h" |
30 | #include "i915_drm.h" | 31 | #include "i915_drm.h" |
31 | #include "i915_drv.h" | 32 | #include "i915_drv.h" |
33 | #include "intel_dp.h" | ||
32 | 34 | ||
33 | #include "drm_crtc_helper.h" | 35 | #include "drm_crtc_helper.h" |
34 | 36 | ||
37 | #define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) | ||
38 | |||
35 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); | 39 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); |
40 | static void intel_update_watermarks(struct drm_device *dev); | ||
36 | 41 | ||
37 | typedef struct { | 42 | typedef struct { |
38 | /* given values */ | 43 | /* given values */ |
@@ -85,7 +90,7 @@ struct intel_limit { | |||
85 | #define I8XX_P2_SLOW 4 | 90 | #define I8XX_P2_SLOW 4 |
86 | #define I8XX_P2_FAST 2 | 91 | #define I8XX_P2_FAST 2 |
87 | #define I8XX_P2_LVDS_SLOW 14 | 92 | #define I8XX_P2_LVDS_SLOW 14 |
88 | #define I8XX_P2_LVDS_FAST 14 /* No fast option */ | 93 | #define I8XX_P2_LVDS_FAST 7 |
89 | #define I8XX_P2_SLOW_LIMIT 165000 | 94 | #define I8XX_P2_SLOW_LIMIT 165000 |
90 | 95 | ||
91 | #define I9XX_DOT_MIN 20000 | 96 | #define I9XX_DOT_MIN 20000 |
@@ -127,19 +132,6 @@ struct intel_limit { | |||
127 | #define I9XX_P2_LVDS_FAST 7 | 132 | #define I9XX_P2_LVDS_FAST 7 |
128 | #define I9XX_P2_LVDS_SLOW_LIMIT 112000 | 133 | #define I9XX_P2_LVDS_SLOW_LIMIT 112000 |
129 | 134 | ||
130 | #define INTEL_LIMIT_I8XX_DVO_DAC 0 | ||
131 | #define INTEL_LIMIT_I8XX_LVDS 1 | ||
132 | #define INTEL_LIMIT_I9XX_SDVO_DAC 2 | ||
133 | #define INTEL_LIMIT_I9XX_LVDS 3 | ||
134 | #define INTEL_LIMIT_G4X_SDVO 4 | ||
135 | #define INTEL_LIMIT_G4X_HDMI_DAC 5 | ||
136 | #define INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS 6 | ||
137 | #define INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS 7 | ||
138 | #define INTEL_LIMIT_IGD_SDVO_DAC 8 | ||
139 | #define INTEL_LIMIT_IGD_LVDS 9 | ||
140 | #define INTEL_LIMIT_IGDNG_SDVO_DAC 10 | ||
141 | #define INTEL_LIMIT_IGDNG_LVDS 11 | ||
142 | |||
143 | /*The parameter is for SDVO on G4x platform*/ | 135 | /*The parameter is for SDVO on G4x platform*/ |
144 | #define G4X_DOT_SDVO_MIN 25000 | 136 | #define G4X_DOT_SDVO_MIN 25000 |
145 | #define G4X_DOT_SDVO_MAX 270000 | 137 | #define G4X_DOT_SDVO_MAX 270000 |
@@ -218,6 +210,25 @@ struct intel_limit { | |||
218 | #define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7 | 210 | #define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7 |
219 | #define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0 | 211 | #define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0 |
220 | 212 | ||
213 | /*The parameter is for DISPLAY PORT on G4x platform*/ | ||
214 | #define G4X_DOT_DISPLAY_PORT_MIN 161670 | ||
215 | #define G4X_DOT_DISPLAY_PORT_MAX 227000 | ||
216 | #define G4X_N_DISPLAY_PORT_MIN 1 | ||
217 | #define G4X_N_DISPLAY_PORT_MAX 2 | ||
218 | #define G4X_M_DISPLAY_PORT_MIN 97 | ||
219 | #define G4X_M_DISPLAY_PORT_MAX 108 | ||
220 | #define G4X_M1_DISPLAY_PORT_MIN 0x10 | ||
221 | #define G4X_M1_DISPLAY_PORT_MAX 0x12 | ||
222 | #define G4X_M2_DISPLAY_PORT_MIN 0x05 | ||
223 | #define G4X_M2_DISPLAY_PORT_MAX 0x06 | ||
224 | #define G4X_P_DISPLAY_PORT_MIN 10 | ||
225 | #define G4X_P_DISPLAY_PORT_MAX 20 | ||
226 | #define G4X_P1_DISPLAY_PORT_MIN 1 | ||
227 | #define G4X_P1_DISPLAY_PORT_MAX 2 | ||
228 | #define G4X_P2_DISPLAY_PORT_SLOW 10 | ||
229 | #define G4X_P2_DISPLAY_PORT_FAST 10 | ||
230 | #define G4X_P2_DISPLAY_PORT_LIMIT 0 | ||
231 | |||
221 | /* IGDNG */ | 232 | /* IGDNG */ |
222 | /* as we calculate clock using (register_value + 2) for | 233 | /* as we calculate clock using (register_value + 2) for |
223 | N/M1/M2, so here the range value for them is (actual_value-2). | 234 | N/M1/M2, so here the range value for them is (actual_value-2). |
@@ -256,8 +267,14 @@ static bool | |||
256 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 267 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
257 | int target, int refclk, intel_clock_t *best_clock); | 268 | int target, int refclk, intel_clock_t *best_clock); |
258 | 269 | ||
259 | static const intel_limit_t intel_limits[] = { | 270 | static bool |
260 | { /* INTEL_LIMIT_I8XX_DVO_DAC */ | 271 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, |
272 | int target, int refclk, intel_clock_t *best_clock); | ||
273 | static bool | ||
274 | intel_find_pll_igdng_dp(const intel_limit_t *, struct drm_crtc *crtc, | ||
275 | int target, int refclk, intel_clock_t *best_clock); | ||
276 | |||
277 | static const intel_limit_t intel_limits_i8xx_dvo = { | ||
261 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, | 278 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, |
262 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, | 279 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, |
263 | .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, | 280 | .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, |
@@ -269,8 +286,9 @@ static const intel_limit_t intel_limits[] = { | |||
269 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, | 286 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, |
270 | .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, | 287 | .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, |
271 | .find_pll = intel_find_best_PLL, | 288 | .find_pll = intel_find_best_PLL, |
272 | }, | 289 | }; |
273 | { /* INTEL_LIMIT_I8XX_LVDS */ | 290 | |
291 | static const intel_limit_t intel_limits_i8xx_lvds = { | ||
274 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, | 292 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, |
275 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, | 293 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, |
276 | .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, | 294 | .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, |
@@ -282,8 +300,9 @@ static const intel_limit_t intel_limits[] = { | |||
282 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, | 300 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, |
283 | .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, | 301 | .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, |
284 | .find_pll = intel_find_best_PLL, | 302 | .find_pll = intel_find_best_PLL, |
285 | }, | 303 | }; |
286 | { /* INTEL_LIMIT_I9XX_SDVO_DAC */ | 304 | |
305 | static const intel_limit_t intel_limits_i9xx_sdvo = { | ||
287 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, | 306 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, |
288 | .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, | 307 | .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, |
289 | .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, | 308 | .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, |
@@ -295,8 +314,9 @@ static const intel_limit_t intel_limits[] = { | |||
295 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, | 314 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, |
296 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, | 315 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, |
297 | .find_pll = intel_find_best_PLL, | 316 | .find_pll = intel_find_best_PLL, |
298 | }, | 317 | }; |
299 | { /* INTEL_LIMIT_I9XX_LVDS */ | 318 | |
319 | static const intel_limit_t intel_limits_i9xx_lvds = { | ||
300 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, | 320 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, |
301 | .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, | 321 | .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, |
302 | .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, | 322 | .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, |
@@ -311,9 +331,10 @@ static const intel_limit_t intel_limits[] = { | |||
311 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 331 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
312 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, | 332 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, |
313 | .find_pll = intel_find_best_PLL, | 333 | .find_pll = intel_find_best_PLL, |
314 | }, | 334 | }; |
335 | |||
315 | /* below parameter and function is for G4X Chipset Family*/ | 336 | /* below parameter and function is for G4X Chipset Family*/ |
316 | { /* INTEL_LIMIT_G4X_SDVO */ | 337 | static const intel_limit_t intel_limits_g4x_sdvo = { |
317 | .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX }, | 338 | .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX }, |
318 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, | 339 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, |
319 | .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX }, | 340 | .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX }, |
@@ -327,8 +348,9 @@ static const intel_limit_t intel_limits[] = { | |||
327 | .p2_fast = G4X_P2_SDVO_FAST | 348 | .p2_fast = G4X_P2_SDVO_FAST |
328 | }, | 349 | }, |
329 | .find_pll = intel_g4x_find_best_PLL, | 350 | .find_pll = intel_g4x_find_best_PLL, |
330 | }, | 351 | }; |
331 | { /* INTEL_LIMIT_G4X_HDMI_DAC */ | 352 | |
353 | static const intel_limit_t intel_limits_g4x_hdmi = { | ||
332 | .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX }, | 354 | .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX }, |
333 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, | 355 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, |
334 | .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX }, | 356 | .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX }, |
@@ -342,8 +364,9 @@ static const intel_limit_t intel_limits[] = { | |||
342 | .p2_fast = G4X_P2_HDMI_DAC_FAST | 364 | .p2_fast = G4X_P2_HDMI_DAC_FAST |
343 | }, | 365 | }, |
344 | .find_pll = intel_g4x_find_best_PLL, | 366 | .find_pll = intel_g4x_find_best_PLL, |
345 | }, | 367 | }; |
346 | { /* INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS */ | 368 | |
369 | static const intel_limit_t intel_limits_g4x_single_channel_lvds = { | ||
347 | .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN, | 370 | .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN, |
348 | .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX }, | 371 | .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX }, |
349 | .vco = { .min = G4X_VCO_MIN, | 372 | .vco = { .min = G4X_VCO_MIN, |
@@ -365,8 +388,9 @@ static const intel_limit_t intel_limits[] = { | |||
365 | .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST | 388 | .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST |
366 | }, | 389 | }, |
367 | .find_pll = intel_g4x_find_best_PLL, | 390 | .find_pll = intel_g4x_find_best_PLL, |
368 | }, | 391 | }; |
369 | { /* INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS */ | 392 | |
393 | static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { | ||
370 | .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN, | 394 | .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN, |
371 | .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX }, | 395 | .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX }, |
372 | .vco = { .min = G4X_VCO_MIN, | 396 | .vco = { .min = G4X_VCO_MIN, |
@@ -388,8 +412,32 @@ static const intel_limit_t intel_limits[] = { | |||
388 | .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST | 412 | .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST |
389 | }, | 413 | }, |
390 | .find_pll = intel_g4x_find_best_PLL, | 414 | .find_pll = intel_g4x_find_best_PLL, |
391 | }, | 415 | }; |
392 | { /* INTEL_LIMIT_IGD_SDVO */ | 416 | |
417 | static const intel_limit_t intel_limits_g4x_display_port = { | ||
418 | .dot = { .min = G4X_DOT_DISPLAY_PORT_MIN, | ||
419 | .max = G4X_DOT_DISPLAY_PORT_MAX }, | ||
420 | .vco = { .min = G4X_VCO_MIN, | ||
421 | .max = G4X_VCO_MAX}, | ||
422 | .n = { .min = G4X_N_DISPLAY_PORT_MIN, | ||
423 | .max = G4X_N_DISPLAY_PORT_MAX }, | ||
424 | .m = { .min = G4X_M_DISPLAY_PORT_MIN, | ||
425 | .max = G4X_M_DISPLAY_PORT_MAX }, | ||
426 | .m1 = { .min = G4X_M1_DISPLAY_PORT_MIN, | ||
427 | .max = G4X_M1_DISPLAY_PORT_MAX }, | ||
428 | .m2 = { .min = G4X_M2_DISPLAY_PORT_MIN, | ||
429 | .max = G4X_M2_DISPLAY_PORT_MAX }, | ||
430 | .p = { .min = G4X_P_DISPLAY_PORT_MIN, | ||
431 | .max = G4X_P_DISPLAY_PORT_MAX }, | ||
432 | .p1 = { .min = G4X_P1_DISPLAY_PORT_MIN, | ||
433 | .max = G4X_P1_DISPLAY_PORT_MAX}, | ||
434 | .p2 = { .dot_limit = G4X_P2_DISPLAY_PORT_LIMIT, | ||
435 | .p2_slow = G4X_P2_DISPLAY_PORT_SLOW, | ||
436 | .p2_fast = G4X_P2_DISPLAY_PORT_FAST }, | ||
437 | .find_pll = intel_find_pll_g4x_dp, | ||
438 | }; | ||
439 | |||
440 | static const intel_limit_t intel_limits_igd_sdvo = { | ||
393 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, | 441 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, |
394 | .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, | 442 | .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, |
395 | .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, | 443 | .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, |
@@ -401,8 +449,9 @@ static const intel_limit_t intel_limits[] = { | |||
401 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, | 449 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, |
402 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, | 450 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, |
403 | .find_pll = intel_find_best_PLL, | 451 | .find_pll = intel_find_best_PLL, |
404 | }, | 452 | }; |
405 | { /* INTEL_LIMIT_IGD_LVDS */ | 453 | |
454 | static const intel_limit_t intel_limits_igd_lvds = { | ||
406 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, | 455 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, |
407 | .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, | 456 | .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, |
408 | .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, | 457 | .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, |
@@ -415,8 +464,9 @@ static const intel_limit_t intel_limits[] = { | |||
415 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 464 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
416 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, | 465 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, |
417 | .find_pll = intel_find_best_PLL, | 466 | .find_pll = intel_find_best_PLL, |
418 | }, | 467 | }; |
419 | { /* INTEL_LIMIT_IGDNG_SDVO_DAC */ | 468 | |
469 | static const intel_limit_t intel_limits_igdng_sdvo = { | ||
420 | .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, | 470 | .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, |
421 | .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, | 471 | .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, |
422 | .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, | 472 | .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, |
@@ -429,8 +479,9 @@ static const intel_limit_t intel_limits[] = { | |||
429 | .p2_slow = IGDNG_P2_SDVO_DAC_SLOW, | 479 | .p2_slow = IGDNG_P2_SDVO_DAC_SLOW, |
430 | .p2_fast = IGDNG_P2_SDVO_DAC_FAST }, | 480 | .p2_fast = IGDNG_P2_SDVO_DAC_FAST }, |
431 | .find_pll = intel_igdng_find_best_PLL, | 481 | .find_pll = intel_igdng_find_best_PLL, |
432 | }, | 482 | }; |
433 | { /* INTEL_LIMIT_IGDNG_LVDS */ | 483 | |
484 | static const intel_limit_t intel_limits_igdng_lvds = { | ||
434 | .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, | 485 | .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, |
435 | .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, | 486 | .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, |
436 | .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, | 487 | .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, |
@@ -443,16 +494,15 @@ static const intel_limit_t intel_limits[] = { | |||
443 | .p2_slow = IGDNG_P2_LVDS_SLOW, | 494 | .p2_slow = IGDNG_P2_LVDS_SLOW, |
444 | .p2_fast = IGDNG_P2_LVDS_FAST }, | 495 | .p2_fast = IGDNG_P2_LVDS_FAST }, |
445 | .find_pll = intel_igdng_find_best_PLL, | 496 | .find_pll = intel_igdng_find_best_PLL, |
446 | }, | ||
447 | }; | 497 | }; |
448 | 498 | ||
449 | static const intel_limit_t *intel_igdng_limit(struct drm_crtc *crtc) | 499 | static const intel_limit_t *intel_igdng_limit(struct drm_crtc *crtc) |
450 | { | 500 | { |
451 | const intel_limit_t *limit; | 501 | const intel_limit_t *limit; |
452 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 502 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
453 | limit = &intel_limits[INTEL_LIMIT_IGDNG_LVDS]; | 503 | limit = &intel_limits_igdng_lvds; |
454 | else | 504 | else |
455 | limit = &intel_limits[INTEL_LIMIT_IGDNG_SDVO_DAC]; | 505 | limit = &intel_limits_igdng_sdvo; |
456 | 506 | ||
457 | return limit; | 507 | return limit; |
458 | } | 508 | } |
@@ -467,19 +517,19 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) | |||
467 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == | 517 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == |
468 | LVDS_CLKB_POWER_UP) | 518 | LVDS_CLKB_POWER_UP) |
469 | /* LVDS with dual channel */ | 519 | /* LVDS with dual channel */ |
470 | limit = &intel_limits | 520 | limit = &intel_limits_g4x_dual_channel_lvds; |
471 | [INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS]; | ||
472 | else | 521 | else |
473 | /* LVDS with dual channel */ | 522 | /* LVDS with dual channel */ |
474 | limit = &intel_limits | 523 | limit = &intel_limits_g4x_single_channel_lvds; |
475 | [INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS]; | ||
476 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || | 524 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || |
477 | intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { | 525 | intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { |
478 | limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC]; | 526 | limit = &intel_limits_g4x_hdmi; |
479 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { | 527 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { |
480 | limit = &intel_limits[INTEL_LIMIT_G4X_SDVO]; | 528 | limit = &intel_limits_g4x_sdvo; |
529 | } else if (intel_pipe_has_type (crtc, INTEL_OUTPUT_DISPLAYPORT)) { | ||
530 | limit = &intel_limits_g4x_display_port; | ||
481 | } else /* The option is for other outputs */ | 531 | } else /* The option is for other outputs */ |
482 | limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; | 532 | limit = &intel_limits_i9xx_sdvo; |
483 | 533 | ||
484 | return limit; | 534 | return limit; |
485 | } | 535 | } |
@@ -495,19 +545,19 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc) | |||
495 | limit = intel_g4x_limit(crtc); | 545 | limit = intel_g4x_limit(crtc); |
496 | } else if (IS_I9XX(dev) && !IS_IGD(dev)) { | 546 | } else if (IS_I9XX(dev) && !IS_IGD(dev)) { |
497 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 547 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
498 | limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; | 548 | limit = &intel_limits_i9xx_lvds; |
499 | else | 549 | else |
500 | limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; | 550 | limit = &intel_limits_i9xx_sdvo; |
501 | } else if (IS_IGD(dev)) { | 551 | } else if (IS_IGD(dev)) { |
502 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 552 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
503 | limit = &intel_limits[INTEL_LIMIT_IGD_LVDS]; | 553 | limit = &intel_limits_igd_lvds; |
504 | else | 554 | else |
505 | limit = &intel_limits[INTEL_LIMIT_IGD_SDVO_DAC]; | 555 | limit = &intel_limits_igd_sdvo; |
506 | } else { | 556 | } else { |
507 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 557 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
508 | limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS]; | 558 | limit = &intel_limits_i8xx_lvds; |
509 | else | 559 | else |
510 | limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC]; | 560 | limit = &intel_limits_i8xx_dvo; |
511 | } | 561 | } |
512 | return limit; | 562 | return limit; |
513 | } | 563 | } |
@@ -553,6 +603,23 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) | |||
553 | return false; | 603 | return false; |
554 | } | 604 | } |
555 | 605 | ||
606 | struct drm_connector * | ||
607 | intel_pipe_get_output (struct drm_crtc *crtc) | ||
608 | { | ||
609 | struct drm_device *dev = crtc->dev; | ||
610 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
611 | struct drm_connector *l_entry, *ret = NULL; | ||
612 | |||
613 | list_for_each_entry(l_entry, &mode_config->connector_list, head) { | ||
614 | if (l_entry->encoder && | ||
615 | l_entry->encoder->crtc == crtc) { | ||
616 | ret = l_entry; | ||
617 | break; | ||
618 | } | ||
619 | } | ||
620 | return ret; | ||
621 | } | ||
622 | |||
556 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) | 623 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) |
557 | /** | 624 | /** |
558 | * Returns whether the given set of divisors are valid for a given refclk with | 625 | * Returns whether the given set of divisors are valid for a given refclk with |
@@ -599,8 +666,8 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
599 | intel_clock_t clock; | 666 | intel_clock_t clock; |
600 | int err = target; | 667 | int err = target; |
601 | 668 | ||
602 | if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && | 669 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && |
603 | (I915_READ(LVDS) & LVDS_PORT_EN) != 0) { | 670 | (I915_READ(LVDS)) != 0) { |
604 | /* | 671 | /* |
605 | * For LVDS, if the panel is on, just rely on its current | 672 | * For LVDS, if the panel is on, just rely on its current |
606 | * settings for dual-channel. We haven't figured out how to | 673 | * settings for dual-channel. We haven't figured out how to |
@@ -707,6 +774,30 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
707 | } | 774 | } |
708 | 775 | ||
709 | static bool | 776 | static bool |
777 | intel_find_pll_igdng_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
778 | int target, int refclk, intel_clock_t *best_clock) | ||
779 | { | ||
780 | struct drm_device *dev = crtc->dev; | ||
781 | intel_clock_t clock; | ||
782 | if (target < 200000) { | ||
783 | clock.n = 1; | ||
784 | clock.p1 = 2; | ||
785 | clock.p2 = 10; | ||
786 | clock.m1 = 12; | ||
787 | clock.m2 = 9; | ||
788 | } else { | ||
789 | clock.n = 2; | ||
790 | clock.p1 = 1; | ||
791 | clock.p2 = 10; | ||
792 | clock.m1 = 14; | ||
793 | clock.m2 = 8; | ||
794 | } | ||
795 | intel_clock(dev, refclk, &clock); | ||
796 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | ||
797 | return true; | ||
798 | } | ||
799 | |||
800 | static bool | ||
710 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 801 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
711 | int target, int refclk, intel_clock_t *best_clock) | 802 | int target, int refclk, intel_clock_t *best_clock) |
712 | { | 803 | { |
@@ -718,6 +809,14 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
718 | int err_most = 47; | 809 | int err_most = 47; |
719 | found = false; | 810 | found = false; |
720 | 811 | ||
812 | /* eDP has only 2 clock choice, no n/m/p setting */ | ||
813 | if (HAS_eDP) | ||
814 | return true; | ||
815 | |||
816 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) | ||
817 | return intel_find_pll_igdng_dp(limit, crtc, target, | ||
818 | refclk, best_clock); | ||
819 | |||
721 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 820 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
722 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == | 821 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == |
723 | LVDS_CLKB_POWER_UP) | 822 | LVDS_CLKB_POWER_UP) |
@@ -764,6 +863,32 @@ out: | |||
764 | return found; | 863 | return found; |
765 | } | 864 | } |
766 | 865 | ||
866 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ | ||
867 | static bool | ||
868 | intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
869 | int target, int refclk, intel_clock_t *best_clock) | ||
870 | { | ||
871 | intel_clock_t clock; | ||
872 | if (target < 200000) { | ||
873 | clock.p1 = 2; | ||
874 | clock.p2 = 10; | ||
875 | clock.n = 2; | ||
876 | clock.m1 = 23; | ||
877 | clock.m2 = 8; | ||
878 | } else { | ||
879 | clock.p1 = 1; | ||
880 | clock.p2 = 10; | ||
881 | clock.n = 1; | ||
882 | clock.m1 = 14; | ||
883 | clock.m2 = 2; | ||
884 | } | ||
885 | clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2); | ||
886 | clock.p = (clock.p1 * clock.p2); | ||
887 | clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; | ||
888 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | ||
889 | return true; | ||
890 | } | ||
891 | |||
767 | void | 892 | void |
768 | intel_wait_for_vblank(struct drm_device *dev) | 893 | intel_wait_for_vblank(struct drm_device *dev) |
769 | { | 894 | { |
@@ -828,19 +953,31 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
828 | } | 953 | } |
829 | 954 | ||
830 | mutex_lock(&dev->struct_mutex); | 955 | mutex_lock(&dev->struct_mutex); |
831 | ret = i915_gem_object_pin(intel_fb->obj, alignment); | 956 | ret = i915_gem_object_pin(obj, alignment); |
832 | if (ret != 0) { | 957 | if (ret != 0) { |
833 | mutex_unlock(&dev->struct_mutex); | 958 | mutex_unlock(&dev->struct_mutex); |
834 | return ret; | 959 | return ret; |
835 | } | 960 | } |
836 | 961 | ||
837 | ret = i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1); | 962 | ret = i915_gem_object_set_to_gtt_domain(obj, 1); |
838 | if (ret != 0) { | 963 | if (ret != 0) { |
839 | i915_gem_object_unpin(intel_fb->obj); | 964 | i915_gem_object_unpin(obj); |
840 | mutex_unlock(&dev->struct_mutex); | 965 | mutex_unlock(&dev->struct_mutex); |
841 | return ret; | 966 | return ret; |
842 | } | 967 | } |
843 | 968 | ||
969 | /* Pre-i965 needs to install a fence for tiled scan-out */ | ||
970 | if (!IS_I965G(dev) && | ||
971 | obj_priv->fence_reg == I915_FENCE_REG_NONE && | ||
972 | obj_priv->tiling_mode != I915_TILING_NONE) { | ||
973 | ret = i915_gem_object_get_fence_reg(obj); | ||
974 | if (ret != 0) { | ||
975 | i915_gem_object_unpin(obj); | ||
976 | mutex_unlock(&dev->struct_mutex); | ||
977 | return ret; | ||
978 | } | ||
979 | } | ||
980 | |||
844 | dspcntr = I915_READ(dspcntr_reg); | 981 | dspcntr = I915_READ(dspcntr_reg); |
845 | /* Mask out pixel format bits in case we change it */ | 982 | /* Mask out pixel format bits in case we change it */ |
846 | dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; | 983 | dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; |
@@ -860,7 +997,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
860 | break; | 997 | break; |
861 | default: | 998 | default: |
862 | DRM_ERROR("Unknown color depth\n"); | 999 | DRM_ERROR("Unknown color depth\n"); |
863 | i915_gem_object_unpin(intel_fb->obj); | 1000 | i915_gem_object_unpin(obj); |
864 | mutex_unlock(&dev->struct_mutex); | 1001 | mutex_unlock(&dev->struct_mutex); |
865 | return -EINVAL; | 1002 | return -EINVAL; |
866 | } | 1003 | } |
@@ -915,13 +1052,97 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
915 | return 0; | 1052 | return 0; |
916 | } | 1053 | } |
917 | 1054 | ||
1055 | /* Disable the VGA plane that we never use */ | ||
1056 | static void i915_disable_vga (struct drm_device *dev) | ||
1057 | { | ||
1058 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1059 | u8 sr1; | ||
1060 | u32 vga_reg; | ||
1061 | |||
1062 | if (IS_IGDNG(dev)) | ||
1063 | vga_reg = CPU_VGACNTRL; | ||
1064 | else | ||
1065 | vga_reg = VGACNTRL; | ||
1066 | |||
1067 | if (I915_READ(vga_reg) & VGA_DISP_DISABLE) | ||
1068 | return; | ||
1069 | |||
1070 | I915_WRITE8(VGA_SR_INDEX, 1); | ||
1071 | sr1 = I915_READ8(VGA_SR_DATA); | ||
1072 | I915_WRITE8(VGA_SR_DATA, sr1 | (1 << 5)); | ||
1073 | udelay(100); | ||
1074 | |||
1075 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
1076 | } | ||
1077 | |||
1078 | static void igdng_disable_pll_edp (struct drm_crtc *crtc) | ||
1079 | { | ||
1080 | struct drm_device *dev = crtc->dev; | ||
1081 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1082 | u32 dpa_ctl; | ||
1083 | |||
1084 | DRM_DEBUG("\n"); | ||
1085 | dpa_ctl = I915_READ(DP_A); | ||
1086 | dpa_ctl &= ~DP_PLL_ENABLE; | ||
1087 | I915_WRITE(DP_A, dpa_ctl); | ||
1088 | } | ||
1089 | |||
1090 | static void igdng_enable_pll_edp (struct drm_crtc *crtc) | ||
1091 | { | ||
1092 | struct drm_device *dev = crtc->dev; | ||
1093 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1094 | u32 dpa_ctl; | ||
1095 | |||
1096 | dpa_ctl = I915_READ(DP_A); | ||
1097 | dpa_ctl |= DP_PLL_ENABLE; | ||
1098 | I915_WRITE(DP_A, dpa_ctl); | ||
1099 | udelay(200); | ||
1100 | } | ||
1101 | |||
1102 | |||
1103 | static void igdng_set_pll_edp (struct drm_crtc *crtc, int clock) | ||
1104 | { | ||
1105 | struct drm_device *dev = crtc->dev; | ||
1106 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1107 | u32 dpa_ctl; | ||
1108 | |||
1109 | DRM_DEBUG("eDP PLL enable for clock %d\n", clock); | ||
1110 | dpa_ctl = I915_READ(DP_A); | ||
1111 | dpa_ctl &= ~DP_PLL_FREQ_MASK; | ||
1112 | |||
1113 | if (clock < 200000) { | ||
1114 | u32 temp; | ||
1115 | dpa_ctl |= DP_PLL_FREQ_160MHZ; | ||
1116 | /* workaround for 160Mhz: | ||
1117 | 1) program 0x4600c bits 15:0 = 0x8124 | ||
1118 | 2) program 0x46010 bit 0 = 1 | ||
1119 | 3) program 0x46034 bit 24 = 1 | ||
1120 | 4) program 0x64000 bit 14 = 1 | ||
1121 | */ | ||
1122 | temp = I915_READ(0x4600c); | ||
1123 | temp &= 0xffff0000; | ||
1124 | I915_WRITE(0x4600c, temp | 0x8124); | ||
1125 | |||
1126 | temp = I915_READ(0x46010); | ||
1127 | I915_WRITE(0x46010, temp | 1); | ||
1128 | |||
1129 | temp = I915_READ(0x46034); | ||
1130 | I915_WRITE(0x46034, temp | (1 << 24)); | ||
1131 | } else { | ||
1132 | dpa_ctl |= DP_PLL_FREQ_270MHZ; | ||
1133 | } | ||
1134 | I915_WRITE(DP_A, dpa_ctl); | ||
1135 | |||
1136 | udelay(500); | ||
1137 | } | ||
1138 | |||
918 | static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | 1139 | static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) |
919 | { | 1140 | { |
920 | struct drm_device *dev = crtc->dev; | 1141 | struct drm_device *dev = crtc->dev; |
921 | struct drm_i915_private *dev_priv = dev->dev_private; | 1142 | struct drm_i915_private *dev_priv = dev->dev_private; |
922 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1143 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
923 | int pipe = intel_crtc->pipe; | 1144 | int pipe = intel_crtc->pipe; |
924 | int plane = intel_crtc->pipe; | 1145 | int plane = intel_crtc->plane; |
925 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; | 1146 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; |
926 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; | 1147 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; |
927 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; | 1148 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; |
@@ -932,6 +1153,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
932 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; | 1153 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; |
933 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; | 1154 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; |
934 | int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; | 1155 | int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; |
1156 | int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ; | ||
935 | int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; | 1157 | int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; |
936 | int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; | 1158 | int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; |
937 | int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; | 1159 | int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; |
@@ -945,7 +1167,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
945 | int trans_vblank_reg = (pipe == 0) ? TRANS_VBLANK_A : TRANS_VBLANK_B; | 1167 | int trans_vblank_reg = (pipe == 0) ? TRANS_VBLANK_A : TRANS_VBLANK_B; |
946 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; | 1168 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; |
947 | u32 temp; | 1169 | u32 temp; |
948 | int tries = 5, j; | 1170 | int tries = 5, j, n; |
949 | 1171 | ||
950 | /* XXX: When our outputs are all unaware of DPMS modes other than off | 1172 | /* XXX: When our outputs are all unaware of DPMS modes other than off |
951 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. | 1173 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. |
@@ -955,27 +1177,32 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
955 | case DRM_MODE_DPMS_STANDBY: | 1177 | case DRM_MODE_DPMS_STANDBY: |
956 | case DRM_MODE_DPMS_SUSPEND: | 1178 | case DRM_MODE_DPMS_SUSPEND: |
957 | DRM_DEBUG("crtc %d dpms on\n", pipe); | 1179 | DRM_DEBUG("crtc %d dpms on\n", pipe); |
958 | /* enable PCH DPLL */ | 1180 | if (HAS_eDP) { |
959 | temp = I915_READ(pch_dpll_reg); | 1181 | /* enable eDP PLL */ |
960 | if ((temp & DPLL_VCO_ENABLE) == 0) { | 1182 | igdng_enable_pll_edp(crtc); |
961 | I915_WRITE(pch_dpll_reg, temp | DPLL_VCO_ENABLE); | 1183 | } else { |
962 | I915_READ(pch_dpll_reg); | 1184 | /* enable PCH DPLL */ |
963 | } | 1185 | temp = I915_READ(pch_dpll_reg); |
964 | 1186 | if ((temp & DPLL_VCO_ENABLE) == 0) { | |
965 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ | 1187 | I915_WRITE(pch_dpll_reg, temp | DPLL_VCO_ENABLE); |
966 | temp = I915_READ(fdi_rx_reg); | 1188 | I915_READ(pch_dpll_reg); |
967 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | | 1189 | } |
968 | FDI_SEL_PCDCLK | | ||
969 | FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ | ||
970 | I915_READ(fdi_rx_reg); | ||
971 | udelay(200); | ||
972 | 1190 | ||
973 | /* Enable CPU FDI TX PLL, always on for IGDNG */ | 1191 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ |
974 | temp = I915_READ(fdi_tx_reg); | 1192 | temp = I915_READ(fdi_rx_reg); |
975 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { | 1193 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | |
976 | I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE); | 1194 | FDI_SEL_PCDCLK | |
977 | I915_READ(fdi_tx_reg); | 1195 | FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ |
978 | udelay(100); | 1196 | I915_READ(fdi_rx_reg); |
1197 | udelay(200); | ||
1198 | |||
1199 | /* Enable CPU FDI TX PLL, always on for IGDNG */ | ||
1200 | temp = I915_READ(fdi_tx_reg); | ||
1201 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { | ||
1202 | I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE); | ||
1203 | I915_READ(fdi_tx_reg); | ||
1204 | udelay(100); | ||
1205 | } | ||
979 | } | 1206 | } |
980 | 1207 | ||
981 | /* Enable CPU pipe */ | 1208 | /* Enable CPU pipe */ |
@@ -994,122 +1221,126 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
994 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); | 1221 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); |
995 | } | 1222 | } |
996 | 1223 | ||
997 | /* enable CPU FDI TX and PCH FDI RX */ | 1224 | if (!HAS_eDP) { |
998 | temp = I915_READ(fdi_tx_reg); | 1225 | /* enable CPU FDI TX and PCH FDI RX */ |
999 | temp |= FDI_TX_ENABLE; | 1226 | temp = I915_READ(fdi_tx_reg); |
1000 | temp |= FDI_DP_PORT_WIDTH_X4; /* default */ | 1227 | temp |= FDI_TX_ENABLE; |
1001 | temp &= ~FDI_LINK_TRAIN_NONE; | 1228 | temp |= FDI_DP_PORT_WIDTH_X4; /* default */ |
1002 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1229 | temp &= ~FDI_LINK_TRAIN_NONE; |
1003 | I915_WRITE(fdi_tx_reg, temp); | 1230 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1004 | I915_READ(fdi_tx_reg); | 1231 | I915_WRITE(fdi_tx_reg, temp); |
1232 | I915_READ(fdi_tx_reg); | ||
1005 | 1233 | ||
1006 | temp = I915_READ(fdi_rx_reg); | 1234 | temp = I915_READ(fdi_rx_reg); |
1007 | temp &= ~FDI_LINK_TRAIN_NONE; | 1235 | temp &= ~FDI_LINK_TRAIN_NONE; |
1008 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1236 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1009 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENABLE); | 1237 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENABLE); |
1010 | I915_READ(fdi_rx_reg); | 1238 | I915_READ(fdi_rx_reg); |
1011 | 1239 | ||
1012 | udelay(150); | 1240 | udelay(150); |
1013 | 1241 | ||
1014 | /* Train FDI. */ | 1242 | /* Train FDI. */ |
1015 | /* umask FDI RX Interrupt symbol_lock and bit_lock bit | 1243 | /* umask FDI RX Interrupt symbol_lock and bit_lock bit |
1016 | for train result */ | 1244 | for train result */ |
1017 | temp = I915_READ(fdi_rx_imr_reg); | 1245 | temp = I915_READ(fdi_rx_imr_reg); |
1018 | temp &= ~FDI_RX_SYMBOL_LOCK; | 1246 | temp &= ~FDI_RX_SYMBOL_LOCK; |
1019 | temp &= ~FDI_RX_BIT_LOCK; | 1247 | temp &= ~FDI_RX_BIT_LOCK; |
1020 | I915_WRITE(fdi_rx_imr_reg, temp); | 1248 | I915_WRITE(fdi_rx_imr_reg, temp); |
1021 | I915_READ(fdi_rx_imr_reg); | 1249 | I915_READ(fdi_rx_imr_reg); |
1022 | udelay(150); | 1250 | udelay(150); |
1023 | 1251 | ||
1024 | temp = I915_READ(fdi_rx_iir_reg); | 1252 | temp = I915_READ(fdi_rx_iir_reg); |
1025 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1253 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1026 | 1254 | ||
1027 | if ((temp & FDI_RX_BIT_LOCK) == 0) { | 1255 | if ((temp & FDI_RX_BIT_LOCK) == 0) { |
1028 | for (j = 0; j < tries; j++) { | 1256 | for (j = 0; j < tries; j++) { |
1029 | temp = I915_READ(fdi_rx_iir_reg); | 1257 | temp = I915_READ(fdi_rx_iir_reg); |
1030 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1258 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1031 | if (temp & FDI_RX_BIT_LOCK) | 1259 | if (temp & FDI_RX_BIT_LOCK) |
1032 | break; | 1260 | break; |
1033 | udelay(200); | 1261 | udelay(200); |
1034 | } | 1262 | } |
1035 | if (j != tries) | 1263 | if (j != tries) |
1264 | I915_WRITE(fdi_rx_iir_reg, | ||
1265 | temp | FDI_RX_BIT_LOCK); | ||
1266 | else | ||
1267 | DRM_DEBUG("train 1 fail\n"); | ||
1268 | } else { | ||
1036 | I915_WRITE(fdi_rx_iir_reg, | 1269 | I915_WRITE(fdi_rx_iir_reg, |
1037 | temp | FDI_RX_BIT_LOCK); | 1270 | temp | FDI_RX_BIT_LOCK); |
1038 | else | 1271 | DRM_DEBUG("train 1 ok 2!\n"); |
1039 | DRM_DEBUG("train 1 fail\n"); | 1272 | } |
1040 | } else { | 1273 | temp = I915_READ(fdi_tx_reg); |
1041 | I915_WRITE(fdi_rx_iir_reg, | 1274 | temp &= ~FDI_LINK_TRAIN_NONE; |
1042 | temp | FDI_RX_BIT_LOCK); | 1275 | temp |= FDI_LINK_TRAIN_PATTERN_2; |
1043 | DRM_DEBUG("train 1 ok 2!\n"); | 1276 | I915_WRITE(fdi_tx_reg, temp); |
1044 | } | 1277 | |
1045 | temp = I915_READ(fdi_tx_reg); | 1278 | temp = I915_READ(fdi_rx_reg); |
1046 | temp &= ~FDI_LINK_TRAIN_NONE; | 1279 | temp &= ~FDI_LINK_TRAIN_NONE; |
1047 | temp |= FDI_LINK_TRAIN_PATTERN_2; | 1280 | temp |= FDI_LINK_TRAIN_PATTERN_2; |
1048 | I915_WRITE(fdi_tx_reg, temp); | 1281 | I915_WRITE(fdi_rx_reg, temp); |
1049 | |||
1050 | temp = I915_READ(fdi_rx_reg); | ||
1051 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1052 | temp |= FDI_LINK_TRAIN_PATTERN_2; | ||
1053 | I915_WRITE(fdi_rx_reg, temp); | ||
1054 | 1282 | ||
1055 | udelay(150); | 1283 | udelay(150); |
1056 | 1284 | ||
1057 | temp = I915_READ(fdi_rx_iir_reg); | 1285 | temp = I915_READ(fdi_rx_iir_reg); |
1058 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1286 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1059 | 1287 | ||
1060 | if ((temp & FDI_RX_SYMBOL_LOCK) == 0) { | 1288 | if ((temp & FDI_RX_SYMBOL_LOCK) == 0) { |
1061 | for (j = 0; j < tries; j++) { | 1289 | for (j = 0; j < tries; j++) { |
1062 | temp = I915_READ(fdi_rx_iir_reg); | 1290 | temp = I915_READ(fdi_rx_iir_reg); |
1063 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1291 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1064 | if (temp & FDI_RX_SYMBOL_LOCK) | 1292 | if (temp & FDI_RX_SYMBOL_LOCK) |
1065 | break; | 1293 | break; |
1066 | udelay(200); | 1294 | udelay(200); |
1067 | } | 1295 | } |
1068 | if (j != tries) { | 1296 | if (j != tries) { |
1297 | I915_WRITE(fdi_rx_iir_reg, | ||
1298 | temp | FDI_RX_SYMBOL_LOCK); | ||
1299 | DRM_DEBUG("train 2 ok 1!\n"); | ||
1300 | } else | ||
1301 | DRM_DEBUG("train 2 fail\n"); | ||
1302 | } else { | ||
1069 | I915_WRITE(fdi_rx_iir_reg, | 1303 | I915_WRITE(fdi_rx_iir_reg, |
1070 | temp | FDI_RX_SYMBOL_LOCK); | 1304 | temp | FDI_RX_SYMBOL_LOCK); |
1071 | DRM_DEBUG("train 2 ok 1!\n"); | 1305 | DRM_DEBUG("train 2 ok 2!\n"); |
1072 | } else | 1306 | } |
1073 | DRM_DEBUG("train 2 fail\n"); | 1307 | DRM_DEBUG("train done\n"); |
1074 | } else { | ||
1075 | I915_WRITE(fdi_rx_iir_reg, temp | FDI_RX_SYMBOL_LOCK); | ||
1076 | DRM_DEBUG("train 2 ok 2!\n"); | ||
1077 | } | ||
1078 | DRM_DEBUG("train done\n"); | ||
1079 | 1308 | ||
1080 | /* set transcoder timing */ | 1309 | /* set transcoder timing */ |
1081 | I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg)); | 1310 | I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg)); |
1082 | I915_WRITE(trans_hblank_reg, I915_READ(cpu_hblank_reg)); | 1311 | I915_WRITE(trans_hblank_reg, I915_READ(cpu_hblank_reg)); |
1083 | I915_WRITE(trans_hsync_reg, I915_READ(cpu_hsync_reg)); | 1312 | I915_WRITE(trans_hsync_reg, I915_READ(cpu_hsync_reg)); |
1084 | 1313 | ||
1085 | I915_WRITE(trans_vtot_reg, I915_READ(cpu_vtot_reg)); | 1314 | I915_WRITE(trans_vtot_reg, I915_READ(cpu_vtot_reg)); |
1086 | I915_WRITE(trans_vblank_reg, I915_READ(cpu_vblank_reg)); | 1315 | I915_WRITE(trans_vblank_reg, I915_READ(cpu_vblank_reg)); |
1087 | I915_WRITE(trans_vsync_reg, I915_READ(cpu_vsync_reg)); | 1316 | I915_WRITE(trans_vsync_reg, I915_READ(cpu_vsync_reg)); |
1088 | 1317 | ||
1089 | /* enable PCH transcoder */ | 1318 | /* enable PCH transcoder */ |
1090 | temp = I915_READ(transconf_reg); | 1319 | temp = I915_READ(transconf_reg); |
1091 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | 1320 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); |
1092 | I915_READ(transconf_reg); | 1321 | I915_READ(transconf_reg); |
1093 | 1322 | ||
1094 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) | 1323 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) |
1095 | ; | 1324 | ; |
1096 | 1325 | ||
1097 | /* enable normal */ | 1326 | /* enable normal */ |
1098 | 1327 | ||
1099 | temp = I915_READ(fdi_tx_reg); | 1328 | temp = I915_READ(fdi_tx_reg); |
1100 | temp &= ~FDI_LINK_TRAIN_NONE; | 1329 | temp &= ~FDI_LINK_TRAIN_NONE; |
1101 | I915_WRITE(fdi_tx_reg, temp | FDI_LINK_TRAIN_NONE | | 1330 | I915_WRITE(fdi_tx_reg, temp | FDI_LINK_TRAIN_NONE | |
1102 | FDI_TX_ENHANCE_FRAME_ENABLE); | 1331 | FDI_TX_ENHANCE_FRAME_ENABLE); |
1103 | I915_READ(fdi_tx_reg); | 1332 | I915_READ(fdi_tx_reg); |
1104 | 1333 | ||
1105 | temp = I915_READ(fdi_rx_reg); | 1334 | temp = I915_READ(fdi_rx_reg); |
1106 | temp &= ~FDI_LINK_TRAIN_NONE; | 1335 | temp &= ~FDI_LINK_TRAIN_NONE; |
1107 | I915_WRITE(fdi_rx_reg, temp | FDI_LINK_TRAIN_NONE | | 1336 | I915_WRITE(fdi_rx_reg, temp | FDI_LINK_TRAIN_NONE | |
1108 | FDI_RX_ENHANCE_FRAME_ENABLE); | 1337 | FDI_RX_ENHANCE_FRAME_ENABLE); |
1109 | I915_READ(fdi_rx_reg); | 1338 | I915_READ(fdi_rx_reg); |
1110 | 1339 | ||
1111 | /* wait one idle pattern time */ | 1340 | /* wait one idle pattern time */ |
1112 | udelay(100); | 1341 | udelay(100); |
1342 | |||
1343 | } | ||
1113 | 1344 | ||
1114 | intel_crtc_load_lut(crtc); | 1345 | intel_crtc_load_lut(crtc); |
1115 | 1346 | ||
@@ -1117,8 +1348,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1117 | case DRM_MODE_DPMS_OFF: | 1348 | case DRM_MODE_DPMS_OFF: |
1118 | DRM_DEBUG("crtc %d dpms off\n", pipe); | 1349 | DRM_DEBUG("crtc %d dpms off\n", pipe); |
1119 | 1350 | ||
1120 | /* Disable the VGA plane that we never use */ | 1351 | i915_disable_vga(dev); |
1121 | I915_WRITE(CPU_VGACNTRL, VGA_DISP_DISABLE); | ||
1122 | 1352 | ||
1123 | /* Disable display plane */ | 1353 | /* Disable display plane */ |
1124 | temp = I915_READ(dspcntr_reg); | 1354 | temp = I915_READ(dspcntr_reg); |
@@ -1134,17 +1364,23 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1134 | if ((temp & PIPEACONF_ENABLE) != 0) { | 1364 | if ((temp & PIPEACONF_ENABLE) != 0) { |
1135 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); | 1365 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); |
1136 | I915_READ(pipeconf_reg); | 1366 | I915_READ(pipeconf_reg); |
1367 | n = 0; | ||
1137 | /* wait for cpu pipe off, pipe state */ | 1368 | /* wait for cpu pipe off, pipe state */ |
1138 | while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) | 1369 | while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) { |
1139 | ; | 1370 | n++; |
1371 | if (n < 60) { | ||
1372 | udelay(500); | ||
1373 | continue; | ||
1374 | } else { | ||
1375 | DRM_DEBUG("pipe %d off delay\n", pipe); | ||
1376 | break; | ||
1377 | } | ||
1378 | } | ||
1140 | } else | 1379 | } else |
1141 | DRM_DEBUG("crtc %d is disabled\n", pipe); | 1380 | DRM_DEBUG("crtc %d is disabled\n", pipe); |
1142 | 1381 | ||
1143 | /* IGDNG-A : disable cpu panel fitter ? */ | 1382 | if (HAS_eDP) { |
1144 | temp = I915_READ(pf_ctl_reg); | 1383 | igdng_disable_pll_edp(crtc); |
1145 | if ((temp & PF_ENABLE) != 0) { | ||
1146 | I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); | ||
1147 | I915_READ(pf_ctl_reg); | ||
1148 | } | 1384 | } |
1149 | 1385 | ||
1150 | /* disable CPU FDI tx and PCH FDI rx */ | 1386 | /* disable CPU FDI tx and PCH FDI rx */ |
@@ -1156,6 +1392,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1156 | I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE); | 1392 | I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE); |
1157 | I915_READ(fdi_rx_reg); | 1393 | I915_READ(fdi_rx_reg); |
1158 | 1394 | ||
1395 | udelay(100); | ||
1396 | |||
1159 | /* still set train pattern 1 */ | 1397 | /* still set train pattern 1 */ |
1160 | temp = I915_READ(fdi_tx_reg); | 1398 | temp = I915_READ(fdi_tx_reg); |
1161 | temp &= ~FDI_LINK_TRAIN_NONE; | 1399 | temp &= ~FDI_LINK_TRAIN_NONE; |
@@ -1167,14 +1405,25 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1167 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1405 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1168 | I915_WRITE(fdi_rx_reg, temp); | 1406 | I915_WRITE(fdi_rx_reg, temp); |
1169 | 1407 | ||
1408 | udelay(100); | ||
1409 | |||
1170 | /* disable PCH transcoder */ | 1410 | /* disable PCH transcoder */ |
1171 | temp = I915_READ(transconf_reg); | 1411 | temp = I915_READ(transconf_reg); |
1172 | if ((temp & TRANS_ENABLE) != 0) { | 1412 | if ((temp & TRANS_ENABLE) != 0) { |
1173 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); | 1413 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); |
1174 | I915_READ(transconf_reg); | 1414 | I915_READ(transconf_reg); |
1415 | n = 0; | ||
1175 | /* wait for PCH transcoder off, transcoder state */ | 1416 | /* wait for PCH transcoder off, transcoder state */ |
1176 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) | 1417 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) { |
1177 | ; | 1418 | n++; |
1419 | if (n < 60) { | ||
1420 | udelay(500); | ||
1421 | continue; | ||
1422 | } else { | ||
1423 | DRM_DEBUG("transcoder %d off delay\n", pipe); | ||
1424 | break; | ||
1425 | } | ||
1426 | } | ||
1178 | } | 1427 | } |
1179 | 1428 | ||
1180 | /* disable PCH DPLL */ | 1429 | /* disable PCH DPLL */ |
@@ -1192,6 +1441,22 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1192 | I915_READ(fdi_rx_reg); | 1441 | I915_READ(fdi_rx_reg); |
1193 | } | 1442 | } |
1194 | 1443 | ||
1444 | /* Disable CPU FDI TX PLL */ | ||
1445 | temp = I915_READ(fdi_tx_reg); | ||
1446 | if ((temp & FDI_TX_PLL_ENABLE) != 0) { | ||
1447 | I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_PLL_ENABLE); | ||
1448 | I915_READ(fdi_tx_reg); | ||
1449 | udelay(100); | ||
1450 | } | ||
1451 | |||
1452 | /* Disable PF */ | ||
1453 | temp = I915_READ(pf_ctl_reg); | ||
1454 | if ((temp & PF_ENABLE) != 0) { | ||
1455 | I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); | ||
1456 | I915_READ(pf_ctl_reg); | ||
1457 | } | ||
1458 | I915_WRITE(pf_win_size, 0); | ||
1459 | |||
1195 | /* Wait for the clocks to turn off. */ | 1460 | /* Wait for the clocks to turn off. */ |
1196 | udelay(150); | 1461 | udelay(150); |
1197 | break; | 1462 | break; |
@@ -1251,13 +1516,15 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1251 | 1516 | ||
1252 | /* Give the overlay scaler a chance to enable if it's on this pipe */ | 1517 | /* Give the overlay scaler a chance to enable if it's on this pipe */ |
1253 | //intel_crtc_dpms_video(crtc, true); TODO | 1518 | //intel_crtc_dpms_video(crtc, true); TODO |
1519 | intel_update_watermarks(dev); | ||
1254 | break; | 1520 | break; |
1255 | case DRM_MODE_DPMS_OFF: | 1521 | case DRM_MODE_DPMS_OFF: |
1522 | intel_update_watermarks(dev); | ||
1256 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 1523 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
1257 | //intel_crtc_dpms_video(crtc, FALSE); TODO | 1524 | //intel_crtc_dpms_video(crtc, FALSE); TODO |
1258 | 1525 | ||
1259 | /* Disable the VGA plane that we never use */ | 1526 | /* Disable the VGA plane that we never use */ |
1260 | I915_WRITE(VGACNTRL, VGA_DISP_DISABLE); | 1527 | i915_disable_vga(dev); |
1261 | 1528 | ||
1262 | /* Disable display plane */ | 1529 | /* Disable display plane */ |
1263 | temp = I915_READ(dspcntr_reg); | 1530 | temp = I915_READ(dspcntr_reg); |
@@ -1431,7 +1698,6 @@ static int intel_get_core_clock_speed(struct drm_device *dev) | |||
1431 | return 0; /* Silence gcc warning */ | 1698 | return 0; /* Silence gcc warning */ |
1432 | } | 1699 | } |
1433 | 1700 | ||
1434 | |||
1435 | /** | 1701 | /** |
1436 | * Return the pipe currently connected to the panel fitter, | 1702 | * Return the pipe currently connected to the panel fitter, |
1437 | * or -1 if the panel fitter is not present or not in use | 1703 | * or -1 if the panel fitter is not present or not in use |
@@ -1490,7 +1756,7 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes, | |||
1490 | 1756 | ||
1491 | temp = (u64) DATA_N * pixel_clock; | 1757 | temp = (u64) DATA_N * pixel_clock; |
1492 | temp = div_u64(temp, link_clock); | 1758 | temp = div_u64(temp, link_clock); |
1493 | m_n->gmch_m = (temp * bytes_per_pixel) / nlanes; | 1759 | m_n->gmch_m = div_u64(temp * bytes_per_pixel, nlanes); |
1494 | m_n->gmch_n = DATA_N; | 1760 | m_n->gmch_n = DATA_N; |
1495 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | 1761 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
1496 | 1762 | ||
@@ -1501,6 +1767,464 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes, | |||
1501 | } | 1767 | } |
1502 | 1768 | ||
1503 | 1769 | ||
1770 | struct intel_watermark_params { | ||
1771 | unsigned long fifo_size; | ||
1772 | unsigned long max_wm; | ||
1773 | unsigned long default_wm; | ||
1774 | unsigned long guard_size; | ||
1775 | unsigned long cacheline_size; | ||
1776 | }; | ||
1777 | |||
1778 | /* IGD has different values for various configs */ | ||
1779 | static struct intel_watermark_params igd_display_wm = { | ||
1780 | IGD_DISPLAY_FIFO, | ||
1781 | IGD_MAX_WM, | ||
1782 | IGD_DFT_WM, | ||
1783 | IGD_GUARD_WM, | ||
1784 | IGD_FIFO_LINE_SIZE | ||
1785 | }; | ||
1786 | static struct intel_watermark_params igd_display_hplloff_wm = { | ||
1787 | IGD_DISPLAY_FIFO, | ||
1788 | IGD_MAX_WM, | ||
1789 | IGD_DFT_HPLLOFF_WM, | ||
1790 | IGD_GUARD_WM, | ||
1791 | IGD_FIFO_LINE_SIZE | ||
1792 | }; | ||
1793 | static struct intel_watermark_params igd_cursor_wm = { | ||
1794 | IGD_CURSOR_FIFO, | ||
1795 | IGD_CURSOR_MAX_WM, | ||
1796 | IGD_CURSOR_DFT_WM, | ||
1797 | IGD_CURSOR_GUARD_WM, | ||
1798 | IGD_FIFO_LINE_SIZE, | ||
1799 | }; | ||
1800 | static struct intel_watermark_params igd_cursor_hplloff_wm = { | ||
1801 | IGD_CURSOR_FIFO, | ||
1802 | IGD_CURSOR_MAX_WM, | ||
1803 | IGD_CURSOR_DFT_WM, | ||
1804 | IGD_CURSOR_GUARD_WM, | ||
1805 | IGD_FIFO_LINE_SIZE | ||
1806 | }; | ||
1807 | static struct intel_watermark_params i945_wm_info = { | ||
1808 | I945_FIFO_SIZE, | ||
1809 | I915_MAX_WM, | ||
1810 | 1, | ||
1811 | 2, | ||
1812 | I915_FIFO_LINE_SIZE | ||
1813 | }; | ||
1814 | static struct intel_watermark_params i915_wm_info = { | ||
1815 | I915_FIFO_SIZE, | ||
1816 | I915_MAX_WM, | ||
1817 | 1, | ||
1818 | 2, | ||
1819 | I915_FIFO_LINE_SIZE | ||
1820 | }; | ||
1821 | static struct intel_watermark_params i855_wm_info = { | ||
1822 | I855GM_FIFO_SIZE, | ||
1823 | I915_MAX_WM, | ||
1824 | 1, | ||
1825 | 2, | ||
1826 | I830_FIFO_LINE_SIZE | ||
1827 | }; | ||
1828 | static struct intel_watermark_params i830_wm_info = { | ||
1829 | I830_FIFO_SIZE, | ||
1830 | I915_MAX_WM, | ||
1831 | 1, | ||
1832 | 2, | ||
1833 | I830_FIFO_LINE_SIZE | ||
1834 | }; | ||
1835 | |||
1836 | /** | ||
1837 | * intel_calculate_wm - calculate watermark level | ||
1838 | * @clock_in_khz: pixel clock | ||
1839 | * @wm: chip FIFO params | ||
1840 | * @pixel_size: display pixel size | ||
1841 | * @latency_ns: memory latency for the platform | ||
1842 | * | ||
1843 | * Calculate the watermark level (the level at which the display plane will | ||
1844 | * start fetching from memory again). Each chip has a different display | ||
1845 | * FIFO size and allocation, so the caller needs to figure that out and pass | ||
1846 | * in the correct intel_watermark_params structure. | ||
1847 | * | ||
1848 | * As the pixel clock runs, the FIFO will be drained at a rate that depends | ||
1849 | * on the pixel size. When it reaches the watermark level, it'll start | ||
1850 | * fetching FIFO line sized based chunks from memory until the FIFO fills | ||
1851 | * past the watermark point. If the FIFO drains completely, a FIFO underrun | ||
1852 | * will occur, and a display engine hang could result. | ||
1853 | */ | ||
1854 | static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | ||
1855 | struct intel_watermark_params *wm, | ||
1856 | int pixel_size, | ||
1857 | unsigned long latency_ns) | ||
1858 | { | ||
1859 | long entries_required, wm_size; | ||
1860 | |||
1861 | entries_required = (clock_in_khz * pixel_size * latency_ns) / 1000000; | ||
1862 | entries_required /= wm->cacheline_size; | ||
1863 | |||
1864 | DRM_DEBUG("FIFO entries required for mode: %d\n", entries_required); | ||
1865 | |||
1866 | wm_size = wm->fifo_size - (entries_required + wm->guard_size); | ||
1867 | |||
1868 | DRM_DEBUG("FIFO watermark level: %d\n", wm_size); | ||
1869 | |||
1870 | /* Don't promote wm_size to unsigned... */ | ||
1871 | if (wm_size > (long)wm->max_wm) | ||
1872 | wm_size = wm->max_wm; | ||
1873 | if (wm_size <= 0) | ||
1874 | wm_size = wm->default_wm; | ||
1875 | return wm_size; | ||
1876 | } | ||
1877 | |||
1878 | struct cxsr_latency { | ||
1879 | int is_desktop; | ||
1880 | unsigned long fsb_freq; | ||
1881 | unsigned long mem_freq; | ||
1882 | unsigned long display_sr; | ||
1883 | unsigned long display_hpll_disable; | ||
1884 | unsigned long cursor_sr; | ||
1885 | unsigned long cursor_hpll_disable; | ||
1886 | }; | ||
1887 | |||
1888 | static struct cxsr_latency cxsr_latency_table[] = { | ||
1889 | {1, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | ||
1890 | {1, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | ||
1891 | {1, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | ||
1892 | |||
1893 | {1, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ | ||
1894 | {1, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ | ||
1895 | {1, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ | ||
1896 | |||
1897 | {1, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ | ||
1898 | {1, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ | ||
1899 | {1, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ | ||
1900 | |||
1901 | {0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ | ||
1902 | {0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ | ||
1903 | {0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ | ||
1904 | |||
1905 | {0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ | ||
1906 | {0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ | ||
1907 | {0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ | ||
1908 | |||
1909 | {0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ | ||
1910 | {0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ | ||
1911 | {0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ | ||
1912 | }; | ||
1913 | |||
1914 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, | ||
1915 | int mem) | ||
1916 | { | ||
1917 | int i; | ||
1918 | struct cxsr_latency *latency; | ||
1919 | |||
1920 | if (fsb == 0 || mem == 0) | ||
1921 | return NULL; | ||
1922 | |||
1923 | for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { | ||
1924 | latency = &cxsr_latency_table[i]; | ||
1925 | if (is_desktop == latency->is_desktop && | ||
1926 | fsb == latency->fsb_freq && mem == latency->mem_freq) | ||
1927 | break; | ||
1928 | } | ||
1929 | if (i >= ARRAY_SIZE(cxsr_latency_table)) { | ||
1930 | DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n"); | ||
1931 | return NULL; | ||
1932 | } | ||
1933 | return latency; | ||
1934 | } | ||
1935 | |||
1936 | static void igd_disable_cxsr(struct drm_device *dev) | ||
1937 | { | ||
1938 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1939 | u32 reg; | ||
1940 | |||
1941 | /* deactivate cxsr */ | ||
1942 | reg = I915_READ(DSPFW3); | ||
1943 | reg &= ~(IGD_SELF_REFRESH_EN); | ||
1944 | I915_WRITE(DSPFW3, reg); | ||
1945 | DRM_INFO("Big FIFO is disabled\n"); | ||
1946 | } | ||
1947 | |||
1948 | static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock, | ||
1949 | int pixel_size) | ||
1950 | { | ||
1951 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1952 | u32 reg; | ||
1953 | unsigned long wm; | ||
1954 | struct cxsr_latency *latency; | ||
1955 | |||
1956 | latency = intel_get_cxsr_latency(IS_IGDG(dev), dev_priv->fsb_freq, | ||
1957 | dev_priv->mem_freq); | ||
1958 | if (!latency) { | ||
1959 | DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n"); | ||
1960 | igd_disable_cxsr(dev); | ||
1961 | return; | ||
1962 | } | ||
1963 | |||
1964 | /* Display SR */ | ||
1965 | wm = intel_calculate_wm(clock, &igd_display_wm, pixel_size, | ||
1966 | latency->display_sr); | ||
1967 | reg = I915_READ(DSPFW1); | ||
1968 | reg &= 0x7fffff; | ||
1969 | reg |= wm << 23; | ||
1970 | I915_WRITE(DSPFW1, reg); | ||
1971 | DRM_DEBUG("DSPFW1 register is %x\n", reg); | ||
1972 | |||
1973 | /* cursor SR */ | ||
1974 | wm = intel_calculate_wm(clock, &igd_cursor_wm, pixel_size, | ||
1975 | latency->cursor_sr); | ||
1976 | reg = I915_READ(DSPFW3); | ||
1977 | reg &= ~(0x3f << 24); | ||
1978 | reg |= (wm & 0x3f) << 24; | ||
1979 | I915_WRITE(DSPFW3, reg); | ||
1980 | |||
1981 | /* Display HPLL off SR */ | ||
1982 | wm = intel_calculate_wm(clock, &igd_display_hplloff_wm, | ||
1983 | latency->display_hpll_disable, I915_FIFO_LINE_SIZE); | ||
1984 | reg = I915_READ(DSPFW3); | ||
1985 | reg &= 0xfffffe00; | ||
1986 | reg |= wm & 0x1ff; | ||
1987 | I915_WRITE(DSPFW3, reg); | ||
1988 | |||
1989 | /* cursor HPLL off SR */ | ||
1990 | wm = intel_calculate_wm(clock, &igd_cursor_hplloff_wm, pixel_size, | ||
1991 | latency->cursor_hpll_disable); | ||
1992 | reg = I915_READ(DSPFW3); | ||
1993 | reg &= ~(0x3f << 16); | ||
1994 | reg |= (wm & 0x3f) << 16; | ||
1995 | I915_WRITE(DSPFW3, reg); | ||
1996 | DRM_DEBUG("DSPFW3 register is %x\n", reg); | ||
1997 | |||
1998 | /* activate cxsr */ | ||
1999 | reg = I915_READ(DSPFW3); | ||
2000 | reg |= IGD_SELF_REFRESH_EN; | ||
2001 | I915_WRITE(DSPFW3, reg); | ||
2002 | |||
2003 | DRM_INFO("Big FIFO is enabled\n"); | ||
2004 | |||
2005 | return; | ||
2006 | } | ||
2007 | |||
2008 | const static int latency_ns = 3000; /* default for non-igd platforms */ | ||
2009 | |||
2010 | static int intel_get_fifo_size(struct drm_device *dev, int plane) | ||
2011 | { | ||
2012 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2013 | uint32_t dsparb = I915_READ(DSPARB); | ||
2014 | int size; | ||
2015 | |||
2016 | if (IS_I9XX(dev)) { | ||
2017 | if (plane == 0) | ||
2018 | size = dsparb & 0x7f; | ||
2019 | else | ||
2020 | size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - | ||
2021 | (dsparb & 0x7f); | ||
2022 | } else if (IS_I85X(dev)) { | ||
2023 | if (plane == 0) | ||
2024 | size = dsparb & 0x1ff; | ||
2025 | else | ||
2026 | size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - | ||
2027 | (dsparb & 0x1ff); | ||
2028 | size >>= 1; /* Convert to cachelines */ | ||
2029 | } else if (IS_845G(dev)) { | ||
2030 | size = dsparb & 0x7f; | ||
2031 | size >>= 2; /* Convert to cachelines */ | ||
2032 | } else { | ||
2033 | size = dsparb & 0x7f; | ||
2034 | size >>= 1; /* Convert to cachelines */ | ||
2035 | } | ||
2036 | |||
2037 | DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A", | ||
2038 | size); | ||
2039 | |||
2040 | return size; | ||
2041 | } | ||
2042 | |||
2043 | static void i965_update_wm(struct drm_device *dev) | ||
2044 | { | ||
2045 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2046 | |||
2047 | DRM_DEBUG("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR 8\n"); | ||
2048 | |||
2049 | /* 965 has limitations... */ | ||
2050 | I915_WRITE(DSPFW1, (8 << 16) | (8 << 8) | (8 << 0)); | ||
2051 | I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); | ||
2052 | } | ||
2053 | |||
2054 | static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | ||
2055 | int planeb_clock, int sr_hdisplay, int pixel_size) | ||
2056 | { | ||
2057 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2058 | uint32_t fwater_lo; | ||
2059 | uint32_t fwater_hi; | ||
2060 | int total_size, cacheline_size, cwm, srwm = 1; | ||
2061 | int planea_wm, planeb_wm; | ||
2062 | struct intel_watermark_params planea_params, planeb_params; | ||
2063 | unsigned long line_time_us; | ||
2064 | int sr_clock, sr_entries = 0; | ||
2065 | |||
2066 | /* Create copies of the base settings for each pipe */ | ||
2067 | if (IS_I965GM(dev) || IS_I945GM(dev)) | ||
2068 | planea_params = planeb_params = i945_wm_info; | ||
2069 | else if (IS_I9XX(dev)) | ||
2070 | planea_params = planeb_params = i915_wm_info; | ||
2071 | else | ||
2072 | planea_params = planeb_params = i855_wm_info; | ||
2073 | |||
2074 | /* Grab a couple of global values before we overwrite them */ | ||
2075 | total_size = planea_params.fifo_size; | ||
2076 | cacheline_size = planea_params.cacheline_size; | ||
2077 | |||
2078 | /* Update per-plane FIFO sizes */ | ||
2079 | planea_params.fifo_size = intel_get_fifo_size(dev, 0); | ||
2080 | planeb_params.fifo_size = intel_get_fifo_size(dev, 1); | ||
2081 | |||
2082 | planea_wm = intel_calculate_wm(planea_clock, &planea_params, | ||
2083 | pixel_size, latency_ns); | ||
2084 | planeb_wm = intel_calculate_wm(planeb_clock, &planeb_params, | ||
2085 | pixel_size, latency_ns); | ||
2086 | DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); | ||
2087 | |||
2088 | /* | ||
2089 | * Overlay gets an aggressive default since video jitter is bad. | ||
2090 | */ | ||
2091 | cwm = 2; | ||
2092 | |||
2093 | /* Calc sr entries for one plane configs */ | ||
2094 | if (sr_hdisplay && (!planea_clock || !planeb_clock)) { | ||
2095 | /* self-refresh has much higher latency */ | ||
2096 | const static int sr_latency_ns = 6000; | ||
2097 | |||
2098 | sr_clock = planea_clock ? planea_clock : planeb_clock; | ||
2099 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); | ||
2100 | |||
2101 | /* Use ns/us then divide to preserve precision */ | ||
2102 | sr_entries = (((sr_latency_ns / line_time_us) + 1) * | ||
2103 | pixel_size * sr_hdisplay) / 1000; | ||
2104 | sr_entries = roundup(sr_entries / cacheline_size, 1); | ||
2105 | DRM_DEBUG("self-refresh entries: %d\n", sr_entries); | ||
2106 | srwm = total_size - sr_entries; | ||
2107 | if (srwm < 0) | ||
2108 | srwm = 1; | ||
2109 | if (IS_I9XX(dev)) | ||
2110 | I915_WRITE(FW_BLC_SELF, (srwm & 0x3f)); | ||
2111 | } | ||
2112 | |||
2113 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", | ||
2114 | planea_wm, planeb_wm, cwm, srwm); | ||
2115 | |||
2116 | fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f); | ||
2117 | fwater_hi = (cwm & 0x1f); | ||
2118 | |||
2119 | /* Set request length to 8 cachelines per fetch */ | ||
2120 | fwater_lo = fwater_lo | (1 << 24) | (1 << 8); | ||
2121 | fwater_hi = fwater_hi | (1 << 8); | ||
2122 | |||
2123 | I915_WRITE(FW_BLC, fwater_lo); | ||
2124 | I915_WRITE(FW_BLC2, fwater_hi); | ||
2125 | } | ||
2126 | |||
2127 | static void i830_update_wm(struct drm_device *dev, int planea_clock, | ||
2128 | int pixel_size) | ||
2129 | { | ||
2130 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2131 | uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff; | ||
2132 | int planea_wm; | ||
2133 | |||
2134 | i830_wm_info.fifo_size = intel_get_fifo_size(dev, 0); | ||
2135 | |||
2136 | planea_wm = intel_calculate_wm(planea_clock, &i830_wm_info, | ||
2137 | pixel_size, latency_ns); | ||
2138 | fwater_lo |= (3<<8) | planea_wm; | ||
2139 | |||
2140 | DRM_DEBUG("Setting FIFO watermarks - A: %d\n", planea_wm); | ||
2141 | |||
2142 | I915_WRITE(FW_BLC, fwater_lo); | ||
2143 | } | ||
2144 | |||
2145 | /** | ||
2146 | * intel_update_watermarks - update FIFO watermark values based on current modes | ||
2147 | * | ||
2148 | * Calculate watermark values for the various WM regs based on current mode | ||
2149 | * and plane configuration. | ||
2150 | * | ||
2151 | * There are several cases to deal with here: | ||
2152 | * - normal (i.e. non-self-refresh) | ||
2153 | * - self-refresh (SR) mode | ||
2154 | * - lines are large relative to FIFO size (buffer can hold up to 2) | ||
2155 | * - lines are small relative to FIFO size (buffer can hold more than 2 | ||
2156 | * lines), so need to account for TLB latency | ||
2157 | * | ||
2158 | * The normal calculation is: | ||
2159 | * watermark = dotclock * bytes per pixel * latency | ||
2160 | * where latency is platform & configuration dependent (we assume pessimal | ||
2161 | * values here). | ||
2162 | * | ||
2163 | * The SR calculation is: | ||
2164 | * watermark = (trunc(latency/line time)+1) * surface width * | ||
2165 | * bytes per pixel | ||
2166 | * where | ||
2167 | * line time = htotal / dotclock | ||
2168 | * and latency is assumed to be high, as above. | ||
2169 | * | ||
2170 | * The final value programmed to the register should always be rounded up, | ||
2171 | * and include an extra 2 entries to account for clock crossings. | ||
2172 | * | ||
2173 | * We don't use the sprite, so we can ignore that. And on Crestline we have | ||
2174 | * to set the non-SR watermarks to 8. | ||
2175 | */ | ||
2176 | static void intel_update_watermarks(struct drm_device *dev) | ||
2177 | { | ||
2178 | struct drm_crtc *crtc; | ||
2179 | struct intel_crtc *intel_crtc; | ||
2180 | int sr_hdisplay = 0; | ||
2181 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; | ||
2182 | int enabled = 0, pixel_size = 0; | ||
2183 | |||
2184 | if (DSPARB_HWCONTROL(dev)) | ||
2185 | return; | ||
2186 | |||
2187 | /* Get the clock config from both planes */ | ||
2188 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
2189 | intel_crtc = to_intel_crtc(crtc); | ||
2190 | if (crtc->enabled) { | ||
2191 | enabled++; | ||
2192 | if (intel_crtc->plane == 0) { | ||
2193 | DRM_DEBUG("plane A (pipe %d) clock: %d\n", | ||
2194 | intel_crtc->pipe, crtc->mode.clock); | ||
2195 | planea_clock = crtc->mode.clock; | ||
2196 | } else { | ||
2197 | DRM_DEBUG("plane B (pipe %d) clock: %d\n", | ||
2198 | intel_crtc->pipe, crtc->mode.clock); | ||
2199 | planeb_clock = crtc->mode.clock; | ||
2200 | } | ||
2201 | sr_hdisplay = crtc->mode.hdisplay; | ||
2202 | sr_clock = crtc->mode.clock; | ||
2203 | if (crtc->fb) | ||
2204 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
2205 | else | ||
2206 | pixel_size = 4; /* by default */ | ||
2207 | } | ||
2208 | } | ||
2209 | |||
2210 | if (enabled <= 0) | ||
2211 | return; | ||
2212 | |||
2213 | /* Single plane configs can enable self refresh */ | ||
2214 | if (enabled == 1 && IS_IGD(dev)) | ||
2215 | igd_enable_cxsr(dev, sr_clock, pixel_size); | ||
2216 | else if (IS_IGD(dev)) | ||
2217 | igd_disable_cxsr(dev); | ||
2218 | |||
2219 | if (IS_I965G(dev)) | ||
2220 | i965_update_wm(dev); | ||
2221 | else if (IS_I9XX(dev) || IS_MOBILE(dev)) | ||
2222 | i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, | ||
2223 | pixel_size); | ||
2224 | else | ||
2225 | i830_update_wm(dev, planea_clock, pixel_size); | ||
2226 | } | ||
2227 | |||
1504 | static int intel_crtc_mode_set(struct drm_crtc *crtc, | 2228 | static int intel_crtc_mode_set(struct drm_crtc *crtc, |
1505 | struct drm_display_mode *mode, | 2229 | struct drm_display_mode *mode, |
1506 | struct drm_display_mode *adjusted_mode, | 2230 | struct drm_display_mode *adjusted_mode, |
@@ -1529,7 +2253,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1529 | intel_clock_t clock; | 2253 | intel_clock_t clock; |
1530 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; | 2254 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; |
1531 | bool ok, is_sdvo = false, is_dvo = false; | 2255 | bool ok, is_sdvo = false, is_dvo = false; |
1532 | bool is_crt = false, is_lvds = false, is_tv = false; | 2256 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
2257 | bool is_edp = false; | ||
1533 | struct drm_mode_config *mode_config = &dev->mode_config; | 2258 | struct drm_mode_config *mode_config = &dev->mode_config; |
1534 | struct drm_connector *connector; | 2259 | struct drm_connector *connector; |
1535 | const intel_limit_t *limit; | 2260 | const intel_limit_t *limit; |
@@ -1545,6 +2270,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1545 | int lvds_reg = LVDS; | 2270 | int lvds_reg = LVDS; |
1546 | u32 temp; | 2271 | u32 temp; |
1547 | int sdvo_pixel_multiply; | 2272 | int sdvo_pixel_multiply; |
2273 | int target_clock; | ||
1548 | 2274 | ||
1549 | drm_vblank_pre_modeset(dev, pipe); | 2275 | drm_vblank_pre_modeset(dev, pipe); |
1550 | 2276 | ||
@@ -1573,6 +2299,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1573 | case INTEL_OUTPUT_ANALOG: | 2299 | case INTEL_OUTPUT_ANALOG: |
1574 | is_crt = true; | 2300 | is_crt = true; |
1575 | break; | 2301 | break; |
2302 | case INTEL_OUTPUT_DISPLAYPORT: | ||
2303 | is_dp = true; | ||
2304 | break; | ||
2305 | case INTEL_OUTPUT_EDP: | ||
2306 | is_edp = true; | ||
2307 | break; | ||
1576 | } | 2308 | } |
1577 | 2309 | ||
1578 | num_outputs++; | 2310 | num_outputs++; |
@@ -1588,6 +2320,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1588 | } else { | 2320 | } else { |
1589 | refclk = 48000; | 2321 | refclk = 48000; |
1590 | } | 2322 | } |
2323 | |||
1591 | 2324 | ||
1592 | /* | 2325 | /* |
1593 | * Returns a set of divisors for the desired target clock with the given | 2326 | * Returns a set of divisors for the desired target clock with the given |
@@ -1623,11 +2356,29 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1623 | } | 2356 | } |
1624 | 2357 | ||
1625 | /* FDI link */ | 2358 | /* FDI link */ |
1626 | if (IS_IGDNG(dev)) | 2359 | if (IS_IGDNG(dev)) { |
1627 | igdng_compute_m_n(3, 4, /* lane num 4 */ | 2360 | int lane, link_bw; |
1628 | adjusted_mode->clock, | 2361 | /* eDP doesn't require FDI link, so just set DP M/N |
1629 | 270000, /* lane clock */ | 2362 | according to current link config */ |
1630 | &m_n); | 2363 | if (is_edp) { |
2364 | struct drm_connector *edp; | ||
2365 | target_clock = mode->clock; | ||
2366 | edp = intel_pipe_get_output(crtc); | ||
2367 | intel_edp_link_config(to_intel_output(edp), | ||
2368 | &lane, &link_bw); | ||
2369 | } else { | ||
2370 | /* DP over FDI requires target mode clock | ||
2371 | instead of link clock */ | ||
2372 | if (is_dp) | ||
2373 | target_clock = mode->clock; | ||
2374 | else | ||
2375 | target_clock = adjusted_mode->clock; | ||
2376 | lane = 4; | ||
2377 | link_bw = 270000; | ||
2378 | } | ||
2379 | igdng_compute_m_n(3, lane, target_clock, | ||
2380 | link_bw, &m_n); | ||
2381 | } | ||
1631 | 2382 | ||
1632 | if (IS_IGD(dev)) | 2383 | if (IS_IGD(dev)) |
1633 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; | 2384 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; |
@@ -1645,11 +2396,13 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1645 | if (is_sdvo) { | 2396 | if (is_sdvo) { |
1646 | dpll |= DPLL_DVO_HIGH_SPEED; | 2397 | dpll |= DPLL_DVO_HIGH_SPEED; |
1647 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | 2398 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; |
1648 | if (IS_I945G(dev) || IS_I945GM(dev)) | 2399 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) |
1649 | dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; | 2400 | dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; |
1650 | else if (IS_IGDNG(dev)) | 2401 | else if (IS_IGDNG(dev)) |
1651 | dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; | 2402 | dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; |
1652 | } | 2403 | } |
2404 | if (is_dp) | ||
2405 | dpll |= DPLL_DVO_HIGH_SPEED; | ||
1653 | 2406 | ||
1654 | /* compute bitmask from p1 value */ | 2407 | /* compute bitmask from p1 value */ |
1655 | if (IS_IGD(dev)) | 2408 | if (IS_IGD(dev)) |
@@ -1746,29 +2499,15 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1746 | dpll_reg = pch_dpll_reg; | 2499 | dpll_reg = pch_dpll_reg; |
1747 | } | 2500 | } |
1748 | 2501 | ||
1749 | if (dpll & DPLL_VCO_ENABLE) { | 2502 | if (is_edp) { |
2503 | igdng_disable_pll_edp(crtc); | ||
2504 | } else if ((dpll & DPLL_VCO_ENABLE)) { | ||
1750 | I915_WRITE(fp_reg, fp); | 2505 | I915_WRITE(fp_reg, fp); |
1751 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); | 2506 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); |
1752 | I915_READ(dpll_reg); | 2507 | I915_READ(dpll_reg); |
1753 | udelay(150); | 2508 | udelay(150); |
1754 | } | 2509 | } |
1755 | 2510 | ||
1756 | if (IS_IGDNG(dev)) { | ||
1757 | /* enable PCH clock reference source */ | ||
1758 | /* XXX need to change the setting for other outputs */ | ||
1759 | u32 temp; | ||
1760 | temp = I915_READ(PCH_DREF_CONTROL); | ||
1761 | temp &= ~DREF_NONSPREAD_SOURCE_MASK; | ||
1762 | temp |= DREF_NONSPREAD_CK505_ENABLE; | ||
1763 | temp &= ~DREF_SSC_SOURCE_MASK; | ||
1764 | temp |= DREF_SSC_SOURCE_ENABLE; | ||
1765 | temp &= ~DREF_SSC1_ENABLE; | ||
1766 | /* if no eDP, disable source output to CPU */ | ||
1767 | temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; | ||
1768 | temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; | ||
1769 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
1770 | } | ||
1771 | |||
1772 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. | 2511 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
1773 | * This is an exception to the general rule that mode_set doesn't turn | 2512 | * This is an exception to the general rule that mode_set doesn't turn |
1774 | * things on. | 2513 | * things on. |
@@ -1797,24 +2536,28 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1797 | I915_WRITE(lvds_reg, lvds); | 2536 | I915_WRITE(lvds_reg, lvds); |
1798 | I915_READ(lvds_reg); | 2537 | I915_READ(lvds_reg); |
1799 | } | 2538 | } |
2539 | if (is_dp) | ||
2540 | intel_dp_set_m_n(crtc, mode, adjusted_mode); | ||
1800 | 2541 | ||
1801 | I915_WRITE(fp_reg, fp); | 2542 | if (!is_edp) { |
1802 | I915_WRITE(dpll_reg, dpll); | 2543 | I915_WRITE(fp_reg, fp); |
1803 | I915_READ(dpll_reg); | ||
1804 | /* Wait for the clocks to stabilize. */ | ||
1805 | udelay(150); | ||
1806 | |||
1807 | if (IS_I965G(dev) && !IS_IGDNG(dev)) { | ||
1808 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | ||
1809 | I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | | ||
1810 | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); | ||
1811 | } else { | ||
1812 | /* write it again -- the BIOS does, after all */ | ||
1813 | I915_WRITE(dpll_reg, dpll); | 2544 | I915_WRITE(dpll_reg, dpll); |
2545 | I915_READ(dpll_reg); | ||
2546 | /* Wait for the clocks to stabilize. */ | ||
2547 | udelay(150); | ||
2548 | |||
2549 | if (IS_I965G(dev) && !IS_IGDNG(dev)) { | ||
2550 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | ||
2551 | I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | | ||
2552 | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); | ||
2553 | } else { | ||
2554 | /* write it again -- the BIOS does, after all */ | ||
2555 | I915_WRITE(dpll_reg, dpll); | ||
2556 | } | ||
2557 | I915_READ(dpll_reg); | ||
2558 | /* Wait for the clocks to stabilize. */ | ||
2559 | udelay(150); | ||
1814 | } | 2560 | } |
1815 | I915_READ(dpll_reg); | ||
1816 | /* Wait for the clocks to stabilize. */ | ||
1817 | udelay(150); | ||
1818 | 2561 | ||
1819 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | | 2562 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | |
1820 | ((adjusted_mode->crtc_htotal - 1) << 16)); | 2563 | ((adjusted_mode->crtc_htotal - 1) << 16)); |
@@ -1844,10 +2587,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1844 | I915_WRITE(link_m1_reg, m_n.link_m); | 2587 | I915_WRITE(link_m1_reg, m_n.link_m); |
1845 | I915_WRITE(link_n1_reg, m_n.link_n); | 2588 | I915_WRITE(link_n1_reg, m_n.link_n); |
1846 | 2589 | ||
1847 | /* enable FDI RX PLL too */ | 2590 | if (is_edp) { |
1848 | temp = I915_READ(fdi_rx_reg); | 2591 | igdng_set_pll_edp(crtc, adjusted_mode->clock); |
1849 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); | 2592 | } else { |
1850 | udelay(200); | 2593 | /* enable FDI RX PLL too */ |
2594 | temp = I915_READ(fdi_rx_reg); | ||
2595 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); | ||
2596 | udelay(200); | ||
2597 | } | ||
1851 | } | 2598 | } |
1852 | 2599 | ||
1853 | I915_WRITE(pipeconf_reg, pipeconf); | 2600 | I915_WRITE(pipeconf_reg, pipeconf); |
@@ -1859,6 +2606,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1859 | 2606 | ||
1860 | /* Flush the plane changes */ | 2607 | /* Flush the plane changes */ |
1861 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 2608 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
2609 | |||
2610 | intel_update_watermarks(dev); | ||
2611 | |||
1862 | drm_vblank_post_modeset(dev, pipe); | 2612 | drm_vblank_post_modeset(dev, pipe); |
1863 | 2613 | ||
1864 | return ret; | 2614 | return ret; |
@@ -2347,6 +3097,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
2347 | 3097 | ||
2348 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); | 3098 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); |
2349 | intel_crtc->pipe = pipe; | 3099 | intel_crtc->pipe = pipe; |
3100 | intel_crtc->plane = pipe; | ||
2350 | for (i = 0; i < 256; i++) { | 3101 | for (i = 0; i < 256; i++) { |
2351 | intel_crtc->lut_r[i] = i; | 3102 | intel_crtc->lut_r[i] = i; |
2352 | intel_crtc->lut_g[i] = i; | 3103 | intel_crtc->lut_g[i] = i; |
@@ -2419,7 +3170,7 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask) | |||
2419 | 3170 | ||
2420 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 3171 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
2421 | struct intel_output *intel_output = to_intel_output(connector); | 3172 | struct intel_output *intel_output = to_intel_output(connector); |
2422 | if (type_mask & (1 << intel_output->type)) | 3173 | if (type_mask & intel_output->clone_mask) |
2423 | index_mask |= (1 << entry); | 3174 | index_mask |= (1 << entry); |
2424 | entry++; | 3175 | entry++; |
2425 | } | 3176 | } |
@@ -2441,12 +3192,17 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2441 | if (IS_IGDNG(dev)) { | 3192 | if (IS_IGDNG(dev)) { |
2442 | int found; | 3193 | int found; |
2443 | 3194 | ||
3195 | if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED)) | ||
3196 | intel_dp_init(dev, DP_A); | ||
3197 | |||
2444 | if (I915_READ(HDMIB) & PORT_DETECTED) { | 3198 | if (I915_READ(HDMIB) & PORT_DETECTED) { |
2445 | /* check SDVOB */ | 3199 | /* check SDVOB */ |
2446 | /* found = intel_sdvo_init(dev, HDMIB); */ | 3200 | /* found = intel_sdvo_init(dev, HDMIB); */ |
2447 | found = 0; | 3201 | found = 0; |
2448 | if (!found) | 3202 | if (!found) |
2449 | intel_hdmi_init(dev, HDMIB); | 3203 | intel_hdmi_init(dev, HDMIB); |
3204 | if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED)) | ||
3205 | intel_dp_init(dev, PCH_DP_B); | ||
2450 | } | 3206 | } |
2451 | 3207 | ||
2452 | if (I915_READ(HDMIC) & PORT_DETECTED) | 3208 | if (I915_READ(HDMIC) & PORT_DETECTED) |
@@ -2455,27 +3211,39 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2455 | if (I915_READ(HDMID) & PORT_DETECTED) | 3211 | if (I915_READ(HDMID) & PORT_DETECTED) |
2456 | intel_hdmi_init(dev, HDMID); | 3212 | intel_hdmi_init(dev, HDMID); |
2457 | 3213 | ||
3214 | if (I915_READ(PCH_DP_C) & DP_DETECTED) | ||
3215 | intel_dp_init(dev, PCH_DP_C); | ||
3216 | |||
3217 | if (I915_READ(PCH_DP_D) & DP_DETECTED) | ||
3218 | intel_dp_init(dev, PCH_DP_D); | ||
3219 | |||
2458 | } else if (IS_I9XX(dev)) { | 3220 | } else if (IS_I9XX(dev)) { |
2459 | int found; | 3221 | bool found = false; |
2460 | u32 reg; | ||
2461 | 3222 | ||
2462 | if (I915_READ(SDVOB) & SDVO_DETECTED) { | 3223 | if (I915_READ(SDVOB) & SDVO_DETECTED) { |
2463 | found = intel_sdvo_init(dev, SDVOB); | 3224 | found = intel_sdvo_init(dev, SDVOB); |
2464 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) | 3225 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) |
2465 | intel_hdmi_init(dev, SDVOB); | 3226 | intel_hdmi_init(dev, SDVOB); |
3227 | |||
3228 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) | ||
3229 | intel_dp_init(dev, DP_B); | ||
2466 | } | 3230 | } |
2467 | 3231 | ||
2468 | /* Before G4X SDVOC doesn't have its own detect register */ | 3232 | /* Before G4X SDVOC doesn't have its own detect register */ |
2469 | if (IS_G4X(dev)) | ||
2470 | reg = SDVOC; | ||
2471 | else | ||
2472 | reg = SDVOB; | ||
2473 | 3233 | ||
2474 | if (I915_READ(reg) & SDVO_DETECTED) { | 3234 | if (I915_READ(SDVOB) & SDVO_DETECTED) |
2475 | found = intel_sdvo_init(dev, SDVOC); | 3235 | found = intel_sdvo_init(dev, SDVOC); |
2476 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) | 3236 | |
3237 | if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) { | ||
3238 | |||
3239 | if (SUPPORTS_INTEGRATED_HDMI(dev)) | ||
2477 | intel_hdmi_init(dev, SDVOC); | 3240 | intel_hdmi_init(dev, SDVOC); |
3241 | if (SUPPORTS_INTEGRATED_DP(dev)) | ||
3242 | intel_dp_init(dev, DP_C); | ||
2478 | } | 3243 | } |
3244 | |||
3245 | if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) | ||
3246 | intel_dp_init(dev, DP_D); | ||
2479 | } else | 3247 | } else |
2480 | intel_dvo_init(dev); | 3248 | intel_dvo_init(dev); |
2481 | 3249 | ||
@@ -2485,42 +3253,10 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2485 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 3253 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
2486 | struct intel_output *intel_output = to_intel_output(connector); | 3254 | struct intel_output *intel_output = to_intel_output(connector); |
2487 | struct drm_encoder *encoder = &intel_output->enc; | 3255 | struct drm_encoder *encoder = &intel_output->enc; |
2488 | int crtc_mask = 0, clone_mask = 0; | ||
2489 | 3256 | ||
2490 | /* valid crtcs */ | 3257 | encoder->possible_crtcs = intel_output->crtc_mask; |
2491 | switch(intel_output->type) { | 3258 | encoder->possible_clones = intel_connector_clones(dev, |
2492 | case INTEL_OUTPUT_HDMI: | 3259 | intel_output->clone_mask); |
2493 | crtc_mask = ((1 << 0)| | ||
2494 | (1 << 1)); | ||
2495 | clone_mask = ((1 << INTEL_OUTPUT_HDMI)); | ||
2496 | break; | ||
2497 | case INTEL_OUTPUT_DVO: | ||
2498 | case INTEL_OUTPUT_SDVO: | ||
2499 | crtc_mask = ((1 << 0)| | ||
2500 | (1 << 1)); | ||
2501 | clone_mask = ((1 << INTEL_OUTPUT_ANALOG) | | ||
2502 | (1 << INTEL_OUTPUT_DVO) | | ||
2503 | (1 << INTEL_OUTPUT_SDVO)); | ||
2504 | break; | ||
2505 | case INTEL_OUTPUT_ANALOG: | ||
2506 | crtc_mask = ((1 << 0)| | ||
2507 | (1 << 1)); | ||
2508 | clone_mask = ((1 << INTEL_OUTPUT_ANALOG) | | ||
2509 | (1 << INTEL_OUTPUT_DVO) | | ||
2510 | (1 << INTEL_OUTPUT_SDVO)); | ||
2511 | break; | ||
2512 | case INTEL_OUTPUT_LVDS: | ||
2513 | crtc_mask = (1 << 1); | ||
2514 | clone_mask = (1 << INTEL_OUTPUT_LVDS); | ||
2515 | break; | ||
2516 | case INTEL_OUTPUT_TVOUT: | ||
2517 | crtc_mask = ((1 << 0) | | ||
2518 | (1 << 1)); | ||
2519 | clone_mask = (1 << INTEL_OUTPUT_TVOUT); | ||
2520 | break; | ||
2521 | } | ||
2522 | encoder->possible_crtcs = crtc_mask; | ||
2523 | encoder->possible_clones = intel_connector_clones(dev, clone_mask); | ||
2524 | } | 3260 | } |
2525 | } | 3261 | } |
2526 | 3262 | ||
@@ -2627,6 +3363,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
2627 | if (IS_I965G(dev)) { | 3363 | if (IS_I965G(dev)) { |
2628 | dev->mode_config.max_width = 8192; | 3364 | dev->mode_config.max_width = 8192; |
2629 | dev->mode_config.max_height = 8192; | 3365 | dev->mode_config.max_height = 8192; |
3366 | } else if (IS_I9XX(dev)) { | ||
3367 | dev->mode_config.max_width = 4096; | ||
3368 | dev->mode_config.max_height = 4096; | ||
2630 | } else { | 3369 | } else { |
2631 | dev->mode_config.max_width = 2048; | 3370 | dev->mode_config.max_width = 2048; |
2632 | dev->mode_config.max_height = 2048; | 3371 | dev->mode_config.max_height = 2048; |