Commit e30e251a authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Split gen8_gt_irq_handler into ack+handle

As we did on VLV, split the gt irq handling to ack and handler phases on
CHV. Leave the BDW+ codepath mostly intact for now.
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1460571598-24452-13-git-send-email-ville.syrjala@linux.intel.comReviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 261e40b8
...@@ -1324,60 +1324,45 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift) ...@@ -1324,60 +1324,45 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift)
tasklet_schedule(&engine->irq_tasklet); tasklet_schedule(&engine->irq_tasklet);
} }
static irqreturn_t gen8_gt_irq_handler(struct drm_i915_private *dev_priv, static irqreturn_t gen8_gt_irq_ack(struct drm_i915_private *dev_priv,
u32 master_ctl) u32 master_ctl,
u32 gt_iir[4])
{ {
irqreturn_t ret = IRQ_NONE; irqreturn_t ret = IRQ_NONE;
if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) { if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) {
u32 iir = I915_READ_FW(GEN8_GT_IIR(0)); gt_iir[0] = I915_READ_FW(GEN8_GT_IIR(0));
if (iir) { if (gt_iir[0]) {
I915_WRITE_FW(GEN8_GT_IIR(0), iir); I915_WRITE_FW(GEN8_GT_IIR(0), gt_iir[0]);
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
gen8_cs_irq_handler(&dev_priv->engine[RCS],
iir, GEN8_RCS_IRQ_SHIFT);
gen8_cs_irq_handler(&dev_priv->engine[BCS],
iir, GEN8_BCS_IRQ_SHIFT);
} else } else
DRM_ERROR("The master control interrupt lied (GT0)!\n"); DRM_ERROR("The master control interrupt lied (GT0)!\n");
} }
if (master_ctl & (GEN8_GT_VCS1_IRQ | GEN8_GT_VCS2_IRQ)) { if (master_ctl & (GEN8_GT_VCS1_IRQ | GEN8_GT_VCS2_IRQ)) {
u32 iir = I915_READ_FW(GEN8_GT_IIR(1)); gt_iir[1] = I915_READ_FW(GEN8_GT_IIR(1));
if (iir) { if (gt_iir[1]) {
I915_WRITE_FW(GEN8_GT_IIR(1), iir); I915_WRITE_FW(GEN8_GT_IIR(1), gt_iir[1]);
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
gen8_cs_irq_handler(&dev_priv->engine[VCS],
iir, GEN8_VCS1_IRQ_SHIFT);
gen8_cs_irq_handler(&dev_priv->engine[VCS2],
iir, GEN8_VCS2_IRQ_SHIFT);
} else } else
DRM_ERROR("The master control interrupt lied (GT1)!\n"); DRM_ERROR("The master control interrupt lied (GT1)!\n");
} }
if (master_ctl & GEN8_GT_VECS_IRQ) { if (master_ctl & GEN8_GT_VECS_IRQ) {
u32 iir = I915_READ_FW(GEN8_GT_IIR(3)); gt_iir[3] = I915_READ_FW(GEN8_GT_IIR(3));
if (iir) { if (gt_iir[3]) {
I915_WRITE_FW(GEN8_GT_IIR(3), iir); I915_WRITE_FW(GEN8_GT_IIR(3), gt_iir[3]);
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
gen8_cs_irq_handler(&dev_priv->engine[VECS],
iir, GEN8_VECS_IRQ_SHIFT);
} else } else
DRM_ERROR("The master control interrupt lied (GT3)!\n"); DRM_ERROR("The master control interrupt lied (GT3)!\n");
} }
if (master_ctl & GEN8_GT_PM_IRQ) { if (master_ctl & GEN8_GT_PM_IRQ) {
u32 iir = I915_READ_FW(GEN8_GT_IIR(2)); gt_iir[2] = I915_READ_FW(GEN8_GT_IIR(2));
if (iir & dev_priv->pm_rps_events) { if (gt_iir[2] & dev_priv->pm_rps_events) {
I915_WRITE_FW(GEN8_GT_IIR(2), I915_WRITE_FW(GEN8_GT_IIR(2),
iir & dev_priv->pm_rps_events); gt_iir[2] & dev_priv->pm_rps_events);
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
gen6_rps_irq_handler(dev_priv, iir);
} else } else
DRM_ERROR("The master control interrupt lied (PM)!\n"); DRM_ERROR("The master control interrupt lied (PM)!\n");
} }
...@@ -1385,6 +1370,31 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_i915_private *dev_priv, ...@@ -1385,6 +1370,31 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_i915_private *dev_priv,
return ret; return ret;
} }
static void gen8_gt_irq_handler(struct drm_i915_private *dev_priv,
u32 gt_iir[4])
{
if (gt_iir[0]) {
gen8_cs_irq_handler(&dev_priv->engine[RCS],
gt_iir[0], GEN8_RCS_IRQ_SHIFT);
gen8_cs_irq_handler(&dev_priv->engine[BCS],
gt_iir[0], GEN8_BCS_IRQ_SHIFT);
}
if (gt_iir[1]) {
gen8_cs_irq_handler(&dev_priv->engine[VCS],
gt_iir[1], GEN8_VCS1_IRQ_SHIFT);
gen8_cs_irq_handler(&dev_priv->engine[VCS2],
gt_iir[1], GEN8_VCS2_IRQ_SHIFT);
}
if (gt_iir[3])
gen8_cs_irq_handler(&dev_priv->engine[VECS],
gt_iir[3], GEN8_VECS_IRQ_SHIFT);
if (gt_iir[2] & dev_priv->pm_rps_events)
gen6_rps_irq_handler(dev_priv, gt_iir[2]);
}
static bool bxt_port_hotplug_long_detect(enum port port, u32 val) static bool bxt_port_hotplug_long_detect(enum port port, u32 val)
{ {
switch (port) { switch (port) {
...@@ -1864,6 +1874,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) ...@@ -1864,6 +1874,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
do { do {
u32 master_ctl, iir; u32 master_ctl, iir;
u32 gt_iir[4] = {};
u32 pipe_stats[I915_MAX_PIPES] = {}; u32 pipe_stats[I915_MAX_PIPES] = {};
u32 hotplug_status = 0; u32 hotplug_status = 0;
u32 ier = 0; u32 ier = 0;
...@@ -1893,7 +1904,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) ...@@ -1893,7 +1904,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
ier = I915_READ(VLV_IER); ier = I915_READ(VLV_IER);
I915_WRITE(VLV_IER, 0); I915_WRITE(VLV_IER, 0);
gen8_gt_irq_handler(dev_priv, master_ctl); gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
if (iir & I915_DISPLAY_PORT_INTERRUPT) if (iir & I915_DISPLAY_PORT_INTERRUPT)
hotplug_status = i9xx_hpd_irq_ack(dev_priv); hotplug_status = i9xx_hpd_irq_ack(dev_priv);
...@@ -1913,6 +1924,8 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) ...@@ -1913,6 +1924,8 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
POSTING_READ(GEN8_MASTER_IRQ); POSTING_READ(GEN8_MASTER_IRQ);
gen8_gt_irq_handler(dev_priv, gt_iir);
if (hotplug_status) if (hotplug_status)
i9xx_hpd_irq_handler(dev, hotplug_status); i9xx_hpd_irq_handler(dev, hotplug_status);
...@@ -2479,6 +2492,7 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) ...@@ -2479,6 +2492,7 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
struct drm_device *dev = arg; struct drm_device *dev = arg;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 master_ctl; u32 master_ctl;
u32 gt_iir[4] = {};
irqreturn_t ret; irqreturn_t ret;
if (!intel_irqs_enabled(dev_priv)) if (!intel_irqs_enabled(dev_priv))
...@@ -2495,7 +2509,8 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) ...@@ -2495,7 +2509,8 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
disable_rpm_wakeref_asserts(dev_priv); disable_rpm_wakeref_asserts(dev_priv);
/* Find, clear, then process each source of interrupt */ /* Find, clear, then process each source of interrupt */
ret = gen8_gt_irq_handler(dev_priv, master_ctl); ret = gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
gen8_gt_irq_handler(dev_priv, gt_iir);
ret |= gen8_de_irq_handler(dev_priv, master_ctl); ret |= gen8_de_irq_handler(dev_priv, master_ctl);
I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment