From patchwork Sat Feb 26 18:30:17 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 592741 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p1QIfXLw012359 for ; Sat, 26 Feb 2011 18:41:55 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A8F399F37C for ; Sat, 26 Feb 2011 10:41:32 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-iw0-f177.google.com (mail-iw0-f177.google.com [209.85.214.177]) by gabe.freedesktop.org (Postfix) with ESMTP id E25E49E9DB for ; Sat, 26 Feb 2011 10:30:42 -0800 (PST) Received: by mail-iw0-f177.google.com with SMTP id 36so2094154iwn.36 for ; Sat, 26 Feb 2011 10:30:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=5EK/TIFhc3PclKMbOMnnj77ubFj/Xjvwsc5vTFqO1cs=; b=Js5UUKPKAujhjsPxekEtJEb3ayxUGtIRtdVUgJdjucJew9shU4AEC20DS8JwV9R7F4 oIZSOy4O5QgExeIPGz1NHhg4li2wwOals6K80+lDzp5FkO5I0nKBQibbPmhCHwPA8pzq msJrUVFAVqm916Pp0gDx58f04+R5Xw+k3FsvM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=o8welmdbXQhNRSMcmYi6T/ywm3IoBNbmp2iEctFvAONyElMhINmrcg7O95DpQzx/fO IuT4La/PBeFyWFOHBC7VDoMzltS253RXMQ2J9eBTs4e02y3M2kHNpP1g5JD0BuhwvCLn 3D4oN6dFesdtwj8RRBDczuRmuKUHGe3orCQOo= Received: by 10.42.226.67 with SMTP id iv3mr2517199icb.358.1298745042720; Sat, 26 Feb 2011 10:30:42 -0800 (PST) Received: from localhost.localdomain ([67.208.96.87]) by mx.google.com with ESMTPS id wd12sm1519339icb.17.2011.02.26.10.30.41 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 26 Feb 2011 10:30:42 -0800 (PST) From: Ben Widawsky To: intel-gfx@lists.freedesktop.org Date: Sat, 26 Feb 2011 10:30:17 -0800 Message-Id: <1298745018-5937-8-git-send-email-bwidawsk@gmail.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1298745018-5937-1-git-send-email-bwidawsk@gmail.com> References: <1298745018-5937-1-git-send-email-bwidawsk@gmail.com> Subject: [Intel-gfx] [RFC] [PATCH 7/8] drm/i915/context: context switch implementation X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Sat, 26 Feb 2011 18:41:55 +0000 (UTC) diff --git a/drivers/gpu/drm/i915/i915_context.c b/drivers/gpu/drm/i915/i915_context.c index 2e38fa8..3719a87 100644 --- a/drivers/gpu/drm/i915/i915_context.c +++ b/drivers/gpu/drm/i915/i915_context.c @@ -123,28 +123,34 @@ static int context_init(struct drm_i915_gem_context *ctx, */ last = ring->context_switch(ring, ctx, 0, I915_CONTEXT_SAVE_ONLY); - if (!last) { - ret = EIO; + if (last != ctx) { + DRM_ERROR("Context switch state invalid"); + ret = -EIO; goto err_out; } last = ring->context_switch(ring, ctx, 0, I915_CONTEXT_SAVE_ONLY | I915_CONTEXT_FORCED_SWITCH); - if (!last) { - ret = EIO; + if (last != ctx) { + DRM_ERROR("First context switch fail"); + ret = -EIO; goto err_out; } last = ring->context_switch(ring, ctx, 0, I915_CONTEXT_NORMAL_SWITCH | I915_CONTEXT_FORCED_SWITCH); + if (last != ctx) { + DRM_ERROR("Final context switch fail"); + ret = -EIO; + goto err_out; + } } else { last = ring->context_switch(ring, ctx, 0, I915_CONTEXT_SAVE_ONLY); - } - - if (!last) { - ret = EIO; - goto err_out; + if (!last) { + ret = -EIO; + goto err_out; + } } if (!last->is_default) @@ -346,7 +352,11 @@ void i915_context_load(struct drm_device *dev) ret = logical_context_alloc(dev, NULL, 0, &dev_priv->default_context); if (ret) dev_priv->contexts_disabled = true; + else { + DRM_DEBUG_DRIVER("HW context support initialized\n"); + } mutex_unlock(&dev->struct_mutex); + } void i915_context_unload(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 98ccbd9..39669ff 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -909,6 +909,7 @@ struct drm_i915_gem_context { uint8_t ring_enable; struct drm_i915_gem_object *obj; bool is_default; + bool is_initialized; struct drm_gem_object **bufs; int slot_count; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 789c478..7d18c07 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -734,6 +734,102 @@ render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, return 0; } +static int do_ring_switch(struct intel_ring_buffer *ring, + struct drm_i915_gem_context *new_context, + u32 hw_flags) +{ + struct drm_device *dev = ring->dev; + int ret = 0; + + if (!new_context->is_initialized) { + ret = intel_ring_begin(ring, 6); + if (ret) + return ret; + intel_ring_emit(ring, MI_NOOP | (1 << 22) | new_context->id); + intel_ring_emit(ring, MI_FLUSH); + } else { + ret = intel_ring_begin(ring, 4); + if (ret) + return ret; + } + + DRM_DEBUG_DRIVER("Context switch %d -> %d\n", + ring->last_context ? ring->last_context->id : -1, + new_context->id); + + if (IS_IRONLAKE_D(dev) || IS_IRONLAKE_M(dev)) + intel_ring_emit(ring, MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN); + else + intel_ring_emit(ring, MI_NOOP); + + intel_ring_emit(ring, MI_SET_CONTEXT); + intel_ring_emit(ring, new_context->obj->gtt_offset | + MI_MM_SPACE_GTT | + MI_SAVE_EXT_STATE_EN | + MI_RESTORE_EXT_STATE_EN | + hw_flags); + + if (IS_IRONLAKE_D(dev) || IS_IRONLAKE_M(dev)) + intel_ring_emit(ring, MI_SUSPEND_FLUSH); + /* TODO: we may need a NOOP here */ + else + intel_ring_emit(ring, MI_NOOP); + + intel_ring_advance(ring); + + return ret; + +} + +static struct drm_i915_gem_context * +render_ring_context_switch(struct intel_ring_buffer *ring, + struct drm_i915_gem_context *new_context, + u32 seqno, u32 flags) +{ + struct drm_device *dev = ring->dev; + bool force = (flags & I915_CONTEXT_FORCED_SWITCH) ? true : false; + struct drm_i915_gem_context *last = NULL; + uint32_t hw_flags = 0; + + if (WARN_ON(new_context->obj->gtt_offset == 0)) + return NULL; + + /* last_context is only protected by struct_mutex */ + WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + + if (!force && (ring->last_context == new_context)) { + if (WARN_ON(seqno == 0)) + seqno = ring->get_seqno(ring); + + if (!new_context->is_default) + i915_gem_object_move_to_active(new_context->obj, + ring, seqno); + return new_context; + } + + if (flags & I915_CONTEXT_SAVE_ONLY) + hw_flags = MI_RESTORE_INHIBIT; + + if (do_ring_switch(ring, new_context, hw_flags)) + return NULL; + + last = ring->last_context; + ring->last_context = new_context; + + if (last && !last->is_default) + i915_gem_object_move_to_active(last->obj, ring, seqno); + + /* XXX The first call to this default and last are NULL. Unfortunately + * the only mechanism we have to determine failure is */ + if (!new_context->is_initialized && !last) { + WARN_ON(!new_context->is_default); + last = new_context; + } else + new_context->is_initialized = true; + + return last; +} + static void cleanup_status_page(struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = ring->dev->dev_private; @@ -1008,6 +1104,7 @@ static const struct intel_ring_buffer render_ring = { .irq_put = render_ring_put_irq, .dispatch_execbuffer = render_ring_dispatch_execbuffer, .cleanup = render_ring_cleanup, + .context_switch = render_ring_context_switch, }; /* ring buffer for bit-stream decoder */