Re: [Intel-gfx] [PATCH 23/43] drm/i915/bdw: Interrupts with logical rings
On Thu, Jul 24, 2014 at 05:04:31PM +0100, Thomas Daniel wrote: From: Oscar Mateo oscar.ma...@intel.com We need to attend context switch interrupts from all rings. Also, fixed writing IMR/IER and added HWSTAM at ring init time. Notice that, if added to irq_enable_mask, the context switch interrupts would be incorrectly masked out when the user interrupts are due to no users waiting on a sequence number. Therefore, this commit adds a bitmask of interrupts to be kept unmasked at all times. v2: Disable HWSTAM, as suggested by Damien (nobody listens to these interrupts, anyway). v3: Add new get/put_irq functions. Signed-off-by: Thomas Daniel thomas.dan...@intel.com (v1) Signed-off-by: Oscar Mateo oscar.ma...@intel.com (v2 v3) irq_keep_mask is a nifty idea, would be pretty to roll it out for legacy rings too. But totally optional. -Daniel --- drivers/gpu/drm/i915/i915_irq.c | 19 -- drivers/gpu/drm/i915/i915_reg.h |3 ++ drivers/gpu/drm/i915/intel_lrc.c| 58 +++ drivers/gpu/drm/i915/intel_ringbuffer.h |1 + 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a38b5c3..f77a4ca 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1643,6 +1643,8 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, notify_ring(dev, dev_priv-ring[RCS]); if (bcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[BCS]); + if ((rcs | bcs) GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); } else DRM_ERROR(The master control interrupt lied (GT0)!\n); } @@ -1655,9 +1657,13 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, vcs = tmp GEN8_VCS1_IRQ_SHIFT; if (vcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[VCS]); + if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); vcs = tmp GEN8_VCS2_IRQ_SHIFT; if (vcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[VCS2]); + if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); } else DRM_ERROR(The master control interrupt lied (GT1)!\n); } @@ -1681,6 +1687,8 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, vcs = tmp GEN8_VECS_IRQ_SHIFT; if (vcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[VECS]); + if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); } else DRM_ERROR(The master control interrupt lied (GT3)!\n); } @@ -3768,12 +3776,17 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv) /* These are interrupts we'll toggle with the ring mask register */ uint32_t gt_interrupts[] = { GT_RENDER_USER_INTERRUPT GEN8_RCS_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_RCS_IRQ_SHIFT | GT_RENDER_L3_PARITY_ERROR_INTERRUPT | - GT_RENDER_USER_INTERRUPT GEN8_BCS_IRQ_SHIFT, + GT_RENDER_USER_INTERRUPT GEN8_BCS_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_BCS_IRQ_SHIFT, GT_RENDER_USER_INTERRUPT GEN8_VCS1_IRQ_SHIFT | - GT_RENDER_USER_INTERRUPT GEN8_VCS2_IRQ_SHIFT, + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_VCS1_IRQ_SHIFT | + GT_RENDER_USER_INTERRUPT GEN8_VCS2_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_VCS2_IRQ_SHIFT, 0, - GT_RENDER_USER_INTERRUPT GEN8_VECS_IRQ_SHIFT + GT_RENDER_USER_INTERRUPT GEN8_VECS_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_VECS_IRQ_SHIFT }; for (i = 0; i ARRAY_SIZE(gt_interrupts); i++) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 70dddac..bfc0c01 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1062,6 +1062,7 @@ enum punit_power_well { #define RING_ACTHD_UDW(base) ((base)+0x5c) #define RING_NOPID(base) ((base)+0x94) #define RING_IMR(base) ((base)+0xa8) +#define RING_HWSTAM(base)((base)+0x98) #define
Re: [Intel-gfx] [PATCH 23/43] drm/i915/bdw: Interrupts with logical rings
On Thu, Jul 24, 2014 at 05:04:31PM +0100, Thomas Daniel wrote: From: Oscar Mateo oscar.ma...@intel.com We need to attend context switch interrupts from all rings. Also, fixed writing IMR/IER and added HWSTAM at ring init time. Notice that, if added to irq_enable_mask, the context switch interrupts would be incorrectly masked out when the user interrupts are due to no users waiting on a sequence number. Therefore, this commit adds a bitmask of interrupts to be kept unmasked at all times. v2: Disable HWSTAM, as suggested by Damien (nobody listens to these interrupts, anyway). v3: Add new get/put_irq functions. Signed-off-by: Thomas Daniel thomas.dan...@intel.com (v1) Signed-off-by: Oscar Mateo oscar.ma...@intel.com (v2 v3) --- drivers/gpu/drm/i915/i915_irq.c | 19 -- drivers/gpu/drm/i915/i915_reg.h |3 ++ drivers/gpu/drm/i915/intel_lrc.c| 58 +++ drivers/gpu/drm/i915/intel_ringbuffer.h |1 + 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a38b5c3..f77a4ca 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1643,6 +1643,8 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, notify_ring(dev, dev_priv-ring[RCS]); if (bcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[BCS]); + if ((rcs | bcs) GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); } else DRM_ERROR(The master control interrupt lied (GT0)!\n); } @@ -1655,9 +1657,13 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, vcs = tmp GEN8_VCS1_IRQ_SHIFT; if (vcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[VCS]); + if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); vcs = tmp GEN8_VCS2_IRQ_SHIFT; if (vcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[VCS2]); + if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); } else DRM_ERROR(The master control interrupt lied (GT1)!\n); } @@ -1681,6 +1687,8 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, vcs = tmp GEN8_VECS_IRQ_SHIFT; if (vcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[VECS]); + if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); } else DRM_ERROR(The master control interrupt lied (GT3)!\n); } @@ -3768,12 +3776,17 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv) /* These are interrupts we'll toggle with the ring mask register */ uint32_t gt_interrupts[] = { GT_RENDER_USER_INTERRUPT GEN8_RCS_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_RCS_IRQ_SHIFT | GT_RENDER_L3_PARITY_ERROR_INTERRUPT | - GT_RENDER_USER_INTERRUPT GEN8_BCS_IRQ_SHIFT, + GT_RENDER_USER_INTERRUPT GEN8_BCS_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_BCS_IRQ_SHIFT, GT_RENDER_USER_INTERRUPT GEN8_VCS1_IRQ_SHIFT | - GT_RENDER_USER_INTERRUPT GEN8_VCS2_IRQ_SHIFT, + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_VCS1_IRQ_SHIFT | + GT_RENDER_USER_INTERRUPT GEN8_VCS2_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_VCS2_IRQ_SHIFT, 0, - GT_RENDER_USER_INTERRUPT GEN8_VECS_IRQ_SHIFT + GT_RENDER_USER_INTERRUPT GEN8_VECS_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_VECS_IRQ_SHIFT }; for (i = 0; i ARRAY_SIZE(gt_interrupts); i++) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 70dddac..bfc0c01 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1062,6 +1062,7 @@ enum punit_power_well { #define RING_ACTHD_UDW(base) ((base)+0x5c) #define RING_NOPID(base) ((base)+0x94) #define RING_IMR(base) ((base)+0xa8) +#define RING_HWSTAM(base)((base)+0x98) #define RING_TIMESTAMP(base) ((base)+0x358) #define TAIL_ADDR 0x0018 #define HEAD_WRAP_COUNT0xFFE0 @@
[Intel-gfx] [PATCH 23/43] drm/i915/bdw: Interrupts with logical rings
From: Oscar Mateo oscar.ma...@intel.com We need to attend context switch interrupts from all rings. Also, fixed writing IMR/IER and added HWSTAM at ring init time. Notice that, if added to irq_enable_mask, the context switch interrupts would be incorrectly masked out when the user interrupts are due to no users waiting on a sequence number. Therefore, this commit adds a bitmask of interrupts to be kept unmasked at all times. v2: Disable HWSTAM, as suggested by Damien (nobody listens to these interrupts, anyway). v3: Add new get/put_irq functions. Signed-off-by: Thomas Daniel thomas.dan...@intel.com (v1) Signed-off-by: Oscar Mateo oscar.ma...@intel.com (v2 v3) --- drivers/gpu/drm/i915/i915_irq.c | 19 -- drivers/gpu/drm/i915/i915_reg.h |3 ++ drivers/gpu/drm/i915/intel_lrc.c| 58 +++ drivers/gpu/drm/i915/intel_ringbuffer.h |1 + 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a38b5c3..f77a4ca 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1643,6 +1643,8 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, notify_ring(dev, dev_priv-ring[RCS]); if (bcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[BCS]); + if ((rcs | bcs) GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); } else DRM_ERROR(The master control interrupt lied (GT0)!\n); } @@ -1655,9 +1657,13 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, vcs = tmp GEN8_VCS1_IRQ_SHIFT; if (vcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[VCS]); + if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); vcs = tmp GEN8_VCS2_IRQ_SHIFT; if (vcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[VCS2]); + if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); } else DRM_ERROR(The master control interrupt lied (GT1)!\n); } @@ -1681,6 +1687,8 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, vcs = tmp GEN8_VECS_IRQ_SHIFT; if (vcs GT_RENDER_USER_INTERRUPT) notify_ring(dev, dev_priv-ring[VECS]); + if (vcs GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER(TODO: Context switch\n); } else DRM_ERROR(The master control interrupt lied (GT3)!\n); } @@ -3768,12 +3776,17 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv) /* These are interrupts we'll toggle with the ring mask register */ uint32_t gt_interrupts[] = { GT_RENDER_USER_INTERRUPT GEN8_RCS_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_RCS_IRQ_SHIFT | GT_RENDER_L3_PARITY_ERROR_INTERRUPT | - GT_RENDER_USER_INTERRUPT GEN8_BCS_IRQ_SHIFT, + GT_RENDER_USER_INTERRUPT GEN8_BCS_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_BCS_IRQ_SHIFT, GT_RENDER_USER_INTERRUPT GEN8_VCS1_IRQ_SHIFT | - GT_RENDER_USER_INTERRUPT GEN8_VCS2_IRQ_SHIFT, + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_VCS1_IRQ_SHIFT | + GT_RENDER_USER_INTERRUPT GEN8_VCS2_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_VCS2_IRQ_SHIFT, 0, - GT_RENDER_USER_INTERRUPT GEN8_VECS_IRQ_SHIFT + GT_RENDER_USER_INTERRUPT GEN8_VECS_IRQ_SHIFT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT GEN8_VECS_IRQ_SHIFT }; for (i = 0; i ARRAY_SIZE(gt_interrupts); i++) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 70dddac..bfc0c01 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1062,6 +1062,7 @@ enum punit_power_well { #define RING_ACTHD_UDW(base) ((base)+0x5c) #define RING_NOPID(base) ((base)+0x94) #define RING_IMR(base) ((base)+0xa8) +#define RING_HWSTAM(base) ((base)+0x98) #define RING_TIMESTAMP(base) ((base)+0x358) #define TAIL_ADDR0x0018 #define HEAD_WRAP_COUNT 0xFFE0 @@ -4590,6 +4591,8 @@ enum punit_power_well { #define GEN8_GT_IIR(which)