From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ben Widawsky Subject: [PATCH 54/66] drm/i915: USE LRI for switching PP_DIR_BASE Date: Thu, 27 Jun 2013 16:30:55 -0700 Message-ID: <1372375867-1003-55-git-send-email-ben@bwidawsk.net> References: <1372375867-1003-1-git-send-email-ben@bwidawsk.net> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from shiva.localdomain (unknown [209.20.75.48]) by gabe.freedesktop.org (Postfix) with ESMTP id 68D75E5F39 for ; Thu, 27 Jun 2013 16:28:36 -0700 (PDT) In-Reply-To: <1372375867-1003-1-git-send-email-ben@bwidawsk.net> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces+gcfxdi-intel-gfx=m.gmane.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+gcfxdi-intel-gfx=m.gmane.org@lists.freedesktop.org To: Intel GFX Cc: Ben Widawsky List-Id: intel-gfx@lists.freedesktop.org The docs seem to suggest this is the appropriate method (though it doesn't say so outright). We certainly must do this for switching VMs on the fly, since synchronizing the rings to MMIO updates isn't acceptable. Signed-off-by: Ben Widawsky --- drivers/gpu/drm/i915/i915_gem_gtt.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 583d136..be5c7a9 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -171,13 +171,44 @@ static int gen6_ppgtt_enable(struct i915_hw_ppgtt *ppgtt) /* GFX_MODE is per-ring on gen7+ */ } + POSTING_READ(GAM_ECOCHK); for_each_ring(ring, dev_priv, i) { + int ret; + if (INTEL_INFO(dev)->gen >= 7) I915_WRITE(RING_MODE_GEN7(ring), _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); - I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); - I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset); + /* If we're in reset, we can assume the GPU is sufficiently idle + * to manually frob these bits. Ideally we could use the ring + * functions, except our error handling makes it quite difficult + * (can't use intel_ring_begin, ring->flush, or + * intel_ring_advance) + */ + if (i915_reset_in_progress(&dev_priv->gpu_error)) { + WARN_ON(ppgtt != dev_priv->gtt.aliasing_ppgtt); + I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); + I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset); + return 0; + } + + /* NB: TLBs must be flushed and invalidated before a switch */ + ret = ring->flush(ring, I915_GEM_GPU_DOMAINS, + I915_GEM_GPU_DOMAINS); + if (ret) + return ret; + + ret = intel_ring_begin(ring, 6); + if (ret) + return ret; + + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(2)); + intel_ring_emit(ring, RING_PP_DIR_DCLV(ring)); + intel_ring_emit(ring, PP_DIR_DCLV_2G); + intel_ring_emit(ring, RING_PP_DIR_BASE(ring)); + intel_ring_emit(ring, pd_offset); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); } return 0; } -- 1.8.3.1