Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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.com


Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 261e40b8
Loading
Loading
Loading
Loading
+47 −32
Original line number Diff line number Diff line
@@ -1324,60 +1324,45 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift)
		tasklet_schedule(&engine->irq_tasklet);
}

static irqreturn_t gen8_gt_irq_handler(struct drm_i915_private *dev_priv,
				       u32 master_ctl)
static irqreturn_t gen8_gt_irq_ack(struct drm_i915_private *dev_priv,
				   u32 master_ctl,
				   u32 gt_iir[4])
{
	irqreturn_t ret = IRQ_NONE;

	if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) {
		u32 iir = I915_READ_FW(GEN8_GT_IIR(0));
		if (iir) {
			I915_WRITE_FW(GEN8_GT_IIR(0), iir);
		gt_iir[0] = I915_READ_FW(GEN8_GT_IIR(0));
		if (gt_iir[0]) {
			I915_WRITE_FW(GEN8_GT_IIR(0), gt_iir[0]);
			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
			DRM_ERROR("The master control interrupt lied (GT0)!\n");
	}

	if (master_ctl & (GEN8_GT_VCS1_IRQ | GEN8_GT_VCS2_IRQ)) {
		u32 iir = I915_READ_FW(GEN8_GT_IIR(1));
		if (iir) {
			I915_WRITE_FW(GEN8_GT_IIR(1), iir);
		gt_iir[1] = I915_READ_FW(GEN8_GT_IIR(1));
		if (gt_iir[1]) {
			I915_WRITE_FW(GEN8_GT_IIR(1), gt_iir[1]);
			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
			DRM_ERROR("The master control interrupt lied (GT1)!\n");
	}

	if (master_ctl & GEN8_GT_VECS_IRQ) {
		u32 iir = I915_READ_FW(GEN8_GT_IIR(3));
		if (iir) {
			I915_WRITE_FW(GEN8_GT_IIR(3), iir);
		gt_iir[3] = I915_READ_FW(GEN8_GT_IIR(3));
		if (gt_iir[3]) {
			I915_WRITE_FW(GEN8_GT_IIR(3), gt_iir[3]);
			ret = IRQ_HANDLED;

			gen8_cs_irq_handler(&dev_priv->engine[VECS],
					    iir, GEN8_VECS_IRQ_SHIFT);
		} else
			DRM_ERROR("The master control interrupt lied (GT3)!\n");
	}

	if (master_ctl & GEN8_GT_PM_IRQ) {
		u32 iir = I915_READ_FW(GEN8_GT_IIR(2));
		if (iir & dev_priv->pm_rps_events) {
		gt_iir[2] = I915_READ_FW(GEN8_GT_IIR(2));
		if (gt_iir[2] & dev_priv->pm_rps_events) {
			I915_WRITE_FW(GEN8_GT_IIR(2),
				      iir & dev_priv->pm_rps_events);
				      gt_iir[2] & dev_priv->pm_rps_events);
			ret = IRQ_HANDLED;
			gen6_rps_irq_handler(dev_priv, iir);
		} else
			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,
	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)
{
	switch (port) {
@@ -1864,6 +1874,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)

	do {
		u32 master_ctl, iir;
		u32 gt_iir[4] = {};
		u32 pipe_stats[I915_MAX_PIPES] = {};
		u32 hotplug_status = 0;
		u32 ier = 0;
@@ -1893,7 +1904,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
		ier = I915_READ(VLV_IER);
		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)
			hotplug_status = i9xx_hpd_irq_ack(dev_priv);
@@ -1913,6 +1924,8 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
		I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
		POSTING_READ(GEN8_MASTER_IRQ);

		gen8_gt_irq_handler(dev_priv, gt_iir);

		if (hotplug_status)
			i9xx_hpd_irq_handler(dev, hotplug_status);

@@ -2479,6 +2492,7 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
	struct drm_device *dev = arg;
	struct drm_i915_private *dev_priv = dev->dev_private;
	u32 master_ctl;
	u32 gt_iir[4] = {};
	irqreturn_t ret;

	if (!intel_irqs_enabled(dev_priv))
@@ -2495,7 +2509,8 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
	disable_rpm_wakeref_asserts(dev_priv);

	/* 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);

	I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);