In order to implement atomic mode sets, we'll need to hold state shared by multiple crtcs in the drm_atomic_state struct. This patch moves towards that goal by introducing struct intel_atomic_state for that purpose and moving the staged pll configuration into it. Current state will be moved in a follow up patch. Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.h | 3 +- drivers/gpu/drm/i915/intel_ddi.c | 11 ++-- drivers/gpu/drm/i915/intel_display.c | 104 +++++++++++++++-------------------- drivers/gpu/drm/i915/intel_drv.h | 8 ++- 4 files changed, 59 insertions(+), 67 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b09173f..862edc4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -297,7 +297,6 @@ struct intel_shared_dpll_config { struct intel_shared_dpll { struct intel_shared_dpll_config config; - struct intel_shared_dpll_config *new_config; int active; /* count of number of active CRTCs (i.e. DPMS on) */ bool on; /* is the PLL actually active? Disabled during modeset */ @@ -504,6 +503,7 @@ struct drm_i915_error_state { struct intel_connector; struct intel_encoder; struct intel_crtc_state; +struct intel_atomic_state; struct intel_initial_plane_config; struct intel_crtc; struct intel_limit; @@ -546,6 +546,7 @@ struct drm_i915_display_funcs { void (*get_initial_plane_config)(struct intel_crtc *, struct intel_initial_plane_config *); int (*crtc_compute_clock)(struct intel_crtc *crtc, + struct intel_atomic_state *state, struct intel_crtc_state *crtc_state); void (*crtc_enable)(struct drm_crtc *crtc); void (*crtc_disable)(struct drm_crtc *crtc); diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index ad8b73d..1cd541f 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -909,6 +909,7 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */, static bool hsw_ddi_pll_select(struct intel_crtc *intel_crtc, + struct intel_atomic_state *state, struct intel_crtc_state *crtc_state, struct intel_encoder *intel_encoder, int clock) @@ -926,7 +927,7 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, crtc_state->dpll_hw_state.wrpll = val; - pll = intel_get_shared_dpll(intel_crtc, crtc_state); + pll = intel_get_shared_dpll(intel_crtc, state, crtc_state); if (pll == NULL) { DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", pipe_name(intel_crtc->pipe)); @@ -1096,6 +1097,7 @@ found: static bool skl_ddi_pll_select(struct intel_crtc *intel_crtc, + struct intel_atomic_state *state, struct intel_crtc_state *crtc_state, struct intel_encoder *intel_encoder, int clock) @@ -1150,7 +1152,7 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, crtc_state->dpll_hw_state.cfgcr1 = cfgcr1; crtc_state->dpll_hw_state.cfgcr2 = cfgcr2; - pll = intel_get_shared_dpll(intel_crtc, crtc_state); + pll = intel_get_shared_dpll(intel_crtc, state, crtc_state); if (pll == NULL) { DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", pipe_name(intel_crtc->pipe)); @@ -1171,6 +1173,7 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, * function should be folded into compute_config() eventually. */ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc, + struct intel_atomic_state *state, struct intel_crtc_state *crtc_state) { struct drm_device *dev = intel_crtc->base.dev; @@ -1179,10 +1182,10 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc, int clock = crtc_state->port_clock; if (IS_SKYLAKE(dev)) - return skl_ddi_pll_select(intel_crtc, crtc_state, + return skl_ddi_pll_select(intel_crtc, state, crtc_state, intel_encoder, clock); else - return hsw_ddi_pll_select(intel_crtc, crtc_state, + return hsw_ddi_pll_select(intel_crtc, state, crtc_state, intel_encoder, clock); } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3d220a6..159e6c8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3891,6 +3891,7 @@ void intel_put_shared_dpll(struct intel_crtc *crtc) } struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, + struct intel_atomic_state *state, struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; @@ -3905,7 +3906,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", crtc->base.base.id, pll->name); - WARN_ON(pll->new_config->crtc_mask); + WARN_ON(state->shared_dpll[i].crtc_mask); goto found; } @@ -3914,15 +3915,15 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, pll = &dev_priv->shared_dplls[i]; /* Only want to check enabled timings first */ - if (pll->new_config->crtc_mask == 0) + if (state->shared_dpll[i].crtc_mask == 0) continue; if (memcmp(&crtc_state->dpll_hw_state, - &pll->new_config->hw_state, - sizeof(pll->new_config->hw_state)) == 0) { + &state->shared_dpll[i].hw_state, + sizeof(state->shared_dpll[i].hw_state)) == 0) { DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, ative %d)\n", crtc->base.base.id, pll->name, - pll->new_config->crtc_mask, + state->shared_dpll[i].crtc_mask, pll->active); goto found; } @@ -3931,7 +3932,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, /* Ok no matching timings, maybe there's a free one? */ for (i = 0; i < dev_priv->num_shared_dpll; i++) { pll = &dev_priv->shared_dplls[i]; - if (pll->new_config->crtc_mask == 0) { + if (state->shared_dpll[i].crtc_mask == 0) { DRM_DEBUG_KMS("CRTC:%d allocated %s\n", crtc->base.base.id, pll->name); goto found; @@ -3941,14 +3942,14 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, return NULL; found: - if (pll->new_config->crtc_mask == 0) - pll->new_config->hw_state = crtc_state->dpll_hw_state; + if (state->shared_dpll[i].crtc_mask == 0) + state->shared_dpll[i].hw_state = crtc_state->dpll_hw_state; crtc_state->shared_dpll = i; DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name, pipe_name(crtc->pipe)); - pll->new_config->crtc_mask |= 1 << crtc->pipe; + state->shared_dpll[i].crtc_mask |= 1 << crtc->pipe; return pll; } @@ -3962,6 +3963,7 @@ found: * releasing the references of pipes specified in clear_pipes. */ static int intel_shared_dpll_start_config(struct drm_i915_private *dev_priv, + struct intel_atomic_state *state, unsigned clear_pipes) { struct intel_shared_dpll *pll; @@ -3970,54 +3972,23 @@ static int intel_shared_dpll_start_config(struct drm_i915_private *dev_priv, for (i = 0; i < dev_priv->num_shared_dpll; i++) { pll = &dev_priv->shared_dplls[i]; - pll->new_config = kmemdup(&pll->config, sizeof pll->config, - GFP_KERNEL); - if (!pll->new_config) - goto cleanup; - - pll->new_config->crtc_mask &= ~clear_pipes; + memcpy(&state->shared_dpll[i], &pll->config, + sizeof pll->config); + state->shared_dpll[i].crtc_mask &= ~clear_pipes; } return 0; - -cleanup: - while (--i >= 0) { - pll = &dev_priv->shared_dplls[i]; - kfree(pll->new_config); - pll->new_config = NULL; - } - - return -ENOMEM; } -static void intel_shared_dpll_commit(struct drm_i915_private *dev_priv) +static void intel_shared_dpll_commit(struct drm_i915_private *dev_priv, + struct intel_atomic_state *state) { struct intel_shared_dpll *pll; enum intel_dpll_id i; for (i = 0; i < dev_priv->num_shared_dpll; i++) { pll = &dev_priv->shared_dplls[i]; - - WARN_ON(pll->new_config == &pll->config); - - pll->config = *pll->new_config; - kfree(pll->new_config); - pll->new_config = NULL; - } -} - -static void intel_shared_dpll_abort_config(struct drm_i915_private *dev_priv) -{ - struct intel_shared_dpll *pll; - enum intel_dpll_id i; - - for (i = 0; i < dev_priv->num_shared_dpll; i++) { - pll = &dev_priv->shared_dplls[i]; - - WARN_ON(pll->new_config == &pll->config); - - kfree(pll->new_config); - pll->new_config = NULL; + pll->config = state->shared_dpll[i]; } } @@ -6426,6 +6397,7 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) } static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, + struct intel_atomic_state *state, struct intel_crtc_state *crtc_state) { struct drm_device *dev = crtc->base.dev; @@ -7452,6 +7424,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc, } static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, + struct intel_atomic_state *state, struct intel_crtc_state *crtc_state) { struct drm_device *dev = crtc->base.dev; @@ -7498,7 +7471,7 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, else crtc_state->dpll_hw_state.fp1 = fp; - pll = intel_get_shared_dpll(crtc, crtc_state); + pll = intel_get_shared_dpll(crtc, state, crtc_state); if (pll == NULL) { DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", pipe_name(crtc->pipe)); @@ -8070,9 +8043,10 @@ void hsw_disable_pc8(struct drm_i915_private *dev_priv) } static int haswell_crtc_compute_clock(struct intel_crtc *crtc, + struct intel_atomic_state *state, struct intel_crtc_state *crtc_state) { - if (!intel_ddi_pll_select(crtc, crtc_state)) + if (!intel_ddi_pll_select(crtc, state, crtc_state)) return -EINVAL; crtc->lowfreq_avail = false; @@ -10417,14 +10391,15 @@ static bool intel_crtc_in_use(struct drm_crtc *crtc) } static void -intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes) +intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes, + struct intel_atomic_state *state) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_encoder *intel_encoder; struct intel_crtc *intel_crtc; struct drm_connector *connector; - intel_shared_dpll_commit(dev_priv); + intel_shared_dpll_commit(dev_priv, state); for_each_intel_encoder(dev, intel_encoder) { if (!intel_encoder->base.crtc) @@ -11022,6 +10997,7 @@ out: } static int __intel_set_mode_setup_plls(struct drm_device *dev, + struct intel_atomic_state *state, unsigned modeset_pipes, unsigned disable_pipes) { @@ -11033,21 +11009,18 @@ static int __intel_set_mode_setup_plls(struct drm_device *dev, if (!dev_priv->display.crtc_compute_clock) return 0; - ret = intel_shared_dpll_start_config(dev_priv, clear_pipes); + ret = intel_shared_dpll_start_config(dev_priv, state, clear_pipes); if (ret) - goto done; + return ret; for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) { - struct intel_crtc_state *state = intel_crtc->new_config; + struct intel_crtc_state *crtc_state = intel_crtc->new_config; ret = dev_priv->display.crtc_compute_clock(intel_crtc, - state); - if (ret) { - intel_shared_dpll_abort_config(dev_priv); - goto done; - } + state, crtc_state); + if (ret) + break; } -done: return ret; } @@ -11063,6 +11036,7 @@ static int __intel_set_mode(struct drm_crtc *crtc, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_display_mode *saved_mode; struct intel_crtc *intel_crtc; + struct intel_atomic_state *state = NULL; int ret = 0; saved_mode = kmalloc(sizeof(*saved_mode), GFP_KERNEL); @@ -11088,7 +11062,14 @@ static int __intel_set_mode(struct drm_crtc *crtc, prepare_pipes &= ~disable_pipes; } - ret = __intel_set_mode_setup_plls(dev, modeset_pipes, disable_pipes); + state = kzalloc(sizeof *state, GFP_KERNEL); + if (!state) { + ret = -ENOMEM; + goto done; + } + + ret = __intel_set_mode_setup_plls(dev, state, + modeset_pipes, disable_pipes); if (ret) goto done; @@ -11124,7 +11105,7 @@ static int __intel_set_mode(struct drm_crtc *crtc, /* Only after disabling all output pipelines that will be changed can we * update the the output configuration. */ - intel_modeset_update_state(dev, prepare_pipes); + intel_modeset_update_state(dev, prepare_pipes, state); modeset_update_crtc_power_domains(dev); @@ -11155,6 +11136,7 @@ done: if (ret && crtc->enabled) crtc->mode = *saved_mode; + kfree(state); kfree(saved_mode); return ret; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index eef79cc..f2f4210 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -243,6 +243,10 @@ typedef struct dpll { int p; } intel_clock_t; +struct intel_atomic_state { + struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS]; +}; + struct intel_plane_state { struct drm_plane_state base; struct drm_rect src; @@ -837,6 +841,7 @@ void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc); void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc); bool intel_ddi_pll_select(struct intel_crtc *crtc, + struct intel_atomic_state *state, struct intel_crtc_state *crtc_state); void intel_ddi_set_pipe_settings(struct drm_crtc *crtc); void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder); @@ -962,7 +967,8 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv, #define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true) #define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false) struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *state); + struct intel_atomic_state *state, + struct intel_crtc_state *crtc_state); void intel_put_shared_dpll(struct intel_crtc *crtc); void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, -- 2.1.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx