Message ID | 20241001195803.3371-4-ville.syrjala@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/i915: Vblank/CRC irq stuf | expand |
On Tue, 01 Oct 2024, Ville Syrjala <ville.syrjala@linux.intel.com> wrote: > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > 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 vblanl locks, so let's assert that the innermost of those *vblank Reviewed-by: Jani Nikula <jani.nikula@intel.com> > is held, in anticipation of other callers. > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > --- > .../gpu/drm/i915/display/intel_display_irq.c | 34 +++++++++++++------ > 1 file changed, 24 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c > index 43a0b3565bc8..feeb3a29972a 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)
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 43a0b3565bc8..feeb3a29972a 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)