All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ville Syrjala <ville.syrjala@linux.intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH v2 4/5] drm/i915: Finish the irq ack+handler split for ilk+
Date: Wed, 26 Jun 2019 21:03:43 +0300	[thread overview]
Message-ID: <20190626180344.26314-5-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <20190626180344.26314-1-ville.syrjala@linux.intel.com>

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

All the older platforms already follow the ack+handler apporoach
for interrupts. Convert ilk+ as well. As the number of registers
involved is rather large we'll introduce a few more structs to
carry the register values around.

The unfortunate side effect of this is some growth:
add/remove: 5/0 grow/shrink: 3/5 up/down: 1933/-1052 (881)
Function                                     old     new   delta
gen8_de_irq_ack                                -    1229   +1229
ironlake_irq_handler                        2808    2973    +165
cpt_irq_ack                                    -     117    +117
ibx_hpd_irq_ack.isra                           -     106    +106
hsw_psr_irq_ack                                -      91     +91
gen8_irq_handler                             204     291     +87
ilk_hpd_irq_ack.isra                           -      82     +82
gen11_irq_handler                            846     902     +56
cpt_irq_handler                              511     440     -71
ilk_hpd_irq_handler                          195     114     -81
ibx_hpd_irq_handler                          235     118    -117
icp_irq_handler                              417     250    -167
gen8_de_irq_handler                         2198    1582    -616
Total: Before=33251, After=34132, chg +2.65%

but we'll fix that up afterwards.

v2: Drop the zero initialization (Chris)
    Drop the gen11+ check for GEN11_DE_HPD_IRQ as
    the bit was mbz before (Chris)
    Adapt to PCH_MCC changes

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_irq.c | 442 +++++++++++++++++++++-----------
 1 file changed, 293 insertions(+), 149 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index bc6f814aa5a1..b83c9d71d630 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2361,6 +2361,13 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
 	return ret;
 }
 
+struct ilk_de_irq_regs {
+	u32 iir;
+	u32 err_int; /* ivb/hsw */
+	u32 psr_iir; /* hsw */
+	struct hpd_irq_regs hpd;
+};
+
 struct pch_irq_regs {
 	u32 iir;
 	u32 serr_int; /* cpt/lpt */
@@ -2467,9 +2474,17 @@ static void ibx_irq_handler(struct drm_i915_private *dev_priv,
 		intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_B);
 }
 
-static void ivb_err_int_handler(struct drm_i915_private *dev_priv)
+static void ivb_err_int_ack(struct drm_i915_private *dev_priv,
+			    struct ilk_de_irq_regs *de)
 {
-	u32 err_int = I915_READ(GEN7_ERR_INT);
+	de->err_int = I915_READ(GEN7_ERR_INT);
+	I915_WRITE(GEN7_ERR_INT, de->err_int);
+}
+
+static void ivb_err_int_handler(struct drm_i915_private *dev_priv,
+				const struct ilk_de_irq_regs *de)
+{
+	u32 err_int = de->err_int;
 	enum pipe pipe;
 
 	if (err_int & ERR_INT_POISON)
@@ -2486,8 +2501,6 @@ static void ivb_err_int_handler(struct drm_i915_private *dev_priv)
 				hsw_pipe_crc_irq_handler(dev_priv, pipe);
 		}
 	}
