From patchwork Wed Dec 17 15:19:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Gordon X-Patchwork-Id: 5507321 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 0CABEBEEA8 for ; Wed, 17 Dec 2014 15:19:24 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0AAF120A22 for ; Wed, 17 Dec 2014 15:19:23 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id D5FDA20A16 for ; Wed, 17 Dec 2014 15:19:21 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CE97B6E8BE; Wed, 17 Dec 2014 07:19:20 -0800 (PST) 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 AC3996E8BE for ; Wed, 17 Dec 2014 07:19:19 -0800 (PST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 17 Dec 2014 07:19:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.07,594,1413270000"; d="scan'208";a="655655940" Received: from dsgordon-linux.isw.intel.com ([10.102.226.149]) by orsmga002.jf.intel.com with ESMTP; 17 Dec 2014 07:19:18 -0800 From: Dave Gordon To: intel-gfx@lists.freedesktop.org Date: Wed, 17 Dec 2014 15:19:02 +0000 Message-Id: <1418829542-9608-1-git-send-email-david.s.gordon@intel.com> X-Mailer: git-send-email 1.7.9.5 Subject: [Intel-gfx] [PATCH] drm/i915: use TAIL rather than ACTHD for synchronising reads X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 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.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_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 On some generations of chips, it is necessary to read an MMIO register before getting the sequence number from the status page in main memory, in order to ensure coherency; and on all generations this should be either helpful or harmless. In general, we want this operation to be the cheapest possible, since we require only the side-effect of DMA completion and don't interpret the result of the read, and don't require any coordination with other threads, power domains, or anything else. However, finding a suitable register may be problematic; on GEN6 chips the ACTHD register was used, but on VLV et al access to this register requires FORCEWAKE and therefore many complications involving spinlocks and polling. So this commit introduces this synchronising operation as a distinct vfunc in uncore, so that it can be GEN- or chip-specific if needed. For now, a sample 'universal' implementation is provided which just reads the TAIL register of the render engine, this being a register which should always be accessible on all GENs without requiring forcewake or other complications. We then change gen6_ring_get_seqno() to use this new SYNC_READ rather than a POSTING_READ of ACTHD. Note that both older (pre-GEN6) and newer (GEN8+) devices don't currently include any posting read in their own get_seqno() implementations, so this affects only GEN6 and 7 devices. Signed-off-by: Dave Gordon Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com) --- drivers/gpu/drm/i915/i915_drv.h | 7 +++++++ drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +- drivers/gpu/drm/i915/intel_uncore.c | 9 +++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3047291f..9826cb6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -593,6 +593,9 @@ struct intel_uncore_funcs { uint32_t val, bool trace); void (*mmio_writeq)(struct drm_i915_private *dev_priv, off_t offset, uint64_t val, bool trace); + + /* Read any suitable register, for DMA synchronisation purposes only */ + void (*sync_read)(struct drm_i915_private *dev_priv); }; struct intel_uncore { @@ -3161,6 +3164,8 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val); #define I915_READ_NOTRACE(reg) dev_priv->uncore.funcs.mmio_readl(dev_priv, (reg), false) #define I915_WRITE_NOTRACE(reg, val) dev_priv->uncore.funcs.mmio_writel(dev_priv, (reg), (val), false) +#define I915_SYNC_READ() dev_priv->uncore.funcs.sync_read(dev_priv) + /* Be very careful with read/write 64-bit values. On 32-bit machines, they * will be implemented using 2 32-bit writes in an arbitrary order with * an arbitrary delay between them. This can cause the hardware to @@ -3184,6 +3189,8 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val); #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) #define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) +#define SYNC_READ() I915_SYNC_READ() + /* "Broadcast RGB" property */ #define INTEL_BROADCAST_RGB_AUTO 0 #define INTEL_BROADCAST_RGB_FULL 1 diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 12a36f0..74bffce 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1217,7 +1217,7 @@ gen6_ring_get_seqno(struct intel_engine_cs *ring, bool lazy_coherency) * ACTHD) before reading the status page. */ if (!lazy_coherency) { struct drm_i915_private *dev_priv = ring->dev->dev_private; - POSTING_READ(RING_ACTHD(ring->mmio_base)); + SYNC_READ(); } return intel_read_status_page(ring, I915_GEM_HWS_INDEX); diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index e9561de..8fc40c4 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -737,6 +737,14 @@ hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv) } } +static void +gen4_sync_read(struct drm_i915_private *dev_priv) +{ + /* No HEADER, no FOOTER, just the raw read */ + (void)__raw_i915_read32(dev_priv, + RING_TAIL(dev_priv->ring[RCS].mmio_base)); +} + #define REG_READ_HEADER(x) \ unsigned long irqflags; \ u##x val = 0; \ @@ -1139,6 +1147,7 @@ do { \ dev_priv->uncore.funcs.mmio_readw = x##_read16; \ dev_priv->uncore.funcs.mmio_readl = x##_read32; \ dev_priv->uncore.funcs.mmio_readq = x##_read64; \ + dev_priv->uncore.funcs.sync_read = gen4_sync_read; \ } while (0) void intel_uncore_init(struct drm_device *dev)