]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/irq: add display irq funcs, start with intel_display_irq_reset()
authorJani Nikula <jani.nikula@intel.com>
Wed, 13 May 2026 16:13:26 +0000 (19:13 +0300)
committerJani Nikula <jani.nikula@intel.com>
Sat, 16 May 2026 09:19:23 +0000 (12:19 +0300)
Introduce display irq hooks with struct intel_display_irq_funcs, and add
the ->reset hook as the first thing. Call the reset hooks from i915 and
xe core via intel_display_irq_reset().

Relocate the gen8 and gen11 HAS_DISPLAY() check to
intel_display_irq_reset(), as the funcs pointer won't be initialized for
no display.

Note: We're increasingly moving to the territory of not touching display
at all if there's no display or it has been fused off. Which is good,
but care must be taken to not have hardware setup required also for no
display cases in display code. Also note that the line is fuzzy for
older platforms, but there we also don't have fusing.

v2:
- make the structs static const (Sashiko)
- relocate HAS_DISPLAY() (Sashiko)

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/f9d75e8af92b5550a9d07f29491be5313b7c866b.1778688699.git.jani.nikula@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/display/intel_display_core.h
drivers/gpu/drm/i915/display/intel_display_irq.c
drivers/gpu/drm/i915/display/intel_display_irq.h
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/xe/display/xe_display.c

index 76745ce6a716ef0c636df30eaed1bdd8cdecc7cb..3dc5ac75a98bef23a9a3d461490174d9ea397cf7 100644 (file)
@@ -475,6 +475,9 @@ struct intel_display {
        } ips;
 
        struct {
+               /* internal display irq functions */
+               const struct intel_display_irq_funcs *funcs;
+
                /* protects the irq masks */
                spinlock_t lock;
 
index c656d59c757124fb24bb71123106ad66b0b2c108..27599a303843b9da40d58da9bb3847273cb1b1a9 100644 (file)
@@ -1947,7 +1947,7 @@ static void _vlv_display_irq_reset(struct intel_display *display)
        display->irq.vlv_imr_mask = ~0u;
 }
 
-void vlv_display_irq_reset(struct intel_display *display)
+static void vlv_display_irq_reset(struct intel_display *display)
 {
        spin_lock_irq(&display->irq.lock);
        if (display->irq.vlv_display_irqs_enabled)
@@ -1955,7 +1955,7 @@ void vlv_display_irq_reset(struct intel_display *display)
        spin_unlock_irq(&display->irq.lock);
 }
 
-void i9xx_display_irq_reset(struct intel_display *display)
+static void i9xx_display_irq_reset(struct intel_display *display)
 {
        if (HAS_HOTPLUG(display)) {
                i915_hotplug_interrupt_update(display, 0xffffffff, 0);
@@ -2076,7 +2076,7 @@ static void ibx_display_irq_reset(struct intel_display *display)
                intel_de_write(display, SERR_INT, 0xffffffff);
 }
 
-void ilk_display_irq_reset(struct intel_display *display)
+static void ilk_display_irq_reset(struct intel_display *display)
 {
        irq_reset(display, DE_IRQ_REGS);
        display->irq.ilk_de_imr_mask = ~0u;
@@ -2092,13 +2092,10 @@ void ilk_display_irq_reset(struct intel_display *display)
        ibx_display_irq_reset(display);
 }
 
-void gen8_display_irq_reset(struct intel_display *display)
+static void gen8_display_irq_reset(struct intel_display *display)
 {
        enum pipe pipe;
 
-       if (!HAS_DISPLAY(display))
-               return;
-
        intel_de_write(display, EDP_PSR_IMR, 0xffffffff);
        intel_de_write(display, EDP_PSR_IIR, 0xffffffff);
 
@@ -2114,15 +2111,12 @@ void gen8_display_irq_reset(struct intel_display *display)
                ibx_display_irq_reset(display);
 }
 
-void gen11_display_irq_reset(struct intel_display *display)
+static void gen11_display_irq_reset(struct intel_display *display)
 {
        enum pipe pipe;
        u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
                BIT(TRANSCODER_C) | BIT(TRANSCODER_D);
 
-       if (!HAS_DISPLAY(display))
-               return;
-
        intel_de_write(display, GEN11_DISPLAY_INT_CTL, 0);
 
        if (DISPLAY_VER(display) >= 12) {
@@ -2453,6 +2447,38 @@ struct intel_display_irq_funcs {
        void (*reset)(struct intel_display *display);
 };
 
+static const struct intel_display_irq_funcs gen11_display_irq_funcs = {
+       .reset = gen11_display_irq_reset,
+};
+
+static const struct intel_display_irq_funcs gen8_display_irq_funcs = {
+       .reset = gen8_display_irq_reset,
+};
+
+static const struct intel_display_irq_funcs vlv_display_irq_funcs = {
+       .reset = vlv_display_irq_reset,
+};
+
+static const struct intel_display_irq_funcs ilk_display_irq_funcs = {
+       .reset = ilk_display_irq_reset,
+};
+
+static const struct intel_display_irq_funcs i965_display_irq_funcs = {
+       .reset = i9xx_display_irq_reset,
+};
+
+static const struct intel_display_irq_funcs i915_display_irq_funcs = {
+       .reset = i9xx_display_irq_reset,
+};
+
+void intel_display_irq_reset(struct intel_display *display)
+{
+       if (!HAS_DISPLAY(display))
+               return;
+
+       display->irq.funcs->reset(display);
+}
+
 void intel_display_irq_init(struct intel_display *display)
 {
        spin_lock_init(&display->irq.lock);
@@ -2463,6 +2489,19 @@ void intel_display_irq_init(struct intel_display *display)
 
        INIT_WORK(&display->irq.vblank_notify_work,
                  intel_display_vblank_notify_work);
+
+       if (DISPLAY_VER(display) >= 11)
+               display->irq.funcs = &gen11_display_irq_funcs;
+       else if (display->platform.cherryview || display->platform.valleyview)
+               display->irq.funcs = &vlv_display_irq_funcs;
+       else if (DISPLAY_VER(display) >= 8)
+               display->irq.funcs = &gen8_display_irq_funcs;
+       else if (DISPLAY_VER(display) >= 5)
+               display->irq.funcs = &ilk_display_irq_funcs;
+       else if (DISPLAY_VER(display) == 4)
+               display->irq.funcs = &i965_display_irq_funcs;
+       else
+               display->irq.funcs = &i915_display_irq_funcs;
 }
 
 struct intel_display_irq_snapshot {
index d25b9ea4272b40ccb7258298e855d791697bcc6e..21b2145656cdd5b6c4f8b74bd36407d4d0164e4c 100644 (file)
@@ -58,11 +58,7 @@ void gen11_display_irq_handler(struct intel_display *display);
 u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl);
 void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir);
 
-void i9xx_display_irq_reset(struct intel_display *display);
-void ilk_display_irq_reset(struct intel_display *display);
-void vlv_display_irq_reset(struct intel_display *display);
-void gen8_display_irq_reset(struct intel_display *display);
-void gen11_display_irq_reset(struct intel_display *display);
+void intel_display_irq_reset(struct intel_display *display);
 
 u32 i9xx_display_irq_enable_mask(struct intel_display *display);
 void i915_display_irq_postinstall(struct intel_display *display);
index ef9eadf38a5335928fdf8b221e493c2f6cf2c312..c4f56a8699100c514b8c7f697cb93bb40c566983 100644 (file)
@@ -640,7 +640,7 @@ static void ilk_irq_reset(struct drm_i915_private *dev_priv)
        struct intel_display *display = dev_priv->display;
 
        /* The master interrupt enable is in DEIER, reset display irq first */
-       ilk_display_irq_reset(display);
+       intel_display_irq_reset(display);
        gen5_gt_irq_reset(to_gt(dev_priv));
 }
 
@@ -653,7 +653,7 @@ static void valleyview_irq_reset(struct drm_i915_private *dev_priv)
 
        gen5_gt_irq_reset(to_gt(dev_priv));
 
-       vlv_display_irq_reset(display);
+       intel_display_irq_reset(display);
 }
 
 static void gen8_irq_reset(struct drm_i915_private *dev_priv)
