diff mbox series

[10/11] drm/i915: migrate pll enable/disable code to intel_dpll.[ch]

Message ID 42acfc7660491e9cf50879c3b3c20d69e0397cb2.1610622609.git.jani.nikula@intel.com (mailing list archive)
State New, archived
Headers show
Series rebased refactor of intel_display | expand

Commit Message

Jani Nikula Jan. 14, 2021, 11:13 a.m. UTC
From: Dave Airlie <airlied@redhat.com>

This moves the older i9xx/vlv/chv enable/disable to dpll file.

!!! FIXME: Dave's s-o-b !!!

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 512 -------------------
 drivers/gpu/drm/i915/display/intel_display.h |   3 -
 drivers/gpu/drm/i915/display/intel_dp.c      |   1 +
 drivers/gpu/drm/i915/display/intel_dpll.c    | 509 ++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dpll.h    |  18 +
 drivers/gpu/drm/i915/display/intel_pps.c     |   1 +
 6 files changed, 529 insertions(+), 515 deletions(-)

Comments

Ville Syrjälä Jan. 14, 2021, 3:59 p.m. UTC | #1
On Thu, Jan 14, 2021 at 01:13:54PM +0200, Jani Nikula wrote:
> From: Dave Airlie <airlied@redhat.com>
> 
> This moves the older i9xx/vlv/chv enable/disable to dpll file.
> 
> !!! FIXME: Dave's s-o-b !!!
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 512 -------------------
>  drivers/gpu/drm/i915/display/intel_display.h |   3 -
>  drivers/gpu/drm/i915/display/intel_dp.c      |   1 +
>  drivers/gpu/drm/i915/display/intel_dpll.c    | 509 ++++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_dpll.h    |  18 +
>  drivers/gpu/drm/i915/display/intel_pps.c     |   1 +
>  6 files changed, 529 insertions(+), 515 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 7398927e1627..8abd49cf9c2b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -109,10 +109,6 @@ static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state);
>  static void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state);
>  static void hsw_set_pipeconf(const struct intel_crtc_state *crtc_state);
>  static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state);
> -static void vlv_prepare_pll(struct intel_crtc *crtc,
> -			    const struct intel_crtc_state *pipe_config);
> -static void chv_prepare_pll(struct intel_crtc *crtc,
> -			    const struct intel_crtc_state *pipe_config);
>  static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state);
>  static void intel_modeset_setup_hw_state(struct drm_device *dev,
>  					 struct drm_modeset_acquire_ctx *ctx);
> @@ -565,224 +561,6 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
>  	assert_pch_hdmi_disabled(dev_priv, pipe, PORT_D, PCH_HDMID);
>  }
>  
> -static void _vlv_enable_pll(struct intel_crtc *crtc,
> -			    const struct intel_crtc_state *pipe_config)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	enum pipe pipe = crtc->pipe;
> -
> -	intel_de_write(dev_priv, DPLL(pipe), pipe_config->dpll_hw_state.dpll);
> -	intel_de_posting_read(dev_priv, DPLL(pipe));
> -	udelay(150);
> -
> -	if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
> -		drm_err(&dev_priv->drm, "DPLL %d failed to lock\n", pipe);
> -}
> -
> -static void vlv_enable_pll(struct intel_crtc *crtc,
> -			   const struct intel_crtc_state *pipe_config)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	enum pipe pipe = crtc->pipe;
> -
> -	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder);
> -
> -	/* PLL is protected by panel, make sure we can write it */
> -	assert_panel_unlocked(dev_priv, pipe);
> -
> -	if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
> -		_vlv_enable_pll(crtc, pipe_config);
> -
> -	intel_de_write(dev_priv, DPLL_MD(pipe),
> -		       pipe_config->dpll_hw_state.dpll_md);
> -	intel_de_posting_read(dev_priv, DPLL_MD(pipe));
> -}
> -
> -
> -static void _chv_enable_pll(struct intel_crtc *crtc,
> -			    const struct intel_crtc_state *pipe_config)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	enum pipe pipe = crtc->pipe;
> -	enum dpio_channel port = vlv_pipe_to_channel(pipe);
> -	u32 tmp;
> -
> -	vlv_dpio_get(dev_priv);
> -
> -	/* Enable back the 10bit clock to display controller */
> -	tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
> -	tmp |= DPIO_DCLKP_EN;
> -	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), tmp);
> -
> -	vlv_dpio_put(dev_priv);
> -
> -	/*
> -	 * Need to wait > 100ns between dclkp clock enable bit and PLL enable.
> -	 */
> -	udelay(1);
> -
> -	/* Enable PLL */
> -	intel_de_write(dev_priv, DPLL(pipe), pipe_config->dpll_hw_state.dpll);
> -
> -	/* Check PLL is locked */
> -	if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
> -		drm_err(&dev_priv->drm, "PLL %d failed to lock\n", pipe);
> -}
> -
> -static void chv_enable_pll(struct intel_crtc *crtc,
> -			   const struct intel_crtc_state *pipe_config)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	enum pipe pipe = crtc->pipe;
> -
> -	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder);
> -
> -	/* PLL is protected by panel, make sure we can write it */
> -	assert_panel_unlocked(dev_priv, pipe);
> -
> -	if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
> -		_chv_enable_pll(crtc, pipe_config);
> -
> -	if (pipe != PIPE_A) {
> -		/*
> -		 * WaPixelRepeatModeFixForC0:chv
> -		 *
> -		 * DPLLCMD is AWOL. Use chicken bits to propagate
> -		 * the value from DPLLBMD to either pipe B or C.
> -		 */
> -		intel_de_write(dev_priv, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe));
> -		intel_de_write(dev_priv, DPLL_MD(PIPE_B),
> -			       pipe_config->dpll_hw_state.dpll_md);
> -		intel_de_write(dev_priv, CBR4_VLV, 0);
> -		dev_priv->chv_dpll_md[pipe] = pipe_config->dpll_hw_state.dpll_md;
> -
> -		/*
> -		 * DPLLB VGA mode also seems to cause problems.
> -		 * We should always have it disabled.
> -		 */
> -		drm_WARN_ON(&dev_priv->drm,
> -			    (intel_de_read(dev_priv, DPLL(PIPE_B)) &
> -			     DPLL_VGA_MODE_DIS) == 0);
> -	} else {
> -		intel_de_write(dev_priv, DPLL_MD(pipe),
> -			       pipe_config->dpll_hw_state.dpll_md);
> -		intel_de_posting_read(dev_priv, DPLL_MD(pipe));
> -	}
> -}
> -
> -static bool i9xx_has_pps(struct drm_i915_private *dev_priv)
> -{
> -	if (IS_I830(dev_priv))
> -		return false;
> -
> -	return IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv);
> -}
> -
> -static void i9xx_enable_pll(struct intel_crtc *crtc,
> -			    const struct intel_crtc_state *crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	i915_reg_t reg = DPLL(crtc->pipe);
> -	u32 dpll = crtc_state->dpll_hw_state.dpll;
> -	int i;
> -
> -	assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder);
> -
> -	/* PLL is protected by panel, make sure we can write it */
> -	if (i9xx_has_pps(dev_priv))
> -		assert_panel_unlocked(dev_priv, crtc->pipe);
> -
> -	/*
> -	 * Apparently we need to have VGA mode enabled prior to changing
> -	 * the P1/P2 dividers. Otherwise the DPLL will keep using the old
> -	 * dividers, even though the register value does change.
> -	 */
> -	intel_de_write(dev_priv, reg, dpll & ~DPLL_VGA_MODE_DIS);
> -	intel_de_write(dev_priv, reg, dpll);
> -
> -	/* Wait for the clocks to stabilize. */
> -	intel_de_posting_read(dev_priv, reg);
> -	udelay(150);
> -
> -	if (INTEL_GEN(dev_priv) >= 4) {
> -		intel_de_write(dev_priv, DPLL_MD(crtc->pipe),
> -			       crtc_state->dpll_hw_state.dpll_md);
> -	} else {
> -		/* The pixel multiplier can only be updated once the
> -		 * DPLL is enabled and the clocks are stable.
> -		 *
> -		 * So write it again.
> -		 */
> -		intel_de_write(dev_priv, reg, dpll);
> -	}
> -
> -	/* We do this three times for luck */
> -	for (i = 0; i < 3; i++) {
> -		intel_de_write(dev_priv, reg, dpll);
> -		intel_de_posting_read(dev_priv, reg);
> -		udelay(150); /* wait for warmup */
> -	}
> -}
> -
> -static void i9xx_disable_pll(const struct intel_crtc_state *crtc_state)
> -{
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	enum pipe pipe = crtc->pipe;
> -
> -	/* Don't disable pipe or pipe PLLs if needed */
> -	if (IS_I830(dev_priv))
> -		return;
> -
> -	/* Make sure the pipe isn't still relying on us */
> -	assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder);
> -
> -	intel_de_write(dev_priv, DPLL(pipe), DPLL_VGA_MODE_DIS);
> -	intel_de_posting_read(dev_priv, DPLL(pipe));
> -}
> -
> -static void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
> -{
> -	u32 val;
> -
> -	/* Make sure the pipe isn't still relying on us */
> -	assert_pipe_disabled(dev_priv, (enum transcoder)pipe);
> -
> -	val = DPLL_INTEGRATED_REF_CLK_VLV |
> -		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
> -	if (pipe != PIPE_A)
> -		val |= DPLL_INTEGRATED_CRI_CLK_VLV;
> -
> -	intel_de_write(dev_priv, DPLL(pipe), val);
> -	intel_de_posting_read(dev_priv, DPLL(pipe));
> -}
> -
> -static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
> -{
> -	enum dpio_channel port = vlv_pipe_to_channel(pipe);
> -	u32 val;
> -
> -	/* Make sure the pipe isn't still relying on us */
> -	assert_pipe_disabled(dev_priv, (enum transcoder)pipe);
> -
> -	val = DPLL_SSC_REF_CLK_CHV |
> -		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
> -	if (pipe != PIPE_A)
> -		val |= DPLL_INTEGRATED_CRI_CLK_VLV;
> -
> -	intel_de_write(dev_priv, DPLL(pipe), val);
> -	intel_de_posting_read(dev_priv, DPLL(pipe));
> -
> -	vlv_dpio_get(dev_priv);
> -
> -	/* Disable 10bit clock to display controller */
> -	val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
> -	val &= ~DPIO_DCLKP_EN;
> -	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), val);
> -
> -	vlv_dpio_put(dev_priv);
> -}
> -
>  void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
>  			 struct intel_digital_port *dig_port,
>  			 unsigned int expected_mask)
> @@ -5709,35 +5487,6 @@ static void intel_panel_sanitize_ssc(struct drm_i915_private *dev_priv)
>  	}
>  }
>  
> -static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, enum pipe
> -		pipe)
> -{
> -	u32 reg_val;
> -
> -	/*
> -	 * PLLB opamp always calibrates to max value of 0x3f, force enable it
> -	 * and set it to a reasonable value instead.
> -	 */
> -	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
> -	reg_val &= 0xffffff00;
> -	reg_val |= 0x00000030;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
> -
> -	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
> -	reg_val &= 0x00ffffff;
> -	reg_val |= 0x8c000000;
> -	vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
> -
> -	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
> -	reg_val &= 0xffffff00;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
> -
> -	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
> -	reg_val &= 0x00ffffff;
> -	reg_val |= 0xb0000000;
> -	vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
> -}
> -
>  static void intel_pch_transcoder_set_m_n(const struct intel_crtc_state *crtc_state,
>  					 const struct intel_link_m_n *m_n)
>  {
> @@ -5833,267 +5582,6 @@ void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state, enum link_m_n_s
>  		intel_cpu_transcoder_set_m_n(crtc_state, dp_m_n, dp_m2_n2);
>  }
>  
> -static void vlv_prepare_pll(struct intel_crtc *crtc,
> -			    const struct intel_crtc_state *pipe_config)
> -{
> -	struct drm_device *dev = crtc->base.dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -	enum pipe pipe = crtc->pipe;
> -	u32 mdiv;
> -	u32 bestn, bestm1, bestm2, bestp1, bestp2;
> -	u32 coreclk, reg_val;
> -
> -	/* Enable Refclk */
> -	intel_de_write(dev_priv, DPLL(pipe),
> -		       pipe_config->dpll_hw_state.dpll & ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV));
> -
> -	/* No need to actually set up the DPLL with DSI */
> -	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
> -		return;
> -
> -	vlv_dpio_get(dev_priv);
> -
> -	bestn = pipe_config->dpll.n;
> -	bestm1 = pipe_config->dpll.m1;
> -	bestm2 = pipe_config->dpll.m2;
> -	bestp1 = pipe_config->dpll.p1;
> -	bestp2 = pipe_config->dpll.p2;
> -
> -	/* See eDP HDMI DPIO driver vbios notes doc */
> -
> -	/* PLL B needs special handling */
> -	if (pipe == PIPE_B)
> -		vlv_pllb_recal_opamp(dev_priv, pipe);
> -
> -	/* Set up Tx target for periodic Rcomp update */
> -	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9_BCAST, 0x0100000f);
> -
> -	/* Disable target IRef on PLL */
> -	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW8(pipe));
> -	reg_val &= 0x00ffffff;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW8(pipe), reg_val);
> -
> -	/* Disable fast lock */
> -	vlv_dpio_write(dev_priv, pipe, VLV_CMN_DW0, 0x610);
> -
> -	/* Set idtafcrecal before PLL is enabled */
> -	mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
> -	mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT));
> -	mdiv |= ((bestn << DPIO_N_SHIFT));
> -	mdiv |= (1 << DPIO_K_SHIFT);
> -
> -	/*
> -	 * Post divider depends on pixel clock rate, DAC vs digital (and LVDS,
> -	 * but we don't support that).
> -	 * Note: don't use the DAC post divider as it seems unstable.
> -	 */
> -	mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT);
> -	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
> -
> -	mdiv |= DPIO_ENABLE_CALIBRATION;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
> -
> -	/* Set HBR and RBR LPF coefficients */
> -	if (pipe_config->port_clock == 162000 ||
> -	    intel_crtc_has_type(pipe_config, INTEL_OUTPUT_ANALOG) ||
> -	    intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI))
> -		vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
> -				 0x009f0003);
> -	else
> -		vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
> -				 0x00d0000f);
> -
> -	if (intel_crtc_has_dp_encoder(pipe_config)) {
> -		/* Use SSC source */
> -		if (pipe == PIPE_A)
> -			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
> -					 0x0df40000);
> -		else
> -			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
> -					 0x0df70000);
> -	} else { /* HDMI or VGA */
> -		/* Use bend source */
> -		if (pipe == PIPE_A)
> -			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
> -					 0x0df70000);
> -		else
> -			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
> -					 0x0df40000);
> -	}
> -
> -	coreclk = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW7(pipe));
> -	coreclk = (coreclk & 0x0000ff00) | 0x01c00000;
> -	if (intel_crtc_has_dp_encoder(pipe_config))
> -		coreclk |= 0x01000000;
> -	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk);
> -
> -	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW11(pipe), 0x87871000);
> -
> -	vlv_dpio_put(dev_priv);
> -}
> -
> -static void chv_prepare_pll(struct intel_crtc *crtc,
> -			    const struct intel_crtc_state *pipe_config)
> -{
> -	struct drm_device *dev = crtc->base.dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -	enum pipe pipe = crtc->pipe;
> -	enum dpio_channel port = vlv_pipe_to_channel(pipe);
> -	u32 loopfilter, tribuf_calcntr;
> -	u32 bestn, bestm1, bestm2, bestp1, bestp2, bestm2_frac;
> -	u32 dpio_val;
> -	int vco;
> -
> -	/* Enable Refclk and SSC */
> -	intel_de_write(dev_priv, DPLL(pipe),
> -		       pipe_config->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE);
> -
> -	/* No need to actually set up the DPLL with DSI */
> -	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
> -		return;
> -
> -	bestn = pipe_config->dpll.n;
> -	bestm2_frac = pipe_config->dpll.m2 & 0x3fffff;
> -	bestm1 = pipe_config->dpll.m1;
> -	bestm2 = pipe_config->dpll.m2 >> 22;
> -	bestp1 = pipe_config->dpll.p1;
> -	bestp2 = pipe_config->dpll.p2;
> -	vco = pipe_config->dpll.vco;
> -	dpio_val = 0;
> -	loopfilter = 0;
> -
> -	vlv_dpio_get(dev_priv);
> -
> -	/* p1 and p2 divider */
> -	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW13(port),
> -			5 << DPIO_CHV_S1_DIV_SHIFT |
> -			bestp1 << DPIO_CHV_P1_DIV_SHIFT |
> -			bestp2 << DPIO_CHV_P2_DIV_SHIFT |
> -			1 << DPIO_CHV_K_DIV_SHIFT);
> -
> -	/* Feedback post-divider - m2 */
> -	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW0(port), bestm2);
> -
> -	/* Feedback refclk divider - n and m1 */
> -	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW1(port),
> -			DPIO_CHV_M1_DIV_BY_2 |
> -			1 << DPIO_CHV_N_DIV_SHIFT);
> -
> -	/* M2 fraction division */
> -	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW2(port), bestm2_frac);
> -
> -	/* M2 fraction division enable */
> -	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
> -	dpio_val &= ~(DPIO_CHV_FEEDFWD_GAIN_MASK | DPIO_CHV_FRAC_DIV_EN);
> -	dpio_val |= (2 << DPIO_CHV_FEEDFWD_GAIN_SHIFT);
> -	if (bestm2_frac)
> -		dpio_val |= DPIO_CHV_FRAC_DIV_EN;
> -	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW3(port), dpio_val);
> -
> -	/* Program digital lock detect threshold */
> -	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW9(port));
> -	dpio_val &= ~(DPIO_CHV_INT_LOCK_THRESHOLD_MASK |
> -					DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE);
> -	dpio_val |= (0x5 << DPIO_CHV_INT_LOCK_THRESHOLD_SHIFT);
> -	if (!bestm2_frac)
> -		dpio_val |= DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE;
> -	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW9(port), dpio_val);
> -
> -	/* Loop filter */
> -	if (vco == 5400000) {
> -		loopfilter |= (0x3 << DPIO_CHV_PROP_COEFF_SHIFT);
> -		loopfilter |= (0x8 << DPIO_CHV_INT_COEFF_SHIFT);
> -		loopfilter |= (0x1 << DPIO_CHV_GAIN_CTRL_SHIFT);
> -		tribuf_calcntr = 0x9;
> -	} else if (vco <= 6200000) {
> -		loopfilter |= (0x5 << DPIO_CHV_PROP_COEFF_SHIFT);
> -		loopfilter |= (0xB << DPIO_CHV_INT_COEFF_SHIFT);
> -		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
> -		tribuf_calcntr = 0x9;
> -	} else if (vco <= 6480000) {
> -		loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
> -		loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
> -		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
> -		tribuf_calcntr = 0x8;
> -	} else {
> -		/* Not supported. Apply the same limits as in the max case */
> -		loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
> -		loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
> -		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
> -		tribuf_calcntr = 0;
> -	}
> -	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW6(port), loopfilter);
> -
> -	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW8(port));
> -	dpio_val &= ~DPIO_CHV_TDC_TARGET_CNT_MASK;
> -	dpio_val |= (tribuf_calcntr << DPIO_CHV_TDC_TARGET_CNT_SHIFT);
> -	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW8(port), dpio_val);
> -
> -	/* AFC Recal */
> -	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port),
> -			vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)) |
> -			DPIO_AFC_RECAL);
> -
> -	vlv_dpio_put(dev_priv);
> -}
> -
> -/**
> - * vlv_force_pll_on - forcibly enable just the PLL
> - * @dev_priv: i915 private structure
> - * @pipe: pipe PLL to enable
> - * @dpll: PLL configuration
> - *
> - * Enable the PLL for @pipe using the supplied @dpll config. To be used
> - * in cases where we need the PLL enabled even when @pipe is not going to
> - * be enabled.
> - */
> -int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
> -		     const struct dpll *dpll)
> -{
> -	struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
> -	struct intel_crtc_state *pipe_config;
> -
> -	pipe_config = intel_crtc_state_alloc(crtc);
> -	if (!pipe_config)
> -		return -ENOMEM;
> -
> -	pipe_config->cpu_transcoder = (enum transcoder)pipe;
> -	pipe_config->pixel_multiplier = 1;
> -	pipe_config->dpll = *dpll;
> -
> -	if (IS_CHERRYVIEW(dev_priv)) {
> -		chv_compute_dpll(crtc, pipe_config);
> -		chv_prepare_pll(crtc, pipe_config);
> -		chv_enable_pll(crtc, pipe_config);
> -	} else {
> -		vlv_compute_dpll(crtc, pipe_config);
> -		vlv_prepare_pll(crtc, pipe_config);
> -		vlv_enable_pll(crtc, pipe_config);
> -	}
> -
> -	kfree(pipe_config);
> -
> -	return 0;
> -}
> -
> -/**
> - * vlv_force_pll_off - forcibly disable just the PLL
> - * @dev_priv: i915 private structure
> - * @pipe: pipe PLL to disable
> - *
> - * Disable the PLL for @pipe. To be used in cases where we need
> - * the PLL enabled even when @pipe is not going to be enabled.
> - */
> -void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe)
> -{
> -	if (IS_CHERRYVIEW(dev_priv))
> -		chv_disable_pll(dev_priv, pipe);
> -	else
> -		vlv_disable_pll(dev_priv, pipe);
> -}
> -
> -
> -
>  static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
>  {
>  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index f4214e161a9d..1cc1073a8f64 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -586,9 +586,6 @@ void intel_cleanup_plane_fb(struct drm_plane *plane,
>  void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
>  				    enum pipe pipe);
>  
> -int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
> -		     const struct dpll *dpll);
> -void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe);
>  int lpt_get_iclkip(struct drm_i915_private *dev_priv);
>  bool intel_fuzzy_clock_check(int clock1, int clock2);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index ec94ebdaf7b8..edb038cc7cd1 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -50,6 +50,7 @@
>  #include "intel_dp.h"
>  #include "intel_dp_link_training.h"
>  #include "intel_dp_mst.h"
> +#include "intel_dpll.h"
>  #include "intel_dpio_phy.h"
>  #include "intel_fifo_underrun.h"
>  #include "intel_hdcp.h"
> diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c
> index 7ba7f315aaee..166e9a3a8c09 100644
> --- a/drivers/gpu/drm/i915/display/intel_dpll.c
> +++ b/drivers/gpu/drm/i915/display/intel_dpll.c
> @@ -3,11 +3,13 @@
>   * Copyright © 2020 Intel Corporation
>   */
>  #include <linux/kernel.h>
> +#include "intel_crtc.h"
>  #include "intel_display_types.h"
>  #include "intel_display.h"
>  #include "intel_dpll.h"
>  #include "intel_lvds.h"
>  #include "intel_panel.h"
> +#include "intel_sideband.h"
>  
>  struct intel_limit {
>  	struct {
> @@ -1361,3 +1363,510 @@ intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv)
>  	else
>  		dev_priv->display.crtc_compute_clock = i8xx_crtc_compute_clock;
>  }
> +
> +static bool i9xx_has_pps(struct drm_i915_private *dev_priv)
> +{
> +	if (IS_I830(dev_priv))
> +		return false;
> +
> +	return IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv);
> +}
> +
> +void i9xx_enable_pll(struct intel_crtc *crtc,
> +		     const struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	i915_reg_t reg = DPLL(crtc->pipe);
> +	u32 dpll = crtc_state->dpll_hw_state.dpll;
> +	int i;
> +
> +	assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder);
> +
> +	/* PLL is protected by panel, make sure we can write it */
> +	if (i9xx_has_pps(dev_priv))
> +		assert_panel_unlocked(dev_priv, crtc->pipe);
> +
> +	/*
> +	 * Apparently we need to have VGA mode enabled prior to changing
> +	 * the P1/P2 dividers. Otherwise the DPLL will keep using the old
> +	 * dividers, even though the register value does change.
> +	 */
> +	intel_de_write(dev_priv, reg, dpll & ~DPLL_VGA_MODE_DIS);
> +	intel_de_write(dev_priv, reg, dpll);
> +
> +	/* Wait for the clocks to stabilize. */
> +	intel_de_posting_read(dev_priv, reg);
> +	udelay(150);
> +
> +	if (INTEL_GEN(dev_priv) >= 4) {
> +		intel_de_write(dev_priv, DPLL_MD(crtc->pipe),
> +			       crtc_state->dpll_hw_state.dpll_md);
> +	} else {
> +		/* The pixel multiplier can only be updated once the
> +		 * DPLL is enabled and the clocks are stable.
> +		 *
> +		 * So write it again.
> +		 */
> +		intel_de_write(dev_priv, reg, dpll);
> +	}
> +
> +	/* We do this three times for luck */
> +	for (i = 0; i < 3; i++) {
> +		intel_de_write(dev_priv, reg, dpll);
> +		intel_de_posting_read(dev_priv, reg);
> +		udelay(150); /* wait for warmup */
> +	}
> +}
> +
> +static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv,
> +				 enum pipe pipe)
> +{
> +	u32 reg_val;
> +
> +	/*
> +	 * PLLB opamp always calibrates to max value of 0x3f, force enable it
> +	 * and set it to a reasonable value instead.
> +	 */
> +	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
> +	reg_val &= 0xffffff00;
> +	reg_val |= 0x00000030;
> +	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
> +
> +	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
> +	reg_val &= 0x00ffffff;
> +	reg_val |= 0x8c000000;
> +	vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
> +
> +	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
> +	reg_val &= 0xffffff00;
> +	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
> +
> +	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
> +	reg_val &= 0x00ffffff;
> +	reg_val |= 0xb0000000;
> +	vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
> +}
> +
> +static void _vlv_enable_pll(struct intel_crtc *crtc,
> +			    const struct intel_crtc_state *pipe_config)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	enum pipe pipe = crtc->pipe;
> +
> +	intel_de_write(dev_priv, DPLL(pipe), pipe_config->dpll_hw_state.dpll);
> +	intel_de_posting_read(dev_priv, DPLL(pipe));
> +	udelay(150);
> +
> +	if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
> +		drm_err(&dev_priv->drm, "DPLL %d failed to lock\n", pipe);
> +}
> +
> +void vlv_enable_pll(struct intel_crtc *crtc,
> +		    const struct intel_crtc_state *pipe_config)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	enum pipe pipe = crtc->pipe;
> +
> +	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder);
> +
> +	/* PLL is protected by panel, make sure we can write it */
> +	assert_panel_unlocked(dev_priv, pipe);
> +
> +	if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
> +		_vlv_enable_pll(crtc, pipe_config);
> +
> +	intel_de_write(dev_priv, DPLL_MD(pipe),
> +		       pipe_config->dpll_hw_state.dpll_md);
> +	intel_de_posting_read(dev_priv, DPLL_MD(pipe));
> +}
> +
> +
> +static void _chv_enable_pll(struct intel_crtc *crtc,
> +			    const struct intel_crtc_state *pipe_config)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	enum pipe pipe = crtc->pipe;
> +	enum dpio_channel port = vlv_pipe_to_channel(pipe);
> +	u32 tmp;
> +
> +	vlv_dpio_get(dev_priv);
> +
> +	/* Enable back the 10bit clock to display controller */
> +	tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
> +	tmp |= DPIO_DCLKP_EN;
> +	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), tmp);
> +
> +	vlv_dpio_put(dev_priv);
> +
> +	/*
> +	 * Need to wait > 100ns between dclkp clock enable bit and PLL enable.
> +	 */
> +	udelay(1);
> +
> +	/* Enable PLL */
> +	intel_de_write(dev_priv, DPLL(pipe), pipe_config->dpll_hw_state.dpll);
> +
> +	/* Check PLL is locked */
> +	if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
> +		drm_err(&dev_priv->drm, "PLL %d failed to lock\n", pipe);
> +}
> +
> +void chv_enable_pll(struct intel_crtc *crtc,
> +		    const struct intel_crtc_state *pipe_config)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	enum pipe pipe = crtc->pipe;
> +
> +	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder);
> +
> +	/* PLL is protected by panel, make sure we can write it */
> +	assert_panel_unlocked(dev_priv, pipe);
> +
> +	if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
> +		_chv_enable_pll(crtc, pipe_config);
> +
> +	if (pipe != PIPE_A) {
> +		/*
> +		 * WaPixelRepeatModeFixForC0:chv
> +		 *
> +		 * DPLLCMD is AWOL. Use chicken bits to propagate
> +		 * the value from DPLLBMD to either pipe B or C.
> +		 */
> +		intel_de_write(dev_priv, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe));
> +		intel_de_write(dev_priv, DPLL_MD(PIPE_B),
> +			       pipe_config->dpll_hw_state.dpll_md);
> +		intel_de_write(dev_priv, CBR4_VLV, 0);
> +		dev_priv->chv_dpll_md[pipe] = pipe_config->dpll_hw_state.dpll_md;
> +
> +		/*
> +		 * DPLLB VGA mode also seems to cause problems.
> +		 * We should always have it disabled.
> +		 */
> +		drm_WARN_ON(&dev_priv->drm,
> +			    (intel_de_read(dev_priv, DPLL(PIPE_B)) &
> +			     DPLL_VGA_MODE_DIS) == 0);
> +	} else {
> +		intel_de_write(dev_priv, DPLL_MD(pipe),
> +			       pipe_config->dpll_hw_state.dpll_md);
> +		intel_de_posting_read(dev_priv, DPLL_MD(pipe));
> +	}
> +}
> +
> +void vlv_prepare_pll(struct intel_crtc *crtc,
> +		     const struct intel_crtc_state *pipe_config)
> +{
> +	struct drm_device *dev = crtc->base.dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	enum pipe pipe = crtc->pipe;
> +	u32 mdiv;
> +	u32 bestn, bestm1, bestm2, bestp1, bestp2;
> +	u32 coreclk, reg_val;
> +
> +	/* Enable Refclk */
> +	intel_de_write(dev_priv, DPLL(pipe),
> +		       pipe_config->dpll_hw_state.dpll & ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV));
> +
> +	/* No need to actually set up the DPLL with DSI */
> +	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
> +		return;
> +
> +	vlv_dpio_get(dev_priv);
> +
> +	bestn = pipe_config->dpll.n;
> +	bestm1 = pipe_config->dpll.m1;
> +	bestm2 = pipe_config->dpll.m2;
> +	bestp1 = pipe_config->dpll.p1;
> +	bestp2 = pipe_config->dpll.p2;
> +
> +	/* See eDP HDMI DPIO driver vbios notes doc */
> +
> +	/* PLL B needs special handling */
> +	if (pipe == PIPE_B)
> +		vlv_pllb_recal_opamp(dev_priv, pipe);
> +
> +	/* Set up Tx target for periodic Rcomp update */
> +	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9_BCAST, 0x0100000f);
> +
> +	/* Disable target IRef on PLL */
> +	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW8(pipe));
> +	reg_val &= 0x00ffffff;
> +	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW8(pipe), reg_val);
> +
> +	/* Disable fast lock */
> +	vlv_dpio_write(dev_priv, pipe, VLV_CMN_DW0, 0x610);
> +
> +	/* Set idtafcrecal before PLL is enabled */
> +	mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
> +	mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT));
> +	mdiv |= ((bestn << DPIO_N_SHIFT));
> +	mdiv |= (1 << DPIO_K_SHIFT);
> +
> +	/*
> +	 * Post divider depends on pixel clock rate, DAC vs digital (and LVDS,
> +	 * but we don't support that).
> +	 * Note: don't use the DAC post divider as it seems unstable.
> +	 */
> +	mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT);
> +	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
> +
> +	mdiv |= DPIO_ENABLE_CALIBRATION;
> +	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
> +
> +	/* Set HBR and RBR LPF coefficients */
> +	if (pipe_config->port_clock == 162000 ||
> +	    intel_crtc_has_type(pipe_config, INTEL_OUTPUT_ANALOG) ||
> +	    intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI))
> +		vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
> +				 0x009f0003);
> +	else
> +		vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
> +				 0x00d0000f);
> +
> +	if (intel_crtc_has_dp_encoder(pipe_config)) {
> +		/* Use SSC source */
> +		if (pipe == PIPE_A)
> +			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
> +					 0x0df40000);
> +		else
> +			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
> +					 0x0df70000);
> +	} else { /* HDMI or VGA */
> +		/* Use bend source */
> +		if (pipe == PIPE_A)
> +			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
> +					 0x0df70000);
> +		else
> +			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
> +					 0x0df40000);
> +	}
> +
> +	coreclk = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW7(pipe));
> +	coreclk = (coreclk & 0x0000ff00) | 0x01c00000;
> +	if (intel_crtc_has_dp_encoder(pipe_config))
> +		coreclk |= 0x01000000;
> +	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk);
> +
> +	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW11(pipe), 0x87871000);
> +
> +	vlv_dpio_put(dev_priv);
> +}
> +
> +void chv_prepare_pll(struct intel_crtc *crtc,
> +		     const struct intel_crtc_state *pipe_config)
> +{
> +	struct drm_device *dev = crtc->base.dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	enum pipe pipe = crtc->pipe;
> +	enum dpio_channel port = vlv_pipe_to_channel(pipe);
> +	u32 loopfilter, tribuf_calcntr;
> +	u32 bestn, bestm1, bestm2, bestp1, bestp2, bestm2_frac;
> +	u32 dpio_val;
> +	int vco;
> +
> +	/* Enable Refclk and SSC */
> +	intel_de_write(dev_priv, DPLL(pipe),
> +		       pipe_config->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE);
> +
> +	/* No need to actually set up the DPLL with DSI */
> +	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
> +		return;
> +
> +	bestn = pipe_config->dpll.n;
> +	bestm2_frac = pipe_config->dpll.m2 & 0x3fffff;
> +	bestm1 = pipe_config->dpll.m1;
> +	bestm2 = pipe_config->dpll.m2 >> 22;
> +	bestp1 = pipe_config->dpll.p1;
> +	bestp2 = pipe_config->dpll.p2;
> +	vco = pipe_config->dpll.vco;
> +	dpio_val = 0;
> +	loopfilter = 0;
> +
> +	vlv_dpio_get(dev_priv);
> +
> +	/* p1 and p2 divider */
> +	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW13(port),
> +			5 << DPIO_CHV_S1_DIV_SHIFT |
> +			bestp1 << DPIO_CHV_P1_DIV_SHIFT |
> +			bestp2 << DPIO_CHV_P2_DIV_SHIFT |
> +			1 << DPIO_CHV_K_DIV_SHIFT);
> +
> +	/* Feedback post-divider - m2 */
> +	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW0(port), bestm2);
> +
> +	/* Feedback refclk divider - n and m1 */
> +	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW1(port),
> +			DPIO_CHV_M1_DIV_BY_2 |
> +			1 << DPIO_CHV_N_DIV_SHIFT);
> +
> +	/* M2 fraction division */
> +	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW2(port), bestm2_frac);
> +
> +	/* M2 fraction division enable */
> +	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
> +	dpio_val &= ~(DPIO_CHV_FEEDFWD_GAIN_MASK | DPIO_CHV_FRAC_DIV_EN);
> +	dpio_val |= (2 << DPIO_CHV_FEEDFWD_GAIN_SHIFT);
> +	if (bestm2_frac)
> +		dpio_val |= DPIO_CHV_FRAC_DIV_EN;
> +	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW3(port), dpio_val);
> +
> +	/* Program digital lock detect threshold */
> +	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW9(port));
> +	dpio_val &= ~(DPIO_CHV_INT_LOCK_THRESHOLD_MASK |
> +					DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE);
> +	dpio_val |= (0x5 << DPIO_CHV_INT_LOCK_THRESHOLD_SHIFT);
> +	if (!bestm2_frac)
> +		dpio_val |= DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE;
> +	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW9(port), dpio_val);
> +
> +	/* Loop filter */
> +	if (vco == 5400000) {
> +		loopfilter |= (0x3 << DPIO_CHV_PROP_COEFF_SHIFT);
> +		loopfilter |= (0x8 << DPIO_CHV_INT_COEFF_SHIFT);
> +		loopfilter |= (0x1 << DPIO_CHV_GAIN_CTRL_SHIFT);
> +		tribuf_calcntr = 0x9;
> +	} else if (vco <= 6200000) {
> +		loopfilter |= (0x5 << DPIO_CHV_PROP_COEFF_SHIFT);
> +		loopfilter |= (0xB << DPIO_CHV_INT_COEFF_SHIFT);
> +		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
> +		tribuf_calcntr = 0x9;
> +	} else if (vco <= 6480000) {
> +		loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
> +		loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
> +		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
> +		tribuf_calcntr = 0x8;
> +	} else {
> +		/* Not supported. Apply the same limits as in the max case */
> +		loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
> +		loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
> +		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
> +		tribuf_calcntr = 0;
> +	}
> +	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW6(port), loopfilter);
> +
> +	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW8(port));
> +	dpio_val &= ~DPIO_CHV_TDC_TARGET_CNT_MASK;
> +	dpio_val |= (tribuf_calcntr << DPIO_CHV_TDC_TARGET_CNT_SHIFT);
> +	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW8(port), dpio_val);
> +
> +	/* AFC Recal */
> +	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port),
> +			vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)) |
> +			DPIO_AFC_RECAL);
> +
> +	vlv_dpio_put(dev_priv);
> +}
> +
> +/**
> + * vlv_force_pll_on - forcibly enable just the PLL
> + * @dev_priv: i915 private structure
> + * @pipe: pipe PLL to enable
> + * @dpll: PLL configuration
> + *
> + * Enable the PLL for @pipe using the supplied @dpll config. To be used
> + * in cases where we need the PLL enabled even when @pipe is not going to
> + * be enabled.
> + */
> +int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
> +		     const struct dpll *dpll)
> +{
> +	struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
> +	struct intel_crtc_state *pipe_config;
> +
> +	pipe_config = intel_crtc_state_alloc(crtc);
> +	if (!pipe_config)
> +		return -ENOMEM;
> +
> +	pipe_config->cpu_transcoder = (enum transcoder)pipe;
> +	pipe_config->pixel_multiplier = 1;
> +	pipe_config->dpll = *dpll;
> +
> +	if (IS_CHERRYVIEW(dev_priv)) {
> +		chv_compute_dpll(crtc, pipe_config);
> +		chv_prepare_pll(crtc, pipe_config);
> +		chv_enable_pll(crtc, pipe_config);
> +	} else {
> +		vlv_compute_dpll(crtc, pipe_config);
> +		vlv_prepare_pll(crtc, pipe_config);
> +		vlv_enable_pll(crtc, pipe_config);
> +	}
> +
> +	kfree(pipe_config);
> +
> +	return 0;
> +}
> +
> +void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
> +{
> +	u32 val;
> +
> +	/* Make sure the pipe isn't still relying on us */
> +	assert_pipe_disabled(dev_priv, (enum transcoder)pipe);
> +
> +	val = DPLL_INTEGRATED_REF_CLK_VLV |
> +		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
> +	if (pipe != PIPE_A)
> +		val |= DPLL_INTEGRATED_CRI_CLK_VLV;
> +
> +	intel_de_write(dev_priv, DPLL(pipe), val);
> +	intel_de_posting_read(dev_priv, DPLL(pipe));
> +}
> +
> +void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
> +{
> +	enum dpio_channel port = vlv_pipe_to_channel(pipe);
> +	u32 val;
> +
> +	/* Make sure the pipe isn't still relying on us */
> +	assert_pipe_disabled(dev_priv, (enum transcoder)pipe);
> +
> +	val = DPLL_SSC_REF_CLK_CHV |
> +		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
> +	if (pipe != PIPE_A)
> +		val |= DPLL_INTEGRATED_CRI_CLK_VLV;
> +
> +	intel_de_write(dev_priv, DPLL(pipe), val);
> +	intel_de_posting_read(dev_priv, DPLL(pipe));
> +
> +	vlv_dpio_get(dev_priv);
> +
> +	/* Disable 10bit clock to display controller */
> +	val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
> +	val &= ~DPIO_DCLKP_EN;
> +	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), val);
> +
> +	vlv_dpio_put(dev_priv);
> +}
> +
> +void i9xx_disable_pll(const struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	enum pipe pipe = crtc->pipe;
> +
> +	/* Don't disable pipe or pipe PLLs if needed */
> +	if (IS_I830(dev_priv))
> +		return;
> +
> +	/* Make sure the pipe isn't still relying on us */
> +	assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder);
> +
> +	intel_de_write(dev_priv, DPLL(pipe), DPLL_VGA_MODE_DIS);
> +	intel_de_posting_read(dev_priv, DPLL(pipe));
> +}
> +
> +
> +/**
> + * vlv_force_pll_off - forcibly disable just the PLL
> + * @dev_priv: i915 private structure
> + * @pipe: pipe PLL to disable
> + *
> + * Disable the PLL for @pipe. To be used in cases where we need
> + * the PLL enabled even when @pipe is not going to be enabled.
> + */
> +void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe)
> +{
> +	if (IS_CHERRYVIEW(dev_priv))
> +		chv_disable_pll(dev_priv, pipe);
> +	else
> +		vlv_disable_pll(dev_priv, pipe);
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_dpll.h b/drivers/gpu/drm/i915/display/intel_dpll.h
> index caf4615092e1..7ff4b0d29ed1 100644
> --- a/drivers/gpu/drm/i915/display/intel_dpll.h
> +++ b/drivers/gpu/drm/i915/display/intel_dpll.h
> @@ -10,6 +10,7 @@ struct dpll;
>  struct drm_i915_private;
>  struct intel_crtc;
>  struct intel_crtc_state;
> +enum pipe;
>  
>  void intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv);
>  int vlv_calc_dpll_params(int refclk, struct dpll *clock);
> @@ -20,4 +21,21 @@ void vlv_compute_dpll(struct intel_crtc *crtc,
>  void chv_compute_dpll(struct intel_crtc *crtc,
>  		      struct intel_crtc_state *pipe_config);
>  
> +int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
> +		     const struct dpll *dpll);
> +void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe);
> +void i9xx_enable_pll(struct intel_crtc *crtc,
> +		     const struct intel_crtc_state *crtc_state);
> +void vlv_enable_pll(struct intel_crtc *crtc,
> +		    const struct intel_crtc_state *pipe_config);
> +void chv_enable_pll(struct intel_crtc *crtc,
> +		    const struct intel_crtc_state *pipe_config);
> +void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe);
> +void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe);
> +void i9xx_disable_pll(const struct intel_crtc_state *crtc_state);
> +void vlv_prepare_pll(struct intel_crtc *crtc,
> +		     const struct intel_crtc_state *pipe_config);
> +void chv_prepare_pll(struct intel_crtc *crtc,
> +		     const struct intel_crtc_state *pipe_config);
> +
>  #endif
> diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c
> index 58eff6289d12..0a9b2abf290e 100644
> --- a/drivers/gpu/drm/i915/display/intel_pps.c
> +++ b/drivers/gpu/drm/i915/display/intel_pps.c
> @@ -6,6 +6,7 @@
>  #include "i915_drv.h"
>  #include "intel_display_types.h"
>  #include "intel_dp.h"
> +#include "intel_dpll.h"
>  #include "intel_pps.h"
>  
>  static void vlv_steal_power_sequencer(struct drm_i915_private *dev_priv,
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 7398927e1627..8abd49cf9c2b 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -109,10 +109,6 @@  static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state);
 static void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state);
 static void hsw_set_pipeconf(const struct intel_crtc_state *crtc_state);
 static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state);
