drm/i915: Switch to common shared dpll framework for WRPLLs

Mostly this patch is one big excersize in deleting code and asserts
which are no longer needed. Note that we still abuse the shared dpll
framework a bit since we call the enable/disable functions from the
crtc mode_set and off hooks. But changing the actual hardware sequence
will be done in the next step.

Note that besides the massive amount of changes in this patch the
places and order in which the low-level WRPLL code is called is
absolutely unchanged.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>
[imre: rebased on patchset version w/o pch/crt/fdi refactoring]
Signed-off-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 150b64b..60e67a1 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -388,30 +388,12 @@
 
 void intel_ddi_put_crtc_pll(struct drm_crtc *crtc)
 {
-	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
-	struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(intel_crtc);
 
-	switch (intel_crtc->config.ddi_pll_sel) {
-	case PORT_CLK_SEL_WRPLL1:
-		plls->wrpll1_refcount--;
-		if (plls->wrpll1_refcount == 0) {
-			pll->disable(dev_priv, pll);
-		}
-		intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
-		break;
-	case PORT_CLK_SEL_WRPLL2:
-		plls->wrpll2_refcount--;
-		if (plls->wrpll2_refcount == 0) {
-			pll->disable(dev_priv, pll);
-		}
-		intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
-		break;
-	}
+	if (intel_crtc_to_shared_dpll(intel_crtc))
+		intel_disable_shared_dpll(intel_crtc);
 
-	WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n");
-	WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n");
+	intel_put_shared_dpll(intel_crtc);
 }
 
 #define LC_FREQ 2700
@@ -731,17 +713,14 @@
 {
 	struct drm_crtc *crtc = &intel_crtc->base;
 	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
-	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
-	struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
 	int type = intel_encoder->type;
-	enum pipe pipe = intel_crtc->pipe;
 	int clock = intel_crtc->config.port_clock;
 
 	intel_ddi_put_crtc_pll(crtc);
 
 	if (type == INTEL_OUTPUT_HDMI) {
 		struct intel_shared_dpll *pll;
-		uint32_t reg, val;
+		uint32_t val;
 		unsigned p, n2, r2;
 
 		intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
@@ -750,79 +729,21 @@
 		      WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
 		      WRPLL_DIVIDER_POST(p);
 
-		if (val == I915_READ(WRPLL_CTL1)) {
-			DRM_DEBUG_KMS("Reusing WRPLL 1 on pipe %c\n",
-				      pipe_name(pipe));
-			reg = WRPLL_CTL1;
-		} else if (val == I915_READ(WRPLL_CTL2)) {
-			DRM_DEBUG_KMS("Reusing WRPLL 2 on pipe %c\n",
-				      pipe_name(pipe));
-			reg = WRPLL_CTL2;
-		} else if (plls->wrpll1_refcount == 0) {
-			DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n",
-				      pipe_name(pipe));
-			reg = WRPLL_CTL1;
-		} else if (plls->wrpll2_refcount == 0) {
-			DRM_DEBUG_KMS("Using WRPLL 2 on pipe %c\n",
-				      pipe_name(pipe));
-			reg = WRPLL_CTL2;
-		} else {
-			DRM_ERROR("No WRPLLs available!\n");
+		intel_crtc->config.dpll_hw_state.wrpll = val;
+
+		pll = intel_get_shared_dpll(intel_crtc);
+		if (pll == NULL) {
+			DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
+					 pipe_name(intel_crtc->pipe));
 			return false;
 		}
 
-		DRM_DEBUG_KMS("WRPLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n",
-			      clock, p, n2, r2);
-
-		if (reg == WRPLL_CTL1) {
-			plls->wrpll1_refcount++;
-			intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL1;
-			intel_crtc->config.shared_dpll = DPLL_ID_WRPLL1;
-		} else {
-			plls->wrpll2_refcount++;
-			intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL2;
-			intel_crtc->config.shared_dpll = DPLL_ID_WRPLL2;
-		}
-
-		intel_crtc->config.dpll_hw_state.wrpll = val;
-
-		pll = &dev_priv->shared_dplls[intel_crtc->config.shared_dpll];
-		pll->hw_state.wrpll = val;
+		intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
 	}
 
 	return true;
 }
 
-/*
- * To be called after intel_ddi_pll_select(). That one selects the PLL to be
- * used, this one actually enables the PLL.
- */
-void intel_ddi_pll_enable(struct intel_crtc *crtc)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
-	int refcount;
-	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
-
-	switch (crtc->config.ddi_pll_sel) {
-	case PORT_CLK_SEL_WRPLL1:
-	case PORT_CLK_SEL_WRPLL2:
-		if (crtc->config.ddi_pll_sel == PORT_CLK_SEL_WRPLL1) {
-			refcount = plls->wrpll1_refcount;
-		} else {
-			refcount = plls->wrpll2_refcount;
-		}
-		break;
-	default:
-		return;
-	}
-
-	if (refcount == 1) {
-		pll->enable(dev_priv, pll);
-	}
-}
-
 void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
 {
 	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
@@ -1054,35 +975,6 @@
 	return false;
 }
 
-void intel_ddi_setup_hw_pll_state(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	enum pipe pipe;
-	struct intel_crtc *intel_crtc;
-
-	dev_priv->ddi_plls.wrpll1_refcount = 0;
-	dev_priv->ddi_plls.wrpll2_refcount = 0;
-
-	for_each_pipe(pipe) {
-		intel_crtc =
-			to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
-
-		if (!intel_crtc->active) {
-			intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
-			continue;
-		}
-
-		switch (intel_crtc->config.ddi_pll_sel) {
-		case PORT_CLK_SEL_WRPLL1:
-			dev_priv->ddi_plls.wrpll1_refcount++;
-			break;
-		case PORT_CLK_SEL_WRPLL2:
-			dev_priv->ddi_plls.wrpll2_refcount++;
-			break;
-		}
-	}
-}
-
 void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
 {
 	struct drm_crtc *crtc = &intel_crtc->base;
@@ -1288,10 +1180,6 @@
 static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
 			       struct intel_shared_dpll *pll)
 {
-	uint32_t cur_val;
-
-	cur_val = I915_READ(WRPLL_CTL(pll->id));
-	WARN(cur_val & WRPLL_PLL_ENABLE, "%s already enabled\n", pll->name);
 	I915_WRITE(WRPLL_CTL(pll->id), pll->hw_state.wrpll);
 	POSTING_READ(WRPLL_CTL(pll->id));
 	udelay(20);
@@ -1303,7 +1191,6 @@
 	uint32_t val;
 
 	val = I915_READ(WRPLL_CTL(pll->id));
-	WARN_ON(!(val & WRPLL_PLL_ENABLE));
 	I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
 	POSTING_READ(WRPLL_CTL(pll->id));
 }
@@ -1334,11 +1221,9 @@
 	uint32_t val = I915_READ(LCPLL_CTL);
 	int i;
 
-	/* Dummy setup until everything is moved over to avoid upsetting the hw
-	 * state cross checker. */
-	dev_priv->num_shared_dpll = 0;
+	dev_priv->num_shared_dpll = 2;
 
-	for (i = 0; i < 2; i++) {
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
 		dev_priv->shared_dplls[i].id = i;
 		dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
 		dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;