-
-	I915_WRITE(GEN7_ERR_INT, err_int);
 }
 
 static void cpt_serr_int_ack(struct drm_i915_private *dev_priv,
@@ -2665,17 +2678,38 @@ static void ilk_hpd_irq_handler(struct drm_i915_private *dev_priv,
 	intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
 }
 
+static void ilk_display_irq_ack(struct drm_i915_private *dev_priv,
+				struct ilk_de_irq_regs *de,
+				struct pch_irq_regs *pch)
+{
+	de->hpd.hotplug_trigger = de->iir & DE_DP_A_HOTPLUG;
+
+	if (de->hpd.hotplug_trigger)
+		ilk_hpd_irq_ack(dev_priv, &de->hpd);
+
+	/* check event from PCH */
+	if (de->iir & DE_PCH_EVENT) {
+		pch->iir = I915_READ(SDEIIR);
+
+		if (HAS_PCH_CPT(dev_priv))
+			cpt_irq_ack(dev_priv, pch);
+		else
+			ibx_irq_ack(dev_priv, pch);
+
+		/* should clear PCH hotplug event before clear CPU irq */
+		I915_WRITE(SDEIIR, pch->iir);
+	}
+}
+
 static void ilk_display_irq_handler(struct drm_i915_private *dev_priv,
-				    u32 de_iir)
+				    const struct ilk_de_irq_regs *de,
+				    const struct pch_irq_regs *pch)
 {
-	struct hpd_irq_regs hpd;
+	u32 de_iir = de->iir;
 	enum pipe pipe;
 
-	hpd.hotplug_trigger = de_iir & DE_DP_A_HOTPLUG;
-	if (hpd.hotplug_trigger) {
-		ilk_hpd_irq_ack(dev_priv, &hpd);
-		ilk_hpd_irq_handler(dev_priv, &hpd, hpd_ilk);
-	}
+	if (de->hpd.hotplug_trigger)
+		ilk_hpd_irq_handler(dev_priv, &de->hpd, hpd_ilk);
 
 	if (de_iir & DE_AUX_CHANNEL_A)
 		dp_aux_irq_handler(dev_priv);
@@ -2699,47 +2733,65 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv,
 
 	/* check event from PCH */
 	if (de_iir & DE_PCH_EVENT) {
-		struct pch_irq_regs pch;
-
-		pch.iir = I915_READ(SDEIIR);
-
-		if (HAS_PCH_CPT(dev_priv)) {
-			cpt_irq_ack(dev_priv, &pch);
-			cpt_irq_handler(dev_priv, &pch);
-		} else {
-			ibx_irq_ack(dev_priv, &pch);
-			ibx_irq_handler(dev_priv, &pch);
-		}
-
-		/* should clear PCH hotplug event before clear CPU irq */
-		I915_WRITE(SDEIIR, pch.iir);
+		if (HAS_PCH_CPT(dev_priv))
+			cpt_irq_handler(dev_priv, pch);
+		else
+			ibx_irq_handler(dev_priv, pch);
 	}
 
 	if (IS_GEN(dev_priv, 5) && de_iir & DE_PCU_EVENT)
 		ironlake_rps_change_irq_handler(dev_priv);
 }
 
+static void hsw_psr_irq_ack(struct drm_i915_private *dev_priv,
+			    u32 *psr_iir)
+{
+	*psr_iir = I915_READ(EDP_PSR_IIR);
+	if (*psr_iir)
+		I915_WRITE(EDP_PSR_IIR, *psr_iir);
+}
+
+static void ivb_display_irq_ack(struct drm_i915_private *dev_priv,
+				struct ilk_de_irq_regs *de,
+				struct pch_irq_regs *pch)
+{
+	de->hpd.hotplug_trigger = de->iir & DE_DP_A_HOTPLUG_IVB;
+
+	if (de->hpd.hotplug_trigger)
+		ilk_hpd_irq_ack(dev_priv, &de->hpd);
+
+	if (de->iir & DE_ERR_INT_IVB)
+		ivb_err_int_ack(dev_priv, de);
+
+	if (de->iir & DE_EDP_PSR_INT_HSW)
+		hsw_psr_irq_ack(dev_priv, &de->psr_iir);
+
+	/* check event from PCH */
+	if (!HAS_PCH_NOP(dev_priv) && de->iir & DE_PCH_EVENT_IVB) {
+		pch->iir = I915_READ(SDEIIR);
+
+		cpt_irq_ack(dev_priv, pch);
+
+		/* clear PCH hotplug event before clear CPU irq */
+		I915_WRITE(SDEIIR, pch->iir);
+	}
+}
+
 static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
-				    u32 de_iir)
+				    const struct ilk_de_irq_regs *de,
+				    const struct pch_irq_regs *pch)
 {
-	struct hpd_irq_regs hpd;
+	u32 de_iir = de->iir;
 	enum pipe pipe;
 
-	hpd.hotplug_trigger = de_iir & DE_DP_A_HOTPLUG_IVB;
-	if (hpd.hotplug_trigger)  {
-		ilk_hpd_irq_ack(dev_priv, &hpd);
-		ilk_hpd_irq_handler(dev_priv, &hpd, hpd_ivb);
-	}
+	if (de->hpd.hotplug_trigger)
+		ilk_hpd_irq_handler(dev_priv, &de->hpd, hpd_ivb);
 
 	if (de_iir & DE_ERR_INT_IVB)
-		ivb_err_int_handler(dev_priv);
-
-	if (de_iir & DE_EDP_PSR_INT_HSW) {
-		u32 psr_iir = I915_READ(EDP_PSR_IIR);
+		ivb_err_int_handler(dev_priv, de);
 
-		intel_psr_irq_handler(dev_priv, psr_iir);
-		I915_WRITE(EDP_PSR_IIR, psr_iir);
-	}
+	if (de_iir & DE_EDP_PSR_INT_HSW)
+		intel_psr_irq_handler(dev_priv, de->psr_iir);
 
 	if (de_iir & DE_AUX_CHANNEL_A_IVB)
 		dp_aux_irq_handler(dev_priv);
@@ -2748,22 +2800,13 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
 		intel_opregion_asle_intr(dev_priv);
 
 	for_each_pipe(dev_priv, pipe) {
-		if (de_iir & (DE_PIPE_VBLANK_IVB(pipe)))
+		if (de_iir & DE_PIPE_VBLANK_IVB(pipe))
 			drm_handle_vblank(&dev_priv->drm, pipe);
 	}
 
 	/* check event from PCH */
-	if (!HAS_PCH_NOP(dev_priv) && (de_iir & DE_PCH_EVENT_IVB)) {
-		struct pch_irq_regs pch;
-
-		pch.iir = I915_READ(SDEIIR);
-
-		cpt_irq_ack(dev_priv, &pch);
-		cpt_irq_handler(dev_priv, &pch);
-
-		/* clear PCH hotplug event before clear CPU irq */
-		I915_WRITE(SDEIIR, pch.iir);
-	}
+	if (!HAS_PCH_NOP(dev_priv) && de_iir & DE_PCH_EVENT_IVB)
+		cpt_irq_handler(dev_priv, pch);
 }
 
 /*
@@ -2777,7 +2820,9 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
 static irqreturn_t ironlake_irq_handler(int irq, void *arg)
 {
 	struct drm_i915_private *dev_priv = arg;
-	u32 de_iir, gt_iir, de_ier, sde_ier = 0;
+	u32 gt_iir, pm_iir = 0, de_ier, sde_ier = 0;
+	struct ilk_de_irq_regs de;
+	struct pch_irq_regs pch;
 	irqreturn_t ret = IRQ_NONE;
 
 	if (!intel_irqs_enabled(dev_priv))
@@ -2803,8 +2848,30 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
 	/* Find, clear, then process each source of interrupt */
 
 	gt_iir = I915_READ(GTIIR);
-	if (gt_iir) {
+	de.iir = I915_READ(DEIIR);
+	if (INTEL_GEN(dev_priv) >= 6)
+		pm_iir = I915_READ(GEN6_PMIIR);
+
+	if (gt_iir)
 		I915_WRITE(GTIIR, gt_iir);
+
+	if (de.iir) {
+		if (INTEL_GEN(dev_priv) >= 7)
+			ivb_display_irq_ack(dev_priv, &de, &pch);
+		else
+			ilk_display_irq_ack(dev_priv, &de, &pch);
+
+		I915_WRITE(DEIIR, de.iir);
+	}
+
+	if (pm_iir)
+		I915_WRITE(GEN6_PMIIR, pm_iir);
+
+	I915_WRITE(DEIER, de_ier);
+	if (!HAS_PCH_NOP(dev_priv))
+		I915_WRITE(SDEIER, sde_ier);
+
+	if (gt_iir) {
 		ret = IRQ_HANDLED;
 		if (INTEL_GEN(dev_priv) >= 6)
 			snb_gt_irq_handler(dev_priv, gt_iir);
@@ -2812,29 +2879,19 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
 			ilk_gt_irq_handler(dev_priv, gt_iir);
 	}
 
-	de_iir = I915_READ(DEIIR);
-	if (de_iir) {
-		I915_WRITE(DEIIR, de_iir);
+	if (de.iir) {
 		ret = IRQ_HANDLED;
 		if (INTEL_GEN(dev_priv) >= 7)
-			ivb_display_irq_handler(dev_priv, de_iir);
+			ivb_display_irq_handler(dev_priv, &de, &pch);
 		else
-			ilk_display_irq_handler(dev_priv, de_iir);
+			ilk_display_irq_handler(dev_priv, &de, &pch);
 	}
 
-	if (INTEL_GEN(dev_priv) >= 6) {
-		u32 pm_iir = I915_READ(GEN6_PMIIR);
-		if (pm_iir) {
-			I915_WRITE(GEN6_PMIIR, pm_iir);
-			ret = IRQ_HANDLED;
-			gen6_rps_irq_handler(dev_priv, pm_iir);
-		}
+	if (pm_iir) {
+		ret = IRQ_HANDLED;
+		gen6_rps_irq_handler(dev_priv, pm_iir);
 	}
 
-	I915_WRITE(DEIER, de_ier);
-	if (!HAS_PCH_NOP(dev_priv))
-		I915_WRITE(SDEIER, sde_ier);
-
 	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
 	enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
 
@@ -2861,37 +2918,129 @@ static void bxt_hpd_irq_handler(struct drm_i915_private *dev_priv,
 	intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
 }
 
-static void gen11_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 iir)
+struct gen8_de_irq_regs {
+	u32 pipe_iir[I915_MAX_PIPES];
+	u32 port_iir;
+	u32 misc_iir;
+	u32 psr_iir;
+	u32 hpd_iir; /* icl+ */
+	struct hpd_irq_regs ddi;
+	struct hpd_irq_regs tc, tbt; /* icl+ */
+};
+
+static void gen11_hpd_irq_ack(struct drm_i915_private *dev_priv,
+			      struct gen8_de_irq_regs *de)
 {
-	struct hpd_irq_regs tc;
-	struct hpd_irq_regs tbt;
-	u32 pin_mask = 0, long_mask = 0;
+	de->tc.hotplug_trigger = de->hpd_iir & GEN11_DE_TC_HOTPLUG_MASK;
+	de->tbt.hotplug_trigger = de->hpd_iir & GEN11_DE_TBT_HOTPLUG_MASK;
+
+	if (de->tc.hotplug_trigger) {
+		de->tc.dig_hotplug_reg = I915_READ(GEN11_TC_HOTPLUG_CTL);
+		I915_WRITE(GEN11_TC_HOTPLUG_CTL, de->tc.dig_hotplug_reg);
+	}
 
-	tc.hotplug_trigger = iir & GEN11_DE_TC_HOTPLUG_MASK;
-	tbt.hotplug_trigger = iir & GEN11_DE_TBT_HOTPLUG_MASK;
+	if (de->tbt.hotplug_trigger) {
+		de->tbt.dig_hotplug_reg = I915_READ(GEN11_TBT_HOTPLUG_CTL);
+		I915_WRITE(GEN11_TBT_HOTPLUG_CTL, de->tbt.dig_hotplug_reg);
+	}
+}
 
-	if (tc.hotplug_trigger) {
-		tc.dig_hotplug_reg = I915_READ(GEN11_TC_HOTPLUG_CTL);
-		I915_WRITE(GEN11_TC_HOTPLUG_CTL, tc.dig_hotplug_reg);
+static void gen11_hpd_irq_handler(struct drm_i915_private *dev_priv,
+				  const struct gen8_de_irq_regs *de)
+{
+	u32 pin_mask = 0, long_mask = 0;
 
+	if (de->tc.hotplug_trigger) {
 		intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
-				   &tc, hpd_gen11,
+				   &de->tc, hpd_gen11,
 				   gen11_port_hotplug_long_detect);
 	}
 
-	if (tbt.hotplug_trigger) {
-		tbt.dig_hotplug_reg = I915_READ(GEN11_TBT_HOTPLUG_CTL);
-		I915_WRITE(GEN11_TBT_HOTPLUG_CTL, tbt.dig_hotplug_reg);
-
+	if (de->tbt.hotplug_trigger) {
 		intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
-				   &tbt, hpd_gen11,
+				   &de->tbt, hpd_gen11,
 				   gen11_port_hotplug_long_detect);
 	}
 
 	if (pin_mask)
 		intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
 	else
-		DRM_ERROR("Unexpected DE HPD interrupt 0x%08x\n", iir);
+		DRM_ERROR("Unexpected DE HPD interrupt 0x%08x\n", de->hpd_iir);
+}
+
+static void
+gen8_de_irq_ack(struct drm_i915_private *dev_priv, u32 master_ctl,
+		struct gen8_de_irq_regs *de, struct pch_irq_regs *pch)
+{
+	enum pipe pipe;
+
+	if (master_ctl & GEN8_DE_MISC_IRQ) {
+		de->misc_iir = I915_READ(GEN8_DE_MISC_IIR);
+
+		if (de->misc_iir) {
+			if (de->misc_iir & GEN8_DE_EDP_PSR)
+				hsw_psr_irq_ack(dev_priv, &de->psr_iir);
+
+			I915_WRITE(GEN8_DE_MISC_IIR, de->misc_iir);
+		}
+	}
+
+	if (master_ctl & GEN11_DE_HPD_IRQ) {
+		de->hpd_iir = I915_READ(GEN11_DE_HPD_IIR);
+
+		if (de->hpd_iir) {
+			gen11_hpd_irq_ack(dev_priv, de);
+
+			I915_WRITE(GEN11_DE_HPD_IIR, de->hpd_iir);
+		}
+	}
+
+	if (master_ctl & GEN8_DE_PORT_IRQ) {
+		de->port_iir = I915_READ(GEN8_DE_PORT_IIR);
+
+		if (de->port_iir) {
+			if (IS_GEN9_LP(dev_priv)) {
+				de->ddi.hotplug_trigger = de->port_iir & BXT_DE_PORT_HOTPLUG_MASK;
+				if (de->ddi.hotplug_trigger)
+					bxt_hpd_irq_ack(dev_priv, &de->ddi);
+			} else if (IS_BROADWELL(dev_priv)) {
+				de->ddi.hotplug_trigger = de->port_iir & GEN8_PORT_DP_A_HOTPLUG;
+				if (de->ddi.hotplug_trigger)
+					ilk_hpd_irq_ack(dev_priv, &de->ddi);
+			}
+
+			I915_WRITE(GEN8_DE_PORT_IIR, de->port_iir);
+		}
+	}
+
+	for_each_pipe(dev_priv, pipe) {
+		if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe)))
+			continue;
+
+		de->pipe_iir[pipe] = I915_READ(GEN8_DE_PIPE_IIR(pipe));
+		if (de->pipe_iir[pipe])
+			I915_WRITE(GEN8_DE_PIPE_IIR(pipe), de->pipe_iir[pipe]);
+	}
+
+	if (HAS_PCH_SPLIT(dev_priv) && !HAS_PCH_NOP(dev_priv) &&
+	    master_ctl & GEN8_DE_PCH_IRQ) {
+		/*
+		 * FIXME(BDW): Assume for now that the new interrupt handling
+		 * scheme also closed the SDE interrupt handling race we've seen
+		 * on older pch-split platforms. But this needs testing.
+		 */
+		pch->iir = I915_READ(SDEIIR);
+		if (pch->iir) {
+			if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
+				icp_irq_ack(dev_priv, pch);
+			else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT)
+				spt_irq_ack(dev_priv, pch);
+			else
+				cpt_irq_ack(dev_priv, pch);
+
+			I915_WRITE(SDEIIR, pch->iir);
+		}
+	}
 }
 
 static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv)
@@ -2922,57 +3071,51 @@ static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv)
 }
 
 static irqreturn_t
-gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
+gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl,
+		    const struct gen8_de_irq_regs *de,
+		    const struct pch_irq_regs *pch)
 {
 	irqreturn_t ret = IRQ_NONE;
-	u32 iir;
 	enum pipe pipe;
 
 	if (master_ctl & GEN8_DE_MISC_IRQ) {
-		iir = I915_READ(GEN8_DE_MISC_IIR);
+		u32 iir = de->misc_iir;
+
 		if (iir) {
 			bool found = false;
 
-			I915_WRITE(GEN8_DE_MISC_IIR, iir);
-			ret = IRQ_HANDLED;
-
 			if (iir & GEN8_DE_MISC_GSE) {
 				intel_opregion_asle_intr(dev_priv);
 				found = true;
 			}
 
 			if (iir & GEN8_DE_EDP_PSR) {
-				u32 psr_iir = I915_READ(EDP_PSR_IIR);
-
-				intel_psr_irq_handler(dev_priv, psr_iir);
-				I915_WRITE(EDP_PSR_IIR, psr_iir);
+				intel_psr_irq_handler(dev_priv, de->psr_iir);
 				found = true;
 			}
 
 			if (!found)
 				DRM_ERROR("Unexpected DE Misc interrupt\n");
-		}
-		else
+		} else {
 			DRM_ERROR("The master control interrupt lied (DE MISC)!\n");
+		}
 	}
 
-	if (INTEL_GEN(dev_priv) >= 11 && (master_ctl & GEN11_DE_HPD_IRQ)) {
-		iir = I915_READ(GEN11_DE_HPD_IIR);
-		if (iir) {
-			I915_WRITE(GEN11_DE_HPD_IIR, iir);
-			ret = IRQ_HANDLED;
-			gen11_hpd_irq_handler(dev_priv, iir);
-		} else {
+	if (master_ctl & GEN11_DE_HPD_IRQ) {
+		u32 iir = de->hpd_iir;
+
+		if (iir)
+			gen11_hpd_irq_handler(dev_priv, de);
+		else
 			DRM_ERROR("The master control interrupt lied, (DE HPD)!\n");
-		}
 	}
 
 	if (master_ctl & GEN8_DE_PORT_IRQ) {
-		iir = I915_READ(GEN8_DE_PORT_IIR);
+		u32 iir = de->port_iir;
+
 		if (iir) {
 			bool found = false;
 
-			I915_WRITE(GEN8_DE_PORT_IIR, iir);
 			ret = IRQ_HANDLED;
 
 			if (iir & gen8_de_port_aux_mask(dev_priv)) {
@@ -2980,24 +3123,12 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
 				found = true;
 			}
 
-			if (IS_GEN9_LP(dev_priv)) {
-				struct hpd_irq_regs ddi;
-
-				ddi.hotplug_trigger = iir & BXT_DE_PORT_HOTPLUG_MASK;
-				if (ddi.hotplug_trigger) {
-					bxt_hpd_irq_ack(dev_priv, &ddi);
-					bxt_hpd_irq_handler(dev_priv, &ddi, hpd_bxt);
-					found = true;
-				}
-			} else if (IS_BROADWELL(dev_priv)) {
-				struct hpd_irq_regs ddi;
-
-				ddi.hotplug_trigger = iir & GEN8_PORT_DP_A_HOTPLUG;
-				if (ddi.hotplug_trigger) {
-					ilk_hpd_irq_ack(dev_priv, &ddi);
-					ilk_hpd_irq_handler(dev_priv, &ddi, hpd_bdw);
-					found = true;
-				}
+			if (IS_GEN9_LP(dev_priv) && de->ddi.hotplug_trigger) {
+				bxt_hpd_irq_handler(dev_priv, &de->ddi, hpd_bxt);
+				found = true;
+			} else if (IS_BROADWELL(dev_priv) && de->ddi.hotplug_trigger) {
+				ilk_hpd_irq_handler(dev_priv, &de->ddi, hpd_bdw);
+				found = true;
 			}
 
 			if (IS_GEN9_LP(dev_priv) && (iir & BXT_DE_PORT_GMBUS)) {
@@ -3007,25 +3138,24 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
 
 			if (!found)
 				DRM_ERROR("Unexpected DE Port interrupt\n");
-		}
-		else
+		} else {
 			DRM_ERROR("The master control interrupt lied (DE PORT)!\n");
+		}
 	}
 
 	for_each_pipe(dev_priv, pipe) {
+		u32 iir = de->pipe_iir[pipe];
 		u32 fault_errors;
 
 		if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe)))
 			continue;
 