-static void vlv_prepare_pll(struct intel_crtc *crtc,
-			    const struct intel_crtc_state *pipe_config);
-static void chv_prepare_pll(struct intel_crtc *crtc,
-			    const struct intel_crtc_state *pipe_config);
 static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state);
 static void intel_modeset_setup_hw_state(struct drm_device *dev,
 					 struct drm_modeset_acquire_ctx *ctx);
@@ -565,224 +561,6 @@  static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
 	assert_pch_hdmi_disabled(dev_priv, pipe, PORT_D, PCH_HDMID);
 }
 
-static void _vlv_enable_pll(struct intel_crtc *crtc,
-			    const struct intel_crtc_state *pipe_config)
-{
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	enum pipe pipe = crtc->pipe;
-
-	intel_de_write(dev_priv, DPLL(pipe), pipe_config->dpll_hw_state.dpll);
-	intel_de_posting_read(dev_priv, DPLL(pipe));
-	udelay(150);
-
-	if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
-		drm_err(&dev_priv->drm, "DPLL %d failed to lock\n", pipe);
-}
-
-static void vlv_enable_pll(struct intel_crtc *crtc,
-			   const struct intel_crtc_state *pipe_config)
-{
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	enum pipe pipe = crtc->pipe;
-
-	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder);
-
-	/* PLL is protected by panel, make sure we can write it */
-	assert_panel_unlocked(dev_priv, pipe);
-
-	if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
-		_vlv_enable_pll(crtc, pipe_config);
-
-	intel_de_write(dev_priv, DPLL_MD(pipe),
-		       pipe_config->dpll_hw_state.dpll_md);
-	intel_de_posting_read(dev_priv, DPLL_MD(pipe));
-}
-
-
-static void _chv_enable_pll(struct intel_crtc *crtc,
-			    const struct intel_crtc_state *pipe_config)
-{
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	enum pipe pipe = crtc->pipe;
-	enum dpio_channel port = vlv_pipe_to_channel(pipe);
-	u32 tmp;
-
-	vlv_dpio_get(dev_priv);
-
-	/* Enable back the 10bit clock to display controller */
-	tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
-	tmp |= DPIO_DCLKP_EN;
-	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), tmp);
-
-	vlv_dpio_put(dev_priv);
-
-	/*
-	 * Need to wait > 100ns between dclkp clock enable bit and PLL enable.
-	 */
-	udelay(1);
-
-	/* Enable PLL */
-	intel_de_write(dev_priv, DPLL(pipe), pipe_config->dpll_hw_state.dpll);
-
-	/* Check PLL is locked */
-	if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
-		drm_err(&dev_priv->drm, "PLL %d failed to lock\n", pipe);
-}
-
-static void chv_enable_pll(struct intel_crtc *crtc,
-			   const struct intel_crtc_state *pipe_config)
-{
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	enum pipe pipe = crtc->pipe;
-
-	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder);
-
-	/* PLL is protected by panel, make sure we can write it */
-	assert_panel_unlocked(dev_priv, pipe);
-
-	if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
-		_chv_enable_pll(crtc, pipe_config);
-
-	if (pipe != PIPE_A) {
-		/*
-		 * WaPixelRepeatModeFixForC0:chv
-		 *
-		 * DPLLCMD is AWOL. Use chicken bits to propagate
-		 * the value from DPLLBMD to either pipe B or C.
-		 */
-		intel_de_write(dev_priv, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe));
-		intel_de_write(dev_priv, DPLL_MD(PIPE_B),
-			       pipe_config->dpll_hw_state.dpll_md);
-		intel_de_write(dev_priv, CBR4_VLV, 0);
-		dev_priv->chv_dpll_md[pipe] = pipe_config->dpll_hw_state.dpll_md;
-
-		/*
-		 * DPLLB VGA mode also seems to cause problems.
-		 * We should always have it disabled.
-		 */
-		drm_WARN_ON(&dev_priv->drm,
-			    (intel_de_read(dev_priv, DPLL(PIPE_B)) &
-			     DPLL_VGA_MODE_DIS) == 0);
-	} else {
-		intel_de_write(dev_priv, DPLL_MD(pipe),
-			       pipe_config->dpll_hw_state.dpll_md);
-		intel_de_posting_read(dev_priv, DPLL_MD(pipe));
-	}
-}
-
-static bool i9xx_has_pps(struct drm_i915_private *dev_priv)
-{
-	if (IS_I830(dev_priv))
-		return false;
-
-	return IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv);
-}
-
-static void i9xx_enable_pll(struct intel_crtc *crtc,
-			    const struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	i915_reg_t reg = DPLL(crtc->pipe);
-	u32 dpll = crtc_state->dpll_hw_state.dpll;
-	int i;
-
-	assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder);
-
-	/* PLL is protected by panel, make sure we can write it */
-	if (i9xx_has_pps(dev_priv))
-		assert_panel_unlocked(dev_priv, crtc->pipe);
-
-	/*
-	 * Apparently we need to have VGA mode enabled prior to changing
-	 * the P1/P2 dividers. Otherwise the DPLL will keep using the old
-	 * dividers, even though the register value does change.
-	 */
-	intel_de_write(dev_priv, reg, dpll & ~DPLL_VGA_MODE_DIS);
-	intel_de_write(dev_priv, reg, dpll);
-
-	/* Wait for the clocks to stabilize. */
-	intel_de_posting_read(dev_priv, reg);
-	udelay(150);
-
-	if (INTEL_GEN(dev_priv) >= 4) {
-		intel_de_write(dev_priv, DPLL_MD(crtc->pipe),
-			       crtc_state->dpll_hw_state.dpll_md);
-	} else {
-		/* The pixel multiplier can only be updated once the
-		 * DPLL is enabled and the clocks are stable.
-		 *
-		 * So write it again.
-		 */
-		intel_de_write(dev_priv, reg, dpll);
-	}
-
-	/* We do this three times for luck */
-	for (i = 0; i < 3; i++) {
-		intel_de_write(dev_priv, reg, dpll);
-		intel_de_posting_read(dev_priv, reg);
-		udelay(150); /* wait for warmup */
-	}
-}
-
-static void i9xx_disable_pll(const struct intel_crtc_state *crtc_state)
-{
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	enum pipe pipe = crtc->pipe;
-
-	/* Don't disable pipe or pipe PLLs if needed */
-	if (IS_I830(dev_priv))
-		return;
-
-	/* Make sure the pipe isn't still relying on us */
-	assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder);
-
-	intel_de_write(dev_priv, DPLL(pipe), DPLL_VGA_MODE_DIS);
-	intel_de_posting_read(dev_priv, DPLL(pipe));
-}
-
-static void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
-{
-	u32 val;
-
-	/* Make sure the pipe isn't still relying on us */
-	assert_pipe_disabled(dev_priv, (enum transcoder)pipe);
-
-	val = DPLL_INTEGRATED_REF_CLK_VLV |
-		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
-	if (pipe != PIPE_A)
-		val |= DPLL_INTEGRATED_CRI_CLK_VLV;
-
-	intel_de_write(dev_priv, DPLL(pipe), val);
-	intel_de_posting_read(dev_priv, DPLL(pipe));
-}
-
-static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
-{
-	enum dpio_channel port = vlv_pipe_to_channel(pipe);
-	u32 val;
-
-	/* Make sure the pipe isn't still relying on us */
-	assert_pipe_disabled(dev_priv, (enum transcoder)pipe);
-
-	val = DPLL_SSC_REF_CLK_CHV |
-		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
-	if (pipe != PIPE_A)
-		val |= DPLL_INTEGRATED_CRI_CLK_VLV;
-
-	intel_de_write(dev_priv, DPLL(pipe), val);
-	intel_de_posting_read(dev_priv, DPLL(pipe));
-
-	vlv_dpio_get(dev_priv);
-
-	/* Disable 10bit clock to display controller */
-	val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
-	val &= ~DPIO_DCLKP_EN;
-	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), val);
-
-	vlv_dpio_put(dev_priv);
-}
-
 void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
 			 struct intel_digital_port *dig_port,
 			 unsigned int expected_mask)
