intel-xe.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Jani Nikula <jani.nikula@intel.com>
Cc: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org
Subject: Re: [PATCH v2 5/5] drm/i915/irq: split ILK display irq handling
Date: Tue, 23 Sep 2025 17:45:17 +0300	[thread overview]
Message-ID: <aNKyfVyQPpMsCpQy@intel.com> (raw)
In-Reply-To: <e8ea7c985c3f3a80870f3333bde2e1bf30d653b0.1758637773.git.jani.nikula@intel.com>

On Tue, Sep 23, 2025 at 05:31:08PM +0300, Jani Nikula wrote:
> Split out display irq handling on ilk. Since the master IRQ enable is in
> DEIIR, we'll need to do this in two parts. First, add
> ilk_display_irq_master_disable() to disable master and south interrupts,
> and second, add (repurposed) ilk_display_irq_handler() to finish display
> irq handling.
> 
> It's not the prettiest thing you ever saw, but improves separation of
> display irq handling. And removes HAS_PCH_NOP() and DISPLAY_VER() checks
> from core irq code.
> 
> v2:
> - Separate ilk_display_irq_master_enable() (Ville)
> - Use _fw mmio accessors (Ville)
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  .../gpu/drm/i915/display/intel_display_irq.c  | 51 ++++++++++++++++++-
>  .../gpu/drm/i915/display/intel_display_irq.h  |  5 +-
>  drivers/gpu/drm/i915/i915_irq.c               | 31 +++--------
>  3 files changed, 58 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
> index 4d51900123ea..e1a812f6159b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_irq.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
> @@ -872,7 +872,7 @@ static void ilk_gtt_fault_irq_handler(struct intel_display *display)
>  	}
>  }
>  
> -void ilk_display_irq_handler(struct intel_display *display, u32 de_iir)
> +static void _ilk_display_irq_handler(struct intel_display *display, u32 de_iir)
>  {
>  	enum pipe pipe;
>  	u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG;
> @@ -923,7 +923,7 @@ void ilk_display_irq_handler(struct intel_display *display, u32 de_iir)
>  		ilk_display_rps_irq_handler(display);
>  }
>  
> -void ivb_display_irq_handler(struct intel_display *display, u32 de_iir)
> +static void _ivb_display_irq_handler(struct intel_display *display, u32 de_iir)
>  {
>  	enum pipe pipe;
>  	u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG_IVB;
> @@ -972,6 +972,53 @@ void ivb_display_irq_handler(struct intel_display *display, u32 de_iir)
>  	}
>  }
>  
> +void ilk_display_irq_master_disable(struct intel_display *display, u32 *de_ier, u32 *sde_ier)
> +{
> +	/* disable master interrupt before clearing iir  */
> +	*de_ier = intel_de_read_fw(display, DEIER);
> +	intel_de_write_fw(display, DEIER, *de_ier & ~DE_MASTER_IRQ_CONTROL);
> +
> +	/*
> +	 * Disable south interrupts. We'll only write to SDEIIR once, so further
> +	 * interrupts will be stored on its back queue, and then we'll be able
> +	 * to process them after we restore SDEIER (as soon as we restore it,
> +	 * we'll get an interrupt if SDEIIR still has something to process due
> +	 * to its back queue).
> +	 */
> +	if (!HAS_PCH_NOP(display)) {
> +		*sde_ier = intel_de_read_fw(display, SDEIER);
> +		intel_de_write_fw(display, SDEIER, 0);
> +	} else {
> +		*sde_ier = 0;
> +	}
> +}
> +
> +void ilk_display_irq_master_enable(struct intel_display *display, u32 de_ier, u32 sde_ier)
> +{
> +	intel_de_write_fw(display, DEIER, de_ier);
> +
> +	if (sde_ier)
> +		intel_de_write_fw(display, SDEIER, sde_ier);
> +}
> +
> +bool ilk_display_irq_handler(struct intel_display *display)
> +{
> +	u32 de_iir;
> +	bool handled = false;
> +
> +	de_iir = intel_de_read_fw(display, DEIIR);
> +	if (de_iir) {
> +		intel_de_write_fw(display, DEIIR, de_iir);
> +		if (DISPLAY_VER(display) >= 7)
> +			_ivb_display_irq_handler(display, de_iir);
> +		else
> +			_ilk_display_irq_handler(display, de_iir);
> +		handled = true;
> +	}
> +
> +	return handled;
> +}
> +
>  static u32 gen8_de_port_aux_mask(struct intel_display *display)
>  {
>  	u32 mask;
> diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h
> index e44d88e0d7e7..84acd31948cf 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_irq.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h
> @@ -47,8 +47,9 @@ void i965_disable_vblank(struct drm_crtc *crtc);
>  void ilk_disable_vblank(struct drm_crtc *crtc);
>  void bdw_disable_vblank(struct drm_crtc *crtc);
>  
> -void ivb_display_irq_handler(struct intel_display *display, u32 de_iir);
> -void ilk_display_irq_handler(struct intel_display *display, u32 de_iir);
> +void ilk_display_irq_master_disable(struct intel_display *display, u32 *de_ier, u32 *sde_ier);
> +void ilk_display_irq_master_enable(struct intel_display *display, u32 de_ier, u32 sde_ier);
> +bool ilk_display_irq_handler(struct intel_display *display);
>  void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl);
>  void gen11_display_irq_handler(struct intel_display *display);
>  
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 90174ce9195c..11a727b74849 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -414,7 +414,7 @@ static irqreturn_t ilk_irq_handler(int irq, void *arg)
>  	struct drm_i915_private *i915 = arg;
>  	struct intel_display *display = i915->display;
>  	void __iomem * const regs = intel_uncore_regs(&i915->uncore);
> -	u32 de_iir, gt_iir, de_ier, sde_ier = 0;
> +	u32 gt_iir, de_ier = 0, sde_ier = 0;
>  	irqreturn_t ret = IRQ_NONE;
>  
>  	if (unlikely(!intel_irqs_enabled(i915)))
> @@ -423,19 +423,8 @@ static irqreturn_t ilk_irq_handler(int irq, void *arg)
>  	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
>  	disable_rpm_wakeref_asserts(&i915->runtime_pm);
>  
> -	/* disable master interrupt before clearing iir  */
> -	de_ier = raw_reg_read(regs, DEIER);
> -	raw_reg_write(regs, DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
> -
> -	/* Disable south interrupts. We'll only write to SDEIIR once, so further
> -	 * interrupts will will be stored on its back queue, and then we'll be
> -	 * able to process them after we restore SDEIER (as soon as we restore
> -	 * it, we'll get an interrupt if SDEIIR still has something to process
> -	 * due to its back queue). */
> -	if (!HAS_PCH_NOP(display)) {
> -		sde_ier = raw_reg_read(regs, SDEIER);
> -		raw_reg_write(regs, SDEIER, 0);
> -	}
> +	/* Disable master and south interrupts */
> +	ilk_display_irq_master_disable(display, &de_ier, &sde_ier);
>  
>  	/* Find, clear, then process each source of interrupt */
>  
> @@ -449,15 +438,8 @@ static irqreturn_t ilk_irq_handler(int irq, void *arg)
>  		ret = IRQ_HANDLED;
>  	}
>  
> -	de_iir = raw_reg_read(regs, DEIIR);
> -	if (de_iir) {
> -		raw_reg_write(regs, DEIIR, de_iir);
> -		if (DISPLAY_VER(display) >= 7)
> -			ivb_display_irq_handler(display, de_iir);
> -		else
> -			ilk_display_irq_handler(display, de_iir);
> +	if (ilk_display_irq_handler(display))
>  		ret = IRQ_HANDLED;
> -	}
>  
>  	if (GRAPHICS_VER(i915) >= 6) {
>  		u32 pm_iir = raw_reg_read(regs, GEN6_PMIIR);
> @@ -468,9 +450,8 @@ static irqreturn_t ilk_irq_handler(int irq, void *arg)
>  		}
>  	}
>  
> -	raw_reg_write(regs, DEIER, de_ier);
> -	if (sde_ier)
> -		raw_reg_write(regs, SDEIER, sde_ier);
> +	/* Re-enable master and south interrupts */
> +	ilk_display_irq_master_enable(display, de_ier, sde_ier);
>  
>  	pmu_irq_stats(i915, ret);
>  
> -- 
> 2.47.3

