From patchwork Fri Nov 7 18:14:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Gordon X-Patchwork-Id: 5254891 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 54F379F387 for ; Fri, 7 Nov 2014 18:14:40 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5C1E32012B for ; Fri, 7 Nov 2014 18:14:39 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 5ECEB2011B for ; Fri, 7 Nov 2014 18:14:38 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9885E6ECD3; Fri, 7 Nov 2014 10:14:37 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id 6D4E96ECD3 for ; Fri, 7 Nov 2014 10:14:35 -0800 (PST) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga101.fm.intel.com with ESMTP; 07 Nov 2014 10:14:14 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,862,1389772800"; d="scan'208";a="413130100" Received: from dsgordon-linux.isw.intel.com ([10.102.226.64]) by FMSMGA003.fm.intel.com with ESMTP; 07 Nov 2014 10:05:34 -0800 From: Dave Gordon To: intel-gfx@lists.freedesktop.org Date: Fri, 7 Nov 2014 18:14:11 +0000 Message-Id: <1415384051-6596-1-git-send-email-david.s.gordon@intel.com> X-Mailer: git-send-email 1.7.9.5 Subject: [Intel-gfx] [PATCH] drm/i915: Refactor gen6_gt_force_wake_{get, put} 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.8 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 This is largely for the benefit of TDR, which needs to be able to call the forcewake functions from a context where it must not sleep. Hence we split the forcewake {get,put} operations into inner core versions that don't include pm {get,put} calls, and outer wrappers that do. Callers of the existing interfaces will see no change from this, but it will enable TDR to safely access the registers it needs to sample. Signed-off-by: Dave Gordon --- drivers/gpu/drm/i915/intel_uncore.c | 61 ++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 68e722b..c2d3896 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -560,20 +560,19 @@ void intel_uncore_sanitize(struct drm_device *dev) } /* - * Generally this is called implicitly by the register read function. However, - * if some sequence requires the GT to not power down then this function should - * be called at the beginning of the sequence followed by a call to - * gen6_gt_force_wake_put() at the end of the sequence. + * Inner core of the force_wake_get operation, exposed for the + * benefit of special cases such as TDR. You should only use + * this interface if (a) you need not to sleep, and (b) you know + * a priori that PM issues have been handled elsewhere. All other + * callers should use the regular version below. */ -void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine) +void gen6_gt_force_wake_get_no_pm(struct drm_i915_private *dev_priv, int fw_engine) { unsigned long irqflags; if (!dev_priv->uncore.funcs.force_wake_get) return; - intel_runtime_pm_get(dev_priv); - /* Redirect to Gen9 specific routine */ if (IS_GEN9(dev_priv->dev)) return gen9_force_wake_get(dev_priv, fw_engine); @@ -589,9 +588,33 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine) } /* - * see gen6_gt_force_wake_get() + * Generally this is called implicitly by the register read function. + * However, if some sequence of accesses requires the GT to not power + * down between accesses then this function should be called at the + * beginning of the sequence followed by a gen6_gt_force_wake_put() at + * the end of the sequence. */ -void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) +void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine) +{ + /* No forcewake implies no PM either */ + if (!dev_priv->uncore.funcs.force_wake_get) + return; + + intel_runtime_pm_get(dev_priv); + + gen6_gt_force_wake_get_no_pm(dev_priv, fw_engine); +} + +/* + * see gen6_gt_force_wake_get_no_pm() + * + * This function returns true if the refcount would have gone to zero, + * but the actual forcewake_put operation has been deferred to a timed + * callback, and thus the caller must NOT call intel_runtime_pm_put(). + * In all other cases (count would not have gone to zero, or it did and + * the hardware operation has already completed), it returns false. + */ +bool gen6_gt_force_wake_put_no_pm(struct drm_i915_private *dev_priv, int fw_engine) { unsigned long irqflags; bool delayed = false; @@ -602,13 +625,13 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) /* Redirect to Gen9 specific routine */ if (IS_GEN9(dev_priv->dev)) { gen9_force_wake_put(dev_priv, fw_engine); - goto out; + return false; } /* Redirect to VLV specific routine */ if (IS_VALLEYVIEW(dev_priv->dev)) { vlv_force_wake_put(dev_priv, fw_engine); - goto out; + return false; } @@ -623,7 +646,21 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) } spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); -out: + return delayed; +} + +/* + * see gen6_gt_force_wake_get() + */ +void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) +{ + bool delayed; + + /* No forcewake implies no PM either */ + if (!dev_priv->uncore.funcs.force_wake_put) + return; + + delayed = gen6_gt_force_wake_put_no_pm(dev_priv, fw_engine); if (!delayed) intel_runtime_pm_put(dev_priv); }