@@ -5709,35 +5487,6 @@  static void intel_panel_sanitize_ssc(struct drm_i915_private *dev_priv)
 	}
 }
 
-static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, enum pipe
-		pipe)
-{
-	u32 reg_val;
-
-	/*
-	 * PLLB opamp always calibrates to max value of 0x3f, force enable it
-	 * and set it to a reasonable value instead.
-	 */
-	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
-	reg_val &= 0xffffff00;
-	reg_val |= 0x00000030;
-	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
-
-	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
-	reg_val &= 0x00ffffff;
-	reg_val |= 0x8c000000;
-	vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
-
-	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
-	reg_val &= 0xffffff00;
-	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
-
-	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
-	reg_val &= 0x00ffffff;
-	reg_val |= 0xb0000000;
-	vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
-}
-
 static void intel_pch_transcoder_set_m_n(const struct intel_crtc_state *crtc_state,
 					 const struct intel_link_m_n *m_n)
 {
@@ -5833,267 +5582,6 @@  void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state, enum link_m_n_s
 		intel_cpu_transcoder_set_m_n(crtc_state, dp_m_n, dp_m2_n2);
 }
 
-static void vlv_prepare_pll(struct intel_crtc *crtc,
-			    const struct intel_crtc_state *pipe_config)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	enum pipe pipe = crtc->pipe;
-	u32 mdiv;
-	u32 bestn, bestm1, bestm2, bestp1, bestp2;
-	u32 coreclk, reg_val;
-
-	/* Enable Refclk */
-	intel_de_write(dev_priv, DPLL(pipe),
-		       pipe_config->dpll_hw_state.dpll & ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV));
-
-	/* No need to actually set up the DPLL with DSI */
-	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
-		return;
-
-	vlv_dpio_get(dev_priv);
-
-	bestn = pipe_config->dpll.n;
-	bestm1 = pipe_config->dpll.m1;
-	bestm2 = pipe_config->dpll.m2;
-	bestp1 = pipe_config->dpll.p1;
-	bestp2 = pipe_config->dpll.p2;
-
-	/* See eDP HDMI DPIO driver vbios notes doc */
-
-	/* PLL B needs special handling */
-	if (pipe == PIPE_B)
-		vlv_pllb_recal_opamp(dev_priv, pipe);
-
-	/* Set up Tx target for periodic Rcomp update */
-	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9_BCAST, 0x0100000f);
-
-	/* Disable target IRef on PLL */
-	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW8(pipe));
-	reg_val &= 0x00ffffff;
-	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW8(pipe), reg_val);
-
-	/* Disable fast lock */
-	vlv_dpio_write(dev_priv, pipe, VLV_CMN_DW0, 0x610);
-
-	/* Set idtafcrecal before PLL is enabled */
-	mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
-	mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT));
-	mdiv |= ((bestn << DPIO_N_SHIFT));
-	mdiv |= (1 << DPIO_K_SHIFT);
-
-	/*
-	 * Post divider depends on pixel clock rate, DAC vs digital (and LVDS,
-	 * but we don't support that).
-	 * Note: don't use the DAC post divider as it seems unstable.
-	 */
-	mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT);
-	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
-
-	mdiv |= DPIO_ENABLE_CALIBRATION;
-	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
-
-	/* Set HBR and RBR LPF coefficients */
-	if (pipe_config->port_clock == 162000 ||
-	    intel_crtc_has_type(pipe_config, INTEL_OUTPUT_ANALOG) ||
-	    intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI))
-		vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
-				 0x009f0003);
-	else
-		vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
-				 0x00d0000f);
-
-	if (intel_crtc_has_dp_encoder(pipe_config)) {
-		/* Use SSC source */
-		if (pipe == PIPE_A)
-			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
-					 0x0df40000);
-		else
-			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
-					 0x0df70000);
-	} else { /* HDMI or VGA */
-		/* Use bend source */
-		if (pipe == PIPE_A)
-			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
-					 0x0df70000);
-		else
-			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
-					 0x0df40000);
-	}
-
-	coreclk = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW7(pipe));
-	coreclk = (coreclk & 0x0000ff00) | 0x01c00000;
-	if (intel_crtc_has_dp_encoder(pipe_config))
-		coreclk |= 0x01000000;
-	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk);
-
-	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW11(pipe), 0x87871000);
-
-	vlv_dpio_put(dev_priv);
-}
-
-static void chv_prepare_pll(struct intel_crtc *crtc,
-			    const struct intel_crtc_state *pipe_config)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	enum pipe pipe = crtc->pipe;
-	enum dpio_channel port = vlv_pipe_to_channel(pipe);
-	u32 loopfilter, tribuf_calcntr;
-	u32 bestn, bestm1, bestm2, bestp1, bestp2, bestm2_frac;
-	u32 dpio_val;
-	int vco;
-
-	/* Enable Refclk and SSC */
-	intel_de_write(dev_priv, DPLL(pipe),
-		       pipe_config->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE);
-
-	/* No need to actually set up the DPLL with DSI */
-	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
-		return;
-
-	bestn = pipe_config->dpll.n;
-	bestm2_frac = pipe_config->dpll.m2 & 0x3fffff;
-	bestm1 = pipe_config->dpll.m1;
-	bestm2 = pipe_config->dpll.m2 >> 22;
-	bestp1 = pipe_config->dpll.p1;
-	bestp2 = pipe_config->dpll.p2;
-	vco = pipe_config->dpll.vco;
-	dpio_val = 0;
-	loopfilter = 0;
-
-	vlv_dpio_get(dev_priv);
-
-	/* p1 and p2 divider */
-	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW13(port),
-			5 << DPIO_CHV_S1_DIV_SHIFT |
-			bestp1 << DPIO_CHV_P1_DIV_SHIFT |
-			bestp2 << DPIO_CHV_P2_DIV_SHIFT |
-			1 << DPIO_CHV_K_DIV_SHIFT);
-
-	/* Feedback post-divider - m2 */
-	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW0(port), bestm2);
-
-	/* Feedback refclk divider - n and m1 */
-	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW1(port),
-			DPIO_CHV_M1_DIV_BY_2 |
-			1 << DPIO_CHV_N_DIV_SHIFT);
-
-	/* M2 fraction division */
-	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW2(port), bestm2_frac);
-
-	/* M2 fraction division enable */
-	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
-	dpio_val &= ~(DPIO_CHV_FEEDFWD_GAIN_MASK | DPIO_CHV_FRAC_DIV_EN);
-	dpio_val |= (2 << DPIO_CHV_FEEDFWD_GAIN_SHIFT);
-	if (bestm2_frac)
-		dpio_val |= DPIO_CHV_FRAC_DIV_EN;
-	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW3(port), dpio_val);
-
-	/* Program digital lock detect threshold */
-	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW9(port));
-	dpio_val &= ~(DPIO_CHV_INT_LOCK_THRESHOLD_MASK |
-					DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE);
-	dpio_val |= (0x5 << DPIO_CHV_INT_LOCK_THRESHOLD_SHIFT);
-	if (!bestm2_frac)
-		dpio_val |= DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE;
-	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW9(port), dpio_val);
-
-	/* Loop filter */
-	if (vco == 5400000) {
-		loopfilter |= (0x3 << DPIO_CHV_PROP_COEFF_SHIFT);
-		loopfilter |= (0x8 << DPIO_CHV_INT_COEFF_SHIFT);
-		loopfilter |= (0x1 << DPIO_CHV_GAIN_CTRL_SHIFT);
-		tribuf_calcntr = 0x9;
-	} else if (vco <= 6200000) {
-		loopfilter |= (0x5 << DPIO_CHV_PROP_COEFF_SHIFT);
-		loopfilter |= (0xB << DPIO_CHV_INT_COEFF_SHIFT);
-		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
-		tribuf_calcntr = 0x9;
-	} else if (vco <= 6480000) {
-		loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
-		loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
-		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
-		tribuf_calcntr = 0x8;
-	} else {
-		/* Not supported. Apply the same limits as in the max case */
-		loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
-		loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
-		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
-		tribuf_calcntr = 0;
-	}
-	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW6(port), loopfilter);
-
-	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW8(port));
-	dpio_val &= ~DPIO_CHV_TDC_TARGET_CNT_MASK;
-	dpio_val |= (tribuf_calcntr << DPIO_CHV_TDC_TARGET_CNT_SHIFT);
-	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW8(port), dpio_val);
-
-	/* AFC Recal */
-	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port),
-			vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)) |
-			DPIO_AFC_RECAL);
-
-	vlv_dpio_put(dev_priv);
-}
-
-/**
- * vlv_force_pll_on - forcibly enable just the PLL
- * @dev_priv: i915 private structure
- * @pipe: pipe PLL to enable
- * @dpll: PLL configuration
- *
- * Enable the PLL for @pipe using the supplied @dpll config. To be used
- * in cases where we need the PLL enabled even when @pipe is not going to
- * be enabled.
- */
-int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
-		     const struct dpll *dpll)
-{
-	struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
-	struct intel_crtc_state *pipe_config;
-
-	pipe_config = intel_crtc_state_alloc(crtc);
-	if (!pipe_config)
-		return -ENOMEM;
-
-	pipe_config->cpu_transcoder = (enum transcoder)pipe;
-	pipe_config->pixel_multiplier = 1;
-	pipe_config->dpll = *dpll;
-
-	if (IS_CHERRYVIEW(dev_priv)) {
-		chv_compute_dpll(crtc, pipe_config);
-		chv_prepare_pll(crtc, pipe_config);
-		chv_enable_pll(crtc, pipe_config);
-	} else {
-		vlv_compute_dpll(crtc, pipe_config);
-		vlv_prepare_pll(crtc, pipe_config);
-		vlv_enable_pll(crtc, pipe_config);
-	}
-
-	kfree(pipe_config);
-
-	return 0;
-}
-
-/**
- * vlv_force_pll_off - forcibly disable just the PLL
- * @dev_priv: i915 private structure
- * @pipe: pipe PLL to disable
- *
- * Disable the PLL for @pipe. To be used in cases where we need
- * the PLL enabled even when @pipe is not going to be enabled.
- */
-void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe)
-{
-	if (IS_CHERRYVIEW(dev_priv))
-		chv_disable_pll(dev_priv, pipe);
-	else
-		vlv_disable_pll(dev_priv, pipe);
-}
-
-
-
 static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index f4214e161a9d..1cc1073a8f64 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -586,9 +586,6 @@  void intel_cleanup_plane_fb(struct drm_plane *plane,
 void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
 				    enum pipe pipe);
 
