[PATCH 4/4] drm/i915: Apply the i915gm/i945gm irq C-state w/a to CRC interrupts
Jani Nikula
jani.nikula at linux.intel.com
Wed Oct 2 10:46:22 UTC 2024
On Tue, 01 Oct 2024, Ville Syrjala <ville.syrjala at linux.intel.com> wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
>
> Turns out CRC interrupts also fail to wake up i915gm/i945gm from
> C2+. I suppose this is a generic problem, but for most other
> interrupts the system will be busy enough already prior to
> the irq being issued. But CRC interrupts are like vblank interrupts
> and only fire once per frame, so plenty of time to fall asleep
> in between them.
>
> Apply the same core clock gating trick to CRC interrupts
> that we use for vblank interrupts.
>
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
Reviewed-by: Jani Nikula <jani.nikula at intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_display_irq.c | 14 +++++++++++++-
> drivers/gpu/drm/i915/display/intel_display_irq.h | 2 ++
> drivers/gpu/drm/i915/display/intel_pipe_crc.c | 4 ++++
> 3 files changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
> index feeb3a29972a..fa5a42fc8501 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_irq.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
> @@ -1264,7 +1264,7 @@ static void i915gm_irq_cstate_wa_enable(struct drm_i915_private *i915)
> lockdep_assert_held(&i915->drm.vblank_time_lock);
>
> /*
> - * Vblank interrupts fail to wake the device up from C2+.
> + * Vblank/CRC interrupts fail to wake the device up from C2+.
> * Disabling render clock gating during C-states avoids
> * the problem. There is a small power cost so we do this
> * only when vblank interrupts are actually enabled.
> @@ -1281,6 +1281,18 @@ static void i915gm_irq_cstate_wa_disable(struct drm_i915_private *i915)
> intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE));
> }
>
> +void i915gm_irq_cstate_wa(struct drm_i915_private *i915, bool enable)
> +{
> + spin_lock_irq(&i915->drm.vblank_time_lock);
> +
> + if (enable)
> + i915gm_irq_cstate_wa_enable(i915);
> + else
> + i915gm_irq_cstate_wa_disable(i915);
> +
> + spin_unlock_irq(&i915->drm.vblank_time_lock);
> +}
> +
> int i8xx_enable_vblank(struct drm_crtc *crtc)
> {
> struct drm_i915_private *dev_priv = to_i915(crtc->dev);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h
> index bf9d269d0e3f..4b493cff7b8e 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_irq.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h
> @@ -78,4 +78,6 @@ void valleyview_pipestat_irq_handler(struct drm_i915_private *i915, u32 pipe_sta
>
> void intel_display_irq_init(struct drm_i915_private *i915);
>
> +void i915gm_irq_cstate_wa(struct drm_i915_private *i915, bool enable);
> +
> #endif /* __INTEL_DISPLAY_IRQ_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc.c b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
> index 82ceede0b2b1..304da826dee1 100644
> --- a/drivers/gpu/drm/i915/display/intel_pipe_crc.c
> +++ b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
> @@ -32,6 +32,7 @@
> #include "i915_reg.h"
> #include "intel_atomic.h"
> #include "intel_de.h"
> +#include "intel_display_irq.h"
> #include "intel_display_types.h"
> #include "intel_pipe_crc.h"
> #include "intel_pipe_crc_regs.h"
> @@ -285,6 +286,9 @@ intel_crtc_crc_setup_workarounds(struct intel_crtc *crtc, bool enable)
> struct drm_modeset_acquire_ctx ctx;
> int ret;
>
> + if (IS_I945GM(dev_priv) || IS_I915GM(dev_priv))
> + i915gm_irq_cstate_wa(dev_priv, enable);
> +
> drm_modeset_acquire_init(&ctx, 0);
>
> state = drm_atomic_state_alloc(&dev_priv->drm);
--
Jani Nikula, Intel
More information about the Intel-gfx
mailing list