diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-07-04 10:26:04 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-07-10 16:11:18 -0400 |
commit | 0e50338cf0f0009a5c9bc847a4c86a1d4438af66 (patch) | |
tree | d7fec4572eee7e3ddc20b9a3bfe1934b4135d9f4 | |
parent | 3fcf305b36a7be8bfc8f9e53b0498fbba7768da6 (diff) |
drm/i915: Precompute static ddi_pll_sel values in encoders
This way only the dynamic WRPLL selection for hdmi ddi mode is
done in intel_ddi_pll_select.
v2: Don't clobber the precomputed values when selecting clocks fro
hdmi encoders.
v3 (from Paulo): Rebase on top of the s/IS_HASWELL/HAS_DDI/ patch.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Paulo Zanoni <przanoni@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 23 |
3 files changed, 26 insertions, 35 deletions
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 30bfdc735fee..4b085611a281 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -315,8 +315,10 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder, | |||
315 | pipe_config->pipe_bpp = 24; | 315 | pipe_config->pipe_bpp = 24; |
316 | 316 | ||
317 | /* FDI must always be 2.7 GHz */ | 317 | /* FDI must always be 2.7 GHz */ |
318 | if (HAS_DDI(dev)) | 318 | if (HAS_DDI(dev)) { |
319 | pipe_config->ddi_pll_sel = PORT_CLK_SEL_SPLL; | ||
319 | pipe_config->port_clock = 135000 * 2; | 320 | pipe_config->port_clock = 135000 * 2; |
321 | } | ||
320 | 322 | ||
321 | return true; | 323 | return true; |
322 | } | 324 | } |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 1b4748bf56fc..195d52ef512f 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -403,6 +403,7 @@ void intel_ddi_put_crtc_pll(struct drm_crtc *crtc) | |||
403 | I915_WRITE(WRPLL_CTL1, val & ~WRPLL_PLL_ENABLE); | 403 | I915_WRITE(WRPLL_CTL1, val & ~WRPLL_PLL_ENABLE); |
404 | POSTING_READ(WRPLL_CTL1); | 404 | POSTING_READ(WRPLL_CTL1); |
405 | } | 405 | } |
406 | intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE; | ||
406 | break; | 407 | break; |
407 | case PORT_CLK_SEL_WRPLL2: | 408 | case PORT_CLK_SEL_WRPLL2: |
408 | plls->wrpll2_refcount--; | 409 | plls->wrpll2_refcount--; |
@@ -413,13 +414,12 @@ void intel_ddi_put_crtc_pll(struct drm_crtc *crtc) | |||
413 | I915_WRITE(WRPLL_CTL2, val & ~WRPLL_PLL_ENABLE); | 414 | I915_WRITE(WRPLL_CTL2, val & ~WRPLL_PLL_ENABLE); |
414 | POSTING_READ(WRPLL_CTL2); | 415 | POSTING_READ(WRPLL_CTL2); |
415 | } | 416 | } |
417 | intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE; | ||
416 | break; | 418 | break; |
417 | } | 419 | } |
418 | 420 | ||
419 | WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n"); | 421 | WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n"); |
420 | WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n"); | 422 | WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n"); |
421 | |||
422 | intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE; | ||
423 | } | 423 | } |
424 | 424 | ||
425 | #define LC_FREQ 2700 | 425 | #define LC_FREQ 2700 |
@@ -739,7 +739,6 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc) | |||
739 | { | 739 | { |
740 | struct drm_crtc *crtc = &intel_crtc->base; | 740 | struct drm_crtc *crtc = &intel_crtc->base; |
741 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); | 741 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
742 | struct drm_encoder *encoder = &intel_encoder->base; | ||
743 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; | 742 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
744 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; | 743 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; |
745 | int type = intel_encoder->type; | 744 | int type = intel_encoder->type; |
@@ -748,26 +747,7 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc) | |||
748 | 747 | ||
749 | intel_ddi_put_crtc_pll(crtc); | 748 | intel_ddi_put_crtc_pll(crtc); |
750 | 749 | ||
751 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { | 750 | if (type == INTEL_OUTPUT_HDMI) { |
752 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
753 | |||
754 | switch (intel_dp->link_bw) { | ||
755 | case DP_LINK_BW_1_62: | ||
756 | intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_LCPLL_810; | ||
757 | break; | ||
758 | case DP_LINK_BW_2_7: | ||
759 | intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350; | ||
760 | break; | ||
761 | case DP_LINK_BW_5_4: | ||
762 | intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700; | ||
763 | break; | ||
764 | default: | ||
765 | DRM_ERROR("Link bandwidth %d unsupported\n", | ||
766 | intel_dp->link_bw); | ||
767 | return false; | ||
768 | } | ||
769 | |||
770 | } else if (type == INTEL_OUTPUT_HDMI) { | ||
771 | uint32_t reg, val; | 751 | uint32_t reg, val; |
772 | unsigned p, n2, r2; | 752 | unsigned p, n2, r2; |
773 | 753 | ||
@@ -808,14 +788,6 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc) | |||
808 | plls->wrpll2_refcount++; | 788 | plls->wrpll2_refcount++; |
809 | intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL2; | 789 | intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL2; |
810 | } | 790 | } |
811 | |||
812 | } else if (type == INTEL_OUTPUT_ANALOG) { | ||
813 | DRM_DEBUG_KMS("Using SPLL on pipe %c\n", | ||
814 | pipe_name(pipe)); | ||
815 | intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_SPLL; | ||
816 | } else { | ||
817 | WARN(1, "Invalid DDI encoder type %d\n", type); | ||
818 | return false; | ||
819 | } | 791 | } |
820 | 792 | ||
821 | return true; | 793 | return true; |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 568e532e3b42..ec080e5f3e24 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -746,6 +746,22 @@ intel_dp_connector_unregister(struct intel_connector *intel_connector) | |||
746 | } | 746 | } |
747 | 747 | ||
748 | static void | 748 | static void |
749 | hsw_dp_set_ddi_pll_sel(struct intel_crtc_config *pipe_config, int link_bw) | ||
750 | { | ||
751 | switch (link_bw) { | ||
752 | case DP_LINK_BW_1_62: | ||
753 | pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810; | ||
754 | break; | ||
755 | case DP_LINK_BW_2_7: | ||
756 | pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350; | ||
757 | break; | ||
758 | case DP_LINK_BW_5_4: | ||
759 | pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700; | ||
760 | break; | ||
761 | } | ||
762 | } | ||
763 | |||
764 | static void | ||
749 | intel_dp_set_clock(struct intel_encoder *encoder, | 765 | intel_dp_set_clock(struct intel_encoder *encoder, |
750 | struct intel_crtc_config *pipe_config, int link_bw) | 766 | struct intel_crtc_config *pipe_config, int link_bw) |
751 | { | 767 | { |
@@ -756,8 +772,6 @@ intel_dp_set_clock(struct intel_encoder *encoder, | |||
756 | if (IS_G4X(dev)) { | 772 | if (IS_G4X(dev)) { |
757 | divisor = gen4_dpll; | 773 | divisor = gen4_dpll; |
758 | count = ARRAY_SIZE(gen4_dpll); | 774 | count = ARRAY_SIZE(gen4_dpll); |
759 | } else if (HAS_DDI(dev)) { | ||
760 | /* Haswell has special-purpose DP DDI clocks. */ | ||
761 | } else if (HAS_PCH_SPLIT(dev)) { | 775 | } else if (HAS_PCH_SPLIT(dev)) { |
762 | divisor = pch_dpll; | 776 | divisor = pch_dpll; |
763 | count = ARRAY_SIZE(pch_dpll); | 777 | count = ARRAY_SIZE(pch_dpll); |
@@ -928,7 +942,10 @@ found: | |||
928 | &pipe_config->dp_m2_n2); | 942 | &pipe_config->dp_m2_n2); |
929 | } | 943 | } |
930 | 944 | ||
931 | intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw); | 945 | if (HAS_DDI(dev)) |
946 | hsw_dp_set_ddi_pll_sel(pipe_config, intel_dp->link_bw); | ||
947 | else | ||
948 | intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw); | ||
932 | 949 | ||
933 | return true; | 950 | return true; |
934 | } | 951 | } |