-int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
-		     const struct dpll *dpll);
-void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe);
 int lpt_get_iclkip(struct drm_i915_private *dev_priv);
 bool intel_fuzzy_clock_check(int clock1, int clock2);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index ec94ebdaf7b8..edb038cc7cd1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -50,6 +50,7 @@ 
 #include "intel_dp.h"
 #include "intel_dp_link_training.h"
 #include "intel_dp_mst.h"
+#include "intel_dpll.h"
 #include "intel_dpio_phy.h"
 #include "intel_fifo_underrun.h"
 #include "intel_hdcp.h"
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c
index 7ba7f315aaee..166e9a3a8c09 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -3,11 +3,13 @@ 
  * Copyright © 2020 Intel Corporation
  */
 #include <linux/kernel.h>
+#include "intel_crtc.h"
 #include "intel_display_types.h"
 #include "intel_display.h"
 #include "intel_dpll.h"
 #include "intel_lvds.h"
 #include "intel_panel.h"
+#include "intel_sideband.h"
 
 struct intel_limit {
 	struct {
@@ -1361,3 +1363,510 @@  intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv)
 	else
 		dev_priv->display.crtc_compute_clock = i8xx_crtc_compute_clock;
 }
+
+static bool i9xx_has_pps(struct drm_i915_private *dev_priv)
+{
+	if (IS_I830(dev_priv))
+		return false;
+
+	return IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv);
+}
+
+void i9xx_enable_pll(struct intel_crtc *crtc,
+		     const struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	i915_reg_t reg = DPLL(crtc->pipe);
+	u32 dpll = crtc_state->dpll_hw_state.dpll;
+	int i;
+
+	assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder);
+
+	/* PLL is protected by panel, make sure we can write it */
+	if (i9xx_has_pps(dev_priv))
+		assert_panel_unlocked(dev_priv, crtc->pipe);
+
+	/*
+	 * Apparently we need to have VGA mode enabled prior to changing
+	 * the P1/P2 dividers. Otherwise the DPLL will keep using the old
+	 * dividers, even though the register value does change.
+	 */
+	intel_de_write(dev_priv, reg, dpll & ~DPLL_VGA_MODE_DIS);
+	intel_de_write(dev_priv, reg, dpll);
+
+	/* Wait for the clocks to stabilize. */
+	intel_de_posting_read(dev_priv, reg);
+	udelay(150);
+
+	if (INTEL_GEN(dev_priv) >= 4) {
+		intel_de_write(dev_priv, DPLL_MD(crtc->pipe),
+			       crtc_state->dpll_hw_state.dpll_md);
+	} else {
+		/* The pixel multiplier can only be updated once the
+		 * DPLL is enabled and the clocks are stable.
+		 *
+		 * So write it again.
+		 */
+		intel_de_write(dev_priv, reg, dpll);
+	}
+
+	/* We do this three times for luck */
+	for (i = 0; i < 3; i++) {
+		intel_de_write(dev_priv, reg, dpll);
+		intel_de_posting_read(dev_priv, reg);
+		udelay(150); /* wait for warmup */
+	}
+}
+
+static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv,
+				 enum pipe pipe)
+{
+	u32 reg_val;
+
+	/*
+	 * PLLB opamp always calibrates to max value of 0x3f, force enable it
+	 * and set it to a reasonable value instead.
+	 */
+	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
+	reg_val &= 0xffffff00;
+	reg_val |= 0x00000030;
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
+
+	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
+	reg_val &= 0x00ffffff;
+	reg_val |= 0x8c000000;
+	vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
+
+	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW9(1));
+	reg_val &= 0xffffff00;
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9(1), reg_val);
+
+	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_REF_DW13);
+	reg_val &= 0x00ffffff;
+	reg_val |= 0xb0000000;
+	vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val);
+}
+
+static void _vlv_enable_pll(struct intel_crtc *crtc,
+			    const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+
+	intel_de_write(dev_priv, DPLL(pipe), pipe_config->dpll_hw_state.dpll);
+	intel_de_posting_read(dev_priv, DPLL(pipe));
+	udelay(150);
+
+	if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
+		drm_err(&dev_priv->drm, "DPLL %d failed to lock\n", pipe);
+}
+
+void vlv_enable_pll(struct intel_crtc *crtc,
+		    const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+
+	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder);
+
+	/* PLL is protected by panel, make sure we can write it */
+	assert_panel_unlocked(dev_priv, pipe);
+
+	if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
+		_vlv_enable_pll(crtc, pipe_config);
+
+	intel_de_write(dev_priv, DPLL_MD(pipe),
+		       pipe_config->dpll_hw_state.dpll_md);
+	intel_de_posting_read(dev_priv, DPLL_MD(pipe));
+}
+
+
+static void _chv_enable_pll(struct intel_crtc *crtc,
+			    const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+	enum dpio_channel port = vlv_pipe_to_channel(pipe);
+	u32 tmp;
+
+	vlv_dpio_get(dev_priv);
+
+	/* Enable back the 10bit clock to display controller */
+	tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
+	tmp |= DPIO_DCLKP_EN;
+	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), tmp);
+
+	vlv_dpio_put(dev_priv);
+
+	/*
+	 * Need to wait > 100ns between dclkp clock enable bit and PLL enable.
+	 */
+	udelay(1);
+
+	/* Enable PLL */
+	intel_de_write(dev_priv, DPLL(pipe), pipe_config->dpll_hw_state.dpll);
+
+	/* Check PLL is locked */
+	if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
+		drm_err(&dev_priv->drm, "PLL %d failed to lock\n", pipe);
+}
+
+void chv_enable_pll(struct intel_crtc *crtc,
+		    const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+
+	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder);
+
+	/* PLL is protected by panel, make sure we can write it */
+	assert_panel_unlocked(dev_priv, pipe);
+
+	if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE)
+		_chv_enable_pll(crtc, pipe_config);
+
+	if (pipe != PIPE_A) {
+		/*
+		 * WaPixelRepeatModeFixForC0:chv
+		 *
+		 * DPLLCMD is AWOL. Use chicken bits to propagate
+		 * the value from DPLLBMD to either pipe B or C.
+		 */
+		intel_de_write(dev_priv, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe));
+		intel_de_write(dev_priv, DPLL_MD(PIPE_B),
+			       pipe_config->dpll_hw_state.dpll_md);
+		intel_de_write(dev_priv, CBR4_VLV, 0);
+		dev_priv->chv_dpll_md[pipe] = pipe_config->dpll_hw_state.dpll_md;
+
+		/*
+		 * DPLLB VGA mode also seems to cause problems.
+		 * We should always have it disabled.
+		 */
+		drm_WARN_ON(&dev_priv->drm,
+			    (intel_de_read(dev_priv, DPLL(PIPE_B)) &
+			     DPLL_VGA_MODE_DIS) == 0);
+	} else {
+		intel_de_write(dev_priv, DPLL_MD(pipe),
+			       pipe_config->dpll_hw_state.dpll_md);
+		intel_de_posting_read(dev_priv, DPLL_MD(pipe));
+	}
+}
+
+void vlv_prepare_pll(struct intel_crtc *crtc,
+		     const struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	enum pipe pipe = crtc->pipe;
+	u32 mdiv;
+	u32 bestn, bestm1, bestm2, bestp1, bestp2;
+	u32 coreclk, reg_val;
+
+	/* Enable Refclk */
+	intel_de_write(dev_priv, DPLL(pipe),
+		       pipe_config->dpll_hw_state.dpll & ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV));
+
+	/* No need to actually set up the DPLL with DSI */
+	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
+		return;
+
+	vlv_dpio_get(dev_priv);
+
+	bestn = pipe_config->dpll.n;
+	bestm1 = pipe_config->dpll.m1;
+	bestm2 = pipe_config->dpll.m2;
+	bestp1 = pipe_config->dpll.p1;
+	bestp2 = pipe_config->dpll.p2;
+
+	/* See eDP HDMI DPIO driver vbios notes doc */
+
+	/* PLL B needs special handling */
+	if (pipe == PIPE_B)
+		vlv_pllb_recal_opamp(dev_priv, pipe);
+
+	/* Set up Tx target for periodic Rcomp update */
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW9_BCAST, 0x0100000f);
+
+	/* Disable target IRef on PLL */
+	reg_val = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW8(pipe));
+	reg_val &= 0x00ffffff;
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW8(pipe), reg_val);
+
+	/* Disable fast lock */
+	vlv_dpio_write(dev_priv, pipe, VLV_CMN_DW0, 0x610);
+
+	/* Set idtafcrecal before PLL is enabled */
+	mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
+	mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT));
+	mdiv |= ((bestn << DPIO_N_SHIFT));
+	mdiv |= (1 << DPIO_K_SHIFT);
+
+	/*
+	 * Post divider depends on pixel clock rate, DAC vs digital (and LVDS,
+	 * but we don't support that).
+	 * Note: don't use the DAC post divider as it seems unstable.
+	 */
+	mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT);
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
+
+	mdiv |= DPIO_ENABLE_CALIBRATION;
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv);
+
+	/* Set HBR and RBR LPF coefficients */
+	if (pipe_config->port_clock == 162000 ||
+	    intel_crtc_has_type(pipe_config, INTEL_OUTPUT_ANALOG) ||
+	    intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI))
+		vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
+				 0x009f0003);
+	else
+		vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
+				 0x00d0000f);
+
+	if (intel_crtc_has_dp_encoder(pipe_config)) {
+		/* Use SSC source */
+		if (pipe == PIPE_A)
+			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
+					 0x0df40000);
+		else
+			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
+					 0x0df70000);
+	} else { /* HDMI or VGA */
+		/* Use bend source */
+		if (pipe == PIPE_A)
+			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
+					 0x0df70000);
+		else
+			vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
+					 0x0df40000);
+	}
+
+	coreclk = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW7(pipe));
+	coreclk = (coreclk & 0x0000ff00) | 0x01c00000;
+	if (intel_crtc_has_dp_encoder(pipe_config))
+		coreclk |= 0x01000000;
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk);
+
+	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW11(pipe), 0x87871000);
+
+	vlv_dpio_put(dev_priv);
+}
+
+void chv_prepare_pll(struct intel_crtc *crtc,
+		     const struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	enum pipe pipe = crtc->pipe;
+	enum dpio_channel port = vlv_pipe_to_channel(pipe);
+	u32 loopfilter, tribuf_calcntr;
+	u32 bestn, bestm1, bestm2, bestp1, bestp2, bestm2_frac;
+	u32 dpio_val;
+	int vco;
+
+	/* Enable Refclk and SSC */
+	intel_de_write(dev_priv, DPLL(pipe),
+		       pipe_config->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE);
+
+	/* No need to actually set up the DPLL with DSI */
+	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
+		return;
+
+	bestn = pipe_config->dpll.n;
+	bestm2_frac = pipe_config->dpll.m2 & 0x3fffff;
+	bestm1 = pipe_config->dpll.m1;
+	bestm2 = pipe_config->dpll.m2 >> 22;
+	bestp1 = pipe_config->dpll.p1;
+	bestp2 = pipe_config->dpll.p2;
+	vco = pipe_config->dpll.vco;
+	dpio_val = 0;
+	loopfilter = 0;
+
+	vlv_dpio_get(dev_priv);
+
+	/* p1 and p2 divider */
+	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW13(port),
+			5 << DPIO_CHV_S1_DIV_SHIFT |
+			bestp1 << DPIO_CHV_P1_DIV_SHIFT |
+			bestp2 << DPIO_CHV_P2_DIV_SHIFT |
+			1 << DPIO_CHV_K_DIV_SHIFT);
+
+	/* Feedback post-divider - m2 */
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW0(port), bestm2);
+
+	/* Feedback refclk divider - n and m1 */
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW1(port),
+			DPIO_CHV_M1_DIV_BY_2 |
+			1 << DPIO_CHV_N_DIV_SHIFT);
+
+	/* M2 fraction division */
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW2(port), bestm2_frac);
+
+	/* M2 fraction division enable */
+	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
+	dpio_val &= ~(DPIO_CHV_FEEDFWD_GAIN_MASK | DPIO_CHV_FRAC_DIV_EN);
+	dpio_val |= (2 << DPIO_CHV_FEEDFWD_GAIN_SHIFT);
+	if (bestm2_frac)
+		dpio_val |= DPIO_CHV_FRAC_DIV_EN;
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW3(port), dpio_val);
+
+	/* Program digital lock detect threshold */
+	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW9(port));
+	dpio_val &= ~(DPIO_CHV_INT_LOCK_THRESHOLD_MASK |
+					DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE);
+	dpio_val |= (0x5 << DPIO_CHV_INT_LOCK_THRESHOLD_SHIFT);
+	if (!bestm2_frac)
+		dpio_val |= DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE;
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW9(port), dpio_val);
+
+	/* Loop filter */
+	if (vco == 5400000) {
+		loopfilter |= (0x3 << DPIO_CHV_PROP_COEFF_SHIFT);
+		loopfilter |= (0x8 << DPIO_CHV_INT_COEFF_SHIFT);
+		loopfilter |= (0x1 << DPIO_CHV_GAIN_CTRL_SHIFT);
+		tribuf_calcntr = 0x9;
+	} else if (vco <= 6200000) {
+		loopfilter |= (0x5 << DPIO_CHV_PROP_COEFF_SHIFT);
+		loopfilter |= (0xB << DPIO_CHV_INT_COEFF_SHIFT);
+		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
+		tribuf_calcntr = 0x9;
+	} else if (vco <= 6480000) {
+		loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
+		loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
+		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
+		tribuf_calcntr = 0x8;
+	} else {
+		/* Not supported. Apply the same limits as in the max case */
+		loopfilter |= (0x4 << DPIO_CHV_PROP_COEFF_SHIFT);
+		loopfilter |= (0x9 << DPIO_CHV_INT_COEFF_SHIFT);
+		loopfilter |= (0x3 << DPIO_CHV_GAIN_CTRL_SHIFT);
+		tribuf_calcntr = 0;
+	}
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW6(port), loopfilter);
+
+	dpio_val = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW8(port));
+	dpio_val &= ~DPIO_CHV_TDC_TARGET_CNT_MASK;
+	dpio_val |= (tribuf_calcntr << DPIO_CHV_TDC_TARGET_CNT_SHIFT);
+	vlv_dpio_write(dev_priv, pipe, CHV_PLL_DW8(port), dpio_val);
+
+	/* AFC Recal */
+	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port),
+			vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)) |
+			DPIO_AFC_RECAL);
+
+	vlv_dpio_put(dev_priv);
+}
+
+/**
+ * vlv_force_pll_on - forcibly enable just the PLL
+ * @dev_priv: i915 private structure
+ * @pipe: pipe PLL to enable
+ * @dpll: PLL configuration
+ *
+ * Enable the PLL for @pipe using the supplied @dpll config. To be used
+ * in cases where we need the PLL enabled even when @pipe is not going to
+ * be enabled.
+ */
+int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
+		     const struct dpll *dpll)
+{
+	struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
+	struct intel_crtc_state *pipe_config;
+
+	pipe_config = intel_crtc_state_alloc(crtc);
+	if (!pipe_config)
+		return -ENOMEM;
+
+	pipe_config->cpu_transcoder = (enum transcoder)pipe;
+	pipe_config->pixel_multiplier = 1;
+	pipe_config->dpll = *dpll;
+
+	if (IS_CHERRYVIEW(dev_priv)) {
+		chv_compute_dpll(crtc, pipe_config);
+		chv_prepare_pll(crtc, pipe_config);
+		chv_enable_pll(crtc, pipe_config);
+	} else {
+		vlv_compute_dpll(crtc, pipe_config);
+		vlv_prepare_pll(crtc, pipe_config);
+		vlv_enable_pll(crtc, pipe_config);
+	}
+
+	kfree(pipe_config);
+
+	return 0;
+}
+
+void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
+{
+	u32 val;
+
+	/* Make sure the pipe isn't still relying on us */
+	assert_pipe_disabled(dev_priv, (enum transcoder)pipe);
+
+	val = DPLL_INTEGRATED_REF_CLK_VLV |
+		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
+	if (pipe != PIPE_A)
+		val |= DPLL_INTEGRATED_CRI_CLK_VLV;
+
+	intel_de_write(dev_priv, DPLL(pipe), val);
+	intel_de_posting_read(dev_priv, DPLL(pipe));
+}
+
+void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
+{
+	enum dpio_channel port = vlv_pipe_to_channel(pipe);
+	u32 val;
+
+	/* Make sure the pipe isn't still relying on us */
+	assert_pipe_disabled(dev_priv, (enum transcoder)pipe);
+
+	val = DPLL_SSC_REF_CLK_CHV |
+		DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
+	if (pipe != PIPE_A)
+		val |= DPLL_INTEGRATED_CRI_CLK_VLV;
+
+	intel_de_write(dev_priv, DPLL(pipe), val);
+	intel_de_posting_read(dev_priv, DPLL(pipe));
+
+	vlv_dpio_get(dev_priv);
+
+	/* Disable 10bit clock to display controller */
+	val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
+	val &= ~DPIO_DCLKP_EN;
+	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), val);
+
+	vlv_dpio_put(dev_priv);
+}
+
+void i9xx_disable_pll(const struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+
+	/* Don't disable pipe or pipe PLLs if needed */
+	if (IS_I830(dev_priv))
+		return;
+
+	/* Make sure the pipe isn't still relying on us */
+	assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder);
+
+	intel_de_write(dev_priv, DPLL(pipe), DPLL_VGA_MODE_DIS);
+	intel_de_posting_read(dev_priv, DPLL(pipe));
+}
+
+
+/**
+ * vlv_force_pll_off - forcibly disable just the PLL
+ * @dev_priv: i915 private structure
+ * @pipe: pipe PLL to disable
+ *
+ * Disable the PLL for @pipe. To be used in cases where we need
+ * the PLL enabled even when @pipe is not going to be enabled.
+ */
+void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe)
+{
+	if (IS_CHERRYVIEW(dev_priv))
+		chv_disable_pll(dev_priv, pipe);
+	else
+		vlv_disable_pll(dev_priv, pipe);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.h b/drivers/gpu/drm/i915/display/intel_dpll.h
index caf4615092e1..7ff4b0d29ed1 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.h
+++ b/drivers/gpu/drm/i915/display/intel_dpll.h
@@ -10,6 +10,7 @@  struct dpll;
 struct drm_i915_private;
 struct intel_crtc;
 struct intel_crtc_state;
+enum pipe;
 
 void intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv);
 int vlv_calc_dpll_params(int refclk, struct dpll *clock);
