From: Ville Syrjälä Date: Tue, 1 Oct 2024 19:58:02 +0000 (+0300) Subject: drm/i915: Extract i915gm_irq_cstate_wa_{disable,enable}() X-Git-Tag: v6.13-rc1~122^2~19^2~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f45cc1d373aeeabaaed0cef6c938bfcbbbd9962f;p=thirdparty%2Fkernel%2Flinux.git drm/i915: Extract i915gm_irq_cstate_wa_{disable,enable}() Extract the i915gm/i945gm vblank irq C-state workaround to separate functions. We'll need to reuse these in order to guarantee timely CRC interrupt delivery as well. The irq.vblank_enabled count is currently protected by the drm vblank locks, so let's assert that the innermost of those is held, in anticipation of other callers. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20241001195803.3371-4-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 43a0b3565bc89..feeb3a29972a4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -1259,6 +1259,28 @@ void gen11_display_irq_handler(struct drm_i915_private *i915) enable_rpm_wakeref_asserts(&i915->runtime_pm); } +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+. + * 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. + */ + if (i915->display.irq.vblank_enabled++ == 0) + intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_ENABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); +} + +static void i915gm_irq_cstate_wa_disable(struct drm_i915_private *i915) +{ + lockdep_assert_held(&i915->drm.vblank_time_lock); + + if (--i915->display.irq.vblank_enabled == 0) + intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); +} + int i8xx_enable_vblank(struct drm_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->dev); @@ -1287,14 +1309,7 @@ int i915gm_enable_vblank(struct drm_crtc *crtc) { struct drm_i915_private *i915 = to_i915(crtc->dev); - /* - * Vblank 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. - */ - if (i915->display.irq.vblank_enabled++ == 0) - intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_ENABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); + i915gm_irq_cstate_wa_enable(i915); return i8xx_enable_vblank(crtc); } @@ -1305,8 +1320,7 @@ void i915gm_disable_vblank(struct drm_crtc *crtc) i8xx_disable_vblank(crtc); - if (--i915->display.irq.vblank_enabled == 0) - intel_uncore_write(&i915->uncore, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); + i915gm_irq_cstate_wa_disable(i915); } int i965_enable_vblank(struct drm_crtc *crtc)