aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-01 11:16:21 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-04 08:01:48 -0400
commitff9a6750aca3553c78385a9aa89b678b2b9be7df (patch)
treec27e3b057e5e99957fb950a28f2dbcb749ba7511 /drivers
parent7c62a164faea430c6e4c411eb0870640cf51a6e5 (diff)
drm/i915: store adjusted dotclock in adjusted_mode->clock
... not the port clock. This allows us to kill the funny semantics around pixel_target_clock. Since the dpll code still needs the real port clock, add a new port_clock field to the pipe configuration. Handling the default case for that one is a bit tricky, since encoders might not consistently overwrite it when retrying the crtc/encoder bw arbitrage step in the compute config stage. Hence we need to always clear port_clock and update it again if the encoder hasn't put in something more specific. This can't be done in one step since the encoder might want to adjust the mode first. I was a bit on the fence whether I should subsume the pixel multiplier handling into the port_clock, too. But then I decided against this since it's on an abstract level still the dotclock of the adjusted mode, and only our hw makes it a bit special due to the separate pixel mulitplier setting (which requires that the dpll runs at the non-multiplied dotclock). So after this patch the adjusted_mode accurately describes the mode we feed into the port, after the panel fitter and pixel multiplier (or line doubling, if we ever bother with that) have done their job. Since the fdi link is between the pfit and the pixel multiplier steps we need to be careful with calculating the fdi link config. v2: Fix up ilk cpu pll handling. v3: Introduce an fdi_dotclock variable in ironlake_fdi_compute_config to make it clearer that we transmit the adjusted_mode without the pixel multiplier taken into account. The old code multiplied the the available link bw with the pixel multiplier, which results in the same fdi configuration, but is much more confusing. v4: Rebase on top of Imre's is_cpu_edp removal. v5: Rebase on top of Paulo's haswell watermark fixes, which introduce a new place which looked at the pixel_clock and so needed conversion. v6: Split out prep patches as requested by Paulo Zanoni. Also rebase on top of the fdi dotclock handling fix in the fdi lanes/bw computation code. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> (v3) Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v6) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c3
-rw-r--r--drivers/gpu/drm/i915/intel_display.c32
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c18
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h13
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c4
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c5
6 files changed, 35 insertions, 40 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 9649df806079..486c46bf5ccf 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -624,7 +624,7 @@ intel_ddi_calculate_wrpll(int clock /* in Hz */,
624 clock, *p_out, *n2_out, *r2_out); 624 clock, *p_out, *n2_out, *r2_out);
625} 625}
626 626
627bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock) 627bool intel_ddi_pll_mode_set(struct drm_crtc *crtc)
628{ 628{
629 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 629 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
630 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); 630 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
@@ -634,6 +634,7 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
634 int type = intel_encoder->type; 634 int type = intel_encoder->type;
635 enum pipe pipe = intel_crtc->pipe; 635 enum pipe pipe = intel_crtc->pipe;
636 uint32_t reg, val; 636 uint32_t reg, val;
637 int clock = intel_crtc->config.port_clock;
637 638
638 /* TODO: reuse PLLs when possible (compare values) */ 639 /* TODO: reuse PLLs when possible (compare values) */
639 640
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 711ec3314893..60d4bfd40107 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3989,7 +3989,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
3989{ 3989{
3990 struct drm_device *dev = intel_crtc->base.dev; 3990 struct drm_device *dev = intel_crtc->base.dev;
3991 struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; 3991 struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
3992 int target_clock, lane, link_bw, fdi_dotclock; 3992 int lane, link_bw, fdi_dotclock;
3993 bool setup_ok, needs_recompute = false; 3993 bool setup_ok, needs_recompute = false;
3994 3994
3995retry: 3995retry:
@@ -4002,12 +4002,7 @@ retry:
4002 */ 4002 */
4003 link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; 4003 link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
4004 4004
4005 if (pipe_config->pixel_target_clock) 4005 fdi_dotclock = adjusted_mode->clock;
4006 target_clock = pipe_config->pixel_target_clock;
4007 else
4008 target_clock = adjusted_mode->clock;
4009
4010 fdi_dotclock = target_clock;
4011 if (pipe_config->pixel_multiplier > 1) 4006 if (pipe_config->pixel_multiplier > 1)
4012 fdi_dotclock /= pipe_config->pixel_multiplier; 4007 fdi_dotclock /= pipe_config->pixel_multiplier;
4013 4008
@@ -4357,8 +4352,6 @@ static void vlv_update_pll(struct intel_crtc *crtc)
4357{ 4352{
4358 struct drm_device *dev = crtc->base.dev; 4353 struct drm_device *dev = crtc->base.dev;
4359 struct drm_i915_private *dev_priv = dev->dev_private; 4354 struct drm_i915_private *dev_priv = dev->dev_private;
4360 struct drm_display_mode *adjusted_mode =
4361 &crtc->config.adjusted_mode;
4362 struct intel_encoder *encoder; 4355 struct intel_encoder *encoder;
4363 int pipe = crtc->pipe; 4356 int pipe = crtc->pipe;
4364 u32 dpll, mdiv; 4357 u32 dpll, mdiv;
@@ -4411,7 +4404,7 @@ static void vlv_update_pll(struct intel_crtc *crtc)
4411 vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); 4404 vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
4412 4405
4413 /* Set HBR and RBR LPF coefficients */ 4406 /* Set HBR and RBR LPF coefficients */
4414 if (adjusted_mode->clock == 162000 || 4407 if (crtc->config.port_clock == 162000 ||
4415 intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI)) 4408 intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI))
4416 vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), 4409 vlv_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe),
4417 0x005f0021); 4410 0x005f0021);
@@ -4856,7 +4849,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
4856 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. 4849 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
4857 */ 4850 */
4858 limit = intel_limit(crtc, refclk); 4851 limit = intel_limit(crtc, refclk);
4859 ok = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock, 4852 ok = dev_priv->display.find_dpll(limit, crtc,
4853 intel_crtc->config.port_clock,
4860 refclk, NULL, &clock); 4854 refclk, NULL, &clock);
4861 if (!ok && !intel_crtc->config.clock_set) { 4855 if (!ok && !intel_crtc->config.clock_set) {
4862 DRM_ERROR("Couldn't find PLL settings for mode!\n"); 4856 DRM_ERROR("Couldn't find PLL settings for mode!\n");
@@ -5464,7 +5458,6 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
5464} 5458}
5465 5459
5466static bool ironlake_compute_clocks(struct drm_crtc *crtc, 5460static bool ironlake_compute_clocks(struct drm_crtc *crtc,
5467 struct drm_display_mode *adjusted_mode,
5468 intel_clock_t *clock, 5461 intel_clock_t *clock,
5469 bool *has_reduced_clock, 5462 bool *has_reduced_clock,
5470 intel_clock_t *reduced_clock) 5463 intel_clock_t *reduced_clock)
@@ -5492,7 +5485,8 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
5492 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. 5485 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
5493 */ 5486 */
5494 limit = intel_limit(crtc, refclk); 5487 limit = intel_limit(crtc, refclk);
5495 ret = dev_priv->display.find_dpll(limit, crtc, adjusted_mode->clock, 5488 ret = dev_priv->display.find_dpll(limit, crtc,
5489 to_intel_crtc(crtc)->config.port_clock,
5496 refclk, NULL, clock); 5490 refclk, NULL, clock);
5497 if (!ret) 5491 if (!ret)
5498 return false; 5492 return false;
@@ -5692,7 +5686,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
5692 WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)), 5686 WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)),
5693 "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev)); 5687 "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev));
5694 5688
5695 ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock, 5689 ok = ironlake_compute_clocks(crtc, &clock,
5696 &has_reduced_clock, &reduced_clock); 5690 &has_reduced_clock, &reduced_clock);
5697 if (!ok && !intel_crtc->config.clock_set) { 5691 if (!ok && !intel_crtc->config.clock_set) {
5698 DRM_ERROR("Couldn't find PLL settings for mode!\n"); 5692 DRM_ERROR("Couldn't find PLL settings for mode!\n");
@@ -5895,7 +5889,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
5895 WARN(num_connectors != 1, "%d connectors attached to pipe %c\n", 5889 WARN(num_connectors != 1, "%d connectors attached to pipe %c\n",
5896 num_connectors, pipe_name(pipe)); 5890 num_connectors, pipe_name(pipe));
5897 5891
5898 if (!intel_ddi_pll_mode_set(crtc, adjusted_mode->clock)) 5892 if (!intel_ddi_pll_mode_set(crtc))
5899 return -EINVAL; 5893 return -EINVAL;
5900 5894
5901 /* Ensure that the cursor is valid for the new mode before changing... */ 5895 /* Ensure that the cursor is valid for the new mode before changing... */
@@ -7805,6 +7799,9 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
7805 goto fail; 7799 goto fail;
7806 7800
7807encoder_retry: 7801encoder_retry:
7802 /* Ensure the port clock default is reset when retrying. */
7803 pipe_config->port_clock = 0;
7804
7808 /* Pass our mode to the connectors and the CRTC to give them a chance to 7805 /* Pass our mode to the connectors and the CRTC to give them a chance to
7809 * adjust it according to limitations or connector properties, and also 7806 * adjust it according to limitations or connector properties, and also
7810 * a chance to reject the mode entirely. 7807 * a chance to reject the mode entirely.
@@ -7833,6 +7830,11 @@ encoder_retry:
7833 } 7830 }
7834 } 7831 }
7835 7832
7833 /* Set default port clock if not overwritten by the encoder. Needs to be
7834 * done afterwards in case the encoder adjusts the mode. */
7835 if (!pipe_config->port_clock)
7836 pipe_config->port_clock = pipe_config->adjusted_mode.clock;
7837
7836 ret = intel_crtc_compute_config(crtc, pipe_config); 7838 ret = intel_crtc_compute_config(crtc, pipe_config);
7837 if (ret < 0) { 7839 if (ret < 0) {
7838 DRM_DEBUG_KMS("CRTC fixup failed\n"); 7840 DRM_DEBUG_KMS("CRTC fixup failed\n");
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 3b490c097400..759a1c5d170d 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -677,7 +677,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
677 int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; 677 int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
678 int bpp, mode_rate; 678 int bpp, mode_rate;
679 static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; 679 static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
680 int target_clock, link_avail, link_clock; 680 int link_avail, link_clock;
681 681
682 if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A) 682 if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A)
683 pipe_config->has_pch_encoder = true; 683 pipe_config->has_pch_encoder = true;
@@ -694,8 +694,6 @@ intel_dp_compute_config(struct intel_encoder *encoder,
694 intel_pch_panel_fitting(intel_crtc, pipe_config, 694 intel_pch_panel_fitting(intel_crtc, pipe_config,
695 intel_connector->panel.fitting_mode); 695 intel_connector->panel.fitting_mode);
696 } 696 }
697 /* We need to take the panel's fixed mode into account. */
698 target_clock = adjusted_mode->clock;
699 697
700 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) 698 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
701 return false; 699 return false;
@@ -711,7 +709,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
711 bpp = min_t(int, bpp, dev_priv->vbt.edp_bpp); 709 bpp = min_t(int, bpp, dev_priv->vbt.edp_bpp);
712 710
713 for (; bpp >= 6*3; bpp -= 2*3) { 711 for (; bpp >= 6*3; bpp -= 2*3) {
714 mode_rate = intel_dp_link_required(target_clock, bpp); 712 mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
715 713
716 for (clock = 0; clock <= max_clock; clock++) { 714 for (clock = 0; clock <= max_clock; clock++) {
717 for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { 715 for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
@@ -746,18 +744,17 @@ found:
746 744
747 intel_dp->link_bw = bws[clock]; 745 intel_dp->link_bw = bws[clock];
748 intel_dp->lane_count = lane_count; 746 intel_dp->lane_count = lane_count;
749 adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
750 pipe_config->pipe_bpp = bpp; 747 pipe_config->pipe_bpp = bpp;
751 pipe_config->pixel_target_clock = target_clock; 748 pipe_config->port_clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
752 749
753 DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n", 750 DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
754 intel_dp->link_bw, intel_dp->lane_count, 751 intel_dp->link_bw, intel_dp->lane_count,
755 adjusted_mode->clock, bpp); 752 pipe_config->port_clock, bpp);
756 DRM_DEBUG_KMS("DP link bw required %i available %i\n", 753 DRM_DEBUG_KMS("DP link bw required %i available %i\n",
757 mode_rate, link_avail); 754 mode_rate, link_avail);
758 755
759 intel_link_compute_m_n(bpp, lane_count, 756 intel_link_compute_m_n(bpp, lane_count,
760 target_clock, adjusted_mode->clock, 757 adjusted_mode->clock, pipe_config->port_clock,
761 &pipe_config->dp_m_n); 758 &pipe_config->dp_m_n);
762 759
763 intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw); 760 intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
@@ -788,12 +785,11 @@ static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp)
788 struct drm_i915_private *dev_priv = dev->dev_private; 785 struct drm_i915_private *dev_priv = dev->dev_private;
789 u32 dpa_ctl; 786 u32 dpa_ctl;
790 787
791 DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", 788 DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", crtc->config.port_clock);
792 crtc->config.adjusted_mode.clock);
793 dpa_ctl = I915_READ(DP_A); 789 dpa_ctl = I915_READ(DP_A);
794 dpa_ctl &= ~DP_PLL_FREQ_MASK; 790 dpa_ctl &= ~DP_PLL_FREQ_MASK;
795 791
796 if (crtc->config.adjusted_mode.clock == 162000) { 792 if (crtc->config.port_clock == 162000) {
797 /* For a long time we've carried around a ILK-DevA w/a for the 793 /* For a long time we've carried around a ILK-DevA w/a for the
798 * 160MHz clock. If we're really unlucky, it's still required. 794 * 160MHz clock. If we're really unlucky, it's still required.
799 */ 795 */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index fdf6303be0a9..afda71fdb4a6 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -243,12 +243,13 @@ struct intel_crtc_config {
243 243
244 int pipe_bpp; 244 int pipe_bpp;
245 struct intel_link_m_n dp_m_n; 245 struct intel_link_m_n dp_m_n;
246 /** 246
247 * This is currently used by DP and HDMI encoders since those can have a 247 /*
248 * target pixel clock != the port link clock (which is currently stored 248 * Frequence the dpll for the port should run at. Differs from the
249 * in adjusted_mode->clock). 249 * adjusted dotclock e.g. for DP or 12bpc hdmi mode.
250 */ 250 */
251 int pixel_target_clock; 251 int port_clock;
252
252 /* Used by SDVO (and if we ever fix it, HDMI). */ 253 /* Used by SDVO (and if we ever fix it, HDMI). */
253 unsigned pixel_multiplier; 254 unsigned pixel_multiplier;
254 255
@@ -786,7 +787,7 @@ extern void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
786extern void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc); 787extern void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
787extern void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc); 788extern void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
788extern void intel_ddi_setup_hw_pll_state(struct drm_device *dev); 789extern void intel_ddi_setup_hw_pll_state(struct drm_device *dev);
789extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock); 790extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc);
790extern void intel_ddi_put_crtc_pll(struct drm_crtc *crtc); 791extern void intel_ddi_put_crtc_pll(struct drm_crtc *crtc);
791extern void intel_ddi_set_pipe_settings(struct drm_crtc *crtc); 792extern void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
792extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder); 793extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 8062a92e6e80..bc12518a21b4 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -835,9 +835,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
835 desired_bpp = 12*3; 835 desired_bpp = 12*3;
836 836
837 /* Need to adjust the port link by 1.5x for 12bpc. */ 837 /* Need to adjust the port link by 1.5x for 12bpc. */
838 adjusted_mode->clock = clock_12bpc; 838 pipe_config->port_clock = clock_12bpc;
839 pipe_config->pixel_target_clock =
840 pipe_config->requested_mode.clock;
841 } else { 839 } else {
842 DRM_DEBUG_KMS("picking bpc to 8 for HDMI output\n"); 840 DRM_DEBUG_KMS("picking bpc to 8 for HDMI output\n");
843 desired_bpp = 8*3; 841 desired_bpp = 8*3;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 49a188718f9d..4126fb1b3dd4 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2078,10 +2078,7 @@ static uint32_t hsw_wm_get_pixel_rate(struct drm_device *dev,
2078 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 2078 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
2079 uint32_t pixel_rate, pfit_size; 2079 uint32_t pixel_rate, pfit_size;
2080 2080
2081 if (intel_crtc->config.pixel_target_clock) 2081 pixel_rate = intel_crtc->config.adjusted_mode.clock;
2082 pixel_rate = intel_crtc->config.pixel_target_clock;
2083 else
2084 pixel_rate = intel_crtc->config.adjusted_mode.clock;
2085 2082
2086 /* We only use IF-ID interlacing. If we ever use PF-ID we'll need to 2083 /* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
2087 * adjust the pixel_rate here. */ 2084 * adjust the pixel_rate here. */