-		iir = I915_READ(GEN8_DE_PIPE_IIR(pipe));
 		if (!iir) {
 			DRM_ERROR("The master control interrupt lied (DE PIPE)!\n");
 			continue;
 		}
 
 		ret = IRQ_HANDLED;
-		I915_WRITE(GEN8_DE_PIPE_IIR(pipe), iir);
 
 		if (iir & GEN8_PIPE_VBLANK)
 			drm_handle_vblank(&dev_priv->drm, pipe);
@@ -3045,31 +3175,24 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
 
 	if (HAS_PCH_SPLIT(dev_priv) && !HAS_PCH_NOP(dev_priv) &&
 	    master_ctl & GEN8_DE_PCH_IRQ) {
-		struct pch_irq_regs pch;
+		u32 iir = pch->iir;
 
 		/*
 		 * FIXME(BDW): Assume for now that the new interrupt handling
 		 * scheme also closed the SDE interrupt handling race we've seen
 		 * on older pch-split platforms. But this needs testing.
 		 */
-		pch.iir = I915_READ(SDEIIR);
-		if (pch.iir) {
-			I915_WRITE(SDEIIR, pch.iir);
+		if (iir) {
 			ret = IRQ_HANDLED;
 
-			if (INTEL_PCH_TYPE(dev_priv) >= PCH_MCC) {
-				icp_irq_ack(dev_priv, &pch);
-				icp_irq_handler(dev_priv, &pch, hpd_mcc);
-			} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) {
-				icp_irq_ack(dev_priv, &pch);
-				icp_irq_handler(dev_priv, &pch, hpd_icp);
-			} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT) {
-				spt_irq_ack(dev_priv, &pch);
-				spt_irq_handler(dev_priv, &pch);
-			} else {
-				cpt_irq_ack(dev_priv, &pch);
-				cpt_irq_handler(dev_priv, &pch);
-			}
+			if (INTEL_PCH_TYPE(dev_priv) >= PCH_MCC)
+				icp_irq_handler(dev_priv, pch, hpd_mcc);
+			else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
+				icp_irq_handler(dev_priv, pch, hpd_icp);
+			else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT)
+				spt_irq_handler(dev_priv, pch);
+			else
+				cpt_irq_handler(dev_priv, pch);
 		} else {
 			/*
 			 * Like on previous PCH there seems to be something
@@ -3106,6 +3229,8 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
 	void __iomem * const regs = dev_priv->uncore.regs;
 	u32 master_ctl;
 	u32 gt_iir[4];
+	struct gen8_de_irq_regs de;
+	struct pch_irq_regs pch;
 
 	if (!intel_irqs_enabled(dev_priv))
 		return IRQ_NONE;
@@ -3122,7 +3247,7 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
 	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
 	if (master_ctl & ~GEN8_GT_IRQS) {
 		disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
-		gen8_de_irq_handler(dev_priv, master_ctl);
+		gen8_de_irq_ack(dev_priv, master_ctl, &de, &pch);
 		enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
 	}
 
@@ -3130,6 +3255,12 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
 
 	gen8_gt_irq_handler(dev_priv, master_ctl, gt_iir);
 
+	if (master_ctl & ~GEN8_GT_IRQS) {
+		disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
+		gen8_de_irq_handler(dev_priv, master_ctl, &de, &pch);
+		enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
+	}
+
 	return IRQ_HANDLED;
 }
 
@@ -3305,6 +3436,9 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg)
 	void __iomem * const regs = i915->uncore.regs;
 	u32 master_ctl;
 	u32 gu_misc_iir;
+	u32 disp_ctl;
+	struct gen8_de_irq_regs de;
+	struct pch_irq_regs pch;
 
 	if (!intel_irqs_enabled(i915))
 		return IRQ_NONE;
@@ -3320,14 +3454,14 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg)
 
 	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
 	if (master_ctl & GEN11_DISPLAY_IRQ) {
-		const u32 disp_ctl = raw_reg_read(regs, GEN11_DISPLAY_INT_CTL);
+		disp_ctl = raw_reg_read(regs, GEN11_DISPLAY_INT_CTL);
 
 		disable_rpm_wakeref_asserts(&i915->runtime_pm);
 		/*
 		 * GEN11_DISPLAY_INT_CTL has same format as GEN8_MASTER_IRQ
 		 * for the display related bits.
 		 */
-		gen8_de_irq_handler(i915, disp_ctl);
+		gen8_de_irq_ack(i915, disp_ctl, &de, &pch);
 		enable_rpm_wakeref_asserts(&i915->runtime_pm);
 	}
 
