[Intel-gfx] [PATCH 02/12] drm/i915: ensure the HW is powered during display pipe HW readout
Mika Kuoppala
mika.kuoppala at linux.intel.com
Mon Feb 15 13:23:07 UTC 2016
Imre Deak <imre.deak at intel.com> writes:
> The assumption when adding the intel_display_power_is_enabled() checks
> was that if it returns success the power can't be turned off afterwards
> during the HW access, which is guaranteed by modeset locks. This isn't
> always true, so make sure we hold a dedicated reference for the time of
> the access.
>
> Signed-off-by: Imre Deak <imre.deak at intel.com>
Was concerned on domain mask overflows but there was already
BUILD_BUG_ON for it.
Revieved-by: Mika Kuoppala <mika.kuoppala at intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 67 ++++++++++++++++++++++++++----------
> 1 file changed, 48 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 836bbdc..6abfc54 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -8181,18 +8181,22 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
> {
> struct drm_device *dev = crtc->base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> + enum intel_display_power_domain power_domain;
> uint32_t tmp;
> + bool ret;
>
> - if (!intel_display_power_is_enabled(dev_priv,
> - POWER_DOMAIN_PIPE(crtc->pipe)))
> + power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
> + if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
> return false;
>
> pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
> pipe_config->shared_dpll = DPLL_ID_PRIVATE;
>
> + ret = false;
> +
> tmp = I915_READ(PIPECONF(crtc->pipe));
> if (!(tmp & PIPECONF_ENABLE))
> - return false;
> + goto out;
>
> if (IS_G4X(dev) || IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
> switch (tmp & PIPECONF_BPC_MASK) {
> @@ -8272,7 +8276,12 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
> pipe_config->base.adjusted_mode.crtc_clock =
> pipe_config->port_clock / pipe_config->pixel_multiplier;
>
> - return true;
> + ret = true;
> +
> +out:
> + intel_display_power_put(dev_priv, power_domain);
> +
> + return ret;
> }
>
> static void ironlake_init_pch_refclk(struct drm_device *dev)
> @@ -9376,18 +9385,21 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
> {
> struct drm_device *dev = crtc->base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> + enum intel_display_power_domain power_domain;
> uint32_t tmp;
> + bool ret;
>
> - if (!intel_display_power_is_enabled(dev_priv,
> - POWER_DOMAIN_PIPE(crtc->pipe)))
> + power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
> + if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
> return false;
>
> pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
> pipe_config->shared_dpll = DPLL_ID_PRIVATE;
>
> + ret = false;
> tmp = I915_READ(PIPECONF(crtc->pipe));
> if (!(tmp & PIPECONF_ENABLE))
> - return false;
> + goto out;
>
> switch (tmp & PIPECONF_BPC_MASK) {
> case PIPECONF_6BPC:
> @@ -9450,7 +9462,12 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
>
> ironlake_get_pfit_config(crtc, pipe_config);
>
> - return true;
> + ret = true;
> +
> +out:
> + intel_display_power_put(dev_priv, power_domain);
> +
> + return ret;
> }
>
> static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
> @@ -9982,12 +9999,17 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
> {
> struct drm_device *dev = crtc->base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> - enum intel_display_power_domain pfit_domain;
> + enum intel_display_power_domain power_domain;
> + unsigned long power_domain_mask;
> uint32_t tmp;
> + bool ret;
>
> - if (!intel_display_power_is_enabled(dev_priv,
> - POWER_DOMAIN_PIPE(crtc->pipe)))
> + power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
> + if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
> return false;
> + power_domain_mask = BIT(power_domain);
> +
> + ret = false;
>
> pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
> pipe_config->shared_dpll = DPLL_ID_PRIVATE;
> @@ -10014,13 +10036,14 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
> pipe_config->cpu_transcoder = TRANSCODER_EDP;
> }
>
> - if (!intel_display_power_is_enabled(dev_priv,
> - POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder)))
> - return false;
> + power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder);
> + if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
> + goto out;
> + power_domain_mask |= BIT(power_domain);
>
> tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder));
> if (!(tmp & PIPECONF_ENABLE))
> - return false;
> + goto out;
>
> haswell_get_ddi_port_state(crtc, pipe_config);
>
> @@ -10030,14 +10053,14 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
> skl_init_scalers(dev, crtc, pipe_config);
> }
>
> - pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
> -
> if (INTEL_INFO(dev)->gen >= 9) {
> pipe_config->scaler_state.scaler_id = -1;
> pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX);
> }
>
> - if (intel_display_power_is_enabled(dev_priv, pfit_domain)) {
> + power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
> + if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {
> + power_domain_mask |= BIT(power_domain);
> if (INTEL_INFO(dev)->gen >= 9)
> skylake_get_pfit_config(crtc, pipe_config);
> else
> @@ -10055,7 +10078,13 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
> pipe_config->pixel_multiplier = 1;
> }
>
> - return true;
> + ret = true;
> +
> +out:
> + for_each_power_domain(power_domain, power_domain_mask)
> + intel_display_power_put(dev_priv, power_domain);
> +
> + return ret;
> }
>
> static void i845_update_cursor(struct drm_crtc *crtc, u32 base,
> --
> 2.5.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
More information about the Intel-gfx
mailing list