From patchwork Tue Nov 2 08:31:01 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zou, Nanhai" X-Patchwork-Id: 296822 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 oA28VirZ012272 for ; Tue, 2 Nov 2010 08:32:04 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F23239E935 for ; Tue, 2 Nov 2010 01:31:43 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id F0CDD9E82A for ; Tue, 2 Nov 2010 01:31:27 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 02 Nov 2010 01:31:27 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.58,279,1286175600"; d="scan'208";a="673336623" Received: from linux-g45.sh.intel.com (HELO hdmi.sh.intel.com) ([10.239.13.29]) by orsmga001.jf.intel.com with ESMTP; 02 Nov 2010 01:31:26 -0700 From: Zou Nan hai To: intel-gfx@lists.freedesktop.org, Chris Wilson Date: Tue, 2 Nov 2010 16:31:01 +0800 Message-Id: <1288686661-12154-1-git-send-email-nanhai.zou@intel.com> X-Mailer: git-send-email 1.7.1 Subject: [Intel-gfx] [PATCH] drm/i915: SNB BLT workaround 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.3 (demeter1.kernel.org [140.211.167.41]); Tue, 02 Nov 2010 08:32:05 +0000 (UTC) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 09f2dc3..4070f32 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -854,15 +854,98 @@ blt_ring_put_user_irq(struct drm_device *dev, /* do nothing */ } + +/* workaround for some stepping of SNB, + each time when BLT engine ring tail moved, + the first command in the ring to be parsed + should be MI_BATCH_BUFFER_START + */ +static struct drm_gem_object *wa_batch; +static unsigned long wa_batch_addr; + +#define NEED_BLT_WORKAROUND(dev) \ + (IS_GEN6(dev) && (dev->pdev->revision < 8)) + +static int blt_ring_init(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + u32 *ptr; + struct drm_i915_gem_object *batch; + if (NEED_BLT_WORKAROUND(dev) && wa_batch == NULL) { + wa_batch = i915_gem_alloc_object(dev, 4096); + + i915_gem_object_pin(wa_batch, 4096); + + batch = to_intel_bo(wa_batch); + wa_batch_addr = batch->gtt_offset; + + ptr = kmap(batch->pages[0]); + memset((u8 *)ptr, 0, 4096); + *ptr = MI_BATCH_BUFFER_END; + kunmap(batch->pages[0]); + } + return init_ring_common(dev, ring); +} + +static void blt_ring_flush(struct drm_device *dev, + struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains) +{ + if (NEED_BLT_WORKAROUND(dev)) { + intel_ring_begin(dev, ring, 6); + intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START); + intel_ring_emit(dev, ring, wa_batch_addr); + } else + intel_ring_begin(dev, ring, 4); + + intel_ring_emit(dev, ring, MI_FLUSH_DW); + intel_ring_emit(dev, ring, 0); + intel_ring_emit(dev, ring, 0); + intel_ring_emit(dev, ring, 0); + + intel_ring_advance(dev, ring); +} + +static u32 +blt_ring_add_request(struct drm_device *dev, + struct intel_ring_buffer *ring, + u32 flush_domains) +{ + u32 seqno; + + seqno = i915_gem_get_seqno(dev); + + if (NEED_BLT_WORKAROUND(dev)) { + intel_ring_begin(dev, ring, 6); + intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START); + intel_ring_emit(dev, ring, wa_batch_addr); + } else { + intel_ring_begin(dev, ring, 4); + } + + intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); + intel_ring_emit(dev, ring, + I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(dev, ring, seqno); + intel_ring_emit(dev, ring, MI_USER_INTERRUPT); + + intel_ring_advance(dev, ring); + + DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); + + return seqno; +} + static const struct intel_ring_buffer gen6_blt_ring = { .name = "blt ring", .id = RING_BLT, .mmio_base = BLT_RING_BASE, .size = 32 * PAGE_SIZE, - .init = init_ring_common, + .init = blt_ring_init, .write_tail = ring_write_tail, - .flush = gen6_ring_flush, - .add_request = ring_add_request, + .flush = blt_ring_flush, + .add_request = blt_ring_add_request, .get_seqno = ring_status_page_get_seqno, .user_irq_get = blt_ring_get_user_irq, .user_irq_put = blt_ring_put_user_irq,