From 8106ddbd7733f31205007f97be0866b408772907 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 8 Mar 2016 17:46:18 +0200 Subject: [PATCH] drm/i915: Store a direct pointer to shared dpll in intel_crtc_state Change the type of intel_crtc_state->shared_dpll to be a pointer to a shared dpll. With this there is no need to first convert the id stored in the crtc state to a pointer in order to use it. It does introduce a bit of hassle on doing the opposite. The long term objective is to hide details about dpll ids behind the shared dpll interface. Signed-off-by: Ander Conselvan de Oliveira Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-5-git-send-email-ander.conselvan.de.oliveira@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 4 +- drivers/gpu/drm/i915/intel_display.c | 108 +++++++++++++++++--------- drivers/gpu/drm/i915/intel_dpll_mgr.c | 51 +++++++++--- drivers/gpu/drm/i915/intel_drv.h | 19 ++++- drivers/gpu/drm/i915/intel_lvds.c | 2 +- 5 files changed, 132 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 54880662f597..b6af5c0a6ae6 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1209,6 +1209,7 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state, struct intel_encoder *intel_encoder) { + struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); int clock = crtc_state->port_clock; if (intel_encoder->type == INTEL_OUTPUT_HDMI) { @@ -1244,7 +1245,8 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll)) return false; - crtc_state->shared_dpll = DPLL_ID_SPLL; + crtc_state->shared_dpll = + intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_SPLL); spll->hw_state.spll = crtc_state->dpll_hw_state.spll; spll->crtc_mask |= 1 << intel_crtc->pipe; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1d5695d07abd..579da412a200 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1843,8 +1843,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, BUG_ON(!HAS_PCH_SPLIT(dev)); /* Make sure PCH DPLL is enabled */ - assert_shared_dpll_enabled(dev_priv, - intel_crtc_to_shared_dpll(intel_crtc)); + assert_shared_dpll_enabled(dev_priv, intel_crtc->config->shared_dpll); /* FDI must be feeding us bits for PCH ports */ assert_fdi_tx_enabled(dev_priv, pipe); @@ -4147,7 +4146,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) temp = I915_READ(PCH_DPLL_SEL); temp |= TRANS_DPLL_ENABLE(pipe); sel = TRANS_DPLLB_SEL(pipe); - if (intel_crtc->config->shared_dpll == DPLL_ID_PCH_PLL_B) + if (intel_crtc->config->shared_dpll == + intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_PCH_PLL_B)) temp |= sel; else temp &= ~sel; @@ -4883,7 +4883,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A, false); - if (intel_crtc_to_shared_dpll(intel_crtc)) + if (intel_crtc->config->shared_dpll) intel_enable_shared_dpll(intel_crtc); if (intel_crtc->config->has_dp_encoder) @@ -8052,7 +8052,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, return false; pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; - pipe_config->shared_dpll = DPLL_ID_PRIVATE; + pipe_config->shared_dpll = NULL; ret = false; @@ -9256,7 +9256,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, return false; pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; - pipe_config->shared_dpll = DPLL_ID_PRIVATE; + pipe_config->shared_dpll = NULL; ret = false; tmp = I915_READ(PIPECONF(crtc->pipe)); @@ -9285,6 +9285,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) { struct intel_shared_dpll *pll; + enum intel_dpll_id pll_id; pipe_config->has_pch_encoder = true; @@ -9295,17 +9296,18 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, ironlake_get_fdi_m_n_config(crtc, pipe_config); if (HAS_PCH_IBX(dev_priv->dev)) { - pipe_config->shared_dpll = - (enum intel_dpll_id) crtc->pipe; + pll_id = (enum intel_dpll_id) crtc->pipe; } else { tmp = I915_READ(PCH_DPLL_SEL); if (tmp & TRANS_DPLLB_SEL(crtc->pipe)) - pipe_config->shared_dpll = DPLL_ID_PCH_PLL_B; + pll_id = DPLL_ID_PCH_PLL_B; else - pipe_config->shared_dpll = DPLL_ID_PCH_PLL_A; + pll_id= DPLL_ID_PCH_PLL_A; } - pll = &dev_priv->shared_dplls[pipe_config->shared_dpll]; + pipe_config->shared_dpll = + intel_get_shared_dpll_by_id(dev_priv, pll_id); + pll = pipe_config->shared_dpll; WARN_ON(!pll->get_hw_state(dev_priv, pll, &pipe_config->dpll_hw_state)); @@ -9741,28 +9743,34 @@ static void bxt_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port, struct intel_crtc_state *pipe_config) { + enum intel_dpll_id id; + switch (port) { case PORT_A: pipe_config->ddi_pll_sel = SKL_DPLL0; - pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1; + id = DPLL_ID_SKL_DPLL1; break; case PORT_B: pipe_config->ddi_pll_sel = SKL_DPLL1; - pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2; + id = DPLL_ID_SKL_DPLL2; break; case PORT_C: pipe_config->ddi_pll_sel = SKL_DPLL2; - pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3; + id = DPLL_ID_SKL_DPLL3; break; default: DRM_ERROR("Incorrect port type\n"); + return; } + + pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id); } static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port, struct intel_crtc_state *pipe_config) { + enum intel_dpll_id id; u32 temp, dpll_ctl1; temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port); @@ -9777,36 +9785,53 @@ static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv, */ dpll_ctl1 = I915_READ(DPLL_CTRL1); pipe_config->dpll_hw_state.ctrl1 = dpll_ctl1 & 0x3f; - break; + return; case SKL_DPLL1: - pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1; + id = DPLL_ID_SKL_DPLL1; break; case SKL_DPLL2: - pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2; + id = DPLL_ID_SKL_DPLL2; break; case SKL_DPLL3: - pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3; + id = DPLL_ID_SKL_DPLL3; break; + default: + MISSING_CASE(pipe_config->ddi_pll_sel); + return; } + + pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id); } static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port, struct intel_crtc_state *pipe_config) { + enum intel_dpll_id id; + pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port)); switch (pipe_config->ddi_pll_sel) { case PORT_CLK_SEL_WRPLL1: - pipe_config->shared_dpll = DPLL_ID_WRPLL1; + id = DPLL_ID_WRPLL1; break; case PORT_CLK_SEL_WRPLL2: - pipe_config->shared_dpll = DPLL_ID_WRPLL2; + id = DPLL_ID_WRPLL2; break; case PORT_CLK_SEL_SPLL: - pipe_config->shared_dpll = DPLL_ID_SPLL; + id = DPLL_ID_SPLL; break; + default: + MISSING_CASE(pipe_config->ddi_pll_sel); + /* fall through */ + case PORT_CLK_SEL_NONE: + case PORT_CLK_SEL_LCPLL_810: + case PORT_CLK_SEL_LCPLL_1350: + case PORT_CLK_SEL_LCPLL_2700: + return; } + + pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id); } static void haswell_get_ddi_port_state(struct intel_crtc *crtc, @@ -9829,9 +9854,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc, else haswell_get_ddi_pll(dev_priv, port, pipe_config); - if (pipe_config->shared_dpll >= 0) { - pll = &dev_priv->shared_dplls[pipe_config->shared_dpll]; - + pll = pipe_config->shared_dpll; + if (pll) { WARN_ON(!pll->get_hw_state(dev_priv, pll, &pipe_config->dpll_hw_state)); } @@ -9871,7 +9895,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, ret = false; pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; - pipe_config->shared_dpll = DPLL_ID_PRIVATE; + pipe_config->shared_dpll = NULL; tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); if (tmp & TRANS_DDI_FUNC_ENABLE) { @@ -11868,7 +11892,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, if (mode_changed && crtc_state->enable && dev_priv->display.crtc_compute_clock && - !WARN_ON(pipe_config->shared_dpll != DPLL_ID_PRIVATE)) { + !WARN_ON(pipe_config->shared_dpll)) { ret = dev_priv->display.crtc_compute_clock(intel_crtc, pipe_config); if (ret) @@ -12213,7 +12237,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state) struct drm_crtc_state tmp_state; struct intel_crtc_scaler_state scaler_state; struct intel_dpll_hw_state dpll_hw_state; - enum intel_dpll_id shared_dpll; + struct intel_shared_dpll *shared_dpll; uint32_t ddi_pll_sel; bool force_thru; @@ -12483,6 +12507,15 @@ intel_pipe_config_compare(struct drm_device *dev, ret = false; \ } +#define PIPE_CONF_CHECK_P(name) \ + if (current_config->name != pipe_config->name) { \ + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \ + "(expected %p, found %p)\n", \ + current_config->name, \ + pipe_config->name); \ + ret = false; \ + } + #define PIPE_CONF_CHECK_M_N(name) \ if (!intel_compare_link_m_n(¤t_config->name, \ &pipe_config->name,\ @@ -12650,7 +12683,7 @@ intel_pipe_config_compare(struct drm_device *dev, PIPE_CONF_CHECK_X(ddi_pll_sel); - PIPE_CONF_CHECK_I(shared_dpll); + PIPE_CONF_CHECK_P(shared_dpll); PIPE_CONF_CHECK_X(dpll_hw_state.dpll); PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md); PIPE_CONF_CHECK_X(dpll_hw_state.fp0); @@ -12669,6 +12702,7 @@ intel_pipe_config_compare(struct drm_device *dev, #undef PIPE_CONF_CHECK_X #undef PIPE_CONF_CHECK_I +#undef PIPE_CONF_CHECK_P #undef PIPE_CONF_CHECK_I_ALT #undef PIPE_CONF_CHECK_FLAGS #undef PIPE_CONF_CHECK_CLOCK_FUZZY @@ -12892,7 +12926,8 @@ check_shared_dpll_state(struct drm_device *dev) int i; for (i = 0; i < dev_priv->num_shared_dpll; i++) { - struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; + struct intel_shared_dpll *pll = + intel_get_shared_dpll_by_id(dev_priv, i); int enabled_crtcs = 0, active_crtcs = 0; bool active; @@ -12914,9 +12949,9 @@ check_shared_dpll_state(struct drm_device *dev) pll->on, active); for_each_intel_crtc(dev, crtc) { - if (crtc->base.state->enable && intel_crtc_to_shared_dpll(crtc) == pll) + if (crtc->base.state->enable && crtc->config->shared_dpll == pll) enabled_crtcs++; - if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) + if (crtc->active && crtc->config->shared_dpll == pll) active_crtcs++; } I915_STATE_WARN(pll->active != active_crtcs, @@ -12995,20 +13030,21 @@ static void intel_modeset_clear_plls(struct drm_atomic_state *state) for_each_crtc_in_state(state, crtc, crtc_state, i) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int old_dpll = to_intel_crtc_state(crtc->state)->shared_dpll; + struct intel_shared_dpll *old_dpll = + to_intel_crtc_state(crtc->state)->shared_dpll; if (!needs_modeset(crtc_state)) continue; - to_intel_crtc_state(crtc_state)->shared_dpll = DPLL_ID_PRIVATE; + to_intel_crtc_state(crtc_state)->shared_dpll = NULL; - if (old_dpll == DPLL_ID_PRIVATE) + if (!old_dpll) continue; if (!shared_dpll) shared_dpll = intel_atomic_get_shared_dpll_state(state); - shared_dpll[old_dpll].crtc_mask &= ~(1 << intel_crtc->pipe); + intel_shared_dpll_config_put(shared_dpll, old_dpll, intel_crtc); } } @@ -15655,7 +15691,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) pll->active = 0; pll->config.crtc_mask = 0; for_each_intel_crtc(dev, crtc) { - if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) { + if (crtc->active && crtc->config->shared_dpll == pll) { pll->active++; pll->config.crtc_mask |= 1 << crtc->pipe; } diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 11effe3652c6..889ceedcaab8 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -24,14 +24,43 @@ #include "intel_drv.h" struct intel_shared_dpll * -intel_crtc_to_shared_dpll(struct intel_crtc *crtc) +intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv, + enum intel_dpll_id id) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + return &dev_priv->shared_dplls[id]; +} - if (crtc->config->shared_dpll < 0) - return NULL; +enum intel_dpll_id +intel_get_shared_dpll_id(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ + if (WARN_ON(pll < dev_priv->shared_dplls|| + pll > &dev_priv->shared_dplls[dev_priv->num_shared_dpll])) + return -1; + + return (enum intel_dpll_id) (pll - dev_priv->shared_dplls); +} + +void +intel_shared_dpll_config_get(struct intel_shared_dpll_config *config, + struct intel_shared_dpll *pll, + struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + enum intel_dpll_id id = intel_get_shared_dpll_id(dev_priv, pll); + + config[id].crtc_mask |= 1 << crtc->pipe; +} + +void +intel_shared_dpll_config_put(struct intel_shared_dpll_config *config, + struct intel_shared_dpll *pll, + struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + enum intel_dpll_id id = intel_get_shared_dpll_id(dev_priv, pll); - return &dev_priv->shared_dplls[crtc->config->shared_dpll]; + config[id].crtc_mask &= ~(1 << crtc->pipe); } /* For ILK+ */ @@ -55,7 +84,7 @@ void intel_prepare_shared_dpll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); + struct intel_shared_dpll *pll = crtc->config->shared_dpll; if (WARN_ON(pll == NULL)) return; @@ -82,7 +111,7 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); + struct intel_shared_dpll *pll = crtc->config->shared_dpll; if (WARN_ON(pll == NULL)) return; @@ -112,7 +141,7 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); + struct intel_shared_dpll *pll = crtc->config->shared_dpll; /* PCH only available on ILK+ */ if (INTEL_INFO(dev)->gen < 5) @@ -265,11 +294,11 @@ intel_get_shared_dpll(struct intel_crtc *crtc, shared_dpll[i].hw_state = crtc_state->dpll_hw_state; - crtc_state->shared_dpll = i; + crtc_state->shared_dpll = pll; DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name, pipe_name(crtc->pipe)); - shared_dpll[i].crtc_mask |= 1 << crtc->pipe; + intel_shared_dpll_config_get(shared_dpll, pll, crtc); return pll; } @@ -360,7 +389,7 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv, /* Make sure no transcoder isn't still depending on us. */ for_each_intel_crtc(dev, crtc) { - if (intel_crtc_to_shared_dpll(crtc) == pll) + if (crtc->config->shared_dpll == pll) assert_pch_transcoder_disabled(dev_priv, crtc->pipe); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 94aaad92bf73..1fbf069d9671 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -483,8 +483,8 @@ struct intel_crtc_state { * haswell. */ struct dpll dpll; - /* Selected dpll when shared or DPLL_ID_PRIVATE. */ - enum intel_dpll_id shared_dpll; + /* Selected dpll when shared or NULL. */ + struct intel_shared_dpll *shared_dpll; /* * - PORT_CLK_SEL for DDI ports on HSW/BDW. @@ -1204,7 +1204,20 @@ void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, enum pipe pipe); /* shared dpll functions */ -struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc); +struct intel_shared_dpll * +intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv, + enum intel_dpll_id id); +enum intel_dpll_id +intel_get_shared_dpll_id(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll); +void +intel_shared_dpll_config_get(struct intel_shared_dpll_config *config, + struct intel_shared_dpll *pll, + struct intel_crtc *crtc); +void +intel_shared_dpll_config_put(struct intel_shared_dpll_config *config, + struct intel_shared_dpll *pll, + struct intel_crtc *crtc); void assert_shared_dpll(struct drm_i915_private *dev_priv, struct intel_shared_dpll *pll, bool state); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index b35342f7b969..cbd1b0d547ee 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -145,7 +145,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder) if (HAS_PCH_SPLIT(dev)) { assert_fdi_rx_pll_disabled(dev_priv, pipe); assert_shared_dpll_disabled(dev_priv, - intel_crtc_to_shared_dpll(crtc)); + crtc->config->shared_dpll); } else { assert_pll_disabled(dev_priv, pipe); } -- 2.30.2