drm/i915: migrate pll enable/disable code to intel_dpll.[ch]
authorDave Airlie <airlied@redhat.com>
Fri, 5 Feb 2021 14:48:40 +0000 (16:48 +0200)
committerJani Nikula <jani.nikula@intel.com>
Mon, 8 Feb 2021 10:03:34 +0000 (12:03 +0200)
This moves the older i9xx/vlv/chv enable/disable to dpll file.

Signed-off-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/7fa8c76b0f07f3ede9efd7c1f989f33fbc8c53a3.1612536383.git.jani.nikula@intel.com
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/display/intel_display.h
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/display/intel_dpll.c
drivers/gpu/drm/i915/display/intel_dpll.h
drivers/gpu/drm/i915/display/intel_pps.c

index e9e8a52..ef29065 100644 (file)
@@ -113,10 +113,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);
@@ -569,224 +565,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)
@@ -5774,35 +5552,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)
 {
@@ -5898,267 +5647,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);
index 2bbd2ee..c80e5a3 100644 (file)
@@ -594,9 +594,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);
 
index 96789fb..4f89e0d 100644 (file)
@@ -50,6 +50,7 @@
 #include "intel_dp_aux.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"
index 7ba7f31..166e9a3 100644 (file)
@@ -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);
+}
index caf4615..7ff4b0d 100644 (file)
@@ -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
index c4867a8..f20ba71 100644 (file)
@@ -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,