@@ -3335,6 +3469,16 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg)
 
 	gen11_master_intr_enable(regs);
 
+	if (master_ctl & GEN11_DISPLAY_IRQ) {
+		disable_rpm_wakeref_asserts(&i915->runtime_pm);
+		/*
+		 * GEN11_DISPLAY_INT_CTL has same format as GEN8_MASTER_IRQ
+		 * for the display related bits.
+		 */
+		gen8_de_irq_handler(i915, disp_ctl, &de, &pch);
+		enable_rpm_wakeref_asserts(&i915->runtime_pm);
+	}
+
 	gen11_gu_misc_irq_handler(i915, gu_misc_iir);
 
 	return IRQ_HANDLED;
-- 
2.21.0

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

  parent reply	other threads:[~2019-06-26 18:04 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-26 18:03 [PATCH v2 0/5] Finish the ack+handler split for irq handler Ville Syrjala
2019-06-26 18:03 ` [PATCH v2 1/5] drm/i915: Add gen8_de_pipe_fault_mask() Ville Syrjala
2019-06-26 18:03 ` [PATCH v2 2/5] drm/i915: Introduce struct hpd_irq_regs Ville Syrjala
2019-06-26 18:03 ` [PATCH v2 3/5] drm/i915: Split pch irq handling to ack+handler Ville Syrjala
2019-06-26 18:03 ` Ville Syrjala [this message]
2019-06-26 18:03 ` [PATCH v2 5/5] drm/i915: Use raw_reg_read()/write() in ilk+ irq handlers Ville Syrjala
2019-06-26 20:10 ` ✓ Fi.CI.BAT: success for Finish the ack+handler split for irq handler Patchwork
2019-06-27  8:06 ` ✓ Fi.CI.IGT: " 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=20190626180344.26314-5-ville.syrjala@linux.intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.