From patchwork Thu Jun 26 17:23:57 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Harrison X-Patchwork-Id: 4428971 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E9CDC9F319 for ; Thu, 26 Jun 2014 17:25:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 799FC2038C for ; Thu, 26 Jun 2014 17:25:31 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 1836E20272 for ; Thu, 26 Jun 2014 17:25:27 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 86F3C6E1C2; Thu, 26 Jun 2014 10:25:26 -0700 (PDT) X-Original-To: Intel-GFX@lists.freedesktop.org Delivered-To: Intel-GFX@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTP id DCF056E1DB for ; Thu, 26 Jun 2014 10:25:25 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 26 Jun 2014 10:25:25 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.01,554,1400050800"; d="scan'208";a="561434566" Received: from johnharr-linux.iwi.intel.com ([172.28.253.52]) by fmsmga002.fm.intel.com with ESMTP; 26 Jun 2014 10:25:01 -0700 From: John.C.Harrison@Intel.com To: Intel-GFX@lists.freedesktop.org Date: Thu, 26 Jun 2014 18:23:57 +0100 Message-Id: <1403803475-16337-7-git-send-email-John.C.Harrison@Intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1403803475-16337-1-git-send-email-John.C.Harrison@Intel.com> References: <1403803475-16337-1-git-send-email-John.C.Harrison@Intel.com> Organization: Intel Corporation (UK) Ltd. - Co. Reg. #1134945 - Pipers Way, Swindon SN3 1RJ Subject: [Intel-gfx] [RFC 06/44] drm/i915: Fixes for FIFO space queries X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.15 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 From: John Harrison The previous code was not correctly masking the value of the GTFIFOCTL register, leading to overruns and the message "MMIO read or write has been dropped". In addition, the checks were repeated in several different places. This commit replaces these various checks with a simple (inline) function to encapsulate the read-and-mask operation. In addition, it adds a custom wait-for-fifo function for VLV, as the timing parameters are somewhat different from those on earlier chips. Reviewed-by: Jesse Barnes --- drivers/gpu/drm/i915/intel_uncore.c | 49 ++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 871c284..6a3dddf 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -47,6 +47,12 @@ assert_device_not_suspended(struct drm_i915_private *dev_priv) "Device suspended\n"); } +static inline u32 fifo_free_entries(struct drm_i915_private *dev_priv) +{ + u32 count = __raw_i915_read32(dev_priv, GTFIFOCTL); + return count & GT_FIFO_FREE_ENTRIES_MASK; +} + static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) { u32 gt_thread_status_mask; @@ -154,6 +160,28 @@ static void __gen7_gt_force_wake_mt_put(struct drm_i915_private *dev_priv, gen6_gt_check_fifodbg(dev_priv); } +static int __vlv_gt_wait_for_fifo(struct drm_i915_private *dev_priv) +{ + u32 free = fifo_free_entries(dev_priv); + int loop1, loop2; + + for (loop1 = 0; loop1 < 5000 && free < GT_FIFO_NUM_RESERVED_ENTRIES; ) { + for (loop2 = 0; loop2 < 1000 && free < GT_FIFO_NUM_RESERVED_ENTRIES; loop2 += 10) { + udelay(10); + free = fifo_free_entries(dev_priv); + } + loop1 += loop2; + if (loop1 > 1000 || free < 48) + DRM_DEBUG("after %d us, the FIFO has %d slots", loop1, free); + } + + dev_priv->uncore.fifo_count = free; + if (WARN(free < GT_FIFO_NUM_RESERVED_ENTRIES, + "FIFO has insufficient space (%d slots)", free)) + return -1; + return 0; +} + static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) { int ret = 0; @@ -161,16 +189,15 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) /* On VLV, FIFO will be shared by both SW and HW. * So, we need to read the FREE_ENTRIES everytime */ if (IS_VALLEYVIEW(dev_priv->dev)) - dev_priv->uncore.fifo_count = - __raw_i915_read32(dev_priv, GTFIFOCTL) & - GT_FIFO_FREE_ENTRIES_MASK; + return __vlv_gt_wait_for_fifo(dev_priv); if (dev_priv->uncore.fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) { int loop = 500; - u32 fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK; + u32 fifo = fifo_free_entries(dev_priv); + while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) { udelay(10); - fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK; + fifo = fifo_free_entries(dev_priv); } if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES)) ++ret; @@ -194,6 +221,11 @@ static void vlv_force_wake_reset(struct drm_i915_private *dev_priv) static void __vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine) { +#if 1 + if (__gen6_gt_wait_for_fifo(dev_priv)) + gen6_gt_check_fifodbg(dev_priv); +#endif + /* Check for Render Engine */ if (FORCEWAKE_RENDER & fw_engine) { if (wait_for_atomic((__raw_i915_read32(dev_priv, @@ -238,6 +270,10 @@ static void __vlv_force_wake_get(struct drm_i915_private *dev_priv, static void __vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) { +#if 1 + if (__gen6_gt_wait_for_fifo(dev_priv)) + gen6_gt_check_fifodbg(dev_priv); +#endif /* Check for Render Engine */ if (FORCEWAKE_RENDER & fw_engine) @@ -355,8 +391,7 @@ static void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore) if (IS_GEN6(dev) || IS_GEN7(dev)) dev_priv->uncore.fifo_count = - __raw_i915_read32(dev_priv, GTFIFOCTL) & - GT_FIFO_FREE_ENTRIES_MASK; + fifo_free_entries(dev_priv); } else { dev_priv->uncore.forcewake_count = 0; dev_priv->uncore.fw_rendercount = 0;