@@ -20,4 +21,21 @@  void vlv_compute_dpll(struct intel_crtc *crtc,
 void chv_compute_dpll(struct intel_crtc *crtc,
 		      struct intel_crtc_state *pipe_config);
 
+int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
+		     const struct dpll *dpll);
+void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe);
+void i9xx_enable_pll(struct intel_crtc *crtc,
+		     const struct intel_crtc_state *crtc_state);
+void vlv_enable_pll(struct intel_crtc *crtc,
+		    const struct intel_crtc_state *pipe_config);
+void chv_enable_pll(struct intel_crtc *crtc,
+		    const struct intel_crtc_state *pipe_config);
+void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe);
+void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe);
+void i9xx_disable_pll(const struct intel_crtc_state *crtc_state);
+void vlv_prepare_pll(struct intel_crtc *crtc,
+		     const struct intel_crtc_state *pipe_config);
+void chv_prepare_pll(struct intel_crtc *crtc,
+		     const struct intel_crtc_state *pipe_config);
+
 #endif
diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c
index 58eff6289d12..0a9b2abf290e 100644
--- a/drivers/gpu/drm/i915/display/intel_pps.c
+++ b/drivers/gpu/drm/i915/display/intel_pps.c
@@ -6,6 +6,7 @@ 
 #include "i915_drv.h"
 #include "intel_display_types.h"
 #include "intel_dp.h"
+#include "intel_dpll.h"
 #include "intel_pps.h"
 
 static void vlv_steal_power_sequencer(struct drm_i915_private *dev_priv,