Commit 97b492f5 authored by Lucas De Marchi's avatar Lucas De Marchi
Browse files

drm/i915/dg1: add support for the master unit interrupt



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.sripada@intel.com>
Cc: Daniele Spurio Ceraolo <daniele.ceraolospurio@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: default avatarJosé Roberto de Souza <jose.souza@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200713182321.12390-4-lucas.demarchi@intel.com
parent fd38cdb8
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -495,6 +495,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));

+53 −3
Original line number Diff line number Diff line
@@ -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,6 +2960,9 @@ static void gen11_irq_reset(struct drm_i915_private *dev_priv)
{
	struct intel_uncore *uncore = &dev_priv->uncore;

	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);
@@ -3517,9 +3560,14 @@ static void gen11_irq_postinstall(struct drm_i915_private *dev_priv)

	I915_WRITE(GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE);

	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)
+4 −0
Original line number Diff line number Diff line
@@ -7733,6 +7733,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)