@@ -664,7 +664,7 @@ static void gen8_irq_reset(struct drm_i915_private *dev_priv)
        gen8_master_intr_disable(intel_uncore_regs(uncore));
 
        gen8_gt_irq_reset(to_gt(dev_priv));
-       gen8_display_irq_reset(display);
+       intel_display_irq_reset(display);
        gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS);
 }
 
@@ -677,7 +677,7 @@ static void gen11_irq_reset(struct drm_i915_private *dev_priv)
        gen11_master_intr_disable(intel_uncore_regs(&dev_priv->uncore));
 
        gen11_gt_irq_reset(gt);
-       gen11_display_irq_reset(display);
+       intel_display_irq_reset(display);
 
        gen2_irq_reset(uncore, GEN11_GU_MISC_IRQ_REGS);
        gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS);
@@ -695,7 +695,7 @@ static void dg1_irq_reset(struct drm_i915_private *dev_priv)
        for_each_gt(gt, dev_priv, i)
                gen11_gt_irq_reset(gt);
 
-       gen11_display_irq_reset(display);
+       intel_display_irq_reset(display);
 
        gen2_irq_reset(uncore, GEN11_GU_MISC_IRQ_REGS);
        gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS);
@@ -715,7 +715,7 @@ static void cherryview_irq_reset(struct drm_i915_private *dev_priv)
 
        gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS);
 
-       vlv_display_irq_reset(display);
+       intel_display_irq_reset(display);
 }
 
 static void ilk_irq_postinstall(struct drm_i915_private *dev_priv)
@@ -864,7 +864,7 @@ static void i915_irq_reset(struct drm_i915_private *dev_priv)
        struct intel_display *display = dev_priv->display;
        struct intel_uncore *uncore = &dev_priv->uncore;
 
-       i9xx_display_irq_reset(display);
+       intel_display_irq_reset(display);
 
        gen2_error_reset(uncore, GEN2_ERROR_REGS);
        gen2_irq_reset(uncore, GEN2_IRQ_REGS);
@@ -951,7 +951,7 @@ static void i965_irq_reset(struct drm_i915_private *dev_priv)
        struct intel_display *display = dev_priv->display;
        struct intel_uncore *uncore = &dev_priv->uncore;
 
-       i9xx_display_irq_reset(display);
+       intel_display_irq_reset(display);
 
        gen2_error_reset(uncore, GEN2_ERROR_REGS);
        gen2_irq_reset(uncore, GEN2_IRQ_REGS);
index fc198236e9de13b60a5233ffc8848622772527ec..6ce8f37ddd445dea99c4428b79782186ac4c0df8 100644 (file)
@@ -243,7 +243,7 @@ void xe_display_irq_reset(struct xe_device *xe)
        if (!xe->info.probe_display)
                return;
 
-       gen11_display_irq_reset(display);
+       intel_display_irq_reset(display);
 }
 
 void xe_display_irq_postinstall(struct xe_device *xe)