-- 
Ville Syrjälä
Intel

  reply	other threads:[~2025-09-23 14:45 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-23 14:31 [PATCH v2 0/5] drm/i915/irq: display irq refactoring Jani Nikula
2025-09-23 14:31 ` [PATCH v2 1/5] drm/i915/irq: drop intel_psr_regs.h include Jani Nikula
2025-09-23 14:39   ` Ville Syrjälä
2025-09-23 14:31 ` [PATCH v2 2/5] drm/i915/irq: initialize gen2_imr_mask in terms of enable_mask Jani Nikula
2025-09-23 14:40   ` Ville Syrjälä
2025-09-23 14:31 ` [PATCH v2 3/5] drm/i915/irq: abstract i9xx_display_irq_enable_mask() Jani Nikula
2025-09-23 14:41   ` Ville Syrjälä
2025-09-23 14:31 ` [PATCH v2 4/5] drm/i915/irq: move check for HAS_HOTPLUG() inside i9xx_hpd_irq_ack() Jani Nikula
2025-09-23 14:43   ` Ville Syrjälä
2025-09-23 14:31 ` [PATCH v2 5/5] drm/i915/irq: split ILK display irq handling Jani Nikula
2025-09-23 14:45   ` Ville Syrjälä [this message]
2025-09-24  6:47     ` Jani Nikula
2025-09-23 15:08 ` ✓ CI.KUnit: success for drm/i915/irq: display irq refactoring (rev2) Patchwork
2025-09-23 17:58 ` ✗ Xe.CI.Full: failure " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aNKyfVyQPpMsCpQy@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=jani.nikula@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).