aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c356
1 files changed, 234 insertions, 122 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 002612fae717..b27202d23ebc 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -70,8 +70,6 @@ struct intel_limit {
70 intel_p2_t p2; 70 intel_p2_t p2;
71 bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, 71 bool (* find_pll)(const intel_limit_t *, struct drm_crtc *,
72 int, int, intel_clock_t *); 72 int, int, intel_clock_t *);
73 bool (* find_reduced_pll)(const intel_limit_t *, struct drm_crtc *,
74 int, int, intel_clock_t *);
75}; 73};
76 74
77#define I8XX_DOT_MIN 25000 75#define I8XX_DOT_MIN 25000
@@ -242,41 +240,91 @@ struct intel_limit {
242#define IRONLAKE_DOT_MAX 350000 240#define IRONLAKE_DOT_MAX 350000
243#define IRONLAKE_VCO_MIN 1760000 241#define IRONLAKE_VCO_MIN 1760000
244#define IRONLAKE_VCO_MAX 3510000 242#define IRONLAKE_VCO_MAX 3510000
245#define IRONLAKE_N_MIN 1
246#define IRONLAKE_N_MAX 5
247#define IRONLAKE_M_MIN 79
248#define IRONLAKE_M_MAX 118
249#define IRONLAKE_M1_MIN 12 243#define IRONLAKE_M1_MIN 12
250#define IRONLAKE_M1_MAX 23 244#define IRONLAKE_M1_MAX 22
251#define IRONLAKE_M2_MIN 5 245#define IRONLAKE_M2_MIN 5
252#define IRONLAKE_M2_MAX 9 246#define IRONLAKE_M2_MAX 9
253#define IRONLAKE_P_SDVO_DAC_MIN 5
254#define IRONLAKE_P_SDVO_DAC_MAX 80
255#define IRONLAKE_P_LVDS_MIN 28
256#define IRONLAKE_P_LVDS_MAX 112
257#define IRONLAKE_P1_MIN 1
258#define IRONLAKE_P1_MAX 8
259#define IRONLAKE_P2_SDVO_DAC_SLOW 10
260#define IRONLAKE_P2_SDVO_DAC_FAST 5
261#define IRONLAKE_P2_LVDS_SLOW 14 /* single channel */
262#define IRONLAKE_P2_LVDS_FAST 7 /* double channel */
263#define IRONLAKE_P2_DOT_LIMIT 225000 /* 225Mhz */ 247#define IRONLAKE_P2_DOT_LIMIT 225000 /* 225Mhz */
264 248
265#define IRONLAKE_P_DISPLAY_PORT_MIN 10 249/* We have parameter ranges for different type of outputs. */
266#define IRONLAKE_P_DISPLAY_PORT_MAX 20 250
267#define IRONLAKE_P2_DISPLAY_PORT_FAST 10 251/* DAC & HDMI Refclk 120Mhz */
268#define IRONLAKE_P2_DISPLAY_PORT_SLOW 10 252#define IRONLAKE_DAC_N_MIN 1
269#define IRONLAKE_P2_DISPLAY_PORT_LIMIT 0 253#define IRONLAKE_DAC_N_MAX 5
270#define IRONLAKE_P1_DISPLAY_PORT_MIN 1 254#define IRONLAKE_DAC_M_MIN 79
271#define IRONLAKE_P1_DISPLAY_PORT_MAX 2 255#define IRONLAKE_DAC_M_MAX 127
256#define IRONLAKE_DAC_P_MIN 5
257#define IRONLAKE_DAC_P_MAX 80
258#define IRONLAKE_DAC_P1_MIN 1
259#define IRONLAKE_DAC_P1_MAX 8
260#define IRONLAKE_DAC_P2_SLOW 10
261#define IRONLAKE_DAC_P2_FAST 5
262
263/* LVDS single-channel 120Mhz refclk */
264#define IRONLAKE_LVDS_S_N_MIN 1
265#define IRONLAKE_LVDS_S_N_MAX 3
266#define IRONLAKE_LVDS_S_M_MIN 79
267#define IRONLAKE_LVDS_S_M_MAX 118
268#define IRONLAKE_LVDS_S_P_MIN 28
269#define IRONLAKE_LVDS_S_P_MAX 112
270#define IRONLAKE_LVDS_S_P1_MIN 2
271#define IRONLAKE_LVDS_S_P1_MAX 8
272#define IRONLAKE_LVDS_S_P2_SLOW 14
273#define IRONLAKE_LVDS_S_P2_FAST 14
274
275/* LVDS dual-channel 120Mhz refclk */
276#define IRONLAKE_LVDS_D_N_MIN 1
277#define IRONLAKE_LVDS_D_N_MAX 3
278#define IRONLAKE_LVDS_D_M_MIN 79
279#define IRONLAKE_LVDS_D_M_MAX 127
280#define IRONLAKE_LVDS_D_P_MIN 14
281#define IRONLAKE_LVDS_D_P_MAX 56
282#define IRONLAKE_LVDS_D_P1_MIN 2
283#define IRONLAKE_LVDS_D_P1_MAX 8
284#define IRONLAKE_LVDS_D_P2_SLOW 7
285#define IRONLAKE_LVDS_D_P2_FAST 7
286
287/* LVDS single-channel 100Mhz refclk */
288#define IRONLAKE_LVDS_S_SSC_N_MIN 1
289#define IRONLAKE_LVDS_S_SSC_N_MAX 2
290#define IRONLAKE_LVDS_S_SSC_M_MIN 79
291#define IRONLAKE_LVDS_S_SSC_M_MAX 126
292#define IRONLAKE_LVDS_S_SSC_P_MIN 28
293#define IRONLAKE_LVDS_S_SSC_P_MAX 112
294#define IRONLAKE_LVDS_S_SSC_P1_MIN 2
295#define IRONLAKE_LVDS_S_SSC_P1_MAX 8
296#define IRONLAKE_LVDS_S_SSC_P2_SLOW 14
297#define IRONLAKE_LVDS_S_SSC_P2_FAST 14
298
299/* LVDS dual-channel 100Mhz refclk */
300#define IRONLAKE_LVDS_D_SSC_N_MIN 1
301#define IRONLAKE_LVDS_D_SSC_N_MAX 3
302#define IRONLAKE_LVDS_D_SSC_M_MIN 79
303#define IRONLAKE_LVDS_D_SSC_M_MAX 126
304#define IRONLAKE_LVDS_D_SSC_P_MIN 14
305#define IRONLAKE_LVDS_D_SSC_P_MAX 42
306#define IRONLAKE_LVDS_D_SSC_P1_MIN 2
307#define IRONLAKE_LVDS_D_SSC_P1_MAX 6
308#define IRONLAKE_LVDS_D_SSC_P2_SLOW 7
309#define IRONLAKE_LVDS_D_SSC_P2_FAST 7
310
311/* DisplayPort */
312#define IRONLAKE_DP_N_MIN 1
313#define IRONLAKE_DP_N_MAX 2
314#define IRONLAKE_DP_M_MIN 81
315#define IRONLAKE_DP_M_MAX 90
316#define IRONLAKE_DP_P_MIN 10
317#define IRONLAKE_DP_P_MAX 20
318#define IRONLAKE_DP_P2_FAST 10
319#define IRONLAKE_DP_P2_SLOW 10
320#define IRONLAKE_DP_P2_LIMIT 0
321#define IRONLAKE_DP_P1_MIN 1
322#define IRONLAKE_DP_P1_MAX 2
272 323
273static bool 324static bool
274intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, 325intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
275 int target, int refclk, intel_clock_t *best_clock); 326 int target, int refclk, intel_clock_t *best_clock);
276static bool 327static bool
277intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
278 int target, int refclk, intel_clock_t *best_clock);
279static bool
280intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, 328intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
281 int target, int refclk, intel_clock_t *best_clock); 329 int target, int refclk, intel_clock_t *best_clock);
282 330
@@ -299,7 +347,6 @@ static const intel_limit_t intel_limits_i8xx_dvo = {
299 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, 347 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
300 .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, 348 .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST },
301 .find_pll = intel_find_best_PLL, 349 .find_pll = intel_find_best_PLL,
302 .find_reduced_pll = intel_find_best_reduced_PLL,
303}; 350};
304 351
305static const intel_limit_t intel_limits_i8xx_lvds = { 352static const intel_limit_t intel_limits_i8xx_lvds = {
@@ -314,7 +361,6 @@ static const intel_limit_t intel_limits_i8xx_lvds = {
314 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, 361 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
315 .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, 362 .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST },
316 .find_pll = intel_find_best_PLL, 363 .find_pll = intel_find_best_PLL,
317 .find_reduced_pll = intel_find_best_reduced_PLL,
318}; 364};
319 365
320static const intel_limit_t intel_limits_i9xx_sdvo = { 366static const intel_limit_t intel_limits_i9xx_sdvo = {
@@ -329,7 +375,6 @@ static const intel_limit_t intel_limits_i9xx_sdvo = {
329 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, 375 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
330 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, 376 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
331 .find_pll = intel_find_best_PLL, 377 .find_pll = intel_find_best_PLL,
332 .find_reduced_pll = intel_find_best_reduced_PLL,
333}; 378};
334 379
335static const intel_limit_t intel_limits_i9xx_lvds = { 380static const intel_limit_t intel_limits_i9xx_lvds = {
@@ -347,7 +392,6 @@ static const intel_limit_t intel_limits_i9xx_lvds = {
347 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, 392 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
348 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, 393 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST },
349 .find_pll = intel_find_best_PLL, 394 .find_pll = intel_find_best_PLL,
350 .find_reduced_pll = intel_find_best_reduced_PLL,
351}; 395};
352 396
353 /* below parameter and function is for G4X Chipset Family*/ 397 /* below parameter and function is for G4X Chipset Family*/
@@ -365,7 +409,6 @@ static const intel_limit_t intel_limits_g4x_sdvo = {
365 .p2_fast = G4X_P2_SDVO_FAST 409 .p2_fast = G4X_P2_SDVO_FAST
366 }, 410 },
367 .find_pll = intel_g4x_find_best_PLL, 411 .find_pll = intel_g4x_find_best_PLL,
368 .find_reduced_pll = intel_g4x_find_best_PLL,
369}; 412};
370 413
371static const intel_limit_t intel_limits_g4x_hdmi = { 414static const intel_limit_t intel_limits_g4x_hdmi = {
@@ -382,7 +425,6 @@ static const intel_limit_t intel_limits_g4x_hdmi = {
382 .p2_fast = G4X_P2_HDMI_DAC_FAST 425 .p2_fast = G4X_P2_HDMI_DAC_FAST
383 }, 426 },
384 .find_pll = intel_g4x_find_best_PLL, 427 .find_pll = intel_g4x_find_best_PLL,
385 .find_reduced_pll = intel_g4x_find_best_PLL,
386}; 428};
387 429
388static const intel_limit_t intel_limits_g4x_single_channel_lvds = { 430static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
@@ -407,7 +449,6 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
407 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST 449 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST
408 }, 450 },
409 .find_pll = intel_g4x_find_best_PLL, 451 .find_pll = intel_g4x_find_best_PLL,
410 .find_reduced_pll = intel_g4x_find_best_PLL,
411}; 452};
412 453
413static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { 454static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
@@ -432,7 +473,6 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
432 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST 473 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST
433 }, 474 },
434 .find_pll = intel_g4x_find_best_PLL, 475 .find_pll = intel_g4x_find_best_PLL,
435 .find_reduced_pll = intel_g4x_find_best_PLL,
436}; 476};
437 477
438static const intel_limit_t intel_limits_g4x_display_port = { 478static const intel_limit_t intel_limits_g4x_display_port = {
@@ -470,7 +510,6 @@ static const intel_limit_t intel_limits_pineview_sdvo = {
470 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, 510 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
471 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, 511 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
472 .find_pll = intel_find_best_PLL, 512 .find_pll = intel_find_best_PLL,
473 .find_reduced_pll = intel_find_best_reduced_PLL,
474}; 513};
475 514
476static const intel_limit_t intel_limits_pineview_lvds = { 515static const intel_limit_t intel_limits_pineview_lvds = {
@@ -486,36 +525,80 @@ static const intel_limit_t intel_limits_pineview_lvds = {
486 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, 525 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
487 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, 526 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW },
488 .find_pll = intel_find_best_PLL, 527 .find_pll = intel_find_best_PLL,
489 .find_reduced_pll = intel_find_best_reduced_PLL,
490}; 528};
491 529
492static const intel_limit_t intel_limits_ironlake_sdvo = { 530static const intel_limit_t intel_limits_ironlake_dac = {
531 .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX },
532 .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX },
533 .n = { .min = IRONLAKE_DAC_N_MIN, .max = IRONLAKE_DAC_N_MAX },
534 .m = { .min = IRONLAKE_DAC_M_MIN, .max = IRONLAKE_DAC_M_MAX },
535 .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX },
536 .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX },
537 .p = { .min = IRONLAKE_DAC_P_MIN, .max = IRONLAKE_DAC_P_MAX },
538 .p1 = { .min = IRONLAKE_DAC_P1_MIN, .max = IRONLAKE_DAC_P1_MAX },
539 .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
540 .p2_slow = IRONLAKE_DAC_P2_SLOW,
541 .p2_fast = IRONLAKE_DAC_P2_FAST },
542 .find_pll = intel_g4x_find_best_PLL,
543};
544
545static const intel_limit_t intel_limits_ironlake_single_lvds = {
546 .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX },
547 .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX },
548 .n = { .min = IRONLAKE_LVDS_S_N_MIN, .max = IRONLAKE_LVDS_S_N_MAX },
549 .m = { .min = IRONLAKE_LVDS_S_M_MIN, .max = IRONLAKE_LVDS_S_M_MAX },
550 .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX },
551 .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX },
552 .p = { .min = IRONLAKE_LVDS_S_P_MIN, .max = IRONLAKE_LVDS_S_P_MAX },
553 .p1 = { .min = IRONLAKE_LVDS_S_P1_MIN, .max = IRONLAKE_LVDS_S_P1_MAX },
554 .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
555 .p2_slow = IRONLAKE_LVDS_S_P2_SLOW,
556 .p2_fast = IRONLAKE_LVDS_S_P2_FAST },
557 .find_pll = intel_g4x_find_best_PLL,
558};
559
560static const intel_limit_t intel_limits_ironlake_dual_lvds = {
561 .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX },
562 .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX },
563 .n = { .min = IRONLAKE_LVDS_D_N_MIN, .max = IRONLAKE_LVDS_D_N_MAX },
564 .m = { .min = IRONLAKE_LVDS_D_M_MIN, .max = IRONLAKE_LVDS_D_M_MAX },
565 .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX },
566 .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX },
567 .p = { .min = IRONLAKE_LVDS_D_P_MIN, .max = IRONLAKE_LVDS_D_P_MAX },
568 .p1 = { .min = IRONLAKE_LVDS_D_P1_MIN, .max = IRONLAKE_LVDS_D_P1_MAX },
569 .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
570 .p2_slow = IRONLAKE_LVDS_D_P2_SLOW,
571 .p2_fast = IRONLAKE_LVDS_D_P2_FAST },
572 .find_pll = intel_g4x_find_best_PLL,
573};
574
575static const intel_limit_t intel_limits_ironlake_single_lvds_100m = {
493 .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, 576 .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX },
494 .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, 577 .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX },
495 .n = { .min = IRONLAKE_N_MIN, .max = IRONLAKE_N_MAX }, 578 .n = { .min = IRONLAKE_LVDS_S_SSC_N_MIN, .max = IRONLAKE_LVDS_S_SSC_N_MAX },
496 .m = { .min = IRONLAKE_M_MIN, .max = IRONLAKE_M_MAX }, 579 .m = { .min = IRONLAKE_LVDS_S_SSC_M_MIN, .max = IRONLAKE_LVDS_S_SSC_M_MAX },
497 .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, 580 .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX },
498 .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, 581 .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX },
499 .p = { .min = IRONLAKE_P_SDVO_DAC_MIN, .max = IRONLAKE_P_SDVO_DAC_MAX }, 582 .p = { .min = IRONLAKE_LVDS_S_SSC_P_MIN, .max = IRONLAKE_LVDS_S_SSC_P_MAX },
500 .p1 = { .min = IRONLAKE_P1_MIN, .max = IRONLAKE_P1_MAX }, 583 .p1 = { .min = IRONLAKE_LVDS_S_SSC_P1_MIN,.max = IRONLAKE_LVDS_S_SSC_P1_MAX },
501 .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, 584 .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
502 .p2_slow = IRONLAKE_P2_SDVO_DAC_SLOW, 585 .p2_slow = IRONLAKE_LVDS_S_SSC_P2_SLOW,
503 .p2_fast = IRONLAKE_P2_SDVO_DAC_FAST }, 586 .p2_fast = IRONLAKE_LVDS_S_SSC_P2_FAST },
504 .find_pll = intel_g4x_find_best_PLL, 587 .find_pll = intel_g4x_find_best_PLL,
505}; 588};
506 589
507static const intel_limit_t intel_limits_ironlake_lvds = { 590static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = {
508 .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, 591 .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX },
509 .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, 592 .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX },
510 .n = { .min = IRONLAKE_N_MIN, .max = IRONLAKE_N_MAX }, 593 .n = { .min = IRONLAKE_LVDS_D_SSC_N_MIN, .max = IRONLAKE_LVDS_D_SSC_N_MAX },
511 .m = { .min = IRONLAKE_M_MIN, .max = IRONLAKE_M_MAX }, 594 .m = { .min = IRONLAKE_LVDS_D_SSC_M_MIN, .max = IRONLAKE_LVDS_D_SSC_M_MAX },
512 .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, 595 .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX },
513 .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, 596 .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX },
514 .p = { .min = IRONLAKE_P_LVDS_MIN, .max = IRONLAKE_P_LVDS_MAX }, 597 .p = { .min = IRONLAKE_LVDS_D_SSC_P_MIN, .max = IRONLAKE_LVDS_D_SSC_P_MAX },
515 .p1 = { .min = IRONLAKE_P1_MIN, .max = IRONLAKE_P1_MAX }, 598 .p1 = { .min = IRONLAKE_LVDS_D_SSC_P1_MIN,.max = IRONLAKE_LVDS_D_SSC_P1_MAX },
516 .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, 599 .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
517 .p2_slow = IRONLAKE_P2_LVDS_SLOW, 600 .p2_slow = IRONLAKE_LVDS_D_SSC_P2_SLOW,
518 .p2_fast = IRONLAKE_P2_LVDS_FAST }, 601 .p2_fast = IRONLAKE_LVDS_D_SSC_P2_FAST },
519 .find_pll = intel_g4x_find_best_PLL, 602 .find_pll = intel_g4x_find_best_PLL,
520}; 603};
521 604
@@ -524,34 +607,53 @@ static const intel_limit_t intel_limits_ironlake_display_port = {
524 .max = IRONLAKE_DOT_MAX }, 607 .max = IRONLAKE_DOT_MAX },
525 .vco = { .min = IRONLAKE_VCO_MIN, 608 .vco = { .min = IRONLAKE_VCO_MIN,
526 .max = IRONLAKE_VCO_MAX}, 609 .max = IRONLAKE_VCO_MAX},
527 .n = { .min = IRONLAKE_N_MIN, 610 .n = { .min = IRONLAKE_DP_N_MIN,
528 .max = IRONLAKE_N_MAX }, 611 .max = IRONLAKE_DP_N_MAX },
529 .m = { .min = IRONLAKE_M_MIN, 612 .m = { .min = IRONLAKE_DP_M_MIN,
530 .max = IRONLAKE_M_MAX }, 613 .max = IRONLAKE_DP_M_MAX },
531 .m1 = { .min = IRONLAKE_M1_MIN, 614 .m1 = { .min = IRONLAKE_M1_MIN,
532 .max = IRONLAKE_M1_MAX }, 615 .max = IRONLAKE_M1_MAX },
533 .m2 = { .min = IRONLAKE_M2_MIN, 616 .m2 = { .min = IRONLAKE_M2_MIN,
534 .max = IRONLAKE_M2_MAX }, 617 .max = IRONLAKE_M2_MAX },
535 .p = { .min = IRONLAKE_P_DISPLAY_PORT_MIN, 618 .p = { .min = IRONLAKE_DP_P_MIN,
536 .max = IRONLAKE_P_DISPLAY_PORT_MAX }, 619 .max = IRONLAKE_DP_P_MAX },
537 .p1 = { .min = IRONLAKE_P1_DISPLAY_PORT_MIN, 620 .p1 = { .min = IRONLAKE_DP_P1_MIN,
538 .max = IRONLAKE_P1_DISPLAY_PORT_MAX}, 621 .max = IRONLAKE_DP_P1_MAX},
539 .p2 = { .dot_limit = IRONLAKE_P2_DISPLAY_PORT_LIMIT, 622 .p2 = { .dot_limit = IRONLAKE_DP_P2_LIMIT,
540 .p2_slow = IRONLAKE_P2_DISPLAY_PORT_SLOW, 623 .p2_slow = IRONLAKE_DP_P2_SLOW,
541 .p2_fast = IRONLAKE_P2_DISPLAY_PORT_FAST }, 624 .p2_fast = IRONLAKE_DP_P2_FAST },
542 .find_pll = intel_find_pll_ironlake_dp, 625 .find_pll = intel_find_pll_ironlake_dp,
543}; 626};
544 627
545static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc) 628static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc)
546{ 629{
630 struct drm_device *dev = crtc->dev;
631 struct drm_i915_private *dev_priv = dev->dev_private;
547 const intel_limit_t *limit; 632 const intel_limit_t *limit;
548 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) 633 int refclk = 120;
549 limit = &intel_limits_ironlake_lvds; 634
550 else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || 635 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
636 if (dev_priv->lvds_use_ssc && dev_priv->lvds_ssc_freq == 100)
637 refclk = 100;
638
639 if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) ==
640 LVDS_CLKB_POWER_UP) {
641 /* LVDS dual channel */
642 if (refclk == 100)
643 limit = &intel_limits_ironlake_dual_lvds_100m;
644 else
645 limit = &intel_limits_ironlake_dual_lvds;
646 } else {
647 if (refclk == 100)
648 limit = &intel_limits_ironlake_single_lvds_100m;
649 else
650 limit = &intel_limits_ironlake_single_lvds;
651 }
652 } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
551 HAS_eDP) 653 HAS_eDP)
552 limit = &intel_limits_ironlake_display_port; 654 limit = &intel_limits_ironlake_display_port;
553 else 655 else
554 limit = &intel_limits_ironlake_sdvo; 656 limit = &intel_limits_ironlake_dac;
555 657
556 return limit; 658 return limit;
557} 659}
@@ -768,46 +870,6 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
768 return (err != target); 870 return (err != target);
769} 871}
770 872
771
772static bool
773intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
774 int target, int refclk, intel_clock_t *best_clock)
775
776{
777 struct drm_device *dev = crtc->dev;
778 intel_clock_t clock;
779 int err = target;
780 bool found = false;
781
782 memcpy(&clock, best_clock, sizeof(intel_clock_t));
783
784 for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
785 for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
786 /* m1 is always 0 in Pineview */
787 if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev))
788 break;
789 for (clock.n = limit->n.min; clock.n <= limit->n.max;
790 clock.n++) {
791 int this_err;
792
793 intel_clock(dev, refclk, &clock);
794
795 if (!intel_PLL_is_valid(crtc, &clock))
796 continue;
797
798 this_err = abs(clock.dot - target);
799 if (this_err < err) {
800 *best_clock = clock;
801 err = this_err;
802 found = true;
803 }
804 }
805 }
806 }
807
808 return found;
809}
810
811static bool 873static bool
812intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, 874intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
813 int target, int refclk, intel_clock_t *best_clock) 875 int target, int refclk, intel_clock_t *best_clock)
@@ -969,6 +1031,8 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
969 1031
970 /* enable it... */ 1032 /* enable it... */
971 fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC; 1033 fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC;
1034 if (IS_I945GM(dev))
1035 fbc_ctl |= FBC_C3_IDLE; /* 945 needs special SR handling */
972 fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; 1036 fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT;
973 fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; 1037 fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
974 if (obj_priv->tiling_mode != I915_TILING_NONE) 1038 if (obj_priv->tiling_mode != I915_TILING_NONE)
@@ -1262,7 +1326,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
1262 return ret; 1326 return ret;
1263 } 1327 }
1264 1328
1265 ret = i915_gem_object_set_to_gtt_domain(obj, 1); 1329 ret = i915_gem_object_set_to_display_plane(obj);
1266 if (ret != 0) { 1330 if (ret != 0) {
1267 i915_gem_object_unpin(obj); 1331 i915_gem_object_unpin(obj);
1268 mutex_unlock(&dev->struct_mutex); 1332 mutex_unlock(&dev->struct_mutex);
@@ -1693,6 +1757,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
1693 case DRM_MODE_DPMS_OFF: 1757 case DRM_MODE_DPMS_OFF:
1694 DRM_DEBUG_KMS("crtc %d dpms off\n", pipe); 1758 DRM_DEBUG_KMS("crtc %d dpms off\n", pipe);
1695 1759
1760 drm_vblank_off(dev, pipe);
1696 /* Disable display plane */ 1761 /* Disable display plane */
1697 temp = I915_READ(dspcntr_reg); 1762 temp = I915_READ(dspcntr_reg);
1698 if ((temp & DISPLAY_PLANE_ENABLE) != 0) { 1763 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
@@ -2574,6 +2639,10 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock,
2574 sr_entries = roundup(sr_entries / cacheline_size, 1); 2639 sr_entries = roundup(sr_entries / cacheline_size, 1);
2575 DRM_DEBUG("self-refresh entries: %d\n", sr_entries); 2640 DRM_DEBUG("self-refresh entries: %d\n", sr_entries);
2576 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); 2641 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
2642 } else {
2643 /* Turn off self refresh if both pipes are enabled */
2644 I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
2645 & ~FW_BLC_SELF_EN);
2577 } 2646 }
2578 2647
2579 DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n", 2648 DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n",
@@ -2617,6 +2686,10 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock,
2617 srwm = 1; 2686 srwm = 1;
2618 srwm &= 0x3f; 2687 srwm &= 0x3f;
2619 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); 2688 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
2689 } else {
2690 /* Turn off self refresh if both pipes are enabled */
2691 I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
2692 & ~FW_BLC_SELF_EN);
2620 } 2693 }
2621 2694
2622 DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", 2695 DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n",
@@ -2685,6 +2758,10 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
2685 if (srwm < 0) 2758 if (srwm < 0)
2686 srwm = 1; 2759 srwm = 1;
2687 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f)); 2760 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f));
2761 } else {
2762 /* Turn off self refresh if both pipes are enabled */
2763 I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
2764 & ~FW_BLC_SELF_EN);
2688 } 2765 }
2689 2766
2690 DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", 2767 DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
@@ -2910,10 +2987,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2910 return -EINVAL; 2987 return -EINVAL;
2911 } 2988 }
2912 2989
2913 if (is_lvds && limit->find_reduced_pll && 2990 if (is_lvds && dev_priv->lvds_downclock_avail) {
2914 dev_priv->lvds_downclock_avail) { 2991 has_reduced_clock = limit->find_pll(limit, crtc,
2915 memcpy(&reduced_clock, &clock, sizeof(intel_clock_t));
2916 has_reduced_clock = limit->find_reduced_pll(limit, crtc,
2917 dev_priv->lvds_downclock, 2992 dev_priv->lvds_downclock,
2918 refclk, 2993 refclk,
2919 &reduced_clock); 2994 &reduced_clock);
@@ -2981,6 +3056,21 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2981 temp |= PIPE_8BPC; 3056 temp |= PIPE_8BPC;
2982 else 3057 else
2983 temp |= PIPE_6BPC; 3058 temp |= PIPE_6BPC;
3059 } else if (is_edp) {
3060 switch (dev_priv->edp_bpp/3) {
3061 case 8:
3062 temp |= PIPE_8BPC;
3063 break;
3064 case 10:
3065 temp |= PIPE_10BPC;
3066 break;
3067 case 6:
3068 temp |= PIPE_6BPC;
3069 break;
3070 case 12:
3071 temp |= PIPE_12BPC;
3072 break;
3073 }
2984 } else 3074 } else
2985 temp |= PIPE_8BPC; 3075 temp |= PIPE_8BPC;
2986 I915_WRITE(pipeconf_reg, temp); 3076 I915_WRITE(pipeconf_reg, temp);
@@ -3991,7 +4081,8 @@ static void intel_crtc_destroy(struct drm_crtc *crtc)
3991struct intel_unpin_work { 4081struct intel_unpin_work {
3992 struct work_struct work; 4082 struct work_struct work;
3993 struct drm_device *dev; 4083 struct drm_device *dev;
3994 struct drm_gem_object *obj; 4084 struct drm_gem_object *old_fb_obj;
4085 struct drm_gem_object *pending_flip_obj;
3995 struct drm_pending_vblank_event *event; 4086 struct drm_pending_vblank_event *event;
3996 int pending; 4087 int pending;
3997}; 4088};
@@ -4002,8 +4093,9 @@ static void intel_unpin_work_fn(struct work_struct *__work)
4002 container_of(__work, struct intel_unpin_work, work); 4093 container_of(__work, struct intel_unpin_work, work);
4003 4094
4004 mutex_lock(&work->dev->struct_mutex); 4095 mutex_lock(&work->dev->struct_mutex);
4005 i915_gem_object_unpin(work->obj); 4096 i915_gem_object_unpin(work->old_fb_obj);
4006 drm_gem_object_unreference(work->obj); 4097 drm_gem_object_unreference(work->pending_flip_obj);
4098 drm_gem_object_unreference(work->old_fb_obj);
4007 mutex_unlock(&work->dev->struct_mutex); 4099 mutex_unlock(&work->dev->struct_mutex);
4008 kfree(work); 4100 kfree(work);
4009} 4101}
@@ -4026,6 +4118,12 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
4026 spin_lock_irqsave(&dev->event_lock, flags); 4118 spin_lock_irqsave(&dev->event_lock, flags);
4027 work = intel_crtc->unpin_work; 4119 work = intel_crtc->unpin_work;
4028 if (work == NULL || !work->pending) { 4120 if (work == NULL || !work->pending) {
4121 if (work && !work->pending) {
4122 obj_priv = work->pending_flip_obj->driver_private;
4123 DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n",
4124 obj_priv,
4125 atomic_read(&obj_priv->pending_flip));
4126 }
4029 spin_unlock_irqrestore(&dev->event_lock, flags); 4127 spin_unlock_irqrestore(&dev->event_lock, flags);
4030 return; 4128 return;
4031 } 4129 }
@@ -4046,8 +4144,11 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
4046 4144
4047 spin_unlock_irqrestore(&dev->event_lock, flags); 4145 spin_unlock_irqrestore(&dev->event_lock, flags);
4048 4146
4049 obj_priv = work->obj->driver_private; 4147 obj_priv = work->pending_flip_obj->driver_private;
4050 if (atomic_dec_and_test(&obj_priv->pending_flip)) 4148
4149 /* Initial scanout buffer will have a 0 pending flip count */
4150 if ((atomic_read(&obj_priv->pending_flip) == 0) ||
4151 atomic_dec_and_test(&obj_priv->pending_flip))
4051 DRM_WAKEUP(&dev_priv->pending_flip_queue); 4152 DRM_WAKEUP(&dev_priv->pending_flip_queue);
4052 schedule_work(&work->work); 4153 schedule_work(&work->work);
4053} 4154}
@@ -4060,8 +4161,11 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane)
4060 unsigned long flags; 4161 unsigned long flags;
4061 4162
4062 spin_lock_irqsave(&dev->event_lock, flags); 4163 spin_lock_irqsave(&dev->event_lock, flags);
4063 if (intel_crtc->unpin_work) 4164 if (intel_crtc->unpin_work) {
4064 intel_crtc->unpin_work->pending = 1; 4165 intel_crtc->unpin_work->pending = 1;
4166 } else {
4167 DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n");
4168 }
4065 spin_unlock_irqrestore(&dev->event_lock, flags); 4169 spin_unlock_irqrestore(&dev->event_lock, flags);
4066} 4170}
4067 4171
@@ -4077,7 +4181,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4077 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 4181 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
4078 struct intel_unpin_work *work; 4182 struct intel_unpin_work *work;
4079 unsigned long flags; 4183 unsigned long flags;
4080 int ret; 4184 int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
4185 int ret, pipesrc;
4081 RING_LOCALS; 4186 RING_LOCALS;
4082 4187
4083 work = kzalloc(sizeof *work, GFP_KERNEL); 4188 work = kzalloc(sizeof *work, GFP_KERNEL);
@@ -4089,12 +4194,13 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4089 work->event = event; 4194 work->event = event;
4090 work->dev = crtc->dev; 4195 work->dev = crtc->dev;
4091 intel_fb = to_intel_framebuffer(crtc->fb); 4196 intel_fb = to_intel_framebuffer(crtc->fb);
4092 work->obj = intel_fb->obj; 4197 work->old_fb_obj = intel_fb->obj;
4093 INIT_WORK(&work->work, intel_unpin_work_fn); 4198 INIT_WORK(&work->work, intel_unpin_work_fn);
4094 4199
4095 /* We borrow the event spin lock for protecting unpin_work */ 4200 /* We borrow the event spin lock for protecting unpin_work */
4096 spin_lock_irqsave(&dev->event_lock, flags); 4201 spin_lock_irqsave(&dev->event_lock, flags);
4097 if (intel_crtc->unpin_work) { 4202 if (intel_crtc->unpin_work) {
4203 DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
4098 spin_unlock_irqrestore(&dev->event_lock, flags); 4204 spin_unlock_irqrestore(&dev->event_lock, flags);
4099 kfree(work); 4205 kfree(work);
4100 mutex_unlock(&dev->struct_mutex); 4206 mutex_unlock(&dev->struct_mutex);
@@ -4108,19 +4214,24 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4108 4214
4109 ret = intel_pin_and_fence_fb_obj(dev, obj); 4215 ret = intel_pin_and_fence_fb_obj(dev, obj);
4110 if (ret != 0) { 4216 if (ret != 0) {
4217 DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
4218 obj->driver_private);
4111 kfree(work); 4219 kfree(work);
4220 intel_crtc->unpin_work = NULL;
4112 mutex_unlock(&dev->struct_mutex); 4221 mutex_unlock(&dev->struct_mutex);
4113 return ret; 4222 return ret;
4114 } 4223 }
4115 4224
4116 /* Reference the old fb object for the scheduled work. */ 4225 /* Reference the objects for the scheduled work. */
4117 drm_gem_object_reference(work->obj); 4226 drm_gem_object_reference(work->old_fb_obj);
4227 drm_gem_object_reference(obj);
4118 4228
4119 crtc->fb = fb; 4229 crtc->fb = fb;
4120 i915_gem_object_flush_write_domain(obj); 4230 i915_gem_object_flush_write_domain(obj);
4121 drm_vblank_get(dev, intel_crtc->pipe); 4231 drm_vblank_get(dev, intel_crtc->pipe);
4122 obj_priv = obj->driver_private; 4232 obj_priv = obj->driver_private;
4123 atomic_inc(&obj_priv->pending_flip); 4233 atomic_inc(&obj_priv->pending_flip);
4234 work->pending_flip_obj = obj;
4124 4235
4125 BEGIN_LP_RING(4); 4236 BEGIN_LP_RING(4);
4126 OUT_RING(MI_DISPLAY_FLIP | 4237 OUT_RING(MI_DISPLAY_FLIP |
@@ -4128,7 +4239,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
4128 OUT_RING(fb->pitch); 4239 OUT_RING(fb->pitch);
4129 if (IS_I965G(dev)) { 4240 if (IS_I965G(dev)) {
4130 OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); 4241 OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
4131 OUT_RING((fb->width << 16) | fb->height); 4242 pipesrc = I915_READ(pipesrc_reg);
4243 OUT_RING(pipesrc & 0x0fff0fff);
4132 } else { 4244 } else {
4133 OUT_RING(obj_priv->gtt_offset); 4245 OUT_RING(obj_priv->gtt_offset);
4134 OUT_RING(MI_NOOP); 4246 OUT_RING(MI_NOOP);