Rev 2360 | Rev 3037 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2360 | Rev 3031 | ||
---|---|---|---|
Line 30... | Line 30... | ||
30 | #include |
30 | #include |
31 | #include |
31 | #include |
32 | #include |
32 | #include |
33 | //#include |
33 | //#include |
34 | #include |
34 | #include |
35 | #include "drmP.h" |
35 | #include |
36 | #include "intel_drv.h" |
36 | #include "intel_drv.h" |
37 | #include "i915_drm.h" |
37 | #include |
38 | #include "i915_drv.h" |
38 | #include "i915_drv.h" |
39 | #include "i915_trace.h" |
39 | #include "i915_trace.h" |
40 | #include "drm_dp_helper.h" |
40 | #include |
41 | #include "drm_crtc_helper.h" |
41 | #include |
- | 42 | //#include |
|
Line 42... | Line 43... | ||
42 | 43 | ||
Line 43... | Line 44... | ||
43 | phys_addr_t get_bus_addr(void); |
44 | phys_addr_t get_bus_addr(void); |
44 | 45 | ||
Line 61... | Line 62... | ||
61 | { |
62 | { |
62 | return (void *) error; |
63 | return (void *) error; |
63 | } |
64 | } |
Line 64... | Line -... | ||
64 | - | ||
65 | - | ||
66 | static inline int pci_read_config_word(struct pci_dev *dev, int where, |
- | |
67 | u16 *val) |
- | |
68 | { |
- | |
69 | *val = PciRead16(dev->busnr, dev->devfn, where); |
- | |
70 | return 1; |
- | |
71 | } |
- | |
72 | 65 | ||
Line 73... | Line 66... | ||
73 | 66 | ||
74 | #define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) |
- | |
75 | 67 | #define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) |
|
76 | bool intel_pipe_has_type(struct drm_crtc *crtc, int type); |
68 | |
Line 77... | Line 69... | ||
77 | static void intel_update_watermarks(struct drm_device *dev); |
69 | bool intel_pipe_has_type(struct drm_crtc *crtc, int type); |
78 | static void intel_increase_pllclock(struct drm_crtc *crtc); |
70 | static void intel_increase_pllclock(struct drm_crtc *crtc); |
79 | static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); |
71 | //static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); |
80 | 72 | ||
Line 103... | Line 95... | ||
103 | typedef struct intel_limit intel_limit_t; |
95 | typedef struct intel_limit intel_limit_t; |
104 | struct intel_limit { |
96 | struct intel_limit { |
105 | intel_range_t dot, vco, n, m, m1, m2, p, p1; |
97 | intel_range_t dot, vco, n, m, m1, m2, p, p1; |
106 | intel_p2_t p2; |
98 | intel_p2_t p2; |
107 | bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, |
99 | bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, |
108 | int, int, intel_clock_t *); |
100 | int, int, intel_clock_t *, intel_clock_t *); |
109 | }; |
101 | }; |
Line 110... | Line 102... | ||
110 | 102 | ||
111 | /* FDI */ |
103 | /* FDI */ |
Line 112... | Line 104... | ||
112 | #define IRONLAKE_FDI_FREQ 2700000 /* in kHz for mode->clock */ |
104 | #define IRONLAKE_FDI_FREQ 2700000 /* in kHz for mode->clock */ |
113 | 105 | ||
114 | static bool |
106 | static bool |
- | 107 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
|
115 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
108 | int target, int refclk, intel_clock_t *match_clock, |
116 | int target, int refclk, intel_clock_t *best_clock); |
109 | intel_clock_t *best_clock); |
117 | static bool |
110 | static bool |
- | 111 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
|
Line 118... | Line 112... | ||
118 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
112 | int target, int refclk, intel_clock_t *match_clock, |
119 | int target, int refclk, intel_clock_t *best_clock); |
113 | intel_clock_t *best_clock); |
120 | 114 | ||
- | 115 | static bool |
|
121 | static bool |
116 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, |
122 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, |
117 | int target, int refclk, intel_clock_t *match_clock, |
123 | int target, int refclk, intel_clock_t *best_clock); |
118 | intel_clock_t *best_clock); |
- | 119 | static bool |
|
- | 120 | intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, |
|
- | 121 | int target, int refclk, intel_clock_t *match_clock, |
|
- | 122 | intel_clock_t *best_clock); |
|
- | 123 | ||
- | 124 | static bool |
|
Line 124... | Line 125... | ||
124 | static bool |
125 | intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, |
125 | intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, |
126 | int target, int refclk, intel_clock_t *match_clock, |
126 | int target, int refclk, intel_clock_t *best_clock); |
127 | intel_clock_t *best_clock); |
127 | 128 | ||
Line 384... | Line 385... | ||
384 | .p2 = { .dot_limit = 0, |
385 | .p2 = { .dot_limit = 0, |
385 | .p2_slow = 10, .p2_fast = 10 }, |
386 | .p2_slow = 10, .p2_fast = 10 }, |
386 | .find_pll = intel_find_pll_ironlake_dp, |
387 | .find_pll = intel_find_pll_ironlake_dp, |
387 | }; |
388 | }; |
Line -... | Line 389... | ||
- | 389 | ||
- | 390 | static const intel_limit_t intel_limits_vlv_dac = { |
|
- | 391 | .dot = { .min = 25000, .max = 270000 }, |
|
- | 392 | .vco = { .min = 4000000, .max = 6000000 }, |
|
- | 393 | .n = { .min = 1, .max = 7 }, |
|
- | 394 | .m = { .min = 22, .max = 450 }, /* guess */ |
|
- | 395 | .m1 = { .min = 2, .max = 3 }, |
|
- | 396 | .m2 = { .min = 11, .max = 156 }, |
|
- | 397 | .p = { .min = 10, .max = 30 }, |
|
- | 398 | .p1 = { .min = 2, .max = 3 }, |
|
- | 399 | .p2 = { .dot_limit = 270000, |
|
- | 400 | .p2_slow = 2, .p2_fast = 20 }, |
|
- | 401 | .find_pll = intel_vlv_find_best_pll, |
|
- | 402 | }; |
|
- | 403 | ||
- | 404 | static const intel_limit_t intel_limits_vlv_hdmi = { |
|
- | 405 | .dot = { .min = 20000, .max = 165000 }, |
|
- | 406 | .vco = { .min = 5994000, .max = 4000000 }, |
|
- | 407 | .n = { .min = 1, .max = 7 }, |
|
- | 408 | .m = { .min = 60, .max = 300 }, /* guess */ |
|
- | 409 | .m1 = { .min = 2, .max = 3 }, |
|
- | 410 | .m2 = { .min = 11, .max = 156 }, |
|
- | 411 | .p = { .min = 10, .max = 30 }, |
|
- | 412 | .p1 = { .min = 2, .max = 3 }, |
|
- | 413 | .p2 = { .dot_limit = 270000, |
|
- | 414 | .p2_slow = 2, .p2_fast = 20 }, |
|
- | 415 | .find_pll = intel_vlv_find_best_pll, |
|
- | 416 | }; |
|
- | 417 | ||
- | 418 | static const intel_limit_t intel_limits_vlv_dp = { |
|
- | 419 | .dot = { .min = 162000, .max = 270000 }, |
|
- | 420 | .vco = { .min = 5994000, .max = 4000000 }, |
|
- | 421 | .n = { .min = 1, .max = 7 }, |
|
- | 422 | .m = { .min = 60, .max = 300 }, /* guess */ |
|
- | 423 | .m1 = { .min = 2, .max = 3 }, |
|
- | 424 | .m2 = { .min = 11, .max = 156 }, |
|
- | 425 | .p = { .min = 10, .max = 30 }, |
|
- | 426 | .p1 = { .min = 2, .max = 3 }, |
|
- | 427 | .p2 = { .dot_limit = 270000, |
|
- | 428 | .p2_slow = 2, .p2_fast = 20 }, |
|
- | 429 | .find_pll = intel_vlv_find_best_pll, |
|
- | 430 | }; |
|
- | 431 | ||
- | 432 | u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg) |
|
- | 433 | { |
|
- | 434 | unsigned long flags; |
|
- | 435 | u32 val = 0; |
|
- | 436 | ||
- | 437 | spin_lock_irqsave(&dev_priv->dpio_lock, flags); |
|
- | 438 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { |
|
- | 439 | DRM_ERROR("DPIO idle wait timed out\n"); |
|
- | 440 | goto out_unlock; |
|
- | 441 | } |
|
- | 442 | ||
- | 443 | I915_WRITE(DPIO_REG, reg); |
|
- | 444 | I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_READ | DPIO_PORTID | |
|
- | 445 | DPIO_BYTE); |
|
- | 446 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { |
|
- | 447 | DRM_ERROR("DPIO read wait timed out\n"); |
|
- | 448 | goto out_unlock; |
|
- | 449 | } |
|
- | 450 | val = I915_READ(DPIO_DATA); |
|
- | 451 | ||
- | 452 | out_unlock: |
|
- | 453 | spin_unlock_irqrestore(&dev_priv->dpio_lock, flags); |
|
- | 454 | return val; |
|
- | 455 | } |
|
- | 456 | ||
- | 457 | static void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, |
|
- | 458 | u32 val) |
|
- | 459 | { |
|
- | 460 | unsigned long flags; |
|
- | 461 | ||
- | 462 | spin_lock_irqsave(&dev_priv->dpio_lock, flags); |
|
- | 463 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { |
|
- | 464 | DRM_ERROR("DPIO idle wait timed out\n"); |
|
- | 465 | goto out_unlock; |
|
- | 466 | } |
|
- | 467 | ||
- | 468 | I915_WRITE(DPIO_DATA, val); |
|
- | 469 | I915_WRITE(DPIO_REG, reg); |
|
- | 470 | I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_WRITE | DPIO_PORTID | |
|
- | 471 | DPIO_BYTE); |
|
- | 472 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) |
|
- | 473 | DRM_ERROR("DPIO write wait timed out\n"); |
|
- | 474 | ||
- | 475 | out_unlock: |
|
- | 476 | spin_unlock_irqrestore(&dev_priv->dpio_lock, flags); |
|
- | 477 | } |
|
- | 478 | ||
- | 479 | static void vlv_init_dpio(struct drm_device *dev) |
|
- | 480 | { |
|
- | 481 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 482 | ||
- | 483 | /* Reset the DPIO config */ |
|
- | 484 | I915_WRITE(DPIO_CTL, 0); |
|
- | 485 | POSTING_READ(DPIO_CTL); |
|
- | 486 | I915_WRITE(DPIO_CTL, 1); |
|
- | 487 | POSTING_READ(DPIO_CTL); |
|
- | 488 | } |
|
- | 489 | ||
- | 490 | static int intel_dual_link_lvds_callback(const struct dmi_system_id *id) |
|
- | 491 | { |
|
- | 492 | DRM_INFO("Forcing lvds to dual link mode on %s\n", id->ident); |
|
- | 493 | return 1; |
|
- | 494 | } |
|
- | 495 | ||
- | 496 | static const struct dmi_system_id intel_dual_link_lvds[] = { |
|
- | 497 | { |
|
- | 498 | .callback = intel_dual_link_lvds_callback, |
|
- | 499 | .ident = "Apple MacBook Pro (Core i5/i7 Series)", |
|
- | 500 | .matches = { |
|
- | 501 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), |
|
- | 502 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro8,2"), |
|
- | 503 | }, |
|
- | 504 | }, |
|
- | 505 | { } /* terminating entry */ |
|
- | 506 | }; |
|
- | 507 | ||
- | 508 | static bool is_dual_link_lvds(struct drm_i915_private *dev_priv, |
|
- | 509 | unsigned int reg) |
|
- | 510 | { |
|
- | 511 | unsigned int val; |
|
- | 512 | ||
- | 513 | /* use the module option value if specified */ |
|
- | 514 | if (i915_lvds_channel_mode > 0) |
|
- | 515 | return i915_lvds_channel_mode == 2; |
|
- | 516 | ||
- | 517 | // if (dmi_check_system(intel_dual_link_lvds)) |
|
- | 518 | // return true; |
|
- | 519 | ||
- | 520 | if (dev_priv->lvds_val) |
|
- | 521 | val = dev_priv->lvds_val; |
|
- | 522 | else { |
|
- | 523 | /* BIOS should set the proper LVDS register value at boot, but |
|
- | 524 | * in reality, it doesn't set the value when the lid is closed; |
|
- | 525 | * we need to check "the value to be set" in VBT when LVDS |
|
- | 526 | * register is uninitialized. |
|
- | 527 | */ |
|
- | 528 | val = I915_READ(reg); |
|
- | 529 | if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED))) |
|
- | 530 | val = dev_priv->bios_lvds_val; |
|
- | 531 | dev_priv->lvds_val = val; |
|
- | 532 | } |
|
- | 533 | return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP; |
|
- | 534 | } |
|
388 | 535 | ||
389 | static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, |
536 | static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, |
390 | int refclk) |
537 | int refclk) |
391 | { |
538 | { |
392 | struct drm_device *dev = crtc->dev; |
539 | struct drm_device *dev = crtc->dev; |
393 | struct drm_i915_private *dev_priv = dev->dev_private; |
540 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 394... | Line 541... | ||
394 | const intel_limit_t *limit; |
541 | const intel_limit_t *limit; |
395 | 542 | ||
396 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
- | |
397 | if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == |
543 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
398 | LVDS_CLKB_POWER_UP) { |
544 | if (is_dual_link_lvds(dev_priv, PCH_LVDS)) { |
399 | /* LVDS dual channel */ |
545 | /* LVDS dual channel */ |
400 | if (refclk == 100000) |
546 | if (refclk == 100000) |
401 | limit = &intel_limits_ironlake_dual_lvds_100m; |
547 | limit = &intel_limits_ironlake_dual_lvds_100m; |
Line 421... | Line 567... | ||
421 | struct drm_device *dev = crtc->dev; |
567 | struct drm_device *dev = crtc->dev; |
422 | struct drm_i915_private *dev_priv = dev->dev_private; |
568 | struct drm_i915_private *dev_priv = dev->dev_private; |
423 | const intel_limit_t *limit; |
569 | const intel_limit_t *limit; |
Line 424... | Line 570... | ||
424 | 570 | ||
425 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
571 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
426 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == |
- | |
427 | LVDS_CLKB_POWER_UP) |
572 | if (is_dual_link_lvds(dev_priv, LVDS)) |
428 | /* LVDS with dual channel */ |
573 | /* LVDS with dual channel */ |
429 | limit = &intel_limits_g4x_dual_channel_lvds; |
574 | limit = &intel_limits_g4x_dual_channel_lvds; |
430 | else |
575 | else |
431 | /* LVDS with dual channel */ |
576 | /* LVDS with dual channel */ |
Line 455... | Line 600... | ||
455 | } else if (IS_PINEVIEW(dev)) { |
600 | } else if (IS_PINEVIEW(dev)) { |
456 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
601 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
457 | limit = &intel_limits_pineview_lvds; |
602 | limit = &intel_limits_pineview_lvds; |
458 | else |
603 | else |
459 | limit = &intel_limits_pineview_sdvo; |
604 | limit = &intel_limits_pineview_sdvo; |
- | 605 | } else if (IS_VALLEYVIEW(dev)) { |
|
- | 606 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) |
|
- | 607 | limit = &intel_limits_vlv_dac; |
|
- | 608 | else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) |
|
- | 609 | limit = &intel_limits_vlv_hdmi; |
|
- | 610 | else |
|
- | 611 | limit = &intel_limits_vlv_dp; |
|
460 | } else if (!IS_GEN2(dev)) { |
612 | } else if (!IS_GEN2(dev)) { |
461 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
613 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
462 | limit = &intel_limits_i9xx_lvds; |
614 | limit = &intel_limits_i9xx_lvds; |
463 | else |
615 | else |
464 | limit = &intel_limits_i9xx_sdvo; |
616 | limit = &intel_limits_i9xx_sdvo; |
Line 496... | Line 648... | ||
496 | * Returns whether any output on the specified pipe is of the specified type |
648 | * Returns whether any output on the specified pipe is of the specified type |
497 | */ |
649 | */ |
498 | bool intel_pipe_has_type(struct drm_crtc *crtc, int type) |
650 | bool intel_pipe_has_type(struct drm_crtc *crtc, int type) |
499 | { |
651 | { |
500 | struct drm_device *dev = crtc->dev; |
652 | struct drm_device *dev = crtc->dev; |
501 | struct drm_mode_config *mode_config = &dev->mode_config; |
- | |
502 | struct intel_encoder *encoder; |
653 | struct intel_encoder *encoder; |
Line 503... | Line 654... | ||
503 | 654 | ||
504 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) |
655 | for_each_encoder_on_crtc(dev, crtc, encoder) |
505 | if (encoder->base.crtc == crtc && encoder->type == type) |
656 | if (encoder->type == type) |
Line 506... | Line 657... | ||
506 | return true; |
657 | return true; |
507 | 658 | ||
Line 543... | Line 694... | ||
543 | return true; |
694 | return true; |
544 | } |
695 | } |
Line 545... | Line 696... | ||
545 | 696 | ||
546 | static bool |
697 | static bool |
547 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
698 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
- | 699 | int target, int refclk, intel_clock_t *match_clock, |
|
Line 548... | Line 700... | ||
548 | int target, int refclk, intel_clock_t *best_clock) |
700 | intel_clock_t *best_clock) |
549 | 701 | ||
550 | { |
702 | { |
551 | struct drm_device *dev = crtc->dev; |
703 | struct drm_device *dev = crtc->dev; |
Line 559... | Line 711... | ||
559 | * For LVDS, if the panel is on, just rely on its current |
711 | * For LVDS, if the panel is on, just rely on its current |
560 | * settings for dual-channel. We haven't figured out how to |
712 | * settings for dual-channel. We haven't figured out how to |
561 | * reliably set up different single/dual channel state, if we |
713 | * reliably set up different single/dual channel state, if we |
562 | * even can. |
714 | * even can. |
563 | */ |
715 | */ |
564 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == |
716 | if (is_dual_link_lvds(dev_priv, LVDS)) |
565 | LVDS_CLKB_POWER_UP) |
- | |
566 | clock.p2 = limit->p2.p2_fast; |
717 | clock.p2 = limit->p2.p2_fast; |
567 | else |
718 | else |
568 | clock.p2 = limit->p2.p2_slow; |
719 | clock.p2 = limit->p2.p2_slow; |
569 | } else { |
720 | } else { |
570 | if (target < limit->p2.dot_limit) |
721 | if (target < limit->p2.dot_limit) |
Line 590... | Line 741... | ||
590 | 741 | ||
591 | intel_clock(dev, refclk, &clock); |
742 | intel_clock(dev, refclk, &clock); |
592 | if (!intel_PLL_is_valid(dev, limit, |
743 | if (!intel_PLL_is_valid(dev, limit, |
593 | &clock)) |
744 | &clock)) |
- | 745 | continue; |
|
- | 746 | if (match_clock && |
|
- | 747 | clock.p != match_clock->p) |
|
Line 594... | Line 748... | ||
594 | continue; |
748 | continue; |
595 | 749 | ||
596 | this_err = abs(clock.dot - target); |
750 | this_err = abs(clock.dot - target); |
597 | if (this_err < err) { |
751 | if (this_err < err) { |
Line 606... | Line 760... | ||
606 | return (err != target); |
760 | return (err != target); |
607 | } |
761 | } |
Line 608... | Line 762... | ||
608 | 762 | ||
609 | static bool |
763 | static bool |
610 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
764 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
- | 765 | int target, int refclk, intel_clock_t *match_clock, |
|
611 | int target, int refclk, intel_clock_t *best_clock) |
766 | intel_clock_t *best_clock) |
612 | { |
767 | { |
613 | struct drm_device *dev = crtc->dev; |
768 | struct drm_device *dev = crtc->dev; |
614 | struct drm_i915_private *dev_priv = dev->dev_private; |
769 | struct drm_i915_private *dev_priv = dev->dev_private; |
615 | intel_clock_t clock; |
770 | intel_clock_t clock; |
Line 653... | Line 808... | ||
653 | 808 | ||
654 | intel_clock(dev, refclk, &clock); |
809 | intel_clock(dev, refclk, &clock); |
655 | if (!intel_PLL_is_valid(dev, limit, |
810 | if (!intel_PLL_is_valid(dev, limit, |
656 | &clock)) |
811 | &clock)) |
- | 812 | continue; |
|
- | 813 | if (match_clock && |
|
- | 814 | clock.p != match_clock->p) |
|
Line 657... | Line 815... | ||
657 | continue; |
815 | continue; |
658 | 816 | ||
659 | this_err = abs(clock.dot - target); |
817 | this_err = abs(clock.dot - target); |
660 | if (this_err < err_most) { |
818 | if (this_err < err_most) { |
Line 670... | Line 828... | ||
670 | return found; |
828 | return found; |
671 | } |
829 | } |
Line 672... | Line 830... | ||
672 | 830 | ||
673 | static bool |
831 | static bool |
674 | intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, |
832 | intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, |
- | 833 | int target, int refclk, intel_clock_t *match_clock, |
|
675 | int target, int refclk, intel_clock_t *best_clock) |
834 | intel_clock_t *best_clock) |
676 | { |
835 | { |
677 | struct drm_device *dev = crtc->dev; |
836 | struct drm_device *dev = crtc->dev; |
Line 678... | Line 837... | ||
678 | intel_clock_t clock; |
837 | intel_clock_t clock; |
Line 696... | Line 855... | ||
696 | } |
855 | } |
Line 697... | Line 856... | ||
697 | 856 | ||
698 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ |
857 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ |
699 | static bool |
858 | static bool |
700 | intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, |
859 | intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, |
- | 860 | int target, int refclk, intel_clock_t *match_clock, |
|
701 | int target, int refclk, intel_clock_t *best_clock) |
861 | intel_clock_t *best_clock) |
702 | { |
862 | { |
703 | intel_clock_t clock; |
863 | intel_clock_t clock; |
704 | if (target < 200000) { |
864 | if (target < 200000) { |
705 | clock.p1 = 2; |
865 | clock.p1 = 2; |
Line 719... | Line 879... | ||
719 | clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; |
879 | clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; |
720 | clock.vco = 0; |
880 | clock.vco = 0; |
721 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); |
881 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); |
722 | return true; |
882 | return true; |
723 | } |
883 | } |
- | 884 | static bool |
|
- | 885 | intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, |
|
- | 886 | int target, int refclk, intel_clock_t *match_clock, |
|
- | 887 | intel_clock_t *best_clock) |
|
- | 888 | { |
|
- | 889 | u32 p1, p2, m1, m2, vco, bestn, bestm1, bestm2, bestp1, bestp2; |
|
- | 890 | u32 m, n, fastclk; |
|
- | 891 | u32 updrate, minupdate, fracbits, p; |
|
- | 892 | unsigned long bestppm, ppm, absppm; |
|
- | 893 | int dotclk, flag; |
|
- | 894 | ||
- | 895 | flag = 0; |
|
- | 896 | dotclk = target * 1000; |
|
- | 897 | bestppm = 1000000; |
|
- | 898 | ppm = absppm = 0; |
|
- | 899 | fastclk = dotclk / (2*100); |
|
- | 900 | updrate = 0; |
|
- | 901 | minupdate = 19200; |
|
- | 902 | fracbits = 1; |
|
- | 903 | n = p = p1 = p2 = m = m1 = m2 = vco = bestn = 0; |
|
- | 904 | bestm1 = bestm2 = bestp1 = bestp2 = 0; |
|
- | 905 | ||
- | 906 | /* based on hardware requirement, prefer smaller n to precision */ |
|
- | 907 | for (n = limit->n.min; n <= ((refclk) / minupdate); n++) { |
|
- | 908 | updrate = refclk / n; |
|
- | 909 | for (p1 = limit->p1.max; p1 > limit->p1.min; p1--) { |
|
- | 910 | for (p2 = limit->p2.p2_fast+1; p2 > 0; p2--) { |
|
- | 911 | if (p2 > 10) |
|
- | 912 | p2 = p2 - 1; |
|
- | 913 | p = p1 * p2; |
|
- | 914 | /* based on hardware requirement, prefer bigger m1,m2 values */ |
|
- | 915 | for (m1 = limit->m1.min; m1 <= limit->m1.max; m1++) { |
|
- | 916 | m2 = (((2*(fastclk * p * n / m1 )) + |
|
- | 917 | refclk) / (2*refclk)); |
|
- | 918 | m = m1 * m2; |
|
- | 919 | vco = updrate * m; |
|
- | 920 | if (vco >= limit->vco.min && vco < limit->vco.max) { |
|
- | 921 | ppm = 1000000 * ((vco / p) - fastclk) / fastclk; |
|
- | 922 | absppm = (ppm > 0) ? ppm : (-ppm); |
|
- | 923 | if (absppm < 100 && ((p1 * p2) > (bestp1 * bestp2))) { |
|
- | 924 | bestppm = 0; |
|
- | 925 | flag = 1; |
|
- | 926 | } |
|
- | 927 | if (absppm < bestppm - 10) { |
|
- | 928 | bestppm = absppm; |
|
- | 929 | flag = 1; |
|
- | 930 | } |
|
- | 931 | if (flag) { |
|
- | 932 | bestn = n; |
|
- | 933 | bestm1 = m1; |
|
- | 934 | bestm2 = m2; |
|
- | 935 | bestp1 = p1; |
|
- | 936 | bestp2 = p2; |
|
- | 937 | flag = 0; |
|
- | 938 | } |
|
- | 939 | } |
|
- | 940 | } |
|
- | 941 | } |
|
- | 942 | } |
|
- | 943 | } |
|
- | 944 | best_clock->n = bestn; |
|
- | 945 | best_clock->m1 = bestm1; |
|
- | 946 | best_clock->m2 = bestm2; |
|
- | 947 | best_clock->p1 = bestp1; |
|
- | 948 | best_clock->p2 = bestp2; |
|
- | 949 | ||
- | 950 | return true; |
|
- | 951 | } |
|
- | 952 | ||
- | 953 | static void ironlake_wait_for_vblank(struct drm_device *dev, int pipe) |
|
- | 954 | { |
|
- | 955 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 956 | u32 frame, frame_reg = PIPEFRAME(pipe); |
|
- | 957 | ||
- | 958 | frame = I915_READ(frame_reg); |
|
- | 959 | ||
- | 960 | if (wait_for(I915_READ_NOTRACE(frame_reg) != frame, 50)) |
|
- | 961 | DRM_DEBUG_KMS("vblank wait timed out\n"); |
|
- | 962 | } |
|
Line 724... | Line 963... | ||
724 | 963 | ||
725 | /** |
964 | /** |
726 | * intel_wait_for_vblank - wait for vblank on a given pipe |
965 | * intel_wait_for_vblank - wait for vblank on a given pipe |
727 | * @dev: drm device |
966 | * @dev: drm device |
Line 733... | Line 972... | ||
733 | void intel_wait_for_vblank(struct drm_device *dev, int pipe) |
972 | void intel_wait_for_vblank(struct drm_device *dev, int pipe) |
734 | { |
973 | { |
735 | struct drm_i915_private *dev_priv = dev->dev_private; |
974 | struct drm_i915_private *dev_priv = dev->dev_private; |
736 | int pipestat_reg = PIPESTAT(pipe); |
975 | int pipestat_reg = PIPESTAT(pipe); |
Line -... | Line 976... | ||
- | 976 | ||
- | 977 | if (INTEL_INFO(dev)->gen >= 5) { |
|
- | 978 | ironlake_wait_for_vblank(dev, pipe); |
|
- | 979 | return; |
|
- | 980 | } |
|
737 | 981 | ||
738 | /* Clear existing vblank status. Note this will clear any other |
982 | /* Clear existing vblank status. Note this will clear any other |
739 | * sticky status fields as well. |
983 | * sticky status fields as well. |
740 | * |
984 | * |
741 | * This races with i915_driver_irq_handler() with the result |
985 | * This races with i915_driver_irq_handler() with the result |
Line 783... | Line 1027... | ||
783 | int reg = PIPECONF(pipe); |
1027 | int reg = PIPECONF(pipe); |
Line 784... | Line 1028... | ||
784 | 1028 | ||
785 | /* Wait for the Pipe State to go off */ |
1029 | /* Wait for the Pipe State to go off */ |
786 | if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0, |
1030 | if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0, |
787 | 100)) |
1031 | 100)) |
788 | DRM_DEBUG_KMS("pipe_off wait timed out\n"); |
1032 | WARN(1, "pipe_off wait timed out\n"); |
789 | } else { |
1033 | } else { |
790 | u32 last_line; |
1034 | u32 last_line, line_mask; |
791 | int reg = PIPEDSL(pipe); |
1035 | int reg = PIPEDSL(pipe); |
- | 1036 | unsigned long timeout = GetTimerTicks() + msecs_to_jiffies(100); |
|
- | 1037 | ||
- | 1038 | if (IS_GEN2(dev)) |
|
- | 1039 | line_mask = DSL_LINEMASK_GEN2; |
|
- | 1040 | else |
|
Line 792... | Line 1041... | ||
792 | unsigned long timeout = jiffies + msecs_to_jiffies(100); |
1041 | line_mask = DSL_LINEMASK_GEN3; |
793 | 1042 | ||
794 | /* Wait for the display line to settle */ |
1043 | /* Wait for the display line to settle */ |
795 | do { |
1044 | do { |
796 | last_line = I915_READ(reg) & DSL_LINEMASK; |
1045 | last_line = I915_READ(reg) & line_mask; |
797 | mdelay(5); |
1046 | mdelay(5); |
798 | } while (((I915_READ(reg) & DSL_LINEMASK) != last_line) && |
1047 | } while (((I915_READ(reg) & line_mask) != last_line) && |
799 | time_after(timeout, jiffies)); |
1048 | time_after(timeout, GetTimerTicks())); |
800 | if (time_after(jiffies, timeout)) |
1049 | if (time_after(GetTimerTicks(), timeout)) |
801 | DRM_DEBUG_KMS("pipe_off wait timed out\n"); |
1050 | WARN(1, "pipe_off wait timed out\n"); |
Line 802... | Line 1051... | ||
802 | } |
1051 | } |
803 | } |
1052 | } |
Line 825... | Line 1074... | ||
825 | #define assert_pll_enabled(d, p) assert_pll(d, p, true) |
1074 | #define assert_pll_enabled(d, p) assert_pll(d, p, true) |
826 | #define assert_pll_disabled(d, p) assert_pll(d, p, false) |
1075 | #define assert_pll_disabled(d, p) assert_pll(d, p, false) |
Line 827... | Line 1076... | ||
827 | 1076 | ||
828 | /* For ILK+ */ |
1077 | /* For ILK+ */ |
- | 1078 | static void assert_pch_pll(struct drm_i915_private *dev_priv, |
|
- | 1079 | struct intel_pch_pll *pll, |
|
829 | static void assert_pch_pll(struct drm_i915_private *dev_priv, |
1080 | struct intel_crtc *crtc, |
830 | enum pipe pipe, bool state) |
1081 | bool state) |
831 | { |
- | |
832 | int reg; |
1082 | { |
833 | u32 val; |
1083 | u32 val; |
Line 834... | Line 1084... | ||
834 | bool cur_state; |
1084 | bool cur_state; |
- | 1085 | ||
835 | 1086 | if (HAS_PCH_LPT(dev_priv->dev)) { |
|
- | 1087 | DRM_DEBUG_DRIVER("LPT detected: skipping PCH PLL test\n"); |
|
Line -... | Line 1088... | ||
- | 1088 | return; |
|
836 | if (HAS_PCH_CPT(dev_priv->dev)) { |
1089 | } |
- | 1090 | ||
Line -... | Line 1091... | ||
- | 1091 | if (WARN (!pll, |
|
837 | u32 pch_dpll; |
1092 | "asserting PCH PLL %s with no PLL\n", state_string(state))) |
838 | 1093 | return; |
|
- | 1094 | ||
839 | pch_dpll = I915_READ(PCH_DPLL_SEL); |
1095 | val = I915_READ(pll->pll_reg); |
Line 840... | Line 1096... | ||
840 | 1096 | cur_state = !!(val & DPLL_VCO_ENABLE); |
|
841 | /* Make sure the selected PLL is enabled to the transcoder */ |
1097 | WARN(cur_state != state, |
842 | WARN(!((pch_dpll >> (4 * pipe)) & 8), |
1098 | "PCH PLL state for reg %x assertion failure (expected %s, current %s), val=%08x\n", |
Line 843... | Line 1099... | ||
843 | "transcoder %d PLL not enabled\n", pipe); |
1099 | pll->pll_reg, state_string(state), state_string(cur_state), val); |
844 | 1100 | ||
- | 1101 | /* Make sure the selected PLL is correctly attached to the transcoder */ |
|
- | 1102 | if (crtc && HAS_PCH_CPT(dev_priv->dev)) { |
|
- | 1103 | u32 pch_dpll; |
|
845 | /* Convert the transcoder pipe number to a pll pipe number */ |
1104 | |
846 | pipe = (pch_dpll >> (4 * pipe)) & 1; |
1105 | pch_dpll = I915_READ(PCH_DPLL_SEL); |
847 | } |
1106 | cur_state = pll->pll_reg == _PCH_DPLL_B; |
- | 1107 | if (!WARN(((pch_dpll >> (4 * crtc->pipe)) & 1) != cur_state, |
|
848 | 1108 | "PLL[%d] not attached to this transcoder %d: %08x\n", |
|
- | 1109 | cur_state, crtc->pipe, pch_dpll)) { |
|
- | 1110 | cur_state = !!(val >> (4*crtc->pipe + 3)); |
|
- | 1111 | WARN(cur_state != state, |
|
849 | reg = PCH_DPLL(pipe); |
1112 | "PLL[%d] not %s on this transcoder %d: %08x\n", |
- | 1113 | pll->pll_reg == _PCH_DPLL_B, |
|
850 | val = I915_READ(reg); |
1114 | state_string(state), |
851 | cur_state = !!(val & DPLL_VCO_ENABLE); |
1115 | crtc->pipe, |
Line 852... | Line 1116... | ||
852 | WARN(cur_state != state, |
1116 | val); |
853 | "PCH PLL state assertion failure (expected %s, current %s)\n", |
1117 | } |
854 | state_string(state), state_string(cur_state)); |
1118 | } |
855 | } |
1119 | } |
856 | #define assert_pch_pll_enabled(d, p) assert_pch_pll(d, p, true) |
1120 | #define assert_pch_pll_enabled(d, p, c) assert_pch_pll(d, p, c, true) |
857 | #define assert_pch_pll_disabled(d, p) assert_pch_pll(d, p, false) |
1121 | #define assert_pch_pll_disabled(d, p, c) assert_pch_pll(d, p, c, false) |
Line -... | Line 1122... | ||
- | 1122 | ||
- | 1123 | static void assert_fdi_tx(struct drm_i915_private *dev_priv, |
|
- | 1124 | enum pipe pipe, bool state) |
|
- | 1125 | { |
|
- | 1126 | int reg; |
|
- | 1127 | u32 val; |
|
858 | 1128 | bool cur_state; |
|
859 | static void assert_fdi_tx(struct drm_i915_private *dev_priv, |
1129 | |
860 | enum pipe pipe, bool state) |
1130 | if (IS_HASWELL(dev_priv->dev)) { |
- | 1131 | /* On Haswell, DDI is used instead of FDI_TX_CTL */ |
|
861 | { |
1132 | reg = DDI_FUNC_CTL(pipe); |
862 | int reg; |
1133 | val = I915_READ(reg); |
863 | u32 val; |
1134 | cur_state = !!(val & PIPE_DDI_FUNC_ENABLE); |
864 | bool cur_state; |
1135 | } else { |
865 | 1136 | reg = FDI_TX_CTL(pipe); |
|
Line 878... | Line 1149... | ||
878 | { |
1149 | { |
879 | int reg; |
1150 | int reg; |
880 | u32 val; |
1151 | u32 val; |
881 | bool cur_state; |
1152 | bool cur_state; |
Line -... | Line 1153... | ||
- | 1153 | ||
- | 1154 | if (IS_HASWELL(dev_priv->dev) && pipe > 0) { |
|
- | 1155 | DRM_ERROR("Attempting to enable FDI_RX on Haswell pipe > 0\n"); |
|
- | 1156 | return; |
|
882 | 1157 | } else { |
|
883 | reg = FDI_RX_CTL(pipe); |
1158 | reg = FDI_RX_CTL(pipe); |
884 | val = I915_READ(reg); |
1159 | val = I915_READ(reg); |
- | 1160 | cur_state = !!(val & FDI_RX_ENABLE); |
|
885 | cur_state = !!(val & FDI_RX_ENABLE); |
1161 | } |
886 | WARN(cur_state != state, |
1162 | WARN(cur_state != state, |
887 | "FDI RX state assertion failure (expected %s, current %s)\n", |
1163 | "FDI RX state assertion failure (expected %s, current %s)\n", |
888 | state_string(state), state_string(cur_state)); |
1164 | state_string(state), state_string(cur_state)); |
889 | } |
1165 | } |
Line 898... | Line 1174... | ||
898 | 1174 | ||
899 | /* ILK FDI PLL is always enabled */ |
1175 | /* ILK FDI PLL is always enabled */ |
900 | if (dev_priv->info->gen == 5) |
1176 | if (dev_priv->info->gen == 5) |
Line -... | Line 1177... | ||
- | 1177 | return; |
|
- | 1178 | ||
- | 1179 | /* On Haswell, DDI ports are responsible for the FDI PLL setup */ |
|
- | 1180 | if (IS_HASWELL(dev_priv->dev)) |
|
901 | return; |
1181 | return; |
902 | 1182 | ||
903 | reg = FDI_TX_CTL(pipe); |
1183 | reg = FDI_TX_CTL(pipe); |
904 | val = I915_READ(reg); |
1184 | val = I915_READ(reg); |
Line 909... | Line 1189... | ||
909 | enum pipe pipe) |
1189 | enum pipe pipe) |
910 | { |
1190 | { |
911 | int reg; |
1191 | int reg; |
912 | u32 val; |
1192 | u32 val; |
Line -... | Line 1193... | ||
- | 1193 | ||
- | 1194 | if (IS_HASWELL(dev_priv->dev) && pipe > 0) { |
|
- | 1195 | DRM_ERROR("Attempting to enable FDI on Haswell with pipe > 0\n"); |
|
- | 1196 | return; |
|
913 | 1197 | } |
|
914 | reg = FDI_RX_CTL(pipe); |
1198 | reg = FDI_RX_CTL(pipe); |
915 | val = I915_READ(reg); |
1199 | val = I915_READ(reg); |
916 | WARN(!(val & FDI_RX_PLL_ENABLE), "FDI RX PLL assertion failure, should be active but is disabled\n"); |
1200 | WARN(!(val & FDI_RX_PLL_ENABLE), "FDI RX PLL assertion failure, should be active but is disabled\n"); |
Line 950... | Line 1234... | ||
950 | { |
1234 | { |
951 | int reg; |
1235 | int reg; |
952 | u32 val; |
1236 | u32 val; |
953 | bool cur_state; |
1237 | bool cur_state; |
Line -... | Line 1238... | ||
- | 1238 | ||
- | 1239 | /* if we need the pipe A quirk it must be always on */ |
|
- | 1240 | if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) |
|
- | 1241 | state = true; |
|
954 | 1242 | ||
955 | reg = PIPECONF(pipe); |
1243 | reg = PIPECONF(pipe); |
956 | val = I915_READ(reg); |
1244 | val = I915_READ(reg); |
957 | cur_state = !!(val & PIPECONF_ENABLE); |
1245 | cur_state = !!(val & PIPECONF_ENABLE); |
958 | WARN(cur_state != state, |
1246 | WARN(cur_state != state, |
959 | "pipe %c assertion failure (expected %s, current %s)\n", |
1247 | "pipe %c assertion failure (expected %s, current %s)\n", |
960 | pipe_name(pipe), state_string(state), state_string(cur_state)); |
1248 | pipe_name(pipe), state_string(state), state_string(cur_state)); |
Line 961... | Line 1249... | ||
961 | } |
1249 | } |
962 | 1250 | ||
963 | static void assert_plane_enabled(struct drm_i915_private *dev_priv, |
1251 | static void assert_plane(struct drm_i915_private *dev_priv, |
964 | enum plane plane) |
1252 | enum plane plane, bool state) |
965 | { |
1253 | { |
- | 1254 | int reg; |
|
Line 966... | Line 1255... | ||
966 | int reg; |
1255 | u32 val; |
967 | u32 val; |
1256 | bool cur_state; |
968 | 1257 | ||
- | 1258 | reg = DSPCNTR(plane); |
|
969 | reg = DSPCNTR(plane); |
1259 | val = I915_READ(reg); |
970 | val = I915_READ(reg); |
1260 | cur_state = !!(val & DISPLAY_PLANE_ENABLE); |
971 | WARN(!(val & DISPLAY_PLANE_ENABLE), |
1261 | WARN(cur_state != state, |
Line -... | Line 1262... | ||
- | 1262 | "plane %c assertion failure (expected %s, current %s)\n", |
|
- | 1263 | plane_name(plane), state_string(state), state_string(cur_state)); |
|
- | 1264 | } |
|
972 | "plane %c assertion failure, should be active but is disabled\n", |
1265 | |
973 | plane_name(plane)); |
1266 | #define assert_plane_enabled(d, p) assert_plane(d, p, true) |
974 | } |
1267 | #define assert_plane_disabled(d, p) assert_plane(d, p, false) |
975 | 1268 | ||
976 | static void assert_planes_disabled(struct drm_i915_private *dev_priv, |
1269 | static void assert_planes_disabled(struct drm_i915_private *dev_priv, |
977 | enum pipe pipe) |
1270 | enum pipe pipe) |
Line 978... | Line 1271... | ||
978 | { |
1271 | { |
979 | int reg, i; |
1272 | int reg, i; |
- | 1273 | u32 val; |
|
- | 1274 | int cur_pipe; |
|
- | 1275 | ||
- | 1276 | /* Planes are fixed to pipes on ILK+ */ |
|
- | 1277 | if (HAS_PCH_SPLIT(dev_priv->dev)) { |
|
980 | u32 val; |
1278 | reg = DSPCNTR(pipe); |
- | 1279 | val = I915_READ(reg); |
|
Line 981... | Line 1280... | ||
981 | int cur_pipe; |
1280 | WARN((val & DISPLAY_PLANE_ENABLE), |
982 | 1281 | "plane %c assertion failure, should be disabled but not\n", |
|
983 | /* Planes are fixed to pipes on ILK+ */ |
1282 | plane_name(pipe)); |
984 | if (HAS_PCH_SPLIT(dev_priv->dev)) |
1283 | return; |
Line 999... | Line 1298... | ||
999 | static void assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) |
1298 | static void assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) |
1000 | { |
1299 | { |
1001 | u32 val; |
1300 | u32 val; |
1002 | bool enabled; |
1301 | bool enabled; |
Line -... | Line 1302... | ||
- | 1302 | ||
- | 1303 | if (HAS_PCH_LPT(dev_priv->dev)) { |
|
- | 1304 | DRM_DEBUG_DRIVER("LPT does not has PCH refclk, skipping check\n"); |
|
- | 1305 | return; |
|
- | 1306 | } |
|
1003 | 1307 | ||
1004 | val = I915_READ(PCH_DREF_CONTROL); |
1308 | val = I915_READ(PCH_DREF_CONTROL); |
1005 | enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK | |
1309 | enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK | |
1006 | DREF_SUPERSPREAD_SOURCE_MASK)); |
1310 | DREF_SUPERSPREAD_SOURCE_MASK)); |
1007 | WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n"); |
1311 | WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n"); |
Line 1092... | Line 1396... | ||
1092 | { |
1396 | { |
1093 | u32 val = I915_READ(reg); |
1397 | u32 val = I915_READ(reg); |
1094 | WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val), |
1398 | WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val), |
1095 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", |
1399 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", |
1096 | reg, pipe_name(pipe)); |
1400 | reg, pipe_name(pipe)); |
- | 1401 | ||
- | 1402 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0 |
|
- | 1403 | && (val & DP_PIPEB_SELECT), |
|
- | 1404 | "IBX PCH dp port still using transcoder B\n"); |
|
1097 | } |
1405 | } |
Line 1098... | Line 1406... | ||
1098 | 1406 | ||
1099 | static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, |
1407 | static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, |
1100 | enum pipe pipe, int reg) |
1408 | enum pipe pipe, int reg) |
1101 | { |
1409 | { |
1102 | u32 val = I915_READ(reg); |
1410 | u32 val = I915_READ(reg); |
1103 | WARN(hdmi_pipe_enabled(dev_priv, val, pipe), |
1411 | WARN(hdmi_pipe_enabled(dev_priv, pipe, val), |
1104 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", |
1412 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", |
- | 1413 | reg, pipe_name(pipe)); |
|
- | 1414 | ||
- | 1415 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & PORT_ENABLE) == 0 |
|
- | 1416 | && (val & SDVO_PIPE_B_SELECT), |
|
1105 | reg, pipe_name(pipe)); |
1417 | "IBX PCH hdmi port still using transcoder B\n"); |
Line 1106... | Line 1418... | ||
1106 | } |
1418 | } |
1107 | 1419 | ||
1108 | static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, |
1420 | static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, |
Line 1115... | Line 1427... | ||
1115 | assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); |
1427 | assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); |
1116 | assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); |
1428 | assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); |
Line 1117... | Line 1429... | ||
1117 | 1429 | ||
1118 | reg = PCH_ADPA; |
1430 | reg = PCH_ADPA; |
1119 | val = I915_READ(reg); |
1431 | val = I915_READ(reg); |
1120 | WARN(adpa_pipe_enabled(dev_priv, val, pipe), |
1432 | WARN(adpa_pipe_enabled(dev_priv, pipe, val), |
1121 | "PCH VGA enabled on transcoder %c, should be disabled\n", |
1433 | "PCH VGA enabled on transcoder %c, should be disabled\n", |
Line 1122... | Line 1434... | ||
1122 | pipe_name(pipe)); |
1434 | pipe_name(pipe)); |
1123 | 1435 | ||
1124 | reg = PCH_LVDS; |
1436 | reg = PCH_LVDS; |
1125 | val = I915_READ(reg); |
1437 | val = I915_READ(reg); |
1126 | WARN(lvds_pipe_enabled(dev_priv, val, pipe), |
1438 | WARN(lvds_pipe_enabled(dev_priv, pipe, val), |
Line 1127... | Line 1439... | ||
1127 | "PCH LVDS enabled on transcoder %c, should be disabled\n", |
1439 | "PCH LVDS enabled on transcoder %c, should be disabled\n", |
1128 | pipe_name(pipe)); |
1440 | pipe_name(pipe)); |
Line 1140... | Line 1452... | ||
1140 | * Enable @pipe's PLL so we can start pumping pixels from a plane. Check to |
1452 | * Enable @pipe's PLL so we can start pumping pixels from a plane. Check to |
1141 | * make sure the PLL reg is writable first though, since the panel write |
1453 | * make sure the PLL reg is writable first though, since the panel write |
1142 | * protect mechanism may be enabled. |
1454 | * protect mechanism may be enabled. |
1143 | * |
1455 | * |
1144 | * Note! This is for pre-ILK only. |
1456 | * Note! This is for pre-ILK only. |
- | 1457 | * |
|
- | 1458 | * Unfortunately needed by dvo_ns2501 since the dvo depends on it running. |
|
1145 | */ |
1459 | */ |
1146 | static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) |
1460 | static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) |
1147 | { |
1461 | { |
1148 | int reg; |
1462 | int reg; |
1149 | u32 val; |
1463 | u32 val; |
Line 1150... | Line 1464... | ||
1150 | 1464 | ||
1151 | /* No really, not for ILK+ */ |
1465 | /* No really, not for ILK+ */ |
Line 1152... | Line 1466... | ||
1152 | BUG_ON(dev_priv->info->gen >= 5); |
1466 | BUG_ON(!IS_VALLEYVIEW(dev_priv->dev) && dev_priv->info->gen >= 5); |
1153 | 1467 | ||
1154 | /* PLL is protected by panel, make sure we can write it */ |
1468 | /* PLL is protected by panel, make sure we can write it */ |
Line 1197... | Line 1511... | ||
1197 | val &= ~DPLL_VCO_ENABLE; |
1511 | val &= ~DPLL_VCO_ENABLE; |
1198 | I915_WRITE(reg, val); |
1512 | I915_WRITE(reg, val); |
1199 | POSTING_READ(reg); |
1513 | POSTING_READ(reg); |
1200 | } |
1514 | } |
Line -... | Line 1515... | ||
- | 1515 | ||
- | 1516 | /* SBI access */ |
|
- | 1517 | static void |
|
- | 1518 | intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value) |
|
- | 1519 | { |
|
- | 1520 | unsigned long flags; |
|
- | 1521 | ||
- | 1522 | spin_lock_irqsave(&dev_priv->dpio_lock, flags); |
|
- | 1523 | if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, |
|
- | 1524 | 100)) { |
|
- | 1525 | DRM_ERROR("timeout waiting for SBI to become ready\n"); |
|
- | 1526 | goto out_unlock; |
|
- | 1527 | } |
|
- | 1528 | ||
- | 1529 | I915_WRITE(SBI_ADDR, |
|
- | 1530 | (reg << 16)); |
|
- | 1531 | I915_WRITE(SBI_DATA, |
|
- | 1532 | value); |
|
- | 1533 | I915_WRITE(SBI_CTL_STAT, |
|
- | 1534 | SBI_BUSY | |
|
- | 1535 | SBI_CTL_OP_CRWR); |
|
- | 1536 | ||
- | 1537 | if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, |
|
- | 1538 | 100)) { |
|
- | 1539 | DRM_ERROR("timeout waiting for SBI to complete write transaction\n"); |
|
- | 1540 | goto out_unlock; |
|
- | 1541 | } |
|
- | 1542 | ||
- | 1543 | out_unlock: |
|
- | 1544 | spin_unlock_irqrestore(&dev_priv->dpio_lock, flags); |
|
- | 1545 | } |
|
- | 1546 | ||
- | 1547 | static u32 |
|
- | 1548 | intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg) |
|
- | 1549 | { |
|
- | 1550 | unsigned long flags; |
|
- | 1551 | u32 value = 0; |
|
- | 1552 | ||
- | 1553 | spin_lock_irqsave(&dev_priv->dpio_lock, flags); |
|
- | 1554 | if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, |
|
- | 1555 | 100)) { |
|
- | 1556 | DRM_ERROR("timeout waiting for SBI to become ready\n"); |
|
- | 1557 | goto out_unlock; |
|
- | 1558 | } |
|
- | 1559 | ||
- | 1560 | I915_WRITE(SBI_ADDR, |
|
- | 1561 | (reg << 16)); |
|
- | 1562 | I915_WRITE(SBI_CTL_STAT, |
|
- | 1563 | SBI_BUSY | |
|
- | 1564 | SBI_CTL_OP_CRRD); |
|
- | 1565 | ||
- | 1566 | if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, |
|
- | 1567 | 100)) { |
|
- | 1568 | DRM_ERROR("timeout waiting for SBI to complete read transaction\n"); |
|
- | 1569 | goto out_unlock; |
|
- | 1570 | } |
|
- | 1571 | ||
- | 1572 | value = I915_READ(SBI_DATA); |
|
- | 1573 | ||
- | 1574 | out_unlock: |
|
- | 1575 | spin_unlock_irqrestore(&dev_priv->dpio_lock, flags); |
|
- | 1576 | return value; |
|
- | 1577 | } |
|
1201 | 1578 | ||
1202 | /** |
1579 | /** |
1203 | * intel_enable_pch_pll - enable PCH PLL |
1580 | * intel_enable_pch_pll - enable PCH PLL |
1204 | * @dev_priv: i915 private structure |
1581 | * @dev_priv: i915 private structure |
1205 | * @pipe: pipe PLL to enable |
1582 | * @pipe: pipe PLL to enable |
1206 | * |
1583 | * |
1207 | * The PCH PLL needs to be enabled before the PCH transcoder, since it |
1584 | * The PCH PLL needs to be enabled before the PCH transcoder, since it |
1208 | * drives the transcoder clock. |
1585 | * drives the transcoder clock. |
1209 | */ |
1586 | */ |
1210 | static void intel_enable_pch_pll(struct drm_i915_private *dev_priv, |
- | |
1211 | enum pipe pipe) |
1587 | static void intel_enable_pch_pll(struct intel_crtc *intel_crtc) |
- | 1588 | { |
|
- | 1589 | struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; |
|
1212 | { |
1590 | struct intel_pch_pll *pll; |
1213 | int reg; |
1591 | int reg; |
Line -... | Line 1592... | ||
- | 1592 | u32 val; |
|
- | 1593 | ||
- | 1594 | /* PCH PLLs only available on ILK, SNB and IVB */ |
|
1214 | u32 val; |
1595 | BUG_ON(dev_priv->info->gen < 5); |
1215 | 1596 | pll = intel_crtc->pch_pll; |
|
Line 1216... | Line 1597... | ||
1216 | if (pipe > 1) |
1597 | if (pll == NULL) |
- | 1598 | return; |
|
- | 1599 | ||
- | 1600 | if (WARN_ON(pll->refcount == 0)) |
|
- | 1601 | return; |
|
1217 | return; |
1602 | |
Line 1218... | Line 1603... | ||
1218 | 1603 | DRM_DEBUG_KMS("enable PCH PLL %x (active %d, on? %d)for crtc %d\n", |
|
1219 | /* PCH only available on ILK+ */ |
1604 | pll->pll_reg, pll->active, pll->on, |
Line -... | Line 1605... | ||
- | 1605 | intel_crtc->base.base.id); |
|
- | 1606 | ||
- | 1607 | /* PCH refclock must be enabled first */ |
|
- | 1608 | assert_pch_refclk_enabled(dev_priv); |
|
- | 1609 | ||
- | 1610 | if (pll->active++ && pll->on) { |
|
- | 1611 | assert_pch_pll_enabled(dev_priv, pll, NULL); |
|
1220 | BUG_ON(dev_priv->info->gen < 5); |
1612 | return; |
1221 | 1613 | } |
|
1222 | /* PCH refclock must be enabled first */ |
1614 | |
1223 | assert_pch_refclk_enabled(dev_priv); |
1615 | DRM_DEBUG_KMS("enabling PCH PLL %x\n", pll->pll_reg); |
1224 | 1616 | ||
1225 | reg = PCH_DPLL(pipe); |
1617 | reg = pll->pll_reg; |
- | 1618 | val = I915_READ(reg); |
|
- | 1619 | val |= DPLL_VCO_ENABLE; |
|
1226 | val = I915_READ(reg); |
1620 | I915_WRITE(reg, val); |
Line 1227... | Line 1621... | ||
1227 | val |= DPLL_VCO_ENABLE; |
1621 | POSTING_READ(reg); |
1228 | I915_WRITE(reg, val); |
- | |
1229 | POSTING_READ(reg); |
1622 | udelay(200); |
- | 1623 | ||
- | 1624 | pll->on = true; |
|
1230 | udelay(200); |
1625 | } |
1231 | } |
- | |
1232 | - | ||
1233 | static void intel_disable_pch_pll(struct drm_i915_private *dev_priv, |
- | |
1234 | enum pipe pipe) |
- | |
1235 | { |
1626 | |
Line 1236... | Line 1627... | ||
1236 | int reg; |
1627 | static void intel_disable_pch_pll(struct intel_crtc *intel_crtc) |
1237 | u32 val, pll_mask = TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL, |
1628 | { |
- | 1629 | struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; |
|
- | 1630 | struct intel_pch_pll *pll = intel_crtc->pch_pll; |
|
Line 1238... | Line 1631... | ||
1238 | pll_sel = TRANSC_DPLL_ENABLE; |
1631 | int reg; |
1239 | 1632 | u32 val; |
|
Line 1240... | Line 1633... | ||
1240 | if (pipe > 1) |
1633 | |
1241 | return; |
1634 | /* PCH only available on ILK+ */ |
1242 | - | ||
1243 | /* PCH only available on ILK+ */ |
1635 | BUG_ON(dev_priv->info->gen < 5); |
Line -... | Line 1636... | ||
- | 1636 | if (pll == NULL) |
|
- | 1637 | return; |
|
- | 1638 | ||
- | 1639 | if (WARN_ON(pll->refcount == 0)) |
|
Line -... | Line 1640... | ||
- | 1640 | return; |
|
1244 | BUG_ON(dev_priv->info->gen < 5); |
1641 | |
1245 | 1642 | DRM_DEBUG_KMS("disable PCH PLL %x (active %d, on? %d) for crtc %d\n", |
|
- | 1643 | pll->pll_reg, pll->active, pll->on, |
|
- | 1644 | intel_crtc->base.base.id); |
|
- | 1645 | ||
- | 1646 | if (WARN_ON(pll->active == 0)) { |
|
- | 1647 | assert_pch_pll_disabled(dev_priv, pll, NULL); |
|
- | 1648 | return; |
|
Line 1246... | Line 1649... | ||
1246 | /* Make sure transcoder isn't still depending on us */ |
1649 | } |
1247 | assert_transcoder_disabled(dev_priv, pipe); |
1650 | |
1248 | 1651 | if (--pll->active) { |
|
1249 | if (pipe == 0) |
1652 | assert_pch_pll_enabled(dev_priv, pll, NULL); |
1250 | pll_sel |= TRANSC_DPLLA_SEL; |
1653 | return; |
1251 | else if (pipe == 1) |
1654 | } |
- | 1655 | ||
- | 1656 | DRM_DEBUG_KMS("disabling PCH PLL %x\n", pll->pll_reg); |
|
1252 | pll_sel |= TRANSC_DPLLB_SEL; |
1657 | |
Line 1253... | Line 1658... | ||
1253 | 1658 | /* Make sure transcoder isn't still depending on us */ |
|
1254 | 1659 | assert_transcoder_disabled(dev_priv, intel_crtc->pipe); |
|
1255 | if ((I915_READ(PCH_DPLL_SEL) & pll_mask) == pll_sel) |
1660 | |
1256 | return; |
1661 | reg = pll->pll_reg; |
1257 | 1662 | val = I915_READ(reg); |
|
- | 1663 | val &= ~DPLL_VCO_ENABLE; |
|
Line 1258... | Line 1664... | ||
1258 | reg = PCH_DPLL(pipe); |
1664 | I915_WRITE(reg, val); |
1259 | val = I915_READ(reg); |
1665 | POSTING_READ(reg); |
Line 1260... | Line 1666... | ||
1260 | val &= ~DPLL_VCO_ENABLE; |
1666 | udelay(200); |
1261 | I915_WRITE(reg, val); |
1667 | |
- | 1668 | pll->on = false; |
|
- | 1669 | } |
|
Line 1262... | Line 1670... | ||
1262 | POSTING_READ(reg); |
1670 | |
1263 | udelay(200); |
1671 | static void intel_enable_transcoder(struct drm_i915_private *dev_priv, |
1264 | } |
1672 | enum pipe pipe) |
Line -... | Line 1673... | ||
- | 1673 | { |
|
- | 1674 | int reg; |
|
- | 1675 | u32 val, pipeconf_val; |
|
- | 1676 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
|
1265 | 1677 | ||
1266 | static void intel_enable_transcoder(struct drm_i915_private *dev_priv, |
1678 | /* PCH only available on ILK+ */ |
- | 1679 | BUG_ON(dev_priv->info->gen < 5); |
|
Line 1267... | Line 1680... | ||
1267 | enum pipe pipe) |
1680 | |
1268 | { |
1681 | /* Make sure PCH DPLL is enabled */ |
1269 | int reg; |
1682 | assert_pch_pll_enabled(dev_priv, |
1270 | u32 val; |
1683 | to_intel_crtc(crtc)->pch_pll, |
1271 | 1684 | to_intel_crtc(crtc)); |
|
1272 | /* PCH only available on ILK+ */ |
1685 | |
1273 | BUG_ON(dev_priv->info->gen < 5); |
1686 | /* FDI must be feeding us bits for PCH ports */ |
1274 | 1687 | assert_fdi_tx_enabled(dev_priv, pipe); |
|
- | 1688 | assert_fdi_rx_enabled(dev_priv, pipe); |
|
- | 1689 | ||
- | 1690 | if (IS_HASWELL(dev_priv->dev) && pipe > 0) { |
|
- | 1691 | DRM_ERROR("Attempting to enable transcoder on Haswell with pipe > 0\n"); |
|
- | 1692 | return; |
|
- | 1693 | } |
|
- | 1694 | reg = TRANSCONF(pipe); |
|
- | 1695 | val = I915_READ(reg); |
|
- | 1696 | pipeconf_val = I915_READ(PIPECONF(pipe)); |
|
- | 1697 | ||
- | 1698 | if (HAS_PCH_IBX(dev_priv->dev)) { |
|
1275 | /* Make sure PCH DPLL is enabled */ |
1699 | /* |
1276 | assert_pch_pll_enabled(dev_priv, pipe); |
1700 | * make the BPC in transcoder be consistent with |
1277 | 1701 | * that in pipeconf reg. |
|
1278 | /* FDI must be feeding us bits for PCH ports */ |
1702 | */ |
Line 1395... | Line 1819... | ||
1395 | if ((val & PIPECONF_ENABLE) == 0) |
1819 | if ((val & PIPECONF_ENABLE) == 0) |
1396 | return; |
1820 | return; |
Line 1397... | Line 1821... | ||
1397 | 1821 | ||
1398 | I915_WRITE(reg, val & ~PIPECONF_ENABLE); |
1822 | I915_WRITE(reg, val & ~PIPECONF_ENABLE); |
- | 1823 | intel_wait_for_pipe_off(dev_priv->dev, pipe); |
|
1399 | intel_wait_for_pipe_off(dev_priv->dev, pipe); |
1824 | |
Line 1400... | Line 1825... | ||
1400 | } |
1825 | } |
1401 | 1826 | ||
1402 | /* |
1827 | /* |
1403 | * Plane regs are double buffered, going from enabled->disabled needs a |
1828 | * Plane regs are double buffered, going from enabled->disabled needs a |
1404 | * trigger in order to latch. The display address reg provides this. |
1829 | * trigger in order to latch. The display address reg provides this. |
1405 | */ |
1830 | */ |
1406 | static void intel_flush_display_plane(struct drm_i915_private *dev_priv, |
1831 | void intel_flush_display_plane(struct drm_i915_private *dev_priv, |
1407 | enum plane plane) |
1832 | enum plane plane) |
1408 | { |
1833 | { |
1409 | I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane))); |
1834 | I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane))); |
Line 1459... | Line 1884... | ||
1459 | I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); |
1884 | I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); |
1460 | intel_flush_display_plane(dev_priv, plane); |
1885 | intel_flush_display_plane(dev_priv, plane); |
1461 | intel_wait_for_vblank(dev_priv->dev, pipe); |
1886 | intel_wait_for_vblank(dev_priv->dev, pipe); |
1462 | } |
1887 | } |
Line 1463... | Line -... | ||
1463 | - | ||
1464 | static void disable_pch_dp(struct drm_i915_private *dev_priv, |
- | |
1465 | enum pipe pipe, int reg, u32 port_sel) |
- | |
1466 | { |
- | |
1467 | u32 val = I915_READ(reg); |
- | |
1468 | if (dp_pipe_enabled(dev_priv, pipe, port_sel, val)) { |
- | |
1469 | DRM_DEBUG_KMS("Disabling pch dp %x on pipe %d\n", reg, pipe); |
- | |
1470 | I915_WRITE(reg, val & ~DP_PORT_EN); |
- | |
1471 | } |
- | |
1472 | } |
- | |
1473 | - | ||
1474 | static void disable_pch_hdmi(struct drm_i915_private *dev_priv, |
- | |
1475 | enum pipe pipe, int reg) |
- | |
1476 | { |
- | |
1477 | u32 val = I915_READ(reg); |
- | |
1478 | if (hdmi_pipe_enabled(dev_priv, val, pipe)) { |
- | |
1479 | DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", |
- | |
1480 | reg, pipe); |
- | |
1481 | I915_WRITE(reg, val & ~PORT_ENABLE); |
- | |
1482 | } |
- | |
1483 | } |
- | |
1484 | - | ||
1485 | /* Disable any ports connected to this transcoder */ |
- | |
1486 | static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, |
- | |
1487 | enum pipe pipe) |
- | |
1488 | { |
- | |
1489 | u32 reg, val; |
- | |
1490 | - | ||
1491 | val = I915_READ(PCH_PP_CONTROL); |
- | |
1492 | I915_WRITE(PCH_PP_CONTROL, val | PANEL_UNLOCK_REGS); |
- | |
1493 | - | ||
1494 | disable_pch_dp(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B); |
- | |
1495 | disable_pch_dp(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); |
- | |
1496 | disable_pch_dp(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); |
- | |
1497 | - | ||
1498 | reg = PCH_ADPA; |
- | |
1499 | val = I915_READ(reg); |
- | |
1500 | if (adpa_pipe_enabled(dev_priv, val, pipe)) |
- | |
1501 | I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); |
- | |
1502 | - | ||
1503 | reg = PCH_LVDS; |
- | |
1504 | val = I915_READ(reg); |
- | |
1505 | if (lvds_pipe_enabled(dev_priv, val, pipe)) { |
- | |
1506 | DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val); |
- | |
1507 | I915_WRITE(reg, val & ~LVDS_PORT_EN); |
- | |
1508 | POSTING_READ(reg); |
- | |
1509 | udelay(100); |
- | |
1510 | } |
- | |
1511 | - | ||
1512 | disable_pch_hdmi(dev_priv, pipe, HDMIB); |
- | |
1513 | disable_pch_hdmi(dev_priv, pipe, HDMIC); |
- | |
1514 | disable_pch_hdmi(dev_priv, pipe, HDMID); |
- | |
1515 | } |
- | |
1516 | - | ||
1517 | static void i8xx_disable_fbc(struct drm_device *dev) |
- | |
1518 | { |
- | |
1519 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1520 | u32 fbc_ctl; |
- | |
1521 | - | ||
1522 | /* Disable compression */ |
- | |
1523 | fbc_ctl = I915_READ(FBC_CONTROL); |
- | |
1524 | if ((fbc_ctl & FBC_CTL_EN) == 0) |
- | |
1525 | return; |
- | |
1526 | - | ||
1527 | fbc_ctl &= ~FBC_CTL_EN; |
- | |
1528 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
- | |
1529 | - | ||
1530 | /* Wait for compressing bit to clear */ |
- | |
1531 | if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10)) { |
- | |
1532 | DRM_DEBUG_KMS("FBC idle timed out\n"); |
- | |
1533 | return; |
- | |
1534 | } |
- | |
1535 | - | ||
1536 | DRM_DEBUG_KMS("disabled FBC\n"); |
- | |
1537 | } |
- | |
1538 | - | ||
1539 | static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) |
- | |
1540 | { |
- | |
1541 | struct drm_device *dev = crtc->dev; |
- | |
1542 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1543 | struct drm_framebuffer *fb = crtc->fb; |
- | |
1544 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
- | |
1545 | struct drm_i915_gem_object *obj = intel_fb->obj; |
- | |
1546 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
1547 | int cfb_pitch; |
- | |
1548 | int plane, i; |
- | |
1549 | u32 fbc_ctl, fbc_ctl2; |
- | |
1550 | - | ||
1551 | cfb_pitch = dev_priv->cfb_size / FBC_LL_SIZE; |
- | |
1552 | if (fb->pitches[0] < cfb_pitch) |
- | |
1553 | cfb_pitch = fb->pitches[0]; |
- | |
1554 | - | ||
1555 | /* FBC_CTL wants 64B units */ |
- | |
1556 | cfb_pitch = (cfb_pitch / 64) - 1; |
- | |
1557 | plane = intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB; |
- | |
1558 | - | ||
1559 | /* Clear old tags */ |
- | |
1560 | for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++) |
- | |
1561 | I915_WRITE(FBC_TAG + (i * 4), 0); |
- | |
1562 | - | ||
1563 | /* Set it up... */ |
- | |
1564 | fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE; |
- | |
1565 | fbc_ctl2 |= plane; |
- | |
1566 | I915_WRITE(FBC_CONTROL2, fbc_ctl2); |
- | |
1567 | I915_WRITE(FBC_FENCE_OFF, crtc->y); |
- | |
1568 | - | ||
1569 | /* enable it... */ |
- | |
1570 | fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC; |
- | |
1571 | if (IS_I945GM(dev)) |
- | |
1572 | fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ |
- | |
1573 | fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; |
- | |
1574 | fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; |
- | |
1575 | fbc_ctl |= obj->fence_reg; |
- | |
1576 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
- | |
1577 | - | ||
1578 | DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %d, ", |
- | |
1579 | cfb_pitch, crtc->y, intel_crtc->plane); |
- | |
1580 | } |
- | |
1581 | - | ||
1582 | static bool i8xx_fbc_enabled(struct drm_device *dev) |
- | |
1583 | { |
- | |
1584 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1585 | - | ||
1586 | return I915_READ(FBC_CONTROL) & FBC_CTL_EN; |
- | |
1587 | } |
- | |
1588 | - | ||
1589 | static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) |
- | |
1590 | { |
- | |
1591 | struct drm_device *dev = crtc->dev; |
- | |
1592 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1593 | struct drm_framebuffer *fb = crtc->fb; |
- | |
1594 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
- | |
1595 | struct drm_i915_gem_object *obj = intel_fb->obj; |
- | |
1596 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
1597 | int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; |
- | |
1598 | unsigned long stall_watermark = 200; |
- | |
1599 | u32 dpfc_ctl; |
- | |
1600 | - | ||
1601 | dpfc_ctl = plane | DPFC_SR_EN | DPFC_CTL_LIMIT_1X; |
- | |
1602 | dpfc_ctl |= DPFC_CTL_FENCE_EN | obj->fence_reg; |
- | |
1603 | I915_WRITE(DPFC_CHICKEN, DPFC_HT_MODIFY); |
- | |
1604 | - | ||
1605 | I915_WRITE(DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | |
- | |
1606 | (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | |
- | |
1607 | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); |
- | |
1608 | I915_WRITE(DPFC_FENCE_YOFF, crtc->y); |
- | |
1609 | - | ||
1610 | /* enable it... */ |
- | |
1611 | I915_WRITE(DPFC_CONTROL, I915_READ(DPFC_CONTROL) | DPFC_CTL_EN); |
- | |
1612 | - | ||
1613 | DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); |
- | |
1614 | } |
- | |
1615 | - | ||
1616 | static void g4x_disable_fbc(struct drm_device *dev) |
- | |
1617 | { |
- | |
1618 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1619 | u32 dpfc_ctl; |
- | |
1620 | - | ||
1621 | /* Disable compression */ |
- | |
1622 | dpfc_ctl = I915_READ(DPFC_CONTROL); |
- | |
1623 | if (dpfc_ctl & DPFC_CTL_EN) { |
- | |
1624 | dpfc_ctl &= ~DPFC_CTL_EN; |
- | |
1625 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); |
- | |
1626 | - | ||
1627 | DRM_DEBUG_KMS("disabled FBC\n"); |
- | |
1628 | } |
- | |
1629 | } |
- | |
1630 | - | ||
1631 | static bool g4x_fbc_enabled(struct drm_device *dev) |
- | |
1632 | { |
- | |
1633 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1634 | - | ||
1635 | return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; |
- | |
1636 | } |
- | |
1637 | - | ||
1638 | static void sandybridge_blit_fbc_update(struct drm_device *dev) |
- | |
1639 | { |
- | |
1640 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1641 | u32 blt_ecoskpd; |
- | |
1642 | - | ||
1643 | /* Make sure blitter notifies FBC of writes */ |
- | |
1644 | gen6_gt_force_wake_get(dev_priv); |
- | |
1645 | blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD); |
- | |
1646 | blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY << |
- | |
1647 | GEN6_BLITTER_LOCK_SHIFT; |
- | |
1648 | I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); |
- | |
1649 | blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY; |
- | |
1650 | I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); |
- | |
1651 | blt_ecoskpd &= ~(GEN6_BLITTER_FBC_NOTIFY << |
- | |
1652 | GEN6_BLITTER_LOCK_SHIFT); |
- | |
1653 | I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); |
- | |
1654 | POSTING_READ(GEN6_BLITTER_ECOSKPD); |
- | |
1655 | gen6_gt_force_wake_put(dev_priv); |
- | |
1656 | } |
- | |
1657 | - | ||
1658 | static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) |
- | |
1659 | { |
- | |
1660 | struct drm_device *dev = crtc->dev; |
- | |
1661 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1662 | struct drm_framebuffer *fb = crtc->fb; |
- | |
1663 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
- | |
1664 | struct drm_i915_gem_object *obj = intel_fb->obj; |
- | |
1665 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
1666 | int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; |
- | |
1667 | unsigned long stall_watermark = 200; |
- | |
1668 | u32 dpfc_ctl; |
- | |
1669 | - | ||
1670 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); |
- | |
1671 | dpfc_ctl &= DPFC_RESERVED; |
- | |
1672 | dpfc_ctl |= (plane | DPFC_CTL_LIMIT_1X); |
- | |
1673 | /* Set persistent mode for front-buffer rendering, ala X. */ |
- | |
1674 | dpfc_ctl |= DPFC_CTL_PERSISTENT_MODE; |
- | |
1675 | dpfc_ctl |= (DPFC_CTL_FENCE_EN | obj->fence_reg); |
- | |
1676 | I915_WRITE(ILK_DPFC_CHICKEN, DPFC_HT_MODIFY); |
- | |
1677 | - | ||
1678 | I915_WRITE(ILK_DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | |
- | |
1679 | (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | |
- | |
1680 | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); |
- | |
1681 | I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); |
- | |
1682 | I915_WRITE(ILK_FBC_RT_BASE, obj->gtt_offset | ILK_FBC_RT_VALID); |
- | |
1683 | /* enable it... */ |
- | |
1684 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); |
- | |
1685 | - | ||
1686 | if (IS_GEN6(dev)) { |
- | |
1687 | I915_WRITE(SNB_DPFC_CTL_SA, |
- | |
1688 | SNB_CPU_FENCE_ENABLE | obj->fence_reg); |
- | |
1689 | I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y); |
- | |
1690 | sandybridge_blit_fbc_update(dev); |
- | |
1691 | } |
- | |
1692 | - | ||
1693 | DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); |
- | |
1694 | } |
- | |
1695 | - | ||
1696 | static void ironlake_disable_fbc(struct drm_device *dev) |
- | |
1697 | { |
- | |
1698 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1699 | u32 dpfc_ctl; |
- | |
1700 | - | ||
1701 | /* Disable compression */ |
- | |
1702 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); |
- | |
1703 | if (dpfc_ctl & DPFC_CTL_EN) { |
- | |
1704 | dpfc_ctl &= ~DPFC_CTL_EN; |
- | |
1705 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); |
- | |
1706 | - | ||
1707 | DRM_DEBUG_KMS("disabled FBC\n"); |
- | |
1708 | } |
- | |
1709 | } |
- | |
1710 | - | ||
1711 | static bool ironlake_fbc_enabled(struct drm_device *dev) |
- | |
1712 | { |
- | |
1713 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1714 | - | ||
1715 | return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN; |
- | |
1716 | } |
- | |
1717 | - | ||
1718 | bool intel_fbc_enabled(struct drm_device *dev) |
- | |
1719 | { |
- | |
1720 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1721 | - | ||
1722 | if (!dev_priv->display.fbc_enabled) |
- | |
1723 | return false; |
- | |
1724 | - | ||
1725 | return dev_priv->display.fbc_enabled(dev); |
- | |
1726 | } |
- | |
1727 | - | ||
1728 | - | ||
1729 | - | ||
1730 | - | ||
1731 | - | ||
1732 | - | ||
1733 | - | ||
1734 | - | ||
1735 | - | ||
1736 | - | ||
1737 | static void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) |
- | |
1738 | { |
- | |
1739 | struct intel_fbc_work *work; |
- | |
1740 | struct drm_device *dev = crtc->dev; |
- | |
1741 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1742 | - | ||
1743 | if (!dev_priv->display.enable_fbc) |
- | |
1744 | return; |
- | |
1745 | - | ||
1746 | // intel_cancel_fbc_work(dev_priv); |
- | |
1747 | - | ||
1748 | // work = kzalloc(sizeof *work, GFP_KERNEL); |
- | |
1749 | // if (work == NULL) { |
- | |
1750 | // dev_priv->display.enable_fbc(crtc, interval); |
- | |
1751 | // return; |
- | |
1752 | // } |
- | |
1753 | - | ||
1754 | // work->crtc = crtc; |
- | |
1755 | // work->fb = crtc->fb; |
- | |
1756 | // work->interval = interval; |
- | |
1757 | // INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn); |
- | |
1758 | - | ||
1759 | // dev_priv->fbc_work = work; |
- | |
1760 | - | ||
1761 | DRM_DEBUG_KMS("scheduling delayed FBC enable\n"); |
- | |
1762 | - | ||
1763 | /* Delay the actual enabling to let pageflipping cease and the |
- | |
1764 | * display to settle before starting the compression. Note that |
- | |
1765 | * this delay also serves a second purpose: it allows for a |
- | |
1766 | * vblank to pass after disabling the FBC before we attempt |
- | |
1767 | * to modify the control registers. |
- | |
1768 | * |
- | |
1769 | * A more complicated solution would involve tracking vblanks |
- | |
1770 | * following the termination of the page-flipping sequence |
- | |
1771 | * and indeed performing the enable as a co-routine and not |
- | |
1772 | * waiting synchronously upon the vblank. |
- | |
1773 | */ |
- | |
1774 | // schedule_delayed_work(&work->work, msecs_to_jiffies(50)); |
- | |
1775 | } |
- | |
1776 | - | ||
1777 | void intel_disable_fbc(struct drm_device *dev) |
- | |
1778 | { |
- | |
1779 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1780 | - | ||
1781 | // intel_cancel_fbc_work(dev_priv); |
- | |
1782 | - | ||
1783 | if (!dev_priv->display.disable_fbc) |
- | |
1784 | return; |
- | |
1785 | - | ||
1786 | dev_priv->display.disable_fbc(dev); |
- | |
1787 | dev_priv->cfb_plane = -1; |
- | |
1788 | } |
- | |
1789 | - | ||
1790 | /** |
- | |
1791 | * intel_update_fbc - enable/disable FBC as needed |
- | |
1792 | * @dev: the drm_device |
- | |
1793 | * |
- | |
1794 | * Set up the framebuffer compression hardware at mode set time. We |
- | |
1795 | * enable it if possible: |
- | |
1796 | * - plane A only (on pre-965) |
- | |
1797 | * - no pixel mulitply/line duplication |
- | |
1798 | * - no alpha buffer discard |
- | |
1799 | * - no dual wide |
- | |
1800 | * - framebuffer <= 2048 in width, 1536 in height |
- | |
1801 | * |
- | |
1802 | * We can't assume that any compression will take place (worst case), |
- | |
1803 | * so the compressed buffer has to be the same size as the uncompressed |
- | |
1804 | * one. It also must reside (along with the line length buffer) in |
- | |
1805 | * stolen memory. |
- | |
1806 | * |
- | |
1807 | * We need to enable/disable FBC on a global basis. |
- | |
1808 | */ |
- | |
1809 | static void intel_update_fbc(struct drm_device *dev) |
- | |
1810 | { |
- | |
1811 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1812 | struct drm_crtc *crtc = NULL, *tmp_crtc; |
- | |
1813 | struct intel_crtc *intel_crtc; |
- | |
1814 | struct drm_framebuffer *fb; |
- | |
1815 | struct intel_framebuffer *intel_fb; |
- | |
1816 | struct drm_i915_gem_object *obj; |
- | |
1817 | int enable_fbc; |
- | |
1818 | - | ||
1819 | DRM_DEBUG_KMS("\n"); |
- | |
1820 | - | ||
1821 | if (!i915_powersave) |
- | |
1822 | return; |
- | |
1823 | - | ||
1824 | if (!I915_HAS_FBC(dev)) |
- | |
1825 | return; |
- | |
1826 | - | ||
1827 | /* |
- | |
1828 | * If FBC is already on, we just have to verify that we can |
- | |
1829 | * keep it that way... |
- | |
1830 | * Need to disable if: |
- | |
1831 | * - more than one pipe is active |
- | |
1832 | * - changing FBC params (stride, fence, mode) |
- | |
1833 | * - new fb is too large to fit in compressed buffer |
- | |
1834 | * - going to an unsupported config (interlace, pixel multiply, etc.) |
- | |
1835 | */ |
- | |
1836 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { |
- | |
1837 | if (tmp_crtc->enabled && tmp_crtc->fb) { |
- | |
1838 | if (crtc) { |
- | |
1839 | DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); |
- | |
1840 | dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; |
- | |
1841 | goto out_disable; |
- | |
1842 | } |
- | |
1843 | crtc = tmp_crtc; |
- | |
1844 | } |
- | |
1845 | } |
- | |
1846 | - | ||
1847 | if (!crtc || crtc->fb == NULL) { |
- | |
1848 | DRM_DEBUG_KMS("no output, disabling\n"); |
- | |
1849 | dev_priv->no_fbc_reason = FBC_NO_OUTPUT; |
- | |
1850 | goto out_disable; |
- | |
1851 | } |
- | |
1852 | - | ||
1853 | intel_crtc = to_intel_crtc(crtc); |
- | |
1854 | fb = crtc->fb; |
- | |
1855 | intel_fb = to_intel_framebuffer(fb); |
- | |
1856 | obj = intel_fb->obj; |
- | |
1857 | - | ||
1858 | enable_fbc = i915_enable_fbc; |
- | |
1859 | if (enable_fbc < 0) { |
- | |
1860 | DRM_DEBUG_KMS("fbc set to per-chip default\n"); |
- | |
1861 | enable_fbc = 1; |
- | |
1862 | if (INTEL_INFO(dev)->gen <= 6) |
- | |
1863 | enable_fbc = 0; |
- | |
1864 | } |
- | |
1865 | if (!enable_fbc) { |
- | |
1866 | DRM_DEBUG_KMS("fbc disabled per module param\n"); |
- | |
1867 | dev_priv->no_fbc_reason = FBC_MODULE_PARAM; |
- | |
1868 | goto out_disable; |
- | |
1869 | } |
- | |
1870 | if (intel_fb->obj->base.size > dev_priv->cfb_size) { |
- | |
1871 | DRM_DEBUG_KMS("framebuffer too large, disabling " |
- | |
1872 | "compression\n"); |
- | |
1873 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; |
- | |
1874 | goto out_disable; |
- | |
1875 | } |
- | |
1876 | if ((crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) || |
- | |
1877 | (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)) { |
- | |
1878 | DRM_DEBUG_KMS("mode incompatible with compression, " |
- | |
1879 | "disabling\n"); |
- | |
1880 | dev_priv->no_fbc_reason = FBC_UNSUPPORTED_MODE; |
- | |
1881 | goto out_disable; |
- | |
1882 | } |
- | |
1883 | if ((crtc->mode.hdisplay > 2048) || |
- | |
1884 | (crtc->mode.vdisplay > 1536)) { |
- | |
1885 | DRM_DEBUG_KMS("mode too large for compression, disabling\n"); |
- | |
1886 | dev_priv->no_fbc_reason = FBC_MODE_TOO_LARGE; |
- | |
1887 | goto out_disable; |
- | |
1888 | } |
- | |
1889 | if ((IS_I915GM(dev) || IS_I945GM(dev)) && intel_crtc->plane != 0) { |
- | |
1890 | DRM_DEBUG_KMS("plane not 0, disabling compression\n"); |
- | |
1891 | dev_priv->no_fbc_reason = FBC_BAD_PLANE; |
- | |
1892 | goto out_disable; |
- | |
1893 | } |
- | |
1894 | - | ||
1895 | /* The use of a CPU fence is mandatory in order to detect writes |
- | |
1896 | * by the CPU to the scanout and trigger updates to the FBC. |
- | |
1897 | */ |
- | |
1898 | // if (obj->tiling_mode != I915_TILING_X || |
- | |
1899 | // obj->fence_reg == I915_FENCE_REG_NONE) { |
- | |
1900 | // DRM_DEBUG_KMS("framebuffer not tiled or fenced, disabling compression\n"); |
- | |
1901 | // dev_priv->no_fbc_reason = FBC_NOT_TILED; |
- | |
1902 | // goto out_disable; |
- | |
1903 | // } |
- | |
1904 | - | ||
1905 | /* If the kernel debugger is active, always disable compression */ |
- | |
1906 | if (in_dbg_master()) |
- | |
1907 | goto out_disable; |
- | |
1908 | - | ||
1909 | /* If the scanout has not changed, don't modify the FBC settings. |
- | |
1910 | * Note that we make the fundamental assumption that the fb->obj |
- | |
1911 | * cannot be unpinned (and have its GTT offset and fence revoked) |
- | |
1912 | * without first being decoupled from the scanout and FBC disabled. |
- | |
1913 | */ |
- | |
1914 | if (dev_priv->cfb_plane == intel_crtc->plane && |
- | |
1915 | dev_priv->cfb_fb == fb->base.id && |
- | |
1916 | dev_priv->cfb_y == crtc->y) |
- | |
1917 | return; |
- | |
1918 | - | ||
1919 | if (intel_fbc_enabled(dev)) { |
- | |
1920 | /* We update FBC along two paths, after changing fb/crtc |
- | |
1921 | * configuration (modeswitching) and after page-flipping |
- | |
1922 | * finishes. For the latter, we know that not only did |
- | |
1923 | * we disable the FBC at the start of the page-flip |
- | |
1924 | * sequence, but also more than one vblank has passed. |
- | |
1925 | * |
- | |
1926 | * For the former case of modeswitching, it is possible |
- | |
1927 | * to switch between two FBC valid configurations |
- | |
1928 | * instantaneously so we do need to disable the FBC |
- | |
1929 | * before we can modify its control registers. We also |
- | |
1930 | * have to wait for the next vblank for that to take |
- | |
1931 | * effect. However, since we delay enabling FBC we can |
- | |
1932 | * assume that a vblank has passed since disabling and |
- | |
1933 | * that we can safely alter the registers in the deferred |
- | |
1934 | * callback. |
- | |
1935 | * |
- | |
1936 | * In the scenario that we go from a valid to invalid |
- | |
1937 | * and then back to valid FBC configuration we have |
- | |
1938 | * no strict enforcement that a vblank occurred since |
- | |
1939 | * disabling the FBC. However, along all current pipe |
- | |
1940 | * disabling paths we do need to wait for a vblank at |
- | |
1941 | * some point. And we wait before enabling FBC anyway. |
- | |
1942 | */ |
- | |
1943 | DRM_DEBUG_KMS("disabling active FBC for update\n"); |
- | |
1944 | intel_disable_fbc(dev); |
- | |
1945 | } |
- | |
1946 | - | ||
1947 | intel_enable_fbc(crtc, 500); |
- | |
1948 | return; |
- | |
1949 | - | ||
1950 | out_disable: |
- | |
1951 | /* Multiple disables should be harmless */ |
- | |
1952 | if (intel_fbc_enabled(dev)) { |
- | |
1953 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); |
- | |
1954 | intel_disable_fbc(dev); |
- | |
1955 | } |
- | |
1956 | } |
- | |
1957 | 1888 | ||
1958 | int |
1889 | int |
1959 | intel_pin_and_fence_fb_obj(struct drm_device *dev, |
1890 | intel_pin_and_fence_fb_obj(struct drm_device *dev, |
1960 | struct drm_i915_gem_object *obj, |
1891 | struct drm_i915_gem_object *obj, |
1961 | struct intel_ring_buffer *pipelined) |
1892 | struct intel_ring_buffer *pipelined) |
Line 2009... | Line 1940... | ||
2009 | err_interruptible: |
1940 | err_interruptible: |
2010 | dev_priv->mm.interruptible = true; |
1941 | dev_priv->mm.interruptible = true; |
2011 | return ret; |
1942 | return ret; |
2012 | } |
1943 | } |
Line -... | Line 1944... | ||
- | 1944 | ||
- | 1945 | void intel_unpin_fb_obj(struct drm_i915_gem_object *obj) |
|
- | 1946 | { |
|
- | 1947 | // i915_gem_object_unpin_fence(obj); |
|
- | 1948 | // i915_gem_object_unpin(obj); |
|
- | 1949 | } |
|
- | 1950 | ||
- | 1951 | /* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel |
|
- | 1952 | * is assumed to be a power-of-two. */ |
|
- | 1953 | static unsigned long gen4_compute_dspaddr_offset_xtiled(int *x, int *y, |
|
- | 1954 | unsigned int bpp, |
|
- | 1955 | unsigned int pitch) |
|
- | 1956 | { |
|
- | 1957 | int tile_rows, tiles; |
|
- | 1958 | ||
- | 1959 | tile_rows = *y / 8; |
|
- | 1960 | *y %= 8; |
|
- | 1961 | tiles = *x / (512/bpp); |
|
- | 1962 | *x %= 512/bpp; |
|
- | 1963 | ||
- | 1964 | return tile_rows * pitch * 8 + tiles * 4096; |
|
- | 1965 | } |
|
2013 | 1966 | ||
2014 | static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
1967 | static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
2015 | int x, int y) |
1968 | int x, int y) |
2016 | { |
1969 | { |
2017 | struct drm_device *dev = crtc->dev; |
1970 | struct drm_device *dev = crtc->dev; |
2018 | struct drm_i915_private *dev_priv = dev->dev_private; |
1971 | struct drm_i915_private *dev_priv = dev->dev_private; |
2019 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1972 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2020 | struct intel_framebuffer *intel_fb; |
1973 | struct intel_framebuffer *intel_fb; |
2021 | struct drm_i915_gem_object *obj; |
1974 | struct drm_i915_gem_object *obj; |
2022 | int plane = intel_crtc->plane; |
1975 | int plane = intel_crtc->plane; |
2023 | unsigned long Start, Offset; |
1976 | unsigned long linear_offset; |
2024 | u32 dspcntr; |
1977 | u32 dspcntr; |
Line 2025... | Line 1978... | ||
2025 | u32 reg; |
1978 | u32 reg; |
2026 | 1979 | ||
Line 2065... | Line 2018... | ||
2065 | dspcntr &= ~DISPPLANE_TILED; |
2018 | dspcntr &= ~DISPPLANE_TILED; |
2066 | } |
2019 | } |
Line 2067... | Line 2020... | ||
2067 | 2020 | ||
Line -... | Line 2021... | ||
- | 2021 | I915_WRITE(reg, dspcntr); |
|
- | 2022 | ||
- | 2023 | linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); |
|
2068 | I915_WRITE(reg, dspcntr); |
2024 | |
- | 2025 | if (INTEL_INFO(dev)->gen >= 4) { |
|
2069 | 2026 | intel_crtc->dspaddr_offset = |
|
- | 2027 | gen4_compute_dspaddr_offset_xtiled(&x, &y, |
|
- | 2028 | fb->bits_per_pixel / 8, |
|
- | 2029 | fb->pitches[0]); |
|
- | 2030 | linear_offset -= intel_crtc->dspaddr_offset; |
|
- | 2031 | } else { |
|
Line 2070... | Line 2032... | ||
2070 | Start = obj->gtt_offset; |
2032 | intel_crtc->dspaddr_offset = linear_offset; |
2071 | Offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); |
2033 | } |
2072 | 2034 | ||
2073 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", |
2035 | DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n", |
2074 | Start, Offset, x, y, fb->pitches[0]); |
2036 | obj->gtt_offset, linear_offset, x, y, fb->pitches[0]); |
- | 2037 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); |
|
2075 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); |
2038 | if (INTEL_INFO(dev)->gen >= 4) { |
2076 | if (INTEL_INFO(dev)->gen >= 4) { |
2039 | I915_MODIFY_DISPBASE(DSPSURF(plane), |
2077 | I915_WRITE(DSPSURF(plane), Start); |
2040 | obj->gtt_offset + intel_crtc->dspaddr_offset); |
2078 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); |
2041 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); |
2079 | I915_WRITE(DSPADDR(plane), Offset); |
2042 | I915_WRITE(DSPLINOFF(plane), linear_offset); |
Line 2080... | Line 2043... | ||
2080 | } else |
2043 | } else |
2081 | I915_WRITE(DSPADDR(plane), Start + Offset); |
2044 | I915_WRITE(DSPADDR(plane), obj->gtt_offset + linear_offset); |
Line 2091... | Line 2054... | ||
2091 | struct drm_i915_private *dev_priv = dev->dev_private; |
2054 | struct drm_i915_private *dev_priv = dev->dev_private; |
2092 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2055 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2093 | struct intel_framebuffer *intel_fb; |
2056 | struct intel_framebuffer *intel_fb; |
2094 | struct drm_i915_gem_object *obj; |
2057 | struct drm_i915_gem_object *obj; |
2095 | int plane = intel_crtc->plane; |
2058 | int plane = intel_crtc->plane; |
2096 | unsigned long Start, Offset; |
2059 | unsigned long linear_offset; |
2097 | u32 dspcntr; |
2060 | u32 dspcntr; |
2098 | u32 reg; |
2061 | u32 reg; |
Line 2099... | Line 2062... | ||
2099 | 2062 | ||
2100 | switch (plane) { |
2063 | switch (plane) { |
Line 2146... | Line 2109... | ||
2146 | /* must disable */ |
2109 | /* must disable */ |
2147 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; |
2110 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; |
Line 2148... | Line 2111... | ||
2148 | 2111 | ||
Line -... | Line 2112... | ||
- | 2112 | I915_WRITE(reg, dspcntr); |
|
2149 | I915_WRITE(reg, dspcntr); |
2113 | |
- | 2114 | linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); |
|
2150 | 2115 | intel_crtc->dspaddr_offset = |
|
- | 2116 | gen4_compute_dspaddr_offset_xtiled(&x, &y, |
|
- | 2117 | fb->bits_per_pixel / 8, |
|
Line 2151... | Line 2118... | ||
2151 | Start = obj->gtt_offset; |
2118 | fb->pitches[0]); |
2152 | Offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); |
2119 | linear_offset -= intel_crtc->dspaddr_offset; |
2153 | 2120 | ||
2154 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", |
2121 | DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n", |
- | 2122 | obj->gtt_offset, linear_offset, x, y, fb->pitches[0]); |
|
2155 | Start, Offset, x, y, fb->pitches[0]); |
2123 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); |
2156 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); |
2124 | I915_MODIFY_DISPBASE(DSPSURF(plane), |
2157 | I915_WRITE(DSPSURF(plane), Start); |
2125 | obj->gtt_offset + intel_crtc->dspaddr_offset); |
Line 2158... | Line 2126... | ||
2158 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); |
2126 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); |
2159 | I915_WRITE(DSPADDR(plane), Offset); |
2127 | I915_WRITE(DSPLINOFF(plane), linear_offset); |
Line 2167... | Line 2135... | ||
2167 | intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
2135 | intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
2168 | int x, int y, enum mode_set_atomic state) |
2136 | int x, int y, enum mode_set_atomic state) |
2169 | { |
2137 | { |
2170 | struct drm_device *dev = crtc->dev; |
2138 | struct drm_device *dev = crtc->dev; |
2171 | struct drm_i915_private *dev_priv = dev->dev_private; |
2139 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | 2140 | ||
- | 2141 | if (dev_priv->display.disable_fbc) |
|
- | 2142 | dev_priv->display.disable_fbc(dev); |
|
- | 2143 | intel_increase_pllclock(crtc); |
|
- | 2144 | ||
- | 2145 | return dev_priv->display.update_plane(crtc, fb, x, y); |
|
- | 2146 | } |
|
- | 2147 | ||
- | 2148 | #if 0 |
|
- | 2149 | static int |
|
- | 2150 | intel_finish_fb(struct drm_framebuffer *old_fb) |
|
- | 2151 | { |
|
- | 2152 | struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj; |
|
- | 2153 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; |
|
- | 2154 | bool was_interruptible = dev_priv->mm.interruptible; |
|
2172 | int ret; |
2155 | int ret; |
Line 2173... | Line 2156... | ||
2173 | 2156 | ||
2174 | ret = dev_priv->display.update_plane(crtc, fb, x, y); |
2157 | wait_event(dev_priv->pending_flip_queue, |
2175 | if (ret) |
2158 | atomic_read(&dev_priv->mm.wedged) || |
Line -... | Line 2159... | ||
- | 2159 | atomic_read(&obj->pending_flip) == 0); |
|
- | 2160 | ||
- | 2161 | /* Big Hammer, we also need to ensure that any pending |
|
- | 2162 | * MI_WAIT_FOR_EVENT inside a user batch buffer on the |
|
- | 2163 | * current scanout is retired before unpinning the old |
|
- | 2164 | * framebuffer. |
|
2176 | return ret; |
2165 | * |
- | 2166 | * This should only fail upon a hung GPU, in which case we |
|
- | 2167 | * can safely continue. |
|
2177 | 2168 | */ |
|
- | 2169 | dev_priv->mm.interruptible = false; |
|
Line 2178... | Line 2170... | ||
2178 | intel_update_fbc(dev); |
2170 | ret = i915_gem_object_finish_gpu(obj); |
2179 | intel_increase_pllclock(crtc); |
2171 | dev_priv->mm.interruptible = was_interruptible; |
- | 2172 | ||
Line 2180... | Line 2173... | ||
2180 | 2173 | return ret; |
|
2181 | return 0; |
2174 | } |
2182 | } |
2175 | #endif |
2183 | 2176 | ||
2184 | static int |
2177 | static int |
- | 2178 | intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, |
|
2185 | intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, |
2179 | struct drm_framebuffer *fb) |
2186 | struct drm_framebuffer *old_fb) |
2180 | { |
- | 2181 | struct drm_device *dev = crtc->dev; |
|
2187 | { |
2182 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 2188... | Line -... | ||
2188 | struct drm_device *dev = crtc->dev; |
- | |
2189 | struct drm_i915_master_private *master_priv; |
- | |
2190 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2183 | struct drm_i915_master_private *master_priv; |
2191 | int ret; |
2184 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2192 | 2185 | struct drm_framebuffer *old_fb; |
|
2193 | ENTER(); |
2186 | int ret; |
2194 | 2187 | ||
Line 2195... | Line 2188... | ||
2195 | /* no fb bound */ |
2188 | /* no fb bound */ |
2196 | if (!crtc->fb) { |
- | |
2197 | DRM_ERROR("No FB bound\n"); |
- | |
2198 | return 0; |
- | |
2199 | } |
- | |
2200 | - | ||
2201 | switch (intel_crtc->plane) { |
- | |
2202 | case 0: |
2189 | if (!fb) { |
2203 | case 1: |
2190 | DRM_ERROR("No FB bound\n"); |
2204 | break; |
2191 | return 0; |
2205 | case 2: |
2192 | } |
2206 | if (IS_IVYBRIDGE(dev)) |
2193 | |
Line 2207... | Line 2194... | ||
2207 | break; |
2194 | if(intel_crtc->plane > dev_priv->num_pipe) { |
- | 2195 | DRM_ERROR("no plane for crtc: plane %d, num_pipes %d\n", |
|
- | 2196 | intel_crtc->plane, |
|
- | 2197 | dev_priv->num_pipe); |
|
- | 2198 | return -EINVAL; |
|
- | 2199 | } |
|
- | 2200 | ||
- | 2201 | mutex_lock(&dev->struct_mutex); |
|
- | 2202 | // ret = intel_pin_and_fence_fb_obj(dev, |
|
Line -... | Line 2203... | ||
- | 2203 | // to_intel_framebuffer(fb)->obj, |
|
2208 | /* fall through otherwise */ |
2204 | // NULL); |
- | 2205 | // if (ret != 0) { |
|
2209 | default: |
2206 | // mutex_unlock(&dev->struct_mutex); |
2210 | DRM_ERROR("no plane for crtc\n"); |
2207 | // DRM_ERROR("pin & fence failed\n"); |
2211 | return -EINVAL; |
2208 | // return ret; |
2212 | } |
2209 | // } |
2213 | 2210 | ||
2214 | mutex_lock(&dev->struct_mutex); |
2211 | // if (crtc->fb) |
2215 | 2212 | // intel_finish_fb(crtc->fb); |
|
2216 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, |
2213 | |
Line 2217... | Line 2214... | ||
2217 | LEAVE_ATOMIC_MODE_SET); |
2214 | ret = dev_priv->display.update_plane(crtc, fb, x, y); |
- | 2215 | if (ret) { |
|
- | 2216 | intel_unpin_fb_obj(to_intel_framebuffer(fb)->obj); |
|
2218 | if (ret) { |
2217 | mutex_unlock(&dev->struct_mutex); |
Line 2219... | Line 2218... | ||
2219 | i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); |
2218 | DRM_ERROR("failed to update base address\n"); |
2220 | mutex_unlock(&dev->struct_mutex); |
2219 | LEAVE(); |
- | 2220 | return ret; |
|
- | 2221 | } |
|
Line -... | Line 2222... | ||
- | 2222 | ||
- | 2223 | old_fb = crtc->fb; |
|
Line -... | Line 2224... | ||
- | 2224 | crtc->fb = fb; |
|
2221 | DRM_ERROR("failed to update base address\n"); |
2225 | crtc->x = x; |
Line 2222... | Line 2226... | ||
2222 | LEAVE(); |
2226 | crtc->y = y; |
2223 | return ret; |
2227 | |
2224 | } |
2228 | if (old_fb) { |
Line 2431... | Line 2435... | ||
2431 | { |
2435 | { |
2432 | struct drm_device *dev = crtc->dev; |
2436 | struct drm_device *dev = crtc->dev; |
2433 | struct drm_i915_private *dev_priv = dev->dev_private; |
2437 | struct drm_i915_private *dev_priv = dev->dev_private; |
2434 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2438 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2435 | int pipe = intel_crtc->pipe; |
2439 | int pipe = intel_crtc->pipe; |
2436 | u32 reg, temp, i; |
2440 | u32 reg, temp, i, retry; |
Line 2437... | Line 2441... | ||
2437 | 2441 | ||
2438 | /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit |
2442 | /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit |
2439 | for train result */ |
2443 | for train result */ |
2440 | reg = FDI_RX_IMR(pipe); |
2444 | reg = FDI_RX_IMR(pipe); |
Line 2483... | Line 2487... | ||
2483 | I915_WRITE(reg, temp); |
2487 | I915_WRITE(reg, temp); |
Line 2484... | Line 2488... | ||
2484 | 2488 | ||
2485 | POSTING_READ(reg); |
2489 | POSTING_READ(reg); |
Line -... | Line 2490... | ||
- | 2490 | udelay(500); |
|
2486 | udelay(500); |
2491 | |
2487 | 2492 | for (retry = 0; retry < 5; retry++) { |
|
2488 | reg = FDI_RX_IIR(pipe); |
2493 | reg = FDI_RX_IIR(pipe); |
2489 | temp = I915_READ(reg); |
- | |
2490 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); |
2494 | temp = I915_READ(reg); |
2491 | 2495 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); |
|
2492 | if (temp & FDI_RX_BIT_LOCK) { |
2496 | if (temp & FDI_RX_BIT_LOCK) { |
2493 | I915_WRITE(reg, temp | FDI_RX_BIT_LOCK); |
2497 | I915_WRITE(reg, temp | FDI_RX_BIT_LOCK); |
2494 | DRM_DEBUG_KMS("FDI train 1 done.\n"); |
2498 | DRM_DEBUG_KMS("FDI train 1 done.\n"); |
- | 2499 | break; |
|
- | 2500 | } |
|
- | 2501 | udelay(50); |
|
- | 2502 | } |
|
2495 | break; |
2503 | if (retry < 5) |
2496 | } |
2504 | break; |
2497 | } |
2505 | } |
Line 2498... | Line 2506... | ||
2498 | if (i == 4) |
2506 | if (i == 4) |
Line 2532... | Line 2540... | ||
2532 | I915_WRITE(reg, temp); |
2540 | I915_WRITE(reg, temp); |
Line 2533... | Line 2541... | ||
2533 | 2541 | ||
2534 | POSTING_READ(reg); |
2542 | POSTING_READ(reg); |
Line -... | Line 2543... | ||
- | 2543 | udelay(500); |
|
2535 | udelay(500); |
2544 | |
2536 | 2545 | for (retry = 0; retry < 5; retry++) { |
|
2537 | reg = FDI_RX_IIR(pipe); |
2546 | reg = FDI_RX_IIR(pipe); |
2538 | temp = I915_READ(reg); |
- | |
2539 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); |
2547 | temp = I915_READ(reg); |
2540 | 2548 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); |
|
2541 | if (temp & FDI_RX_SYMBOL_LOCK) { |
2549 | if (temp & FDI_RX_SYMBOL_LOCK) { |
2542 | I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK); |
2550 | I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK); |
2543 | DRM_DEBUG_KMS("FDI train 2 done.\n"); |
2551 | DRM_DEBUG_KMS("FDI train 2 done.\n"); |
- | 2552 | break; |
|
- | 2553 | } |
|
- | 2554 | udelay(50); |
|
- | 2555 | } |
|
2544 | break; |
2556 | if (retry < 5) |
2545 | } |
2557 | break; |
2546 | } |
2558 | } |
Line 2547... | Line 2559... | ||
2547 | if (i == 4) |
2559 | if (i == 4) |
Line 2662... | Line 2674... | ||
2662 | DRM_ERROR("FDI train 2 fail!\n"); |
2674 | DRM_ERROR("FDI train 2 fail!\n"); |
Line 2663... | Line 2675... | ||
2663 | 2675 | ||
2664 | DRM_DEBUG_KMS("FDI train done.\n"); |
2676 | DRM_DEBUG_KMS("FDI train done.\n"); |
Line 2665... | Line 2677... | ||
2665 | } |
2677 | } |
2666 | 2678 | ||
2667 | static void ironlake_fdi_pll_enable(struct drm_crtc *crtc) |
2679 | static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc) |
2668 | { |
2680 | { |
2669 | struct drm_device *dev = crtc->dev; |
- | |
2670 | struct drm_i915_private *dev_priv = dev->dev_private; |
2681 | struct drm_device *dev = intel_crtc->base.dev; |
2671 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2682 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 2672... | Line 2683... | ||
2672 | int pipe = intel_crtc->pipe; |
2683 | int pipe = intel_crtc->pipe; |
2673 | u32 reg, temp; |
2684 | u32 reg, temp; |
Line 2692... | Line 2703... | ||
2692 | I915_WRITE(reg, temp | FDI_PCDCLK); |
2703 | I915_WRITE(reg, temp | FDI_PCDCLK); |
Line 2693... | Line 2704... | ||
2693 | 2704 | ||
2694 | POSTING_READ(reg); |
2705 | POSTING_READ(reg); |
Line -... | Line 2706... | ||
- | 2706 | udelay(200); |
|
- | 2707 | ||
- | 2708 | /* On Haswell, the PLL configuration for ports and pipes is handled |
|
2695 | udelay(200); |
2709 | * separately, as part of DDI setup */ |
2696 | 2710 | if (!IS_HASWELL(dev)) { |
|
2697 | /* Enable CPU FDI TX PLL, always on for Ironlake */ |
2711 | /* Enable CPU FDI TX PLL, always on for Ironlake */ |
2698 | reg = FDI_TX_CTL(pipe); |
2712 | reg = FDI_TX_CTL(pipe); |
2699 | temp = I915_READ(reg); |
2713 | temp = I915_READ(reg); |
Line 2700... | Line 2714... | ||
2700 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { |
2714 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { |
2701 | I915_WRITE(reg, temp | FDI_TX_PLL_ENABLE); |
2715 | I915_WRITE(reg, temp | FDI_TX_PLL_ENABLE); |
2702 | 2716 | ||
2703 | POSTING_READ(reg); |
2717 | POSTING_READ(reg); |
- | 2718 | udelay(100); |
|
- | 2719 | } |
|
- | 2720 | } |
|
- | 2721 | } |
|
- | 2722 | ||
- | 2723 | static void ironlake_fdi_pll_disable(struct intel_crtc *intel_crtc) |
|
- | 2724 | { |
|
- | 2725 | struct drm_device *dev = intel_crtc->base.dev; |
|
- | 2726 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 2727 | int pipe = intel_crtc->pipe; |
|
- | 2728 | u32 reg, temp; |
|
- | 2729 | ||
- | 2730 | /* Switch from PCDclk to Rawclk */ |
|
- | 2731 | reg = FDI_RX_CTL(pipe); |
|
- | 2732 | temp = I915_READ(reg); |
|
- | 2733 | I915_WRITE(reg, temp & ~FDI_PCDCLK); |
|
- | 2734 | ||
- | 2735 | /* Disable CPU FDI TX PLL */ |
|
- | 2736 | reg = FDI_TX_CTL(pipe); |
|
- | 2737 | temp = I915_READ(reg); |
|
- | 2738 | I915_WRITE(reg, temp & ~FDI_TX_PLL_ENABLE); |
|
- | 2739 | ||
- | 2740 | POSTING_READ(reg); |
|
- | 2741 | udelay(100); |
|
- | 2742 | ||
- | 2743 | reg = FDI_RX_CTL(pipe); |
|
- | 2744 | temp = I915_READ(reg); |
|
- | 2745 | I915_WRITE(reg, temp & ~FDI_RX_PLL_ENABLE); |
|
- | 2746 | ||
- | 2747 | /* Wait for the clocks to turn off. */ |
|
Line 2704... | Line 2748... | ||
2704 | udelay(100); |
2748 | POSTING_READ(reg); |
2705 | } |
2749 | udelay(100); |
2706 | } |
2750 | } |
2707 | 2751 | ||
Line 2772... | Line 2816... | ||
2772 | 2816 | ||
2773 | POSTING_READ(reg); |
2817 | POSTING_READ(reg); |
2774 | udelay(100); |
2818 | udelay(100); |
Line 2775... | Line -... | ||
2775 | } |
- | |
2776 | - | ||
2777 | /* |
- | |
2778 | * When we disable a pipe, we need to clear any pending scanline wait events |
- | |
2779 | * to avoid hanging the ring, which we assume we are waiting on. |
2819 | } |
2780 | */ |
2820 | |
- | 2821 | static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) |
|
2781 | static void intel_clear_scanline_wait(struct drm_device *dev) |
2822 | { |
2782 | { |
2823 | struct drm_device *dev = crtc->dev; |
2783 | struct drm_i915_private *dev_priv = dev->dev_private; |
2824 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 2784... | Line -... | ||
2784 | struct intel_ring_buffer *ring; |
- | |
2785 | u32 tmp; |
2825 | unsigned long flags; |
2786 | 2826 | bool pending; |
|
Line 2787... | Line 2827... | ||
2787 | if (IS_GEN2(dev)) |
2827 | |
2788 | /* Can't break the hang on i8xx */ |
2828 | if (atomic_read(&dev_priv->mm.wedged)) |
2789 | return; |
2829 | return false; |
- | 2830 | ||
2790 | 2831 | spin_lock_irqsave(&dev->event_lock, flags); |
|
2791 | ring = LP_RING(dev_priv); |
2832 | pending = to_intel_crtc(crtc)->unpin_work != NULL; |
Line -... | Line 2833... | ||
- | 2833 | spin_unlock_irqrestore(&dev->event_lock, flags); |
|
2792 | tmp = I915_READ_CTL(ring); |
2834 | |
2793 | if (tmp & RING_WAIT) |
2835 | return pending; |
2794 | I915_WRITE_CTL(ring, tmp); |
2836 | } |
2795 | } |
2837 | |
Line 2796... | Line 2838... | ||
2796 | 2838 | #if 0 |
|
2797 | static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) |
2839 | static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) |
Line 2798... | Line -... | ||
2798 | { |
- | |
2799 | struct drm_i915_gem_object *obj; |
- | |
2800 | struct drm_i915_private *dev_priv; |
2840 | { |
2801 | 2841 | struct drm_device *dev = crtc->dev; |
|
- | 2842 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 2843 | ||
- | 2844 | if (crtc->fb == NULL) |
|
- | 2845 | return; |
|
2802 | if (crtc->fb == NULL) |
2846 | |
- | 2847 | wait_event(dev_priv->pending_flip_queue, |
|
Line 2803... | Line 2848... | ||
2803 | return; |
2848 | !intel_crtc_has_pending_flip(crtc)); |
2804 | 2849 | ||
2805 | obj = to_intel_framebuffer(crtc->fb)->obj; |
2850 | mutex_lock(&dev->struct_mutex); |
2806 | dev_priv = crtc->dev->dev_private; |
- | |
2807 | wait_event(dev_priv->pending_flip_queue, |
2851 | intel_finish_fb(crtc->fb); |
Line 2808... | Line 2852... | ||
2808 | atomic_read(&obj->pending_flip) == 0); |
2852 | mutex_unlock(&dev->struct_mutex); |
2809 | } |
2853 | } |
2810 | 2854 | #endif |
|
2811 | static bool intel_crtc_driving_pch(struct drm_crtc *crtc) |
2855 | |
2812 | { |
2856 | static bool intel_crtc_driving_pch(struct drm_crtc *crtc) |
2813 | struct drm_device *dev = crtc->dev; |
- | |
2814 | struct drm_mode_config *mode_config = &dev->mode_config; |
- | |
Line -... | Line 2857... | ||
- | 2857 | { |
|
- | 2858 | struct drm_device *dev = crtc->dev; |
|
- | 2859 | struct intel_encoder *intel_encoder; |
|
- | 2860 | ||
- | 2861 | /* |
|
- | 2862 | * If there's a non-PCH eDP on this crtc, it must be DP_A, and that |
|
- | 2863 | * must be driven by its own crtc; no sharing is possible. |
|
- | 2864 | */ |
|
- | 2865 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) { |
|
- | 2866 | ||
- | 2867 | /* On Haswell, LPT PCH handles the VGA connection via FDI, and Haswell |
|
- | 2868 | * CPU handles all others */ |
|
- | 2869 | if (IS_HASWELL(dev)) { |
|
- | 2870 | /* It is still unclear how this will work on PPT, so throw up a warning */ |
|
- | 2871 | WARN_ON(!HAS_PCH_LPT(dev)); |
|
- | 2872 | ||
2815 | struct intel_encoder *encoder; |
2873 | if (intel_encoder->type == INTEL_OUTPUT_ANALOG) { |
2816 | 2874 | DRM_DEBUG_KMS("Haswell detected DAC encoder, assuming is PCH\n"); |
|
2817 | /* |
2875 | return true; |
2818 | * If there's a non-PCH eDP on this crtc, it must be DP_A, and that |
2876 | } else { |
2819 | * must be driven by its own crtc; no sharing is possible. |
2877 | DRM_DEBUG_KMS("Haswell detected encoder %d, assuming is CPU\n", |
2820 | */ |
2878 | intel_encoder->type); |
2821 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { |
2879 | return false; |
Line 2822... | Line 2880... | ||
2822 | if (encoder->base.crtc != crtc) |
2880 | } |
2823 | continue; |
2881 | } |
Line -... | Line 2882... | ||
- | 2882 | ||
- | 2883 | switch (intel_encoder->type) { |
|
- | 2884 | case INTEL_OUTPUT_EDP: |
|
- | 2885 | if (!intel_encoder_is_pch_edp(&intel_encoder->base)) |
|
- | 2886 | return false; |
|
- | 2887 | continue; |
|
- | 2888 | } |
|
- | 2889 | } |
|
- | 2890 | ||
- | 2891 | return true; |
|
- | 2892 | } |
|
- | 2893 | ||
- | 2894 | /* Program iCLKIP clock to the desired frequency */ |
|
- | 2895 | static void lpt_program_iclkip(struct drm_crtc *crtc) |
|
- | 2896 | { |
|
- | 2897 | struct drm_device *dev = crtc->dev; |
|
- | 2898 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 2899 | u32 divsel, phaseinc, auxdiv, phasedir = 0; |
|
- | 2900 | u32 temp; |
|
- | 2901 | ||
- | 2902 | /* It is necessary to ungate the pixclk gate prior to programming |
|
- | 2903 | * the divisors, and gate it back when it is done. |
|
- | 2904 | */ |
|
- | 2905 | I915_WRITE(PIXCLK_GATE, PIXCLK_GATE_GATE); |
|
- | 2906 | ||
- | 2907 | /* Disable SSCCTL */ |
|
- | 2908 | intel_sbi_write(dev_priv, SBI_SSCCTL6, |
|
- | 2909 | intel_sbi_read(dev_priv, SBI_SSCCTL6) | |
|
- | 2910 | SBI_SSCCTL_DISABLE); |
|
- | 2911 | ||
- | 2912 | /* 20MHz is a corner case which is out of range for the 7-bit divisor */ |
|
- | 2913 | if (crtc->mode.clock == 20000) { |
|
- | 2914 | auxdiv = 1; |
|
- | 2915 | divsel = 0x41; |
|
- | 2916 | phaseinc = 0x20; |
|
- | 2917 | } else { |
|
- | 2918 | /* The iCLK virtual clock root frequency is in MHz, |
|
- | 2919 | * but the crtc->mode.clock in in KHz. To get the divisors, |
|
- | 2920 | * it is necessary to divide one by another, so we |
|
- | 2921 | * convert the virtual clock precision to KHz here for higher |
|
- | 2922 | * precision. |
|
- | 2923 | */ |
|
- | 2924 | u32 iclk_virtual_root_freq = 172800 * 1000; |
|
- | 2925 | u32 iclk_pi_range = 64; |
|
- | 2926 | u32 desired_divisor, msb_divisor_value, pi_value; |
|
- | 2927 | ||
- | 2928 | desired_divisor = (iclk_virtual_root_freq / crtc->mode.clock); |
|
- | 2929 | msb_divisor_value = desired_divisor / iclk_pi_range; |
|
- | 2930 | pi_value = desired_divisor % iclk_pi_range; |
|
- | 2931 | ||
- | 2932 | auxdiv = 0; |
|
- | 2933 | divsel = msb_divisor_value - 2; |
|
- | 2934 | phaseinc = pi_value; |
|
- | 2935 | } |
|
- | 2936 | ||
- | 2937 | /* This should not happen with any sane values */ |
|
- | 2938 | WARN_ON(SBI_SSCDIVINTPHASE_DIVSEL(divsel) & |
|
- | 2939 | ~SBI_SSCDIVINTPHASE_DIVSEL_MASK); |
|
- | 2940 | WARN_ON(SBI_SSCDIVINTPHASE_DIR(phasedir) & |
|
- | 2941 | ~SBI_SSCDIVINTPHASE_INCVAL_MASK); |
|
- | 2942 | ||
- | 2943 | DRM_DEBUG_KMS("iCLKIP clock: found settings for %dKHz refresh rate: auxdiv=%x, divsel=%x, phasedir=%x, phaseinc=%x\n", |
|
- | 2944 | crtc->mode.clock, |
|
- | 2945 | auxdiv, |
|
- | 2946 | divsel, |
|
- | 2947 | phasedir, |
|
- | 2948 | phaseinc); |
|
- | 2949 | ||
- | 2950 | /* Program SSCDIVINTPHASE6 */ |
|
- | 2951 | temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6); |
|
- | 2952 | temp &= ~SBI_SSCDIVINTPHASE_DIVSEL_MASK; |
|
- | 2953 | temp |= SBI_SSCDIVINTPHASE_DIVSEL(divsel); |
|
- | 2954 | temp &= ~SBI_SSCDIVINTPHASE_INCVAL_MASK; |
|
- | 2955 | temp |= SBI_SSCDIVINTPHASE_INCVAL(phaseinc); |
|
- | 2956 | temp |= SBI_SSCDIVINTPHASE_DIR(phasedir); |
|
- | 2957 | temp |= SBI_SSCDIVINTPHASE_PROPAGATE; |
|
- | 2958 | ||
- | 2959 | intel_sbi_write(dev_priv, |
|
- | 2960 | SBI_SSCDIVINTPHASE6, |
|
- | 2961 | temp); |
|
- | 2962 | ||
- | 2963 | /* Program SSCAUXDIV */ |
|
- | 2964 | temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6); |
|
- | 2965 | temp &= ~SBI_SSCAUXDIV_FINALDIV2SEL(1); |
|
- | 2966 | temp |= SBI_SSCAUXDIV_FINALDIV2SEL(auxdiv); |
|
- | 2967 | intel_sbi_write(dev_priv, |
|
- | 2968 | SBI_SSCAUXDIV6, |
|
- | 2969 | temp); |
|
- | 2970 | ||
- | 2971 | ||
- | 2972 | /* Enable modulator and associated divider */ |
|
2824 | 2973 | temp = intel_sbi_read(dev_priv, SBI_SSCCTL6); |
|
2825 | switch (encoder->type) { |
2974 | temp &= ~SBI_SSCCTL_DISABLE; |
2826 | case INTEL_OUTPUT_EDP: |
2975 | intel_sbi_write(dev_priv, |
2827 | if (!intel_encoder_is_pch_edp(&encoder->base)) |
2976 | SBI_SSCCTL6, |
2828 | return false; |
2977 | temp); |
Line 2845... | Line 2994... | ||
2845 | { |
2994 | { |
2846 | struct drm_device *dev = crtc->dev; |
2995 | struct drm_device *dev = crtc->dev; |
2847 | struct drm_i915_private *dev_priv = dev->dev_private; |
2996 | struct drm_i915_private *dev_priv = dev->dev_private; |
2848 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2997 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2849 | int pipe = intel_crtc->pipe; |
2998 | int pipe = intel_crtc->pipe; |
2850 | u32 reg, temp, transc_sel; |
2999 | u32 reg, temp; |
- | 3000 | ||
- | 3001 | assert_transcoder_disabled(dev_priv, pipe); |
|
Line 2851... | Line 3002... | ||
2851 | 3002 | ||
2852 | /* For PCH output, training FDI link */ |
3003 | /* For PCH output, training FDI link */ |
Line 2853... | Line 3004... | ||
2853 | dev_priv->display.fdi_link_train(crtc); |
3004 | dev_priv->display.fdi_link_train(crtc); |
Line 2854... | Line 3005... | ||
2854 | 3005 | ||
2855 | intel_enable_pch_pll(dev_priv, pipe); |
3006 | intel_enable_pch_pll(intel_crtc); |
2856 | 3007 | ||
- | 3008 | if (HAS_PCH_LPT(dev)) { |
|
- | 3009 | DRM_DEBUG_KMS("LPT detected: programming iCLKIP\n"); |
|
Line 2857... | Line -... | ||
2857 | if (HAS_PCH_CPT(dev)) { |
- | |
2858 | transc_sel = intel_crtc->use_pll_a ? TRANSC_DPLLA_SEL : |
3010 | lpt_program_iclkip(crtc); |
2859 | TRANSC_DPLLB_SEL; |
3011 | } else if (HAS_PCH_CPT(dev)) { |
- | 3012 | u32 sel; |
|
- | 3013 | ||
2860 | 3014 | temp = I915_READ(PCH_DPLL_SEL); |
|
2861 | /* Be sure PCH DPLL SEL is set */ |
3015 | switch (pipe) { |
- | 3016 | default: |
|
2862 | temp = I915_READ(PCH_DPLL_SEL); |
3017 | case 0: |
2863 | if (pipe == 0) { |
3018 | temp |= TRANSA_DPLL_ENABLE; |
2864 | temp &= ~(TRANSA_DPLLB_SEL); |
3019 | sel = TRANSA_DPLLB_SEL; |
- | 3020 | break; |
|
2865 | temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL); |
3021 | case 1: |
2866 | } else if (pipe == 1) { |
3022 | temp |= TRANSB_DPLL_ENABLE; |
2867 | temp &= ~(TRANSB_DPLLB_SEL); |
3023 | sel = TRANSB_DPLLB_SEL; |
- | 3024 | break; |
|
2868 | temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); |
3025 | case 2: |
- | 3026 | temp |= TRANSC_DPLL_ENABLE; |
|
- | 3027 | sel = TRANSC_DPLLB_SEL; |
|
- | 3028 | break; |
|
- | 3029 | } |
|
2869 | } else if (pipe == 2) { |
3030 | if (intel_crtc->pch_pll->pll_reg == _PCH_DPLL_B) |
2870 | temp &= ~(TRANSC_DPLLB_SEL); |
3031 | temp |= sel; |
Line 2871... | Line 3032... | ||
2871 | temp |= (TRANSC_DPLL_ENABLE | transc_sel); |
3032 | else |
2872 | } |
3033 | temp &= ~sel; |
Line 2880... | Line 3041... | ||
2880 | I915_WRITE(TRANS_HSYNC(pipe), I915_READ(HSYNC(pipe))); |
3041 | I915_WRITE(TRANS_HSYNC(pipe), I915_READ(HSYNC(pipe))); |
Line 2881... | Line 3042... | ||
2881 | 3042 | ||
2882 | I915_WRITE(TRANS_VTOTAL(pipe), I915_READ(VTOTAL(pipe))); |
3043 | I915_WRITE(TRANS_VTOTAL(pipe), I915_READ(VTOTAL(pipe))); |
2883 | I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe))); |
3044 | I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe))); |
- | 3045 | I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe))); |
|
Line -... | Line 3046... | ||
- | 3046 | I915_WRITE(TRANS_VSYNCSHIFT(pipe), I915_READ(VSYNCSHIFT(pipe))); |
|
2884 | I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe))); |
3047 | |
Line 2885... | Line 3048... | ||
2885 | 3048 | if (!IS_HASWELL(dev)) |
|
2886 | intel_fdi_normal_train(crtc); |
3049 | intel_fdi_normal_train(crtc); |
2887 | 3050 | ||
Line 2924... | Line 3087... | ||
2924 | } |
3087 | } |
Line 2925... | Line 3088... | ||
2925 | 3088 | ||
2926 | intel_enable_transcoder(dev_priv, pipe); |
3089 | intel_enable_transcoder(dev_priv, pipe); |
Line -... | Line 3090... | ||
- | 3090 | } |
|
- | 3091 | ||
- | 3092 | static void intel_put_pch_pll(struct intel_crtc *intel_crtc) |
|
- | 3093 | { |
|
- | 3094 | struct intel_pch_pll *pll = intel_crtc->pch_pll; |
|
- | 3095 | ||
- | 3096 | if (pll == NULL) |
|
- | 3097 | return; |
|
- | 3098 | ||
- | 3099 | if (pll->refcount == 0) { |
|
- | 3100 | WARN(1, "bad PCH PLL refcount\n"); |
|
- | 3101 | return; |
|
- | 3102 | } |
|
- | 3103 | ||
- | 3104 | --pll->refcount; |
|
- | 3105 | intel_crtc->pch_pll = NULL; |
|
- | 3106 | } |
|
- | 3107 | ||
- | 3108 | static struct intel_pch_pll *intel_get_pch_pll(struct intel_crtc *intel_crtc, u32 dpll, u32 fp) |
|
- | 3109 | { |
|
- | 3110 | struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; |
|
- | 3111 | struct intel_pch_pll *pll; |
|
- | 3112 | int i; |
|
- | 3113 | ||
- | 3114 | pll = intel_crtc->pch_pll; |
|
- | 3115 | if (pll) { |
|
- | 3116 | DRM_DEBUG_KMS("CRTC:%d reusing existing PCH PLL %x\n", |
|
- | 3117 | intel_crtc->base.base.id, pll->pll_reg); |
|
- | 3118 | goto prepare; |
|
- | 3119 | } |
|
- | 3120 | ||
- | 3121 | if (HAS_PCH_IBX(dev_priv->dev)) { |
|
- | 3122 | /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ |
|
- | 3123 | i = intel_crtc->pipe; |
|
- | 3124 | pll = &dev_priv->pch_plls[i]; |
|
- | 3125 | ||
- | 3126 | DRM_DEBUG_KMS("CRTC:%d using pre-allocated PCH PLL %x\n", |
|
- | 3127 | intel_crtc->base.base.id, pll->pll_reg); |
|
- | 3128 | ||
- | 3129 | goto found; |
|
- | 3130 | } |
|
- | 3131 | ||
- | 3132 | for (i = 0; i < dev_priv->num_pch_pll; i++) { |
|
- | 3133 | pll = &dev_priv->pch_plls[i]; |
|
- | 3134 | ||
- | 3135 | /* Only want to check enabled timings first */ |
|
- | 3136 | if (pll->refcount == 0) |
|
- | 3137 | continue; |
|
- | 3138 | ||
- | 3139 | if (dpll == (I915_READ(pll->pll_reg) & 0x7fffffff) && |
|
- | 3140 | fp == I915_READ(pll->fp0_reg)) { |
|
- | 3141 | DRM_DEBUG_KMS("CRTC:%d sharing existing PCH PLL %x (refcount %d, ative %d)\n", |
|
- | 3142 | intel_crtc->base.base.id, |
|
- | 3143 | pll->pll_reg, pll->refcount, pll->active); |
|
- | 3144 | ||
- | 3145 | goto found; |
|
- | 3146 | } |
|
- | 3147 | } |
|
- | 3148 | ||
- | 3149 | /* Ok no matching timings, maybe there's a free one? */ |
|
- | 3150 | for (i = 0; i < dev_priv->num_pch_pll; i++) { |
|
- | 3151 | pll = &dev_priv->pch_plls[i]; |
|
- | 3152 | if (pll->refcount == 0) { |
|
- | 3153 | DRM_DEBUG_KMS("CRTC:%d allocated PCH PLL %x\n", |
|
- | 3154 | intel_crtc->base.base.id, pll->pll_reg); |
|
- | 3155 | goto found; |
|
- | 3156 | } |
|
- | 3157 | } |
|
- | 3158 | ||
- | 3159 | return NULL; |
|
- | 3160 | ||
- | 3161 | found: |
|
- | 3162 | intel_crtc->pch_pll = pll; |
|
- | 3163 | pll->refcount++; |
|
- | 3164 | DRM_DEBUG_DRIVER("using pll %d for pipe %d\n", i, intel_crtc->pipe); |
|
- | 3165 | prepare: /* separate function? */ |
|
- | 3166 | DRM_DEBUG_DRIVER("switching PLL %x off\n", pll->pll_reg); |
|
- | 3167 | ||
- | 3168 | /* Wait for the clocks to stabilize before rewriting the regs */ |
|
- | 3169 | I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE); |
|
- | 3170 | POSTING_READ(pll->pll_reg); |
|
- | 3171 | udelay(150); |
|
- | 3172 | ||
- | 3173 | I915_WRITE(pll->fp0_reg, fp); |
|
- | 3174 | I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE); |
|
- | 3175 | pll->on = false; |
|
- | 3176 | return pll; |
|
2927 | } |
3177 | } |
2928 | 3178 | ||
2929 | void intel_cpt_verify_modeset(struct drm_device *dev, int pipe) |
3179 | void intel_cpt_verify_modeset(struct drm_device *dev, int pipe) |
2930 | { |
3180 | { |
2931 | struct drm_i915_private *dev_priv = dev->dev_private; |
3181 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 2947... | Line 3197... | ||
2947 | static void ironlake_crtc_enable(struct drm_crtc *crtc) |
3197 | static void ironlake_crtc_enable(struct drm_crtc *crtc) |
2948 | { |
3198 | { |
2949 | struct drm_device *dev = crtc->dev; |
3199 | struct drm_device *dev = crtc->dev; |
2950 | struct drm_i915_private *dev_priv = dev->dev_private; |
3200 | struct drm_i915_private *dev_priv = dev->dev_private; |
2951 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3201 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | 3202 | struct intel_encoder *encoder; |
|
2952 | int pipe = intel_crtc->pipe; |
3203 | int pipe = intel_crtc->pipe; |
2953 | int plane = intel_crtc->plane; |
3204 | int plane = intel_crtc->plane; |
2954 | u32 temp; |
3205 | u32 temp; |
2955 | bool is_pch_port; |
3206 | bool is_pch_port; |
Line -... | Line 3207... | ||
- | 3207 | ||
- | 3208 | WARN_ON(!crtc->enabled); |
|
2956 | 3209 | ||
2957 | if (intel_crtc->active) |
3210 | if (intel_crtc->active) |
Line 2958... | Line 3211... | ||
2958 | return; |
3211 | return; |
2959 | 3212 | ||
Line 2966... | Line 3219... | ||
2966 | I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN); |
3219 | I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN); |
2967 | } |
3220 | } |
Line 2968... | Line 3221... | ||
2968 | 3221 | ||
Line 2969... | Line 3222... | ||
2969 | is_pch_port = intel_crtc_driving_pch(crtc); |
3222 | is_pch_port = intel_crtc_driving_pch(crtc); |
2970 | 3223 | ||
2971 | if (is_pch_port) |
3224 | if (is_pch_port) { |
- | 3225 | ironlake_fdi_pll_enable(intel_crtc); |
|
- | 3226 | } else { |
|
- | 3227 | assert_fdi_tx_disabled(dev_priv, pipe); |
|
- | 3228 | assert_fdi_rx_disabled(dev_priv, pipe); |
|
- | 3229 | } |
|
- | 3230 | ||
2972 | ironlake_fdi_pll_enable(crtc); |
3231 | for_each_encoder_on_crtc(dev, crtc, encoder) |
Line 2973... | Line 3232... | ||
2973 | else |
3232 | if (encoder->pre_enable) |
2974 | ironlake_fdi_disable(crtc); |
3233 | encoder->pre_enable(encoder); |
2975 | 3234 | ||
2976 | /* Enable panel fitting for LVDS */ |
3235 | /* Enable panel fitting for LVDS */ |
Line 3000... | Line 3259... | ||
3000 | mutex_lock(&dev->struct_mutex); |
3259 | mutex_lock(&dev->struct_mutex); |
3001 | intel_update_fbc(dev); |
3260 | intel_update_fbc(dev); |
3002 | mutex_unlock(&dev->struct_mutex); |
3261 | mutex_unlock(&dev->struct_mutex); |
Line 3003... | Line 3262... | ||
3003 | 3262 | ||
- | 3263 | // intel_crtc_update_cursor(crtc, true); |
|
- | 3264 | ||
- | 3265 | for_each_encoder_on_crtc(dev, crtc, encoder) |
|
- | 3266 | encoder->enable(encoder); |
|
- | 3267 | ||
- | 3268 | if (HAS_PCH_CPT(dev)) |
|
- | 3269 | intel_cpt_verify_modeset(dev, intel_crtc->pipe); |
|
- | 3270 | ||
- | 3271 | /* |
|
- | 3272 | * There seems to be a race in PCH platform hw (at least on some |
|
- | 3273 | * outputs) where an enabled pipe still completes any pageflip right |
|
- | 3274 | * away (as if the pipe is off) instead of waiting for vblank. As soon |
|
- | 3275 | * as the first vblank happend, everything works as expected. Hence just |
|
- | 3276 | * wait for one vblank before returning to avoid strange things |
|
- | 3277 | * happening. |
|
- | 3278 | */ |
|
3004 | // intel_crtc_update_cursor(crtc, true); |
3279 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
Line 3005... | Line 3280... | ||
3005 | } |
3280 | } |
3006 | 3281 | ||
3007 | static void ironlake_crtc_disable(struct drm_crtc *crtc) |
3282 | static void ironlake_crtc_disable(struct drm_crtc *crtc) |
3008 | { |
3283 | { |
3009 | struct drm_device *dev = crtc->dev; |
3284 | struct drm_device *dev = crtc->dev; |
- | 3285 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
3010 | struct drm_i915_private *dev_priv = dev->dev_private; |
3286 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3011 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3287 | struct intel_encoder *encoder; |
3012 | int pipe = intel_crtc->pipe; |
3288 | int pipe = intel_crtc->pipe; |
Line -... | Line 3289... | ||
- | 3289 | int plane = intel_crtc->plane; |
|
3013 | int plane = intel_crtc->plane; |
3290 | u32 reg, temp; |
3014 | u32 reg, temp; |
3291 | |
Line -... | Line 3292... | ||
- | 3292 | ||
3015 | 3293 | if (!intel_crtc->active) |
|
Line 3016... | Line 3294... | ||
3016 | if (!intel_crtc->active) |
3294 | return; |
3017 | return; |
3295 | |
3018 | 3296 | for_each_encoder_on_crtc(dev, crtc, encoder) |
|
Line 3019... | Line 3297... | ||
3019 | ENTER(); |
3297 | encoder->disable(encoder); |
Line 3031... | Line 3309... | ||
3031 | 3309 | ||
3032 | /* Disable PF */ |
3310 | /* Disable PF */ |
3033 | I915_WRITE(PF_CTL(pipe), 0); |
3311 | I915_WRITE(PF_CTL(pipe), 0); |
Line -... | Line 3312... | ||
- | 3312 | I915_WRITE(PF_WIN_SZ(pipe), 0); |
|
- | 3313 | ||
3034 | I915_WRITE(PF_WIN_SZ(pipe), 0); |
3314 | for_each_encoder_on_crtc(dev, crtc, encoder) |
Line 3035... | Line -... | ||
3035 | - | ||
3036 | ironlake_fdi_disable(crtc); |
- | |
3037 | - | ||
3038 | /* This is a horrible layering violation; we should be doing this in |
- | |
3039 | * the connector/encoder ->prepare instead, but we don't always have |
- | |
3040 | * enough information there about the config to know whether it will |
3315 | if (encoder->post_disable) |
Line 3041... | Line 3316... | ||
3041 | * actually be necessary or just cause undesired flicker. |
3316 | encoder->post_disable(encoder); |
Line 3042... | Line 3317... | ||
3042 | */ |
3317 | |
3043 | intel_disable_pch_ports(dev_priv, pipe); |
3318 | ironlake_fdi_disable(crtc); |
Line 3070... | Line 3345... | ||
3070 | } |
3345 | } |
3071 | I915_WRITE(PCH_DPLL_SEL, temp); |
3346 | I915_WRITE(PCH_DPLL_SEL, temp); |
3072 | } |
3347 | } |
Line 3073... | Line 3348... | ||
3073 | 3348 | ||
3074 | /* disable PCH DPLL */ |
- | |
3075 | if (!intel_crtc->no_pll) |
3349 | /* disable PCH DPLL */ |
3076 | intel_disable_pch_pll(dev_priv, pipe); |
- | |
3077 | - | ||
3078 | /* Switch from PCDclk to Rawclk */ |
- | |
3079 | reg = FDI_RX_CTL(pipe); |
- | |
3080 | temp = I915_READ(reg); |
- | |
3081 | I915_WRITE(reg, temp & ~FDI_PCDCLK); |
- | |
3082 | - | ||
3083 | /* Disable CPU FDI TX PLL */ |
- | |
3084 | reg = FDI_TX_CTL(pipe); |
- | |
3085 | temp = I915_READ(reg); |
- | |
Line 3086... | Line -... | ||
3086 | I915_WRITE(reg, temp & ~FDI_TX_PLL_ENABLE); |
- | |
3087 | - | ||
3088 | POSTING_READ(reg); |
- | |
3089 | udelay(100); |
3350 | intel_disable_pch_pll(intel_crtc); |
3090 | - | ||
3091 | reg = FDI_RX_CTL(pipe); |
- | |
3092 | temp = I915_READ(reg); |
- | |
3093 | I915_WRITE(reg, temp & ~FDI_RX_PLL_ENABLE); |
- | |
3094 | - | ||
3095 | /* Wait for the clocks to turn off. */ |
- | |
Line 3096... | Line 3351... | ||
3096 | POSTING_READ(reg); |
3351 | |
3097 | udelay(100); |
3352 | ironlake_fdi_pll_disable(intel_crtc); |
Line 3098... | Line 3353... | ||
3098 | 3353 | ||
3099 | intel_crtc->active = false; |
3354 | intel_crtc->active = false; |
3100 | intel_update_watermarks(dev); |
- | |
3101 | 3355 | intel_update_watermarks(dev); |
|
Line 3102... | Line -... | ||
3102 | mutex_lock(&dev->struct_mutex); |
- | |
3103 | intel_update_fbc(dev); |
- | |
3104 | intel_clear_scanline_wait(dev); |
3356 | |
Line 3105... | Line 3357... | ||
3105 | mutex_unlock(&dev->struct_mutex); |
3357 | mutex_lock(&dev->struct_mutex); |
3106 | 3358 | intel_update_fbc(dev); |
|
3107 | LEAVE(); |
3359 | mutex_unlock(&dev->struct_mutex); |
3108 | 3360 | ||
3109 | } |
- | |
3110 | - | ||
3111 | static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) |
- | |
3112 | { |
- | |
3113 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
3114 | int pipe = intel_crtc->pipe; |
- | |
3115 | int plane = intel_crtc->plane; |
- | |
3116 | - | ||
3117 | /* XXX: When our outputs are all unaware of DPMS modes other than off |
- | |
3118 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. |
- | |
3119 | */ |
- | |
3120 | switch (mode) { |
- | |
3121 | case DRM_MODE_DPMS_ON: |
- | |
3122 | case DRM_MODE_DPMS_STANDBY: |
- | |
3123 | case DRM_MODE_DPMS_SUSPEND: |
- | |
3124 | DRM_DEBUG_KMS("crtc %d/%d dpms on\n", pipe, plane); |
- | |
3125 | ironlake_crtc_enable(crtc); |
- | |
3126 | break; |
- | |
3127 | 3361 | } |
|
Line 3128... | Line 3362... | ||
3128 | case DRM_MODE_DPMS_OFF: |
3362 | |
3129 | DRM_DEBUG_KMS("crtc %d/%d dpms off\n", pipe, plane); |
3363 | static void ironlake_crtc_off(struct drm_crtc *crtc) |
3130 | ironlake_crtc_disable(crtc); |
3364 | { |
Line 3153... | Line 3387... | ||
3153 | static void i9xx_crtc_enable(struct drm_crtc *crtc) |
3387 | static void i9xx_crtc_enable(struct drm_crtc *crtc) |
3154 | { |
3388 | { |
3155 | struct drm_device *dev = crtc->dev; |
3389 | struct drm_device *dev = crtc->dev; |
3156 | struct drm_i915_private *dev_priv = dev->dev_private; |
3390 | struct drm_i915_private *dev_priv = dev->dev_private; |
3157 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3391 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | 3392 | struct intel_encoder *encoder; |
|
3158 | int pipe = intel_crtc->pipe; |
3393 | int pipe = intel_crtc->pipe; |
3159 | int plane = intel_crtc->plane; |
3394 | int plane = intel_crtc->plane; |
Line -... | Line 3395... | ||
- | 3395 | ||
- | 3396 | WARN_ON(!crtc->enabled); |
|
3160 | 3397 | ||
3161 | if (intel_crtc->active) |
3398 | if (intel_crtc->active) |
Line 3162... | Line 3399... | ||
3162 | return; |
3399 | return; |
3163 | 3400 | ||
Line 3172... | Line 3409... | ||
3172 | intel_update_fbc(dev); |
3409 | intel_update_fbc(dev); |
Line 3173... | Line 3410... | ||
3173 | 3410 | ||
3174 | /* Give the overlay scaler a chance to enable if it's on this pipe */ |
3411 | /* Give the overlay scaler a chance to enable if it's on this pipe */ |
3175 | intel_crtc_dpms_overlay(intel_crtc, true); |
3412 | intel_crtc_dpms_overlay(intel_crtc, true); |
- | 3413 | // intel_crtc_update_cursor(crtc, true); |
|
- | 3414 | ||
- | 3415 | for_each_encoder_on_crtc(dev, crtc, encoder) |
|
3176 | // intel_crtc_update_cursor(crtc, true); |
3416 | encoder->enable(encoder); |
Line 3177... | Line 3417... | ||
3177 | } |
3417 | } |
3178 | 3418 | ||
3179 | static void i9xx_crtc_disable(struct drm_crtc *crtc) |
3419 | static void i9xx_crtc_disable(struct drm_crtc *crtc) |
3180 | { |
3420 | { |
3181 | struct drm_device *dev = crtc->dev; |
3421 | struct drm_device *dev = crtc->dev; |
- | 3422 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
3182 | struct drm_i915_private *dev_priv = dev->dev_private; |
3423 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3183 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3424 | struct intel_encoder *encoder; |
Line -... | Line 3425... | ||
- | 3425 | int pipe = intel_crtc->pipe; |
|
3184 | int pipe = intel_crtc->pipe; |
3426 | int plane = intel_crtc->plane; |
3185 | int plane = intel_crtc->plane; |
3427 | |
Line -... | Line 3428... | ||
- | 3428 | ||
- | 3429 | if (!intel_crtc->active) |
|
- | 3430 | return; |
|
3186 | 3431 | ||
3187 | if (!intel_crtc->active) |
3432 | for_each_encoder_on_crtc(dev, crtc, encoder) |
3188 | return; |
3433 | encoder->disable(encoder); |
3189 | 3434 | ||
3190 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
3435 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
Line 3191... | Line 3436... | ||
3191 | intel_crtc_wait_for_pending_flips(crtc); |
3436 | // intel_crtc_wait_for_pending_flips(crtc); |
Line 3201... | Line 3446... | ||
3201 | intel_disable_pll(dev_priv, pipe); |
3446 | intel_disable_pll(dev_priv, pipe); |
Line 3202... | Line 3447... | ||
3202 | 3447 | ||
3203 | intel_crtc->active = false; |
3448 | intel_crtc->active = false; |
3204 | intel_update_fbc(dev); |
3449 | intel_update_fbc(dev); |
3205 | intel_update_watermarks(dev); |
- | |
3206 | intel_clear_scanline_wait(dev); |
3450 | intel_update_watermarks(dev); |
Line 3207... | Line 3451... | ||
3207 | } |
3451 | } |
3208 | 3452 | ||
3209 | static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) |
- | |
3210 | { |
- | |
3211 | /* XXX: When our outputs are all unaware of DPMS modes other than off |
- | |
3212 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. |
- | |
3213 | */ |
- | |
3214 | switch (mode) { |
- | |
3215 | case DRM_MODE_DPMS_ON: |
- | |
3216 | case DRM_MODE_DPMS_STANDBY: |
- | |
3217 | case DRM_MODE_DPMS_SUSPEND: |
- | |
3218 | i9xx_crtc_enable(crtc); |
- | |
3219 | break; |
- | |
3220 | case DRM_MODE_DPMS_OFF: |
- | |
3221 | i9xx_crtc_disable(crtc); |
- | |
3222 | break; |
3453 | static void i9xx_crtc_off(struct drm_crtc *crtc) |
Line 3223... | Line -... | ||
3223 | } |
- | |
3224 | } |
- | |
3225 | - | ||
3226 | /** |
3454 | { |
- | 3455 | } |
|
3227 | * Sets the power management mode of the pipe and plane. |
3456 | |
3228 | */ |
3457 | static void intel_crtc_update_sarea(struct drm_crtc *crtc, |
3229 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) |
- | |
3230 | { |
3458 | bool enabled) |
3231 | struct drm_device *dev = crtc->dev; |
3459 | { |
3232 | struct drm_i915_private *dev_priv = dev->dev_private; |
3460 | struct drm_device *dev = crtc->dev; |
3233 | struct drm_i915_master_private *master_priv; |
- | |
3234 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
3235 | int pipe = intel_crtc->pipe; |
- | |
3236 | bool enabled; |
- | |
3237 | - | ||
3238 | if (intel_crtc->dpms_mode == mode) |
- | |
Line 3239... | Line -... | ||
3239 | return; |
- | |
Line 3240... | Line 3461... | ||
3240 | 3461 | struct drm_i915_master_private *master_priv; |
|
3241 | intel_crtc->dpms_mode = mode; |
3462 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3242 | 3463 | int pipe = intel_crtc->pipe; |
|
Line 3243... | Line 3464... | ||
3243 | dev_priv->display.dpms(crtc, mode); |
3464 | |
3244 | 3465 | ||
3245 | #if 0 |
3466 | #if 0 |
Line 3246... | Line -... | ||
3246 | if (!dev->primary->master) |
- | |
3247 | return; |
- | |
3248 | 3467 | if (!dev->primary->master) |
|
3249 | master_priv = dev->primary->master->driver_priv; |
3468 | return; |
3250 | if (!master_priv->sarea_priv) |
3469 | |
3251 | return; |
3470 | master_priv = dev->primary->master->driver_priv; |
3252 | 3471 | if (!master_priv->sarea_priv) |
|
Line 3267... | Line 3486... | ||
3267 | } |
3486 | } |
3268 | #endif |
3487 | #endif |
Line 3269... | Line 3488... | ||
3269 | 3488 | ||
Line -... | Line 3489... | ||
- | 3489 | } |
|
- | 3490 | ||
- | 3491 | /** |
|
- | 3492 | * Sets the power management mode of the pipe and plane. |
|
- | 3493 | */ |
|
- | 3494 | void intel_crtc_update_dpms(struct drm_crtc *crtc) |
|
- | 3495 | { |
|
- | 3496 | struct drm_device *dev = crtc->dev; |
|
- | 3497 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 3498 | struct intel_encoder *intel_encoder; |
|
- | 3499 | bool enable = false; |
|
- | 3500 | ||
- | 3501 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) |
|
- | 3502 | enable |= intel_encoder->connectors_active; |
|
- | 3503 | ||
- | 3504 | if (enable) |
|
- | 3505 | dev_priv->display.crtc_enable(crtc); |
|
- | 3506 | else |
|
- | 3507 | dev_priv->display.crtc_disable(crtc); |
|
- | 3508 | ||
- | 3509 | intel_crtc_update_sarea(crtc, enable); |
|
- | 3510 | } |
|
- | 3511 | ||
- | 3512 | static void intel_crtc_noop(struct drm_crtc *crtc) |
|
- | 3513 | { |
|
3270 | } |
3514 | } |
3271 | 3515 | ||
3272 | static void intel_crtc_disable(struct drm_crtc *crtc) |
- | |
3273 | { |
3516 | static void intel_crtc_disable(struct drm_crtc *crtc) |
- | 3517 | { |
|
- | 3518 | struct drm_device *dev = crtc->dev; |
|
Line 3274... | Line 3519... | ||
3274 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; |
3519 | struct drm_connector *connector; |
- | 3520 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
Line -... | Line 3521... | ||
- | 3521 | ||
- | 3522 | /* crtc should still be enabled when we disable it. */ |
|
- | 3523 | WARN_ON(!crtc->enabled); |
|
- | 3524 | ||
- | 3525 | dev_priv->display.crtc_disable(crtc); |
|
- | 3526 | intel_crtc_update_sarea(crtc, false); |
|
- | 3527 | dev_priv->display.off(crtc); |
|
3275 | struct drm_device *dev = crtc->dev; |
3528 | |
3276 | 3529 | assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); |
|
3277 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); |
3530 | assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); |
3278 | 3531 | ||
- | 3532 | // if (crtc->fb) { |
|
- | 3533 | // mutex_lock(&dev->struct_mutex); |
|
- | 3534 | // intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); |
|
- | 3535 | // mutex_unlock(&dev->struct_mutex); |
|
- | 3536 | // crtc->fb = NULL; |
|
- | 3537 | // } |
|
- | 3538 | ||
- | 3539 | /* Update computed state. */ |
|
- | 3540 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
|
- | 3541 | if (!connector->encoder || !connector->encoder->crtc) |
|
- | 3542 | continue; |
|
- | 3543 | ||
- | 3544 | if (connector->encoder->crtc != crtc) |
|
3279 | if (crtc->fb) { |
3545 | continue; |
3280 | mutex_lock(&dev->struct_mutex); |
3546 | |
Line 3281... | Line -... | ||
3281 | i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); |
- | |
3282 | mutex_unlock(&dev->struct_mutex); |
- | |
3283 | } |
- | |
3284 | } |
- | |
3285 | - | ||
3286 | /* Prepare for a mode set. |
- | |
3287 | * |
- | |
3288 | * Note we could be a lot smarter here. We need to figure out which outputs |
- | |
3289 | * will be enabled, which disabled (in short, how the config will changes) |
3547 | connector->dpms = DRM_MODE_DPMS_OFF; |
3290 | * and perform the minimum necessary steps to accomplish that, e.g. updating |
3548 | to_intel_encoder(connector->encoder)->connectors_active = false; |
- | 3549 | } |
|
- | 3550 | } |
|
- | 3551 | ||
- | 3552 | void intel_modeset_disable(struct drm_device *dev) |
|
3291 | * watermarks, FBC configuration, making sure PLLs are programmed correctly, |
3553 | { |
- | 3554 | struct drm_crtc *crtc; |
|
3292 | * panel fitting is in the proper state, etc. |
3555 | |
Line 3293... | Line 3556... | ||
3293 | */ |
3556 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
3294 | static void i9xx_crtc_prepare(struct drm_crtc *crtc) |
3557 | if (crtc->enabled) |
3295 | { |
- | |
3296 | i9xx_crtc_disable(crtc); |
3558 | intel_crtc_disable(crtc); |
Line 3297... | Line 3559... | ||
3297 | } |
3559 | } |
3298 | 3560 | } |
|
- | 3561 | ||
- | 3562 | void intel_encoder_noop(struct drm_encoder *encoder) |
|
3299 | static void i9xx_crtc_commit(struct drm_crtc *crtc) |
3563 | { |
- | 3564 | } |
|
3300 | { |
3565 | |
Line -... | Line 3566... | ||
- | 3566 | void intel_encoder_destroy(struct drm_encoder *encoder) |
|
- | 3567 | { |
|
- | 3568 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
|
3301 | i9xx_crtc_enable(crtc); |
3569 | |
3302 | } |
3570 | drm_encoder_cleanup(encoder); |
- | 3571 | kfree(intel_encoder); |
|
- | 3572 | } |
|
- | 3573 | ||
3303 | 3574 | /* Simple dpms helper for encodres with just one connector, no cloning and only |
|
- | 3575 | * one kind of off state. It clamps all !ON modes to fully OFF and changes the |
|
- | 3576 | * state of the entire output pipe. */ |
|
- | 3577 | void intel_encoder_dpms(struct intel_encoder *encoder, int mode) |
|
- | 3578 | { |
|
- | 3579 | if (mode == DRM_MODE_DPMS_ON) { |
|
3304 | static void ironlake_crtc_prepare(struct drm_crtc *crtc) |
3580 | encoder->connectors_active = true; |
Line -... | Line 3581... | ||
- | 3581 | ||
- | 3582 | intel_crtc_update_dpms(encoder->base.crtc); |
|
3305 | { |
3583 | } else { |
3306 | ironlake_crtc_disable(crtc); |
3584 | encoder->connectors_active = false; |
- | 3585 | ||
3307 | } |
3586 | intel_crtc_update_dpms(encoder->base.crtc); |
- | 3587 | } |
|
- | 3588 | } |
|
- | 3589 | ||
- | 3590 | /* Cross check the actual hw state with our own modeset state tracking (and it's |
|
- | 3591 | * internal consistency). */ |
|
- | 3592 | static void intel_connector_check_state(struct intel_connector *connector) |
|
3308 | 3593 | { |
|
- | 3594 | if (connector->get_hw_state(connector)) { |
|
3309 | static void ironlake_crtc_commit(struct drm_crtc *crtc) |
3595 | struct intel_encoder *encoder = connector->encoder; |
- | 3596 | struct drm_crtc *crtc; |
|
- | 3597 | bool encoder_enabled; |
|
- | 3598 | enum pipe pipe; |
|
- | 3599 | ||
- | 3600 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
|
- | 3601 | connector->base.base.id, |
|
- | 3602 | drm_get_connector_name(&connector->base)); |
|
- | 3603 | ||
- | 3604 | WARN(connector->base.dpms == DRM_MODE_DPMS_OFF, |
|
- | 3605 | "wrong connector dpms state\n"); |
|
- | 3606 | WARN(connector->base.encoder != &encoder->base, |
|
- | 3607 | "active connector not linked to encoder\n"); |
|
- | 3608 | WARN(!encoder->connectors_active, |
|
- | 3609 | "encoder->connectors_active not set\n"); |
|
- | 3610 | ||
- | 3611 | encoder_enabled = encoder->get_hw_state(encoder, &pipe); |
|
- | 3612 | WARN(!encoder_enabled, "encoder not enabled\n"); |
|
- | 3613 | if (WARN_ON(!encoder->base.crtc)) |
|
3310 | { |
3614 | return; |
Line -... | Line 3615... | ||
- | 3615 | ||
- | 3616 | crtc = encoder->base.crtc; |
|
3311 | ironlake_crtc_enable(crtc); |
3617 | |
3312 | } |
3618 | WARN(!crtc->enabled, "crtc not enabled\n"); |
3313 | - | ||
3314 | void intel_encoder_prepare(struct drm_encoder *encoder) |
- | |
3315 | { |
3619 | WARN(!to_intel_crtc(crtc)->active, "crtc not active\n"); |
3316 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; |
- | |
Line 3317... | Line 3620... | ||
3317 | /* lvds has its own version of prepare see intel_lvds_prepare */ |
3620 | WARN(pipe != to_intel_crtc(crtc)->pipe, |
3318 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); |
3621 | "encoder active on the wrong pipe\n"); |
- | 3622 | } |
|
Line -... | Line 3623... | ||
- | 3623 | } |
|
- | 3624 | ||
- | 3625 | /* Even simpler default implementation, if there's really no special case to |
|
- | 3626 | * consider. */ |
|
- | 3627 | void intel_connector_dpms(struct drm_connector *connector, int mode) |
|
- | 3628 | { |
|
3319 | } |
3629 | struct intel_encoder *encoder = intel_attached_encoder(connector); |
- | 3630 | ||
- | 3631 | /* All the simple cases only support two dpms states. */ |
|
- | 3632 | if (mode != DRM_MODE_DPMS_ON) |
|
- | 3633 | mode = DRM_MODE_DPMS_OFF; |
|
3320 | 3634 | ||
3321 | void intel_encoder_commit(struct drm_encoder *encoder) |
3635 | if (mode == connector->dpms) |
Line -... | Line 3636... | ||
- | 3636 | return; |
|
- | 3637 | ||
- | 3638 | connector->dpms = mode; |
|
3322 | { |
3639 | |
3323 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; |
3640 | /* Only need to change hw state when actually enabled */ |
- | 3641 | if (encoder->base.crtc) |
|
3324 | struct drm_device *dev = encoder->dev; |
3642 | intel_encoder_dpms(encoder, mode); |
Line 3325... | Line 3643... | ||
3325 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
3643 | else |
3326 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_encoder->base.crtc); |
- | |
3327 | 3644 | WARN_ON(encoder->connectors_active != false); |
|
Line 3328... | Line 3645... | ||
3328 | /* lvds has its own version of commit see intel_lvds_commit */ |
3645 | |
3329 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); |
3646 | intel_modeset_check_state(connector->dev); |
3330 | 3647 | } |
|
3331 | if (HAS_PCH_CPT(dev)) |
3648 | |
3332 | intel_cpt_verify_modeset(dev, intel_crtc->pipe); |
3649 | /* Simple connector->get_hw_state implementation for encoders that support only |
Line 3333... | Line 3650... | ||
3333 | } |
3650 | * one connector and no cloning and hence the encoder state determines the state |
3334 | 3651 | * of the connector. */ |
|
3335 | void intel_encoder_destroy(struct drm_encoder *encoder) |
3652 | bool intel_connector_get_hw_state(struct intel_connector *connector) |
3336 | { |
3653 | { |
3337 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
3654 | enum pipe pipe = 0; |
Line 3338... | Line 3655... | ||
3338 | 3655 | struct intel_encoder *encoder = connector->encoder; |
|
- | 3656 | ||
3339 | drm_encoder_cleanup(encoder); |
3657 | return encoder->get_hw_state(encoder, &pipe); |
3340 | kfree(intel_encoder); |
- | |
3341 | } |
3658 | } |
3342 | 3659 | ||
Line -... | Line 3660... | ||
- | 3660 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, |
|
- | 3661 | const struct drm_display_mode *mode, |
|
- | 3662 | struct drm_display_mode *adjusted_mode) |
|
- | 3663 | { |
|
- | 3664 | struct drm_device *dev = crtc->dev; |
|
- | 3665 | ||
- | 3666 | if (HAS_PCH_SPLIT(dev)) { |
|
3343 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, |
3667 | /* FDI link clock is fixed at 2.7G */ |
3344 | struct drm_display_mode *mode, |
3668 | if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4) |
Line -... | Line 3669... | ||
- | 3669 | return false; |
|
- | 3670 | } |
|
- | 3671 | ||
- | 3672 | /* All interlaced capable intel hw wants timings in frames. Note though |
|
- | 3673 | * that intel_lvds_mode_fixup does some funny tricks with the crtc |
|
3345 | struct drm_display_mode *adjusted_mode) |
3674 | * timings, so we need to be careful not to clobber these.*/ |
3346 | { |
3675 | if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET)) |
3347 | struct drm_device *dev = crtc->dev; |
3676 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
3348 | 3677 | ||
Line 3456... | Line 3785... | ||
3456 | m_n->link_m = pixel_clock; |
3785 | m_n->link_m = pixel_clock; |
3457 | m_n->link_n = link_clock; |
3786 | m_n->link_n = link_clock; |
3458 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); |
3787 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); |
3459 | } |
3788 | } |
Line 3460... | Line -... | ||
3460 | - | ||
3461 | - | ||
3462 | struct intel_watermark_params { |
- | |
3463 | unsigned long fifo_size; |
- | |
3464 | unsigned long max_wm; |
- | |
3465 | unsigned long default_wm; |
- | |
3466 | unsigned long guard_size; |
- | |
3467 | unsigned long cacheline_size; |
- | |
3468 | }; |
- | |
3469 | - | ||
3470 | /* Pineview has different values for various configs */ |
- | |
3471 | static const struct intel_watermark_params pineview_display_wm = { |
- | |
3472 | PINEVIEW_DISPLAY_FIFO, |
- | |
3473 | PINEVIEW_MAX_WM, |
- | |
3474 | PINEVIEW_DFT_WM, |
- | |
3475 | PINEVIEW_GUARD_WM, |
- | |
3476 | PINEVIEW_FIFO_LINE_SIZE |
- | |
3477 | }; |
- | |
3478 | static const struct intel_watermark_params pineview_display_hplloff_wm = { |
- | |
3479 | PINEVIEW_DISPLAY_FIFO, |
- | |
3480 | PINEVIEW_MAX_WM, |
- | |
3481 | PINEVIEW_DFT_HPLLOFF_WM, |
- | |
3482 | PINEVIEW_GUARD_WM, |
- | |
3483 | PINEVIEW_FIFO_LINE_SIZE |
- | |
3484 | }; |
- | |
3485 | static const struct intel_watermark_params pineview_cursor_wm = { |
- | |
3486 | PINEVIEW_CURSOR_FIFO, |
- | |
3487 | PINEVIEW_CURSOR_MAX_WM, |
- | |
3488 | PINEVIEW_CURSOR_DFT_WM, |
- | |
3489 | PINEVIEW_CURSOR_GUARD_WM, |
- | |
3490 | PINEVIEW_FIFO_LINE_SIZE, |
- | |
3491 | }; |
- | |
3492 | static const struct intel_watermark_params pineview_cursor_hplloff_wm = { |
- | |
3493 | PINEVIEW_CURSOR_FIFO, |
- | |
3494 | PINEVIEW_CURSOR_MAX_WM, |
- | |
3495 | PINEVIEW_CURSOR_DFT_WM, |
- | |
3496 | PINEVIEW_CURSOR_GUARD_WM, |
- | |
3497 | PINEVIEW_FIFO_LINE_SIZE |
- | |
3498 | }; |
- | |
3499 | static const struct intel_watermark_params g4x_wm_info = { |
- | |
3500 | G4X_FIFO_SIZE, |
- | |
3501 | G4X_MAX_WM, |
- | |
3502 | G4X_MAX_WM, |
- | |
3503 | 2, |
- | |
3504 | G4X_FIFO_LINE_SIZE, |
- | |
3505 | }; |
- | |
3506 | static const struct intel_watermark_params g4x_cursor_wm_info = { |
- | |
3507 | I965_CURSOR_FIFO, |
- | |
3508 | I965_CURSOR_MAX_WM, |
- | |
3509 | I965_CURSOR_DFT_WM, |
- | |
3510 | 2, |
- | |
3511 | G4X_FIFO_LINE_SIZE, |
- | |
3512 | }; |
- | |
3513 | static const struct intel_watermark_params i965_cursor_wm_info = { |
- | |
3514 | I965_CURSOR_FIFO, |
- | |
3515 | I965_CURSOR_MAX_WM, |
- | |
3516 | I965_CURSOR_DFT_WM, |
- | |
3517 | 2, |
- | |
3518 | I915_FIFO_LINE_SIZE, |
- | |
3519 | }; |
- | |
3520 | static const struct intel_watermark_params i945_wm_info = { |
- | |
3521 | I945_FIFO_SIZE, |
- | |
3522 | I915_MAX_WM, |
- | |
3523 | 1, |
- | |
3524 | 2, |
- | |
3525 | I915_FIFO_LINE_SIZE |
- | |
3526 | }; |
- | |
3527 | static const struct intel_watermark_params i915_wm_info = { |
- | |
3528 | I915_FIFO_SIZE, |
- | |
3529 | I915_MAX_WM, |
- | |
3530 | 1, |
- | |
3531 | 2, |
- | |
3532 | I915_FIFO_LINE_SIZE |
- | |
3533 | }; |
- | |
3534 | static const struct intel_watermark_params i855_wm_info = { |
- | |
3535 | I855GM_FIFO_SIZE, |
- | |
3536 | I915_MAX_WM, |
- | |
3537 | 1, |
- | |
3538 | 2, |
- | |
3539 | I830_FIFO_LINE_SIZE |
- | |
3540 | }; |
- | |
3541 | static const struct intel_watermark_params i830_wm_info = { |
- | |
3542 | I830_FIFO_SIZE, |
- | |
3543 | I915_MAX_WM, |
- | |
3544 | 1, |
- | |
3545 | 2, |
- | |
3546 | I830_FIFO_LINE_SIZE |
- | |
3547 | }; |
- | |
3548 | - | ||
3549 | static const struct intel_watermark_params ironlake_display_wm_info = { |
- | |
3550 | ILK_DISPLAY_FIFO, |
- | |
3551 | ILK_DISPLAY_MAXWM, |
- | |
3552 | ILK_DISPLAY_DFTWM, |
- | |
3553 | 2, |
- | |
3554 | ILK_FIFO_LINE_SIZE |
- | |
3555 | }; |
- | |
3556 | static const struct intel_watermark_params ironlake_cursor_wm_info = { |
- | |
3557 | ILK_CURSOR_FIFO, |
- | |
3558 | ILK_CURSOR_MAXWM, |
- | |
3559 | ILK_CURSOR_DFTWM, |
- | |
3560 | 2, |
- | |
3561 | ILK_FIFO_LINE_SIZE |
- | |
3562 | }; |
- | |
3563 | static const struct intel_watermark_params ironlake_display_srwm_info = { |
- | |
3564 | ILK_DISPLAY_SR_FIFO, |
- | |
3565 | ILK_DISPLAY_MAX_SRWM, |
- | |
3566 | ILK_DISPLAY_DFT_SRWM, |
- | |
3567 | 2, |
- | |
3568 | ILK_FIFO_LINE_SIZE |
- | |
3569 | }; |
- | |
3570 | static const struct intel_watermark_params ironlake_cursor_srwm_info = { |
- | |
3571 | ILK_CURSOR_SR_FIFO, |
- | |
3572 | ILK_CURSOR_MAX_SRWM, |
- | |
3573 | ILK_CURSOR_DFT_SRWM, |
- | |
3574 | 2, |
- | |
3575 | ILK_FIFO_LINE_SIZE |
- | |
3576 | }; |
- | |
3577 | - | ||
3578 | static const struct intel_watermark_params sandybridge_display_wm_info = { |
- | |
3579 | SNB_DISPLAY_FIFO, |
- | |
3580 | SNB_DISPLAY_MAXWM, |
- | |
3581 | SNB_DISPLAY_DFTWM, |
- | |
3582 | 2, |
- | |
3583 | SNB_FIFO_LINE_SIZE |
- | |
3584 | }; |
- | |
3585 | static const struct intel_watermark_params sandybridge_cursor_wm_info = { |
- | |
3586 | SNB_CURSOR_FIFO, |
- | |
3587 | SNB_CURSOR_MAXWM, |
- | |
3588 | SNB_CURSOR_DFTWM, |
- | |
3589 | 2, |
- | |
3590 | SNB_FIFO_LINE_SIZE |
- | |
3591 | }; |
- | |
3592 | static const struct intel_watermark_params sandybridge_display_srwm_info = { |
- | |
3593 | SNB_DISPLAY_SR_FIFO, |
- | |
3594 | SNB_DISPLAY_MAX_SRWM, |
- | |
3595 | SNB_DISPLAY_DFT_SRWM, |
- | |
3596 | 2, |
- | |
3597 | SNB_FIFO_LINE_SIZE |
- | |
3598 | }; |
- | |
3599 | static const struct intel_watermark_params sandybridge_cursor_srwm_info = { |
- | |
3600 | SNB_CURSOR_SR_FIFO, |
- | |
3601 | SNB_CURSOR_MAX_SRWM, |
- | |
3602 | SNB_CURSOR_DFT_SRWM, |
- | |
3603 | 2, |
- | |
3604 | SNB_FIFO_LINE_SIZE |
- | |
3605 | }; |
- | |
3606 | - | ||
3607 | - | ||
3608 | /** |
- | |
3609 | * intel_calculate_wm - calculate watermark level |
- | |
3610 | * @clock_in_khz: pixel clock |
- | |
3611 | * @wm: chip FIFO params |
- | |
3612 | * @pixel_size: display pixel size |
- | |
3613 | * @latency_ns: memory latency for the platform |
- | |
3614 | * |
- | |
3615 | * Calculate the watermark level (the level at which the display plane will |
- | |
3616 | * start fetching from memory again). Each chip has a different display |
- | |
3617 | * FIFO size and allocation, so the caller needs to figure that out and pass |
- | |
3618 | * in the correct intel_watermark_params structure. |
- | |
3619 | * |
- | |
3620 | * As the pixel clock runs, the FIFO will be drained at a rate that depends |
- | |
3621 | * on the pixel size. When it reaches the watermark level, it'll start |
- | |
3622 | * fetching FIFO line sized based chunks from memory until the FIFO fills |
- | |
3623 | * past the watermark point. If the FIFO drains completely, a FIFO underrun |
- | |
3624 | * will occur, and a display engine hang could result. |
- | |
3625 | */ |
- | |
3626 | static unsigned long intel_calculate_wm(unsigned long clock_in_khz, |
- | |
3627 | const struct intel_watermark_params *wm, |
- | |
3628 | int fifo_size, |
- | |
3629 | int pixel_size, |
- | |
3630 | unsigned long latency_ns) |
- | |
3631 | { |
- | |
3632 | long entries_required, wm_size; |
- | |
3633 | - | ||
3634 | /* |
- | |
3635 | * Note: we need to make sure we don't overflow for various clock & |
- | |
3636 | * latency values. |
- | |
3637 | * clocks go from a few thousand to several hundred thousand. |
- | |
3638 | * latency is usually a few thousand |
- | |
3639 | */ |
- | |
3640 | entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) / |
- | |
3641 | 1000; |
- | |
3642 | entries_required = DIV_ROUND_UP(entries_required, wm->cacheline_size); |
- | |
3643 | - | ||
3644 | DRM_DEBUG_KMS("FIFO entries required for mode: %ld\n", entries_required); |
- | |
3645 | - | ||
3646 | wm_size = fifo_size - (entries_required + wm->guard_size); |
- | |
3647 | - | ||
3648 | DRM_DEBUG_KMS("FIFO watermark level: %ld\n", wm_size); |
- | |
3649 | - | ||
3650 | /* Don't promote wm_size to unsigned... */ |
- | |
3651 | if (wm_size > (long)wm->max_wm) |
- | |
3652 | wm_size = wm->max_wm; |
- | |
3653 | if (wm_size <= 0) |
- | |
3654 | wm_size = wm->default_wm; |
- | |
3655 | return wm_size; |
- | |
3656 | } |
- | |
3657 | - | ||
3658 | struct cxsr_latency { |
- | |
3659 | int is_desktop; |
- | |
3660 | int is_ddr3; |
- | |
3661 | unsigned long fsb_freq; |
- | |
3662 | unsigned long mem_freq; |
- | |
3663 | unsigned long display_sr; |
- | |
3664 | unsigned long display_hpll_disable; |
- | |
3665 | unsigned long cursor_sr; |
- | |
3666 | unsigned long cursor_hpll_disable; |
- | |
3667 | }; |
- | |
3668 | - | ||
3669 | static const struct cxsr_latency cxsr_latency_table[] = { |
- | |
3670 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ |
- | |
3671 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ |
- | |
3672 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ |
- | |
3673 | {1, 1, 800, 667, 6420, 36420, 6873, 36873}, /* DDR3-667 SC */ |
- | |
3674 | {1, 1, 800, 800, 5902, 35902, 6318, 36318}, /* DDR3-800 SC */ |
- | |
3675 | - | ||
3676 | {1, 0, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ |
- | |
3677 | {1, 0, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ |
- | |
3678 | {1, 0, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ |
- | |
3679 | {1, 1, 667, 667, 6438, 36438, 6911, 36911}, /* DDR3-667 SC */ |
- | |
3680 | {1, 1, 667, 800, 5941, 35941, 6377, 36377}, /* DDR3-800 SC */ |
- | |
3681 | - | ||
3682 | {1, 0, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ |
- | |
3683 | {1, 0, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ |
- | |
3684 | {1, 0, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ |
- | |
3685 | {1, 1, 400, 667, 6509, 36509, 7062, 37062}, /* DDR3-667 SC */ |
- | |
3686 | {1, 1, 400, 800, 5985, 35985, 6501, 36501}, /* DDR3-800 SC */ |
- | |
3687 | - | ||
3688 | {0, 0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ |
- | |
3689 | {0, 0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ |
- | |
3690 | {0, 0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ |
- | |
3691 | {0, 1, 800, 667, 6476, 36476, 6955, 36955}, /* DDR3-667 SC */ |
- | |
3692 | {0, 1, 800, 800, 5958, 35958, 6400, 36400}, /* DDR3-800 SC */ |
- | |
3693 | - | ||
3694 | {0, 0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ |
- | |
3695 | {0, 0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ |
- | |
3696 | {0, 0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ |
- | |
3697 | {0, 1, 667, 667, 6494, 36494, 6993, 36993}, /* DDR3-667 SC */ |
- | |
3698 | {0, 1, 667, 800, 5998, 35998, 6460, 36460}, /* DDR3-800 SC */ |
- | |
3699 | - | ||
3700 | {0, 0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ |
- | |
3701 | {0, 0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ |
- | |
3702 | {0, 0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ |
- | |
3703 | {0, 1, 400, 667, 6566, 36566, 7145, 37145}, /* DDR3-667 SC */ |
- | |
3704 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ |
- | |
3705 | }; |
- | |
3706 | - | ||
3707 | static const struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, |
- | |
3708 | int is_ddr3, |
- | |
3709 | int fsb, |
- | |
3710 | int mem) |
- | |
3711 | { |
- | |
3712 | const struct cxsr_latency *latency; |
- | |
3713 | int i; |
- | |
3714 | - | ||
3715 | if (fsb == 0 || mem == 0) |
- | |
3716 | return NULL; |
- | |
3717 | - | ||
3718 | for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { |
- | |
3719 | latency = &cxsr_latency_table[i]; |
- | |
3720 | if (is_desktop == latency->is_desktop && |
- | |
3721 | is_ddr3 == latency->is_ddr3 && |
- | |
3722 | fsb == latency->fsb_freq && mem == latency->mem_freq) |
- | |
3723 | return latency; |
- | |
3724 | } |
- | |
3725 | - | ||
3726 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); |
- | |
3727 | - | ||
3728 | return NULL; |
- | |
3729 | } |
- | |
3730 | - | ||
3731 | static void pineview_disable_cxsr(struct drm_device *dev) |
- | |
3732 | { |
- | |
3733 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
3734 | - | ||
3735 | /* deactivate cxsr */ |
- | |
3736 | I915_WRITE(DSPFW3, I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN); |
- | |
3737 | } |
- | |
3738 | - | ||
3739 | /* |
- | |
3740 | * Latency for FIFO fetches is dependent on several factors: |
- | |
3741 | * - memory configuration (speed, channels) |
- | |
3742 | * - chipset |
- | |
3743 | * - current MCH state |
- | |
3744 | * It can be fairly high in some situations, so here we assume a fairly |
- | |
3745 | * pessimal value. It's a tradeoff between extra memory fetches (if we |
- | |
3746 | * set this value too high, the FIFO will fetch frequently to stay full) |
- | |
3747 | * and power consumption (set it too low to save power and we might see |
- | |
3748 | * FIFO underruns and display "flicker"). |
- | |
3749 | * |
- | |
3750 | * A value of 5us seems to be a good balance; safe for very low end |
- | |
3751 | * platforms but not overly aggressive on lower latency configs. |
- | |
3752 | */ |
- | |
3753 | static const int latency_ns = 5000; |
- | |
3754 | - | ||
3755 | static int i9xx_get_fifo_size(struct drm_device *dev, int plane) |
- | |
3756 | { |
- | |
3757 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
3758 | uint32_t dsparb = I915_READ(DSPARB); |
- | |
3759 | int size; |
- | |
3760 | - | ||
3761 | size = dsparb & 0x7f; |
- | |
3762 | if (plane) |
- | |
3763 | size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - size; |
- | |
3764 | - | ||
3765 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, |
- | |
3766 | plane ? "B" : "A", size); |
- | |
3767 | - | ||
3768 | return size; |
- | |
3769 | } |
- | |
3770 | - | ||
3771 | static int i85x_get_fifo_size(struct drm_device *dev, int plane) |
- | |
3772 | { |
- | |
3773 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
3774 | uint32_t dsparb = I915_READ(DSPARB); |
- | |
3775 | int size; |
- | |
3776 | - | ||
3777 | size = dsparb & 0x1ff; |
- | |
3778 | if (plane) |
- | |
3779 | size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - size; |
- | |
3780 | size >>= 1; /* Convert to cachelines */ |
- | |
3781 | - | ||
3782 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, |
- | |
3783 | plane ? "B" : "A", size); |
- | |
3784 | - | ||
3785 | return size; |
- | |
3786 | } |
- | |
3787 | - | ||
3788 | static int i845_get_fifo_size(struct drm_device *dev, int plane) |
- | |
3789 | { |
- | |
3790 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
3791 | uint32_t dsparb = I915_READ(DSPARB); |
- | |
3792 | int size; |
- | |
3793 | - | ||
3794 | size = dsparb & 0x7f; |
- | |
3795 | size >>= 2; /* Convert to cachelines */ |
- | |
3796 | - | ||
3797 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, |
- | |
3798 | plane ? "B" : "A", |
- | |
3799 | size); |
- | |
3800 | - | ||
3801 | return size; |
- | |
3802 | } |
- | |
3803 | - | ||
3804 | static int i830_get_fifo_size(struct drm_device *dev, int plane) |
- | |
3805 | { |
- | |
3806 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
3807 | uint32_t dsparb = I915_READ(DSPARB); |
- | |
3808 | int size; |
- | |
3809 | - | ||
3810 | size = dsparb & 0x7f; |
- | |
3811 | size >>= 1; /* Convert to cachelines */ |
- | |
3812 | - | ||
3813 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, |
- | |
3814 | plane ? "B" : "A", size); |
- | |
3815 | - | ||
3816 | return size; |
- | |
3817 | } |
- | |
3818 | - | ||
3819 | static struct drm_crtc *single_enabled_crtc(struct drm_device *dev) |
- | |
3820 | { |
- | |
3821 | struct drm_crtc *crtc, *enabled = NULL; |
- | |
3822 | - | ||
3823 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
- | |
3824 | if (crtc->enabled && crtc->fb) { |
- | |
3825 | if (enabled) |
- | |
3826 | return NULL; |
- | |
3827 | enabled = crtc; |
- | |
3828 | } |
- | |
3829 | } |
- | |
3830 | - | ||
3831 | return enabled; |
- | |
3832 | } |
- | |
3833 | - | ||
3834 | static void pineview_update_wm(struct drm_device *dev) |
- | |
3835 | { |
- | |
3836 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
3837 | struct drm_crtc *crtc; |
- | |
3838 | const struct cxsr_latency *latency; |
- | |
3839 | u32 reg; |
- | |
3840 | unsigned long wm; |
- | |
3841 | - | ||
3842 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, |
- | |
3843 | dev_priv->fsb_freq, dev_priv->mem_freq); |
- | |
3844 | if (!latency) { |
- | |
3845 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); |
- | |
3846 | pineview_disable_cxsr(dev); |
- | |
3847 | return; |
- | |
3848 | } |
- | |
3849 | - | ||
3850 | crtc = single_enabled_crtc(dev); |
- | |
3851 | if (crtc) { |
- | |
3852 | int clock = crtc->mode.clock; |
- | |
3853 | int pixel_size = crtc->fb->bits_per_pixel / 8; |
- | |
3854 | - | ||
3855 | /* Display SR */ |
- | |
3856 | wm = intel_calculate_wm(clock, &pineview_display_wm, |
- | |
3857 | pineview_display_wm.fifo_size, |
- | |
3858 | pixel_size, latency->display_sr); |
- | |
3859 | reg = I915_READ(DSPFW1); |
- | |
3860 | reg &= ~DSPFW_SR_MASK; |
- | |
3861 | reg |= wm << DSPFW_SR_SHIFT; |
- | |
3862 | I915_WRITE(DSPFW1, reg); |
- | |
3863 | DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg); |
- | |
3864 | - | ||
3865 | /* cursor SR */ |
- | |
3866 | wm = intel_calculate_wm(clock, &pineview_cursor_wm, |
- | |
3867 | pineview_display_wm.fifo_size, |
- | |
3868 | pixel_size, latency->cursor_sr); |
- | |
3869 | reg = I915_READ(DSPFW3); |
- | |
3870 | reg &= ~DSPFW_CURSOR_SR_MASK; |
- | |
3871 | reg |= (wm & 0x3f) << DSPFW_CURSOR_SR_SHIFT; |
- | |
3872 | I915_WRITE(DSPFW3, reg); |
- | |
3873 | - | ||
3874 | /* Display HPLL off SR */ |
- | |
3875 | wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm, |
- | |
3876 | pineview_display_hplloff_wm.fifo_size, |
- | |
3877 | pixel_size, latency->display_hpll_disable); |
- | |
3878 | reg = I915_READ(DSPFW3); |
- | |
3879 | reg &= ~DSPFW_HPLL_SR_MASK; |
- | |
3880 | reg |= wm & DSPFW_HPLL_SR_MASK; |
- | |
3881 | I915_WRITE(DSPFW3, reg); |
- | |
3882 | - | ||
3883 | /* cursor HPLL off SR */ |
- | |
3884 | wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm, |
- | |
3885 | pineview_display_hplloff_wm.fifo_size, |
- | |
3886 | pixel_size, latency->cursor_hpll_disable); |
- | |
3887 | reg = I915_READ(DSPFW3); |
- | |
3888 | reg &= ~DSPFW_HPLL_CURSOR_MASK; |
- | |
3889 | reg |= (wm & 0x3f) << DSPFW_HPLL_CURSOR_SHIFT; |
- | |
3890 | I915_WRITE(DSPFW3, reg); |
- | |
3891 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); |
- | |
3892 | - | ||
3893 | /* activate cxsr */ |
- | |
3894 | I915_WRITE(DSPFW3, |
- | |
3895 | I915_READ(DSPFW3) | PINEVIEW_SELF_REFRESH_EN); |
- | |
3896 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); |
- | |
3897 | } else { |
- | |
3898 | pineview_disable_cxsr(dev); |
- | |
3899 | DRM_DEBUG_KMS("Self-refresh is disabled\n"); |
- | |
3900 | } |
- | |
3901 | } |
- | |
3902 | - | ||
3903 | static bool g4x_compute_wm0(struct drm_device *dev, |
- | |
3904 | int plane, |
- | |
3905 | const struct intel_watermark_params *display, |
- | |
3906 | int display_latency_ns, |
- | |
3907 | const struct intel_watermark_params *cursor, |
- | |
3908 | int cursor_latency_ns, |
- | |
3909 | int *plane_wm, |
- | |
3910 | int *cursor_wm) |
- | |
3911 | { |
- | |
3912 | struct drm_crtc *crtc; |
- | |
3913 | int htotal, hdisplay, clock, pixel_size; |
- | |
3914 | int line_time_us, line_count; |
- | |
3915 | int entries, tlb_miss; |
- | |
3916 | - | ||
3917 | crtc = intel_get_crtc_for_plane(dev, plane); |
- | |
3918 | if (crtc->fb == NULL || !crtc->enabled) { |
- | |
3919 | *cursor_wm = cursor->guard_size; |
- | |
3920 | *plane_wm = display->guard_size; |
- | |
3921 | return false; |
- | |
3922 | } |
- | |
3923 | - | ||
3924 | htotal = crtc->mode.htotal; |
- | |
3925 | hdisplay = crtc->mode.hdisplay; |
- | |
3926 | clock = crtc->mode.clock; |
- | |
3927 | pixel_size = crtc->fb->bits_per_pixel / 8; |
- | |
3928 | - | ||
3929 | /* Use the small buffer method to calculate plane watermark */ |
- | |
3930 | entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; |
- | |
3931 | tlb_miss = display->fifo_size*display->cacheline_size - hdisplay * 8; |
- | |
3932 | if (tlb_miss > 0) |
- | |
3933 | entries += tlb_miss; |
- | |
3934 | entries = DIV_ROUND_UP(entries, display->cacheline_size); |
- | |
3935 | *plane_wm = entries + display->guard_size; |
- | |
3936 | if (*plane_wm > (int)display->max_wm) |
- | |
3937 | *plane_wm = display->max_wm; |
- | |
3938 | - | ||
3939 | /* Use the large buffer method to calculate cursor watermark */ |
- | |
3940 | line_time_us = ((htotal * 1000) / clock); |
- | |
3941 | line_count = (cursor_latency_ns / line_time_us + 1000) / 1000; |
- | |
3942 | entries = line_count * 64 * pixel_size; |
- | |
3943 | tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8; |
- | |
3944 | if (tlb_miss > 0) |
- | |
3945 | entries += tlb_miss; |
- | |
3946 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); |
- | |
3947 | *cursor_wm = entries + cursor->guard_size; |
- | |
3948 | if (*cursor_wm > (int)cursor->max_wm) |
- | |
3949 | *cursor_wm = (int)cursor->max_wm; |
- | |
3950 | - | ||
3951 | return true; |
- | |
3952 | } |
- | |
3953 | - | ||
3954 | /* |
- | |
3955 | * Check the wm result. |
- | |
3956 | * |
- | |
3957 | * If any calculated watermark values is larger than the maximum value that |
- | |
3958 | * can be programmed into the associated watermark register, that watermark |
- | |
3959 | * must be disabled. |
- | |
3960 | */ |
- | |
3961 | static bool g4x_check_srwm(struct drm_device *dev, |
- | |
3962 | int display_wm, int cursor_wm, |
- | |
3963 | const struct intel_watermark_params *display, |
- | |
3964 | const struct intel_watermark_params *cursor) |
- | |
3965 | { |
- | |
3966 | DRM_DEBUG_KMS("SR watermark: display plane %d, cursor %d\n", |
- | |
3967 | display_wm, cursor_wm); |
- | |
3968 | - | ||
3969 | if (display_wm > display->max_wm) { |
- | |
3970 | DRM_DEBUG_KMS("display watermark is too large(%d/%ld), disabling\n", |
- | |
3971 | display_wm, display->max_wm); |
- | |
3972 | return false; |
- | |
3973 | } |
- | |
3974 | - | ||
3975 | if (cursor_wm > cursor->max_wm) { |
- | |
3976 | DRM_DEBUG_KMS("cursor watermark is too large(%d/%ld), disabling\n", |
- | |
3977 | cursor_wm, cursor->max_wm); |
- | |
3978 | return false; |
- | |
3979 | } |
- | |
3980 | - | ||
3981 | if (!(display_wm || cursor_wm)) { |
- | |
3982 | DRM_DEBUG_KMS("SR latency is 0, disabling\n"); |
- | |
3983 | return false; |
- | |
3984 | } |
- | |
3985 | - | ||
3986 | return true; |
- | |
3987 | } |
- | |
3988 | - | ||
3989 | static bool g4x_compute_srwm(struct drm_device *dev, |
- | |
3990 | int plane, |
- | |
3991 | int latency_ns, |
- | |
3992 | const struct intel_watermark_params *display, |
- | |
3993 | const struct intel_watermark_params *cursor, |
- | |
3994 | int *display_wm, int *cursor_wm) |
- | |
3995 | { |
- | |
3996 | struct drm_crtc *crtc; |
- | |
3997 | int hdisplay, htotal, pixel_size, clock; |
- | |
3998 | unsigned long line_time_us; |
- | |
3999 | int line_count, line_size; |
- | |
4000 | int small, large; |
- | |
4001 | int entries; |
- | |
4002 | - | ||
4003 | if (!latency_ns) { |
- | |
4004 | *display_wm = *cursor_wm = 0; |
- | |
4005 | return false; |
- | |
4006 | } |
- | |
4007 | - | ||
4008 | crtc = intel_get_crtc_for_plane(dev, plane); |
- | |
4009 | hdisplay = crtc->mode.hdisplay; |
- | |
4010 | htotal = crtc->mode.htotal; |
- | |
4011 | clock = crtc->mode.clock; |
- | |
4012 | pixel_size = crtc->fb->bits_per_pixel / 8; |
- | |
4013 | - | ||
4014 | line_time_us = (htotal * 1000) / clock; |
- | |
4015 | line_count = (latency_ns / line_time_us + 1000) / 1000; |
- | |
4016 | line_size = hdisplay * pixel_size; |
- | |
4017 | - | ||
4018 | /* Use the minimum of the small and large buffer method for primary */ |
- | |
4019 | small = ((clock * pixel_size / 1000) * latency_ns) / 1000; |
- | |
4020 | large = line_count * line_size; |
- | |
4021 | - | ||
4022 | entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); |
- | |
4023 | *display_wm = entries + display->guard_size; |
- | |
4024 | - | ||
4025 | /* calculate the self-refresh watermark for display cursor */ |
- | |
4026 | entries = line_count * pixel_size * 64; |
- | |
4027 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); |
- | |
4028 | *cursor_wm = entries + cursor->guard_size; |
- | |
4029 | - | ||
4030 | return g4x_check_srwm(dev, |
- | |
4031 | *display_wm, *cursor_wm, |
- | |
4032 | display, cursor); |
- | |
4033 | } |
- | |
4034 | - | ||
4035 | #define single_plane_enabled(mask) is_power_of_2(mask) |
- | |
4036 | - | ||
4037 | static void g4x_update_wm(struct drm_device *dev) |
- | |
4038 | { |
- | |
4039 | static const int sr_latency_ns = 12000; |
- | |
4040 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
4041 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; |
- | |
4042 | int plane_sr, cursor_sr; |
- | |
4043 | unsigned int enabled = 0; |
- | |
4044 | - | ||
4045 | if (g4x_compute_wm0(dev, 0, |
- | |
4046 | &g4x_wm_info, latency_ns, |
- | |
4047 | &g4x_cursor_wm_info, latency_ns, |
- | |
4048 | &planea_wm, &cursora_wm)) |
- | |
4049 | enabled |= 1; |
- | |
4050 | - | ||
4051 | if (g4x_compute_wm0(dev, 1, |
- | |
4052 | &g4x_wm_info, latency_ns, |
- | |
4053 | &g4x_cursor_wm_info, latency_ns, |
- | |
4054 | &planeb_wm, &cursorb_wm)) |
- | |
4055 | enabled |= 2; |
- | |
4056 | - | ||
4057 | plane_sr = cursor_sr = 0; |
- | |
4058 | if (single_plane_enabled(enabled) && |
- | |
4059 | g4x_compute_srwm(dev, ffs(enabled) - 1, |
- | |
4060 | sr_latency_ns, |
- | |
4061 | &g4x_wm_info, |
- | |
4062 | &g4x_cursor_wm_info, |
- | |
4063 | &plane_sr, &cursor_sr)) |
- | |
4064 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); |
- | |
4065 | else |
- | |
4066 | I915_WRITE(FW_BLC_SELF, |
- | |
4067 | I915_READ(FW_BLC_SELF) & ~FW_BLC_SELF_EN); |
- | |
4068 | - | ||
4069 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", |
- | |
4070 | planea_wm, cursora_wm, |
- | |
4071 | planeb_wm, cursorb_wm, |
- | |
4072 | plane_sr, cursor_sr); |
- | |
4073 | - | ||
4074 | I915_WRITE(DSPFW1, |
- | |
4075 | (plane_sr << DSPFW_SR_SHIFT) | |
- | |
4076 | (cursorb_wm << DSPFW_CURSORB_SHIFT) | |
- | |
4077 | (planeb_wm << DSPFW_PLANEB_SHIFT) | |
- | |
4078 | planea_wm); |
- | |
4079 | I915_WRITE(DSPFW2, |
- | |
4080 | (I915_READ(DSPFW2) & DSPFW_CURSORA_MASK) | |
- | |
4081 | (cursora_wm << DSPFW_CURSORA_SHIFT)); |
- | |
4082 | /* HPLL off in SR has some issues on G4x... disable it */ |
- | |
4083 | I915_WRITE(DSPFW3, |
- | |
4084 | (I915_READ(DSPFW3) & ~DSPFW_HPLL_SR_EN) | |
- | |
4085 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); |
- | |
4086 | } |
- | |
4087 | - | ||
4088 | static void i965_update_wm(struct drm_device *dev) |
- | |
4089 | { |
- | |
4090 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
4091 | struct drm_crtc *crtc; |
- | |
4092 | int srwm = 1; |
- | |
4093 | int cursor_sr = 16; |
- | |
4094 | - | ||
4095 | /* Calc sr entries for one plane configs */ |
- | |
4096 | crtc = single_enabled_crtc(dev); |
- | |
4097 | if (crtc) { |
- | |
4098 | /* self-refresh has much higher latency */ |
- | |
4099 | static const int sr_latency_ns = 12000; |
- | |
4100 | int clock = crtc->mode.clock; |
- | |
4101 | int htotal = crtc->mode.htotal; |
- | |
4102 | int hdisplay = crtc->mode.hdisplay; |
- | |
4103 | int pixel_size = crtc->fb->bits_per_pixel / 8; |
- | |
4104 | unsigned long line_time_us; |
- | |
4105 | int entries; |
- | |
4106 | - | ||
4107 | line_time_us = ((htotal * 1000) / clock); |
- | |
4108 | - | ||
4109 | /* Use ns/us then divide to preserve precision */ |
- | |
4110 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
- | |
4111 | pixel_size * hdisplay; |
- | |
4112 | entries = DIV_ROUND_UP(entries, I915_FIFO_LINE_SIZE); |
- | |
4113 | srwm = I965_FIFO_SIZE - entries; |
- | |
4114 | if (srwm < 0) |
- | |
4115 | srwm = 1; |
- | |
4116 | srwm &= 0x1ff; |
- | |
4117 | DRM_DEBUG_KMS("self-refresh entries: %d, wm: %d\n", |
- | |
4118 | entries, srwm); |
- | |
4119 | - | ||
4120 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
- | |
4121 | pixel_size * 64; |
- | |
4122 | entries = DIV_ROUND_UP(entries, |
- | |
4123 | i965_cursor_wm_info.cacheline_size); |
- | |
4124 | cursor_sr = i965_cursor_wm_info.fifo_size - |
- | |
4125 | (entries + i965_cursor_wm_info.guard_size); |
- | |
4126 | - | ||
4127 | if (cursor_sr > i965_cursor_wm_info.max_wm) |
- | |
4128 | cursor_sr = i965_cursor_wm_info.max_wm; |
- | |
4129 | - | ||
4130 | DRM_DEBUG_KMS("self-refresh watermark: display plane %d " |
- | |
4131 | "cursor %d\n", srwm, cursor_sr); |
- | |
4132 | - | ||
4133 | if (IS_CRESTLINE(dev)) |
- | |
4134 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); |
- | |
4135 | } else { |
- | |
4136 | /* Turn off self refresh if both pipes are enabled */ |
- | |
4137 | if (IS_CRESTLINE(dev)) |
- | |
4138 | I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) |
- | |
4139 | & ~FW_BLC_SELF_EN); |
- | |
4140 | } |
- | |
4141 | - | ||
4142 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", |
- | |
4143 | srwm); |
- | |
4144 | - | ||
4145 | /* 965 has limitations... */ |
- | |
4146 | I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | |
- | |
4147 | (8 << 16) | (8 << 8) | (8 << 0)); |
- | |
4148 | I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); |
- | |
4149 | /* update cursor SR watermark */ |
- | |
4150 | I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); |
- | |
4151 | } |
- | |
4152 | - | ||
4153 | static void i9xx_update_wm(struct drm_device *dev) |
- | |
4154 | { |
- | |
4155 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
4156 | const struct intel_watermark_params *wm_info; |
- | |
4157 | uint32_t fwater_lo; |
- | |
4158 | uint32_t fwater_hi; |
- | |
4159 | int cwm, srwm = 1; |
- | |
4160 | int fifo_size; |
- | |
4161 | int planea_wm, planeb_wm; |
- | |
4162 | struct drm_crtc *crtc, *enabled = NULL; |
- | |
4163 | - | ||
4164 | if (IS_I945GM(dev)) |
- | |
4165 | wm_info = &i945_wm_info; |
- | |
4166 | else if (!IS_GEN2(dev)) |
- | |
4167 | wm_info = &i915_wm_info; |
- | |
4168 | else |
- | |
4169 | wm_info = &i855_wm_info; |
- | |
4170 | - | ||
4171 | fifo_size = dev_priv->display.get_fifo_size(dev, 0); |
- | |
4172 | crtc = intel_get_crtc_for_plane(dev, 0); |
- | |
4173 | if (crtc->enabled && crtc->fb) { |
- | |
4174 | planea_wm = intel_calculate_wm(crtc->mode.clock, |
- | |
4175 | wm_info, fifo_size, |
- | |
4176 | crtc->fb->bits_per_pixel / 8, |
- | |
4177 | latency_ns); |
- | |
4178 | enabled = crtc; |
- | |
4179 | } else |
- | |
4180 | planea_wm = fifo_size - wm_info->guard_size; |
- | |
4181 | - | ||
4182 | fifo_size = dev_priv->display.get_fifo_size(dev, 1); |
- | |
4183 | crtc = intel_get_crtc_for_plane(dev, 1); |
- | |
4184 | if (crtc->enabled && crtc->fb) { |
- | |
4185 | planeb_wm = intel_calculate_wm(crtc->mode.clock, |
- | |
4186 | wm_info, fifo_size, |
- | |
4187 | crtc->fb->bits_per_pixel / 8, |
- | |
4188 | latency_ns); |
- | |
4189 | if (enabled == NULL) |
- | |
4190 | enabled = crtc; |
- | |
4191 | else |
- | |
4192 | enabled = NULL; |
- | |
4193 | } else |
- | |
4194 | planeb_wm = fifo_size - wm_info->guard_size; |
- | |
4195 | - | ||
4196 | DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); |
- | |
4197 | - | ||
4198 | /* |
- | |
4199 | * Overlay gets an aggressive default since video jitter is bad. |
- | |
4200 | */ |
- | |
4201 | cwm = 2; |
- | |
4202 | - | ||
4203 | /* Play safe and disable self-refresh before adjusting watermarks. */ |
- | |
4204 | if (IS_I945G(dev) || IS_I945GM(dev)) |
- | |
4205 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | 0); |
- | |
4206 | else if (IS_I915GM(dev)) |
- | |
4207 | I915_WRITE(INSTPM, I915_READ(INSTPM) & ~INSTPM_SELF_EN); |
- | |
4208 | - | ||
4209 | /* Calc sr entries for one plane configs */ |
- | |
4210 | if (HAS_FW_BLC(dev) && enabled) { |
- | |
4211 | /* self-refresh has much higher latency */ |
- | |
4212 | static const int sr_latency_ns = 6000; |
- | |
4213 | int clock = enabled->mode.clock; |
- | |
4214 | int htotal = enabled->mode.htotal; |
- | |
4215 | int hdisplay = enabled->mode.hdisplay; |
- | |
4216 | int pixel_size = enabled->fb->bits_per_pixel / 8; |
- | |
4217 | unsigned long line_time_us; |
- | |
4218 | int entries; |
- | |
4219 | - | ||
4220 | line_time_us = (htotal * 1000) / clock; |
- | |
4221 | - | ||
4222 | /* Use ns/us then divide to preserve precision */ |
- | |
4223 | entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
- | |
4224 | pixel_size * hdisplay; |
- | |
4225 | entries = DIV_ROUND_UP(entries, wm_info->cacheline_size); |
- | |
4226 | DRM_DEBUG_KMS("self-refresh entries: %d\n", entries); |
- | |
4227 | srwm = wm_info->fifo_size - entries; |
- | |
4228 | if (srwm < 0) |
- | |
4229 | srwm = 1; |
- | |
4230 | - | ||
4231 | if (IS_I945G(dev) || IS_I945GM(dev)) |
- | |
4232 | I915_WRITE(FW_BLC_SELF, |
- | |
4233 | FW_BLC_SELF_FIFO_MASK | (srwm & 0xff)); |
- | |
4234 | else if (IS_I915GM(dev)) |
- | |
4235 | I915_WRITE(FW_BLC_SELF, srwm & 0x3f); |
- | |
4236 | } |
- | |
4237 | - | ||
4238 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", |
- | |
4239 | planea_wm, planeb_wm, cwm, srwm); |
- | |
4240 | - | ||
4241 | fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f); |
- | |
4242 | fwater_hi = (cwm & 0x1f); |
- | |
4243 | - | ||
4244 | /* Set request length to 8 cachelines per fetch */ |
- | |
4245 | fwater_lo = fwater_lo | (1 << 24) | (1 << 8); |
- | |
4246 | fwater_hi = fwater_hi | (1 << 8); |
- | |
4247 | - | ||
4248 | I915_WRITE(FW_BLC, fwater_lo); |
- | |
4249 | I915_WRITE(FW_BLC2, fwater_hi); |
- | |
4250 | - | ||
4251 | if (HAS_FW_BLC(dev)) { |
- | |
4252 | if (enabled) { |
- | |
4253 | if (IS_I945G(dev) || IS_I945GM(dev)) |
- | |
4254 | I915_WRITE(FW_BLC_SELF, |
- | |
4255 | FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); |
- | |
4256 | else if (IS_I915GM(dev)) |
- | |
4257 | I915_WRITE(INSTPM, I915_READ(INSTPM) | INSTPM_SELF_EN); |
- | |
4258 | DRM_DEBUG_KMS("memory self refresh enabled\n"); |
- | |
4259 | } else |
- | |
4260 | DRM_DEBUG_KMS("memory self refresh disabled\n"); |
- | |
4261 | } |
- | |
4262 | } |
- | |
4263 | - | ||
4264 | static void i830_update_wm(struct drm_device *dev) |
- | |
4265 | { |
- | |
4266 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
4267 | struct drm_crtc *crtc; |
- | |
4268 | uint32_t fwater_lo; |
- | |
4269 | int planea_wm; |
- | |
4270 | - | ||
4271 | crtc = single_enabled_crtc(dev); |
- | |
4272 | if (crtc == NULL) |
- | |
4273 | return; |
- | |
4274 | - | ||
4275 | planea_wm = intel_calculate_wm(crtc->mode.clock, &i830_wm_info, |
- | |
4276 | dev_priv->display.get_fifo_size(dev, 0), |
- | |
4277 | crtc->fb->bits_per_pixel / 8, |
- | |
4278 | latency_ns); |
- | |
4279 | fwater_lo = I915_READ(FW_BLC) & ~0xfff; |
- | |
4280 | fwater_lo |= (3<<8) | planea_wm; |
- | |
4281 | - | ||
4282 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm); |
- | |
4283 | - | ||
4284 | I915_WRITE(FW_BLC, fwater_lo); |
- | |
4285 | } |
- | |
4286 | - | ||
4287 | #define ILK_LP0_PLANE_LATENCY 700 |
- | |
4288 | #define ILK_LP0_CURSOR_LATENCY 1300 |
- | |
4289 | - | ||
4290 | /* |
- | |
4291 | * Check the wm result. |
- | |
4292 | * |
- | |
4293 | * If any calculated watermark values is larger than the maximum value that |
- | |
4294 | * can be programmed into the associated watermark register, that watermark |
- | |
4295 | * must be disabled. |
- | |
4296 | */ |
- | |
4297 | static bool ironlake_check_srwm(struct drm_device *dev, int level, |
- | |
4298 | int fbc_wm, int display_wm, int cursor_wm, |
- | |
4299 | const struct intel_watermark_params *display, |
- | |
4300 | const struct intel_watermark_params *cursor) |
- | |
4301 | { |
- | |
4302 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
4303 | - | ||
4304 | DRM_DEBUG_KMS("watermark %d: display plane %d, fbc lines %d," |
- | |
4305 | " cursor %d\n", level, display_wm, fbc_wm, cursor_wm); |
- | |
4306 | - | ||
4307 | if (fbc_wm > SNB_FBC_MAX_SRWM) { |
- | |
4308 | DRM_DEBUG_KMS("fbc watermark(%d) is too large(%d), disabling wm%d+\n", |
- | |
4309 | fbc_wm, SNB_FBC_MAX_SRWM, level); |
- | |
4310 | - | ||
4311 | /* fbc has it's own way to disable FBC WM */ |
- | |
4312 | I915_WRITE(DISP_ARB_CTL, |
- | |
4313 | I915_READ(DISP_ARB_CTL) | DISP_FBC_WM_DIS); |
- | |
4314 | return false; |
- | |
4315 | } |
- | |
4316 | - | ||
4317 | if (display_wm > display->max_wm) { |
- | |
4318 | DRM_DEBUG_KMS("display watermark(%d) is too large(%d), disabling wm%d+\n", |
- | |
4319 | display_wm, SNB_DISPLAY_MAX_SRWM, level); |
- | |
4320 | return false; |
- | |
4321 | } |
- | |
4322 | - | ||
4323 | if (cursor_wm > cursor->max_wm) { |
- | |
4324 | DRM_DEBUG_KMS("cursor watermark(%d) is too large(%d), disabling wm%d+\n", |
- | |
4325 | cursor_wm, SNB_CURSOR_MAX_SRWM, level); |
- | |
4326 | return false; |
- | |
4327 | } |
- | |
4328 | - | ||
4329 | if (!(fbc_wm || display_wm || cursor_wm)) { |
- | |
4330 | DRM_DEBUG_KMS("latency %d is 0, disabling wm%d+\n", level, level); |
- | |
4331 | return false; |
- | |
4332 | } |
- | |
4333 | - | ||
4334 | return true; |
- | |
4335 | } |
- | |
4336 | - | ||
4337 | /* |
- | |
4338 | * Compute watermark values of WM[1-3], |
- | |
4339 | */ |
- | |
4340 | static bool ironlake_compute_srwm(struct drm_device *dev, int level, int plane, |
- | |
4341 | int latency_ns, |
- | |
4342 | const struct intel_watermark_params *display, |
- | |
4343 | const struct intel_watermark_params *cursor, |
- | |
4344 | int *fbc_wm, int *display_wm, int *cursor_wm) |
- | |
4345 | { |
- | |
4346 | struct drm_crtc *crtc; |
- | |
4347 | unsigned long line_time_us; |
- | |
4348 | int hdisplay, htotal, pixel_size, clock; |
- | |
4349 | int line_count, line_size; |
- | |
4350 | int small, large; |
- | |
4351 | int entries; |
- | |
4352 | - | ||
4353 | if (!latency_ns) { |
- | |
4354 | *fbc_wm = *display_wm = *cursor_wm = 0; |
- | |
4355 | return false; |
- | |
4356 | } |
- | |
4357 | - | ||
4358 | crtc = intel_get_crtc_for_plane(dev, plane); |
- | |
4359 | hdisplay = crtc->mode.hdisplay; |
- | |
4360 | htotal = crtc->mode.htotal; |
- | |
4361 | clock = crtc->mode.clock; |
- | |
4362 | pixel_size = crtc->fb->bits_per_pixel / 8; |
- | |
4363 | - | ||
4364 | line_time_us = (htotal * 1000) / clock; |
- | |
4365 | line_count = (latency_ns / line_time_us + 1000) / 1000; |
- | |
4366 | line_size = hdisplay * pixel_size; |
- | |
4367 | - | ||
4368 | /* Use the minimum of the small and large buffer method for primary */ |
- | |
4369 | small = ((clock * pixel_size / 1000) * latency_ns) / 1000; |
- | |
4370 | large = line_count * line_size; |
- | |
4371 | - | ||
4372 | entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); |
- | |
4373 | *display_wm = entries + display->guard_size; |
- | |
4374 | - | ||
4375 | /* |
- | |
4376 | * Spec says: |
- | |
4377 | * FBC WM = ((Final Primary WM * 64) / number of bytes per line) + 2 |
- | |
4378 | */ |
- | |
4379 | *fbc_wm = DIV_ROUND_UP(*display_wm * 64, line_size) + 2; |
- | |
4380 | - | ||
4381 | /* calculate the self-refresh watermark for display cursor */ |
- | |
4382 | entries = line_count * pixel_size * 64; |
- | |
4383 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); |
- | |
4384 | *cursor_wm = entries + cursor->guard_size; |
- | |
4385 | - | ||
4386 | return ironlake_check_srwm(dev, level, |
- | |
4387 | *fbc_wm, *display_wm, *cursor_wm, |
- | |
4388 | display, cursor); |
- | |
4389 | } |
- | |
4390 | - | ||
4391 | static void ironlake_update_wm(struct drm_device *dev) |
- | |
4392 | { |
- | |
4393 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
4394 | int fbc_wm, plane_wm, cursor_wm; |
- | |
4395 | unsigned int enabled; |
- | |
4396 | - | ||
4397 | enabled = 0; |
- | |
4398 | if (g4x_compute_wm0(dev, 0, |
- | |
4399 | &ironlake_display_wm_info, |
- | |
4400 | ILK_LP0_PLANE_LATENCY, |
- | |
4401 | &ironlake_cursor_wm_info, |
- | |
4402 | ILK_LP0_CURSOR_LATENCY, |
- | |
4403 | &plane_wm, &cursor_wm)) { |
- | |
4404 | I915_WRITE(WM0_PIPEA_ILK, |
- | |
4405 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); |
- | |
4406 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" |
- | |
4407 | " plane %d, " "cursor: %d\n", |
- | |
4408 | plane_wm, cursor_wm); |
- | |
4409 | enabled |= 1; |
- | |
4410 | } |
- | |
4411 | - | ||
4412 | if (g4x_compute_wm0(dev, 1, |
- | |
4413 | &ironlake_display_wm_info, |
- | |
4414 | ILK_LP0_PLANE_LATENCY, |
- | |
4415 | &ironlake_cursor_wm_info, |
- | |
4416 | ILK_LP0_CURSOR_LATENCY, |
- | |
4417 | &plane_wm, &cursor_wm)) { |
- | |
4418 | I915_WRITE(WM0_PIPEB_ILK, |
- | |
4419 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); |
- | |
4420 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" |
- | |
4421 | " plane %d, cursor: %d\n", |
- | |
4422 | plane_wm, cursor_wm); |
- | |
4423 | enabled |= 2; |
- | |
4424 | } |
- | |
4425 | - | ||
4426 | /* |
- | |
4427 | * Calculate and update the self-refresh watermark only when one |
- | |
4428 | * display plane is used. |
- | |
4429 | */ |
- | |
4430 | I915_WRITE(WM3_LP_ILK, 0); |
- | |
4431 | I915_WRITE(WM2_LP_ILK, 0); |
- | |
4432 | I915_WRITE(WM1_LP_ILK, 0); |
- | |
4433 | - | ||
4434 | if (!single_plane_enabled(enabled)) |
- | |
4435 | return; |
- | |
4436 | enabled = ffs(enabled) - 1; |
- | |
4437 | - | ||
4438 | /* WM1 */ |
- | |
4439 | if (!ironlake_compute_srwm(dev, 1, enabled, |
- | |
4440 | ILK_READ_WM1_LATENCY() * 500, |
- | |
4441 | &ironlake_display_srwm_info, |
- | |
4442 | &ironlake_cursor_srwm_info, |
- | |
4443 | &fbc_wm, &plane_wm, &cursor_wm)) |
- | |
4444 | return; |
- | |
4445 | - | ||
4446 | I915_WRITE(WM1_LP_ILK, |
- | |
4447 | WM1_LP_SR_EN | |
- | |
4448 | (ILK_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | |
- | |
4449 | (fbc_wm << WM1_LP_FBC_SHIFT) | |
- | |
4450 | (plane_wm << WM1_LP_SR_SHIFT) | |
- | |
4451 | cursor_wm); |
- | |
4452 | - | ||
4453 | /* WM2 */ |
- | |
4454 | if (!ironlake_compute_srwm(dev, 2, enabled, |
- | |
4455 | ILK_READ_WM2_LATENCY() * 500, |
- | |
4456 | &ironlake_display_srwm_info, |
- | |
4457 | &ironlake_cursor_srwm_info, |
- | |
4458 | &fbc_wm, &plane_wm, &cursor_wm)) |
- | |
4459 | return; |
- | |
4460 | - | ||
4461 | I915_WRITE(WM2_LP_ILK, |
- | |
4462 | WM2_LP_EN | |
- | |
4463 | (ILK_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | |
- | |
4464 | (fbc_wm << WM1_LP_FBC_SHIFT) | |
- | |
4465 | (plane_wm << WM1_LP_SR_SHIFT) | |
- | |
4466 | cursor_wm); |
- | |
4467 | - | ||
4468 | /* |
- | |
4469 | * WM3 is unsupported on ILK, probably because we don't have latency |
- | |
4470 | * data for that power state |
- | |
4471 | */ |
- | |
4472 | } |
- | |
4473 | - | ||
4474 | void sandybridge_update_wm(struct drm_device *dev) |
- | |
4475 | { |
- | |
4476 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
4477 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ |
- | |
4478 | int fbc_wm, plane_wm, cursor_wm; |
- | |
4479 | unsigned int enabled; |
- | |
4480 | - | ||
4481 | enabled = 0; |
- | |
4482 | if (g4x_compute_wm0(dev, 0, |
- | |
4483 | &sandybridge_display_wm_info, latency, |
- | |
4484 | &sandybridge_cursor_wm_info, latency, |
- | |
4485 | &plane_wm, &cursor_wm)) { |
- | |
4486 | I915_WRITE(WM0_PIPEA_ILK, |
- | |
4487 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); |
- | |
4488 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" |
- | |
4489 | " plane %d, " "cursor: %d\n", |
- | |
4490 | plane_wm, cursor_wm); |
- | |
4491 | enabled |= 1; |
- | |
4492 | } |
- | |
4493 | - | ||
4494 | if (g4x_compute_wm0(dev, 1, |
- | |
4495 | &sandybridge_display_wm_info, latency, |
- | |
4496 | &sandybridge_cursor_wm_info, latency, |
- | |
4497 | &plane_wm, &cursor_wm)) { |
- | |
4498 | I915_WRITE(WM0_PIPEB_ILK, |
- | |
4499 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); |
- | |
4500 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" |
- | |
4501 | " plane %d, cursor: %d\n", |
- | |
4502 | plane_wm, cursor_wm); |
- | |
4503 | enabled |= 2; |
- | |
4504 | } |
- | |
4505 | - | ||
4506 | /* IVB has 3 pipes */ |
- | |
4507 | if (IS_IVYBRIDGE(dev) && |
- | |
4508 | g4x_compute_wm0(dev, 2, |
- | |
4509 | &sandybridge_display_wm_info, latency, |
- | |
4510 | &sandybridge_cursor_wm_info, latency, |
- | |
4511 | &plane_wm, &cursor_wm)) { |
- | |
4512 | I915_WRITE(WM0_PIPEC_IVB, |
- | |
4513 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); |
- | |
4514 | DRM_DEBUG_KMS("FIFO watermarks For pipe C -" |
- | |
4515 | " plane %d, cursor: %d\n", |
- | |
4516 | plane_wm, cursor_wm); |
- | |
4517 | enabled |= 3; |
- | |
4518 | } |
- | |
4519 | - | ||
4520 | /* |
- | |
4521 | * Calculate and update the self-refresh watermark only when one |
- | |
4522 | * display plane is used. |
- | |
4523 | * |
- | |
4524 | * SNB support 3 levels of watermark. |
- | |
4525 | * |
- | |
4526 | * WM1/WM2/WM2 watermarks have to be enabled in the ascending order, |
- | |
4527 | * and disabled in the descending order |
- | |
4528 | * |
- | |
4529 | */ |
- | |
4530 | I915_WRITE(WM3_LP_ILK, 0); |
- | |
4531 | I915_WRITE(WM2_LP_ILK, 0); |
- | |
4532 | I915_WRITE(WM1_LP_ILK, 0); |
- | |
4533 | - | ||
4534 | if (!single_plane_enabled(enabled) || |
- | |
4535 | dev_priv->sprite_scaling_enabled) |
- | |
4536 | return; |
- | |
4537 | enabled = ffs(enabled) - 1; |
- | |
4538 | - | ||
4539 | /* WM1 */ |
- | |
4540 | if (!ironlake_compute_srwm(dev, 1, enabled, |
- | |
4541 | SNB_READ_WM1_LATENCY() * 500, |
- | |
4542 | &sandybridge_display_srwm_info, |
- | |
4543 | &sandybridge_cursor_srwm_info, |
- | |
4544 | &fbc_wm, &plane_wm, &cursor_wm)) |
- | |
4545 | return; |
- | |
4546 | - | ||
4547 | I915_WRITE(WM1_LP_ILK, |
- | |
4548 | WM1_LP_SR_EN | |
- | |
4549 | (SNB_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | |
- | |
4550 | (fbc_wm << WM1_LP_FBC_SHIFT) | |
- | |
4551 | (plane_wm << WM1_LP_SR_SHIFT) | |
- | |
4552 | cursor_wm); |
- | |
4553 | - | ||
4554 | /* WM2 */ |
- | |
4555 | if (!ironlake_compute_srwm(dev, 2, enabled, |
- | |
4556 | SNB_READ_WM2_LATENCY() * 500, |
- | |
4557 | &sandybridge_display_srwm_info, |
- | |
4558 | &sandybridge_cursor_srwm_info, |
- | |
4559 | &fbc_wm, &plane_wm, &cursor_wm)) |
- | |
4560 | return; |
- | |
4561 | - | ||
4562 | I915_WRITE(WM2_LP_ILK, |
- | |
4563 | WM2_LP_EN | |
- | |
4564 | (SNB_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | |
- | |
4565 | (fbc_wm << WM1_LP_FBC_SHIFT) | |
- | |
4566 | (plane_wm << WM1_LP_SR_SHIFT) | |
- | |
4567 | cursor_wm); |
- | |
4568 | - | ||
4569 | /* WM3 */ |
- | |
4570 | if (!ironlake_compute_srwm(dev, 3, enabled, |
- | |
4571 | SNB_READ_WM3_LATENCY() * 500, |
- | |
4572 | &sandybridge_display_srwm_info, |
- | |
4573 | &sandybridge_cursor_srwm_info, |
- | |
4574 | &fbc_wm, &plane_wm, &cursor_wm)) |
- | |
4575 | return; |
- | |
4576 | - | ||
4577 | I915_WRITE(WM3_LP_ILK, |
- | |
4578 | WM3_LP_EN | |
- | |
4579 | (SNB_READ_WM3_LATENCY() << WM1_LP_LATENCY_SHIFT) | |
- | |
4580 | (fbc_wm << WM1_LP_FBC_SHIFT) | |
- | |
4581 | (plane_wm << WM1_LP_SR_SHIFT) | |
- | |
4582 | cursor_wm); |
- | |
4583 | } |
- | |
4584 | - | ||
4585 | static bool |
- | |
4586 | sandybridge_compute_sprite_wm(struct drm_device *dev, int plane, |
- | |
4587 | uint32_t sprite_width, int pixel_size, |
- | |
4588 | const struct intel_watermark_params *display, |
- | |
4589 | int display_latency_ns, int *sprite_wm) |
- | |
4590 | { |
- | |
4591 | struct drm_crtc *crtc; |
- | |
4592 | int clock; |
- | |
4593 | int entries, tlb_miss; |
- | |
4594 | - | ||
4595 | crtc = intel_get_crtc_for_plane(dev, plane); |
- | |
4596 | if (crtc->fb == NULL || !crtc->enabled) { |
- | |
4597 | *sprite_wm = display->guard_size; |
- | |
4598 | return false; |
- | |
4599 | } |
- | |
4600 | - | ||
4601 | clock = crtc->mode.clock; |
- | |
4602 | - | ||
4603 | /* Use the small buffer method to calculate the sprite watermark */ |
- | |
4604 | entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; |
- | |
4605 | tlb_miss = display->fifo_size*display->cacheline_size - |
- | |
4606 | sprite_width * 8; |
- | |
4607 | if (tlb_miss > 0) |
- | |
4608 | entries += tlb_miss; |
- | |
4609 | entries = DIV_ROUND_UP(entries, display->cacheline_size); |
- | |
4610 | *sprite_wm = entries + display->guard_size; |
- | |
4611 | if (*sprite_wm > (int)display->max_wm) |
- | |
4612 | *sprite_wm = display->max_wm; |
- | |
4613 | - | ||
4614 | return true; |
- | |
4615 | } |
- | |
4616 | - | ||
4617 | static bool |
- | |
4618 | sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane, |
- | |
4619 | uint32_t sprite_width, int pixel_size, |
- | |
4620 | const struct intel_watermark_params *display, |
- | |
4621 | int latency_ns, int *sprite_wm) |
- | |
4622 | { |
- | |
4623 | struct drm_crtc *crtc; |
- | |
4624 | unsigned long line_time_us; |
- | |
4625 | int clock; |
- | |
4626 | int line_count, line_size; |
- | |
4627 | int small, large; |
- | |
4628 | int entries; |
- | |
4629 | - | ||
4630 | if (!latency_ns) { |
- | |
4631 | *sprite_wm = 0; |
- | |
4632 | return false; |
- | |
4633 | } |
- | |
4634 | - | ||
4635 | crtc = intel_get_crtc_for_plane(dev, plane); |
- | |
4636 | clock = crtc->mode.clock; |
- | |
4637 | - | ||
4638 | line_time_us = (sprite_width * 1000) / clock; |
- | |
4639 | line_count = (latency_ns / line_time_us + 1000) / 1000; |
- | |
4640 | line_size = sprite_width * pixel_size; |
- | |
4641 | - | ||
4642 | /* Use the minimum of the small and large buffer method for primary */ |
- | |
4643 | small = ((clock * pixel_size / 1000) * latency_ns) / 1000; |
- | |
4644 | large = line_count * line_size; |
- | |
4645 | - | ||
4646 | entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); |
- | |
4647 | *sprite_wm = entries + display->guard_size; |
- | |
4648 | - | ||
4649 | return *sprite_wm > 0x3ff ? false : true; |
- | |
4650 | } |
- | |
4651 | - | ||
4652 | static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, |
- | |
4653 | uint32_t sprite_width, int pixel_size) |
- | |
4654 | { |
- | |
4655 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
4656 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ |
- | |
4657 | int sprite_wm, reg; |
- | |
4658 | int ret; |
- | |
4659 | - | ||
4660 | switch (pipe) { |
- | |
4661 | case 0: |
- | |
4662 | reg = WM0_PIPEA_ILK; |
- | |
4663 | break; |
- | |
4664 | case 1: |
- | |
4665 | reg = WM0_PIPEB_ILK; |
- | |
4666 | break; |
- | |
4667 | case 2: |
- | |
4668 | reg = WM0_PIPEC_IVB; |
- | |
4669 | break; |
- | |
4670 | default: |
- | |
4671 | return; /* bad pipe */ |
- | |
4672 | } |
- | |
4673 | - | ||
4674 | ret = sandybridge_compute_sprite_wm(dev, pipe, sprite_width, pixel_size, |
- | |
4675 | &sandybridge_display_wm_info, |
- | |
4676 | latency, &sprite_wm); |
- | |
4677 | if (!ret) { |
- | |
4678 | DRM_DEBUG_KMS("failed to compute sprite wm for pipe %d\n", |
- | |
4679 | pipe); |
- | |
4680 | return; |
- | |
4681 | } |
- | |
4682 | - | ||
4683 | I915_WRITE(reg, I915_READ(reg) | (sprite_wm << WM0_PIPE_SPRITE_SHIFT)); |
- | |
4684 | DRM_DEBUG_KMS("sprite watermarks For pipe %d - %d\n", pipe, sprite_wm); |
- | |
4685 | - | ||
4686 | - | ||
4687 | ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, |
- | |
4688 | pixel_size, |
- | |
4689 | &sandybridge_display_srwm_info, |
- | |
4690 | SNB_READ_WM1_LATENCY() * 500, |
- | |
4691 | &sprite_wm); |
- | |
4692 | if (!ret) { |
- | |
4693 | DRM_DEBUG_KMS("failed to compute sprite lp1 wm on pipe %d\n", |
- | |
4694 | pipe); |
- | |
4695 | return; |
- | |
4696 | } |
- | |
4697 | I915_WRITE(WM1S_LP_ILK, sprite_wm); |
- | |
4698 | - | ||
4699 | /* Only IVB has two more LP watermarks for sprite */ |
- | |
4700 | if (!IS_IVYBRIDGE(dev)) |
- | |
4701 | return; |
- | |
4702 | - | ||
4703 | ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, |
- | |
4704 | pixel_size, |
- | |
4705 | &sandybridge_display_srwm_info, |
- | |
4706 | SNB_READ_WM2_LATENCY() * 500, |
- | |
4707 | &sprite_wm); |
- | |
4708 | if (!ret) { |
- | |
4709 | DRM_DEBUG_KMS("failed to compute sprite lp2 wm on pipe %d\n", |
- | |
4710 | pipe); |
- | |
4711 | return; |
- | |
4712 | } |
- | |
4713 | I915_WRITE(WM2S_LP_IVB, sprite_wm); |
- | |
4714 | - | ||
4715 | ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, |
- | |
4716 | pixel_size, |
- | |
4717 | &sandybridge_display_srwm_info, |
- | |
4718 | SNB_READ_WM3_LATENCY() * 500, |
- | |
4719 | &sprite_wm); |
- | |
4720 | if (!ret) { |
- | |
4721 | DRM_DEBUG_KMS("failed to compute sprite lp3 wm on pipe %d\n", |
- | |
4722 | pipe); |
- | |
4723 | return; |
- | |
4724 | } |
- | |
4725 | I915_WRITE(WM3S_LP_IVB, sprite_wm); |
- | |
4726 | } |
- | |
4727 | - | ||
4728 | /** |
- | |
4729 | * intel_update_watermarks - update FIFO watermark values based on current modes |
- | |
4730 | * |
- | |
4731 | * Calculate watermark values for the various WM regs based on current mode |
- | |
4732 | * and plane configuration. |
- | |
4733 | * |
- | |
4734 | * There are several cases to deal with here: |
- | |
4735 | * - normal (i.e. non-self-refresh) |
- | |
4736 | * - self-refresh (SR) mode |
- | |
4737 | * - lines are large relative to FIFO size (buffer can hold up to 2) |
- | |
4738 | * - lines are small relative to FIFO size (buffer can hold more than 2 |
- | |
4739 | * lines), so need to account for TLB latency |
- | |
4740 | * |
- | |
4741 | * The normal calculation is: |
- | |
4742 | * watermark = dotclock * bytes per pixel * latency |
- | |
4743 | * where latency is platform & configuration dependent (we assume pessimal |
- | |
4744 | * values here). |
- | |
4745 | * |
- | |
4746 | * The SR calculation is: |
- | |
4747 | * watermark = (trunc(latency/line time)+1) * surface width * |
- | |
4748 | * bytes per pixel |
- | |
4749 | * where |
- | |
4750 | * line time = htotal / dotclock |
- | |
4751 | * surface width = hdisplay for normal plane and 64 for cursor |
- | |
4752 | * and latency is assumed to be high, as above. |
- | |
4753 | * |
- | |
4754 | * The final value programmed to the register should always be rounded up, |
- | |
4755 | * and include an extra 2 entries to account for clock crossings. |
- | |
4756 | * |
- | |
4757 | * We don't use the sprite, so we can ignore that. And on Crestline we have |
- | |
4758 | * to set the non-SR watermarks to 8. |
- | |
4759 | */ |
- | |
4760 | static void intel_update_watermarks(struct drm_device *dev) |
- | |
4761 | { |
- | |
4762 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
4763 | - | ||
4764 | if (dev_priv->display.update_wm) |
- | |
4765 | dev_priv->display.update_wm(dev); |
- | |
4766 | } |
- | |
4767 | - | ||
4768 | void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, |
- | |
4769 | uint32_t sprite_width, int pixel_size) |
- | |
4770 | { |
- | |
4771 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
4772 | - | ||
4773 | if (dev_priv->display.update_sprite_wm) |
- | |
4774 | dev_priv->display.update_sprite_wm(dev, pipe, sprite_width, |
- | |
4775 | pixel_size); |
- | |
4776 | } |
- | |
4777 | 3789 | ||
4778 | static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) |
3790 | static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) |
4779 | { |
3791 | { |
4780 | if (i915_panel_use_ssc >= 0) |
3792 | if (i915_panel_use_ssc >= 0) |
4781 | return i915_panel_use_ssc != 0; |
3793 | return i915_panel_use_ssc != 0; |
Line 4803... | Line 3815... | ||
4803 | * RETURNS: |
3815 | * RETURNS: |
4804 | * Dithering requirement (i.e. false if display bpc and pipe bpc match, |
3816 | * Dithering requirement (i.e. false if display bpc and pipe bpc match, |
4805 | * true if they don't match). |
3817 | * true if they don't match). |
4806 | */ |
3818 | */ |
4807 | static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, |
3819 | static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, |
- | 3820 | struct drm_framebuffer *fb, |
|
4808 | unsigned int *pipe_bpp, |
3821 | unsigned int *pipe_bpp, |
4809 | struct drm_display_mode *mode) |
3822 | struct drm_display_mode *mode) |
4810 | { |
3823 | { |
4811 | struct drm_device *dev = crtc->dev; |
3824 | struct drm_device *dev = crtc->dev; |
4812 | struct drm_i915_private *dev_priv = dev->dev_private; |
3825 | struct drm_i915_private *dev_priv = dev->dev_private; |
4813 | struct drm_encoder *encoder; |
- | |
4814 | struct drm_connector *connector; |
3826 | struct drm_connector *connector; |
- | 3827 | struct intel_encoder *intel_encoder; |
|
4815 | unsigned int display_bpc = UINT_MAX, bpc; |
3828 | unsigned int display_bpc = UINT_MAX, bpc; |
Line 4816... | Line 3829... | ||
4816 | 3829 | ||
4817 | /* Walk the encoders & connectors on this crtc, get min bpc */ |
- | |
4818 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
3830 | /* Walk the encoders & connectors on this crtc, get min bpc */ |
4819 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
- | |
4820 | - | ||
4821 | if (encoder->crtc != crtc) |
- | |
Line 4822... | Line 3831... | ||
4822 | continue; |
3831 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) { |
4823 | 3832 | ||
Line 4824... | Line 3833... | ||
4824 | if (intel_encoder->type == INTEL_OUTPUT_LVDS) { |
3833 | if (intel_encoder->type == INTEL_OUTPUT_LVDS) { |
Line 4835... | Line 3844... | ||
4835 | display_bpc = lvds_bpc; |
3844 | display_bpc = lvds_bpc; |
4836 | } |
3845 | } |
4837 | continue; |
3846 | continue; |
4838 | } |
3847 | } |
Line 4839... | Line -... | ||
4839 | - | ||
4840 | if (intel_encoder->type == INTEL_OUTPUT_EDP) { |
- | |
4841 | /* Use VBT settings if we have an eDP panel */ |
- | |
4842 | unsigned int edp_bpc = dev_priv->edp.bpp / 3; |
- | |
4843 | - | ||
4844 | if (edp_bpc < display_bpc) { |
- | |
4845 | DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); |
- | |
4846 | display_bpc = edp_bpc; |
- | |
4847 | } |
- | |
4848 | continue; |
- | |
4849 | } |
- | |
4850 | 3848 | ||
4851 | /* Not one of the known troublemakers, check the EDID */ |
3849 | /* Not one of the known troublemakers, check the EDID */ |
4852 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
3850 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
4853 | head) { |
3851 | head) { |
4854 | if (connector->encoder != encoder) |
3852 | if (connector->encoder != &intel_encoder->base) |
Line 4855... | Line 3853... | ||
4855 | continue; |
3853 | continue; |
4856 | 3854 | ||
4857 | /* Don't use an invalid EDID bpc value */ |
3855 | /* Don't use an invalid EDID bpc value */ |
Line 4887... | Line 3885... | ||
4887 | * enable dithering as needed, but that costs bandwidth. So choose |
3885 | * enable dithering as needed, but that costs bandwidth. So choose |
4888 | * the minimum value that expresses the full color range of the fb but |
3886 | * the minimum value that expresses the full color range of the fb but |
4889 | * also stays within the max display bpc discovered above. |
3887 | * also stays within the max display bpc discovered above. |
4890 | */ |
3888 | */ |
Line 4891... | Line 3889... | ||
4891 | 3889 | ||
4892 | switch (crtc->fb->depth) { |
3890 | switch (fb->depth) { |
4893 | case 8: |
3891 | case 8: |
4894 | bpc = 8; /* since we go through a colormap */ |
3892 | bpc = 8; /* since we go through a colormap */ |
4895 | break; |
3893 | break; |
4896 | case 15: |
3894 | case 15: |
Line 4920... | Line 3918... | ||
4920 | *pipe_bpp = display_bpc * 3; |
3918 | *pipe_bpp = display_bpc * 3; |
Line 4921... | Line 3919... | ||
4921 | 3919 | ||
4922 | return display_bpc != bpc; |
3920 | return display_bpc != bpc; |
Line 4923... | Line 3921... | ||
4923 | } |
3921 | } |
4924 | - | ||
4925 | static int i9xx_crtc_mode_set(struct drm_crtc *crtc, |
- | |
4926 | struct drm_display_mode *mode, |
- | |
4927 | struct drm_display_mode *adjusted_mode, |
- | |
4928 | int x, int y, |
3922 | |
4929 | struct drm_framebuffer *old_fb) |
3923 | static int vlv_get_refclk(struct drm_crtc *crtc) |
4930 | { |
3924 | { |
4931 | struct drm_device *dev = crtc->dev; |
- | |
4932 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
4933 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
4934 | int pipe = intel_crtc->pipe; |
3925 | struct drm_device *dev = crtc->dev; |
4935 | int plane = intel_crtc->plane; |
- | |
4936 | int refclk, num_connectors = 0; |
- | |
4937 | intel_clock_t clock, reduced_clock; |
- | |
4938 | u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf; |
- | |
4939 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; |
- | |
4940 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
- | |
4941 | struct drm_mode_config *mode_config = &dev->mode_config; |
- | |
4942 | struct intel_encoder *encoder; |
- | |
4943 | const intel_limit_t *limit; |
- | |
4944 | int ret; |
- | |
Line 4945... | Line -... | ||
4945 | u32 temp; |
- | |
4946 | u32 lvds_sync = 0; |
3926 | struct drm_i915_private *dev_priv = dev->dev_private; |
4947 | - | ||
Line 4948... | Line -... | ||
4948 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { |
- | |
4949 | if (encoder->base.crtc != crtc) |
3927 | int refclk = 27000; /* for DP & HDMI */ |
4950 | continue; |
- | |
4951 | 3928 | ||
4952 | switch (encoder->type) { |
- | |
4953 | case INTEL_OUTPUT_LVDS: |
3929 | return 100000; /* only one validated so far */ |
4954 | is_lvds = true; |
- | |
4955 | break; |
3930 | |
4956 | case INTEL_OUTPUT_SDVO: |
- | |
4957 | case INTEL_OUTPUT_HDMI: |
3931 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { |
4958 | is_sdvo = true; |
- | |
4959 | if (encoder->needs_tv_clock) |
- | |
4960 | is_tv = true; |
3932 | refclk = 96000; |
4961 | break; |
- | |
4962 | case INTEL_OUTPUT_DVO: |
- | |
4963 | is_dvo = true; |
3933 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
4964 | break; |
3934 | if (intel_panel_use_ssc(dev_priv)) |
4965 | case INTEL_OUTPUT_TVOUT: |
- | |
4966 | is_tv = true; |
- | |
4967 | break; |
- | |
4968 | case INTEL_OUTPUT_ANALOG: |
- | |
4969 | is_crt = true; |
3935 | refclk = 100000; |
4970 | break; |
3936 | else |
Line 4971... | Line 3937... | ||
4971 | case INTEL_OUTPUT_DISPLAYPORT: |
3937 | refclk = 96000; |
4972 | is_dp = true; |
3938 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) { |
Line -... | Line 3939... | ||
- | 3939 | refclk = 100000; |
|
- | 3940 | } |
|
- | 3941 | ||
- | 3942 | return refclk; |
|
- | 3943 | } |
|
- | 3944 | ||
- | 3945 | static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors) |
|
- | 3946 | { |
|
- | 3947 | struct drm_device *dev = crtc->dev; |
|
4973 | break; |
3948 | struct drm_i915_private *dev_priv = dev->dev_private; |
4974 | } |
3949 | int refclk; |
4975 | 3950 | ||
4976 | num_connectors++; |
3951 | if (IS_VALLEYVIEW(dev)) { |
4977 | } |
3952 | refclk = vlv_get_refclk(crtc); |
4978 | 3953 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && |
|
4979 | if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { |
3954 | intel_panel_use_ssc(dev_priv) && num_connectors < 2) { |
4980 | refclk = dev_priv->lvds_ssc_freq * 1000; |
3955 | refclk = dev_priv->lvds_ssc_freq * 1000; |
4981 | DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", |
3956 | DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", |
Line 4982... | Line -... | ||
4982 | refclk / 1000); |
- | |
4983 | } else if (!IS_GEN2(dev)) { |
- | |
4984 | refclk = 96000; |
- | |
4985 | } else { |
- | |
4986 | refclk = 48000; |
- | |
4987 | } |
- | |
4988 | - | ||
4989 | /* |
- | |
4990 | * Returns a set of divisors for the desired target clock with the given |
- | |
4991 | * refclk, or FALSE. The returned values represent the clock equation: |
3957 | refclk / 1000); |
4992 | * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. |
3958 | } else if (!IS_GEN2(dev)) { |
Line 4993... | Line 3959... | ||
4993 | */ |
3959 | refclk = 96000; |
4994 | limit = intel_limit(crtc, refclk); |
3960 | } else { |
4995 | ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); |
3961 | refclk = 48000; |
4996 | if (!ok) { |
- | |
4997 | DRM_ERROR("Couldn't find PLL settings for mode!\n"); |
- | |
4998 | return -EINVAL; |
- | |
4999 | } |
- | |
5000 | - | ||
5001 | /* Ensure that the cursor is valid for the new mode before changing... */ |
- | |
5002 | // intel_crtc_update_cursor(crtc, true); |
- | |
5003 | - | ||
5004 | if (is_lvds && dev_priv->lvds_downclock_avail) { |
- | |
5005 | has_reduced_clock = limit->find_pll(limit, crtc, |
- | |
5006 | dev_priv->lvds_downclock, |
- | |
5007 | refclk, |
- | |
5008 | &reduced_clock); |
- | |
5009 | if (has_reduced_clock && (clock.p != reduced_clock.p)) { |
- | |
5010 | /* |
- | |
5011 | * If the different P is found, it means that we can't |
- | |
5012 | * switch the display clock by using the FP0/FP1. |
- | |
5013 | * In such case we will disable the LVDS downclock |
3962 | } |
5014 | * feature. |
3963 | |
5015 | */ |
- | |
5016 | DRM_DEBUG_KMS("Different P is found for " |
3964 | return refclk; |
5017 | "LVDS clock/downclock\n"); |
3965 | } |
5018 | has_reduced_clock = 0; |
3966 | |
5019 | } |
3967 | static void i9xx_adjust_sdvo_tv_clock(struct drm_display_mode *adjusted_mode, |
5020 | } |
3968 | intel_clock_t *clock) |
5021 | /* SDVO TV has fixed PLL values depend on its clock range, |
3969 | { |
5022 | this mirrors vbios setting. */ |
3970 | /* SDVO TV has fixed PLL values depend on its clock range, |
5023 | if (is_sdvo && is_tv) { |
3971 | this mirrors vbios setting. */ |
5024 | if (adjusted_mode->clock >= 100000 |
3972 | if (adjusted_mode->clock >= 100000 |
5025 | && adjusted_mode->clock < 140500) { |
3973 | && adjusted_mode->clock < 140500) { |
5026 | clock.p1 = 2; |
3974 | clock->p1 = 2; |
5027 | clock.p2 = 10; |
3975 | clock->p2 = 10; |
5028 | clock.n = 3; |
3976 | clock->n = 3; |
5029 | clock.m1 = 16; |
3977 | clock->m1 = 16; |
5030 | clock.m2 = 8; |
3978 | clock->m2 = 8; |
5031 | } else if (adjusted_mode->clock >= 140500 |
3979 | } else if (adjusted_mode->clock >= 140500 |
Line -... | Line 3980... | ||
- | 3980 | && adjusted_mode->clock <= 200000) { |
|
- | 3981 | clock->p1 = 1; |
|
- | 3982 | clock->p2 = 10; |
|
- | 3983 | clock->n = 6; |
|
- | 3984 | clock->m1 = 12; |
|
- | 3985 | clock->m2 = 8; |
|
- | 3986 | } |
|
- | 3987 | } |
|
- | 3988 | ||
- | 3989 | static void i9xx_update_pll_dividers(struct drm_crtc *crtc, |
|
5032 | && adjusted_mode->clock <= 200000) { |
3990 | intel_clock_t *clock, |
5033 | clock.p1 = 1; |
3991 | intel_clock_t *reduced_clock) |
5034 | clock.p2 = 10; |
3992 | { |
5035 | clock.n = 6; |
3993 | struct drm_device *dev = crtc->dev; |
5036 | clock.m1 = 12; |
3994 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | 3995 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 3996 | int pipe = intel_crtc->pipe; |
|
- | 3997 | u32 fp, fp2 = 0; |
|
- | 3998 | ||
- | 3999 | if (IS_PINEVIEW(dev)) { |
|
- | 4000 | fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2; |
|
- | 4001 | if (reduced_clock) |
|
- | 4002 | fp2 = (1 << reduced_clock->n) << 16 | |
|
- | 4003 | reduced_clock->m1 << 8 | reduced_clock->m2; |
|
- | 4004 | } else { |
|
- | 4005 | fp = clock->n << 16 | clock->m1 << 8 | clock->m2; |
|
- | 4006 | if (reduced_clock) |
|
- | 4007 | fp2 = reduced_clock->n << 16 | reduced_clock->m1 << 8 | |
|
- | 4008 | reduced_clock->m2; |
|
5037 | clock.m2 = 8; |
4009 | } |
- | 4010 | ||
- | 4011 | I915_WRITE(FP0(pipe), fp); |
|
- | 4012 | ||
- | 4013 | intel_crtc->lowfreq_avail = false; |
|
- | 4014 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && |
|
5038 | } |
4015 | reduced_clock && i915_powersave) { |
- | 4016 | I915_WRITE(FP1(pipe), fp2); |
|
5039 | } |
4017 | intel_crtc->lowfreq_avail = true; |
- | 4018 | } else { |
|
5040 | 4019 | I915_WRITE(FP1(pipe), fp); |
|
5041 | if (IS_PINEVIEW(dev)) { |
4020 | } |
- | 4021 | } |
|
- | 4022 | ||
- | 4023 | static void intel_update_lvds(struct drm_crtc *crtc, intel_clock_t *clock, |
|
- | 4024 | struct drm_display_mode *adjusted_mode) |
|
- | 4025 | { |
|
- | 4026 | struct drm_device *dev = crtc->dev; |
|
- | 4027 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 4028 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
5042 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; |
4029 | int pipe = intel_crtc->pipe; |
- | 4030 | u32 temp; |
|
- | 4031 | ||
- | 4032 | temp = I915_READ(LVDS); |
|
- | 4033 | temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; |
|
- | 4034 | if (pipe == 1) { |
|
- | 4035 | temp |= LVDS_PIPEB_SELECT; |
|
- | 4036 | } else { |
|
- | 4037 | temp &= ~LVDS_PIPEB_SELECT; |
|
- | 4038 | } |
|
- | 4039 | /* set the corresponsding LVDS_BORDER bit */ |
|
- | 4040 | temp |= dev_priv->lvds_border_bits; |
|
- | 4041 | /* Set the B0-B3 data pairs corresponding to whether we're going to |
|
- | 4042 | * set the DPLLs for dual-channel mode or not. |
|
- | 4043 | */ |
|
- | 4044 | if (clock->p2 == 7) |
|
- | 4045 | temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; |
|
- | 4046 | else |
|
- | 4047 | temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); |
|
- | 4048 | ||
- | 4049 | /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) |
|
- | 4050 | * appropriately here, but we need to look more thoroughly into how |
|
- | 4051 | * panels behave in the two modes. |
|
- | 4052 | */ |
|
- | 4053 | /* set the dithering flag on LVDS as needed */ |
|
- | 4054 | if (INTEL_INFO(dev)->gen >= 4) { |
|
- | 4055 | if (dev_priv->lvds_dither) |
|
- | 4056 | temp |= LVDS_ENABLE_DITHER; |
|
- | 4057 | else |
|
- | 4058 | temp &= ~LVDS_ENABLE_DITHER; |
|
- | 4059 | } |
|
- | 4060 | temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); |
|
- | 4061 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) |
|
- | 4062 | temp |= LVDS_HSYNC_POLARITY; |
|
- | 4063 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) |
|
- | 4064 | temp |= LVDS_VSYNC_POLARITY; |
|
- | 4065 | I915_WRITE(LVDS, temp); |
|
- | 4066 | } |
|
- | 4067 | ||
- | 4068 | static void vlv_update_pll(struct drm_crtc *crtc, |
|
- | 4069 | struct drm_display_mode *mode, |
|
- | 4070 | struct drm_display_mode *adjusted_mode, |
|
- | 4071 | intel_clock_t *clock, intel_clock_t *reduced_clock, |
|
- | 4072 | int refclk, int num_connectors) |
|
- | 4073 | { |
|
- | 4074 | struct drm_device *dev = crtc->dev; |
|
- | 4075 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 4076 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 4077 | int pipe = intel_crtc->pipe; |
|
- | 4078 | u32 dpll, mdiv, pdiv; |
|
- | 4079 | u32 bestn, bestm1, bestm2, bestp1, bestp2; |
|
- | 4080 | bool is_hdmi; |
|
- | 4081 | ||
- | 4082 | is_hdmi = intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI); |
|
- | 4083 | ||
- | 4084 | bestn = clock->n; |
|
- | 4085 | bestm1 = clock->m1; |
|
- | 4086 | bestm2 = clock->m2; |
|
- | 4087 | bestp1 = clock->p1; |
|
- | 4088 | bestp2 = clock->p2; |
|
- | 4089 | ||
- | 4090 | /* Enable DPIO clock input */ |
|
- | 4091 | dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV | |
|
- | 4092 | DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV; |
|
- | 4093 | I915_WRITE(DPLL(pipe), dpll); |
|
- | 4094 | POSTING_READ(DPLL(pipe)); |
|
- | 4095 | ||
- | 4096 | mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK)); |
|
- | 4097 | mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT)); |
|
- | 4098 | mdiv |= ((bestn << DPIO_N_SHIFT)); |
|
- | 4099 | mdiv |= (1 << DPIO_POST_DIV_SHIFT); |
|
- | 4100 | mdiv |= (1 << DPIO_K_SHIFT); |
|
- | 4101 | mdiv |= DPIO_ENABLE_CALIBRATION; |
|
- | 4102 | intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); |
|
- | 4103 | ||
- | 4104 | intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), 0x01000000); |
|
- | 4105 | ||
- | 4106 | pdiv = DPIO_REFSEL_OVERRIDE | (5 << DPIO_PLL_MODESEL_SHIFT) | |
|
- | 4107 | (3 << DPIO_BIAS_CURRENT_CTL_SHIFT) | (1<<20) | |
|
- | 4108 | (8 << DPIO_DRIVER_CTL_SHIFT) | (5 << DPIO_CLK_BIAS_CTL_SHIFT); |
|
- | 4109 | intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), pdiv); |
|
- | 4110 | ||
- | 4111 | intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), 0x009f0051); |
|
- | 4112 | ||
- | 4113 | dpll |= DPLL_VCO_ENABLE; |
|
- | 4114 | I915_WRITE(DPLL(pipe), dpll); |
|
- | 4115 | POSTING_READ(DPLL(pipe)); |
|
- | 4116 | if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) |
|
- | 4117 | DRM_ERROR("DPLL %d failed to lock\n", pipe); |
|
- | 4118 | ||
- | 4119 | if (is_hdmi) { |
|
- | 4120 | u32 temp = intel_mode_get_pixel_multiplier(adjusted_mode); |
|
- | 4121 | ||
- | 4122 | if (temp > 1) |
|
- | 4123 | temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; |
|
- | 4124 | else |
|
- | 4125 | temp = 0; |
|
- | 4126 | ||
- | 4127 | I915_WRITE(DPLL_MD(pipe), temp); |
|
- | 4128 | POSTING_READ(DPLL_MD(pipe)); |
|
- | 4129 | } |
|
- | 4130 | ||
- | 4131 | intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x641); /* ??? */ |
|
- | 4132 | } |
|
- | 4133 | ||
- | 4134 | static void i9xx_update_pll(struct drm_crtc *crtc, |
|
- | 4135 | struct drm_display_mode *mode, |
|
- | 4136 | struct drm_display_mode *adjusted_mode, |
|
- | 4137 | intel_clock_t *clock, intel_clock_t *reduced_clock, |
|
- | 4138 | int num_connectors) |
|
- | 4139 | { |
|
Line 5043... | Line 4140... | ||
5043 | if (has_reduced_clock) |
4140 | struct drm_device *dev = crtc->dev; |
Line 5044... | Line 4141... | ||
5044 | fp2 = (1 << reduced_clock.n) << 16 | |
4141 | struct drm_i915_private *dev_priv = dev->dev_private; |
5045 | reduced_clock.m1 << 8 | reduced_clock.m2; |
- | |
5046 | } else { |
4142 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
5047 | fp = clock.n << 16 | clock.m1 << 8 | clock.m2; |
4143 | int pipe = intel_crtc->pipe; |
5048 | if (has_reduced_clock) |
4144 | u32 dpll; |
5049 | fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | |
4145 | bool is_sdvo; |
5050 | reduced_clock.m2; |
4146 | |
Line 5063... | Line 4159... | ||
5063 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) |
4159 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) |
5064 | dpll |= (pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; |
4160 | dpll |= (pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; |
5065 | } |
4161 | } |
5066 | dpll |= DPLL_DVO_HIGH_SPEED; |
4162 | dpll |= DPLL_DVO_HIGH_SPEED; |
5067 | } |
4163 | } |
5068 | if (is_dp) |
4164 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) |
5069 | dpll |= DPLL_DVO_HIGH_SPEED; |
4165 | dpll |= DPLL_DVO_HIGH_SPEED; |
Line 5070... | Line 4166... | ||
5070 | 4166 | ||
5071 | /* compute bitmask from p1 value */ |
4167 | /* compute bitmask from p1 value */ |
5072 | if (IS_PINEVIEW(dev)) |
4168 | if (IS_PINEVIEW(dev)) |
5073 | dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW; |
4169 | dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW; |
5074 | else { |
4170 | else { |
5075 | dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; |
4171 | dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; |
5076 | if (IS_G4X(dev) && has_reduced_clock) |
4172 | if (IS_G4X(dev) && reduced_clock) |
5077 | dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; |
4173 | dpll |= (1 << (reduced_clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; |
5078 | } |
4174 | } |
5079 | switch (clock.p2) { |
4175 | switch (clock->p2) { |
5080 | case 5: |
4176 | case 5: |
5081 | dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; |
4177 | dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; |
5082 | break; |
4178 | break; |
5083 | case 7: |
4179 | case 7: |
Line 5090... | Line 4186... | ||
5090 | dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; |
4186 | dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; |
5091 | break; |
4187 | break; |
5092 | } |
4188 | } |
5093 | if (INTEL_INFO(dev)->gen >= 4) |
4189 | if (INTEL_INFO(dev)->gen >= 4) |
5094 | dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); |
4190 | dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); |
- | 4191 | ||
- | 4192 | if (is_sdvo && intel_pipe_has_type(crtc, INTEL_OUTPUT_TVOUT)) |
|
- | 4193 | dpll |= PLL_REF_INPUT_TVCLKINBC; |
|
- | 4194 | else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_TVOUT)) |
|
- | 4195 | /* XXX: just matching BIOS for now */ |
|
- | 4196 | /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ |
|
- | 4197 | dpll |= 3; |
|
- | 4198 | else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && |
|
- | 4199 | intel_panel_use_ssc(dev_priv) && num_connectors < 2) |
|
- | 4200 | dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; |
|
- | 4201 | else |
|
- | 4202 | dpll |= PLL_REF_INPUT_DREFCLK; |
|
- | 4203 | ||
- | 4204 | dpll |= DPLL_VCO_ENABLE; |
|
- | 4205 | I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); |
|
- | 4206 | POSTING_READ(DPLL(pipe)); |
|
- | 4207 | udelay(150); |
|
- | 4208 | ||
- | 4209 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
|
- | 4210 | * This is an exception to the general rule that mode_set doesn't turn |
|
- | 4211 | * things on. |
|
- | 4212 | */ |
|
- | 4213 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
|
- | 4214 | intel_update_lvds(crtc, clock, adjusted_mode); |
|
- | 4215 | ||
- | 4216 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) |
|
- | 4217 | intel_dp_set_m_n(crtc, mode, adjusted_mode); |
|
- | 4218 | ||
- | 4219 | I915_WRITE(DPLL(pipe), dpll); |
|
- | 4220 | ||
- | 4221 | /* Wait for the clocks to stabilize. */ |
|
- | 4222 | POSTING_READ(DPLL(pipe)); |
|
- | 4223 | udelay(150); |
|
- | 4224 | ||
- | 4225 | if (INTEL_INFO(dev)->gen >= 4) { |
|
- | 4226 | u32 temp = 0; |
|
- | 4227 | if (is_sdvo) { |
|
- | 4228 | temp = intel_mode_get_pixel_multiplier(adjusted_mode); |
|
- | 4229 | if (temp > 1) |
|
- | 4230 | temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; |
|
- | 4231 | else |
|
- | 4232 | temp = 0; |
|
- | 4233 | } |
|
- | 4234 | I915_WRITE(DPLL_MD(pipe), temp); |
|
5095 | } else { |
4235 | } else { |
- | 4236 | /* The pixel multiplier can only be updated once the |
|
- | 4237 | * DPLL is enabled and the clocks are stable. |
|
- | 4238 | * |
|
- | 4239 | * So write it again. |
|
- | 4240 | */ |
|
- | 4241 | I915_WRITE(DPLL(pipe), dpll); |
|
- | 4242 | } |
|
- | 4243 | } |
|
- | 4244 | ||
- | 4245 | static void i8xx_update_pll(struct drm_crtc *crtc, |
|
- | 4246 | struct drm_display_mode *adjusted_mode, |
|
- | 4247 | intel_clock_t *clock, |
|
5096 | if (is_lvds) { |
4248 | int num_connectors) |
- | 4249 | { |
|
- | 4250 | struct drm_device *dev = crtc->dev; |
|
- | 4251 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 4252 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 4253 | int pipe = intel_crtc->pipe; |
|
- | 4254 | u32 dpll; |
|
- | 4255 | ||
- | 4256 | dpll = DPLL_VGA_MODE_DIS; |
|
- | 4257 | ||
- | 4258 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
|
5097 | dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; |
4259 | dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; |
5098 | } else { |
4260 | } else { |
5099 | if (clock.p1 == 2) |
4261 | if (clock->p1 == 2) |
5100 | dpll |= PLL_P1_DIVIDE_BY_TWO; |
4262 | dpll |= PLL_P1_DIVIDE_BY_TWO; |
5101 | else |
4263 | else |
5102 | dpll |= (clock.p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT; |
4264 | dpll |= (clock->p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT; |
5103 | if (clock.p2 == 4) |
4265 | if (clock->p2 == 4) |
5104 | dpll |= PLL_P2_DIVIDE_BY_4; |
4266 | dpll |= PLL_P2_DIVIDE_BY_4; |
5105 | } |
4267 | } |
5106 | } |
- | |
Line 5107... | Line -... | ||
5107 | - | ||
5108 | if (is_sdvo && is_tv) |
4268 | |
5109 | dpll |= PLL_REF_INPUT_TVCLKINBC; |
- | |
5110 | else if (is_tv) |
4269 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_TVOUT)) |
5111 | /* XXX: just matching BIOS for now */ |
4270 | /* XXX: just matching BIOS for now */ |
5112 | /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ |
4271 | /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ |
- | 4272 | dpll |= 3; |
|
5113 | dpll |= 3; |
4273 | else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && |
5114 | else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) |
4274 | intel_panel_use_ssc(dev_priv) && num_connectors < 2) |
5115 | dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; |
4275 | dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; |
5116 | else |
4276 | else |
Line -... | Line 4277... | ||
- | 4277 | dpll |= PLL_REF_INPUT_DREFCLK; |
|
- | 4278 | ||
- | 4279 | dpll |= DPLL_VCO_ENABLE; |
|
- | 4280 | I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); |
|
- | 4281 | POSTING_READ(DPLL(pipe)); |
|
- | 4282 | udelay(150); |
|
- | 4283 | ||
- | 4284 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
|
- | 4285 | * This is an exception to the general rule that mode_set doesn't turn |
|
- | 4286 | * things on. |
|
- | 4287 | */ |
|
- | 4288 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
|
- | 4289 | intel_update_lvds(crtc, clock, adjusted_mode); |
|
- | 4290 | ||
- | 4291 | I915_WRITE(DPLL(pipe), dpll); |
|
- | 4292 | ||
- | 4293 | /* Wait for the clocks to stabilize. */ |
|
- | 4294 | POSTING_READ(DPLL(pipe)); |
|
- | 4295 | udelay(150); |
|
- | 4296 | ||
- | 4297 | /* The pixel multiplier can only be updated once the |
|
- | 4298 | * DPLL is enabled and the clocks are stable. |
|
- | 4299 | * |
|
- | 4300 | * So write it again. |
|
- | 4301 | */ |
|
- | 4302 | I915_WRITE(DPLL(pipe), dpll); |
|
- | 4303 | } |
|
- | 4304 | ||
- | 4305 | static int i9xx_crtc_mode_set(struct drm_crtc *crtc, |
|
- | 4306 | struct drm_display_mode *mode, |
|
- | 4307 | struct drm_display_mode *adjusted_mode, |
|
- | 4308 | int x, int y, |
|
- | 4309 | struct drm_framebuffer *fb) |
|
- | 4310 | { |
|
- | 4311 | struct drm_device *dev = crtc->dev; |
|
- | 4312 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 4313 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 4314 | int pipe = intel_crtc->pipe; |
|
- | 4315 | int plane = intel_crtc->plane; |
|
- | 4316 | int refclk, num_connectors = 0; |
|
- | 4317 | intel_clock_t clock, reduced_clock; |
|
- | 4318 | u32 dspcntr, pipeconf, vsyncshift; |
|
- | 4319 | bool ok, has_reduced_clock = false, is_sdvo = false; |
|
- | 4320 | bool is_lvds = false, is_tv = false, is_dp = false; |
|
- | 4321 | struct intel_encoder *encoder; |
|
- | 4322 | const intel_limit_t *limit; |
|
- | 4323 | int ret; |
|
- | 4324 | ||
- | 4325 | for_each_encoder_on_crtc(dev, crtc, encoder) { |
|
- | 4326 | switch (encoder->type) { |
|
- | 4327 | case INTEL_OUTPUT_LVDS: |
|
- | 4328 | is_lvds = true; |
|
- | 4329 | break; |
|
- | 4330 | case INTEL_OUTPUT_SDVO: |
|
- | 4331 | case INTEL_OUTPUT_HDMI: |
|
- | 4332 | is_sdvo = true; |
|
- | 4333 | if (encoder->needs_tv_clock) |
|
- | 4334 | is_tv = true; |
|
- | 4335 | break; |
|
- | 4336 | case INTEL_OUTPUT_TVOUT: |
|
- | 4337 | is_tv = true; |
|
- | 4338 | break; |
|
- | 4339 | case INTEL_OUTPUT_DISPLAYPORT: |
|
- | 4340 | is_dp = true; |
|
- | 4341 | break; |
|
- | 4342 | } |
|
- | 4343 | ||
- | 4344 | num_connectors++; |
|
- | 4345 | } |
|
- | 4346 | ||
- | 4347 | refclk = i9xx_get_refclk(crtc, num_connectors); |
|
- | 4348 | ||
- | 4349 | /* |
|
- | 4350 | * Returns a set of divisors for the desired target clock with the given |
|
- | 4351 | * refclk, or FALSE. The returned values represent the clock equation: |
|
- | 4352 | * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. |
|
- | 4353 | */ |
|
- | 4354 | limit = intel_limit(crtc, refclk); |
|
- | 4355 | ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL, |
|
- | 4356 | &clock); |
|
- | 4357 | if (!ok) { |
|
- | 4358 | DRM_ERROR("Couldn't find PLL settings for mode!\n"); |
|
- | 4359 | return -EINVAL; |
|
- | 4360 | } |
|
- | 4361 | ||
- | 4362 | /* Ensure that the cursor is valid for the new mode before changing... */ |
|
- | 4363 | // intel_crtc_update_cursor(crtc, true); |
|
- | 4364 | ||
- | 4365 | if (is_lvds && dev_priv->lvds_downclock_avail) { |
|
- | 4366 | /* |
|
- | 4367 | * Ensure we match the reduced clock's P to the target clock. |
|
- | 4368 | * If the clocks don't match, we can't switch the display clock |
|
- | 4369 | * by using the FP0/FP1. In such case we will disable the LVDS |
|
- | 4370 | * downclock feature. |
|
- | 4371 | */ |
|
- | 4372 | has_reduced_clock = limit->find_pll(limit, crtc, |
|
- | 4373 | dev_priv->lvds_downclock, |
|
- | 4374 | refclk, |
|
- | 4375 | &clock, |
|
- | 4376 | &reduced_clock); |
|
- | 4377 | } |
|
- | 4378 | ||
- | 4379 | if (is_sdvo && is_tv) |
|
- | 4380 | i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock); |
|
- | 4381 | ||
- | 4382 | i9xx_update_pll_dividers(crtc, &clock, has_reduced_clock ? |
|
- | 4383 | &reduced_clock : NULL); |
|
- | 4384 | ||
- | 4385 | if (IS_GEN2(dev)) |
|
- | 4386 | i8xx_update_pll(crtc, adjusted_mode, &clock, num_connectors); |
|
- | 4387 | else if (IS_VALLEYVIEW(dev)) |
|
- | 4388 | vlv_update_pll(crtc, mode,adjusted_mode, &clock, NULL, |
|
- | 4389 | refclk, num_connectors); |
|
- | 4390 | else |
|
- | 4391 | i9xx_update_pll(crtc, mode, adjusted_mode, &clock, |
|
- | 4392 | has_reduced_clock ? &reduced_clock : NULL, |
|
5117 | dpll |= PLL_REF_INPUT_DREFCLK; |
4393 | num_connectors); |
5118 | 4394 | ||
Line 5119... | Line 4395... | ||
5119 | /* setup pipeconf */ |
4395 | /* setup pipeconf */ |
5120 | pipeconf = I915_READ(PIPECONF(pipe)); |
4396 | pipeconf = I915_READ(PIPECONF(pipe)); |
Line 5121... | Line -... | ||
5121 | - | ||
5122 | /* Set up the display plane register */ |
- | |
5123 | dspcntr = DISPPLANE_GAMMA_ENABLE; |
4397 | |
5124 | 4398 | /* Set up the display plane register */ |
|
5125 | /* Ironlake's plane is forced to pipe, bit 24 is to |
4399 | dspcntr = DISPPLANE_GAMMA_ENABLE; |
5126 | enable color space conversion */ |
4400 | |
Line 5144... | Line 4418... | ||
5144 | } |
4418 | } |
Line 5145... | Line 4419... | ||
5145 | 4419 | ||
5146 | /* default to 8bpc */ |
4420 | /* default to 8bpc */ |
5147 | pipeconf &= ~(PIPECONF_BPP_MASK | PIPECONF_DITHER_EN); |
4421 | pipeconf &= ~(PIPECONF_BPP_MASK | PIPECONF_DITHER_EN); |
5148 | if (is_dp) { |
4422 | if (is_dp) { |
5149 | if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) { |
4423 | if (adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) { |
5150 | pipeconf |= PIPECONF_BPP_6 | |
4424 | pipeconf |= PIPECONF_BPP_6 | |
5151 | PIPECONF_DITHER_EN | |
4425 | PIPECONF_DITHER_EN | |
5152 | PIPECONF_DITHER_TYPE_SP; |
4426 | PIPECONF_DITHER_TYPE_SP; |
5153 | } |
4427 | } |
Line 5154... | Line -... | ||
5154 | } |
- | |
5155 | - | ||
5156 | dpll |= DPLL_VCO_ENABLE; |
4428 | } |
5157 | 4429 | ||
Line 5158... | Line -... | ||
5158 | DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); |
- | |
5159 | drm_mode_debug_printmodeline(mode); |
- | |
5160 | - | ||
5161 | I915_WRITE(FP0(pipe), fp); |
- | |
5162 | I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); |
- | |
5163 | - | ||
5164 | POSTING_READ(DPLL(pipe)); |
- | |
5165 | udelay(150); |
- | |
5166 | - | ||
5167 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
- | |
5168 | * This is an exception to the general rule that mode_set doesn't turn |
- | |
5169 | * things on. |
- | |
5170 | */ |
- | |
5171 | if (is_lvds) { |
- | |
5172 | temp = I915_READ(LVDS); |
- | |
5173 | temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; |
- | |
5174 | if (pipe == 1) { |
- | |
5175 | temp |= LVDS_PIPEB_SELECT; |
- | |
5176 | } else { |
- | |
5177 | temp &= ~LVDS_PIPEB_SELECT; |
- | |
5178 | } |
- | |
5179 | /* set the corresponsding LVDS_BORDER bit */ |
- | |
5180 | temp |= dev_priv->lvds_border_bits; |
- | |
5181 | /* Set the B0-B3 data pairs corresponding to whether we're going to |
- | |
5182 | * set the DPLLs for dual-channel mode or not. |
- | |
5183 | */ |
- | |
5184 | if (clock.p2 == 7) |
- | |
5185 | temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; |
- | |
5186 | else |
- | |
5187 | temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); |
- | |
5188 | - | ||
5189 | /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) |
- | |
5190 | * appropriately here, but we need to look more thoroughly into how |
- | |
5191 | * panels behave in the two modes. |
- | |
5192 | */ |
- | |
5193 | /* set the dithering flag on LVDS as needed */ |
- | |
5194 | if (INTEL_INFO(dev)->gen >= 4) { |
- | |
5195 | if (dev_priv->lvds_dither) |
- | |
5196 | temp |= LVDS_ENABLE_DITHER; |
- | |
5197 | else |
- | |
5198 | temp &= ~LVDS_ENABLE_DITHER; |
- | |
5199 | } |
- | |
5200 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) |
- | |
5201 | lvds_sync |= LVDS_HSYNC_POLARITY; |
- | |
5202 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) |
- | |
5203 | lvds_sync |= LVDS_VSYNC_POLARITY; |
- | |
5204 | if ((temp & (LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY)) |
- | |
5205 | != lvds_sync) { |
- | |
5206 | char flags[2] = "-+"; |
- | |
5207 | DRM_INFO("Changing LVDS panel from " |
- | |
5208 | "(%chsync, %cvsync) to (%chsync, %cvsync)\n", |
- | |
5209 | flags[!(temp & LVDS_HSYNC_POLARITY)], |
- | |
5210 | flags[!(temp & LVDS_VSYNC_POLARITY)], |
- | |
5211 | flags[!(lvds_sync & LVDS_HSYNC_POLARITY)], |
- | |
5212 | flags[!(lvds_sync & LVDS_VSYNC_POLARITY)]); |
- | |
5213 | temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); |
- | |
5214 | temp |= lvds_sync; |
- | |
5215 | } |
- | |
5216 | I915_WRITE(LVDS, temp); |
- | |
5217 | } |
- | |
5218 | - | ||
5219 | if (is_dp) { |
- | |
5220 | intel_dp_set_m_n(crtc, mode, adjusted_mode); |
- | |
5221 | } |
- | |
5222 | - | ||
5223 | I915_WRITE(DPLL(pipe), dpll); |
- | |
5224 | - | ||
5225 | /* Wait for the clocks to stabilize. */ |
- | |
5226 | POSTING_READ(DPLL(pipe)); |
- | |
5227 | udelay(150); |
- | |
5228 | - | ||
5229 | if (INTEL_INFO(dev)->gen >= 4) { |
- | |
5230 | temp = 0; |
- | |
5231 | if (is_sdvo) { |
- | |
5232 | temp = intel_mode_get_pixel_multiplier(adjusted_mode); |
- | |
5233 | if (temp > 1) |
- | |
5234 | temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; |
- | |
5235 | else |
- | |
5236 | temp = 0; |
- | |
5237 | } |
- | |
5238 | I915_WRITE(DPLL_MD(pipe), temp); |
- | |
5239 | } else { |
- | |
5240 | /* The pixel multiplier can only be updated once the |
- | |
5241 | * DPLL is enabled and the clocks are stable. |
- | |
5242 | * |
- | |
5243 | * So write it again. |
- | |
5244 | */ |
- | |
5245 | I915_WRITE(DPLL(pipe), dpll); |
- | |
5246 | } |
- | |
5247 | - | ||
5248 | intel_crtc->lowfreq_avail = false; |
- | |
5249 | if (is_lvds && has_reduced_clock && i915_powersave) { |
4430 | DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); |
- | 4431 | drm_mode_debug_printmodeline(mode); |
|
5250 | I915_WRITE(FP1(pipe), fp2); |
4432 | |
5251 | intel_crtc->lowfreq_avail = true; |
4433 | if (HAS_PIPE_CXSR(dev)) { |
5252 | if (HAS_PIPE_CXSR(dev)) { |
- | |
5253 | DRM_DEBUG_KMS("enabling CxSR downclocking\n"); |
4434 | if (intel_crtc->lowfreq_avail) { |
5254 | pipeconf |= PIPECONF_CXSR_DOWNCLOCK; |
- | |
5255 | } |
- | |
5256 | } else { |
4435 | DRM_DEBUG_KMS("enabling CxSR downclocking\n"); |
5257 | I915_WRITE(FP1(pipe), fp); |
4436 | pipeconf |= PIPECONF_CXSR_DOWNCLOCK; |
5258 | if (HAS_PIPE_CXSR(dev)) { |
4437 | } else { |
5259 | DRM_DEBUG_KMS("disabling CxSR downclocking\n"); |
4438 | DRM_DEBUG_KMS("disabling CxSR downclocking\n"); |
Line 5260... | Line 4439... | ||
5260 | pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; |
4439 | pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; |
- | 4440 | } |
|
5261 | } |
4441 | } |
5262 | } |
4442 | |
5263 | 4443 | pipeconf &= ~PIPECONF_INTERLACE_MASK; |
|
5264 | pipeconf &= ~PIPECONF_INTERLACE_MASK; |
- | |
5265 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { |
4444 | if (!IS_GEN2(dev) && |
5266 | pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; |
- | |
5267 | /* the chip adds 2 halflines automatically */ |
4445 | adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { |
5268 | adjusted_mode->crtc_vdisplay -= 1; |
4446 | pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; |
5269 | adjusted_mode->crtc_vtotal -= 1; |
4447 | /* the chip adds 2 halflines automatically */ |
5270 | adjusted_mode->crtc_vblank_start -= 1; |
4448 | adjusted_mode->crtc_vtotal -= 1; |
5271 | adjusted_mode->crtc_vblank_end -= 1; |
4449 | adjusted_mode->crtc_vblank_end -= 1; |
- | 4450 | vsyncshift = adjusted_mode->crtc_hsync_start |
|
- | 4451 | - adjusted_mode->crtc_htotal/2; |
|
- | 4452 | } else { |
|
- | 4453 | pipeconf |= PIPECONF_PROGRESSIVE; |
|
- | 4454 | vsyncshift = 0; |
|
Line 5272... | Line 4455... | ||
5272 | adjusted_mode->crtc_vsync_end -= 1; |
4455 | } |
5273 | adjusted_mode->crtc_vsync_start -= 1; |
4456 | |
5274 | } else |
4457 | if (!IS_GEN3(dev)) |
5275 | pipeconf |= PIPECONF_PROGRESSIVE; |
4458 | I915_WRITE(VSYNCSHIFT(pipe), vsyncshift); |
Line 5310... | Line 4493... | ||
5310 | 4493 | ||
Line 5311... | Line 4494... | ||
5311 | intel_wait_for_vblank(dev, pipe); |
4494 | intel_wait_for_vblank(dev, pipe); |
5312 | 4495 | ||
5313 | I915_WRITE(DSPCNTR(plane), dspcntr); |
- | |
Line 5314... | Line 4496... | ||
5314 | POSTING_READ(DSPCNTR(plane)); |
4496 | I915_WRITE(DSPCNTR(plane), dspcntr); |
Line 5315... | Line 4497... | ||
5315 | intel_enable_plane(dev_priv, plane, pipe); |
4497 | POSTING_READ(DSPCNTR(plane)); |
Line 5316... | Line 4498... | ||
5316 | 4498 | ||
5317 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
4499 | ret = intel_pipe_set_base(crtc, x, y, fb); |
Line 5387... | Line 4569... | ||
5387 | 4569 | ||
5388 | /* SSC must be turned on before enabling the CPU output */ |
4570 | /* SSC must be turned on before enabling the CPU output */ |
5389 | if (intel_panel_use_ssc(dev_priv) && can_ssc) { |
4571 | if (intel_panel_use_ssc(dev_priv) && can_ssc) { |
5390 | DRM_DEBUG_KMS("Using SSC on panel\n"); |
4572 | DRM_DEBUG_KMS("Using SSC on panel\n"); |
5391 | temp |= DREF_SSC1_ENABLE; |
4573 | temp |= DREF_SSC1_ENABLE; |
- | 4574 | } else |
|
Line 5392... | Line 4575... | ||
5392 | } |
4575 | temp &= ~DREF_SSC1_ENABLE; |
5393 | 4576 | ||
5394 | /* Get SSC going before enabling the outputs */ |
4577 | /* Get SSC going before enabling the outputs */ |
5395 | I915_WRITE(PCH_DREF_CONTROL, temp); |
4578 | I915_WRITE(PCH_DREF_CONTROL, temp); |
Line 5440... | Line 4623... | ||
5440 | static int ironlake_get_refclk(struct drm_crtc *crtc) |
4623 | static int ironlake_get_refclk(struct drm_crtc *crtc) |
5441 | { |
4624 | { |
5442 | struct drm_device *dev = crtc->dev; |
4625 | struct drm_device *dev = crtc->dev; |
5443 | struct drm_i915_private *dev_priv = dev->dev_private; |
4626 | struct drm_i915_private *dev_priv = dev->dev_private; |
5444 | struct intel_encoder *encoder; |
4627 | struct intel_encoder *encoder; |
5445 | struct drm_mode_config *mode_config = &dev->mode_config; |
- | |
5446 | struct intel_encoder *edp_encoder = NULL; |
4628 | struct intel_encoder *edp_encoder = NULL; |
5447 | int num_connectors = 0; |
4629 | int num_connectors = 0; |
5448 | bool is_lvds = false; |
4630 | bool is_lvds = false; |
Line 5449... | Line 4631... | ||
5449 | 4631 | ||
5450 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { |
- | |
5451 | if (encoder->base.crtc != crtc) |
- | |
5452 | continue; |
- | |
5453 | 4632 | for_each_encoder_on_crtc(dev, crtc, encoder) { |
|
5454 | switch (encoder->type) { |
4633 | switch (encoder->type) { |
5455 | case INTEL_OUTPUT_LVDS: |
4634 | case INTEL_OUTPUT_LVDS: |
5456 | is_lvds = true; |
4635 | is_lvds = true; |
5457 | break; |
4636 | break; |
Line 5469... | Line 4648... | ||
5469 | } |
4648 | } |
Line 5470... | Line 4649... | ||
5470 | 4649 | ||
5471 | return 120000; |
4650 | return 120000; |
Line -... | Line 4651... | ||
- | 4651 | } |
|
- | 4652 | ||
- | 4653 | static void ironlake_set_pipeconf(struct drm_crtc *crtc, |
|
- | 4654 | struct drm_display_mode *adjusted_mode, |
|
- | 4655 | bool dither) |
|
- | 4656 | { |
|
- | 4657 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
|
- | 4658 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 4659 | int pipe = intel_crtc->pipe; |
|
- | 4660 | uint32_t val; |
|
- | 4661 | ||
- | 4662 | val = I915_READ(PIPECONF(pipe)); |
|
- | 4663 | ||
- | 4664 | val &= ~PIPE_BPC_MASK; |
|
- | 4665 | switch (intel_crtc->bpp) { |
|
- | 4666 | case 18: |
|
- | 4667 | val |= PIPE_6BPC; |
|
- | 4668 | break; |
|
- | 4669 | case 24: |
|
- | 4670 | val |= PIPE_8BPC; |
|
- | 4671 | break; |
|
- | 4672 | case 30: |
|
- | 4673 | val |= PIPE_10BPC; |
|
- | 4674 | break; |
|
- | 4675 | case 36: |
|
- | 4676 | val |= PIPE_12BPC; |
|
- | 4677 | break; |
|
- | 4678 | default: |
|
- | 4679 | val |= PIPE_8BPC; |
|
- | 4680 | break; |
|
- | 4681 | } |
|
- | 4682 | ||
- | 4683 | val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK); |
|
- | 4684 | if (dither) |
|
- | 4685 | val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP); |
|
- | 4686 | ||
- | 4687 | val &= ~PIPECONF_INTERLACE_MASK; |
|
- | 4688 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) |
|
- | 4689 | val |= PIPECONF_INTERLACED_ILK; |
|
- | 4690 | else |
|
- | 4691 | val |= PIPECONF_PROGRESSIVE; |
|
- | 4692 | ||
- | 4693 | I915_WRITE(PIPECONF(pipe), val); |
|
- | 4694 | POSTING_READ(PIPECONF(pipe)); |
|
- | 4695 | } |
|
- | 4696 | ||
- | 4697 | static bool ironlake_compute_clocks(struct drm_crtc *crtc, |
|
- | 4698 | struct drm_display_mode *adjusted_mode, |
|
- | 4699 | intel_clock_t *clock, |
|
- | 4700 | bool *has_reduced_clock, |
|
- | 4701 | intel_clock_t *reduced_clock) |
|
- | 4702 | { |
|
- | 4703 | struct drm_device *dev = crtc->dev; |
|
- | 4704 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 4705 | struct intel_encoder *intel_encoder; |
|
- | 4706 | int refclk; |
|
- | 4707 | const intel_limit_t *limit; |
|
- | 4708 | bool ret, is_sdvo = false, is_tv = false, is_lvds = false; |
|
- | 4709 | ||
- | 4710 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) { |
|
- | 4711 | switch (intel_encoder->type) { |
|
- | 4712 | case INTEL_OUTPUT_LVDS: |
|
- | 4713 | is_lvds = true; |
|
- | 4714 | break; |
|
- | 4715 | case INTEL_OUTPUT_SDVO: |
|
- | 4716 | case INTEL_OUTPUT_HDMI: |
|
- | 4717 | is_sdvo = true; |
|
- | 4718 | if (intel_encoder->needs_tv_clock) |
|
- | 4719 | is_tv = true; |
|
- | 4720 | break; |
|
- | 4721 | case INTEL_OUTPUT_TVOUT: |
|
- | 4722 | is_tv = true; |
|
- | 4723 | break; |
|
- | 4724 | } |
|
- | 4725 | } |
|
- | 4726 | ||
- | 4727 | refclk = ironlake_get_refclk(crtc); |
|
- | 4728 | ||
- | 4729 | /* |
|
- | 4730 | * Returns a set of divisors for the desired target clock with the given |
|
- | 4731 | * refclk, or FALSE. The returned values represent the clock equation: |
|
- | 4732 | * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. |
|
- | 4733 | */ |
|
- | 4734 | limit = intel_limit(crtc, refclk); |
|
- | 4735 | ret = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL, |
|
- | 4736 | clock); |
|
- | 4737 | if (!ret) |
|
- | 4738 | return false; |
|
- | 4739 | ||
- | 4740 | if (is_lvds && dev_priv->lvds_downclock_avail) { |
|
- | 4741 | /* |
|
- | 4742 | * Ensure we match the reduced clock's P to the target clock. |
|
- | 4743 | * If the clocks don't match, we can't switch the display clock |
|
- | 4744 | * by using the FP0/FP1. In such case we will disable the LVDS |
|
- | 4745 | * downclock feature. |
|
- | 4746 | */ |
|
- | 4747 | *has_reduced_clock = limit->find_pll(limit, crtc, |
|
- | 4748 | dev_priv->lvds_downclock, |
|
- | 4749 | refclk, |
|
- | 4750 | clock, |
|
- | 4751 | reduced_clock); |
|
- | 4752 | } |
|
- | 4753 | ||
- | 4754 | if (is_sdvo && is_tv) |
|
- | 4755 | i9xx_adjust_sdvo_tv_clock(adjusted_mode, clock); |
|
- | 4756 | ||
- | 4757 | return true; |
|
5472 | } |
4758 | } |
5473 | 4759 | ||
5474 | static int ironlake_crtc_mode_set(struct drm_crtc *crtc, |
4760 | static int ironlake_crtc_mode_set(struct drm_crtc *crtc, |
5475 | struct drm_display_mode *mode, |
4761 | struct drm_display_mode *mode, |
5476 | struct drm_display_mode *adjusted_mode, |
4762 | struct drm_display_mode *adjusted_mode, |
5477 | int x, int y, |
4763 | int x, int y, |
5478 | struct drm_framebuffer *old_fb) |
4764 | struct drm_framebuffer *fb) |
5479 | { |
4765 | { |
5480 | struct drm_device *dev = crtc->dev; |
4766 | struct drm_device *dev = crtc->dev; |
5481 | struct drm_i915_private *dev_priv = dev->dev_private; |
4767 | struct drm_i915_private *dev_priv = dev->dev_private; |
5482 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
4768 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
5483 | int pipe = intel_crtc->pipe; |
4769 | int pipe = intel_crtc->pipe; |
5484 | int plane = intel_crtc->plane; |
4770 | int plane = intel_crtc->plane; |
5485 | int refclk, num_connectors = 0; |
4771 | int num_connectors = 0; |
5486 | intel_clock_t clock, reduced_clock; |
4772 | intel_clock_t clock, reduced_clock; |
5487 | u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf; |
4773 | u32 dpll, fp = 0, fp2 = 0; |
5488 | bool ok, has_reduced_clock = false, is_sdvo = false; |
4774 | bool ok, has_reduced_clock = false, is_sdvo = false; |
5489 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
- | |
5490 | struct intel_encoder *has_edp_encoder = NULL; |
- | |
5491 | struct drm_mode_config *mode_config = &dev->mode_config; |
- | |
5492 | struct intel_encoder *encoder; |
4775 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
5493 | const intel_limit_t *limit; |
4776 | struct intel_encoder *encoder, *edp_encoder = NULL; |
5494 | int ret; |
4777 | int ret; |
5495 | struct fdi_m_n m_n = {0}; |
- | |
5496 | u32 temp; |
4778 | struct fdi_m_n m_n = {0}; |
5497 | u32 lvds_sync = 0; |
4779 | u32 temp; |
5498 | int target_clock, pixel_multiplier, lane, link_bw, factor; |
4780 | int target_clock, pixel_multiplier, lane, link_bw, factor; |
- | 4781 | unsigned int pipe_bpp; |
|
Line 5499... | Line -... | ||
5499 | unsigned int pipe_bpp; |
- | |
5500 | bool dither; |
- | |
5501 | 4782 | bool dither; |
|
5502 | ENTER(); |
- | |
5503 | - | ||
5504 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { |
- | |
5505 | if (encoder->base.crtc != crtc) |
4783 | bool is_cpu_edp = false, is_pch_edp = false; |
5506 | continue; |
4784 | |
5507 | 4785 | for_each_encoder_on_crtc(dev, crtc, encoder) { |
|
5508 | switch (encoder->type) { |
4786 | switch (encoder->type) { |
5509 | case INTEL_OUTPUT_LVDS: |
4787 | case INTEL_OUTPUT_LVDS: |
Line 5523... | Line 4801... | ||
5523 | break; |
4801 | break; |
5524 | case INTEL_OUTPUT_DISPLAYPORT: |
4802 | case INTEL_OUTPUT_DISPLAYPORT: |
5525 | is_dp = true; |
4803 | is_dp = true; |
5526 | break; |
4804 | break; |
5527 | case INTEL_OUTPUT_EDP: |
4805 | case INTEL_OUTPUT_EDP: |
- | 4806 | is_dp = true; |
|
- | 4807 | if (intel_encoder_is_pch_edp(&encoder->base)) |
|
- | 4808 | is_pch_edp = true; |
|
- | 4809 | else |
|
- | 4810 | is_cpu_edp = true; |
|
5528 | has_edp_encoder = encoder; |
4811 | edp_encoder = encoder; |
5529 | break; |
4812 | break; |
5530 | } |
4813 | } |
Line 5531... | Line 4814... | ||
5531 | 4814 | ||
5532 | num_connectors++; |
4815 | num_connectors++; |
Line 5533... | Line 4816... | ||
5533 | } |
4816 | } |
5534 | - | ||
5535 | refclk = ironlake_get_refclk(crtc); |
- | |
5536 | - | ||
5537 | /* |
- | |
5538 | * Returns a set of divisors for the desired target clock with the given |
- | |
5539 | * refclk, or FALSE. The returned values represent the clock equation: |
- | |
5540 | * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. |
4817 | |
5541 | */ |
- | |
5542 | limit = intel_limit(crtc, refclk); |
4818 | ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock, |
5543 | ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); |
4819 | &has_reduced_clock, &reduced_clock); |
5544 | if (!ok) { |
4820 | if (!ok) { |
5545 | DRM_ERROR("Couldn't find PLL settings for mode!\n"); |
4821 | DRM_ERROR("Couldn't find PLL settings for mode!\n"); |
Line 5546... | Line 4822... | ||
5546 | return -EINVAL; |
4822 | return -EINVAL; |
5547 | } |
4823 | } |
Line 5548... | Line -... | ||
5548 | - | ||
5549 | /* Ensure that the cursor is valid for the new mode before changing... */ |
- | |
5550 | // intel_crtc_update_cursor(crtc, true); |
- | |
5551 | - | ||
5552 | if (is_lvds && dev_priv->lvds_downclock_avail) { |
- | |
5553 | has_reduced_clock = limit->find_pll(limit, crtc, |
- | |
5554 | dev_priv->lvds_downclock, |
- | |
5555 | refclk, |
- | |
5556 | &reduced_clock); |
- | |
5557 | if (has_reduced_clock && (clock.p != reduced_clock.p)) { |
- | |
5558 | /* |
- | |
5559 | * If the different P is found, it means that we can't |
- | |
5560 | * switch the display clock by using the FP0/FP1. |
- | |
5561 | * In such case we will disable the LVDS downclock |
- | |
5562 | * feature. |
- | |
5563 | */ |
- | |
5564 | DRM_DEBUG_KMS("Different P is found for " |
- | |
5565 | "LVDS clock/downclock\n"); |
- | |
5566 | has_reduced_clock = 0; |
- | |
5567 | } |
- | |
5568 | } |
- | |
5569 | /* SDVO TV has fixed PLL values depend on its clock range, |
- | |
5570 | this mirrors vbios setting. */ |
- | |
5571 | if (is_sdvo && is_tv) { |
- | |
5572 | if (adjusted_mode->clock >= 100000 |
- | |
5573 | && adjusted_mode->clock < 140500) { |
- | |
5574 | clock.p1 = 2; |
- | |
5575 | clock.p2 = 10; |
- | |
5576 | clock.n = 3; |
- | |
5577 | clock.m1 = 16; |
- | |
5578 | clock.m2 = 8; |
- | |
5579 | } else if (adjusted_mode->clock >= 140500 |
- | |
5580 | && adjusted_mode->clock <= 200000) { |
- | |
5581 | clock.p1 = 1; |
- | |
5582 | clock.p2 = 10; |
- | |
5583 | clock.n = 6; |
- | |
5584 | clock.m1 = 12; |
- | |
5585 | clock.m2 = 8; |
4824 | |
5586 | } |
4825 | /* Ensure that the cursor is valid for the new mode before changing... */ |
5587 | } |
4826 | // intel_crtc_update_cursor(crtc, true); |
5588 | 4827 | ||
5589 | /* FDI link */ |
4828 | /* FDI link */ |
5590 | pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); |
4829 | pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); |
5591 | lane = 0; |
- | |
5592 | /* CPU eDP doesn't require FDI link, so just set DP M/N |
- | |
5593 | according to current link config */ |
4830 | lane = 0; |
5594 | if (has_edp_encoder && |
- | |
5595 | !intel_encoder_is_pch_edp(&has_edp_encoder->base)) { |
4831 | /* CPU eDP doesn't require FDI link, so just set DP M/N |
5596 | target_clock = mode->clock; |
- | |
5597 | intel_edp_link_config(has_edp_encoder, |
- | |
5598 | &lane, &link_bw); |
- | |
5599 | } else { |
- | |
5600 | /* [e]DP over FDI requires target mode clock |
- | |
5601 | instead of link clock */ |
- | |
5602 | if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) |
- | |
5603 | target_clock = mode->clock; |
4832 | according to current link config */ |
5604 | else |
4833 | if (is_cpu_edp) { |
5605 | target_clock = adjusted_mode->clock; |
4834 | intel_edp_link_config(edp_encoder, &lane, &link_bw); |
5606 | 4835 | } else { |
|
5607 | /* FDI is a binary signal running at ~2.7GHz, encoding |
4836 | /* FDI is a binary signal running at ~2.7GHz, encoding |
5608 | * each output octet as 10 bits. The actual frequency |
4837 | * each output octet as 10 bits. The actual frequency |
5609 | * is stored as a divider into a 100MHz clock, and the |
4838 | * is stored as a divider into a 100MHz clock, and the |
5610 | * mode pixel clock is stored in units of 1KHz. |
4839 | * mode pixel clock is stored in units of 1KHz. |
5611 | * Hence the bw of each lane in terms of the mode signal |
4840 | * Hence the bw of each lane in terms of the mode signal |
Line -... | Line 4841... | ||
- | 4841 | * is: |
|
- | 4842 | */ |
|
- | 4843 | link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; |
|
- | 4844 | } |
|
- | 4845 | ||
- | 4846 | /* [e]DP over FDI requires target mode clock instead of link clock. */ |
|
- | 4847 | if (edp_encoder) |
|
- | 4848 | target_clock = intel_edp_target_clock(edp_encoder, mode); |
|
5612 | * is: |
4849 | else if (is_dp) |
5613 | */ |
- | |
5614 | link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; |
- | |
5615 | } |
4850 | target_clock = mode->clock; |
5616 | - | ||
5617 | /* determine panel color depth */ |
- | |
5618 | temp = I915_READ(PIPECONF(pipe)); |
4851 | else |
5619 | temp &= ~PIPE_BPC_MASK; |
- | |
5620 | dither = intel_choose_pipe_bpp_dither(crtc, &pipe_bpp, mode); |
- | |
5621 | switch (pipe_bpp) { |
4852 | target_clock = adjusted_mode->clock; |
5622 | case 18: |
4853 | |
5623 | temp |= PIPE_6BPC; |
4854 | /* determine panel color depth */ |
5624 | break; |
4855 | dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp, |
5625 | case 24: |
- | |
5626 | temp |= PIPE_8BPC; |
4856 | adjusted_mode); |
5627 | break; |
- | |
5628 | case 30: |
- | |
5629 | temp |= PIPE_10BPC; |
- | |
5630 | break; |
4857 | if (is_lvds && dev_priv->lvds_dither) |
5631 | case 36: |
4858 | dither = true; |
5632 | temp |= PIPE_12BPC; |
- | |
5633 | break; |
4859 | |
5634 | default: |
- | |
5635 | WARN(1, "intel_choose_pipe_bpp returned invalid value %d\n", |
4860 | if (pipe_bpp != 18 && pipe_bpp != 24 && pipe_bpp != 30 && |
5636 | pipe_bpp); |
- | |
5637 | temp |= PIPE_8BPC; |
4861 | pipe_bpp != 36) { |
5638 | pipe_bpp = 24; |
- | |
Line 5639... | Line 4862... | ||
5639 | break; |
4862 | WARN(1, "intel_choose_pipe_bpp returned invalid value %d\n", |
5640 | } |
4863 | pipe_bpp); |
5641 | 4864 | pipe_bpp = 24; |
|
5642 | intel_crtc->bpp = pipe_bpp; |
4865 | } |
Line 5688... | Line 4911... | ||
5688 | if (pixel_multiplier > 1) { |
4911 | if (pixel_multiplier > 1) { |
5689 | dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; |
4912 | dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; |
5690 | } |
4913 | } |
5691 | dpll |= DPLL_DVO_HIGH_SPEED; |
4914 | dpll |= DPLL_DVO_HIGH_SPEED; |
5692 | } |
4915 | } |
5693 | if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) |
4916 | if (is_dp && !is_cpu_edp) |
5694 | dpll |= DPLL_DVO_HIGH_SPEED; |
4917 | dpll |= DPLL_DVO_HIGH_SPEED; |
Line 5695... | Line 4918... | ||
5695 | 4918 | ||
5696 | /* compute bitmask from p1 value */ |
4919 | /* compute bitmask from p1 value */ |
5697 | dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; |
4920 | dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; |
Line 5722... | Line 4945... | ||
5722 | else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) |
4945 | else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) |
5723 | dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; |
4946 | dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; |
5724 | else |
4947 | else |
5725 | dpll |= PLL_REF_INPUT_DREFCLK; |
4948 | dpll |= PLL_REF_INPUT_DREFCLK; |
Line 5726... | Line -... | ||
5726 | - | ||
5727 | /* setup pipeconf */ |
- | |
5728 | pipeconf = I915_READ(PIPECONF(pipe)); |
- | |
5729 | - | ||
5730 | /* Set up the display plane register */ |
- | |
5731 | dspcntr = DISPPLANE_GAMMA_ENABLE; |
- | |
5732 | 4949 | ||
5733 | DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe); |
4950 | DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe); |
Line 5734... | Line 4951... | ||
5734 | drm_mode_debug_printmodeline(mode); |
4951 | drm_mode_debug_printmodeline(mode); |
5735 | 4952 | ||
5736 | /* PCH eDP needs FDI, but CPU eDP does not */ |
4953 | /* CPU eDP is the only output that doesn't need a PCH PLL of its own on |
5737 | if (!intel_crtc->no_pll) { |
4954 | * pre-Haswell/LPT generation */ |
- | 4955 | if (HAS_PCH_LPT(dev)) { |
|
5738 | if (!has_edp_encoder || |
4956 | DRM_DEBUG_KMS("LPT detected: no PLL for pipe %d necessary\n", |
5739 | intel_encoder_is_pch_edp(&has_edp_encoder->base)) { |
4957 | pipe); |
Line 5740... | Line -... | ||
5740 | I915_WRITE(PCH_FP0(pipe), fp); |
- | |
5741 | I915_WRITE(PCH_DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); |
- | |
5742 | - | ||
5743 | POSTING_READ(PCH_DPLL(pipe)); |
- | |
5744 | udelay(150); |
- | |
5745 | } |
- | |
5746 | } else { |
- | |
5747 | if (dpll == (I915_READ(PCH_DPLL(0)) & 0x7fffffff) && |
4958 | } else if (!is_cpu_edp) { |
5748 | fp == I915_READ(PCH_FP0(0))) { |
- | |
5749 | intel_crtc->use_pll_a = true; |
4959 | struct intel_pch_pll *pll; |
5750 | DRM_DEBUG_KMS("using pipe a dpll\n"); |
- | |
5751 | } else if (dpll == (I915_READ(PCH_DPLL(1)) & 0x7fffffff) && |
4960 | |
5752 | fp == I915_READ(PCH_FP0(1))) { |
4961 | pll = intel_get_pch_pll(intel_crtc, dpll, fp); |
5753 | intel_crtc->use_pll_a = false; |
- | |
5754 | DRM_DEBUG_KMS("using pipe b dpll\n"); |
4962 | if (pll == NULL) { |
5755 | } else { |
4963 | DRM_DEBUG_DRIVER("failed to find PLL for pipe %d\n", |
5756 | DRM_DEBUG_KMS("no matching PLL configuration for pipe 2\n"); |
4964 | pipe); |
- | 4965 | return -EINVAL; |
|
Line 5757... | Line 4966... | ||
5757 | return -EINVAL; |
4966 | } |
5758 | } |
4967 | } else |
5759 | } |
4968 | intel_put_pch_pll(intel_crtc); |
5760 | 4969 | ||
Line 5787... | Line 4996... | ||
5787 | 4996 | ||
5788 | /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) |
4997 | /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) |
5789 | * appropriately here, but we need to look more thoroughly into how |
4998 | * appropriately here, but we need to look more thoroughly into how |
5790 | * panels behave in the two modes. |
4999 | * panels behave in the two modes. |
- | 5000 | */ |
|
5791 | */ |
5001 | temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); |
5792 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) |
5002 | if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) |
5793 | lvds_sync |= LVDS_HSYNC_POLARITY; |
5003 | temp |= LVDS_HSYNC_POLARITY; |
5794 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) |
5004 | if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) |
5795 | lvds_sync |= LVDS_VSYNC_POLARITY; |
- | |
5796 | if ((temp & (LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY)) |
- | |
5797 | != lvds_sync) { |
- | |
5798 | char flags[2] = "-+"; |
- | |
5799 | DRM_INFO("Changing LVDS panel from " |
- | |
5800 | "(%chsync, %cvsync) to (%chsync, %cvsync)\n", |
- | |
5801 | flags[!(temp & LVDS_HSYNC_POLARITY)], |
- | |
5802 | flags[!(temp & LVDS_VSYNC_POLARITY)], |
- | |
5803 | flags[!(lvds_sync & LVDS_HSYNC_POLARITY)], |
- | |
5804 | flags[!(lvds_sync & LVDS_VSYNC_POLARITY)]); |
- | |
5805 | temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); |
- | |
5806 | temp |= lvds_sync; |
- | |
5807 | } |
5005 | temp |= LVDS_VSYNC_POLARITY; |
5808 | I915_WRITE(PCH_LVDS, temp); |
5006 | I915_WRITE(PCH_LVDS, temp); |
Line 5809... | Line -... | ||
5809 | } |
- | |
5810 | - | ||
5811 | pipeconf &= ~PIPECONF_DITHER_EN; |
5007 | } |
5812 | pipeconf &= ~PIPECONF_DITHER_TYPE_MASK; |
- | |
5813 | if ((is_lvds && dev_priv->lvds_dither) || dither) { |
- | |
5814 | pipeconf |= PIPECONF_DITHER_EN; |
- | |
5815 | pipeconf |= PIPECONF_DITHER_TYPE_SP; |
- | |
5816 | } |
5008 | |
5817 | if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { |
5009 | if (is_dp && !is_cpu_edp) { |
5818 | intel_dp_set_m_n(crtc, mode, adjusted_mode); |
5010 | intel_dp_set_m_n(crtc, mode, adjusted_mode); |
5819 | } else { |
5011 | } else { |
5820 | /* For non-DP output, clear any trans DP clock recovery setting.*/ |
5012 | /* For non-DP output, clear any trans DP clock recovery setting.*/ |
5821 | I915_WRITE(TRANSDATA_M1(pipe), 0); |
5013 | I915_WRITE(TRANSDATA_M1(pipe), 0); |
5822 | I915_WRITE(TRANSDATA_N1(pipe), 0); |
5014 | I915_WRITE(TRANSDATA_N1(pipe), 0); |
5823 | I915_WRITE(TRANSDPLINK_M1(pipe), 0); |
5015 | I915_WRITE(TRANSDPLINK_M1(pipe), 0); |
Line 5824... | Line 5016... | ||
5824 | I915_WRITE(TRANSDPLINK_N1(pipe), 0); |
5016 | I915_WRITE(TRANSDPLINK_N1(pipe), 0); |
5825 | } |
- | |
5826 | - | ||
5827 | if (!intel_crtc->no_pll && |
5017 | } |
Line 5828... | Line 5018... | ||
5828 | (!has_edp_encoder || |
5018 | |
5829 | intel_encoder_is_pch_edp(&has_edp_encoder->base))) { |
5019 | if (intel_crtc->pch_pll) { |
5830 | I915_WRITE(PCH_DPLL(pipe), dpll); |
5020 | I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll); |
Line 5831... | Line 5021... | ||
5831 | 5021 | ||
5832 | /* Wait for the clocks to stabilize. */ |
5022 | /* Wait for the clocks to stabilize. */ |
5833 | POSTING_READ(PCH_DPLL(pipe)); |
5023 | POSTING_READ(intel_crtc->pch_pll->pll_reg); |
5834 | udelay(150); |
5024 | udelay(150); |
5835 | 5025 | ||
5836 | /* The pixel multiplier can only be updated once the |
5026 | /* The pixel multiplier can only be updated once the |
5837 | * DPLL is enabled and the clocks are stable. |
5027 | * DPLL is enabled and the clocks are stable. |
Line 5838... | Line 5028... | ||
5838 | * |
5028 | * |
5839 | * So write it again. |
5029 | * So write it again. |
5840 | */ |
5030 | */ |
5841 | I915_WRITE(PCH_DPLL(pipe), dpll); |
5031 | I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll); |
5842 | } |
5032 | } |
5843 | - | ||
5844 | intel_crtc->lowfreq_avail = false; |
- | |
5845 | if (!intel_crtc->no_pll) { |
- | |
5846 | if (is_lvds && has_reduced_clock && i915_powersave) { |
- | |
5847 | I915_WRITE(PCH_FP1(pipe), fp2); |
5033 | |
5848 | intel_crtc->lowfreq_avail = true; |
5034 | intel_crtc->lowfreq_avail = false; |
5849 | if (HAS_PIPE_CXSR(dev)) { |
- | |
5850 | DRM_DEBUG_KMS("enabling CxSR downclocking\n"); |
- | |
5851 | pipeconf |= PIPECONF_CXSR_DOWNCLOCK; |
- | |
5852 | } |
- | |
5853 | } else { |
5035 | if (intel_crtc->pch_pll) { |
5854 | I915_WRITE(PCH_FP1(pipe), fp); |
5036 | if (is_lvds && has_reduced_clock && i915_powersave) { |
Line 5855... | Line -... | ||
5855 | if (HAS_PIPE_CXSR(dev)) { |
- | |
5856 | DRM_DEBUG_KMS("disabling CxSR downclocking\n"); |
5037 | I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2); |
5857 | pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; |
- | |
5858 | } |
5038 | intel_crtc->lowfreq_avail = true; |
5859 | } |
- | |
5860 | } |
5039 | } else { |
5861 | - | ||
5862 | pipeconf &= ~PIPECONF_INTERLACE_MASK; |
5040 | I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp); |
- | 5041 | } |
|
5863 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { |
5042 | } |
5864 | pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; |
5043 | |
5865 | /* the chip adds 2 halflines automatically */ |
5044 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { |
5866 | adjusted_mode->crtc_vdisplay -= 1; |
5045 | /* the chip adds 2 halflines automatically */ |
- | 5046 | adjusted_mode->crtc_vtotal -= 1; |
|
Line 5867... | Line 5047... | ||
5867 | adjusted_mode->crtc_vtotal -= 1; |
5047 | adjusted_mode->crtc_vblank_end -= 1; |
5868 | adjusted_mode->crtc_vblank_start -= 1; |
5048 | I915_WRITE(VSYNCSHIFT(pipe), |
5869 | adjusted_mode->crtc_vblank_end -= 1; |
5049 | adjusted_mode->crtc_hsync_start |
5870 | adjusted_mode->crtc_vsync_end -= 1; |
5050 | - adjusted_mode->crtc_htotal/2); |
Line 5901... | Line 5081... | ||
5901 | I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m); |
5081 | I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m); |
5902 | I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n); |
5082 | I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n); |
5903 | I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m); |
5083 | I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m); |
5904 | I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n); |
5084 | I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n); |
Line 5905... | Line 5085... | ||
5905 | 5085 | ||
5906 | if (has_edp_encoder && |
- | |
5907 | !intel_encoder_is_pch_edp(&has_edp_encoder->base)) { |
5086 | if (is_cpu_edp) |
5908 | ironlake_set_pll_edp(crtc, adjusted_mode->clock); |
- | |
Line 5909... | Line 5087... | ||
5909 | } |
5087 | ironlake_set_pll_edp(crtc, adjusted_mode->clock); |
5910 | - | ||
Line 5911... | Line 5088... | ||
5911 | I915_WRITE(PIPECONF(pipe), pipeconf); |
5088 | |
Line 5912... | Line -... | ||
5912 | POSTING_READ(PIPECONF(pipe)); |
- | |
5913 | 5089 | ironlake_set_pipeconf(crtc, adjusted_mode, dither); |
|
5914 | intel_wait_for_vblank(dev, pipe); |
- | |
5915 | - | ||
5916 | if (IS_GEN5(dev)) { |
- | |
5917 | /* enable address swizzle for tiling buffer */ |
- | |
5918 | temp = I915_READ(DISP_ARB_CTL); |
5090 | |
5919 | I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING); |
5091 | intel_wait_for_vblank(dev, pipe); |
Line 5920... | Line 5092... | ||
5920 | } |
5092 | |
5921 | - | ||
5922 | I915_WRITE(DSPCNTR(plane), dspcntr); |
- | |
Line 5923... | Line 5093... | ||
5923 | POSTING_READ(DSPCNTR(plane)); |
5093 | /* Set up the display plane register */ |
Line 5924... | Line 5094... | ||
5924 | 5094 | I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE); |
|
Line 5925... | Line 5095... | ||
5925 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
5095 | POSTING_READ(DSPCNTR(plane)); |
5926 | 5096 | ||
Line 5927... | Line 5097... | ||
5927 | dbgprintf("Set base\n"); |
5097 | ret = intel_pipe_set_base(crtc, x, y, fb); |
5928 | 5098 | ||
5929 | intel_update_watermarks(dev); |
5099 | intel_update_watermarks(dev); |
5930 | 5100 | ||
5931 | LEAVE(); |
5101 | intel_update_linetime_watermarks(dev, pipe, adjusted_mode); |
5932 | 5102 | ||
5933 | return ret; |
5103 | return ret; |
5934 | } |
5104 | } |
5935 | 5105 | ||
5936 | static int intel_crtc_mode_set(struct drm_crtc *crtc, |
5106 | static int intel_crtc_mode_set(struct drm_crtc *crtc, |
5937 | struct drm_display_mode *mode, |
5107 | struct drm_display_mode *mode, |
Line 5938... | Line 5108... | ||
5938 | struct drm_display_mode *adjusted_mode, |
5108 | struct drm_display_mode *adjusted_mode, |
5939 | int x, int y, |
- | |
Line 5940... | Line 5109... | ||
5940 | struct drm_framebuffer *old_fb) |
5109 | int x, int y, |
5941 | { |
5110 | struct drm_framebuffer *fb) |
5942 | struct drm_device *dev = crtc->dev; |
- | |
5943 | struct drm_i915_private *dev_priv = dev->dev_private; |
5111 | { |
5944 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
5945 | int pipe = intel_crtc->pipe; |
- | |
5946 | int ret; |
- | |
Line 5947... | Line 5112... | ||
5947 | 5112 | struct drm_device *dev = crtc->dev; |
|
5948 | // drm_vblank_pre_modeset(dev, pipe); |
5113 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 5949... | Line 5114... | ||
5949 | ENTER(); |
5114 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
Line 6026... | Line 5191... | ||
6026 | i = I915_READ(G4X_AUD_CNTL_ST); |
5191 | i = I915_READ(G4X_AUD_CNTL_ST); |
6027 | i |= eldv; |
5192 | i |= eldv; |
6028 | I915_WRITE(G4X_AUD_CNTL_ST, i); |
5193 | I915_WRITE(G4X_AUD_CNTL_ST, i); |
6029 | } |
5194 | } |
Line -... | Line 5195... | ||
- | 5195 | ||
- | 5196 | static void haswell_write_eld(struct drm_connector *connector, |
|
- | 5197 | struct drm_crtc *crtc) |
|
- | 5198 | { |
|
- | 5199 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
|
- | 5200 | uint8_t *eld = connector->eld; |
|
- | 5201 | struct drm_device *dev = crtc->dev; |
|
- | 5202 | uint32_t eldv; |
|
- | 5203 | uint32_t i; |
|
- | 5204 | int len; |
|
- | 5205 | int pipe = to_intel_crtc(crtc)->pipe; |
|
- | 5206 | int tmp; |
|
- | 5207 | ||
- | 5208 | int hdmiw_hdmiedid = HSW_AUD_EDID_DATA(pipe); |
|
- | 5209 | int aud_cntl_st = HSW_AUD_DIP_ELD_CTRL(pipe); |
|
- | 5210 | int aud_config = HSW_AUD_CFG(pipe); |
|
- | 5211 | int aud_cntrl_st2 = HSW_AUD_PIN_ELD_CP_VLD; |
|
- | 5212 | ||
- | 5213 | ||
- | 5214 | DRM_DEBUG_DRIVER("HDMI: Haswell Audio initialize....\n"); |
|
- | 5215 | ||
- | 5216 | /* Audio output enable */ |
|
- | 5217 | DRM_DEBUG_DRIVER("HDMI audio: enable codec\n"); |
|
- | 5218 | tmp = I915_READ(aud_cntrl_st2); |
|
- | 5219 | tmp |= (AUDIO_OUTPUT_ENABLE_A << (pipe * 4)); |
|
- | 5220 | I915_WRITE(aud_cntrl_st2, tmp); |
|
- | 5221 | ||
- | 5222 | /* Wait for 1 vertical blank */ |
|
- | 5223 | intel_wait_for_vblank(dev, pipe); |
|
- | 5224 | ||
- | 5225 | /* Set ELD valid state */ |
|
- | 5226 | tmp = I915_READ(aud_cntrl_st2); |
|
- | 5227 | DRM_DEBUG_DRIVER("HDMI audio: pin eld vld status=0x%8x\n", tmp); |
|
- | 5228 | tmp |= (AUDIO_ELD_VALID_A << (pipe * 4)); |
|
- | 5229 | I915_WRITE(aud_cntrl_st2, tmp); |
|
- | 5230 | tmp = I915_READ(aud_cntrl_st2); |
|
- | 5231 | DRM_DEBUG_DRIVER("HDMI audio: eld vld status=0x%8x\n", tmp); |
|
- | 5232 | ||
- | 5233 | /* Enable HDMI mode */ |
|
- | 5234 | tmp = I915_READ(aud_config); |
|
- | 5235 | DRM_DEBUG_DRIVER("HDMI audio: audio conf: 0x%8x\n", tmp); |
|
- | 5236 | /* clear N_programing_enable and N_value_index */ |
|
- | 5237 | tmp &= ~(AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_N_PROG_ENABLE); |
|
- | 5238 | I915_WRITE(aud_config, tmp); |
|
- | 5239 | ||
- | 5240 | DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe)); |
|
- | 5241 | ||
- | 5242 | eldv = AUDIO_ELD_VALID_A << (pipe * 4); |
|
- | 5243 | ||
- | 5244 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { |
|
- | 5245 | DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); |
|
- | 5246 | eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ |
|
- | 5247 | I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ |
|
- | 5248 | } else |
|
- | 5249 | I915_WRITE(aud_config, 0); |
|
- | 5250 | ||
- | 5251 | if (intel_eld_uptodate(connector, |
|
- | 5252 | aud_cntrl_st2, eldv, |
|
- | 5253 | aud_cntl_st, IBX_ELD_ADDRESS, |
|
- | 5254 | hdmiw_hdmiedid)) |
|
- | 5255 | return; |
|
- | 5256 | ||
- | 5257 | i = I915_READ(aud_cntrl_st2); |
|
- | 5258 | i &= ~eldv; |
|
- | 5259 | I915_WRITE(aud_cntrl_st2, i); |
|
- | 5260 | ||
- | 5261 | if (!eld[0]) |
|
- | 5262 | return; |
|
- | 5263 | ||
- | 5264 | i = I915_READ(aud_cntl_st); |
|
- | 5265 | i &= ~IBX_ELD_ADDRESS; |
|
- | 5266 | I915_WRITE(aud_cntl_st, i); |
|
- | 5267 | i = (i >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */ |
|
- | 5268 | DRM_DEBUG_DRIVER("port num:%d\n", i); |
|
- | 5269 | ||
- | 5270 | len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */ |
|
- | 5271 | DRM_DEBUG_DRIVER("ELD size %d\n", len); |
|
- | 5272 | for (i = 0; i < len; i++) |
|
- | 5273 | I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i)); |
|
- | 5274 | ||
- | 5275 | i = I915_READ(aud_cntrl_st2); |
|
- | 5276 | i |= eldv; |
|
- | 5277 | I915_WRITE(aud_cntrl_st2, i); |
|
- | 5278 | ||
- | 5279 | } |
|
6030 | 5280 | ||
6031 | static void ironlake_write_eld(struct drm_connector *connector, |
5281 | static void ironlake_write_eld(struct drm_connector *connector, |
6032 | struct drm_crtc *crtc) |
5282 | struct drm_crtc *crtc) |
6033 | { |
5283 | { |
6034 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
5284 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
6035 | uint8_t *eld = connector->eld; |
5285 | uint8_t *eld = connector->eld; |
6036 | uint32_t eldv; |
5286 | uint32_t eldv; |
6037 | uint32_t i; |
5287 | uint32_t i; |
6038 | int len; |
5288 | int len; |
- | 5289 | int hdmiw_hdmiedid; |
|
6039 | int hdmiw_hdmiedid; |
5290 | int aud_config; |
6040 | int aud_cntl_st; |
5291 | int aud_cntl_st; |
- | 5292 | int aud_cntrl_st2; |
|
Line 6041... | Line 5293... | ||
6041 | int aud_cntrl_st2; |
5293 | int pipe = to_intel_crtc(crtc)->pipe; |
6042 | 5294 | ||
- | 5295 | if (HAS_PCH_IBX(connector->dev)) { |
|
6043 | if (HAS_PCH_IBX(connector->dev)) { |
5296 | hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe); |
6044 | hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID_A; |
5297 | aud_config = IBX_AUD_CFG(pipe); |
6045 | aud_cntl_st = IBX_AUD_CNTL_ST_A; |
5298 | aud_cntl_st = IBX_AUD_CNTL_ST(pipe); |
6046 | aud_cntrl_st2 = IBX_AUD_CNTL_ST2; |
5299 | aud_cntrl_st2 = IBX_AUD_CNTL_ST2; |
- | 5300 | } else { |
|
6047 | } else { |
5301 | hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID(pipe); |
6048 | hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID_A; |
5302 | aud_config = CPT_AUD_CFG(pipe); |
6049 | aud_cntl_st = CPT_AUD_CNTL_ST_A; |
5303 | aud_cntl_st = CPT_AUD_CNTL_ST(pipe); |
Line 6050... | Line -... | ||
6050 | aud_cntrl_st2 = CPT_AUD_CNTRL_ST2; |
- | |
6051 | } |
- | |
6052 | - | ||
6053 | i = to_intel_crtc(crtc)->pipe; |
- | |
6054 | hdmiw_hdmiedid += i * 0x100; |
5304 | aud_cntrl_st2 = CPT_AUD_CNTRL_ST2; |
Line 6055... | Line 5305... | ||
6055 | aud_cntl_st += i * 0x100; |
5305 | } |
6056 | 5306 | ||
6057 | DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(i)); |
5307 | DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(pipe)); |
6058 | 5308 | ||
6059 | i = I915_READ(aud_cntl_st); |
5309 | i = I915_READ(aud_cntl_st); |
6060 | i = (i >> 29) & 0x3; /* DIP_Port_Select, 0x1 = PortB */ |
5310 | i = (i >> 29) & DIP_PORT_SEL_MASK; /* DIP_Port_Select, 0x1 = PortB */ |
6061 | if (!i) { |
5311 | if (!i) { |
Line 6070... | Line 5320... | ||
6070 | } |
5320 | } |
Line 6071... | Line 5321... | ||
6071 | 5321 | ||
6072 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { |
5322 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { |
6073 | DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); |
5323 | DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); |
- | 5324 | eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ |
|
6074 | eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ |
5325 | I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ |
- | 5326 | } else |
|
Line 6075... | Line 5327... | ||
6075 | } |
5327 | I915_WRITE(aud_config, 0); |
6076 | 5328 | ||
6077 | if (intel_eld_uptodate(connector, |
5329 | if (intel_eld_uptodate(connector, |
6078 | aud_cntrl_st2, eldv, |
5330 | aud_cntrl_st2, eldv, |
Line 6133... | Line 5385... | ||
6133 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
5385 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
6134 | int palreg = PALETTE(intel_crtc->pipe); |
5386 | int palreg = PALETTE(intel_crtc->pipe); |
6135 | int i; |
5387 | int i; |
Line 6136... | Line 5388... | ||
6136 | 5388 | ||
6137 | /* The clocks have to be on to load the palette. */ |
5389 | /* The clocks have to be on to load the palette. */ |
6138 | if (!crtc->enabled) |
5390 | if (!crtc->enabled || !intel_crtc->active) |
Line 6139... | Line 5391... | ||
6139 | return; |
5391 | return; |
6140 | 5392 | ||
6141 | /* use legacy palette for Ironlake */ |
5393 | /* use legacy palette for Ironlake */ |
Line 6148... | Line 5400... | ||
6148 | (intel_crtc->lut_g[i] << 8) | |
5400 | (intel_crtc->lut_g[i] << 8) | |
6149 | intel_crtc->lut_b[i]); |
5401 | intel_crtc->lut_b[i]); |
6150 | } |
5402 | } |
6151 | } |
5403 | } |
Line -... | Line 5404... | ||
- | 5404 | ||
- | 5405 | #if 0 |
|
- | 5406 | static void i845_update_cursor(struct drm_crtc *crtc, u32 base) |
|
- | 5407 | { |
|
- | 5408 | struct drm_device *dev = crtc->dev; |
|
- | 5409 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 5410 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 5411 | bool visible = base != 0; |
|
Line -... | Line 5412... | ||
- | 5412 | u32 cntl; |
|
- | 5413 | ||
- | 5414 | if (intel_crtc->cursor_visible == visible) |
|
- | 5415 | return; |
|
- | 5416 | ||
- | 5417 | cntl = I915_READ(_CURACNTR); |
|
- | 5418 | if (visible) { |
|
- | 5419 | /* On these chipsets we can only modify the base whilst |
|
- | 5420 | * the cursor is disabled. |
|
Line -... | Line 5421... | ||
- | 5421 | */ |
|
- | 5422 | I915_WRITE(_CURABASE, base); |
|
- | 5423 | ||
- | 5424 | cntl &= ~(CURSOR_FORMAT_MASK); |
|
- | 5425 | /* XXX width must be 64, stride 256 => 0x00 << 28 */ |
|
- | 5426 | cntl |= CURSOR_ENABLE | |
|
- | 5427 | CURSOR_GAMMA_ENABLE | |
|
- | 5428 | CURSOR_FORMAT_ARGB; |
|
- | 5429 | } else |
|
- | 5430 | cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); |
|
- | 5431 | I915_WRITE(_CURACNTR, cntl); |
|
Line -... | Line 5432... | ||
- | 5432 | ||
- | 5433 | intel_crtc->cursor_visible = visible; |
|
- | 5434 | } |
|
- | 5435 | ||
- | 5436 | static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) |
|
- | 5437 | { |
|
- | 5438 | struct drm_device *dev = crtc->dev; |
|
Line -... | Line 5439... | ||
- | 5439 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 5440 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 5441 | int pipe = intel_crtc->pipe; |
|
- | 5442 | bool visible = base != 0; |
|
- | 5443 | ||
- | 5444 | if (intel_crtc->cursor_visible != visible) { |
|
- | 5445 | uint32_t cntl = I915_READ(CURCNTR(pipe)); |
|
- | 5446 | if (base) { |
|
- | 5447 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); |
|
- | 5448 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; |
|
- | 5449 | cntl |= pipe << 28; /* Connect to correct pipe */ |
|
Line -... | Line 5450... | ||
- | 5450 | } else { |
|
- | 5451 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); |
|
- | 5452 | cntl |= CURSOR_MODE_DISABLE; |
|
- | 5453 | } |
|
- | 5454 | I915_WRITE(CURCNTR(pipe), cntl); |
|
Line -... | Line 5455... | ||
- | 5455 | ||
- | 5456 | intel_crtc->cursor_visible = visible; |
|
- | 5457 | } |
|
- | 5458 | /* and commit changes on next vblank */ |
|
- | 5459 | I915_WRITE(CURBASE(pipe), base); |
|
- | 5460 | } |
|
- | 5461 | ||
Line -... | Line 5462... | ||
- | 5462 | static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) |
|
- | 5463 | { |
|
- | 5464 | struct drm_device *dev = crtc->dev; |
|
- | 5465 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 5466 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 5467 | int pipe = intel_crtc->pipe; |
|
- | 5468 | bool visible = base != 0; |
|
- | 5469 | ||
- | 5470 | if (intel_crtc->cursor_visible != visible) { |
|
- | 5471 | uint32_t cntl = I915_READ(CURCNTR_IVB(pipe)); |
|
Line -... | Line 5472... | ||
- | 5472 | if (base) { |
|
- | 5473 | cntl &= ~CURSOR_MODE; |
|
- | 5474 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; |
|
- | 5475 | } else { |
|
- | 5476 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); |
|
Line -... | Line 5477... | ||
- | 5477 | cntl |= CURSOR_MODE_DISABLE; |
|
- | 5478 | } |
|
- | 5479 | I915_WRITE(CURCNTR_IVB(pipe), cntl); |
|
- | 5480 | ||
- | 5481 | intel_crtc->cursor_visible = visible; |
|
- | 5482 | } |
|
- | 5483 | /* and commit changes on next vblank */ |
|
- | 5484 | I915_WRITE(CURBASE_IVB(pipe), base); |
|
- | 5485 | } |
|
- | 5486 | ||
- | 5487 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ |
|
- | 5488 | static void intel_crtc_update_cursor(struct drm_crtc *crtc, |
|
- | 5489 | bool on) |
|
- | 5490 | { |
|
- | 5491 | struct drm_device *dev = crtc->dev; |
|
- | 5492 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 5493 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 5494 | int pipe = intel_crtc->pipe; |
|
- | 5495 | int x = intel_crtc->cursor_x; |
|
Line -... | Line 5496... | ||
- | 5496 | int y = intel_crtc->cursor_y; |
|
- | 5497 | u32 base, pos; |
|
- | 5498 | bool visible; |
|
- | 5499 | ||
Line -... | Line 5500... | ||
- | 5500 | pos = 0; |
|
- | 5501 | ||
- | 5502 | if (on && crtc->enabled && crtc->fb) { |
|
Line -... | Line 5503... | ||
- | 5503 | base = intel_crtc->cursor_addr; |
|
- | 5504 | if (x > (int) crtc->fb->width) |
|
- | 5505 | base = 0; |
|
- | 5506 | ||
Line -... | Line 5507... | ||
- | 5507 | if (y > (int) crtc->fb->height) |
|
- | 5508 | base = 0; |
|
- | 5509 | } else |
|
Line -... | Line 5510... | ||
- | 5510 | base = 0; |
|
- | 5511 | ||
- | 5512 | if (x < 0) { |
|
- | 5513 | if (x + intel_crtc->cursor_width < 0) |
|
Line -... | Line 5514... | ||
- | 5514 | base = 0; |
|
- | 5515 | ||
- | 5516 | pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; |
|
Line -... | Line 5517... | ||
- | 5517 | x = -x; |
|
- | 5518 | } |
|
- | 5519 | pos |= x << CURSOR_X_SHIFT; |
|
- | 5520 | ||
- | 5521 | if (y < 0) { |
|
- | 5522 | if (y + intel_crtc->cursor_height < 0) |
|
- | 5523 | base = 0; |
|
- | 5524 | ||
- | 5525 | pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; |
|
- | 5526 | y = -y; |
|
- | 5527 | } |
|
Line -... | Line 5528... | ||
- | 5528 | pos |= y << CURSOR_Y_SHIFT; |
|
- | 5529 | ||
- | 5530 | visible = base != 0; |
|
- | 5531 | if (!visible && !intel_crtc->cursor_visible) |
|
- | 5532 | return; |
|
- | 5533 | ||
- | 5534 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { |
|
- | 5535 | I915_WRITE(CURPOS_IVB(pipe), pos); |
|
- | 5536 | ivb_update_cursor(crtc, base); |
|
- | 5537 | } else { |
|
- | 5538 | I915_WRITE(CURPOS(pipe), pos); |
|
Line -... | Line 5539... | ||
- | 5539 | if (IS_845G(dev) || IS_I865G(dev)) |
|
- | 5540 | i845_update_cursor(crtc, base); |
|
- | 5541 | else |
|
- | 5542 | i9xx_update_cursor(crtc, base); |
|
- | 5543 | } |
|
- | 5544 | } |
|
- | 5545 | ||
- | 5546 | static int intel_crtc_cursor_set(struct drm_crtc *crtc, |
|
Line -... | Line 5547... | ||
- | 5547 | struct drm_file *file, |
|
- | 5548 | uint32_t handle, |
|
- | 5549 | uint32_t width, uint32_t height) |
|
- | 5550 | { |
|
- | 5551 | struct drm_device *dev = crtc->dev; |
|
Line -... | Line 5552... | ||
- | 5552 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 5553 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 5554 | struct drm_i915_gem_object *obj; |
|
Line -... | Line 5555... | ||
- | 5555 | uint32_t addr; |
|
- | 5556 | int ret; |
|
- | 5557 | ||
- | 5558 | /* if we want to turn off the cursor ignore width and height */ |
|
- | 5559 | if (!handle) { |
|
Line -... | Line 5560... | ||
- | 5560 | DRM_DEBUG_KMS("cursor off\n"); |
|
- | 5561 | addr = 0; |
|
- | 5562 | obj = NULL; |
|
- | 5563 | mutex_lock(&dev->struct_mutex); |
|
- | 5564 | goto finish; |
|
- | 5565 | } |
|
- | 5566 | ||
- | 5567 | /* Currently we only support 64x64 cursors */ |
|
Line -... | Line 5568... | ||
- | 5568 | if (width != 64 || height != 64) { |
|
- | 5569 | DRM_ERROR("we currently only support 64x64 cursors\n"); |
|
- | 5570 | return -EINVAL; |
|
- | 5571 | } |
|
- | 5572 | ||
Line -... | Line 5573... | ||
- | 5573 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle)); |
|
- | 5574 | if (&obj->base == NULL) |
|
- | 5575 | return -ENOENT; |
|
- | 5576 | ||
- | 5577 | if (obj->base.size < width * height * 4) { |
|
Line -... | Line 5578... | ||
- | 5578 | DRM_ERROR("buffer is to small\n"); |
|
- | 5579 | ret = -ENOMEM; |
|
- | 5580 | goto fail; |
|
- | 5581 | } |
|
- | 5582 | ||
- | 5583 | /* we only need to pin inside GTT if cursor is non-phy */ |
|
- | 5584 | mutex_lock(&dev->struct_mutex); |
|
- | 5585 | if (!dev_priv->info->cursor_needs_physical) { |
|
- | 5586 | if (obj->tiling_mode) { |
|
- | 5587 | DRM_ERROR("cursor cannot be tiled\n"); |
|
- | 5588 | ret = -EINVAL; |
|
- | 5589 | goto fail_locked; |
|
Line -... | Line 5590... | ||
- | 5590 | } |
|
- | 5591 | ||
Line -... | Line 5592... | ||
- | 5592 | ret = i915_gem_object_pin_to_display_plane(obj, 0, NULL); |
|
- | 5593 | if (ret) { |
|
- | 5594 | DRM_ERROR("failed to move cursor bo into the GTT\n"); |
|
- | 5595 | goto fail_locked; |
|
- | 5596 | } |
|
- | 5597 | ||
- | 5598 | ret = i915_gem_object_put_fence(obj); |
|
- | 5599 | if (ret) { |
|
- | 5600 | DRM_ERROR("failed to release fence for cursor"); |
|
Line -... | Line 5601... | ||
- | 5601 | goto fail_unpin; |
|
Line -... | Line 5602... | ||
- | 5602 | } |
|
- | 5603 | ||
- | 5604 | addr = obj->gtt_offset; |
|
- | 5605 | } else { |
|
Line -... | Line 5606... | ||
- | 5606 | int align = IS_I830(dev) ? 16 * 1024 : 256; |
|
Line -... | Line 5607... | ||
- | 5607 | ret = i915_gem_attach_phys_object(dev, obj, |
|
- | 5608 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1, |
|
- | 5609 | align); |
|
- | 5610 | if (ret) { |
|
- | 5611 | DRM_ERROR("failed to attach phys object\n"); |
|
- | 5612 | goto fail_locked; |
|
- | 5613 | } |
|
- | 5614 | addr = obj->phys_obj->handle->busaddr; |
|
- | 5615 | } |
|
Line -... | Line 5616... | ||
- | 5616 | ||
- | 5617 | if (IS_GEN2(dev)) |
|
- | 5618 | I915_WRITE(CURSIZE, (height << 12) | width); |
|
Line -... | Line 5619... | ||
- | 5619 | ||
- | 5620 | finish: |
|
Line -... | Line 5621... | ||
- | 5621 | if (intel_crtc->cursor_bo) { |
|
Line -... | Line 5622... | ||
- | 5622 | if (dev_priv->info->cursor_needs_physical) { |
|
- | 5623 | if (intel_crtc->cursor_bo != obj) |
|
- | 5624 | i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); |
|
Line 6152... | Line 5625... | ||
6152 | 5625 | } else |
|
6153 | 5626 | i915_gem_object_unpin(intel_crtc->cursor_bo); |
|
6154 | 5627 | drm_gem_object_unreference(&intel_crtc->cursor_bo->base); |
|
6155 | 5628 | } |
|
Line 6240... | Line 5713... | ||
6240 | static struct drm_display_mode load_detect_mode = { |
5713 | static struct drm_display_mode load_detect_mode = { |
6241 | DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664, |
5714 | DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664, |
6242 | 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), |
5715 | 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), |
6243 | }; |
5716 | }; |
Line -... | Line 5717... | ||
- | 5717 | ||
- | 5718 | static struct drm_framebuffer * |
|
- | 5719 | intel_framebuffer_create(struct drm_device *dev, |
|
- | 5720 | struct drm_mode_fb_cmd2 *mode_cmd, |
|
- | 5721 | struct drm_i915_gem_object *obj) |
|
- | 5722 | { |
|
- | 5723 | struct intel_framebuffer *intel_fb; |
|
Line -... | Line 5724... | ||
- | 5724 | int ret; |
|
- | 5725 | ||
- | 5726 | intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); |
|
- | 5727 | if (!intel_fb) { |
|
- | 5728 | drm_gem_object_unreference_unlocked(&obj->base); |
|
Line -... | Line 5729... | ||
- | 5729 | return ERR_PTR(-ENOMEM); |
|
- | 5730 | } |
|
- | 5731 | ||
- | 5732 | ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); |
|
- | 5733 | if (ret) { |
|
- | 5734 | drm_gem_object_unreference_unlocked(&obj->base); |
|
Line -... | Line 5735... | ||
- | 5735 | kfree(intel_fb); |
|
- | 5736 | return ERR_PTR(ret); |
|
Line 6244... | Line 5737... | ||
6244 | 5737 | } |
|
6245 | 5738 | ||
6246 | 5739 | return &intel_fb->base; |
|
6247 | 5740 | } |
|
Line 6293... | Line 5786... | ||
6293 | // if (dev_priv->fbdev == NULL) |
5786 | // if (dev_priv->fbdev == NULL) |
6294 | // return NULL; |
5787 | // return NULL; |
Line 6295... | Line 5788... | ||
6295 | 5788 | ||
6296 | // obj = dev_priv->fbdev->ifb.obj; |
5789 | // obj = dev_priv->fbdev->ifb.obj; |
6297 | // if (obj == NULL) |
- | |
6298 | // return NULL; |
- | |
6299 | - | ||
6300 | // fb = &dev_priv->fbdev->ifb.base; |
- | |
6301 | // if (fb->pitch < intel_framebuffer_pitch_for_width(mode->hdisplay, |
- | |
6302 | // fb->bits_per_pixel)) |
5790 | // if (obj == NULL) |
Line 6303... | Line 5791... | ||
6303 | return NULL; |
5791 | return NULL; |
- | 5792 | ||
- | 5793 | // if (obj->base.size < mode->vdisplay * fb->pitch) |
|
6304 | 5794 | if (fb->pitches[0] < intel_framebuffer_pitch_for_width(mode->hdisplay, |
|
Line -... | Line 5795... | ||
- | 5795 | fb->bits_per_pixel)) |
|
- | 5796 | // return NULL; |
|
- | 5797 | ||
6305 | // if (obj->base.size < mode->vdisplay * fb->pitch) |
5798 | if (obj->base.size < mode->vdisplay * fb->pitches[0]) |
6306 | // return NULL; |
5799 | return NULL; |
Line 6307... | Line 5800... | ||
6307 | 5800 | ||
6308 | // return fb; |
- | |
6309 | } |
5801 | // return fb; |
6310 | 5802 | } |
|
6311 | bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, |
5803 | |
6312 | struct drm_connector *connector, |
5804 | bool intel_get_load_detect_pipe(struct drm_connector *connector, |
- | 5805 | struct drm_display_mode *mode, |
|
- | 5806 | struct intel_load_detect_pipe *old) |
|
6313 | struct drm_display_mode *mode, |
5807 | { |
6314 | struct intel_load_detect_pipe *old) |
5808 | struct intel_crtc *intel_crtc; |
6315 | { |
5809 | struct intel_encoder *intel_encoder = |
6316 | struct intel_crtc *intel_crtc; |
5810 | intel_attached_encoder(connector); |
6317 | struct drm_crtc *possible_crtc; |
5811 | struct drm_crtc *possible_crtc; |
6318 | struct drm_encoder *encoder = &intel_encoder->base; |
5812 | struct drm_encoder *encoder = &intel_encoder->base; |
Line 6319... | Line 5813... | ||
6319 | struct drm_crtc *crtc = NULL; |
5813 | struct drm_crtc *crtc = NULL; |
6320 | struct drm_device *dev = encoder->dev; |
5814 | struct drm_device *dev = encoder->dev; |
6321 | struct drm_framebuffer *old_fb; |
5815 | struct drm_framebuffer *fb; |
Line 6337... | Line 5831... | ||
6337 | 5831 | ||
6338 | /* See if we already have a CRTC for this connector */ |
5832 | /* See if we already have a CRTC for this connector */ |
6339 | if (encoder->crtc) { |
5833 | if (encoder->crtc) { |
Line 6340... | Line -... | ||
6340 | crtc = encoder->crtc; |
- | |
6341 | 5834 | crtc = encoder->crtc; |
|
6342 | intel_crtc = to_intel_crtc(crtc); |
5835 | |
Line 6343... | Line 5836... | ||
6343 | old->dpms_mode = intel_crtc->dpms_mode; |
5836 | old->dpms_mode = connector->dpms; |
6344 | old->load_detect_temp = false; |
5837 | old->load_detect_temp = false; |
6345 | - | ||
6346 | /* Make sure the crtc and connector are running */ |
- | |
6347 | if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) { |
- | |
6348 | struct drm_encoder_helper_funcs *encoder_funcs; |
- | |
6349 | struct drm_crtc_helper_funcs *crtc_funcs; |
- | |
6350 | - | ||
6351 | crtc_funcs = crtc->helper_private; |
- | |
6352 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); |
5838 | |
6353 | - | ||
Line 6354... | Line 5839... | ||
6354 | encoder_funcs = encoder->helper_private; |
5839 | /* Make sure the crtc and connector are running */ |
6355 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); |
5840 | if (connector->dpms != DRM_MODE_DPMS_ON) |
Line 6356... | Line 5841... | ||
6356 | } |
5841 | connector->funcs->dpms(connector, DRM_MODE_DPMS_ON); |
Line 6375... | Line 5860... | ||
6375 | if (!crtc) { |
5860 | if (!crtc) { |
6376 | DRM_DEBUG_KMS("no pipe available for load-detect\n"); |
5861 | DRM_DEBUG_KMS("no pipe available for load-detect\n"); |
6377 | return false; |
5862 | return false; |
6378 | } |
5863 | } |
Line 6379... | Line 5864... | ||
6379 | 5864 | ||
6380 | encoder->crtc = crtc; |
5865 | intel_encoder->new_crtc = to_intel_crtc(crtc); |
Line 6381... | Line 5866... | ||
6381 | connector->encoder = encoder; |
5866 | to_intel_connector(connector)->new_encoder = intel_encoder; |
6382 | 5867 | ||
6383 | intel_crtc = to_intel_crtc(crtc); |
5868 | intel_crtc = to_intel_crtc(crtc); |
6384 | old->dpms_mode = intel_crtc->dpms_mode; |
5869 | old->dpms_mode = connector->dpms; |
Line 6385... | Line 5870... | ||
6385 | old->load_detect_temp = true; |
5870 | old->load_detect_temp = true; |
6386 | old->release_fb = NULL; |
5871 | old->release_fb = NULL; |
Line 6387... | Line -... | ||
6387 | - | ||
6388 | if (!mode) |
- | |
6389 | mode = &load_detect_mode; |
5872 | |
6390 | 5873 | if (!mode) |
|
6391 | old_fb = crtc->fb; |
5874 | mode = &load_detect_mode; |
6392 | 5875 | ||
6393 | /* We need a framebuffer large enough to accommodate all accesses |
5876 | /* We need a framebuffer large enough to accommodate all accesses |
6394 | * that the plane may generate whilst we perform load detection. |
5877 | * that the plane may generate whilst we perform load detection. |
6395 | * We can not rely on the fbcon either being present (we get called |
5878 | * We can not rely on the fbcon either being present (we get called |
6396 | * during its initialisation to detect all boot displays, or it may |
5879 | * during its initialisation to detect all boot displays, or it may |
6397 | * not even exist) or that it is large enough to satisfy the |
5880 | * not even exist) or that it is large enough to satisfy the |
6398 | * requested mode. |
5881 | * requested mode. |
6399 | */ |
5882 | */ |
6400 | crtc->fb = mode_fits_in_fbdev(dev, mode); |
5883 | fb = mode_fits_in_fbdev(dev, mode); |
6401 | if (crtc->fb == NULL) { |
5884 | if (fb == NULL) { |
6402 | DRM_DEBUG_KMS("creating tmp fb for load-detection\n"); |
5885 | DRM_DEBUG_KMS("creating tmp fb for load-detection\n"); |
6403 | crtc->fb = intel_framebuffer_create_for_mode(dev, mode, 24, 32); |
5886 | fb = intel_framebuffer_create_for_mode(dev, mode, 24, 32); |
6404 | old->release_fb = crtc->fb; |
5887 | old->release_fb = fb; |
6405 | } else |
- | |
6406 | DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n"); |
5888 | } else |
6407 | if (IS_ERR(crtc->fb)) { |
5889 | DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n"); |
Line 6408... | Line 5890... | ||
6408 | DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n"); |
5890 | if (IS_ERR(fb)) { |
6409 | crtc->fb = old_fb; |
5891 | DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n"); |
6410 | return false; |
5892 | goto fail; |
6411 | } |
5893 | } |
6412 | - | ||
6413 | if (!drm_crtc_helper_set_mode(crtc, mode, 0, 0, old_fb)) { |
5894 | |
6414 | DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n"); |
5895 | if (!intel_set_mode(crtc, mode, 0, 0, fb)) { |
Line 6415... | Line 5896... | ||
6415 | if (old->release_fb) |
5896 | DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n"); |
6416 | old->release_fb->funcs->destroy(old->release_fb); |
5897 | if (old->release_fb) |
Line 6417... | Line 5898... | ||
6417 | crtc->fb = old_fb; |
5898 | old->release_fb->funcs->destroy(old->release_fb); |
- | 5899 | goto fail; |
|
- | 5900 | } |
|
- | 5901 | ||
- | 5902 | /* let the connector get through one full cycle before testing */ |
|
6418 | return false; |
5903 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
Line 6419... | Line 5904... | ||
6419 | } |
5904 | |
6420 | - | ||
6421 | /* let the connector get through one full cycle before testing */ |
5905 | return true; |
6422 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
5906 | fail: |
- | 5907 | connector->encoder = NULL; |
|
- | 5908 | encoder->crtc = NULL; |
|
6423 | 5909 | return false; |
|
6424 | return true; |
- | |
6425 | } |
- | |
6426 | - | ||
6427 | void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, |
- | |
Line 6428... | Line 5910... | ||
6428 | struct drm_connector *connector, |
5910 | } |
6429 | struct intel_load_detect_pipe *old) |
5911 | |
6430 | { |
5912 | void intel_release_load_detect_pipe(struct drm_connector *connector, |
Line 6431... | Line 5913... | ||
6431 | struct drm_encoder *encoder = &intel_encoder->base; |
5913 | struct intel_load_detect_pipe *old) |
- | 5914 | { |
|
- | 5915 | struct intel_encoder *intel_encoder = |
|
- | 5916 | intel_attached_encoder(connector); |
|
6432 | struct drm_device *dev = encoder->dev; |
5917 | struct drm_encoder *encoder = &intel_encoder->base; |
6433 | struct drm_crtc *crtc = encoder->crtc; |
5918 | |
Line 6434... | Line 5919... | ||
6434 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; |
5919 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", |
6435 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; |
5920 | connector->base.id, drm_get_connector_name(connector), |
Line 6436... | Line 5921... | ||
6436 | 5921 | encoder->base.id, drm_get_encoder_name(encoder)); |
|
6437 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", |
5922 | |
Line 6438... | Line 5923... | ||
6438 | connector->base.id, drm_get_connector_name(connector), |
5923 | if (old->load_detect_temp) { |
6439 | encoder->base.id, drm_get_encoder_name(encoder)); |
5924 | struct drm_crtc *crtc = encoder->crtc; |
6440 | 5925 | ||
6441 | if (old->load_detect_temp) { |
- | |
6442 | connector->encoder = NULL; |
- | |
6443 | drm_helper_disable_unused_functions(dev); |
5926 | to_intel_connector(connector)->new_encoder = NULL; |
Line 6444... | Line 5927... | ||
6444 | 5927 | intel_encoder->new_crtc = NULL; |
|
6445 | if (old->release_fb) |
5928 | intel_set_mode(crtc, NULL, 0, 0, NULL); |
6446 | old->release_fb->funcs->destroy(old->release_fb); |
5929 | |
Line 6568... | Line 6051... | ||
6568 | mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1; |
6051 | mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1; |
6569 | mode->vsync_start = (vsync & 0xffff) + 1; |
6052 | mode->vsync_start = (vsync & 0xffff) + 1; |
6570 | mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1; |
6053 | mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1; |
Line 6571... | Line 6054... | ||
6571 | 6054 | ||
6572 | drm_mode_set_name(mode); |
- | |
Line 6573... | Line 6055... | ||
6573 | drm_mode_set_crtcinfo(mode, 0); |
6055 | drm_mode_set_name(mode); |
6574 | 6056 | ||
Line 6575... | Line -... | ||
6575 | return mode; |
- | |
6576 | } |
- | |
6577 | - | ||
6578 | #define GPU_IDLE_TIMEOUT 500 /* ms */ |
- | |
6579 | - | ||
6580 | - | ||
6581 | - | ||
6582 | - | ||
6583 | #define CRTC_IDLE_TIMEOUT 1000 /* ms */ |
- | |
6584 | - | ||
6585 | 6057 | return mode; |
|
6586 | 6058 | } |
|
6587 | 6059 | ||
6588 | static void intel_increase_pllclock(struct drm_crtc *crtc) |
6060 | static void intel_increase_pllclock(struct drm_crtc *crtc) |
6589 | { |
6061 | { |
6590 | struct drm_device *dev = crtc->dev; |
6062 | struct drm_device *dev = crtc->dev; |
6591 | drm_i915_private_t *dev_priv = dev->dev_private; |
6063 | drm_i915_private_t *dev_priv = dev->dev_private; |
6592 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
6064 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
Line 6593... | Line -... | ||
6593 | int pipe = intel_crtc->pipe; |
- | |
6594 | int dpll_reg = DPLL(pipe); |
- | |
6595 | int dpll; |
6065 | int pipe = intel_crtc->pipe; |
6596 | 6066 | int dpll_reg = DPLL(pipe); |
|
Line 6597... | Line 6067... | ||
6597 | ENTER(); |
6067 | int dpll; |
6598 | 6068 | ||
Line 6599... | Line 6069... | ||
6599 | if (HAS_PCH_SPLIT(dev)) |
6069 | if (HAS_PCH_SPLIT(dev)) |
6600 | return; |
6070 | return; |
6601 | 6071 | ||
Line 6602... | Line 6072... | ||
6602 | if (!dev_priv->lvds_downclock_avail) |
6072 | if (!dev_priv->lvds_downclock_avail) |
6603 | return; |
- | |
6604 | - | ||
Line 6605... | Line 6073... | ||
6605 | dpll = I915_READ(dpll_reg); |
6073 | return; |
6606 | if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) { |
6074 | |
6607 | DRM_DEBUG_DRIVER("upclocking LVDS\n"); |
6075 | dpll = I915_READ(dpll_reg); |
Line 6608... | Line 6076... | ||
6608 | 6076 | if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) { |
|
6609 | /* Unlock panel regs */ |
6077 | DRM_DEBUG_DRIVER("upclocking LVDS\n"); |
6610 | I915_WRITE(PP_CONTROL, |
6078 | |
6611 | I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); |
- | |
6612 | - | ||
6613 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; |
- | |
6614 | I915_WRITE(dpll_reg, dpll); |
6079 | assert_panel_unlocked(dev_priv, pipe); |
6615 | intel_wait_for_vblank(dev, pipe); |
- | |
6616 | - | ||
6617 | dpll = I915_READ(dpll_reg); |
- | |
6618 | if (dpll & DISPLAY_RATE_SELECT_FPA1) |
- | |
6619 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); |
6080 | |
Line -... | Line 6081... | ||
- | 6081 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; |
|
- | 6082 | I915_WRITE(dpll_reg, dpll); |
|
- | 6083 | intel_wait_for_vblank(dev, pipe); |
|
- | 6084 | ||
- | 6085 | dpll = I915_READ(dpll_reg); |
|
Line -... | Line 6086... | ||
- | 6086 | if (dpll & DISPLAY_RATE_SELECT_FPA1) |
|
- | 6087 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); |
|
Line -... | Line 6088... | ||
- | 6088 | } |
|
- | 6089 | } |
|
Line -... | Line 6090... | ||
- | 6090 | ||
- | 6091 | static void intel_decrease_pllclock(struct drm_crtc *crtc) |
|
- | 6092 | { |
|
- | 6093 | struct drm_device *dev = crtc->dev; |
|
- | 6094 | drm_i915_private_t *dev_priv = dev->dev_private; |
|
- | 6095 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 6096 | ||
- | 6097 | if (HAS_PCH_SPLIT(dev)) |
|
Line -... | Line 6098... | ||
- | 6098 | return; |
|
Line -... | Line 6099... | ||
- | 6099 | ||
Line -... | Line 6100... | ||
- | 6100 | if (!dev_priv->lvds_downclock_avail) |
|
- | 6101 | return; |
|
- | 6102 | ||
- | 6103 | /* |
|
- | 6104 | * Since this is called by a timer, we should never get here in |
|
- | 6105 | * the manual case. |
|
- | 6106 | */ |
|
- | 6107 | if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { |
|
Line -... | Line 6108... | ||
- | 6108 | int pipe = intel_crtc->pipe; |
|
Line -... | Line 6109... | ||
- | 6109 | int dpll_reg = DPLL(pipe); |
|
- | 6110 | int dpll; |
|
- | 6111 | ||
- | 6112 | DRM_DEBUG_DRIVER("downclocking LVDS\n"); |
|
Line -... | Line 6113... | ||
- | 6113 | ||
- | 6114 | assert_panel_unlocked(dev_priv, pipe); |
|
- | 6115 | ||
Line -... | Line 6116... | ||
- | 6116 | dpll = I915_READ(dpll_reg); |
|
- | 6117 | dpll |= DISPLAY_RATE_SELECT_FPA1; |
|
- | 6118 | I915_WRITE(dpll_reg, dpll); |
|
- | 6119 | intel_wait_for_vblank(dev, pipe); |
|
Line -... | Line 6120... | ||
- | 6120 | dpll = I915_READ(dpll_reg); |
|
- | 6121 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) |
|
Line -... | Line 6122... | ||
- | 6122 | DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); |
|
- | 6123 | } |
|
- | 6124 | ||
Line -... | Line 6125... | ||
- | 6125 | } |
|
- | 6126 | ||
- | 6127 | void intel_mark_busy(struct drm_device *dev) |
|
- | 6128 | { |
|
Line -... | Line 6129... | ||
- | 6129 | i915_update_gfx_val(dev->dev_private); |
|
- | 6130 | } |
|
- | 6131 | ||
- | 6132 | void intel_mark_idle(struct drm_device *dev) |
|
Line -... | Line 6133... | ||
- | 6133 | { |
|
- | 6134 | } |
|
Line -... | Line 6135... | ||
- | 6135 | ||
- | 6136 | void intel_mark_fb_busy(struct drm_i915_gem_object *obj) |
|
- | 6137 | { |
|
Line 6620... | Line -... | ||
6620 | - | ||
- | 6138 | struct drm_device *dev = obj->base.dev; |
|
- | 6139 | struct drm_crtc *crtc; |
|
6621 | /* ...and lock them again */ |
6140 | |
6622 | I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3); |
6141 | if (!i915_powersave) |
Line 6623... | Line 6142... | ||
6623 | } |
6142 | return; |
6624 | 6143 | ||
6625 | LEAVE(); |
6144 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
6626 | 6145 | if (!crtc->fb) |
|
Line 6668... | Line 6187... | ||
6668 | drm_crtc_cleanup(crtc); |
6187 | drm_crtc_cleanup(crtc); |
Line 6669... | Line 6188... | ||
6669 | 6188 | ||
6670 | kfree(intel_crtc); |
6189 | kfree(intel_crtc); |
Line -... | Line 6190... | ||
- | 6190 | } |
|
- | 6191 | ||
- | 6192 | #if 0 |
|
- | 6193 | static void intel_unpin_work_fn(struct work_struct *__work) |
|
- | 6194 | { |
|
Line -... | Line 6195... | ||
- | 6195 | struct intel_unpin_work *work = |
|
- | 6196 | container_of(__work, struct intel_unpin_work, work); |
|
- | 6197 | ||
- | 6198 | mutex_lock(&work->dev->struct_mutex); |
|
Line -... | Line 6199... | ||
- | 6199 | intel_unpin_fb_obj(work->old_fb_obj); |
|
- | 6200 | drm_gem_object_unreference(&work->pending_flip_obj->base); |
|
- | 6201 | drm_gem_object_unreference(&work->old_fb_obj->base); |
|
- | 6202 | ||
Line -... | Line 6203... | ||
- | 6203 | intel_update_fbc(work->dev); |
|
- | 6204 | mutex_unlock(&work->dev->struct_mutex); |
|
- | 6205 | kfree(work); |
|
- | 6206 | } |
|
- | 6207 | ||
- | 6208 | static void do_intel_finish_page_flip(struct drm_device *dev, |
|
- | 6209 | struct drm_crtc *crtc) |
|
- | 6210 | { |
|
- | 6211 | drm_i915_private_t *dev_priv = dev->dev_private; |
|
- | 6212 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
Line -... | Line 6213... | ||
- | 6213 | struct intel_unpin_work *work; |
|
- | 6214 | struct drm_i915_gem_object *obj; |
|
- | 6215 | struct drm_pending_vblank_event *e; |
|
Line -... | Line 6216... | ||
- | 6216 | struct timeval tvbl; |
|
- | 6217 | unsigned long flags; |
|
- | 6218 | ||
- | 6219 | /* Ignore early vblank irqs */ |
|
- | 6220 | if (intel_crtc == NULL) |
|
- | 6221 | return; |
|
Line -... | Line 6222... | ||
- | 6222 | ||
Line -... | Line 6223... | ||
- | 6223 | spin_lock_irqsave(&dev->event_lock, flags); |
|
- | 6224 | work = intel_crtc->unpin_work; |
|
- | 6225 | if (work == NULL || !work->pending) { |
|
Line -... | Line 6226... | ||
- | 6226 | spin_unlock_irqrestore(&dev->event_lock, flags); |
|
- | 6227 | return; |
|
Line -... | Line 6228... | ||
- | 6228 | } |
|
- | 6229 | ||
- | 6230 | intel_crtc->unpin_work = NULL; |
|
- | 6231 | ||
Line -... | Line 6232... | ||
- | 6232 | if (work->event) { |
|
Line -... | Line 6233... | ||
- | 6233 | e = work->event; |
|
Line -... | Line 6234... | ||
- | 6234 | e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &tvbl); |
|
Line -... | Line 6235... | ||
- | 6235 | ||
- | 6236 | e->event.tv_sec = tvbl.tv_sec; |
|
Line -... | Line 6237... | ||
- | 6237 | e->event.tv_usec = tvbl.tv_usec; |
|
- | 6238 | ||
Line -... | Line 6239... | ||
- | 6239 | list_add_tail(&e->base.link, |
|
- | 6240 | &e->base.file_priv->event_list); |
|
Line -... | Line 6241... | ||
- | 6241 | wake_up_interruptible(&e->base.file_priv->event_wait); |
|
- | 6242 | } |
|
- | 6243 | ||
- | 6244 | drm_vblank_put(dev, intel_crtc->pipe); |
|
Line -... | Line 6245... | ||
- | 6245 | ||
- | 6246 | spin_unlock_irqrestore(&dev->event_lock, flags); |
|
Line -... | Line 6247... | ||
- | 6247 | ||
- | 6248 | obj = work->old_fb_obj; |
|
- | 6249 | ||
- | 6250 | atomic_clear_mask(1 << intel_crtc->plane, |
|
Line -... | Line 6251... | ||
- | 6251 | &obj->pending_flip.counter); |
|
- | 6252 | ||
Line -... | Line 6253... | ||
- | 6253 | wake_up(&dev_priv->pending_flip_queue); |
|
- | 6254 | schedule_work(&work->work); |
|
- | 6255 | ||
- | 6256 | trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj); |
|
- | 6257 | } |
|
- | 6258 | ||
Line -... | Line 6259... | ||
- | 6259 | void intel_finish_page_flip(struct drm_device *dev, int pipe) |
|
- | 6260 | { |
|
- | 6261 | drm_i915_private_t *dev_priv = dev->dev_private; |
|
- | 6262 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
|
- | 6263 | ||
- | 6264 | do_intel_finish_page_flip(dev, crtc); |
|
- | 6265 | } |
|
- | 6266 | ||
- | 6267 | void intel_finish_page_flip_plane(struct drm_device *dev, int plane) |
|
Line -... | Line 6268... | ||
- | 6268 | { |
|
- | 6269 | drm_i915_private_t *dev_priv = dev->dev_private; |
|
- | 6270 | struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane]; |
|
- | 6271 | ||
- | 6272 | do_intel_finish_page_flip(dev, crtc); |
|
- | 6273 | } |
|
- | 6274 | ||
- | 6275 | void intel_prepare_page_flip(struct drm_device *dev, int plane) |
|
- | 6276 | { |
|
- | 6277 | drm_i915_private_t *dev_priv = dev->dev_private; |
|
Line -... | Line 6278... | ||
- | 6278 | struct intel_crtc *intel_crtc = |
|
- | 6279 | to_intel_crtc(dev_priv->plane_to_crtc_mapping[plane]); |
|
- | 6280 | unsigned long flags; |
|
Line -... | Line 6281... | ||
- | 6281 | ||
- | 6282 | spin_lock_irqsave(&dev->event_lock, flags); |
|
- | 6283 | if (intel_crtc->unpin_work) { |
|
Line -... | Line 6284... | ||
- | 6284 | if ((++intel_crtc->unpin_work->pending) > 1) |
|
- | 6285 | DRM_ERROR("Prepared flip multiple times\n"); |
|
- | 6286 | } else { |
|
- | 6287 | DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n"); |
|
- | 6288 | } |
|
- | 6289 | spin_unlock_irqrestore(&dev->event_lock, flags); |
|
- | 6290 | } |
|
- | 6291 | ||
- | 6292 | static int intel_gen2_queue_flip(struct drm_device *dev, |
|
- | 6293 | struct drm_crtc *crtc, |
|
- | 6294 | struct drm_framebuffer *fb, |
|
- | 6295 | struct drm_i915_gem_object *obj) |
|
- | 6296 | { |
|
- | 6297 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 6298 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 6299 | u32 flip_mask; |
|
Line -... | Line 6300... | ||
- | 6300 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
|
- | 6301 | int ret; |
|
- | 6302 | ||
- | 6303 | ret = intel_pin_and_fence_fb_obj(dev, obj, ring); |
|
- | 6304 | if (ret) |
|
Line -... | Line 6305... | ||
- | 6305 | goto err; |
|
- | 6306 | ||
- | 6307 | ret = intel_ring_begin(ring, 6); |
|
- | 6308 | if (ret) |
|
- | 6309 | goto err_unpin; |
|
- | 6310 | ||
- | 6311 | /* Can't queue multiple flips, so wait for the previous |
|
- | 6312 | * one to finish before executing the next. |
|
- | 6313 | */ |
|
- | 6314 | if (intel_crtc->plane) |
|
Line -... | Line 6315... | ||
- | 6315 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; |
|
- | 6316 | else |
|
- | 6317 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; |
|
Line -... | Line 6318... | ||
- | 6318 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); |
|
- | 6319 | intel_ring_emit(ring, MI_NOOP); |
|
- | 6320 | intel_ring_emit(ring, MI_DISPLAY_FLIP | |
|
Line -... | Line 6321... | ||
- | 6321 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
|
- | 6322 | intel_ring_emit(ring, fb->pitches[0]); |
|
- | 6323 | intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset); |
|
- | 6324 | intel_ring_emit(ring, 0); /* aux display base address, unused */ |
|
- | 6325 | intel_ring_advance(ring); |
|
- | 6326 | return 0; |
|
- | 6327 | ||
- | 6328 | err_unpin: |
|
- | 6329 | intel_unpin_fb_obj(obj); |
|
- | 6330 | err: |
|
- | 6331 | return ret; |
|
Line -... | Line 6332... | ||
- | 6332 | } |
|
- | 6333 | ||
Line -... | Line 6334... | ||
- | 6334 | static int intel_gen3_queue_flip(struct drm_device *dev, |
|
- | 6335 | struct drm_crtc *crtc, |
|
- | 6336 | struct drm_framebuffer *fb, |
|
- | 6337 | struct drm_i915_gem_object *obj) |
|
- | 6338 | { |
|
Line -... | Line 6339... | ||
- | 6339 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 6340 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 6341 | u32 flip_mask; |
|
- | 6342 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
|
- | 6343 | int ret; |
|
- | 6344 | ||
- | 6345 | ret = intel_pin_and_fence_fb_obj(dev, obj, ring); |
|
- | 6346 | if (ret) |
|
- | 6347 | goto err; |
|
- | 6348 | ||
Line -... | Line 6349... | ||
- | 6349 | ret = intel_ring_begin(ring, 6); |
|
- | 6350 | if (ret) |
|
- | 6351 | goto err_unpin; |
|
Line -... | Line 6352... | ||
- | 6352 | ||
- | 6353 | if (intel_crtc->plane) |
|
- | 6354 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; |
|
Line -... | Line 6355... | ||
- | 6355 | else |
|
- | 6356 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; |
|
- | 6357 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); |
|
- | 6358 | intel_ring_emit(ring, MI_NOOP); |
|
- | 6359 | intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | |
|
- | 6360 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
|
- | 6361 | intel_ring_emit(ring, fb->pitches[0]); |
|
- | 6362 | intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset); |
|
- | 6363 | intel_ring_emit(ring, MI_NOOP); |
|
- | 6364 | ||
- | 6365 | intel_ring_advance(ring); |
|
- | 6366 | return 0; |
|
- | 6367 | ||
- | 6368 | err_unpin: |
|
- | 6369 | intel_unpin_fb_obj(obj); |
|
- | 6370 | err: |
|
- | 6371 | return ret; |
|
- | 6372 | } |
|
- | 6373 | ||
- | 6374 | static int intel_gen4_queue_flip(struct drm_device *dev, |
|
Line -... | Line 6375... | ||
- | 6375 | struct drm_crtc *crtc, |
|
- | 6376 | struct drm_framebuffer *fb, |
|
- | 6377 | struct drm_i915_gem_object *obj) |
|
- | 6378 | { |
|
- | 6379 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
Line -... | Line 6380... | ||
- | 6380 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 6381 | uint32_t pf, pipesrc; |
|
- | 6382 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
|
- | 6383 | int ret; |
|
- | 6384 | ||
- | 6385 | ret = intel_pin_and_fence_fb_obj(dev, obj, ring); |
|
- | 6386 | if (ret) |
|
- | 6387 | goto err; |
|
- | 6388 | ||
- | 6389 | ret = intel_ring_begin(ring, 4); |
|
Line -... | Line 6390... | ||
- | 6390 | if (ret) |
|
- | 6391 | goto err_unpin; |
|
- | 6392 | ||
Line -... | Line 6393... | ||
- | 6393 | /* i965+ uses the linear or tiled offsets from the |
|
- | 6394 | * Display Registers (which do not change across a page-flip) |
|
- | 6395 | * so we need only reprogram the base address. |
|
Line -... | Line 6396... | ||
- | 6396 | */ |
|
- | 6397 | intel_ring_emit(ring, MI_DISPLAY_FLIP | |
|
- | 6398 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
|
- | 6399 | intel_ring_emit(ring, fb->pitches[0]); |
|
- | 6400 | intel_ring_emit(ring, |
|
- | 6401 | (obj->gtt_offset + intel_crtc->dspaddr_offset) | |
|
- | 6402 | obj->tiling_mode); |
|
- | 6403 | ||
- | 6404 | /* XXX Enabling the panel-fitter across page-flip is so far |
|
- | 6405 | * untested on non-native modes, so ignore it for now. |
|
- | 6406 | * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; |
|
- | 6407 | */ |
|
- | 6408 | pf = 0; |
|
- | 6409 | pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; |
|
- | 6410 | intel_ring_emit(ring, pf | pipesrc); |
|
- | 6411 | intel_ring_advance(ring); |
|
Line -... | Line 6412... | ||
- | 6412 | return 0; |
|
- | 6413 | ||
- | 6414 | err_unpin: |
|
- | 6415 | intel_unpin_fb_obj(obj); |
|
- | 6416 | err: |
|
Line -... | Line 6417... | ||
- | 6417 | return ret; |
|
- | 6418 | } |
|
- | 6419 | ||
- | 6420 | static int intel_gen6_queue_flip(struct drm_device *dev, |
|
- | 6421 | struct drm_crtc *crtc, |
|
- | 6422 | struct drm_framebuffer *fb, |
|
- | 6423 | struct drm_i915_gem_object *obj) |
|
- | 6424 | { |
|
- | 6425 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 6426 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 6427 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
|
- | 6428 | uint32_t pf, pipesrc; |
|
- | 6429 | int ret; |
|
- | 6430 | ||
- | 6431 | ret = intel_pin_and_fence_fb_obj(dev, obj, ring); |
|
- | 6432 | if (ret) |
|
Line -... | Line 6433... | ||
- | 6433 | goto err; |
|
- | 6434 | ||
- | 6435 | ret = intel_ring_begin(ring, 4); |
|
Line -... | Line 6436... | ||
- | 6436 | if (ret) |
|
- | 6437 | goto err_unpin; |
|
- | 6438 | ||
- | 6439 | intel_ring_emit(ring, MI_DISPLAY_FLIP | |
|
- | 6440 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
|
- | 6441 | intel_ring_emit(ring, fb->pitches[0] | obj->tiling_mode); |
|
- | 6442 | intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset); |
|
- | 6443 | ||
- | 6444 | /* Contrary to the suggestions in the documentation, |
|
- | 6445 | * "Enable Panel Fitter" does not seem to be required when page |
|
- | 6446 | * flipping with a non-native mode, and worse causes a normal |
|
- | 6447 | * modeset to fail. |
|
- | 6448 | * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; |
|
- | 6449 | */ |
|
- | 6450 | pf = 0; |
|
Line -... | Line 6451... | ||
- | 6451 | pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; |
|
- | 6452 | intel_ring_emit(ring, pf | pipesrc); |
|
- | 6453 | intel_ring_advance(ring); |
|
Line -... | Line 6454... | ||
- | 6454 | return 0; |
|
- | 6455 | ||
- | 6456 | err_unpin: |
|
- | 6457 | intel_unpin_fb_obj(obj); |
|
- | 6458 | err: |
|
- | 6459 | return ret; |
|
Line -... | Line 6460... | ||
- | 6460 | } |
|
- | 6461 | ||
- | 6462 | /* |
|
- | 6463 | * On gen7 we currently use the blit ring because (in early silicon at least) |
|
- | 6464 | * the render ring doesn't give us interrpts for page flip completion, which |
|
Line -... | Line 6465... | ||
- | 6465 | * means clients will hang after the first flip is queued. Fortunately the |
|
- | 6466 | * blit ring generates interrupts properly, so use it instead. |
|
- | 6467 | */ |
|
- | 6468 | static int intel_gen7_queue_flip(struct drm_device *dev, |
|
- | 6469 | struct drm_crtc *crtc, |
|
- | 6470 | struct drm_framebuffer *fb, |
|
- | 6471 | struct drm_i915_gem_object *obj) |
|
Line -... | Line 6472... | ||
- | 6472 | { |
|
- | 6473 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 6474 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 6475 | struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; |
|
- | 6476 | uint32_t plane_bit = 0; |
|
- | 6477 | int ret; |
|
- | 6478 | ||
- | 6479 | ret = intel_pin_and_fence_fb_obj(dev, obj, ring); |
|
- | 6480 | if (ret) |
|
- | 6481 | goto err; |
|
- | 6482 | ||
- | 6483 | switch(intel_crtc->plane) { |
|
Line -... | Line 6484... | ||
- | 6484 | case PLANE_A: |
|
- | 6485 | plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_A; |
|
- | 6486 | break; |
|
Line -... | Line 6487... | ||
- | 6487 | case PLANE_B: |
|
- | 6488 | plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_B; |
|
- | 6489 | break; |
|
- | 6490 | case PLANE_C: |
|
- | 6491 | plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_C; |
|
- | 6492 | break; |
|
- | 6493 | default: |
|
- | 6494 | WARN_ONCE(1, "unknown plane in flip command\n"); |
|
Line -... | Line 6495... | ||
- | 6495 | ret = -ENODEV; |
|
- | 6496 | goto err_unpin; |
|
- | 6497 | } |
|
Line -... | Line 6498... | ||
- | 6498 | ||
- | 6499 | ret = intel_ring_begin(ring, 4); |
|
- | 6500 | if (ret) |
|
- | 6501 | goto err_unpin; |
|
- | 6502 | ||
Line -... | Line 6503... | ||
- | 6503 | intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit); |
|
- | 6504 | intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); |
|
- | 6505 | intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset); |
|
Line -... | Line 6506... | ||
- | 6506 | intel_ring_emit(ring, (MI_NOOP)); |
|
- | 6507 | intel_ring_advance(ring); |
|
- | 6508 | return 0; |
|
- | 6509 | ||
- | 6510 | err_unpin: |
|
- | 6511 | intel_unpin_fb_obj(obj); |
|
Line -... | Line 6512... | ||
- | 6512 | err: |
|
- | 6513 | return ret; |
|
- | 6514 | } |
|
- | 6515 | ||
- | 6516 | static int intel_default_queue_flip(struct drm_device *dev, |
|
Line -... | Line 6517... | ||
- | 6517 | struct drm_crtc *crtc, |
|
- | 6518 | struct drm_framebuffer *fb, |
|
Line -... | Line 6519... | ||
- | 6519 | struct drm_i915_gem_object *obj) |
|
- | 6520 | { |
|
- | 6521 | return -ENODEV; |
|
Line -... | Line 6522... | ||
- | 6522 | } |
|
- | 6523 | ||
- | 6524 | static int intel_crtc_page_flip(struct drm_crtc *crtc, |
|
Line -... | Line 6525... | ||
- | 6525 | struct drm_framebuffer *fb, |
|
Line -... | Line 6526... | ||
- | 6526 | struct drm_pending_vblank_event *event) |
|
Line -... | Line 6527... | ||
- | 6527 | { |
|
Line 6671... | Line -... | ||
6671 | } |
- | |
6672 | - | ||
6673 | - | ||
6674 | - | ||
6675 | - | ||
6676 | - | ||
6677 | - | ||
6678 | - | ||
6679 | - | ||
6680 | - | ||
6681 | - | ||
6682 | - | ||
6683 | - | ||
6684 | - | ||
6685 | 6528 | struct drm_device *dev = crtc->dev; |
|
6686 | - | ||
6687 | 6529 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
6688 | - | ||
6689 | - | ||
6690 | 6530 | struct intel_framebuffer *intel_fb; |
|
- | 6531 | struct drm_i915_gem_object *obj; |
|
Line -... | Line 6532... | ||
- | 6532 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
6691 | 6533 | struct intel_unpin_work *work; |
|
6692 | 6534 | unsigned long flags; |
|
Line 6693... | Line 6535... | ||
6693 | 6535 | int ret; |
|
6694 | 6536 | ||
6695 | 6537 | /* Can't change pixel format via MI display flips. */ |
|
6696 | - | ||
Line 6697... | Line 6538... | ||
6697 | 6538 | if (fb->pixel_format != crtc->fb->pixel_format) |
|
6698 | - | ||
Line 6699... | Line -... | ||
6699 | - | ||
6700 | - | ||
6701 | 6539 | return -EINVAL; |
|
6702 | - | ||
Line -... | Line 6540... | ||
- | 6540 | ||
6703 | 6541 | /* |
|
6704 | - | ||
- | 6542 | * TILEOFF/LINOFF registers can't be changed via MI display flips. |
|
6705 | 6543 | * Note that pitch changes could also affect these register. |
|
6706 | 6544 | */ |
|
Line 6707... | Line 6545... | ||
6707 | 6545 | if (INTEL_INFO(dev)->gen > 3 && |
|
6708 | 6546 | (fb->offsets[0] != crtc->fb->offsets[0] || |
|
6709 | - | ||
6710 | 6547 | fb->pitches[0] != crtc->fb->pitches[0])) |
|
- | 6548 | return -EINVAL; |
|
Line 6711... | Line 6549... | ||
6711 | 6549 | ||
- | 6550 | work = kzalloc(sizeof *work, GFP_KERNEL); |
|
6712 | 6551 | if (work == NULL) |
|
6713 | 6552 | return -ENOMEM; |
|
6714 | 6553 | ||
6715 | 6554 | work->event = event; |
|
Line -... | Line 6555... | ||
- | 6555 | work->dev = crtc->dev; |
|
- | 6556 | intel_fb = to_intel_framebuffer(crtc->fb); |
|
6716 | 6557 | work->old_fb_obj = intel_fb->obj; |
|
6717 | - | ||
6718 | - | ||
6719 | - | ||
6720 | - | ||
6721 | 6558 | INIT_WORK(&work->work, intel_unpin_work_fn); |
|
6722 | 6559 | ||
6723 | 6560 | ret = drm_vblank_get(dev, intel_crtc->pipe); |
|
6724 | - | ||
6725 | - | ||
6726 | - | ||
6727 | - | ||
6728 | - | ||
6729 | - | ||
6730 | - | ||
6731 | - | ||
6732 | - | ||
6733 | - | ||
6734 | 6561 | if (ret) |
|
Line 6735... | Line 6562... | ||
6735 | 6562 | goto free_work; |
|
6736 | 6563 | ||
6737 | 6564 | /* We borrow the event spin lock for protecting unpin_work */ |
|
6738 | static void intel_sanitize_modesetting(struct drm_device *dev, |
6565 | spin_lock_irqsave(&dev->event_lock, flags); |
6739 | int pipe, int plane) |
- | |
Line 6740... | Line -... | ||
6740 | { |
- | |
6741 | struct drm_i915_private *dev_priv = dev->dev_private; |
6566 | if (intel_crtc->unpin_work) { |
6742 | u32 reg, val; |
6567 | spin_unlock_irqrestore(&dev->event_lock, flags); |
Line -... | Line 6568... | ||
- | 6568 | kfree(work); |
|
6743 | 6569 | drm_vblank_put(dev, intel_crtc->pipe); |
|
- | 6570 | ||
Line 6744... | Line 6571... | ||
6744 | if (HAS_PCH_SPLIT(dev)) |
6571 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); |
6745 | return; |
6572 | return -EBUSY; |
6746 | 6573 | } |
|
6747 | /* Who knows what state these registers were left in by the BIOS or |
6574 | intel_crtc->unpin_work = work; |
6748 | * grub? |
6575 | spin_unlock_irqrestore(&dev->event_lock, flags); |
6749 | * |
6576 | |
Line 6750... | Line -... | ||
6750 | * If we leave the registers in a conflicting state (e.g. with the |
- | |
6751 | * display plane reading from the other pipe than the one we intend |
- | |
6752 | * to use) then when we attempt to teardown the active mode, we will |
6577 | intel_fb = to_intel_framebuffer(fb); |
6753 | * not disable the pipes and planes in the correct order -- leaving |
- | |
6754 | * a plane reading from a disabled pipe and possibly leading to |
- | |
6755 | * undefined behaviour. |
- | |
6756 | */ |
6578 | obj = intel_fb->obj; |
Line 6757... | Line -... | ||
6757 | - | ||
6758 | reg = DSPCNTR(plane); |
6579 | |
6759 | val = I915_READ(reg); |
- | |
6760 | - | ||
6761 | if ((val & DISPLAY_PLANE_ENABLE) == 0) |
- | |
6762 | return; |
6580 | ret = i915_mutex_lock_interruptible(dev); |
6763 | if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe) |
- | |
6764 | return; |
- | |
6765 | 6581 | if (ret) |
|
6766 | /* This display plane is active and attached to the other CPU pipe. */ |
6582 | goto cleanup; |
6767 | pipe = !pipe; |
6583 | |
6768 | 6584 | /* Reference the objects for the scheduled work. */ |
|
6769 | /* Disable the plane and wait for it to stop reading from the pipe. */ |
- | |
6770 | intel_disable_plane(dev_priv, plane, pipe); |
- | |
6771 | intel_disable_pipe(dev_priv, pipe); |
- | |
6772 | } |
- | |
6773 | - | ||
6774 | static void intel_crtc_reset(struct drm_crtc *crtc) |
- | |
Line 6775... | Line 6585... | ||
6775 | { |
6585 | drm_gem_object_reference(&work->old_fb_obj->base); |
Line 6776... | Line 6586... | ||
6776 | struct drm_device *dev = crtc->dev; |
6586 | drm_gem_object_reference(&obj->base); |
Line -... | Line 6587... | ||
- | 6587 | ||
- | 6588 | crtc->fb = fb; |
|
- | 6589 | ||
- | 6590 | work->pending_flip_obj = obj; |
|
6777 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
6591 | |
Line -... | Line 6592... | ||
- | 6592 | work->enable_stall_check = true; |
|
- | 6593 | ||
- | 6594 | /* Block clients from rendering to the new back buffer until |
|
- | 6595 | * the flip occurs and the object is no longer visible. |
|
Line -... | Line 6596... | ||
- | 6596 | */ |
|
- | 6597 | atomic_add(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); |
|
- | 6598 | ||
- | 6599 | ret = dev_priv->display.queue_flip(dev, crtc, fb, obj); |
|
- | 6600 | if (ret) |
|
- | 6601 | goto cleanup_pending; |
|
- | 6602 | ||
- | 6603 | intel_disable_fbc(dev); |
|
- | 6604 | intel_mark_fb_busy(obj); |
|
- | 6605 | mutex_unlock(&dev->struct_mutex); |
|
Line -... | Line 6606... | ||
- | 6606 | ||
- | 6607 | trace_i915_flip_request(intel_crtc->plane, obj); |
|
- | 6608 | ||
- | 6609 | return 0; |
|
- | 6610 | ||
Line -... | Line 6611... | ||
- | 6611 | cleanup_pending: |
|
- | 6612 | atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); |
|
- | 6613 | drm_gem_object_unreference(&work->old_fb_obj->base); |
|
- | 6614 | drm_gem_object_unreference(&obj->base); |
|
- | 6615 | mutex_unlock(&dev->struct_mutex); |
|
- | 6616 | ||
Line 6778... | Line 6617... | ||
6778 | 6617 | cleanup: |
|
- | 6618 | spin_lock_irqsave(&dev->event_lock, flags); |
|
6779 | /* Reset flags back to the 'unknown' status so that they |
6619 | intel_crtc->unpin_work = NULL; |
- | 6620 | spin_unlock_irqrestore(&dev->event_lock, flags); |
|
- | 6621 | ||
6780 | * will be correctly set on the initial modeset. |
6622 | drm_vblank_put(dev, intel_crtc->pipe); |
6781 | */ |
6623 | free_work: |
6782 | intel_crtc->dpms_mode = -1; |
6624 | kfree(work); |
6783 | 6625 | ||
6784 | /* We need to fix up any BIOS configuration that conflicts with |
- | |
Line 6785... | Line 6626... | ||
6785 | * our expectations. |
6626 | return ret; |
6786 | */ |
6627 | } |
6787 | intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); |
6628 | |
6788 | } |
- | |
6789 | 6629 | #endif |
|
Line -... | Line 6630... | ||
- | 6630 | ||
6790 | static struct drm_crtc_helper_funcs intel_helper_funcs = { |
6631 | static struct drm_crtc_helper_funcs intel_helper_funcs = { |
- | 6632 | .mode_set_base_atomic = intel_pipe_set_base_atomic, |
|
- | 6633 | .load_lut = intel_crtc_load_lut, |
|
6791 | .dpms = intel_crtc_dpms, |
6634 | .disable = intel_crtc_noop, |
Line 6792... | Line 6635... | ||
6792 | .mode_fixup = intel_crtc_mode_fixup, |
6635 | }; |
- | 6636 | ||
- | 6637 | bool intel_encoder_check_is_cloned(struct intel_encoder *encoder) |
|
6793 | .mode_set = intel_crtc_mode_set, |
6638 | { |
6794 | .mode_set_base = intel_pipe_set_base, |
6639 | struct intel_encoder *other_encoder; |
- | 6640 | struct drm_crtc *crtc = &encoder->new_crtc->base; |
|
- | 6641 | ||
- | 6642 | if (WARN_ON(!crtc)) |
|
Line -... | Line 6643... | ||
- | 6643 | return false; |
|
6795 | .mode_set_base_atomic = intel_pipe_set_base_atomic, |
6644 | |
6796 | .load_lut = intel_crtc_load_lut, |
6645 | list_for_each_entry(other_encoder, |
Line -... | Line 6646... | ||
- | 6646 | &crtc->dev->mode_config.encoder_list, |
|
- | 6647 | base.head) { |
|
6797 | .disable = intel_crtc_disable, |
6648 | |
- | 6649 | if (&other_encoder->new_crtc->base != crtc || |
|
- | 6650 | encoder == other_encoder) |
|
6798 | }; |
6651 | continue; |
Line -... | Line 6652... | ||
- | 6652 | else |
|
- | 6653 | return true; |
|
- | 6654 | } |
|
- | 6655 | ||
6799 | 6656 | return false; |
|
6800 | static const struct drm_crtc_funcs intel_crtc_funcs = { |
6657 | } |
6801 | .reset = intel_crtc_reset, |
6658 | |
- | 6659 | static bool intel_encoder_crtc_ok(struct drm_encoder *encoder, |
|
- | 6660 | struct drm_crtc *crtc) |
|
Line -... | Line 6661... | ||
- | 6661 | { |
|
- | 6662 | struct drm_device *dev; |
|
6802 | // .cursor_set = intel_crtc_cursor_set, |
6663 | struct drm_crtc *tmp; |
6803 | // .cursor_move = intel_crtc_cursor_move, |
6664 | int crtc_mask = 1; |
- | 6665 | ||
Line -... | Line 6666... | ||
- | 6666 | WARN(!crtc, "checking null crtc?\n"); |
|
- | 6667 | ||
- | 6668 | dev = crtc->dev; |
|
- | 6669 | ||
- | 6670 | list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { |
|
- | 6671 | if (tmp == crtc) |
|
- | 6672 | break; |
|
- | 6673 | crtc_mask <<= 1; |
|
- | 6674 | } |
|
6804 | .gamma_set = intel_crtc_gamma_set, |
6675 | |
- | 6676 | if (encoder->possible_crtcs & crtc_mask) |
|
6805 | .set_config = drm_crtc_helper_set_config, |
6677 | return true; |
- | 6678 | return false; |
|
6806 | .destroy = intel_crtc_destroy, |
6679 | } |
6807 | // .page_flip = intel_crtc_page_flip, |
6680 | |
6808 | }; |
6681 | /** |
6809 | 6682 | * intel_modeset_update_staged_output_state |
|
Line 6810... | Line 6683... | ||
6810 | static void intel_crtc_init(struct drm_device *dev, int pipe) |
6683 | * |
Line -... | Line 6684... | ||
- | 6684 | * Updates the staged output configuration state, e.g. after we've read out the |
|
6811 | { |
6685 | * current hw state. |
6812 | drm_i915_private_t *dev_priv = dev->dev_private; |
6686 | */ |
6813 | struct intel_crtc *intel_crtc; |
6687 | static void intel_modeset_update_staged_output_state(struct drm_device *dev) |
6814 | int i; |
6688 | { |
6815 | 6689 | struct intel_encoder *encoder; |
|
- | 6690 | struct intel_connector *connector; |
|
6816 | intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); |
6691 | |
Line 6817... | Line 6692... | ||
6817 | if (intel_crtc == NULL) |
6692 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
6818 | return; |
6693 | base.head) { |
Line 6819... | Line -... | ||
6819 | - | ||
6820 | drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs); |
6694 | connector->new_encoder = |
- | 6695 | to_intel_encoder(connector->base.encoder); |
|
Line 6821... | Line 6696... | ||
6821 | 6696 | } |
|
6822 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); |
6697 | |
- | 6698 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
|
6823 | for (i = 0; i < 256; i++) { |
6699 | base.head) { |
Line -... | Line 6700... | ||
- | 6700 | encoder->new_crtc = |
|
- | 6701 | to_intel_crtc(encoder->base.crtc); |
|
- | 6702 | } |
|
6824 | intel_crtc->lut_r[i] = i; |
6703 | } |
Line 6825... | Line 6704... | ||
6825 | intel_crtc->lut_g[i] = i; |
6704 | |
6826 | intel_crtc->lut_b[i] = i; |
6705 | /** |
Line 6827... | Line -... | ||
6827 | } |
- | |
6828 | - | ||
6829 | /* Swap pipes & planes for FBC on pre-965 */ |
6706 | * intel_modeset_commit_output_state |
6830 | intel_crtc->pipe = pipe; |
- | |
6831 | intel_crtc->plane = pipe; |
- | |
6832 | if (IS_MOBILE(dev) && IS_GEN3(dev)) { |
- | |
6833 | DRM_DEBUG_KMS("swapping pipes & planes for FBC\n"); |
- | |
6834 | intel_crtc->plane = !pipe; |
6707 | * |
Line 6835... | Line -... | ||
6835 | } |
- | |
6836 | 6708 | * This function copies the stage display pipe configuration to the real one. |
|
6837 | BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || |
- | |
6838 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL); |
6709 | */ |
6839 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base; |
- | |
6840 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; |
6710 | static void intel_modeset_commit_output_state(struct drm_device *dev) |
6841 | - | ||
6842 | intel_crtc_reset(&intel_crtc->base); |
- | |
Line 6843... | Line 6711... | ||
6843 | intel_crtc->active = true; /* force the pipe off on setup_init_config */ |
6711 | { |
- | 6712 | struct intel_encoder *encoder; |
|
- | 6713 | struct intel_connector *connector; |
|
6844 | intel_crtc->bpp = 24; /* default for pre-Ironlake */ |
6714 | |
Line -... | Line 6715... | ||
- | 6715 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
|
6845 | 6716 | base.head) { |
|
6846 | if (HAS_PCH_SPLIT(dev)) { |
6717 | connector->base.encoder = &connector->new_encoder->base; |
Line 6847... | Line 6718... | ||
6847 | if (pipe == 2 && IS_IVYBRIDGE(dev)) |
6718 | } |
6848 | intel_crtc->no_pll = true; |
- | |
6849 | intel_helper_funcs.prepare = ironlake_crtc_prepare; |
6719 | |
6850 | intel_helper_funcs.commit = ironlake_crtc_commit; |
6720 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
6851 | } else { |
- | |
6852 | intel_helper_funcs.prepare = i9xx_crtc_prepare; |
6721 | base.head) { |
6853 | intel_helper_funcs.commit = i9xx_crtc_commit; |
6722 | encoder->base.crtc = &encoder->new_crtc->base; |
Line 6854... | Line 6723... | ||
6854 | } |
6723 | } |
6855 | - | ||
6856 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); |
6724 | } |
6857 | - | ||
6858 | intel_crtc->busy = false; |
6725 | |
Line 6859... | Line -... | ||
6859 | - | ||
Line -... | Line 6726... | ||
- | 6726 | static struct drm_display_mode * |
|
- | 6727 | intel_modeset_adjusted_mode(struct drm_crtc *crtc, |
|
- | 6728 | struct drm_display_mode *mode) |
|
6860 | } |
6729 | { |
- | 6730 | struct drm_device *dev = crtc->dev; |
|
- | 6731 | struct drm_display_mode *adjusted_mode; |
|
- | 6732 | struct drm_encoder_helper_funcs *encoder_funcs; |
|
- | 6733 | struct intel_encoder *encoder; |
|
- | 6734 | ||
- | 6735 | adjusted_mode = drm_mode_duplicate(dev, mode); |
|
- | 6736 | if (!adjusted_mode) |
|
- | 6737 | return ERR_PTR(-ENOMEM); |
|
- | 6738 | ||
- | 6739 | /* Pass our mode to the connectors and the CRTC to give them a chance to |
|
- | 6740 | * adjust it according to limitations or connector properties, and also |
|
- | 6741 | * a chance to reject the mode entirely. |
|
- | 6742 | */ |
|
- | 6743 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
|
- | 6744 | base.head) { |
|
6861 | 6745 | ||
6862 | 6746 | if (&encoder->new_crtc->base != crtc) |
|
6863 | 6747 | continue; |
|
Line 6864... | Line 6748... | ||
6864 | 6748 | encoder_funcs = encoder->base.helper_private; |
|
- | 6749 | if (!(encoder_funcs->mode_fixup(&encoder->base, mode, |
|
- | 6750 | adjusted_mode))) { |
|
- | 6751 | DRM_DEBUG_KMS("Encoder fixup failed\n"); |
|
Line 6865... | Line 6752... | ||
6865 | 6752 | goto fail; |
|
6866 | 6753 | } |
|
6867 | 6754 | } |
|
6868 | static int intel_encoder_clones(struct drm_device *dev, int type_mask) |
6755 | |
6869 | { |
- | |
6870 | struct intel_encoder *encoder; |
- | |
6871 | int index_mask = 0; |
6756 | if (!(intel_crtc_mode_fixup(crtc, mode, adjusted_mode))) { |
6872 | int entry = 0; |
- | |
6873 | 6757 | DRM_DEBUG_KMS("CRTC fixup failed\n"); |
|
Line -... | Line 6758... | ||
- | 6758 | goto fail; |
|
- | 6759 | } |
|
- | 6760 | DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); |
|
- | 6761 | ||
- | 6762 | return adjusted_mode; |
|
- | 6763 | fail: |
|
- | 6764 | drm_mode_destroy(dev, adjusted_mode); |
|
- | 6765 | return ERR_PTR(-EINVAL); |
|
- | 6766 | } |
|
6874 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { |
6767 | |
- | 6768 | /* Computes which crtcs are affected and sets the relevant bits in the mask. For |
|
- | 6769 | * simplicity we use the crtc's pipe number (because it's easier to obtain). */ |
|
6875 | if (type_mask & encoder->clone_mask) |
6770 | static void |
- | 6771 | intel_modeset_affected_pipes(struct drm_crtc *crtc, unsigned *modeset_pipes, |
|
6876 | index_mask |= (1 << entry); |
6772 | unsigned *prepare_pipes, unsigned *disable_pipes) |
6877 | entry++; |
6773 | { |
6878 | } |
6774 | struct intel_crtc *intel_crtc; |
6879 | - | ||
6880 | return index_mask; |
- | |
Line 6881... | Line -... | ||
6881 | } |
- | |
6882 | 6775 | struct drm_device *dev = crtc->dev; |
|
Line 6883... | Line 6776... | ||
6883 | static bool has_edp_a(struct drm_device *dev) |
6776 | struct intel_encoder *encoder; |
6884 | { |
6777 | struct intel_connector *connector; |
6885 | struct drm_i915_private *dev_priv = dev->dev_private; |
6778 | struct drm_crtc *tmp_crtc; |
6886 | 6779 | ||
6887 | if (!IS_MOBILE(dev)) |
6780 | *disable_pipes = *modeset_pipes = *prepare_pipes = 0; |
Line 6888... | Line 6781... | ||
6888 | return false; |
6781 | |
6889 | 6782 | /* Check which crtcs have changed outputs connected to them, these need |
|
- | 6783 | * to be part of the prepare_pipes mask. We don't (yet) support global |
|
Line 6890... | Line -... | ||
6890 | if ((I915_READ(DP_A) & DP_DETECTED) == 0) |
- | |
6891 | return false; |
6784 | * modeset across multiple crtcs, so modeset_pipes will only have one |
Line -... | Line 6785... | ||
- | 6785 | * bit set at most. */ |
|
- | 6786 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
|
6892 | 6787 | base.head) { |
|
6893 | if (IS_GEN5(dev) && |
- | |
Line -... | Line 6788... | ||
- | 6788 | if (connector->base.encoder == &connector->new_encoder->base) |
|
- | 6789 | continue; |
|
- | 6790 | ||
- | 6791 | if (connector->base.encoder) { |
|
Line -... | Line 6792... | ||
- | 6792 | tmp_crtc = connector->base.encoder->crtc; |
|
- | 6793 | ||
- | 6794 | *prepare_pipes |= 1 << to_intel_crtc(tmp_crtc)->pipe; |
|
- | 6795 | } |
|
Line -... | Line 6796... | ||
- | 6796 | ||
Line -... | Line 6797... | ||
- | 6797 | if (connector->new_encoder) |
|
- | 6798 | *prepare_pipes |= |
|
- | 6799 | 1 << connector->new_encoder->new_crtc->pipe; |
|
- | 6800 | } |
|
- | 6801 | ||
Line -... | Line 6802... | ||
- | 6802 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
|
- | 6803 | base.head) { |
|
- | 6804 | if (encoder->base.crtc == &encoder->new_crtc->base) |
|
- | 6805 | continue; |
|
- | 6806 | ||
- | 6807 | if (encoder->base.crtc) { |
|
Line -... | Line 6808... | ||
- | 6808 | tmp_crtc = encoder->base.crtc; |
|
- | 6809 | ||
- | 6810 | *prepare_pipes |= 1 << to_intel_crtc(tmp_crtc)->pipe; |
|
- | 6811 | } |
|
- | 6812 | ||
Line -... | Line 6813... | ||
- | 6813 | if (encoder->new_crtc) |
|
- | 6814 | *prepare_pipes |= 1 << encoder->new_crtc->pipe; |
|
- | 6815 | } |
|
Line 6894... | Line 6816... | ||
6894 | (I915_READ(ILK_DISPLAY_CHICKEN_FUSES) & ILK_eDP_A_DISABLE)) |
6816 | |
- | 6817 | /* Check for any pipes that will be fully disabled ... */ |
|
- | 6818 | list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, |
|
- | 6819 | base.head) { |
|
- | 6820 | bool used = false; |
|
- | 6821 | ||
- | 6822 | /* Don't try to disable disabled crtcs. */ |
|
6895 | return false; |
6823 | if (!intel_crtc->base.enabled) |
6896 | 6824 | continue; |
|
6897 | return true; |
6825 | |
- | 6826 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
|
- | 6827 | base.head) { |
|
- | 6828 | if (encoder->new_crtc == intel_crtc) |
|
- | 6829 | used = true; |
|
Line -... | Line 6830... | ||
- | 6830 | } |
|
- | 6831 | ||
6898 | } |
6832 | if (!used) |
- | 6833 | *disable_pipes |= 1 << intel_crtc->pipe; |
|
- | 6834 | } |
|
- | 6835 | ||
- | 6836 | ||
- | 6837 | /* set_mode is also used to update properties on life display pipes. */ |
|
- | 6838 | intel_crtc = to_intel_crtc(crtc); |
|
- | 6839 | if (crtc->enabled) |
|
6899 | 6840 | *prepare_pipes |= 1 << intel_crtc->pipe; |
|
6900 | static void intel_setup_outputs(struct drm_device *dev) |
6841 | |
- | 6842 | /* We only support modeset on one single crtc, hence we need to do that |
|
6901 | { |
6843 | * only for the passed in crtc iff we change anything else than just |
- | 6844 | * disable crtcs. |
|
- | 6845 | * |
|
- | 6846 | * This is actually not true, to be fully compatible with the old crtc |
|
- | 6847 | * helper we automatically disable _any_ output (i.e. doesn't need to be |
|
6902 | struct drm_i915_private *dev_priv = dev->dev_private; |
6848 | * connected to the crtc we're modesetting on) if it's disconnected. |
- | 6849 | * Which is a rather nutty api (since changed the output configuration |
|
- | 6850 | * without userspace's explicit request can lead to confusion), but |
|
- | 6851 | * alas. Hence we currently need to modeset on all pipes we prepare. */ |
|
- | 6852 | if (*prepare_pipes) |
|
6903 | struct intel_encoder *encoder; |
6853 | *modeset_pipes = *prepare_pipes; |
Line 6904... | Line 6854... | ||
6904 | bool dpd_is_edp = false; |
6854 | |
6905 | bool has_lvds = false; |
6855 | /* ... and mask these out. */ |
Line -... | Line 6856... | ||
- | 6856 | *modeset_pipes &= ~(*disable_pipes); |
|
- | 6857 | *prepare_pipes &= ~(*disable_pipes); |
|
- | 6858 | } |
|
6906 | 6859 | ||
6907 | ENTER(); |
6860 | static bool intel_crtc_in_use(struct drm_crtc *crtc) |
Line 6908... | Line -... | ||
6908 | - | ||
6909 | if (IS_MOBILE(dev) && !IS_I830(dev)) |
- | |
6910 | has_lvds = intel_lvds_init(dev); |
- | |
6911 | if (!has_lvds && !HAS_PCH_SPLIT(dev)) { |
- | |
6912 | /* disable the panel fitter on everything but LVDS */ |
- | |
6913 | I915_WRITE(PFIT_CONTROL, 0); |
- | |
6914 | } |
- | |
6915 | - | ||
6916 | if (HAS_PCH_SPLIT(dev)) { |
- | |
6917 | dpd_is_edp = intel_dpd_is_edp(dev); |
- | |
6918 | - | ||
6919 | if (has_edp_a(dev)) |
- | |
6920 | intel_dp_init(dev, DP_A); |
- | |
6921 | - | ||
6922 | if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) |
- | |
6923 | intel_dp_init(dev, PCH_DP_D); |
- | |
6924 | } |
- | |
6925 | 6861 | { |
|
Line 6926... | Line 6862... | ||
6926 | intel_crt_init(dev); |
6862 | struct drm_encoder *encoder; |
6927 | 6863 | struct drm_device *dev = crtc->dev; |
|
- | 6864 | ||
- | 6865 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) |
|
- | 6866 | if (encoder->crtc == crtc) |
|
- | 6867 | return true; |
|
- | 6868 | ||
- | 6869 | return false; |
|
- | 6870 | } |
|
6928 | if (HAS_PCH_SPLIT(dev)) { |
6871 | |
- | 6872 | static void |
|
- | 6873 | intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes) |
|
- | 6874 | { |
|
- | 6875 | struct intel_encoder *intel_encoder; |
|
6929 | int found; |
6876 | struct intel_crtc *intel_crtc; |
- | 6877 | struct drm_connector *connector; |
|
- | 6878 | ||
- | 6879 | list_for_each_entry(intel_encoder, &dev->mode_config.encoder_list, |
|
6930 | 6880 | base.head) { |
|
- | 6881 | if (!intel_encoder->base.crtc) |
|
- | 6882 | continue; |
|
- | 6883 | ||
- | 6884 | intel_crtc = to_intel_crtc(intel_encoder->base.crtc); |
|
- | 6885 | ||
- | 6886 | if (prepare_pipes & (1 << intel_crtc->pipe)) |
|
Line 6931... | Line 6887... | ||
6931 | if (I915_READ(HDMIB) & PORT_DETECTED) { |
6887 | intel_encoder->connectors_active = false; |
6932 | /* PCH SDVOB multiplex with HDMIB */ |
- | |
6933 | found = intel_sdvo_init(dev, PCH_SDVOB); |
6888 | } |
6934 | if (!found) |
6889 | |
Line -... | Line 6890... | ||
- | 6890 | intel_modeset_commit_output_state(dev); |
|
- | 6891 | ||
- | 6892 | /* Update computed state. */ |
|
- | 6893 | list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, |
|
- | 6894 | base.head) { |
|
- | 6895 | intel_crtc->base.enabled = intel_crtc_in_use(&intel_crtc->base); |
|
- | 6896 | } |
|
- | 6897 | ||
- | 6898 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
|
- | 6899 | if (!connector->encoder || !connector->encoder->crtc) |
|
- | 6900 | continue; |
|
- | 6901 | ||
Line 6935... | Line 6902... | ||
6935 | intel_hdmi_init(dev, HDMIB); |
6902 | intel_crtc = to_intel_crtc(connector->encoder->crtc); |
6936 | if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED)) |
6903 | |
6937 | intel_dp_init(dev, PCH_DP_B); |
- | |
6938 | } |
- | |
Line -... | Line 6904... | ||
- | 6904 | if (prepare_pipes & (1 << intel_crtc->pipe)) { |
|
- | 6905 | struct drm_property *dpms_property = |
|
Line -... | Line 6906... | ||
- | 6906 | dev->mode_config.dpms_property; |
|
- | 6907 | ||
- | 6908 | connector->dpms = DRM_MODE_DPMS_ON; |
|
- | 6909 | drm_connector_property_set_value(connector, |
|
- | 6910 | dpms_property, |
|
- | 6911 | DRM_MODE_DPMS_ON); |
|
- | 6912 | ||
- | 6913 | intel_encoder = to_intel_encoder(connector->encoder); |
|
- | 6914 | intel_encoder->connectors_active = true; |
|
- | 6915 | } |
|
- | 6916 | } |
|
- | 6917 | ||
- | 6918 | } |
|
- | 6919 | ||
- | 6920 | #define for_each_intel_crtc_masked(dev, mask, intel_crtc) \ |
|
- | 6921 | list_for_each_entry((intel_crtc), \ |
|
- | 6922 | &(dev)->mode_config.crtc_list, \ |
|
- | 6923 | base.head) \ |
|
Line -... | Line 6924... | ||
- | 6924 | if (mask & (1 <<(intel_crtc)->pipe)) \ |
|
- | 6925 | ||
- | 6926 | void |
|
- | 6927 | intel_modeset_check_state(struct drm_device *dev) |
|
- | 6928 | { |
|
- | 6929 | struct intel_crtc *crtc; |
|
- | 6930 | struct intel_encoder *encoder; |
|
- | 6931 | struct intel_connector *connector; |
|
- | 6932 | ||
- | 6933 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
|
- | 6934 | base.head) { |
|
- | 6935 | /* This also checks the encoder/connector hw state with the |
|
- | 6936 | * ->get_hw_state callbacks. */ |
|
- | 6937 | intel_connector_check_state(connector); |
|
- | 6938 | ||
- | 6939 | WARN(&connector->new_encoder->base != connector->base.encoder, |
|
- | 6940 | "connector's staged encoder doesn't match current encoder\n"); |
|
- | 6941 | } |
|
- | 6942 | ||
- | 6943 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
|
- | 6944 | base.head) { |
|
- | 6945 | bool enabled = false; |
|
- | 6946 | bool active = false; |
|
- | 6947 | enum pipe pipe, tracked_pipe; |
|
Line -... | Line 6948... | ||
- | 6948 | ||
Line -... | Line 6949... | ||
- | 6949 | DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", |
|
- | 6950 | encoder->base.base.id, |
|
Line -... | Line 6951... | ||
- | 6951 | drm_get_encoder_name(&encoder->base)); |
|
- | 6952 | ||
- | 6953 | WARN(&encoder->new_crtc->base != encoder->base.crtc, |
|
- | 6954 | "encoder's stage crtc doesn't match current crtc\n"); |
|
- | 6955 | WARN(encoder->connectors_active && !encoder->base.crtc, |
|
- | 6956 | "encoder's active_connectors set, but no crtc\n"); |
|
- | 6957 | ||
Line -... | Line 6958... | ||
- | 6958 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
|
- | 6959 | base.head) { |
|
- | 6960 | if (connector->base.encoder != &encoder->base) |
|
Line -... | Line 6961... | ||
- | 6961 | continue; |
|
- | 6962 | enabled = true; |
|
- | 6963 | if (connector->base.dpms != DRM_MODE_DPMS_OFF) |
|
Line -... | Line 6964... | ||
- | 6964 | active = true; |
|
- | 6965 | } |
|
6939 | 6966 | WARN(!!encoder->base.crtc != enabled, |
|
6940 | if (I915_READ(HDMIC) & PORT_DETECTED) |
6967 | "encoder's enabled state mismatch " |
6941 | intel_hdmi_init(dev, HDMIC); |
6968 | "(expected %i, found %i)\n", |
6942 | 6969 | !!encoder->base.crtc, enabled); |
|
Line -... | Line 6970... | ||
- | 6970 | WARN(active && !encoder->base.crtc, |
|
- | 6971 | "active encoder with no crtc\n"); |
|
6943 | if (I915_READ(HDMID) & PORT_DETECTED) |
6972 | |
6944 | intel_hdmi_init(dev, HDMID); |
6973 | WARN(encoder->connectors_active != active, |
6945 | 6974 | "encoder's computed active state doesn't match tracked active state " |
|
- | 6975 | "(expected %i, found %i)\n", active, encoder->connectors_active); |
|
- | 6976 | ||
6946 | if (I915_READ(PCH_DP_C) & DP_DETECTED) |
6977 | active = encoder->get_hw_state(encoder, &pipe); |
6947 | intel_dp_init(dev, PCH_DP_C); |
6978 | WARN(active != encoder->connectors_active, |
Line 6948... | Line -... | ||
6948 | - | ||
6949 | if (!dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) |
- | |
6950 | intel_dp_init(dev, PCH_DP_D); |
- | |
6951 | 6979 | "encoder's hw state doesn't match sw tracking " |
|
- | 6980 | "(expected %i, found %i)\n", |
|
Line 6952... | Line -... | ||
6952 | } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { |
- | |
6953 | bool found = false; |
6981 | encoder->connectors_active, active); |
Line -... | Line 6982... | ||
- | 6982 | ||
- | 6983 | if (!encoder->base.crtc) |
|
- | 6984 | continue; |
|
6954 | 6985 | ||
- | 6986 | tracked_pipe = to_intel_crtc(encoder->base.crtc)->pipe; |
|
- | 6987 | WARN(active && pipe != tracked_pipe, |
|
- | 6988 | "active encoder's pipe doesn't match" |
|
- | 6989 | "(expected %i, found %i)\n", |
|
6955 | if (I915_READ(SDVOB) & SDVO_DETECTED) { |
6990 | tracked_pipe, pipe); |
Line 6956... | Line 6991... | ||
6956 | DRM_DEBUG_KMS("probing SDVOB\n"); |
6991 | |
- | 6992 | } |
|
6957 | found = intel_sdvo_init(dev, SDVOB); |
6993 | |
6958 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) { |
6994 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, |
6959 | DRM_DEBUG_KMS("probing HDMI on SDVOB\n"); |
- | |
6960 | intel_hdmi_init(dev, SDVOB); |
6995 | base.head) { |
6961 | } |
- | |
6962 | 6996 | bool enabled = false; |
|
6963 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) { |
- | |
6964 | DRM_DEBUG_KMS("probing DP_B\n"); |
- | |
Line -... | Line 6997... | ||
- | 6997 | bool active = false; |
|
6965 | intel_dp_init(dev, DP_B); |
6998 | |
- | 6999 | DRM_DEBUG_KMS("[CRTC:%d]\n", |
|
6966 | } |
7000 | crtc->base.base.id); |
6967 | } |
7001 | |
Line -... | Line 7002... | ||
- | 7002 | WARN(crtc->active && !crtc->base.enabled, |
|
6968 | 7003 | "active crtc, but not enabled in sw tracking\n"); |
|
6969 | /* Before G4X SDVOC doesn't have its own detect register */ |
7004 | |
- | 7005 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
|
6970 | 7006 | base.head) { |
|
Line -... | Line 7007... | ||
- | 7007 | if (encoder->base.crtc != &crtc->base) |
|
- | 7008 | continue; |
|
- | 7009 | enabled = true; |
|
- | 7010 | if (encoder->connectors_active) |
|
6971 | if (I915_READ(SDVOB) & SDVO_DETECTED) { |
7011 | active = true; |
- | 7012 | } |
|
- | 7013 | WARN(active != crtc->active, |
|
- | 7014 | "crtc's computed active state doesn't match tracked active state " |
|
Line 6972... | Line 7015... | ||
6972 | DRM_DEBUG_KMS("probing SDVOC\n"); |
7015 | "(expected %i, found %i)\n", active, crtc->active); |
6973 | found = intel_sdvo_init(dev, SDVOC); |
7016 | WARN(enabled != crtc->base.enabled, |
6974 | } |
7017 | "crtc's computed enabled state doesn't match tracked enabled state " |
6975 | - | ||
6976 | if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) { |
7018 | "(expected %i, found %i)\n", enabled, crtc->base.enabled); |
Line 6977... | Line -... | ||
6977 | - | ||
6978 | if (SUPPORTS_INTEGRATED_HDMI(dev)) { |
7019 | |
- | 7020 | assert_pipe(dev->dev_private, crtc->pipe, crtc->active); |
|
Line 6979... | Line 7021... | ||
6979 | DRM_DEBUG_KMS("probing HDMI on SDVOC\n"); |
7021 | } |
- | 7022 | } |
|
- | 7023 | ||
6980 | intel_hdmi_init(dev, SDVOC); |
7024 | bool intel_set_mode(struct drm_crtc *crtc, |
- | 7025 | struct drm_display_mode *mode, |
|
- | 7026 | int x, int y, struct drm_framebuffer *fb) |
|
Line -... | Line 7027... | ||
- | 7027 | { |
|
6981 | } |
7028 | struct drm_device *dev = crtc->dev; |
6982 | if (SUPPORTS_INTEGRATED_DP(dev)) { |
7029 | drm_i915_private_t *dev_priv = dev->dev_private; |
6983 | DRM_DEBUG_KMS("probing DP_C\n"); |
7030 | struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode; |
- | 7031 | struct drm_encoder_helper_funcs *encoder_funcs; |
|
Line -... | Line 7032... | ||
- | 7032 | struct drm_encoder *encoder; |
|
6984 | intel_dp_init(dev, DP_C); |
7033 | struct intel_crtc *intel_crtc; |
6985 | } |
7034 | unsigned disable_pipes, prepare_pipes, modeset_pipes; |
- | 7035 | bool ret = true; |
|
- | 7036 | ||
- | 7037 | intel_modeset_affected_pipes(crtc, &modeset_pipes, |
|
Line -... | Line 7038... | ||
- | 7038 | &prepare_pipes, &disable_pipes); |
|
6986 | } |
7039 | |
- | 7040 | DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n", |
|
- | 7041 | modeset_pipes, prepare_pipes, disable_pipes); |
|
Line -... | Line 7042... | ||
- | 7042 | ||
- | 7043 | for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc) |
|
- | 7044 | intel_crtc_disable(&intel_crtc->base); |
|
- | 7045 | ||
- | 7046 | saved_hwmode = crtc->hwmode; |
|
- | 7047 | saved_mode = crtc->mode; |
|
- | 7048 | ||
- | 7049 | /* Hack: Because we don't (yet) support global modeset on multiple |
|
- | 7050 | * crtcs, we don't keep track of the new mode for more than one crtc. |
|
- | 7051 | * Hence simply check whether any bit is set in modeset_pipes in all the |
|
- | 7052 | * pieces of code that are not yet converted to deal with mutliple crtcs |
|
- | 7053 | * changing their mode at the same time. */ |
|
- | 7054 | adjusted_mode = NULL; |
|
- | 7055 | if (modeset_pipes) { |
|
6987 | 7056 | adjusted_mode = intel_modeset_adjusted_mode(crtc, mode); |
|
6988 | if (SUPPORTS_INTEGRATED_DP(dev) && |
7057 | if (IS_ERR(adjusted_mode)) { |
6989 | (I915_READ(DP_D) & DP_DETECTED)) { |
7058 | return false; |
Line 6990... | Line 7059... | ||
6990 | DRM_DEBUG_KMS("probing DP_D\n"); |
7059 | } |
6991 | intel_dp_init(dev, DP_D); |
7060 | } |
Line -... | Line 7061... | ||
- | 7061 | ||
- | 7062 | for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) { |
|
- | 7063 | if (intel_crtc->base.enabled) |
|
6992 | } |
7064 | dev_priv->display.crtc_disable(&intel_crtc->base); |
6993 | } else if (IS_GEN2(dev)) |
7065 | } |
- | 7066 | ||
- | 7067 | /* crtc->mode is already used by the ->mode_set callbacks, hence we need |
|
Line -... | Line 7068... | ||
- | 7068 | * to set it here already despite that we pass it down the callchain. |
|
6994 | intel_dvo_init(dev); |
7069 | */ |
- | 7070 | if (modeset_pipes) |
|
- | 7071 | crtc->mode = *mode; |
|
- | 7072 | ||
- | 7073 | /* Only after disabling all output pipelines that will be changed can we |
|
6995 | 7074 | * update the the output configuration. */ |
|
- | 7075 | intel_modeset_update_state(dev, prepare_pipes); |
|
6996 | // if (SUPPORTS_TV(dev)) |
7076 | |
Line -... | Line 7077... | ||
- | 7077 | /* Set up the DPLL and any encoders state that needs to adjust or depend |
|
- | 7078 | * on the DPLL. |
|
6997 | // intel_tv_init(dev); |
7079 | */ |
- | 7080 | for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) { |
|
Line -... | Line 7081... | ||
- | 7081 | ret = !intel_crtc_mode_set(&intel_crtc->base, |
|
6998 | 7082 | mode, adjusted_mode, |
|
6999 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { |
7083 | x, y, fb); |
7000 | encoder->base.possible_crtcs = encoder->crtc_mask; |
7084 | if (!ret) |
- | 7085 | goto done; |
|
- | 7086 | ||
7001 | encoder->base.possible_clones = |
7087 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
7002 | intel_encoder_clones(dev, encoder->clone_mask); |
7088 | |
- | 7089 | if (encoder->crtc != &intel_crtc->base) |
|
- | 7090 | continue; |
|
7003 | } |
7091 | |
Line -... | Line 7092... | ||
- | 7092 | DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n", |
|
- | 7093 | encoder->base.id, drm_get_encoder_name(encoder), |
|
- | 7094 | mode->base.id, mode->name); |
|
- | 7095 | encoder_funcs = encoder->helper_private; |
|
- | 7096 | encoder_funcs->mode_set(encoder, mode, adjusted_mode); |
|
- | 7097 | } |
|
- | 7098 | } |
|
Line -... | Line 7099... | ||
- | 7099 | ||
- | 7100 | /* Now enable the clocks, plane, pipe, and connectors that we set up. */ |
|
- | 7101 | for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) |
|
- | 7102 | dev_priv->display.crtc_enable(&intel_crtc->base); |
|
Line -... | Line 7103... | ||
- | 7103 | ||
- | 7104 | if (modeset_pipes) { |
|
- | 7105 | /* Store real post-adjustment hardware mode. */ |
|
- | 7106 | crtc->hwmode = *adjusted_mode; |
|
Line -... | Line 7107... | ||
- | 7107 | ||
- | 7108 | /* Calculate and store various constants which |
|
- | 7109 | * are later needed by vblank and swap-completion |
|
- | 7110 | * timestamping. They are derived from true hwmode. |
|
- | 7111 | */ |
|
Line -... | Line 7112... | ||
- | 7112 | drm_calc_timestamping_constants(crtc); |
|
- | 7113 | } |
|
- | 7114 | ||
- | 7115 | /* FIXME: add subpixel order */ |
|
- | 7116 | done: |
|
- | 7117 | drm_mode_destroy(dev, adjusted_mode); |
|
Line -... | Line 7118... | ||
- | 7118 | if (!ret && crtc->enabled) { |
|
Line -... | Line 7119... | ||
- | 7119 | crtc->hwmode = saved_hwmode; |
|
- | 7120 | crtc->mode = saved_mode; |
|
- | 7121 | } else { |
|
- | 7122 | intel_modeset_check_state(dev); |
|
Line -... | Line 7123... | ||
- | 7123 | } |
|
- | 7124 | ||
- | 7125 | return ret; |
|
- | 7126 | } |
|
- | 7127 | ||
- | 7128 | #undef for_each_intel_crtc_masked |
|
Line -... | Line 7129... | ||
- | 7129 | ||
- | 7130 | static void intel_set_config_free(struct intel_set_config *config) |
|
- | 7131 | { |
|
- | 7132 | if (!config) |
|
- | 7133 | return; |
|
Line -... | Line 7134... | ||
- | 7134 | ||
- | 7135 | kfree(config->save_connector_encoders); |
|
- | 7136 | kfree(config->save_encoder_crtcs); |
|
- | 7137 | kfree(config); |
|
- | 7138 | } |
|
- | 7139 | ||
- | 7140 | static int intel_set_config_save_state(struct drm_device *dev, |
|
- | 7141 | struct intel_set_config *config) |
|
Line 7004... | Line 7142... | ||
7004 | 7142 | { |
|
- | 7143 | struct drm_encoder *encoder; |
|
7005 | /* disable all the possible outputs/crtcs before entering KMS mode */ |
7144 | struct drm_connector *connector; |
7006 | // drm_helper_disable_unused_functions(dev); |
7145 | int count; |
- | 7146 | ||
7007 | 7147 | config->save_encoder_crtcs = |
|
7008 | if (HAS_PCH_SPLIT(dev)) |
7148 | kcalloc(dev->mode_config.num_encoder, |
- | 7149 | sizeof(struct drm_crtc *), GFP_KERNEL); |
|
- | 7150 | if (!config->save_encoder_crtcs) |
|
7009 | ironlake_init_pch_refclk(dev); |
7151 | return -ENOMEM; |
- | 7152 | ||
- | 7153 | config->save_connector_encoders = |
|
- | 7154 | kcalloc(dev->mode_config.num_connector, |
|
Line 7010... | Line -... | ||
7010 | - | ||
7011 | LEAVE(); |
7155 | sizeof(struct drm_encoder *), GFP_KERNEL); |
7012 | } |
- | |
7013 | - | ||
7014 | - | ||
7015 | - | ||
7016 | 7156 | if (!config->save_connector_encoders) |
|
Line 7017... | Line 7157... | ||
7017 | 7157 | return -ENOMEM; |
|
7018 | 7158 | ||
7019 | 7159 | /* Copy data. Note that driver private data is not affected. |
|
7020 | 7160 | * Should anything bad happen only the expected state is |
|
7021 | static const struct drm_framebuffer_funcs intel_fb_funcs = { |
7161 | * restored, not the drivers personal bookkeeping. |
7022 | // .destroy = intel_user_framebuffer_destroy, |
7162 | */ |
Line 7023... | Line -... | ||
7023 | // .create_handle = intel_user_framebuffer_create_handle, |
- | |
7024 | }; |
7163 | count = 0; |
7025 | 7164 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
|
7026 | int intel_framebuffer_init(struct drm_device *dev, |
- | |
7027 | struct intel_framebuffer *intel_fb, |
- | |
7028 | struct drm_mode_fb_cmd2 *mode_cmd, |
- | |
7029 | struct drm_i915_gem_object *obj) |
- | |
7030 | { |
7165 | config->save_encoder_crtcs[count++] = encoder->crtc; |
7031 | int ret; |
- | |
7032 | 7166 | } |
|
7033 | if (obj->tiling_mode == I915_TILING_Y) |
7167 | |
7034 | return -EINVAL; |
- | |
7035 | 7168 | count = 0; |
|
7036 | if (mode_cmd->pitches[0] & 63) |
- | |
7037 | return -EINVAL; |
7169 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
7038 | 7170 | config->save_connector_encoders[count++] = connector->encoder; |
|
7039 | switch (mode_cmd->pixel_format) { |
- | |
7040 | case DRM_FORMAT_RGB332: |
- | |
7041 | case DRM_FORMAT_RGB565: |
7171 | } |
7042 | case DRM_FORMAT_XRGB8888: |
7172 | |
7043 | case DRM_FORMAT_ARGB8888: |
- | |
7044 | case DRM_FORMAT_XRGB2101010: |
- | |
7045 | case DRM_FORMAT_ARGB2101010: |
- | |
7046 | /* RGB formats are common across chipsets */ |
- | |
7047 | break; |
- | |
7048 | case DRM_FORMAT_YUYV: |
- | |
7049 | case DRM_FORMAT_UYVY: |
- | |
7050 | case DRM_FORMAT_YVYU: |
- | |
7051 | case DRM_FORMAT_VYUY: |
- | |
7052 | break; |
- | |
7053 | default: |
- | |
7054 | DRM_ERROR("unsupported pixel format\n"); |
7173 | return 0; |
7055 | return -EINVAL; |
- | |
7056 | } |
7174 | } |
Line 7057... | Line 7175... | ||
7057 | 7175 | ||
7058 | ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs); |
7176 | static void intel_set_config_restore_state(struct drm_device *dev, |
7059 | if (ret) { |
7177 | struct intel_set_config *config) |
7060 | DRM_ERROR("framebuffer init failed %d\n", ret); |
7178 | { |
- | 7179 | struct intel_encoder *encoder; |
|
- | 7180 | struct intel_connector *connector; |
|
7061 | return ret; |
7181 | int count; |
Line 7062... | Line -... | ||
7062 | } |
- | |
7063 | - | ||
7064 | drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd); |
7182 | |
7065 | intel_fb->obj = obj; |
- | |
7066 | return 0; |
- | |
7067 | } |
- | |
7068 | - | ||
7069 | - | ||
7070 | static const struct drm_mode_config_funcs intel_mode_funcs = { |
- | |
7071 | .fb_create = NULL /*intel_user_framebuffer_create*/, |
- | |
7072 | .output_poll_changed = NULL /*intel_fb_output_poll_changed*/, |
- | |
Line 7073... | Line 7183... | ||
7073 | }; |
7183 | count = 0; |
7074 | 7184 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { |
|
- | 7185 | encoder->new_crtc = |
|
- | 7186 | to_intel_crtc(config->save_encoder_crtcs[count++]); |
|
Line 7075... | Line 7187... | ||
7075 | 7187 | } |
|
- | 7188 | ||
7076 | 7189 | count = 0; |
|
Line -... | Line 7190... | ||
- | 7190 | list_for_each_entry(connector, &dev->mode_config.connector_list, base.head) { |
|
- | 7191 | connector->new_encoder = |
|
- | 7192 | to_intel_encoder(config->save_connector_encoders[count++]); |
|
- | 7193 | } |
|
7077 | 7194 | } |
|
- | 7195 | ||
- | 7196 | static void |
|
- | 7197 | intel_set_config_compute_mode_changes(struct drm_mode_set *set, |
|
- | 7198 | struct intel_set_config *config) |
|
- | 7199 | { |
|
- | 7200 | ||
Line -... | Line 7201... | ||
- | 7201 | /* We should be able to check here if the fb has the same properties |
|
- | 7202 | * and then just flip_or_move it */ |
|
- | 7203 | if (set->crtc->fb != set->fb) { |
|
- | 7204 | /* If we have no fb then treat it as a full mode set */ |
|
- | 7205 | if (set->crtc->fb == NULL) { |
|
- | 7206 | DRM_DEBUG_KMS("crtc has no fb, full mode set\n"); |
|
- | 7207 | config->mode_changed = true; |
|
- | 7208 | } else if (set->fb == NULL) { |
|
7078 | 7209 | config->mode_changed = true; |
|
7079 | 7210 | } else if (set->fb->depth != set->crtc->fb->depth) { |
|
Line 7080... | Line 7211... | ||
7080 | 7211 | config->mode_changed = true; |
|
- | 7212 | } else if (set->fb->bits_per_pixel != |
|
- | 7213 | set->crtc->fb->bits_per_pixel) { |
|
- | 7214 | config->mode_changed = true; |
|
- | 7215 | } else |
|
7081 | 7216 | config->fb_changed = true; |
|
7082 | 7217 | } |
|
7083 | bool ironlake_set_drps(struct drm_device *dev, u8 val) |
7218 | |
7084 | { |
- | |
7085 | struct drm_i915_private *dev_priv = dev->dev_private; |
7219 | if (set->fb && (set->x != set->crtc->x || set->y != set->crtc->y)) |
7086 | u16 rgvswctl; |
7220 | config->fb_changed = true; |
- | 7221 | ||
Line 7087... | Line -... | ||
7087 | - | ||
7088 | rgvswctl = I915_READ16(MEMSWCTL); |
- | |
7089 | if (rgvswctl & MEMCTL_CMD_STS) { |
- | |
7090 | DRM_DEBUG("gpu busy, RCS change rejected\n"); |
7222 | if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { |
7091 | return false; /* still busy with another command */ |
- | |
Line 7092... | Line -... | ||
7092 | } |
- | |
7093 | - | ||
7094 | rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | |
- | |
7095 | (val << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; |
- | |
7096 | I915_WRITE16(MEMSWCTL, rgvswctl); |
- | |
7097 | POSTING_READ16(MEMSWCTL); |
7223 | DRM_DEBUG_KMS("modes are different, full mode set\n"); |
- | 7224 | drm_mode_debug_printmodeline(&set->crtc->mode); |
|
- | 7225 | drm_mode_debug_printmodeline(set->mode); |
|
- | 7226 | config->mode_changed = true; |
|
- | 7227 | } |
|
- | 7228 | } |
|
- | 7229 | ||
- | 7230 | static int |
|
- | 7231 | intel_modeset_stage_output_state(struct drm_device *dev, |
|
- | 7232 | struct drm_mode_set *set, |
|
- | 7233 | struct intel_set_config *config) |
|
- | 7234 | { |
|
- | 7235 | struct drm_crtc *new_crtc; |
|
- | 7236 | struct intel_connector *connector; |
|
7098 | 7237 | struct intel_encoder *encoder; |
|
7099 | rgvswctl |= MEMCTL_CMD_STS; |
- | |
7100 | I915_WRITE16(MEMSWCTL, rgvswctl); |
- | |
7101 | - | ||
Line -... | Line 7238... | ||
- | 7238 | int count, ro; |
|
- | 7239 | ||
- | 7240 | /* The upper layers ensure that we either disabl a crtc or have a list |
|
- | 7241 | * of connectors. For paranoia, double-check this. */ |
|
- | 7242 | WARN_ON(!set->fb && (set->num_connectors != 0)); |
|
- | 7243 | WARN_ON(set->fb && (set->num_connectors == 0)); |
|
- | 7244 | ||
- | 7245 | count = 0; |
|
- | 7246 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
|
7102 | return true; |
7247 | base.head) { |
7103 | } |
7248 | /* Otherwise traverse passed in connector list and get encoders |
7104 | - | ||
7105 | void ironlake_enable_drps(struct drm_device *dev) |
7249 | * for them. */ |
7106 | { |
- | |
7107 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
7108 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
7250 | for (ro = 0; ro < set->num_connectors; ro++) { |
Line 7109... | Line -... | ||
7109 | u8 fmax, fmin, fstart, vstart; |
- | |
7110 | - | ||
7111 | /* Enable temp reporting */ |
- | |
7112 | I915_WRITE16(PMMISC, I915_READ(PMMISC) | MCPPCE_EN); |
- | |
7113 | I915_WRITE16(TSC1, I915_READ(TSC1) | TSE); |
- | |
7114 | - | ||
7115 | /* 100ms RC evaluation intervals */ |
- | |
7116 | I915_WRITE(RCUPEI, 100000); |
- | |
7117 | I915_WRITE(RCDNEI, 100000); |
- | |
7118 | - | ||
7119 | /* Set max/min thresholds to 90ms and 80ms respectively */ |
- | |
7120 | I915_WRITE(RCBMAXAVG, 90000); |
- | |
7121 | I915_WRITE(RCBMINAVG, 80000); |
- | |
7122 | - | ||
7123 | I915_WRITE(MEMIHYST, 1); |
- | |
7124 | - | ||
7125 | /* Set up min, max, and cur for interrupt handling */ |
- | |
7126 | fmax = (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT; |
- | |
7127 | fmin = (rgvmodectl & MEMMODE_FMIN_MASK); |
- | |
7128 | fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> |
- | |
7129 | MEMMODE_FSTART_SHIFT; |
- | |
7130 | - | ||
7131 | vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> |
- | |
7132 | PXVFREQ_PX_SHIFT; |
- | |
7133 | - | ||
7134 | dev_priv->fmax = fmax; /* IPS callback will increase this */ |
- | |
7135 | dev_priv->fstart = fstart; |
- | |
7136 | - | ||
7137 | dev_priv->max_delay = fstart; |
7251 | if (set->connectors[ro] == &connector->base) { |
7138 | dev_priv->min_delay = fmin; |
- | |
7139 | dev_priv->cur_delay = fstart; |
- | |
7140 | - | ||
7141 | DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", |
- | |
7142 | fmax, fmin, fstart); |
- | |
7143 | - | ||
7144 | I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); |
- | |
7145 | - | ||
7146 | /* |
- | |
7147 | * Interrupts will be enabled in ironlake_irq_postinstall |
- | |
7148 | */ |
- | |
7149 | - | ||
7150 | I915_WRITE(VIDSTART, vstart); |
- | |
7151 | POSTING_READ(VIDSTART); |
- | |
7152 | - | ||
7153 | rgvmodectl |= MEMMODE_SWMODE_EN; |
- | |
7154 | I915_WRITE(MEMMODECTL, rgvmodectl); |
- | |
7155 | - | ||
7156 | if (wait_for((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 10)) |
- | |
7157 | DRM_ERROR("stuck trying to change perf mode\n"); |
- | |
7158 | msleep(1); |
- | |
7159 | - | ||
7160 | ironlake_set_drps(dev, fstart); |
- | |
7161 | - | ||
7162 | dev_priv->last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) + |
- | |
7163 | I915_READ(0x112e0); |
- | |
7164 | // dev_priv->last_time1 = jiffies_to_msecs(jiffies); |
- | |
7165 | dev_priv->last_count2 = I915_READ(0x112f4); |
- | |
7166 | // getrawmonotonic(&dev_priv->last_time2); |
- | |
7167 | } |
- | |
7168 | - | ||
7169 | - | ||
7170 | - | ||
7171 | - | ||
7172 | - | ||
7173 | - | ||
7174 | - | ||
7175 | - | ||
7176 | - | ||
7177 | - | ||
7178 | - | ||
7179 | - | ||
7180 | static unsigned long intel_pxfreq(u32 vidfreq) |
7252 | connector->new_encoder = connector->encoder; |
7181 | { |
- | |
7182 | unsigned long freq; |
- | |
7183 | int div = (vidfreq & 0x3f0000) >> 16; |
- | |
7184 | int post = (vidfreq & 0x3000) >> 12; |
- | |
7185 | int pre = (vidfreq & 0x7); |
- | |
7186 | - | ||
7187 | if (!pre) |
- | |
7188 | return 0; |
- | |
7189 | - | ||
7190 | freq = ((div * 133333) / ((1< |
- | |
7191 | - | ||
7192 | return freq; |
- | |
7193 | } |
7253 | break; |
7194 | - | ||
7195 | void intel_init_emon(struct drm_device *dev) |
- | |
7196 | { |
- | |
7197 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
7198 | u32 lcfuse; |
7254 | } |
7199 | u8 pxw[16]; |
- | |
7200 | int i; |
- | |
7201 | - | ||
7202 | /* Disable to program */ |
- | |
7203 | I915_WRITE(ECR, 0); |
- | |
7204 | POSTING_READ(ECR); |
- | |
7205 | - | ||
7206 | /* Program energy weights for various events */ |
- | |
7207 | I915_WRITE(SDEW, 0x15040d00); |
- | |
7208 | I915_WRITE(CSIEW0, 0x007f0000); |
- | |
7209 | I915_WRITE(CSIEW1, 0x1e220004); |
- | |
7210 | I915_WRITE(CSIEW2, 0x04000004); |
- | |
7211 | - | ||
7212 | for (i = 0; i < 5; i++) |
- | |
7213 | I915_WRITE(PEW + (i * 4), 0); |
- | |
7214 | for (i = 0; i < 3; i++) |
- | |
7215 | I915_WRITE(DEW + (i * 4), 0); |
- | |
7216 | - | ||
7217 | /* Program P-state weights to account for frequency power adjustment */ |
- | |
7218 | for (i = 0; i < 16; i++) { |
- | |
7219 | u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4)); |
- | |
7220 | unsigned long freq = intel_pxfreq(pxvidfreq); |
- | |
7221 | unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >> |
- | |
7222 | PXVFREQ_PX_SHIFT; |
- | |
7223 | unsigned long val; |
- | |
7224 | - | ||
7225 | val = vid * vid; |
- | |
7226 | val *= (freq / 1000); |
- | |
7227 | val *= 255; |
- | |
7228 | val /= (127*127*900); |
- | |
7229 | if (val > 0xff) |
- | |
7230 | DRM_ERROR("bad pxval: %ld\n", val); |
- | |
7231 | pxw[i] = val; |
- | |
7232 | } |
- | |
7233 | /* Render standby states get 0 weight */ |
- | |
7234 | pxw[14] = 0; |
- | |
7235 | pxw[15] = 0; |
- | |
7236 | - | ||
7237 | for (i = 0; i < 4; i++) { |
- | |
Line 7238... | Line 7255... | ||
7238 | u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) | |
7255 | } |
- | 7256 | ||
- | 7257 | /* If we disable the crtc, disable all its connectors. Also, if |
|
7239 | (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]); |
7258 | * the connector is on the changing crtc but not on the new |
- | 7259 | * connector list, disable it. */ |
|
- | 7260 | if ((!set->fb || ro == set->num_connectors) && |
|
Line -... | Line 7261... | ||
- | 7261 | connector->base.encoder && |
|
- | 7262 | connector->base.encoder->crtc == set->crtc) { |
|
7240 | I915_WRITE(PXW + (i * 4), val); |
7263 | connector->new_encoder = NULL; |
- | 7264 | ||
- | 7265 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n", |
|
Line 7241... | Line -... | ||
7241 | } |
- | |
7242 | - | ||
7243 | /* Adjust magic regs to magic values (more experimental results) */ |
7266 | connector->base.base.id, |
7244 | I915_WRITE(OGW0, 0); |
- | |
7245 | I915_WRITE(OGW1, 0); |
- | |
7246 | I915_WRITE(EG0, 0x00007f00); |
- | |
7247 | I915_WRITE(EG1, 0x0000000e); |
7267 | drm_get_connector_name(&connector->base)); |
7248 | I915_WRITE(EG2, 0x000e0000); |
7268 | } |
Line 7249... | Line -... | ||
7249 | I915_WRITE(EG3, 0x68000300); |
- | |
7250 | I915_WRITE(EG4, 0x42000000); |
- | |
7251 | I915_WRITE(EG5, 0x00140031); |
- | |
7252 | I915_WRITE(EG6, 0); |
- | |
7253 | I915_WRITE(EG7, 0); |
- | |
7254 | - | ||
7255 | for (i = 0; i < 8; i++) |
- | |
7256 | I915_WRITE(PXWL + (i * 4), 0); |
7269 | |
7257 | - | ||
Line 7258... | Line -... | ||
7258 | /* Enable PMON + select events */ |
- | |
7259 | I915_WRITE(ECR, 0x80000019); |
7270 | |
7260 | 7271 | if (&connector->new_encoder->base != connector->base.encoder) { |
|
7261 | lcfuse = I915_READ(LCFUSE02); |
- | |
7262 | 7272 | DRM_DEBUG_KMS("encoder changed, full mode switch\n"); |
|
7263 | dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); |
- | |
7264 | } |
7273 | config->mode_changed = true; |
7265 | - | ||
7266 | static bool intel_enable_rc6(struct drm_device *dev) |
7274 | } |
7267 | { |
- | |
7268 | /* |
7275 | |
Line -... | Line 7276... | ||
- | 7276 | /* Disable all disconnected encoders. */ |
|
- | 7277 | if (connector->base.status == connector_status_disconnected) |
|
- | 7278 | connector->new_encoder = NULL; |
|
7269 | * Respect the kernel parameter if it is set |
7279 | } |
- | 7280 | /* connector->new_encoder is now updated for all connectors. */ |
|
- | 7281 | ||
7270 | */ |
7282 | /* Update crtc of enabled connectors. */ |
Line -... | Line 7283... | ||
- | 7283 | count = 0; |
|
7271 | if (i915_enable_rc6 >= 0) |
7284 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
7272 | return i915_enable_rc6; |
- | |
7273 | 7285 | base.head) { |
|
7274 | /* |
7286 | if (!connector->new_encoder) |
Line 7275... | Line -... | ||
7275 | * Disable RC6 on Ironlake |
- | |
7276 | */ |
7287 | continue; |
7277 | if (INTEL_INFO(dev)->gen == 5) |
- | |
7278 | return 0; |
- | |
7279 | - | ||
7280 | /* |
- | |
Line 7281... | Line -... | ||
7281 | * Disable rc6 on Sandybridge |
- | |
7282 | */ |
- | |
7283 | if (INTEL_INFO(dev)->gen == 6) { |
7288 | |
7284 | DRM_DEBUG_DRIVER("Sandybridge: RC6 disabled\n"); |
- | |
7285 | return 0; |
- | |
Line 7286... | Line 7289... | ||
7286 | } |
7289 | new_crtc = connector->new_encoder->base.crtc; |
- | 7290 | ||
- | 7291 | for (ro = 0; ro < set->num_connectors; ro++) { |
|
Line 7287... | Line 7292... | ||
7287 | DRM_DEBUG_DRIVER("RC6 enabled\n"); |
7292 | if (set->connectors[ro] == &connector->base) |
7288 | return 1; |
- | |
7289 | } |
- | |
7290 | - | ||
7291 | void gen6_enable_rps(struct drm_i915_private *dev_priv) |
- | |
7292 | { |
- | |
7293 | u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); |
- | |
7294 | u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); |
- | |
7295 | u32 pcu_mbox, rc6_mask = 0; |
- | |
7296 | int cur_freq, min_freq, max_freq; |
- | |
7297 | int i; |
- | |
7298 | - | ||
7299 | /* Here begins a magic sequence of register writes to enable |
- | |
7300 | * auto-downclocking. |
- | |
7301 | * |
- | |
7302 | * Perhaps there might be some value in exposing these to |
- | |
7303 | * userspace... |
- | |
7304 | */ |
- | |
7305 | I915_WRITE(GEN6_RC_STATE, 0); |
- | |
Line 7306... | Line -... | ||
7306 | mutex_lock(&dev_priv->dev->struct_mutex); |
- | |
7307 | gen6_gt_force_wake_get(dev_priv); |
7293 | new_crtc = set->crtc; |
7308 | - | ||
7309 | /* disable the counters and set deterministic thresholds */ |
7294 | } |
7310 | I915_WRITE(GEN6_RC_CONTROL, 0); |
- | |
7311 | - | ||
7312 | I915_WRITE(GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16); |
- | |
7313 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30); |
- | |
7314 | I915_WRITE(GEN6_RC6pp_WAKE_RATE_LIMIT, 30); |
- | |
7315 | I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); |
- | |
7316 | I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); |
- | |
7317 | - | ||
7318 | for (i = 0; i < I915_NUM_RINGS; i++) |
- | |
7319 | I915_WRITE(RING_MAX_IDLE(dev_priv->ring[i].mmio_base), 10); |
- | |
7320 | - | ||
7321 | I915_WRITE(GEN6_RC_SLEEP, 0); |
- | |
7322 | I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); |
- | |
7323 | I915_WRITE(GEN6_RC6_THRESHOLD, 50000); |
- | |
7324 | I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); |
- | |
7325 | I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ |
- | |
7326 | - | ||
7327 | if (intel_enable_rc6(dev_priv->dev)) |
- | |
7328 | rc6_mask = GEN6_RC_CTL_RC6p_ENABLE | |
- | |
7329 | GEN6_RC_CTL_RC6_ENABLE; |
- | |
7330 | - | ||
7331 | I915_WRITE(GEN6_RC_CONTROL, |
- | |
7332 | rc6_mask | |
- | |
7333 | GEN6_RC_CTL_EI_MODE(1) | |
- | |
7334 | GEN6_RC_CTL_HW_ENABLE); |
- | |
7335 | - | ||
7336 | I915_WRITE(GEN6_RPNSWREQ, |
7295 | |
7337 | GEN6_FREQUENCY(10) | |
7296 | /* Make sure the new CRTC will work with the encoder */ |
7338 | GEN6_OFFSET(0) | |
- | |
7339 | GEN6_AGGRESSIVE_TURBO); |
7297 | if (!intel_encoder_crtc_ok(&connector->new_encoder->base, |
7340 | I915_WRITE(GEN6_RC_VIDEO_FREQ, |
- | |
7341 | GEN6_FREQUENCY(12)); |
- | |
7342 | - | ||
7343 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); |
- | |
7344 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, |
- | |
7345 | 18 << 24 | |
- | |
7346 | 6 << 16); |
- | |
7347 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000); |
- | |
7348 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000); |
- | |
7349 | I915_WRITE(GEN6_RP_UP_EI, 100000); |
- | |
7350 | I915_WRITE(GEN6_RP_DOWN_EI, 5000000); |
- | |
7351 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); |
- | |
7352 | I915_WRITE(GEN6_RP_CONTROL, |
- | |
7353 | GEN6_RP_MEDIA_TURBO | |
- | |
7354 | GEN6_RP_MEDIA_HW_MODE | |
- | |
7355 | GEN6_RP_MEDIA_IS_GFX | |
- | |
7356 | GEN6_RP_ENABLE | |
7298 | new_crtc)) { |
7357 | GEN6_RP_UP_BUSY_AVG | |
- | |
7358 | GEN6_RP_DOWN_IDLE_CONT); |
- | |
7359 | - | ||
7360 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, |
- | |
7361 | 500)) |
- | |
7362 | DRM_ERROR("timeout waiting for pcode mailbox to become idle\n"); |
- | |
7363 | - | ||
Line 7364... | Line -... | ||
7364 | I915_WRITE(GEN6_PCODE_DATA, 0); |
- | |
7365 | I915_WRITE(GEN6_PCODE_MAILBOX, |
- | |
7366 | GEN6_PCODE_READY | |
7299 | return -EINVAL; |
7367 | GEN6_PCODE_WRITE_MIN_FREQ_TABLE); |
- | |
7368 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, |
- | |
7369 | 500)) |
- | |
7370 | DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); |
- | |
7371 | - | ||
7372 | min_freq = (rp_state_cap & 0xff0000) >> 16; |
- | |
7373 | max_freq = rp_state_cap & 0xff; |
- | |
7374 | cur_freq = (gt_perf_status & 0xff00) >> 8; |
- | |
7375 | - | ||
7376 | /* Check for overclock support */ |
- | |
7377 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, |
- | |
7378 | 500)) |
- | |
7379 | DRM_ERROR("timeout waiting for pcode mailbox to become idle\n"); |
- | |
7380 | I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_READ_OC_PARAMS); |
- | |
7381 | pcu_mbox = I915_READ(GEN6_PCODE_DATA); |
- | |
7382 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, |
7300 | } |
Line 7383... | Line 7301... | ||
7383 | 500)) |
7301 | connector->encoder->new_crtc = to_intel_crtc(new_crtc); |
7384 | DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); |
7302 | |
7385 | if (pcu_mbox & (1<<31)) { /* OC supported */ |
- | |
7386 | max_freq = pcu_mbox & 0xff; |
7303 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n", |
7387 | DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 50); |
- | |
7388 | } |
7304 | connector->base.base.id, |
- | 7305 | drm_get_connector_name(&connector->base), |
|
- | 7306 | new_crtc->base.id); |
|
- | 7307 | } |
|
- | 7308 | ||
- | 7309 | /* Check for any encoders that needs to be disabled. */ |
|
7389 | 7310 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
|
Line 7390... | Line 7311... | ||
7390 | /* In units of 100MHz */ |
7311 | base.head) { |
7391 | dev_priv->max_delay = max_freq; |
7312 | list_for_each_entry(connector, |
7392 | dev_priv->min_delay = min_freq; |
7313 | &dev->mode_config.connector_list, |
7393 | dev_priv->cur_delay = cur_freq; |
7314 | base.head) { |
7394 | 7315 | if (connector->new_encoder == encoder) { |
|
7395 | /* requires MSI enabled */ |
- | |
7396 | I915_WRITE(GEN6_PMIER, |
7316 | WARN_ON(!connector->new_encoder->new_crtc); |
Line 7397... | Line -... | ||
7397 | GEN6_PM_MBOX_EVENT | |
- | |
7398 | GEN6_PM_THERMAL_EVENT | |
7317 | |
7399 | GEN6_PM_RP_DOWN_TIMEOUT | |
7318 | goto next_encoder; |
Line 7400... | Line 7319... | ||
7400 | GEN6_PM_RP_UP_THRESHOLD | |
7319 | } |
- | 7320 | } |
|
Line 7401... | Line 7321... | ||
7401 | GEN6_PM_RP_DOWN_THRESHOLD | |
7321 | encoder->new_crtc = NULL; |
7402 | GEN6_PM_RP_UP_EI_EXPIRED | |
7322 | next_encoder: |
7403 | GEN6_PM_RP_DOWN_EI_EXPIRED); |
7323 | /* Only now check for crtc changes so we don't miss encoders |
Line 7404... | Line 7324... | ||
7404 | // spin_lock_irq(&dev_priv->rps_lock); |
7324 | * that will be disabled. */ |
7405 | // WARN_ON(dev_priv->pm_iir != 0); |
- | |
7406 | I915_WRITE(GEN6_PMIMR, 0); |
- | |
7407 | // spin_unlock_irq(&dev_priv->rps_lock); |
- | |
7408 | /* enable all PM interrupts */ |
- | |
7409 | I915_WRITE(GEN6_PMINTRMSK, 0); |
7325 | if (&encoder->new_crtc->base != encoder->base.crtc) { |
- | 7326 | DRM_DEBUG_KMS("crtc changed, full mode switch\n"); |
|
- | 7327 | config->mode_changed = true; |
|
7410 | 7328 | } |
|
Line 7411... | Line 7329... | ||
7411 | gen6_gt_force_wake_put(dev_priv); |
7329 | } |
7412 | mutex_unlock(&dev_priv->dev->struct_mutex); |
7330 | /* Now we've also updated encoder->new_crtc for all encoders. */ |
7413 | } |
7331 | |
7414 | - | ||
Line 7415... | Line -... | ||
7415 | void gen6_update_ring_freq(struct drm_i915_private *dev_priv) |
- | |
7416 | { |
- | |
7417 | int min_freq = 15; |
- | |
7418 | int gpu_freq, ia_freq, max_ia_freq; |
- | |
7419 | int scaling_factor = 180; |
- | |
7420 | - | ||
7421 | // max_ia_freq = cpufreq_quick_get_max(0); |
- | |
7422 | /* |
- | |
7423 | * Default to measured freq if none found, PCU will ensure we don't go |
7332 | return 0; |
7424 | * over |
- | |
7425 | */ |
7333 | } |
7426 | // if (!max_ia_freq) |
- | |
Line 7427... | Line 7334... | ||
7427 | max_ia_freq = 3000000; //tsc_khz; |
7334 | |
- | 7335 | static int intel_crtc_set_config(struct drm_mode_set *set) |
|
7428 | 7336 | { |
|
- | 7337 | struct drm_device *dev; |
|
7429 | /* Convert from kHz to MHz */ |
7338 | struct drm_mode_set save_set; |
- | 7339 | struct intel_set_config *config; |
|
Line 7430... | Line -... | ||
7430 | max_ia_freq /= 1000; |
- | |
7431 | - | ||
7432 | mutex_lock(&dev_priv->dev->struct_mutex); |
- | |
7433 | - | ||
7434 | /* |
7340 | int ret; |
7435 | * For each potential GPU frequency, load a ring frequency we'd like |
7341 | |
Line 7436... | Line 7342... | ||
7436 | * to use for memory access. We do this by specifying the IA frequency |
7342 | BUG_ON(!set); |
7437 | * the PCU should use as a reference to determine the ring frequency. |
7343 | BUG_ON(!set->crtc); |
7438 | */ |
7344 | BUG_ON(!set->crtc->helper_private); |
- | 7345 | ||
- | 7346 | if (!set->mode) |
|
- | 7347 | set->fb = NULL; |
|
Line 7439... | Line -... | ||
7439 | for (gpu_freq = dev_priv->max_delay; gpu_freq >= dev_priv->min_delay; |
- | |
7440 | gpu_freq--) { |
7348 | |
7441 | int diff = dev_priv->max_delay - gpu_freq; |
7349 | /* The fb helper likes to play gross jokes with ->mode_set_config. |
7442 | 7350 | * Unfortunately the crtc helper doesn't do much at all for this case, |
|
7443 | /* |
- | |
7444 | * For GPU frequencies less than 750MHz, just use the lowest |
7351 | * so we have to cope with this madness until the fb helper is fixed up. */ |
7445 | * ring freq. |
7352 | if (set->fb && set->num_connectors == 0) |
Line 7446... | Line 7353... | ||
7446 | */ |
7353 | return 0; |
7447 | if (gpu_freq < min_freq) |
- | |
7448 | ia_freq = 800; |
- | |
7449 | else |
7354 | |
Line -... | Line 7355... | ||
- | 7355 | if (set->fb) { |
|
7450 | ia_freq = max_ia_freq - ((diff * scaling_factor) / 2); |
7356 | DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n", |
- | 7357 | set->crtc->base.id, set->fb->base.id, |
|
7451 | ia_freq = DIV_ROUND_CLOSEST(ia_freq, 100); |
7358 | (int)set->num_connectors, set->x, set->y); |
7452 | 7359 | } else { |
|
7453 | I915_WRITE(GEN6_PCODE_DATA, |
7360 | DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); |
Line 7454... | Line -... | ||
7454 | (ia_freq << GEN6_PCODE_FREQ_IA_RATIO_SHIFT) | |
- | |
7455 | gpu_freq); |
- | |
7456 | I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | |
7361 | } |
Line 7457... | Line 7362... | ||
7457 | GEN6_PCODE_WRITE_MIN_FREQ_TABLE); |
7362 | |
7458 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & |
7363 | dev = set->crtc->dev; |
Line 7459... | Line 7364... | ||
7459 | GEN6_PCODE_READY) == 0, 10)) { |
7364 | |
- | 7365 | ret = -ENOMEM; |
|
- | 7366 | config = kzalloc(sizeof(*config), GFP_KERNEL); |
|
- | 7367 | if (!config) |
|
- | 7368 | goto out_config; |
|
7460 | DRM_ERROR("pcode write of freq table timed out\n"); |
7369 | |
7461 | continue; |
7370 | ret = intel_set_config_save_state(dev, config); |
- | 7371 | if (ret) |
|
- | 7372 | goto out_config; |
|
- | 7373 | ||
- | 7374 | save_set.crtc = set->crtc; |
|
- | 7375 | save_set.mode = &set->crtc->mode; |
|
- | 7376 | save_set.x = set->crtc->x; |
|
- | 7377 | save_set.y = set->crtc->y; |
|
- | 7378 | save_set.fb = set->crtc->fb; |
|
- | 7379 | ||
- | 7380 | /* Compute whether we need a full modeset, only an fb base update or no |
|
- | 7381 | * change at all. In the future we might also check whether only the |
|
Line -... | Line 7382... | ||
- | 7382 | * mode changed, e.g. for LVDS where we only change the panel fitter in |
|
- | 7383 | * such cases. */ |
|
- | 7384 | intel_set_config_compute_mode_changes(set, config); |
|
- | 7385 | ||
- | 7386 | ret = intel_modeset_stage_output_state(dev, set, config); |
|
7462 | } |
7387 | if (ret) |
- | 7388 | goto fail; |
|
7463 | } |
7389 | |
Line 7464... | Line 7390... | ||
7464 | 7390 | if (config->mode_changed) { |
|
7465 | mutex_unlock(&dev_priv->dev->struct_mutex); |
- | |
7466 | } |
7391 | if (set->mode) { |
Line 7467... | Line -... | ||
7467 | - | ||
7468 | static void ironlake_init_clock_gating(struct drm_device *dev) |
7392 | DRM_DEBUG_KMS("attempting to set mode from" |
7469 | { |
- | |
7470 | struct drm_i915_private *dev_priv = dev->dev_private; |
7393 | " userspace\n"); |
7471 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; |
- | |
7472 | - | ||
7473 | /* Required for FBC */ |
- | |
Line 7474... | Line 7394... | ||
7474 | dspclk_gate |= DPFCUNIT_CLOCK_GATE_DISABLE | |
7394 | drm_mode_debug_printmodeline(set->mode); |
7475 | DPFCRUNIT_CLOCK_GATE_DISABLE | |
- | |
7476 | DPFDUNIT_CLOCK_GATE_DISABLE; |
7395 | } |
7477 | /* Required for CxSR */ |
- | |
Line 7478... | Line -... | ||
7478 | dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE; |
- | |
7479 | 7396 | ||
7480 | I915_WRITE(PCH_3DCGDIS0, |
7397 | if (!intel_set_mode(set->crtc, set->mode, |
7481 | MARIUNIT_CLOCK_GATE_DISABLE | |
7398 | set->x, set->y, set->fb)) { |
7482 | SVSMUNIT_CLOCK_GATE_DISABLE); |
7399 | DRM_ERROR("failed to set mode on [CRTC:%d]\n", |
- | 7400 | set->crtc->base.id); |
|
7483 | I915_WRITE(PCH_3DCGDIS1, |
7401 | ret = -EINVAL; |
7484 | VFMUNIT_CLOCK_GATE_DISABLE); |
7402 | goto fail; |
7485 | 7403 | } |
|
- | 7404 | } else if (config->fb_changed) { |
|
7486 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); |
7405 | ret = intel_pipe_set_base(set->crtc, |
7487 | 7406 | set->x, set->y, set->fb); |
|
7488 | /* |
7407 | } |
7489 | * According to the spec the following bits should be set in |
7408 | |
Line 7490... | Line 7409... | ||
7490 | * order to enable memory self-refresh |
7409 | intel_set_config_free(config); |
7491 | * The bit 22/21 of 0x42004 |
- | |
7492 | * The bit 5 of 0x42020 |
7410 | |
Line -... | Line 7411... | ||
- | 7411 | return 0; |
|
7493 | * The bit 15 of 0x45000 |
7412 | |
7494 | */ |
7413 | fail: |
- | 7414 | intel_set_config_restore_state(dev, config); |
|
- | 7415 | ||
- | 7416 | /* Try to restore the config */ |
|
- | 7417 | if (config->mode_changed && |
|
- | 7418 | !intel_set_mode(save_set.crtc, save_set.mode, |
|
7495 | I915_WRITE(ILK_DISPLAY_CHICKEN2, |
7419 | save_set.x, save_set.y, save_set.fb)) |
- | 7420 | DRM_ERROR("failed to restore config after modeset failure\n"); |
|
- | 7421 | ||
7496 | (I915_READ(ILK_DISPLAY_CHICKEN2) | |
7422 | out_config: |
7497 | ILK_DPARB_GATE | ILK_VSDPFD_FULL)); |
7423 | intel_set_config_free(config); |
Line 7498... | Line 7424... | ||
7498 | I915_WRITE(ILK_DSPCLK_GATE, |
7424 | return ret; |
7499 | (I915_READ(ILK_DSPCLK_GATE) | |
7425 | } |
7500 | ILK_DPARB_CLK_GATE)); |
- | |
7501 | I915_WRITE(DISP_ARB_CTL, |
7426 | |
7502 | (I915_READ(DISP_ARB_CTL) | |
7427 | static const struct drm_crtc_funcs intel_crtc_funcs = { |
7503 | DISP_FBC_WM_DIS)); |
7428 | // .cursor_set = intel_crtc_cursor_set, |
Line 7504... | Line 7429... | ||
7504 | I915_WRITE(WM3_LP_ILK, 0); |
7429 | // .cursor_move = intel_crtc_cursor_move, |
7505 | I915_WRITE(WM2_LP_ILK, 0); |
- | |
7506 | I915_WRITE(WM1_LP_ILK, 0); |
- | |
Line 7507... | Line 7430... | ||
7507 | 7430 | .gamma_set = intel_crtc_gamma_set, |
|
7508 | /* |
7431 | .set_config = intel_crtc_set_config, |
7509 | * Based on the document from hardware guys the following bits |
7432 | .destroy = intel_crtc_destroy, |
7510 | * should be set unconditionally in order to enable FBC. |
- | |
7511 | * The bit 22 of 0x42000 |
7433 | // .page_flip = intel_crtc_page_flip, |
Line 7512... | Line -... | ||
7512 | * The bit 22 of 0x42004 |
- | |
7513 | * The bit 7,8,9 of 0x42020. |
7434 | }; |
Line -... | Line 7435... | ||
- | 7435 | ||
7514 | */ |
7436 | static void intel_pch_pll_init(struct drm_device *dev) |
- | 7437 | { |
|
- | 7438 | drm_i915_private_t *dev_priv = dev->dev_private; |
|
- | 7439 | int i; |
|
- | 7440 | ||
7515 | if (IS_IRONLAKE_M(dev)) { |
7441 | if (dev_priv->num_pch_pll == 0) { |
7516 | I915_WRITE(ILK_DISPLAY_CHICKEN1, |
7442 | DRM_DEBUG_KMS("No PCH PLLs on this hardware, skipping initialisation\n"); |
7517 | I915_READ(ILK_DISPLAY_CHICKEN1) | |
- | |
7518 | ILK_FBCQ_DIS); |
- | |
7519 | I915_WRITE(ILK_DISPLAY_CHICKEN2, |
7443 | return; |
Line -... | Line 7444... | ||
- | 7444 | } |
|
- | 7445 | ||
- | 7446 | for (i = 0; i < dev_priv->num_pch_pll; i++) { |
|
7520 | I915_READ(ILK_DISPLAY_CHICKEN2) | |
7447 | dev_priv->pch_plls[i].pll_reg = _PCH_DPLL(i); |
7521 | ILK_DPARB_GATE); |
7448 | dev_priv->pch_plls[i].fp0_reg = _PCH_FP0(i); |
- | 7449 | dev_priv->pch_plls[i].fp1_reg = _PCH_FP1(i); |
|
7522 | I915_WRITE(ILK_DSPCLK_GATE, |
7450 | } |
Line 7523... | Line 7451... | ||
7523 | I915_READ(ILK_DSPCLK_GATE) | |
7451 | } |
7524 | ILK_DPFC_DIS1 | |
7452 | |
7525 | ILK_DPFC_DIS2 | |
- | |
7526 | ILK_CLK_FBC); |
- | |
Line 7527... | Line 7453... | ||
7527 | } |
7453 | static void intel_crtc_init(struct drm_device *dev, int pipe) |
7528 | 7454 | { |
|
7529 | I915_WRITE(ILK_DISPLAY_CHICKEN2, |
7455 | drm_i915_private_t *dev_priv = dev->dev_private; |
7530 | I915_READ(ILK_DISPLAY_CHICKEN2) | |
7456 | struct intel_crtc *intel_crtc; |
7531 | ILK_ELPIN_409_SELECT); |
- | |
7532 | I915_WRITE(_3D_CHICKEN2, |
7457 | int i; |
Line -... | Line 7458... | ||
- | 7458 | ||
7533 | _3D_CHICKEN2_WM_READ_PIPELINED << 16 | |
7459 | intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); |
7534 | _3D_CHICKEN2_WM_READ_PIPELINED); |
7460 | if (intel_crtc == NULL) |
Line -... | Line 7461... | ||
- | 7461 | return; |
|
- | 7462 | ||
- | 7463 | drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs); |
|
- | 7464 | ||
- | 7465 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); |
|
- | 7466 | for (i = 0; i < 256; i++) { |
|
- | 7467 | intel_crtc->lut_r[i] = i; |
|
7535 | } |
7468 | intel_crtc->lut_g[i] = i; |
- | 7469 | intel_crtc->lut_b[i] = i; |
|
- | 7470 | } |
|
- | 7471 | ||
7536 | 7472 | /* Swap pipes & planes for FBC on pre-965 */ |
|
7537 | static void gen6_init_clock_gating(struct drm_device *dev) |
- | |
7538 | { |
7473 | intel_crtc->pipe = pipe; |
Line 7539... | Line -... | ||
7539 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
7540 | int pipe; |
- | |
7541 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; |
- | |
7542 | 7474 | intel_crtc->plane = pipe; |
|
7543 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); |
7475 | if (IS_MOBILE(dev) && IS_GEN3(dev)) { |
Line 7544... | Line 7476... | ||
7544 | 7476 | DRM_DEBUG_KMS("swapping pipes & planes for FBC\n"); |
|
7545 | I915_WRITE(ILK_DISPLAY_CHICKEN2, |
- | |
7546 | I915_READ(ILK_DISPLAY_CHICKEN2) | |
- | |
7547 | ILK_ELPIN_409_SELECT); |
- | |
7548 | 7477 | intel_crtc->plane = !pipe; |
|
7549 | I915_WRITE(WM3_LP_ILK, 0); |
- | |
Line 7550... | Line -... | ||
7550 | I915_WRITE(WM2_LP_ILK, 0); |
- | |
7551 | I915_WRITE(WM1_LP_ILK, 0); |
7478 | } |
7552 | 7479 | ||
- | 7480 | BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || |
|
- | 7481 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL); |
|
- | 7482 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base; |
|
- | 7483 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; |
|
- | 7484 | ||
- | 7485 | intel_crtc->bpp = 24; /* default for pre-Ironlake */ |
|
- | 7486 | ||
7553 | /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock |
7487 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); |
- | 7488 | ||
- | 7489 | dbgprintf("CRTC %d mode %x FB %x enable %d\n", |
|
7554 | * gating disable must be set. Failure to set it results in |
7490 | intel_crtc->base.base.id, intel_crtc->base.mode, |
7555 | * flickering pixels due to Z write ordering failures after |
7491 | intel_crtc->base.fb, intel_crtc->base.enabled); |
7556 | * some amount of runtime in the Mesa "fire" demo, and Unigine |
7492 | |
- | 7493 | } |
|
7557 | * Sanctuary and Tropics, and apparently anything else with |
7494 | |
7558 | * alpha test or pixel discard. |
7495 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
7559 | * |
7496 | struct drm_file *file) |
7560 | * According to the spec, bit 11 (RCCUNIT) must also be set, |
7497 | { |
Line 7561... | Line -... | ||
7561 | * but we didn't debug actual testcases to find it out. |
- | |
7562 | */ |
- | |
7563 | I915_WRITE(GEN6_UCGCTL2, |
- | |
7564 | GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | |
- | |
7565 | GEN6_RCCUNIT_CLOCK_GATE_DISABLE); |
- | |
7566 | - | ||
7567 | /* |
- | |
7568 | * According to the spec the following bits should be |
- | |
7569 | * set in order to enable memory self-refresh and fbc: |
- | |
7570 | * The bit21 and bit22 of 0x42000 |
- | |
7571 | * The bit21 and bit22 of 0x42004 |
- | |
7572 | * The bit5 and bit7 of 0x42020 |
- | |
7573 | * The bit14 of 0x70180 |
- | |
7574 | * The bit14 of 0x71180 |
- | |
7575 | */ |
- | |
7576 | I915_WRITE(ILK_DISPLAY_CHICKEN1, |
- | |
7577 | I915_READ(ILK_DISPLAY_CHICKEN1) | |
- | |
7578 | ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); |
7498 | struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; |
7579 | I915_WRITE(ILK_DISPLAY_CHICKEN2, |
7499 | struct drm_mode_object *drmmode_obj; |
7580 | I915_READ(ILK_DISPLAY_CHICKEN2) | |
7500 | struct intel_crtc *crtc; |
7581 | ILK_DPARB_GATE | ILK_VSDPFD_FULL); |
- | |
7582 | I915_WRITE(ILK_DSPCLK_GATE, |
- | |
7583 | I915_READ(ILK_DSPCLK_GATE) | |
7501 | |
7584 | ILK_DPARB_CLK_GATE | |
7502 | drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id, |
7585 | ILK_DPFD_CLK_GATE); |
- | |
Line 7586... | Line 7503... | ||
7586 | 7503 | DRM_MODE_OBJECT_CRTC); |
|
7587 | for_each_pipe(pipe) { |
7504 | |
7588 | I915_WRITE(DSPCNTR(pipe), |
7505 | if (!drmmode_obj) { |
7589 | I915_READ(DSPCNTR(pipe)) | |
7506 | DRM_ERROR("no such CRTC id\n"); |
Line 7590... | Line -... | ||
7590 | DISPPLANE_TRICKLE_FEED_DISABLE); |
- | |
7591 | intel_flush_display_plane(dev_priv, pipe); |
- | |
7592 | } |
- | |
7593 | } |
- | |
7594 | - | ||
Line -... | Line 7507... | ||
- | 7507 | return -EINVAL; |
|
7595 | static void ivybridge_init_clock_gating(struct drm_device *dev) |
7508 | } |
7596 | { |
7509 | |
7597 | struct drm_i915_private *dev_priv = dev->dev_private; |
7510 | crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); |
Line 7598... | Line 7511... | ||
7598 | int pipe; |
7511 | pipe_from_crtc_id->pipe = crtc->pipe; |
7599 | uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; |
7512 | |
7600 | 7513 | return 0; |
|
7601 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); |
7514 | } |
Line 7602... | Line 7515... | ||
7602 | 7515 | ||
7603 | I915_WRITE(WM3_LP_ILK, 0); |
7516 | static int intel_encoder_clones(struct intel_encoder *encoder) |
7604 | I915_WRITE(WM2_LP_ILK, 0); |
- | |
7605 | I915_WRITE(WM1_LP_ILK, 0); |
7517 | { |
- | 7518 | struct drm_device *dev = encoder->base.dev; |
|
- | 7519 | struct intel_encoder *source_encoder; |
|
- | 7520 | int index_mask = 0; |
|
7606 | 7521 | int entry = 0; |
|
7607 | I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); |
7522 | |
7608 | - | ||
7609 | I915_WRITE(IVB_CHICKEN3, |
7523 | list_for_each_entry(source_encoder, |
- | 7524 | &dev->mode_config.encoder_list, base.head) { |
|
- | 7525 | ||
- | 7526 | if (encoder == source_encoder) |
|
7610 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | |
7527 | index_mask |= (1 << entry); |
7611 | CHICKEN3_DGMG_DONE_FIX_DISABLE); |
7528 | |
Line 7612... | Line -... | ||
7612 | - | ||
7613 | for_each_pipe(pipe) { |
- | |
7614 | I915_WRITE(DSPCNTR(pipe), |
- | |
7615 | I915_READ(DSPCNTR(pipe)) | |
- | |
7616 | DISPPLANE_TRICKLE_FEED_DISABLE); |
- | |
7617 | intel_flush_display_plane(dev_priv, pipe); |
- | |
7618 | } |
- | |
7619 | } |
- | |
7620 | - | ||
7621 | static void g4x_init_clock_gating(struct drm_device *dev) |
- | |
7622 | { |
- | |
7623 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
7624 | uint32_t dspclk_gate; |
- | |
7625 | - | ||
7626 | I915_WRITE(RENCLK_GATE_D1, 0); |
- | |
7627 | I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | |
- | |
7628 | GS_UNIT_CLOCK_GATE_DISABLE | |
- | |
7629 | CL_UNIT_CLOCK_GATE_DISABLE); |
7529 | /* Intel hw has only one MUX where enocoders could be cloned. */ |
- | 7530 | if (encoder->cloneable && source_encoder->cloneable) |
|
- | 7531 | index_mask |= (1 << entry); |
|
- | 7532 | ||
7630 | I915_WRITE(RAMCLK_GATE_D, 0); |
7533 | entry++; |
7631 | dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | |
7534 | } |
7632 | OVRUNIT_CLOCK_GATE_DISABLE | |
7535 | |
7633 | OVCUNIT_CLOCK_GATE_DISABLE; |
7536 | return index_mask; |
7634 | if (IS_GM45(dev)) |
7537 | } |
7635 | dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; |
7538 | |
Line 7894... | Line 7797... | ||
7894 | i855_get_display_clock_speed; |
7797 | i855_get_display_clock_speed; |
7895 | else /* 852, 830 */ |
7798 | else /* 852, 830 */ |
7896 | dev_priv->display.get_display_clock_speed = |
7799 | dev_priv->display.get_display_clock_speed = |
7897 | i830_get_display_clock_speed; |
7800 | i830_get_display_clock_speed; |
Line 7898... | Line -... | ||
7898 | - | ||
7899 | /* For FIFO watermark updates */ |
7801 | |
7900 | if (HAS_PCH_SPLIT(dev)) { |
- | |
7901 | dev_priv->display.force_wake_get = __gen6_gt_force_wake_get; |
- | |
7902 | dev_priv->display.force_wake_put = __gen6_gt_force_wake_put; |
- | |
7903 | - | ||
7904 | /* IVB configs may use multi-threaded forcewake */ |
- | |
7905 | if (IS_IVYBRIDGE(dev)) { |
- | |
7906 | u32 ecobus; |
- | |
7907 | - | ||
7908 | /* A small trick here - if the bios hasn't configured MT forcewake, |
- | |
7909 | * and if the device is in RC6, then force_wake_mt_get will not wake |
- | |
7910 | * the device and the ECOBUS read will return zero. Which will be |
- | |
7911 | * (correctly) interpreted by the test below as MT forcewake being |
- | |
7912 | * disabled. |
- | |
7913 | */ |
- | |
7914 | mutex_lock(&dev->struct_mutex); |
- | |
7915 | __gen6_gt_force_wake_mt_get(dev_priv); |
- | |
7916 | ecobus = I915_READ_NOTRACE(ECOBUS); |
- | |
7917 | __gen6_gt_force_wake_mt_put(dev_priv); |
- | |
7918 | mutex_unlock(&dev->struct_mutex); |
- | |
7919 | - | ||
7920 | if (ecobus & FORCEWAKE_MT_ENABLE) { |
- | |
7921 | DRM_DEBUG_KMS("Using MT version of forcewake\n"); |
- | |
7922 | dev_priv->display.force_wake_get = |
- | |
7923 | __gen6_gt_force_wake_mt_get; |
- | |
7924 | dev_priv->display.force_wake_put = |
- | |
7925 | __gen6_gt_force_wake_mt_put; |
- | |
7926 | } |
- | |
7927 | } |
- | |
7928 | - | ||
7929 | if (HAS_PCH_IBX(dev)) |
- | |
7930 | dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating; |
- | |
7931 | else if (HAS_PCH_CPT(dev)) |
- | |
7932 | dev_priv->display.init_pch_clock_gating = cpt_init_clock_gating; |
- | |
7933 | 7802 | if (HAS_PCH_SPLIT(dev)) { |
|
7934 | if (IS_GEN5(dev)) { |
- | |
7935 | if (I915_READ(MLTR_ILK) & ILK_SRLT_MASK) |
- | |
7936 | dev_priv->display.update_wm = ironlake_update_wm; |
- | |
7937 | else { |
- | |
7938 | DRM_DEBUG_KMS("Failed to get proper latency. " |
- | |
7939 | "Disable CxSR\n"); |
- | |
7940 | dev_priv->display.update_wm = NULL; |
- | |
7941 | } |
7803 | if (IS_GEN5(dev)) { |
7942 | dev_priv->display.fdi_link_train = ironlake_fdi_link_train; |
- | |
7943 | dev_priv->display.init_clock_gating = ironlake_init_clock_gating; |
7804 | dev_priv->display.fdi_link_train = ironlake_fdi_link_train; |
7944 | dev_priv->display.write_eld = ironlake_write_eld; |
7805 | dev_priv->display.write_eld = ironlake_write_eld; |
7945 | } else if (IS_GEN6(dev)) { |
- | |
7946 | if (SNB_READ_WM0_LATENCY()) { |
- | |
7947 | dev_priv->display.update_wm = sandybridge_update_wm; |
- | |
7948 | dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; |
- | |
7949 | } else { |
- | |
7950 | DRM_DEBUG_KMS("Failed to read display plane latency. " |
- | |
7951 | "Disable CxSR\n"); |
- | |
7952 | dev_priv->display.update_wm = NULL; |
- | |
7953 | } |
7806 | } else if (IS_GEN6(dev)) { |
7954 | dev_priv->display.fdi_link_train = gen6_fdi_link_train; |
- | |
7955 | dev_priv->display.init_clock_gating = gen6_init_clock_gating; |
7807 | dev_priv->display.fdi_link_train = gen6_fdi_link_train; |
7956 | dev_priv->display.write_eld = ironlake_write_eld; |
7808 | dev_priv->display.write_eld = ironlake_write_eld; |
7957 | } else if (IS_IVYBRIDGE(dev)) { |
7809 | } else if (IS_IVYBRIDGE(dev)) { |
7958 | /* FIXME: detect B0+ stepping and use auto training */ |
7810 | /* FIXME: detect B0+ stepping and use auto training */ |
7959 | dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train; |
- | |
7960 | if (SNB_READ_WM0_LATENCY()) { |
- | |
7961 | dev_priv->display.update_wm = sandybridge_update_wm; |
- | |
7962 | dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; |
- | |
7963 | } else { |
- | |
7964 | DRM_DEBUG_KMS("Failed to read display plane latency. " |
- | |
7965 | "Disable CxSR\n"); |
- | |
7966 | dev_priv->display.update_wm = NULL; |
- | |
7967 | } |
- | |
7968 | dev_priv->display.init_clock_gating = ivybridge_init_clock_gating; |
7811 | dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train; |
- | 7812 | dev_priv->display.write_eld = ironlake_write_eld; |
|
- | 7813 | } else if (IS_HASWELL(dev)) { |
|
- | 7814 | dev_priv->display.fdi_link_train = hsw_fdi_link_train; |
|
7969 | dev_priv->display.write_eld = ironlake_write_eld; |
7815 | dev_priv->display.write_eld = haswell_write_eld; |
7970 | } else |
7816 | } else |
7971 | dev_priv->display.update_wm = NULL; |
- | |
7972 | } else if (IS_PINEVIEW(dev)) { |
- | |
7973 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), |
- | |
7974 | dev_priv->is_ddr3, |
- | |
7975 | dev_priv->fsb_freq, |
- | |
7976 | dev_priv->mem_freq)) { |
- | |
7977 | DRM_INFO("failed to find known CxSR latency " |
- | |
7978 | "(found ddr%s fsb freq %d, mem freq %d), " |
- | |
7979 | "disabling CxSR\n", |
- | |
7980 | (dev_priv->is_ddr3 == 1) ? "3" : "2", |
- | |
7981 | dev_priv->fsb_freq, dev_priv->mem_freq); |
- | |
7982 | /* Disable CxSR and never update its watermark again */ |
- | |
7983 | pineview_disable_cxsr(dev); |
- | |
7984 | dev_priv->display.update_wm = NULL; |
- | |
7985 | } else |
- | |
7986 | dev_priv->display.update_wm = pineview_update_wm; |
- | |
7987 | dev_priv->display.init_clock_gating = gen3_init_clock_gating; |
7817 | dev_priv->display.update_wm = NULL; |
7988 | } else if (IS_G4X(dev)) { |
7818 | } else if (IS_G4X(dev)) { |
7989 | dev_priv->display.write_eld = g4x_write_eld; |
- | |
7990 | dev_priv->display.update_wm = g4x_update_wm; |
- | |
7991 | dev_priv->display.init_clock_gating = g4x_init_clock_gating; |
- | |
7992 | } else if (IS_GEN4(dev)) { |
- | |
7993 | dev_priv->display.update_wm = i965_update_wm; |
- | |
7994 | if (IS_CRESTLINE(dev)) |
- | |
7995 | dev_priv->display.init_clock_gating = crestline_init_clock_gating; |
- | |
7996 | else if (IS_BROADWATER(dev)) |
- | |
7997 | dev_priv->display.init_clock_gating = broadwater_init_clock_gating; |
- | |
7998 | } else if (IS_GEN3(dev)) { |
- | |
7999 | dev_priv->display.update_wm = i9xx_update_wm; |
- | |
8000 | dev_priv->display.get_fifo_size = i9xx_get_fifo_size; |
- | |
8001 | dev_priv->display.init_clock_gating = gen3_init_clock_gating; |
- | |
8002 | } else if (IS_I865G(dev)) { |
- | |
8003 | dev_priv->display.update_wm = i830_update_wm; |
- | |
8004 | dev_priv->display.init_clock_gating = i85x_init_clock_gating; |
- | |
8005 | dev_priv->display.get_fifo_size = i830_get_fifo_size; |
- | |
8006 | } else if (IS_I85X(dev)) { |
- | |
8007 | dev_priv->display.update_wm = i9xx_update_wm; |
- | |
8008 | dev_priv->display.get_fifo_size = i85x_get_fifo_size; |
- | |
8009 | dev_priv->display.init_clock_gating = i85x_init_clock_gating; |
- | |
8010 | } else { |
- | |
8011 | dev_priv->display.update_wm = i830_update_wm; |
- | |
8012 | dev_priv->display.init_clock_gating = i830_init_clock_gating; |
- | |
8013 | if (IS_845G(dev)) |
- | |
8014 | dev_priv->display.get_fifo_size = i845_get_fifo_size; |
- | |
8015 | else |
- | |
8016 | dev_priv->display.get_fifo_size = i830_get_fifo_size; |
7819 | dev_priv->display.write_eld = g4x_write_eld; |
Line 8017... | Line 7820... | ||
8017 | } |
7820 | } |
8018 | 7821 | ||
Line 8019... | Line -... | ||
8019 | /* Default just returns -ENODEV to indicate unsupported */ |
- | |
8020 | // dev_priv->display.queue_flip = intel_default_queue_flip; |
- | |
8021 | - | ||
8022 | #if 0 |
- | |
8023 | switch (INTEL_INFO(dev)->gen) { |
- | |
Line 8024... | Line -... | ||
8024 | case 2: |
- | |
8025 | dev_priv->display.queue_flip = intel_gen2_queue_flip; |
- | |
8026 | break; |
- | |
Line 8027... | Line -... | ||
8027 | - | ||
8028 | case 3: |
- | |
8029 | dev_priv->display.queue_flip = intel_gen3_queue_flip; |
- | |
8030 | break; |
- | |
Line 8031... | Line -... | ||
8031 | - | ||
8032 | case 4: |
- | |
8033 | case 5: |
- | |
8034 | dev_priv->display.queue_flip = intel_gen4_queue_flip; |
- | |
8035 | break; |
- | |
8036 | - | ||
8037 | case 6: |
- | |
8038 | dev_priv->display.queue_flip = intel_gen6_queue_flip; |
- | |
8039 | break; |
7822 | /* Default just returns -ENODEV to indicate unsupported */ |
Line 8040... | Line 7823... | ||
8040 | case 7: |
7823 | // dev_priv->display.queue_flip = intel_default_queue_flip; |
8041 | dev_priv->display.queue_flip = intel_gen7_queue_flip; |
7824 | |
8042 | break; |
7825 | |
Line 8052... | Line 7835... | ||
8052 | static void quirk_pipea_force(struct drm_device *dev) |
7835 | static void quirk_pipea_force(struct drm_device *dev) |
8053 | { |
7836 | { |
8054 | struct drm_i915_private *dev_priv = dev->dev_private; |
7837 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 8055... | Line 7838... | ||
8055 | 7838 | ||
8056 | dev_priv->quirks |= QUIRK_PIPEA_FORCE; |
7839 | dev_priv->quirks |= QUIRK_PIPEA_FORCE; |
8057 | DRM_DEBUG_DRIVER("applying pipe a force quirk\n"); |
7840 | DRM_INFO("applying pipe a force quirk\n"); |
Line 8058... | Line 7841... | ||
8058 | } |
7841 | } |
8059 | 7842 | ||
8060 | /* |
7843 | /* |
8061 | * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason |
7844 | * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason |
8062 | */ |
7845 | */ |
8063 | static void quirk_ssc_force_disable(struct drm_device *dev) |
7846 | static void quirk_ssc_force_disable(struct drm_device *dev) |
8064 | { |
7847 | { |
- | 7848 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 7849 | dev_priv->quirks |= QUIRK_LVDS_SSC_DISABLE; |
|
- | 7850 | DRM_INFO("applying lvds SSC disable quirk\n"); |
|
- | 7851 | } |
|
- | 7852 | ||
- | 7853 | /* |
|
- | 7854 | * A machine (e.g. Acer Aspire 5734Z) may need to invert the panel backlight |
|
- | 7855 | * brightness value |
|
- | 7856 | */ |
|
- | 7857 | static void quirk_invert_brightness(struct drm_device *dev) |
|
- | 7858 | { |
|
- | 7859 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
8065 | struct drm_i915_private *dev_priv = dev->dev_private; |
7860 | dev_priv->quirks |= QUIRK_INVERT_BRIGHTNESS; |
Line 8066... | Line 7861... | ||
8066 | dev_priv->quirks |= QUIRK_LVDS_SSC_DISABLE; |
7861 | DRM_INFO("applying inverted panel brightness quirk\n"); |
8067 | } |
7862 | } |
8068 | 7863 | ||
8069 | struct intel_quirk { |
7864 | struct intel_quirk { |
8070 | int device; |
7865 | int device; |
8071 | int subsystem_vendor; |
7866 | int subsystem_vendor; |
Line -... | Line 7867... | ||
- | 7867 | int subsystem_device; |
|
8072 | int subsystem_device; |
7868 | void (*hook)(struct drm_device *dev); |
- | 7869 | }; |
|
- | 7870 | ||
- | 7871 | /* For systems that don't have a meaningful PCI subdevice/subvendor ID */ |
|
- | 7872 | struct intel_dmi_quirk { |
|
- | 7873 | void (*hook)(struct drm_device *dev); |
|
- | 7874 | const struct dmi_system_id (*dmi_id_list)[]; |
|
- | 7875 | }; |
|
- | 7876 | ||
- | 7877 | static int intel_dmi_reverse_brightness(const struct dmi_system_id *id) |
|
- | 7878 | { |
|
8073 | void (*hook)(struct drm_device *dev); |
7879 | DRM_INFO("Backlight polarity reversed on %s\n", id->ident); |
- | 7880 | return 1; |
|
- | 7881 | } |
|
- | 7882 | ||
- | 7883 | static const struct intel_dmi_quirk intel_dmi_quirks[] = { |
|
- | 7884 | { |
|
- | 7885 | .dmi_id_list = &(const struct dmi_system_id[]) { |
|
- | 7886 | { |
|
- | 7887 | .callback = intel_dmi_reverse_brightness, |
|
- | 7888 | .ident = "NCR Corporation", |
|
- | 7889 | .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"), |
|
- | 7890 | DMI_MATCH(DMI_PRODUCT_NAME, ""), |
|
- | 7891 | }, |
|
- | 7892 | }, |
|
- | 7893 | { } /* terminating entry */ |
|
- | 7894 | }, |
|
8074 | }; |
7895 | .hook = quirk_invert_brightness, |
8075 | 7896 | }, |
|
8076 | struct intel_quirk intel_quirks[] = { |
7897 | }; |
Line 8077... | Line -... | ||
8077 | /* HP Compaq 2730p needs pipe A force quirk (LP: #291555) */ |
- | |
8078 | { 0x2a42, 0x103c, 0x30eb, quirk_pipea_force }, |
- | |
8079 | /* HP Mini needs pipe A force quirk (LP: #322104) */ |
7898 | |
8080 | { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, |
7899 | static struct intel_quirk intel_quirks[] = { |
Line 8081... | Line -... | ||
8081 | - | ||
8082 | /* Thinkpad R31 needs pipe A force quirk */ |
- | |
8083 | { 0x3577, 0x1014, 0x0505, quirk_pipea_force }, |
- | |
8084 | /* Toshiba Protege R-205, S-209 needs pipe A force quirk */ |
- | |
8085 | { 0x2592, 0x1179, 0x0001, quirk_pipea_force }, |
7900 | /* HP Mini needs pipe A force quirk (LP: #322104) */ |
8086 | 7901 | { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, |
|
Line 8087... | Line 7902... | ||
8087 | /* ThinkPad X30 needs pipe A force quirk (LP: #304614) */ |
7902 | |
8088 | { 0x3577, 0x1014, 0x0513, quirk_pipea_force }, |
- | |
8089 | /* ThinkPad X40 needs pipe A force quirk */ |
7903 | /* Toshiba Protege R-205, S-209 needs pipe A force quirk */ |
- | 7904 | { 0x2592, 0x1179, 0x0001, quirk_pipea_force }, |
|
Line 8090... | Line 7905... | ||
8090 | 7905 | ||
8091 | /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ |
7906 | /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ |
Line 8092... | Line 7907... | ||
8092 | { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, |
7907 | { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, |
8093 | 7908 | ||
- | 7909 | /* 830/845 need to leave pipe A & dpll A up */ |
|
- | 7910 | { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
|
- | 7911 | { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
|
8094 | /* 855 & before need to leave pipe A & dpll A up */ |
7912 | |
Line 8095... | Line 7913... | ||
8095 | { 0x3582, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
7913 | /* Lenovo U160 cannot use SSC on LVDS */ |
8096 | { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
7914 | { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable }, |
8097 | 7915 | ||
Line 8115... | Line 7933... | ||
8115 | q->subsystem_vendor == PCI_ANY_ID) && |
7933 | q->subsystem_vendor == PCI_ANY_ID) && |
8116 | (d->subsystem_device == q->subsystem_device || |
7934 | (d->subsystem_device == q->subsystem_device || |
8117 | q->subsystem_device == PCI_ANY_ID)) |
7935 | q->subsystem_device == PCI_ANY_ID)) |
8118 | q->hook(dev); |
7936 | q->hook(dev); |
8119 | } |
7937 | } |
- | 7938 | // for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) { |
|
- | 7939 | // if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0) |
|
- | 7940 | // intel_dmi_quirks[i].hook(dev); |
|
- | 7941 | // } |
|
8120 | } |
7942 | } |
Line 8121... | Line 7943... | ||
8121 | 7943 | ||
8122 | /* Disable the VGA plane that we never use */ |
7944 | /* Disable the VGA plane that we never use */ |
8123 | static void i915_disable_vga(struct drm_device *dev) |
7945 | static void i915_disable_vga(struct drm_device *dev) |
Line 8130... | Line 7952... | ||
8130 | vga_reg = CPU_VGACNTRL; |
7952 | vga_reg = CPU_VGACNTRL; |
8131 | else |
7953 | else |
8132 | vga_reg = VGACNTRL; |
7954 | vga_reg = VGACNTRL; |
Line 8133... | Line 7955... | ||
8133 | 7955 | ||
8134 | // vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); |
7956 | // vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); |
8135 | out8(VGA_SR_INDEX, 1); |
7957 | out8(SR01, VGA_SR_INDEX); |
8136 | sr1 = in8(VGA_SR_DATA); |
7958 | sr1 = in8(VGA_SR_DATA); |
8137 | out8(VGA_SR_DATA,sr1 | 1<<5); |
7959 | out8(sr1 | 1<<5, VGA_SR_DATA); |
8138 | // vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); |
7960 | // vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); |
Line 8139... | Line 7961... | ||
8139 | udelay(300); |
7961 | udelay(300); |
8140 | 7962 | ||
8141 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); |
7963 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); |
Line -... | Line 7964... | ||
- | 7964 | POSTING_READ(vga_reg); |
|
- | 7965 | } |
|
- | 7966 | ||
- | 7967 | void intel_modeset_init_hw(struct drm_device *dev) |
|
- | 7968 | { |
|
- | 7969 | /* We attempt to init the necessary power wells early in the initialization |
|
- | 7970 | * time, so the subsystems that expect power to be enabled can work. |
|
- | 7971 | */ |
|
- | 7972 | intel_init_power_wells(dev); |
|
- | 7973 | ||
- | 7974 | intel_prepare_ddi(dev); |
|
- | 7975 | ||
- | 7976 | intel_init_clock_gating(dev); |
|
- | 7977 | ||
- | 7978 | // mutex_lock(&dev->struct_mutex); |
|
- | 7979 | // intel_enable_gt_powersave(dev); |
|
8142 | POSTING_READ(vga_reg); |
7980 | // mutex_unlock(&dev->struct_mutex); |
8143 | } |
7981 | } |
8144 | 7982 | ||
8145 | void intel_modeset_init(struct drm_device *dev) |
7983 | void intel_modeset_init(struct drm_device *dev) |
Line 8146... | Line 7984... | ||
8146 | { |
7984 | { |
Line 8147... | Line 7985... | ||
8147 | struct drm_i915_private *dev_priv = dev->dev_private; |
7985 | struct drm_i915_private *dev_priv = dev->dev_private; |
8148 | int i, ret; |
7986 | int i, ret; |
Line -... | Line 7987... | ||
- | 7987 | ||
- | 7988 | drm_mode_config_init(dev); |
|
- | 7989 | ||
8149 | 7990 | dev->mode_config.min_width = 0; |
|
Line 8150... | Line 7991... | ||
8150 | drm_mode_config_init(dev); |
7991 | dev->mode_config.min_height = 0; |
Line -... | Line 7992... | ||
- | 7992 | ||
- | 7993 | dev->mode_config.preferred_depth = 24; |
|
8151 | 7994 | dev->mode_config.prefer_shadow = 1; |
|
Line 8152... | Line 7995... | ||
8152 | dev->mode_config.min_width = 0; |
7995 | |
8153 | dev->mode_config.min_height = 0; |
7996 | dev->mode_config.funcs = &intel_mode_funcs; |
8154 | 7997 | ||
Line 8166... | Line 8009... | ||
8166 | dev->mode_config.max_height = 4096; |
8009 | dev->mode_config.max_height = 4096; |
8167 | } else { |
8010 | } else { |
8168 | dev->mode_config.max_width = 8192; |
8011 | dev->mode_config.max_width = 8192; |
8169 | dev->mode_config.max_height = 8192; |
8012 | dev->mode_config.max_height = 8192; |
8170 | } |
8013 | } |
8171 | dev->mode_config.fb_base = get_bus_addr(); |
8014 | dev->mode_config.fb_base = dev_priv->mm.gtt_base_addr; |
Line 8172... | Line 8015... | ||
8172 | 8015 | ||
8173 | DRM_DEBUG_KMS("%d display pipe%s available.\n", |
8016 | DRM_DEBUG_KMS("%d display pipe%s available.\n", |
Line 8174... | Line 8017... | ||
8174 | dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : ""); |
8017 | dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : ""); |
Line 8178... | Line 8021... | ||
8178 | ret = intel_plane_init(dev, i); |
8021 | ret = intel_plane_init(dev, i); |
8179 | if (ret) |
8022 | if (ret) |
8180 | DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret); |
8023 | DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret); |
8181 | } |
8024 | } |
Line -... | Line 8025... | ||
- | 8025 | ||
- | 8026 | intel_pch_pll_init(dev); |
|
8182 | 8027 | ||
8183 | /* Just disable it once at startup */ |
8028 | /* Just disable it once at startup */ |
8184 | i915_disable_vga(dev); |
8029 | i915_disable_vga(dev); |
- | 8030 | intel_setup_outputs(dev); |
|
Line -... | Line 8031... | ||
- | 8031 | } |
|
- | 8032 | ||
- | 8033 | static void |
|
- | 8034 | intel_connector_break_all_links(struct intel_connector *connector) |
|
- | 8035 | { |
|
- | 8036 | connector->base.dpms = DRM_MODE_DPMS_OFF; |
|
- | 8037 | connector->base.encoder = NULL; |
|
- | 8038 | connector->encoder->connectors_active = false; |
|
- | 8039 | connector->encoder->base.crtc = NULL; |
|
- | 8040 | } |
|
- | 8041 | ||
- | 8042 | static void intel_enable_pipe_a(struct drm_device *dev) |
|
- | 8043 | { |
|
- | 8044 | struct intel_connector *connector; |
|
- | 8045 | struct drm_connector *crt = NULL; |
|
- | 8046 | struct intel_load_detect_pipe load_detect_temp; |
|
- | 8047 | ||
- | 8048 | /* We can't just switch on the pipe A, we need to set things up with a |
|
- | 8049 | * proper mode and output configuration. As a gross hack, enable pipe A |
|
- | 8050 | * by enabling the load detect pipe once. */ |
|
- | 8051 | list_for_each_entry(connector, |
|
- | 8052 | &dev->mode_config.connector_list, |
|
- | 8053 | base.head) { |
|
- | 8054 | if (connector->encoder->type == INTEL_OUTPUT_ANALOG) { |
|
- | 8055 | crt = &connector->base; |
|
- | 8056 | break; |
|
- | 8057 | } |
|
- | 8058 | } |
|
- | 8059 | ||
- | 8060 | if (!crt) |
|
- | 8061 | return; |
|
- | 8062 | ||
- | 8063 | if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp)) |
|
- | 8064 | intel_release_load_detect_pipe(crt, &load_detect_temp); |
|
- | 8065 | ||
- | 8066 | ||
- | 8067 | } |
|
- | 8068 | ||
- | 8069 | static bool |
|
- | 8070 | intel_check_plane_mapping(struct intel_crtc *crtc) |
|
- | 8071 | { |
|
- | 8072 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; |
|
- | 8073 | u32 reg, val; |
|
- | 8074 | ||
- | 8075 | if (dev_priv->num_pipe == 1) |
|
- | 8076 | return true; |
|
- | 8077 | ||
- | 8078 | reg = DSPCNTR(!crtc->plane); |
|
- | 8079 | val = I915_READ(reg); |
|
- | 8080 | ||
- | 8081 | if ((val & DISPLAY_PLANE_ENABLE) && |
|
- | 8082 | (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe)) |
|
- | 8083 | return false; |
|
- | 8084 | ||
- | 8085 | return true; |
|
- | 8086 | } |
|
- | 8087 | ||
- | 8088 | static void intel_sanitize_crtc(struct intel_crtc *crtc) |
|
- | 8089 | { |
|
- | 8090 | struct drm_device *dev = crtc->base.dev; |
|
- | 8091 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 8092 | u32 reg; |
|
- | 8093 | ||
- | 8094 | /* Clear any frame start delays used for debugging left by the BIOS */ |
|
- | 8095 | reg = PIPECONF(crtc->pipe); |
|
- | 8096 | I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); |
|
- | 8097 | ||
- | 8098 | /* We need to sanitize the plane -> pipe mapping first because this will |
|
- | 8099 | * disable the crtc (and hence change the state) if it is wrong. Note |
|
- | 8100 | * that gen4+ has a fixed plane -> pipe mapping. */ |
|
- | 8101 | if (INTEL_INFO(dev)->gen < 4 && !intel_check_plane_mapping(crtc)) { |
|
- | 8102 | struct intel_connector *connector; |
|
- | 8103 | bool plane; |
|
- | 8104 | ||
- | 8105 | DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n", |
|
- | 8106 | crtc->base.base.id); |
|
- | 8107 | ||
- | 8108 | /* Pipe has the wrong plane attached and the plane is active. |
|
- | 8109 | * Temporarily change the plane mapping and disable everything |
|
- | 8110 | * ... */ |
|
- | 8111 | plane = crtc->plane; |
|
- | 8112 | crtc->plane = !plane; |
|
- | 8113 | dev_priv->display.crtc_disable(&crtc->base); |
|
- | 8114 | crtc->plane = plane; |
|
- | 8115 | ||
- | 8116 | /* ... and break all links. */ |
|
- | 8117 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
|
- | 8118 | base.head) { |
|
- | 8119 | if (connector->encoder->base.crtc != &crtc->base) |
|
- | 8120 | continue; |
|
- | 8121 | ||
- | 8122 | intel_connector_break_all_links(connector); |
|
- | 8123 | } |
|
- | 8124 | ||
- | 8125 | WARN_ON(crtc->active); |
|
- | 8126 | crtc->base.enabled = false; |
|
- | 8127 | } |
|
- | 8128 | ||
- | 8129 | if (dev_priv->quirks & QUIRK_PIPEA_FORCE && |
|
- | 8130 | crtc->pipe == PIPE_A && !crtc->active) { |
|
- | 8131 | /* BIOS forgot to enable pipe A, this mostly happens after |
|
- | 8132 | * resume. Force-enable the pipe to fix this, the update_dpms |
|
8185 | intel_setup_outputs(dev); |
8133 | * call below we restore the pipe to the right state, but leave |
- | 8134 | * the required bits on. */ |
|
- | 8135 | intel_enable_pipe_a(dev); |
|
- | 8136 | } |
|
- | 8137 | ||
- | 8138 | /* Adjust the state of the output pipe according to whether we |
|
- | 8139 | * have active connectors/encoders. */ |
|
- | 8140 | intel_crtc_update_dpms(&crtc->base); |
|
- | 8141 | ||
- | 8142 | if (crtc->active != crtc->base.enabled) { |
|
- | 8143 | struct intel_encoder *encoder; |
|
- | 8144 | ||
- | 8145 | /* This can happen either due to bugs in the get_hw_state |
|
- | 8146 | * functions or because the pipe is force-enabled due to the |
|
- | 8147 | * pipe A quirk. */ |
|
- | 8148 | DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was %s, now %s\n", |
|
- | 8149 | crtc->base.base.id, |
|
- | 8150 | crtc->base.enabled ? "enabled" : "disabled", |
|
- | 8151 | crtc->active ? "enabled" : "disabled"); |
|
- | 8152 | ||
- | 8153 | crtc->base.enabled = crtc->active; |
|
- | 8154 | ||
- | 8155 | /* Because we only establish the connector -> encoder -> |
|
- | 8156 | * crtc links if something is active, this means the |
|
- | 8157 | * crtc is now deactivated. Break the links. connector |
|
- | 8158 | * -> encoder links are only establish when things are |
|
- | 8159 | * actually up, hence no need to break them. */ |
|
- | 8160 | WARN_ON(crtc->active); |
|
- | 8161 | ||
- | 8162 | for_each_encoder_on_crtc(dev, &crtc->base, encoder) { |
|
- | 8163 | WARN_ON(encoder->connectors_active); |
|
- | 8164 | encoder->base.crtc = NULL; |
|
- | 8165 | } |
|
- | 8166 | } |
|
- | 8167 | } |
|
- | 8168 | ||
- | 8169 | static void intel_sanitize_encoder(struct intel_encoder *encoder) |
|
- | 8170 | { |
|
- | 8171 | struct intel_connector *connector; |
|
- | 8172 | struct drm_device *dev = encoder->base.dev; |
|
- | 8173 | ||
- | 8174 | /* We need to check both for a crtc link (meaning that the |
|
- | 8175 | * encoder is active and trying to read from a pipe) and the |
|
- | 8176 | * pipe itself being active. */ |
|
- | 8177 | bool has_active_crtc = encoder->base.crtc && |
|
- | 8178 | to_intel_crtc(encoder->base.crtc)->active; |
|
- | 8179 | ||
- | 8180 | if (encoder->connectors_active && !has_active_crtc) { |
|
- | 8181 | DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n", |
|
- | 8182 | encoder->base.base.id, |
|
- | 8183 | drm_get_encoder_name(&encoder->base)); |
|
- | 8184 | ||
- | 8185 | /* Connector is active, but has no active pipe. This is |
|
- | 8186 | * fallout from our resume register restoring. Disable |
|
- | 8187 | * the encoder manually again. */ |
|
- | 8188 | if (encoder->base.crtc) { |
|
- | 8189 | DRM_DEBUG_KMS("[ENCODER:%d:%s] manually disabled\n", |
|
- | 8190 | encoder->base.base.id, |
|
- | 8191 | drm_get_encoder_name(&encoder->base)); |
|
- | 8192 | encoder->disable(encoder); |
|
- | 8193 | } |
|
- | 8194 | ||
- | 8195 | /* Inconsistent output/port/pipe state happens presumably due to |
|
- | 8196 | * a bug in one of the get_hw_state functions. Or someplace else |
|
- | 8197 | * in our code, like the register restore mess on resume. Clamp |
|
- | 8198 | * things to off as a safer default. */ |
|
- | 8199 | list_for_each_entry(connector, |
|
- | 8200 | &dev->mode_config.connector_list, |
|
- | 8201 | base.head) { |
|
- | 8202 | if (connector->encoder != encoder) |
|
- | 8203 | continue; |
|
- | 8204 | ||
- | 8205 | intel_connector_break_all_links(connector); |
|
- | 8206 | } |
|
- | 8207 | } |
|
- | 8208 | /* Enabled encoders without active connectors will be fixed in |
|
- | 8209 | * the crtc fixup. */ |
|
- | 8210 | } |
|
- | 8211 | ||
- | 8212 | /* Scan out the current hw modeset state, sanitizes it and maps it into the drm |
|
- | 8213 | * and i915 state tracking structures. */ |
|
- | 8214 | void intel_modeset_setup_hw_state(struct drm_device *dev) |
|
- | 8215 | { |
|
- | 8216 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 8217 | enum pipe pipe; |
|
- | 8218 | u32 tmp; |
|
- | 8219 | struct intel_crtc *crtc; |
|
- | 8220 | struct intel_encoder *encoder; |
|
- | 8221 | struct intel_connector *connector; |
|
- | 8222 | ||
- | 8223 | for_each_pipe(pipe) { |
|
- | 8224 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
|
- | 8225 | ||
- | 8226 | tmp = I915_READ(PIPECONF(pipe)); |
|
- | 8227 | if (tmp & PIPECONF_ENABLE) |
|
- | 8228 | crtc->active = true; |
|
- | 8229 | else |
|
- | 8230 | crtc->active = false; |
|
- | 8231 | ||
- | 8232 | crtc->base.enabled = crtc->active; |
|
- | 8233 | ||
- | 8234 | DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n", |
|
- | 8235 | crtc->base.base.id, |
|
- | 8236 | crtc->active ? "enabled" : "disabled"); |
|
- | 8237 | } |
|
- | 8238 | ||
- | 8239 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
|
Line -... | Line 8240... | ||
- | 8240 | base.head) { |
|
- | 8241 | pipe = 0; |
|
- | 8242 | ||
- | 8243 | if (encoder->get_hw_state(encoder, &pipe)) { |
|
- | 8244 | encoder->base.crtc = |
|
- | 8245 | dev_priv->pipe_to_crtc_mapping[pipe]; |
|
- | 8246 | } else { |
|
- | 8247 | encoder->base.crtc = NULL; |
|
- | 8248 | } |
|
8186 | 8249 | ||
- | 8250 | encoder->connectors_active = false; |
|
- | 8251 | DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe=%i\n", |
|
- | 8252 | encoder->base.base.id, |
|
- | 8253 | drm_get_encoder_name(&encoder->base), |
|
- | 8254 | encoder->base.crtc ? "enabled" : "disabled", |
|
- | 8255 | pipe); |
|
- | 8256 | } |
|
- | 8257 | ||
- | 8258 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
|
- | 8259 | base.head) { |
|
- | 8260 | if (connector->get_hw_state(connector)) { |
|
- | 8261 | connector->base.dpms = DRM_MODE_DPMS_ON; |
|
- | 8262 | connector->encoder->connectors_active = true; |
|
- | 8263 | connector->base.encoder = &connector->encoder->base; |
|
- | 8264 | } else { |
|
- | 8265 | connector->base.dpms = DRM_MODE_DPMS_OFF; |
|
8187 | intel_init_clock_gating(dev); |
8266 | connector->base.encoder = NULL; |
- | 8267 | } |
|
- | 8268 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] hw state readout: %s\n", |
|
- | 8269 | connector->base.base.id, |
|
- | 8270 | drm_get_connector_name(&connector->base), |
|
- | 8271 | connector->base.encoder ? "enabled" : "disabled"); |
|
- | 8272 | } |
|
- | 8273 | ||
8188 | 8274 | /* HW state is read out, now we need to sanitize this mess. */ |
|
8189 | if (IS_IRONLAKE_M(dev)) { |
8275 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
Line 8190... | Line 8276... | ||
8190 | ironlake_enable_drps(dev); |
8276 | base.head) { |
8191 | intel_init_emon(dev); |
8277 | intel_sanitize_encoder(encoder); |
8192 | } |
8278 | } |
8193 | 8279 | ||
Line 8194... | Line 8280... | ||
8194 | if (IS_GEN6(dev) || IS_GEN7(dev)) { |
8280 | for_each_pipe(pipe) { |
8195 | gen6_enable_rps(dev_priv); |
- | |
- | 8281 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
|
8196 | gen6_update_ring_freq(dev_priv); |
8282 | intel_sanitize_crtc(crtc); |
8197 | } |
8283 | } |
Line 8198... | Line 8284... | ||
8198 | 8284 | ||
8199 | // INIT_WORK(&dev_priv->idle_work, intel_idle_update); |
8285 | intel_modeset_update_staged_output_state(dev); |
8200 | // setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, |
- | |
8201 | // (unsigned long)dev); |
8286 | |
Line 8202... | Line 8287... | ||
8202 | } |
8287 | intel_modeset_check_state(dev); |
- | 8288 | } |
|
- | 8289 | ||
- | 8290 | void intel_modeset_gem_init(struct drm_device *dev) |
|
- | 8291 | { |
|
- | 8292 | intel_modeset_init_hw(dev); |
|
- | 8293 | ||
- | 8294 | // intel_setup_overlay(dev); |
|
- | 8295 | ||
- | 8296 | intel_modeset_setup_hw_state(dev); |
|
- | 8297 | } |
|
- | 8298 | ||
- | 8299 | void intel_modeset_cleanup(struct drm_device *dev) |
|
- | 8300 | { |
|
- | 8301 | #if 0 |
|
- | 8302 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 8303 | struct drm_crtc *crtc; |
|
- | 8304 | struct intel_crtc *intel_crtc; |
|
- | 8305 | ||
- | 8306 | // drm_kms_helper_poll_fini(dev); |
|
- | 8307 | mutex_lock(&dev->struct_mutex); |
|
- | 8308 | ||
- | 8309 | // intel_unregister_dsm_handler(); |
|
- | 8310 | ||
- | 8311 | ||
8203 | 8312 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
|
Line -... | Line 8313... | ||
- | 8313 | /* Skip inactive CRTCs */ |
|
- | 8314 | if (!crtc->fb) |
|
- | 8315 | continue; |
|
- | 8316 | ||
- | 8317 | intel_crtc = to_intel_crtc(crtc); |
|
- | 8318 | intel_increase_pllclock(crtc); |
|
- | 8319 | } |
|
- | 8320 | ||
- | 8321 | intel_disable_fbc(dev); |
|
- | 8322 | ||
- | 8323 | intel_disable_gt_powersave(dev); |
|
- | 8324 | ||
- | 8325 | ironlake_teardown_rc6(dev); |
|
- | 8326 | ||
- | 8327 | if (IS_VALLEYVIEW(dev)) |
|
- | 8328 | vlv_init_dpio(dev); |
|
- | 8329 | ||
- | 8330 | mutex_unlock(&dev->struct_mutex); |
|
- | 8331 | ||
- | 8332 | /* Disable the irq before mode object teardown, for the irq might |
|
- | 8333 | * enqueue unpin/hotplug work. */ |
|
- | 8334 | // drm_irq_uninstall(dev); |
|
- | 8335 | // cancel_work_sync(&dev_priv->hotplug_work); |
|
Line 8204... | Line 8336... | ||
8204 | void intel_modeset_gem_init(struct drm_device *dev) |
8336 | // cancel_work_sync(&dev_priv->rps.work); |
8205 | { |
8337 | |
8206 | if (IS_IRONLAKE_M(dev)) |
8338 | /* flush any delayed tasks or pending work */ |
8207 | ironlake_enable_rc6(dev); |
8339 | // flush_scheduled_work(); |
Line 8224... | Line 8356... | ||
8224 | connector->encoder = encoder; |
8356 | connector->encoder = encoder; |
8225 | drm_mode_connector_attach_encoder(&connector->base, |
8357 | drm_mode_connector_attach_encoder(&connector->base, |
8226 | &encoder->base); |
8358 | &encoder->base); |
8227 | }>5); |
8359 | } |
Line -... | Line 8360... | ||
- | 8360 | ||
- | 8361 | /* |
|
- | 8362 | * set vga decode state - true == enable VGA decode |
|
- | 8363 | */ |
|
- | 8364 | int intel_modeset_vga_set_state(struct drm_device *dev, bool state) |
|
- | 8365 | { |
|
- | 8366 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 8367 | u16 gmch_ctrl; |
|
- | 8368 | ||
- | 8369 | pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &gmch_ctrl); |
|
- | 8370 | if (state) |
|
- | 8371 | gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE; |
|
- | 8372 | else |
|
- | 8373 | gmch_ctrl |= INTEL_GMCH_VGA_DISABLE; |
|
- | 8374 | pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl); |
|
- | 8375 | return 0; |
|
- | 8376 | } |
|
- | 8377 | ||
- | 8378 | #ifdef CONFIG_DEBUG_FS |
|
- | 8379 | #include |
|
- | 8380 | ||
- | 8381 | struct intel_display_error_state { |
|
- | 8382 | struct intel_cursor_error_state { |
|
- | 8383 | u32 control; |
|
- | 8384 | u32 position; |
|
- | 8385 | u32 base; |
|
- | 8386 | u32 size; |
|
- | 8387 | } cursor[I915_MAX_PIPES]; |
|
- | 8388 | ||
- | 8389 | struct intel_pipe_error_state { |
|
- | 8390 | u32 conf; |
|
- | 8391 | u32 source; |
|
- | 8392 | ||
- | 8393 | u32 htotal; |
|
- | 8394 | u32 hblank; |
|
- | 8395 | u32 hsync; |
|
- | 8396 | u32 vtotal; |
|
- | 8397 | u32 vblank; |
|
- | 8398 | u32 vsync; |
|
- | 8399 | } pipe[I915_MAX_PIPES]; |
|
- | 8400 | ||
- | 8401 | struct intel_plane_error_state { |
|
- | 8402 | u32 control; |
|
- | 8403 | u32 stride; |
|
- | 8404 | u32 size; |
|
- | 8405 | u32 pos; |
|
- | 8406 | u32 addr; |
|
- | 8407 | u32 surface; |
|
- | 8408 | u32 tile_offset; |
|
- | 8409 | } plane[I915_MAX_PIPES]; |
|
- | 8410 | }; |
|
- | 8411 | ||
- | 8412 | struct intel_display_error_state * |
|
- | 8413 | intel_display_capture_error_state(struct drm_device *dev) |
|
- | 8414 | { |
|
- | 8415 | drm_i915_private_t *dev_priv = dev->dev_private; |
|
- | 8416 | struct intel_display_error_state *error; |
|
- | 8417 | int i; |
|
- | 8418 | ||
- | 8419 | error = kmalloc(sizeof(*error), GFP_ATOMIC); |
|
- | 8420 | if (error == NULL) |
|
- | 8421 | return NULL; |
|
- | 8422 | ||
- | 8423 | for_each_pipe(i) { |
|
- | 8424 | error->cursor[i].control = I915_READ(CURCNTR(i)); |
|
- | 8425 | error->cursor[i].position = I915_READ(CURPOS(i)); |
|
- | 8426 | error->cursor[i].base = I915_READ(CURBASE(i)); |
|
- | 8427 | ||
- | 8428 | error->plane[i].control = I915_READ(DSPCNTR(i)); |
|
- | 8429 | error->plane[i].stride = I915_READ(DSPSTRIDE(i)); |
|
- | 8430 | error->plane[i].size = I915_READ(DSPSIZE(i)); |
|
- | 8431 | error->plane[i].pos = I915_READ(DSPPOS(i)); |
|
- | 8432 | error->plane[i].addr = I915_READ(DSPADDR(i)); |
|
- | 8433 | if (INTEL_INFO(dev)->gen >= 4) { |
|
- | 8434 | error->plane[i].surface = I915_READ(DSPSURF(i)); |
|
- | 8435 | error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i)); |
|
- | 8436 | } |
|
- | 8437 | ||
- | 8438 | error->pipe[i].conf = I915_READ(PIPECONF(i)); |
|
- | 8439 | error->pipe[i].source = I915_READ(PIPESRC(i)); |
|
- | 8440 | error->pipe[i].htotal = I915_READ(HTOTAL(i)); |
|
- | 8441 | error->pipe[i].hblank = I915_READ(HBLANK(i)); |
|
- | 8442 | error->pipe[i].hsync = I915_READ(HSYNC(i)); |
|
- | 8443 | error->pipe[i].vtotal = I915_READ(VTOTAL(i)); |
|
- | 8444 | error->pipe[i].vblank = I915_READ(VBLANK(i)); |
|
- | 8445 | error->pipe[i].vsync = I915_READ(VSYNC(i)); |
|
- | 8446 | } |
|
- | 8447 | ||
- | 8448 | return error; |
|
- | 8449 | } |
|
- | 8450 | ||
- | 8451 | void |
|
- | 8452 | intel_display_print_error_state(struct seq_file *m, |
|
- | 8453 | struct drm_device *dev, |
|
- | 8454 | struct intel_display_error_state *error) |
|
- | 8455 | { |
|
- | 8456 | drm_i915_private_t *dev_priv = dev->dev_private; |
|
Line -... | Line 8457... | ||
- | 8457 | int i; |
|
- | 8458 | ||
- | 8459 | seq_printf(m, "Num Pipes: %d\n", dev_priv->num_pipe); |
|
- | 8460 | for_each_pipe(i) { |
|
- | 8461 | seq_printf(m, "Pipe [%d]:\n", i); |
|
- | 8462 | seq_printf(m, " CONF: %08x\n", error->pipe[i].conf); |
|
- | 8463 | seq_printf(m, " SRC: %08x\n", error->pipe[i].source); |
|
- | 8464 | seq_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal); |
|
- | 8465 | seq_printf(m, " HBLANK: %08x\n", error->pipe[i].hblank); |
|
- | 8466 | seq_printf(m, " HSYNC: %08x\n", error->pipe[i].hsync); |
|
- | 8467 | seq_printf(m, " VTOTAL: %08x\n", error->pipe[i].vtotal); |
|
- | 8468 | seq_printf(m, " VBLANK: %08x\n", error->pipe[i].vblank); |
|
- | 8469 | seq_printf(m, " VSYNC: %08x\n", error->pipe[i].vsync); |
|
- | 8470 | ||
- | 8471 | seq_printf(m, "Plane [%d]:\n", i); |
|
- | 8472 | seq_printf(m, " CNTR: %08x\n", error->plane[i].control); |
|
- | 8473 | seq_printf(m, " STRIDE: %08x\n", error->plane[i].stride); |
|
- | 8474 | seq_printf(m, " SIZE: %08x\n", error->plane[i].size); |
|
- | 8475 | seq_printf(m, " POS: %08x\n", error->plane[i].pos); |
|
- | 8476 | seq_printf(m, " ADDR: %08x\n", error->plane[i].addr); |
|
- | 8477 | if (INTEL_INFO(dev)->gen >= 4) { |
|
- | 8478 | seq_printf(m, " SURF: %08x\n", error->plane[i].surface); |
|
- | 8479 | seq_printf(m, " TILEOFF: %08x\n", error->plane[i].tile_offset); |
|
- | 8480 | } |
|
- | 8481 | ||
- | 8482 | seq_printf(m, "Cursor [%d]:\n", i); |
|
- | 8483 | seq_printf(m, " CNTR: %08x\n", error->cursor[i].control); |
|
- | 8484 | seq_printf(m, " POS: %08x\n", error->cursor[i].position); |
|
- | 8485 | seq_printf(m, " BASE: %08x\n", error->cursor[i].base); |
|
- | 8486 | } |