From patchwork Sat May 25 19:26:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 2614011 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 6C8F3DF2A2 for ; Sat, 25 May 2013 19:30:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5742FE5DE3 for ; Sat, 25 May 2013 12:30:55 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from shiva.localdomain (unknown [209.20.75.48]) by gabe.freedesktop.org (Postfix) with ESMTP id 77006E5DD8 for ; Sat, 25 May 2013 12:24:46 -0700 (PDT) Received: by shiva.localdomain (Postfix, from userid 1005) id B9CC888630; Sat, 25 May 2013 19:24:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on shiva.chad-versace.us X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, URIBL_BLOCKED autolearn=ham version=3.3.2 Received: from lundgren.kumite (c-24-21-100-90.hsd1.or.comcast.net [24.21.100.90]) by shiva.localdomain (Postfix) with ESMTPSA id CB3C288081; Sat, 25 May 2013 19:24:38 +0000 (UTC) From: Ben Widawsky To: Intel GFX Date: Sat, 25 May 2013 12:26:46 -0700 Message-Id: <1369510028-3343-13-git-send-email-ben@bwidawsk.net> X-Mailer: git-send-email 1.8.2.3 In-Reply-To: <1369510028-3343-1-git-send-email-ben@bwidawsk.net> References: <1369510028-3343-1-git-send-email-ben@bwidawsk.net> Cc: Ben Widawsky Subject: [Intel-gfx] [PATCH 12/34] drm/i915: Split context enabling from init X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 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 We **need** to do this for exactly 1 reason, because we want to embed a PPGTT into the context, but we don't want to special case the default context. To achieve that, we must be able to initialize contexts after the GTT is setup (so we can allocate and pin the default context's BO), but before the PPGTT and rings are initialized. This is because, currently, context initialization requires ring usage. We don't have rings until after the GTT is setup. If we split the enabling part of context initialization, the part requiring the ringbuffer, we can untangle this, and then later embed the PPGTT Incidentally this allows us to also adhere to the original design of context init/fini in future patches: they were only ever meant to be called at driver load and unload. v2: Move hw_contexts_disabled test in i915_gem_context_enable() (Chris) Signed-off-by: Ben Widawsky --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 15 ++++++++++++--- drivers/gpu/drm/i915/i915_gem_context.c | 23 ++++++++++++----------- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d6dd26a..f1b59b1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1715,6 +1715,7 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev, /* i915_gem_context.c */ void i915_gem_context_init(struct drm_device *dev); void i915_gem_context_fini(struct drm_device *dev); +int i915_gem_context_enable(struct drm_i915_private *dev_priv); void i915_gem_context_close(struct drm_device *dev, struct drm_file *file); int i915_switch_context(struct intel_ring_buffer *ring, struct drm_file *file, int to_id); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6d0d302..674154f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4036,10 +4036,17 @@ i915_gem_init_hw(struct drm_device *dev) return ret; /* - * XXX: There was some w/a described somewhere suggesting loading - * contexts before PPGTT. + * XXX: Contexts should only be initialized once. Doing a switch to the + * default context switch however is something we'd like to do after + * reset or thaw (the latter may not actually be necessary for HW, but + * goes with our code better). Context switching requires rings (for + * the do_switch), but before enabling PPGTT. So don't move this. */ - i915_gem_context_init(dev); + if (i915_gem_context_enable(dev_priv)) { + i915_gem_context_fini(dev); + dev_priv->hw_contexts_disabled = true; + } + if (dev_priv->mm.aliasing_ppgtt) { ret = dev_priv->mm.aliasing_ppgtt->enable(dev); if (ret) { @@ -4067,6 +4074,8 @@ int i915_gem_init(struct drm_device *dev) i915_gem_init_global_gtt(dev); + i915_gem_context_init(dev); + ret = i915_gem_init_hw(dev); mutex_unlock(&dev->struct_mutex); if (ret) { diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 9ce0acd..454a2b5 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -219,19 +219,11 @@ static int create_default_context(struct drm_i915_private *dev_priv) goto err_destroy; } - ret = do_switch(ctx); - if (ret) { - DRM_DEBUG_DRIVER("Switch failed %d\n", ret); - goto err_unpin; - } - dev_priv->ring[RCS].default_context = ctx; DRM_DEBUG_DRIVER("Default HW context loaded\n"); return 0; -err_unpin: - i915_gem_object_unpin(ctx->obj); err_destroy: i915_gem_context_unreference(ctx); return ret; @@ -247,9 +239,10 @@ void i915_gem_context_init(struct drm_device *dev) return; } - /* If called from reset, or thaw... we've been here already */ - if (dev_priv->hw_contexts_disabled || - dev_priv->ring[RCS].default_context) + /* Init should only be called once per module load. Eventually the + * restriction on the context_disabled check can be loosened. */ + if (WARN_ON(dev_priv->hw_contexts_disabled || + WARN_ON(dev_priv->ring[RCS].default_context))) return; dev_priv->hw_context_size = round_up(get_context_size(dev), 4096); @@ -302,6 +295,14 @@ void i915_gem_context_fini(struct drm_device *dev) dev_priv->ring[RCS].last_context = NULL; } +int i915_gem_context_enable(struct drm_i915_private *dev_priv) +{ + BUG_ON(!dev_priv->ring[RCS].default_context); + if (dev_priv->hw_contexts_disabled) + return 0; + return do_switch(dev_priv->ring[RCS].default_context); +} + static int context_idr_cleanup(int id, void *p, void *data) { struct i915_hw_context *ctx = p;