From patchwork Fri May 9 12:09:08 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: oscar.mateo@intel.com X-Patchwork-Id: 4142521 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 452B7BFF02 for ; Fri, 9 May 2014 12:15:15 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 09EF92026C for ; Fri, 9 May 2014 12:15:14 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id C56C8201B4 for ; Fri, 9 May 2014 12:15:12 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 68B0F6EF89; Fri, 9 May 2014 05:15:12 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id 279DB6EF88 for ; Fri, 9 May 2014 05:15:09 -0700 (PDT) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 09 May 2014 05:15:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="4.97,1018,1389772800"; d="scan'208"; a="529107230" Received: from omateolo-linux2.iwi.intel.com ([172.28.253.145]) by fmsmga001.fm.intel.com with ESMTP; 09 May 2014 05:15:07 -0700 From: oscar.mateo@intel.com To: intel-gfx@lists.freedesktop.org Date: Fri, 9 May 2014 13:09:08 +0100 Message-Id: <1399637360-4277-39-git-send-email-oscar.mateo@intel.com> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1399637360-4277-1-git-send-email-oscar.mateo@intel.com> References: <1399637360-4277-1-git-send-email-oscar.mateo@intel.com> Cc: Thomas Daniel Subject: [Intel-gfx] [PATCH 38/50] drm/i915/bdw: LR context switch interrupts X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Thomas Daniel 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. Signed-off-by: Thomas Daniel v2: Disable HWSTAM, as suggested by Damien (nobody listens to these interrupts, anyway). Signed-off-by: Oscar Mateo --- drivers/gpu/drm/i915/i915_irq.c | 27 ++++++++++++++++++------- drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_ringbuffer.c | 36 ++++++++++++++++++++------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 873ae50..a28cf6c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1300,7 +1300,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, struct drm_i915_private *dev_priv, u32 master_ctl) { - u32 rcs, bcs, vcs; + u32 rcs, bcs, vcs, vecs; uint32_t tmp = 0; irqreturn_t ret = IRQ_NONE; @@ -1314,6 +1314,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"); I915_WRITE(GEN8_GT_IIR(0), tmp); } else DRM_ERROR("The master control interrupt lied (GT0)!\n"); @@ -1326,9 +1328,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"); I915_WRITE(GEN8_GT_IIR(1), tmp); } else DRM_ERROR("The master control interrupt lied (GT1)!\n"); @@ -1338,9 +1344,11 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, tmp = I915_READ(GEN8_GT_IIR(3)); if (tmp) { ret = IRQ_HANDLED; - vcs = tmp >> GEN8_VECS_IRQ_SHIFT; - if (vcs & GT_RENDER_USER_INTERRUPT) + vecs = tmp >> GEN8_VECS_IRQ_SHIFT; + if (vecs & GT_RENDER_USER_INTERRUPT) notify_ring(dev, &dev_priv->ring[VECS]); + if (vecs & GEN8_GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER("TODO: Context switch\n"); I915_WRITE(GEN8_GT_IIR(3), tmp); } else DRM_ERROR("The master control interrupt lied (GT3)!\n"); @@ -3243,12 +3251,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 | - GT_RENDER_L3_PARITY_ERROR_INTERRUPT | - GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT, + GT_RENDER_L3_PARITY_ERROR_INTERRUPT | + GEN8_GT_CONTEXT_SWITCH_INTERRUPT << GEN8_RCS_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 2e76ec0..97a51f8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -823,6 +823,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 0x001FFFF8 #define HEAD_WRAP_COUNT 0xFFE00000 @@ -4269,6 +4270,7 @@ enum punit_power_well { #define GEN8_GT_IMR(which) (0x44304 + (0x10 * (which))) #define GEN8_GT_IIR(which) (0x44308 + (0x10 * (which))) #define GEN8_GT_IER(which) (0x4430c + (0x10 * (which))) +#define GEN8_GT_CONTEXT_SWITCH_INTERRUPT (1<<8) #define GEN8_BCS_IRQ_SHIFT 16 #define GEN8_RCS_IRQ_SHIFT 0 diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index d38d824..847fec5 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -567,6 +567,12 @@ out: static int init_ring_common_lrc(struct intel_engine *ring) { + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | ring->irq_keep_mask)); + I915_WRITE(RING_HWSTAM(ring->mmio_base), 0xffffffff); + return 0; } @@ -1288,13 +1294,7 @@ gen8_ring_get_irq(struct intel_engine *ring) spin_lock_irqsave(&dev_priv->irq_lock, flags); if (ring->irq_refcount++ == 0) { - if (HAS_L3_DPF(dev) && ring->id == RCS) { - I915_WRITE_IMR(ring, - ~(ring->irq_enable_mask | - GT_RENDER_L3_PARITY_ERROR_INTERRUPT)); - } else { - I915_WRITE_IMR(ring, ~ring->irq_enable_mask); - } + I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | ring->irq_keep_mask)); POSTING_READ(RING_IMR(ring->mmio_base)); } spin_unlock_irqrestore(&dev_priv->irq_lock, flags); @@ -1311,12 +1311,7 @@ gen8_ring_put_irq(struct intel_engine *ring) spin_lock_irqsave(&dev_priv->irq_lock, flags); if (--ring->irq_refcount == 0) { - if (HAS_L3_DPF(dev) && ring->id == RCS) { - I915_WRITE_IMR(ring, - ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT); - } else { - I915_WRITE_IMR(ring, ~0); - } + I915_WRITE_IMR(ring, ~ring->irq_keep_mask); POSTING_READ(RING_IMR(ring->mmio_base)); } spin_unlock_irqrestore(&dev_priv->irq_lock, flags); @@ -2108,15 +2103,20 @@ int intel_init_render_ring(struct drm_device *dev) ring->submit = gen8_submit_ctx; ring->init = init_render_ring_lrc; ring->add_request = gen8_add_request_lrc; + ring->irq_keep_mask = + GEN8_GT_CONTEXT_SWITCH_INTERRUPT << GEN8_RCS_IRQ_SHIFT; } ring->flush = gen8_render_ring_flush; ring->irq_get = gen8_ring_get_irq; ring->irq_put = gen8_ring_put_irq; + if (HAS_L3_DPF(dev)) + ring->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; } else { ring->irq_get = gen6_ring_get_irq; ring->irq_put = gen6_ring_put_irq; } - ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT; + ring->irq_enable_mask = + GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT; ring->get_seqno = gen6_ring_get_seqno; ring->set_seqno = ring_set_seqno; ring->semaphore.sync_to = gen6_ring_sync; @@ -2286,6 +2286,8 @@ int intel_init_bsd_ring(struct drm_device *dev) ring->submit = gen8_submit_ctx; ring->init = init_ring_common_lrc; ring->add_request = gen8_nonrender_add_request_lrc; + ring->irq_keep_mask = + GEN8_GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; } ring->flush = gen8_ring_flush; ring->irq_enable_mask = @@ -2358,6 +2360,8 @@ int intel_init_bsd2_ring(struct drm_device *dev) ring->submit = gen8_submit_ctx; ring->add_request = gen8_nonrender_add_request_lrc; ring->init = init_ring_common_lrc; + ring->irq_keep_mask = + GEN8_GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; } else { ring->submit = ring_write_tail; ring->add_request = gen6_add_request; @@ -2408,6 +2412,8 @@ int intel_init_blt_ring(struct drm_device *dev) ring->submit = gen8_submit_ctx; ring->init = init_ring_common_lrc; ring->add_request = gen8_nonrender_add_request_lrc; + ring->irq_keep_mask = + GEN8_GT_CONTEXT_SWITCH_INTERRUPT << GEN8_BCS_IRQ_SHIFT; } ring->flush = gen8_ring_flush; ring->irq_enable_mask = @@ -2460,6 +2466,8 @@ int intel_init_vebox_ring(struct drm_device *dev) ring->submit = gen8_submit_ctx; ring->init = init_ring_common_lrc; ring->add_request = gen8_nonrender_add_request_lrc; + ring->irq_keep_mask = + GEN8_GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VECS_IRQ_SHIFT; } ring->flush = gen8_ring_flush; ring->irq_enable_mask = diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index c224fdc..709b1f1 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -96,6 +96,7 @@ struct intel_engine { unsigned irq_refcount; /* protected by dev_priv->irq_lock */ u32 irq_enable_mask; /* bitmask to enable ring interrupt */ + u32 irq_keep_mask; /* bitmask for interrupts that should not be masked */ u32 trace_irq_seqno; bool __must_check (*irq_get)(struct intel_engine *ring); void (*irq_put)(struct intel_engine *ring);