aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ddi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ddi.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c141
1 files changed, 13 insertions, 128 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 150b64b45cb6..60e67a11791b 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -388,30 +388,12 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
388 388
389void intel_ddi_put_crtc_pll(struct drm_crtc *crtc) 389void intel_ddi_put_crtc_pll(struct drm_crtc *crtc)
390{ 390{
391 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
392 struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
393 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 391 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
394 struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(intel_crtc);
395 392
396 switch (intel_crtc->config.ddi_pll_sel) { 393 if (intel_crtc_to_shared_dpll(intel_crtc))
397 case PORT_CLK_SEL_WRPLL1: 394 intel_disable_shared_dpll(intel_crtc);
398 plls->wrpll1_refcount--;
399 if (plls->wrpll1_refcount == 0) {
400 pll->disable(dev_priv, pll);
401 }
402 intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
403 break;
404 case PORT_CLK_SEL_WRPLL2:
405 plls->wrpll2_refcount--;
406 if (plls->wrpll2_refcount == 0) {
407 pll->disable(dev_priv, pll);
408 }
409 intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
410 break;
411 }
412 395
413 WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n"); 396 intel_put_shared_dpll(intel_crtc);
414 WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n");
415} 397}
416 398
417#define LC_FREQ 2700 399#define LC_FREQ 2700
@@ -731,17 +713,14 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
731{ 713{
732 struct drm_crtc *crtc = &intel_crtc->base; 714 struct drm_crtc *crtc = &intel_crtc->base;
733 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); 715 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
734 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
735 struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
736 int type = intel_encoder->type; 716 int type = intel_encoder->type;
737 enum pipe pipe = intel_crtc->pipe;
738 int clock = intel_crtc->config.port_clock; 717 int clock = intel_crtc->config.port_clock;
739 718
740 intel_ddi_put_crtc_pll(crtc); 719 intel_ddi_put_crtc_pll(crtc);
741 720
742 if (type == INTEL_OUTPUT_HDMI) { 721 if (type == INTEL_OUTPUT_HDMI) {
743 struct intel_shared_dpll *pll; 722 struct intel_shared_dpll *pll;
744 uint32_t reg, val; 723 uint32_t val;
745 unsigned p, n2, r2; 724 unsigned p, n2, r2;
746 725
747 intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); 726 intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
@@ -750,79 +729,21 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
750 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | 729 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
751 WRPLL_DIVIDER_POST(p); 730 WRPLL_DIVIDER_POST(p);
752 731
753 if (val == I915_READ(WRPLL_CTL1)) { 732 intel_crtc->config.dpll_hw_state.wrpll = val;
754 DRM_DEBUG_KMS("Reusing WRPLL 1 on pipe %c\n",
755 pipe_name(pipe));
756 reg = WRPLL_CTL1;
757 } else if (val == I915_READ(WRPLL_CTL2)) {
758 DRM_DEBUG_KMS("Reusing WRPLL 2 on pipe %c\n",
759 pipe_name(pipe));
760 reg = WRPLL_CTL2;
761 } else if (plls->wrpll1_refcount == 0) {
762 DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n",
763 pipe_name(pipe));
764 reg = WRPLL_CTL1;
765 } else if (plls->wrpll2_refcount == 0) {
766 DRM_DEBUG_KMS("Using WRPLL 2 on pipe %c\n",
767 pipe_name(pipe));
768 reg = WRPLL_CTL2;
769 } else {
770 DRM_ERROR("No WRPLLs available!\n");
771 return false;
772 }
773 733
774 DRM_DEBUG_KMS("WRPLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n", 734 pll = intel_get_shared_dpll(intel_crtc);
775 clock, p, n2, r2); 735 if (pll == NULL) {
776 736 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
777 if (reg == WRPLL_CTL1) { 737 pipe_name(intel_crtc->pipe));
778 plls->wrpll1_refcount++; 738 return false;
779 intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL1;
780 intel_crtc->config.shared_dpll = DPLL_ID_WRPLL1;
781 } else {
782 plls->wrpll2_refcount++;
783 intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL2;
784 intel_crtc->config.shared_dpll = DPLL_ID_WRPLL2;
785 } 739 }
786 740
787 intel_crtc->config.dpll_hw_state.wrpll = val; 741 intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
788
789 pll = &dev_priv->shared_dplls[intel_crtc->config.shared_dpll];
790 pll->hw_state.wrpll = val;
791 } 742 }
792 743
793 return true; 744 return true;
794} 745}
795 746
796/*
797 * To be called after intel_ddi_pll_select(). That one selects the PLL to be
798 * used, this one actually enables the PLL.
799 */
800void intel_ddi_pll_enable(struct intel_crtc *crtc)
801{
802 struct drm_device *dev = crtc->base.dev;
803 struct drm_i915_private *dev_priv = dev->dev_private;
804 struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
805 int refcount;
806 struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
807
808 switch (crtc->config.ddi_pll_sel) {
809 case PORT_CLK_SEL_WRPLL1:
810 case PORT_CLK_SEL_WRPLL2:
811 if (crtc->config.ddi_pll_sel == PORT_CLK_SEL_WRPLL1) {
812 refcount = plls->wrpll1_refcount;
813 } else {
814 refcount = plls->wrpll2_refcount;
815 }
816 break;
817 default:
818 return;
819 }
820
821 if (refcount == 1) {
822 pll->enable(dev_priv, pll);
823 }
824}
825
826void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) 747void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
827{ 748{
828 struct drm_i915_private *dev_priv = crtc->dev->dev_private; 749 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
@@ -1054,35 +975,6 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1054 return false; 975 return false;
1055} 976}
1056 977
1057void intel_ddi_setup_hw_pll_state(struct drm_device *dev)
1058{
1059 struct drm_i915_private *dev_priv = dev->dev_private;
1060 enum pipe pipe;
1061 struct intel_crtc *intel_crtc;
1062
1063 dev_priv->ddi_plls.wrpll1_refcount = 0;
1064 dev_priv->ddi_plls.wrpll2_refcount = 0;
1065
1066 for_each_pipe(pipe) {
1067 intel_crtc =
1068 to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
1069
1070 if (!intel_crtc->active) {
1071 intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
1072 continue;
1073 }
1074
1075 switch (intel_crtc->config.ddi_pll_sel) {
1076 case PORT_CLK_SEL_WRPLL1:
1077 dev_priv->ddi_plls.wrpll1_refcount++;
1078 break;
1079 case PORT_CLK_SEL_WRPLL2:
1080 dev_priv->ddi_plls.wrpll2_refcount++;
1081 break;
1082 }
1083 }
1084}
1085
1086void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) 978void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
1087{ 979{
1088 struct drm_crtc *crtc = &intel_crtc->base; 980 struct drm_crtc *crtc = &intel_crtc->base;
@@ -1288,10 +1180,6 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
1288static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv, 1180static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
1289 struct intel_shared_dpll *pll) 1181 struct intel_shared_dpll *pll)
1290{ 1182{
1291 uint32_t cur_val;
1292
1293 cur_val = I915_READ(WRPLL_CTL(pll->id));
1294 WARN(cur_val & WRPLL_PLL_ENABLE, "%s already enabled\n", pll->name);
1295 I915_WRITE(WRPLL_CTL(pll->id), pll->hw_state.wrpll); 1183 I915_WRITE(WRPLL_CTL(pll->id), pll->hw_state.wrpll);
1296 POSTING_READ(WRPLL_CTL(pll->id)); 1184 POSTING_READ(WRPLL_CTL(pll->id));
1297 udelay(20); 1185 udelay(20);
@@ -1303,7 +1191,6 @@ static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
1303 uint32_t val; 1191 uint32_t val;
1304 1192
1305 val = I915_READ(WRPLL_CTL(pll->id)); 1193 val = I915_READ(WRPLL_CTL(pll->id));
1306 WARN_ON(!(val & WRPLL_PLL_ENABLE));
1307 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE); 1194 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
1308 POSTING_READ(WRPLL_CTL(pll->id)); 1195 POSTING_READ(WRPLL_CTL(pll->id));
1309} 1196}
@@ -1334,11 +1221,9 @@ void intel_ddi_pll_init(struct drm_device *dev)
1334 uint32_t val = I915_READ(LCPLL_CTL); 1221 uint32_t val = I915_READ(LCPLL_CTL);
1335 int i; 1222 int i;
1336 1223
1337 /* Dummy setup until everything is moved over to avoid upsetting the hw 1224 dev_priv->num_shared_dpll = 2;
1338 * state cross checker. */
1339 dev_priv->num_shared_dpll = 0;
1340 1225
1341 for (i = 0; i < 2; i++) { 1226 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
1342 dev_priv->shared_dplls[i].id = i; 1227 dev_priv->shared_dplls[i].id = i;
1343 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i]; 1228 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
1344 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable; 1229 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;