DG1 has master unit interrupt register which is used to indicate the
correct source of interrupt.

v2: fix coding style on register definition

Cc: Radhakrishna Sripada <radhakrishna.srip...@intel.com>
Cc: Daniele Spurio Ceraolo <daniele.ceraolospu...@intel.com>
Cc: Matt Roper <matthew.d.ro...@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demar...@intel.com>
Reviewed-by: José Roberto de Souza <jose.so...@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c |  4 +++
 drivers/gpu/drm/i915/i915_irq.c     | 56 +++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/i915_reg.h     |  4 +++
 3 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 9ca94a435b75..b76a61ec2190 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -492,6 +492,10 @@ static int i915_interrupt_info(struct seq_file *m, void 
*data)
                seq_printf(m, "PCU interrupt enable:\t%08x\n",
                           I915_READ(GEN8_PCU_IER));
        } else if (INTEL_GEN(dev_priv) >= 11) {
+               if (HAS_MASTER_UNIT_IRQ(dev_priv))
+                       seq_printf(m, "Master Unit Interrupt Control:  %08x\n",
+                                  I915_READ(DG1_MSTR_UNIT_INTR));
+
                seq_printf(m, "Master Interrupt Control:  %08x\n",
                           I915_READ(GEN11_GFX_MSTR_IRQ));
 
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 562b43ed077f..4c9d0a4a2476 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2584,6 +2584,46 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg)
                                   gen11_master_intr_enable);
 }
 
+static u32 dg1_master_intr_disable_and_ack(void __iomem * const regs)
+{
+       u32 val;
+
+       /* First disable interrupts */
+       raw_reg_write(regs, DG1_MSTR_UNIT_INTR, 0);
+
+       /* Get the indication levels and ack the master unit */
+       val = raw_reg_read(regs, DG1_MSTR_UNIT_INTR);
+       if (unlikely(!val))
+               return 0;
+
+       raw_reg_write(regs, DG1_MSTR_UNIT_INTR, val);
+
+       /*
+        * Now with master disabled, get a sample of level indications
+        * for this interrupt and ack them right away - we keep GEN11_MASTER_IRQ
+        * out as this bit doesn't exist anymore for DG1
+        */
+       val = raw_reg_read(regs, GEN11_GFX_MSTR_IRQ) & ~GEN11_MASTER_IRQ;
+       if (unlikely(!val))
+               return 0;
+
+       raw_reg_write(regs, GEN11_GFX_MSTR_IRQ, val);
+
+       return val;
+}
+
+static inline void dg1_master_intr_enable(void __iomem * const regs)
+{
+       raw_reg_write(regs, DG1_MSTR_UNIT_INTR, DG1_MSTR_IRQ);
+}
+
+static irqreturn_t dg1_irq_handler(int irq, void *arg)
+{
+       return __gen11_irq_handler(arg,
+                                  dg1_master_intr_disable_and_ack,
+                                  dg1_master_intr_enable);
+}
+
 /* Called from drm generic code, passed 'crtc' which
  * we use as a pipe index
  */
@@ -2920,7 +2960,10 @@ static void gen11_irq_reset(struct drm_i915_private 
*dev_priv)
 {
        struct intel_uncore *uncore = &dev_priv->uncore;
 
-       gen11_master_intr_disable(dev_priv->uncore.regs);
+       if (HAS_MASTER_UNIT_IRQ(dev_priv))
+               dg1_master_intr_disable_and_ack(dev_priv->uncore.regs);
+       else
+               gen11_master_intr_disable(dev_priv->uncore.regs);
 
        gen11_gt_irq_reset(&dev_priv->gt);
        gen11_display_irq_reset(dev_priv);
@@ -3517,8 +3560,13 @@ static void gen11_irq_postinstall(struct 
drm_i915_private *dev_priv)
 
        I915_WRITE(GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE);
 
-       gen11_master_intr_enable(uncore->regs);
-       POSTING_READ(GEN11_GFX_MSTR_IRQ);
+       if (HAS_MASTER_UNIT_IRQ(dev_priv)) {
+               dg1_master_intr_enable(uncore->regs);
+               POSTING_READ(DG1_MSTR_UNIT_INTR);
+       } else {
+               gen11_master_intr_enable(uncore->regs);
+               POSTING_READ(GEN11_GFX_MSTR_IRQ);
+       }
 }
 
 static void cherryview_irq_postinstall(struct drm_i915_private *dev_priv)
@@ -4043,6 +4091,8 @@ static irq_handler_t intel_irq_handler(struct 
drm_i915_private *dev_priv)
                else
                        return i8xx_irq_handler;
        } else {
+               if (HAS_MASTER_UNIT_IRQ(dev_priv))
+                       return dg1_irq_handler;
                if (INTEL_GEN(dev_priv) >= 11)
                        return gen11_irq_handler;
                else if (INTEL_GEN(dev_priv) >= 8)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9d6536afc94b..ed1b8151ce72 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7723,6 +7723,10 @@ enum {
 #define  GEN11_GT_DW1_IRQ              (1 << 1)
 #define  GEN11_GT_DW0_IRQ              (1 << 0)
 
+#define DG1_MSTR_UNIT_INTR             _MMIO(0x190008)
+#define   DG1_MSTR_IRQ                 REG_BIT(31)
+#define   DG1_MSTR_UNIT(u)             REG_BIT(u)
+
 #define GEN11_DISPLAY_INT_CTL          _MMIO(0x44200)
 #define  GEN11_DISPLAY_IRQ_ENABLE      (1 << 31)
 #define  GEN11_AUDIO_CODEC_IRQ         (1 << 24)
-- 
2.26.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to