[Intel-gfx] [PATCH v2 5/5] drm/i915: Use raw_reg_read()/write() in ilk+ irq handlers
Ville Syrjala
ville.syrjala at linux.intel.com
Wed Jun 26 18:03:44 UTC 2019
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
Optimize the irq handlers a bit by switching to the raw register
access functions.
It seems we can go fully lockless due to
WaSerializeKmdDisplayAccess, so in order to protect against that
we grab the irq_lock around the ack. I *think* that should be
sufficient as that's held whenever we otherwise massage the irq
registers. The w/a database lists this only for snb/ivb/hsw, so
maybe we don't even need it for bdw+? But I was too chicken to
leave it out.
This leads to some shrinkage:
add/remove: 1/5 grow/shrink: 3/2 up/down: 183/-1307 (-1124)
Function old new delta
gen8_gt_irq_ack - 104 +104
gen8_irq_handler 291 334 +43
gen11_irq_handler 902 935 +33
cherryview_irq_handler 636 639 +3
ilk_hpd_irq_ack.isra 82 - -82
hsw_psr_irq_ack 91 - -91
gen8_gt_irq_ack.isra 104 - -104
ibx_hpd_irq_ack.isra 106 - -106
cpt_irq_ack 117 - -117
ironlake_irq_handler 2973 2700 -273
gen8_de_irq_ack 1229 695 -534
Total: Before=34132, After=33008, chg -3.29%
so we're now below the original pre-ack/handle split numbers.
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
drivers/gpu/drm/i915/i915_irq.c | 220 +++++++++++++++++---------------
1 file changed, 119 insertions(+), 101 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b83c9d71d630..2ed715d4bddd 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1577,11 +1577,9 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir)
tasklet_hi_schedule(&engine->execlists.tasklet);
}
-static void gen8_gt_irq_ack(struct drm_i915_private *i915,
+static void gen8_gt_irq_ack(void __iomem * const regs,
u32 master_ctl, u32 gt_iir[4])
{
- void __iomem * const regs = i915->uncore.regs;
-
#define GEN8_GT_IRQS (GEN8_GT_RCS_IRQ | \
GEN8_GT_BCS_IRQ | \
GEN8_GT_VCS0_IRQ | \
@@ -2293,6 +2291,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
do {
+ void __iomem * const regs = dev_priv->uncore.regs;
u32 master_ctl, iir;
u32 pipe_stats[I915_MAX_PIPES] = {};
u32 hotplug_status = 0;
@@ -2324,7 +2323,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
ier = I915_READ(VLV_IER);
I915_WRITE(VLV_IER, 0);
- gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
+ gen8_gt_irq_ack(regs, master_ctl, gt_iir);
if (iir & I915_DISPLAY_PORT_INTERRUPT)
hotplug_status = i9xx_hpd_irq_ack(dev_priv);
@@ -2381,7 +2380,7 @@ struct pch_irq_regs {
};
};
-static void ibx_hpd_irq_ack(struct drm_i915_private *dev_priv,
+static void ibx_hpd_irq_ack(void __iomem * const regs,
struct hpd_irq_regs *hpd)
{
/*
@@ -2390,7 +2389,7 @@ static void ibx_hpd_irq_ack(struct drm_i915_private *dev_priv,
* zero. Not acking leads to "The master control interrupt lied (SDE)!"
* errors.
*/
- hpd->dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
+ hpd->dig_hotplug_reg = raw_reg_read(regs, PCH_PORT_HOTPLUG);
if (!hpd->hotplug_trigger) {
u32 mask = PORTA_HOTPLUG_STATUS_MASK |
PORTD_HOTPLUG_STATUS_MASK |
@@ -2399,7 +2398,7 @@ static void ibx_hpd_irq_ack(struct drm_i915_private *dev_priv,
hpd->dig_hotplug_reg &= ~mask;
}
- I915_WRITE(PCH_PORT_HOTPLUG, hpd->dig_hotplug_reg);
+ raw_reg_write(regs, PCH_PORT_HOTPLUG, hpd->dig_hotplug_reg);
}
static void ibx_hpd_irq_handler(struct drm_i915_private *dev_priv,
@@ -2417,12 +2416,12 @@ static void ibx_hpd_irq_handler(struct drm_i915_private *dev_priv,
intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
}
-static void ibx_irq_ack(struct drm_i915_private *dev_priv,
+static void ibx_irq_ack(void __iomem * const regs,
struct pch_irq_regs *pch)
{
pch->hpd.hotplug_trigger = pch->iir & SDE_HOTPLUG_MASK;
- ibx_hpd_irq_ack(dev_priv, &pch->hpd);
+ ibx_hpd_irq_ack(regs, &pch->hpd);
}
static void ibx_irq_handler(struct drm_i915_private *dev_priv,
@@ -2474,11 +2473,11 @@ 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_ack(struct drm_i915_private *dev_priv,
+static void ivb_err_int_ack(void __iomem * const regs,
struct ilk_de_irq_regs *de)
{
- de->err_int = I915_READ(GEN7_ERR_INT);
- I915_WRITE(GEN7_ERR_INT, de->err_int);
+ de->err_int = raw_reg_read(regs, GEN7_ERR_INT);
+ raw_reg_write(regs, GEN7_ERR_INT, de->err_int);
}
static void ivb_err_int_handler(struct drm_i915_private *dev_priv,
@@ -2503,11 +2502,11 @@ static void ivb_err_int_handler(struct drm_i915_private *dev_priv,
}
}
-static void cpt_serr_int_ack(struct drm_i915_private *dev_priv,
+static void cpt_serr_int_ack(void __iomem * const regs,
struct pch_irq_regs *pch)
{
- pch->serr_int = I915_READ(SERR_INT);
- I915_WRITE(SERR_INT, pch->serr_int);
+ pch->serr_int = raw_reg_read(regs, SERR_INT);
+ raw_reg_write(regs, SERR_INT, pch->serr_int);
}
static void cpt_serr_int_handler(struct drm_i915_private *dev_priv,
@@ -2524,15 +2523,15 @@ static void cpt_serr_int_handler(struct drm_i915_private *dev_priv,
intel_pch_fifo_underrun_irq_handler(dev_priv, pipe);
}
-static void cpt_irq_ack(struct drm_i915_private *dev_priv,
+static void cpt_irq_ack(void __iomem * const regs,
struct pch_irq_regs *pch)
{
pch->hpd.hotplug_trigger = pch->iir & SDE_HOTPLUG_MASK_CPT;
- ibx_hpd_irq_ack(dev_priv, &pch->hpd);
+ ibx_hpd_irq_ack(regs, &pch->hpd);
if (pch->iir & SDE_ERROR_CPT)
- cpt_serr_int_ack(dev_priv, pch);
+ cpt_serr_int_ack(regs, pch);
}
static void cpt_irq_handler(struct drm_i915_private *dev_priv,
@@ -2572,20 +2571,20 @@ static void cpt_irq_handler(struct drm_i915_private *dev_priv,
cpt_serr_int_handler(dev_priv, pch);
}
-static void icp_irq_ack(struct drm_i915_private *dev_priv,
+static void icp_irq_ack(void __iomem * const regs,
struct pch_irq_regs *pch)
{
pch->ddi.hotplug_trigger = pch->iir & SDE_DDI_MASK_ICP;
pch->tc.hotplug_trigger = pch->iir & SDE_TC_MASK_ICP;
if (pch->ddi.hotplug_trigger) {
- pch->ddi.dig_hotplug_reg = I915_READ(SHOTPLUG_CTL_DDI);
- I915_WRITE(SHOTPLUG_CTL_DDI, pch->ddi.dig_hotplug_reg);
+ pch->ddi.dig_hotplug_reg = raw_reg_read(regs, SHOTPLUG_CTL_DDI);
+ raw_reg_write(regs, SHOTPLUG_CTL_DDI, pch->ddi.dig_hotplug_reg);
}
if (pch->tc.hotplug_trigger) {
- pch->tc.dig_hotplug_reg = I915_READ(SHOTPLUG_CTL_TC);
- I915_WRITE(SHOTPLUG_CTL_TC, pch->tc.dig_hotplug_reg);
+ pch->tc.dig_hotplug_reg = raw_reg_read(regs, SHOTPLUG_CTL_TC);
+ raw_reg_write(regs, SHOTPLUG_CTL_TC, pch->tc.dig_hotplug_reg);
}
}
@@ -2615,7 +2614,7 @@ static void icp_irq_handler(struct drm_i915_private *dev_priv,
gmbus_irq_handler(dev_priv);
}
-static void spt_irq_ack(struct drm_i915_private *dev_priv,
+static void spt_irq_ack(void __iomem * const regs,
struct pch_irq_regs *pch)
{
pch->hpd.hotplug_trigger = pch->iir & SDE_HOTPLUG_MASK_SPT &
@@ -2623,13 +2622,13 @@ static void spt_irq_ack(struct drm_i915_private *dev_priv,
pch->hpd2.hotplug_trigger = pch->iir & SDE_PORTE_HOTPLUG_SPT;
if (pch->hpd.hotplug_trigger) {
- pch->hpd.dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
- I915_WRITE(PCH_PORT_HOTPLUG, pch->hpd.dig_hotplug_reg);
+ pch->hpd.dig_hotplug_reg = raw_reg_read(regs, PCH_PORT_HOTPLUG);
+ raw_reg_write(regs, PCH_PORT_HOTPLUG, pch->hpd.dig_hotplug_reg);
}
if (pch->hpd2.hotplug_trigger) {
- pch->hpd2.dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG2);
- I915_WRITE(PCH_PORT_HOTPLUG2, pch->hpd2.dig_hotplug_reg);
+ pch->hpd2.dig_hotplug_reg = raw_reg_read(regs, PCH_PORT_HOTPLUG2);
+ raw_reg_write(regs, PCH_PORT_HOTPLUG2, pch->hpd2.dig_hotplug_reg);
}
}
@@ -2658,11 +2657,11 @@ static void spt_irq_handler(struct drm_i915_private *dev_priv,
gmbus_irq_handler(dev_priv);
}
-static void ilk_hpd_irq_ack(struct drm_i915_private *dev_priv,
+static void ilk_hpd_irq_ack(void __iomem * const regs,
struct hpd_irq_regs *hpd)
{
- hpd->dig_hotplug_reg = I915_READ(DIGITAL_PORT_HOTPLUG_CNTRL);
- I915_WRITE(DIGITAL_PORT_HOTPLUG_CNTRL, hpd->dig_hotplug_reg);
+ hpd->dig_hotplug_reg = raw_reg_read(regs, DIGITAL_PORT_HOTPLUG_CNTRL);
+ raw_reg_write(regs, DIGITAL_PORT_HOTPLUG_CNTRL, hpd->dig_hotplug_reg);
}
static void ilk_hpd_irq_handler(struct drm_i915_private *dev_priv,
@@ -2678,26 +2677,27 @@ 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,
+static void ilk_display_irq_ack(struct drm_i915_private *i915,
+ void __iomem * const regs,
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);
+ ilk_hpd_irq_ack(regs, &de->hpd);
/* check event from PCH */
if (de->iir & DE_PCH_EVENT) {
- pch->iir = I915_READ(SDEIIR);
+ pch->iir = raw_reg_read(regs, SDEIIR);
- if (HAS_PCH_CPT(dev_priv))
- cpt_irq_ack(dev_priv, pch);
+ if (HAS_PCH_CPT(i915))
+ cpt_irq_ack(regs, pch);
else
- ibx_irq_ack(dev_priv, pch);
+ ibx_irq_ack(regs, pch);
/* should clear PCH hotplug event before clear CPU irq */
- I915_WRITE(SDEIIR, pch->iir);
+ raw_reg_write(regs, SDEIIR, pch->iir);
}
}
@@ -2743,37 +2743,38 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv,
ironlake_rps_change_irq_handler(dev_priv);
}
-static void hsw_psr_irq_ack(struct drm_i915_private *dev_priv,
+static void hsw_psr_irq_ack(void __iomem * const regs,
u32 *psr_iir)
{
- *psr_iir = I915_READ(EDP_PSR_IIR);
+ *psr_iir = raw_reg_read(regs, EDP_PSR_IIR);
if (*psr_iir)
- I915_WRITE(EDP_PSR_IIR, *psr_iir);
+ raw_reg_write(regs, EDP_PSR_IIR, *psr_iir);
}
-static void ivb_display_irq_ack(struct drm_i915_private *dev_priv,
+static void ivb_display_irq_ack(struct drm_i915_private *i915,
+ void __iomem * const regs,
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);
+ ilk_hpd_irq_ack(regs, &de->hpd);
if (de->iir & DE_ERR_INT_IVB)
- ivb_err_int_ack(dev_priv, de);
+ ivb_err_int_ack(regs, de);
if (de->iir & DE_EDP_PSR_INT_HSW)
- hsw_psr_irq_ack(dev_priv, &de->psr_iir);
+ hsw_psr_irq_ack(regs, &de->psr_iir);
/* check event from PCH */
- if (!HAS_PCH_NOP(dev_priv) && de->iir & DE_PCH_EVENT_IVB) {
- pch->iir = I915_READ(SDEIIR);
+ if (!HAS_PCH_NOP(i915) && de->iir & DE_PCH_EVENT_IVB) {
+ pch->iir = raw_reg_read(regs, SDEIIR);
- cpt_irq_ack(dev_priv, pch);
+ cpt_irq_ack(regs, pch);
/* clear PCH hotplug event before clear CPU irq */
- I915_WRITE(SDEIIR, pch->iir);
+ raw_reg_write(regs, SDEIIR, pch->iir);
}
}
@@ -2820,6 +2821,7 @@ 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;
+ void __iomem * const regs = dev_priv->uncore.regs;
u32 gt_iir, pm_iir = 0, de_ier, sde_ier = 0;
struct ilk_de_irq_regs de;
struct pch_irq_regs pch;
@@ -2831,9 +2833,12 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
/* IRQs are synced during runtime_suspend, we don't require a wakeref */
disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
+ /* WaSerializeKmdDisplayAccess:snb,ivb,hsw */
+ spin_lock(&dev_priv->irq_lock);
+
/* disable master interrupt before clearing iir */
- de_ier = I915_READ(DEIER);
- I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
+ 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
@@ -2841,35 +2846,37 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
* it, we'll get an interrupt if SDEIIR still has something to process
* due to its back queue). */
if (!HAS_PCH_NOP(dev_priv)) {
- sde_ier = I915_READ(SDEIER);
- I915_WRITE(SDEIER, 0);
+ sde_ier = raw_reg_read(regs, SDEIER);
+ raw_reg_write(regs, SDEIER, 0);
}
/* Find, clear, then process each source of interrupt */
- gt_iir = I915_READ(GTIIR);
- de.iir = I915_READ(DEIIR);
+ gt_iir = raw_reg_read(regs, GTIIR);
+ de.iir = raw_reg_read(regs, DEIIR);
if (INTEL_GEN(dev_priv) >= 6)
- pm_iir = I915_READ(GEN6_PMIIR);
+ pm_iir = raw_reg_read(regs, GEN6_PMIIR);
if (gt_iir)
- I915_WRITE(GTIIR, gt_iir);
+ raw_reg_write(regs, GTIIR, gt_iir);
if (de.iir) {
if (INTEL_GEN(dev_priv) >= 7)
- ivb_display_irq_ack(dev_priv, &de, &pch);
+ ivb_display_irq_ack(dev_priv, regs, &de, &pch);
else
- ilk_display_irq_ack(dev_priv, &de, &pch);
+ ilk_display_irq_ack(dev_priv, regs, &de, &pch);
- I915_WRITE(DEIIR, de.iir);
+ raw_reg_write(regs, DEIIR, de.iir);
}
if (pm_iir)
- I915_WRITE(GEN6_PMIIR, pm_iir);
+ raw_reg_write(regs, GEN6_PMIIR, pm_iir);
- I915_WRITE(DEIER, de_ier);
+ raw_reg_write(regs, DEIER, de_ier);
if (!HAS_PCH_NOP(dev_priv))
- I915_WRITE(SDEIER, sde_ier);
+ raw_reg_write(regs, SDEIER, sde_ier);
+
+ spin_unlock(&dev_priv->irq_lock);
if (gt_iir) {
ret = IRQ_HANDLED;
@@ -2898,11 +2905,11 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
return ret;
}
-static void bxt_hpd_irq_ack(struct drm_i915_private *dev_priv,
+static void bxt_hpd_irq_ack(void __iomem * const regs,
struct hpd_irq_regs *hpd)
{
- hpd->dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
- I915_WRITE(PCH_PORT_HOTPLUG, hpd->dig_hotplug_reg);
+ hpd->dig_hotplug_reg = raw_reg_read(regs, PCH_PORT_HOTPLUG);
+ raw_reg_write(regs, PCH_PORT_HOTPLUG, hpd->dig_hotplug_reg);
}
static void bxt_hpd_irq_handler(struct drm_i915_private *dev_priv,
@@ -2928,20 +2935,20 @@ struct gen8_de_irq_regs {
struct hpd_irq_regs tc, tbt; /* icl+ */
};
-static void gen11_hpd_irq_ack(struct drm_i915_private *dev_priv,
+static void gen11_hpd_irq_ack(void __iomem * const regs,
struct gen8_de_irq_regs *de)
{
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);
+ de->tc.dig_hotplug_reg = raw_reg_read(regs, GEN11_TC_HOTPLUG_CTL);
+ raw_reg_write(regs, GEN11_TC_HOTPLUG_CTL, de->tc.dig_hotplug_reg);
}
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);
+ de->tbt.dig_hotplug_reg = raw_reg_read(regs, GEN11_TBT_HOTPLUG_CTL);
+ raw_reg_write(regs, GEN11_TBT_HOTPLUG_CTL, de->tbt.dig_hotplug_reg);
}
}
@@ -2969,76 +2976,77 @@ static void gen11_hpd_irq_handler(struct drm_i915_private *dev_priv,
}
static void
-gen8_de_irq_ack(struct drm_i915_private *dev_priv, u32 master_ctl,
+gen8_de_irq_ack(struct drm_i915_private *i915,
+ void __iomem * const regs, 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);
+ de->misc_iir = raw_reg_read(regs, 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);
+ hsw_psr_irq_ack(regs, &de->psr_iir);
- I915_WRITE(GEN8_DE_MISC_IIR, de->misc_iir);
+ raw_reg_write(regs, GEN8_DE_MISC_IIR, de->misc_iir);
}
}
if (master_ctl & GEN11_DE_HPD_IRQ) {
- de->hpd_iir = I915_READ(GEN11_DE_HPD_IIR);
+ de->hpd_iir = raw_reg_read(regs, GEN11_DE_HPD_IIR);
if (de->hpd_iir) {
- gen11_hpd_irq_ack(dev_priv, de);
+ gen11_hpd_irq_ack(regs, de);
- I915_WRITE(GEN11_DE_HPD_IIR, de->hpd_iir);
+ raw_reg_write(regs, GEN11_DE_HPD_IIR, de->hpd_iir);
}
}
if (master_ctl & GEN8_DE_PORT_IRQ) {
- de->port_iir = I915_READ(GEN8_DE_PORT_IIR);
+ de->port_iir = raw_reg_read(regs, GEN8_DE_PORT_IIR);
if (de->port_iir) {
- if (IS_GEN9_LP(dev_priv)) {
+ if (IS_GEN9_LP(i915)) {
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)) {
+ bxt_hpd_irq_ack(regs, &de->ddi);
+ } else if (IS_BROADWELL(i915)) {
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);
+ ilk_hpd_irq_ack(regs, &de->ddi);
}
- I915_WRITE(GEN8_DE_PORT_IIR, de->port_iir);
+ raw_reg_write(regs, GEN8_DE_PORT_IIR, de->port_iir);
}
}
- for_each_pipe(dev_priv, pipe) {
+ for_each_pipe(i915, pipe) {
if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe)))
continue;
- de->pipe_iir[pipe] = I915_READ(GEN8_DE_PIPE_IIR(pipe));
+ de->pipe_iir[pipe] = raw_reg_read(regs, GEN8_DE_PIPE_IIR(pipe));
if (de->pipe_iir[pipe])
- I915_WRITE(GEN8_DE_PIPE_IIR(pipe), de->pipe_iir[pipe]);
+ raw_reg_write(regs, GEN8_DE_PIPE_IIR(pipe), de->pipe_iir[pipe]);
}
- if (HAS_PCH_SPLIT(dev_priv) && !HAS_PCH_NOP(dev_priv) &&
+ if (HAS_PCH_SPLIT(i915) && !HAS_PCH_NOP(i915) &&
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);
+ pch->iir = raw_reg_read(regs, 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);
+ if (INTEL_PCH_TYPE(i915) >= PCH_ICP)
+ icp_irq_ack(regs, pch);
+ else if (INTEL_PCH_TYPE(i915) >= PCH_SPT)
+ spt_irq_ack(regs, pch);
else
- cpt_irq_ack(dev_priv, pch);
+ cpt_irq_ack(regs, pch);
- I915_WRITE(SDEIIR, pch->iir);
+ raw_reg_write(regs, SDEIIR, pch->iir);
}
}
}
@@ -3235,24 +3243,29 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
if (!intel_irqs_enabled(dev_priv))
return IRQ_NONE;
+ spin_lock(&dev_priv->irq_lock);
+
master_ctl = gen8_master_intr_disable(regs);
if (!master_ctl) {
gen8_master_intr_enable(regs);
+ spin_unlock(&dev_priv->irq_lock);
return IRQ_NONE;
}
/* Find, clear, then process each source of interrupt */
- gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
+ gen8_gt_irq_ack(regs, master_ctl, gt_iir);
/* 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_ack(dev_priv, master_ctl, &de, &pch);
+ gen8_de_irq_ack(dev_priv, regs, master_ctl, &de, &pch);
enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
}
gen8_master_intr_enable(regs);
+ spin_unlock(&dev_priv->irq_lock);
+
gen8_gt_irq_handler(dev_priv, master_ctl, gt_iir);
if (master_ctl & ~GEN8_GT_IRQS) {
@@ -3390,9 +3403,9 @@ gen11_gt_irq_handler(struct drm_i915_private * const i915,
}
static u32
-gen11_gu_misc_irq_ack(struct drm_i915_private *dev_priv, const u32 master_ctl)
+gen11_gu_misc_irq_ack(void __iomem * const regs,
+ u32 master_ctl)
{
- void __iomem * const regs = dev_priv->uncore.regs;
u32 iir;
if (!(master_ctl & GEN11_GU_MISC_IRQ))
@@ -3443,9 +3456,12 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg)
if (!intel_irqs_enabled(i915))
return IRQ_NONE;
+ spin_lock(&i915->irq_lock);
+
master_ctl = gen11_master_intr_disable(regs);
if (!master_ctl) {
gen11_master_intr_enable(regs);
+ spin_unlock(&i915->irq_lock);
return IRQ_NONE;
}
@@ -3461,14 +3477,16 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg)
* GEN11_DISPLAY_INT_CTL has same format as GEN8_MASTER_IRQ
* for the display related bits.
*/
- gen8_de_irq_ack(i915, disp_ctl, &de, &pch);
+ gen8_de_irq_ack(i915, regs, disp_ctl, &de, &pch);
enable_rpm_wakeref_asserts(&i915->runtime_pm);
}
- gu_misc_iir = gen11_gu_misc_irq_ack(i915, master_ctl);
+ gu_misc_iir = gen11_gu_misc_irq_ack(regs, master_ctl);
gen11_master_intr_enable(regs);
+ spin_unlock(&i915->irq_lock);
+
if (master_ctl & GEN11_DISPLAY_IRQ) {
disable_rpm_wakeref_asserts(&i915->runtime_pm);
/*
--
2.21.0
More information about the Intel-gfx
mailing list