From patchwork Fri Mar 30 08:31:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: sagar.a.kamble@intel.com X-Patchwork-Id: 10317395 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8E74360212 for ; Fri, 30 Mar 2018 08:29:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 81F2B2A55F for ; Fri, 30 Mar 2018 08:29:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 771342A566; Fri, 30 Mar 2018 08:29:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DFF402A565 for ; Fri, 30 Mar 2018 08:29:17 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A0DF36E859; Fri, 30 Mar 2018 08:29:16 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id 70AC76E867 for ; Fri, 30 Mar 2018 08:28:55 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 30 Mar 2018 01:28:55 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,380,1517904000"; d="scan'208";a="38104637" Received: from sakamble-desktop.iind.intel.com ([10.223.26.10]) by FMSMGA003.fm.intel.com with ESMTP; 30 Mar 2018 01:28:52 -0700 From: Sagar Arun Kamble To: intel-gfx@lists.freedesktop.org Date: Fri, 30 Mar 2018 14:01:56 +0530 Message-Id: <1522398722-12161-12-git-send-email-sagar.a.kamble@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1522398722-12161-1-git-send-email-sagar.a.kamble@intel.com> References: <1522398722-12161-1-git-send-email-sagar.a.kamble@intel.com> Subject: [Intel-gfx] [PATCH v12 11/17] drm/i915/guc/slpc: Add support for sysfs min/max frequency control X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Sujaritha Sundaresan MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Update sysfs functions to set SLPC parameters when setting max/min user frequency limits. v1: Update for SLPC 2015.2.4 (params for both slice and unslice). Replace HAS_SLPC with intel_slpc_active() (Paulo) v2-v4: Rebase. v5: Removed typecasting the frequency values to u32. (Chris). Changed intel_slpc_active to guc.slpc.enabled. Carved out SLPC helpers to set min and max frequencies. v6: Rebase. Doing explicit SLPC reset on setting frequency to start sane and covered with RPM get/put. Caching SLPC limits post enabling first. v7: Rebase due to change in the dev_priv->pm.rps structure. v8: Updated returns from gt_min_freq_mhz_store and gt_max_freq_mhz_store and i915_min_freq_set and i915_max_freq_set. v9: Rebase. Debugfs interfaces will be removed hence only updated sysfs. Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/i915_sysfs.c | 52 +++++++++++++++++---- drivers/gpu/drm/i915/intel_guc_slpc.c | 86 ++++++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_guc_slpc.h | 6 +++ 3 files changed, 133 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index c3083fa..d1b4793 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -343,10 +343,20 @@ static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev, static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) { struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); + struct intel_guc_slpc *slpc = &dev_priv->guc.slpc; + u32 freq; - return snprintf(buf, PAGE_SIZE, "%d\n", - intel_gpu_freq(dev_priv, - dev_priv->gt_pm.rps.max_freq_softlimit)); + if (USES_GUC_SLPC(dev_priv)) { + mutex_lock(&slpc->lock); + freq = dev_priv->guc.slpc.max_unslice_freq; + mutex_unlock(&slpc->lock); + } else { + mutex_lock(&dev_priv->pcu_lock); + freq = dev_priv->gt_pm.rps.max_freq_softlimit; + mutex_lock(&dev_priv->pcu_lock); + } + + return snprintf(buf, PAGE_SIZE, "%d\n", intel_gpu_freq(dev_priv, freq)); } static ssize_t gt_max_freq_mhz_store(struct device *kdev, @@ -362,12 +372,17 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, if (ret) return ret; + val = intel_freq_opcode(dev_priv, val); + + if (USES_GUC_SLPC(dev_priv)) { + ret = intel_guc_slpc_max_freq_set(&dev_priv->guc.slpc, val); + goto out; + } + intel_runtime_pm_get(dev_priv); mutex_lock(&dev_priv->pcu_lock); - val = intel_freq_opcode(dev_priv, val); - if (val < rps->min_freq || val > rps->max_freq || val < rps->min_freq_softlimit) { @@ -395,16 +410,27 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, intel_runtime_pm_put(dev_priv); +out: return ret ?: count; } static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) { struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); + struct intel_guc_slpc *slpc = &dev_priv->guc.slpc; + u32 freq; - return snprintf(buf, PAGE_SIZE, "%d\n", - intel_gpu_freq(dev_priv, - dev_priv->gt_pm.rps.min_freq_softlimit)); + if (USES_GUC_SLPC(dev_priv)) { + mutex_lock(&slpc->lock); + freq = dev_priv->guc.slpc.min_unslice_freq; + mutex_unlock(&slpc->lock); + } else { + mutex_lock(&dev_priv->pcu_lock); + freq = dev_priv->gt_pm.rps.min_freq_softlimit; + mutex_lock(&dev_priv->pcu_lock); + } + + return snprintf(buf, PAGE_SIZE, "%d\n", intel_gpu_freq(dev_priv, freq)); } static ssize_t gt_min_freq_mhz_store(struct device *kdev, @@ -420,12 +446,17 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, if (ret) return ret; + val = intel_freq_opcode(dev_priv, val); + + if (USES_GUC_SLPC(dev_priv)) { + ret = intel_guc_slpc_min_freq_set(&dev_priv->guc.slpc, val); + goto out; + } + intel_runtime_pm_get(dev_priv); mutex_lock(&dev_priv->pcu_lock); - val = intel_freq_opcode(dev_priv, val); - if (val < rps->min_freq || val > rps->max_freq || val > rps->max_freq_softlimit) { @@ -449,6 +480,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, intel_runtime_pm_put(dev_priv); +out: return ret ?: count; } diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.c b/drivers/gpu/drm/i915/intel_guc_slpc.c index 011e442..34a5963 100644 --- a/drivers/gpu/drm/i915/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/intel_guc_slpc.c @@ -630,7 +630,7 @@ int intel_guc_slpc_init(struct intel_guc_slpc *slpc) */ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc) { - struct slpc_shared_data *data; + struct slpc_shared_data *data, output; struct page *page; mutex_lock(&slpc->lock); @@ -652,7 +652,91 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc) DRM_INFO("SLPC state: %s\n", slpc_get_state(slpc)); + slpc_read_shared_data(slpc, &output); + slpc->max_unslice_freq = output.task_state_data.max_unslice_freq * + GEN9_FREQ_SCALER; + slpc->min_unslice_freq = output.task_state_data.min_unslice_freq * + GEN9_FREQ_SCALER; + + mutex_unlock(&slpc->lock); + + return 0; +} + +/** + * intel_guc_slpc_max_freq_set() - Set max frequency limit for SLPC. + * @slpc: pointer to intel_guc_slpc. + * @val: encoded frequency + * + * This function will invoke GuC SLPC action to update the max frequency + * limit. + * + * Return: 0 on success, non-zero error code on failure. + */ +int intel_guc_slpc_max_freq_set(struct intel_guc_slpc *slpc, u32 val) +{ + struct intel_guc *guc = slpc_to_guc(slpc); + struct drm_i915_private *dev_priv = guc_to_i915(guc); + + if (val < dev_priv->gt_pm.rps.min_freq || + val > dev_priv->gt_pm.rps.max_freq || + val < slpc->min_unslice_freq) + return -EINVAL; + + intel_runtime_pm_get(dev_priv); + mutex_lock(&slpc->lock); + + slpc_set_param(slpc, + SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ, + intel_gpu_freq(dev_priv, val)); + slpc_set_param(slpc, + SLPC_PARAM_GLOBAL_MAX_GT_SLICE_FREQ_MHZ, + intel_gpu_freq(dev_priv, val)); + + host2guc_slpc_reset(slpc); + slpc->max_unslice_freq = val; + + mutex_unlock(&slpc->lock); + intel_runtime_pm_put(dev_priv); + + return 0; +} + +/** + * intel_guc_slpc_min_freq_set() - Set min frequency limit for SLPC. + * @slpc: pointer to intel_guc_slpc. + * @val: encoded frequency + * + * This function will invoke GuC SLPC action to update the min frequency + * limit. + * + * Return: 0 on success, non-zero error code on failure. + */ +int intel_guc_slpc_min_freq_set(struct intel_guc_slpc *slpc, u32 val) +{ + struct intel_guc *guc = slpc_to_guc(slpc); + struct drm_i915_private *dev_priv = guc_to_i915(guc); + + if (val < dev_priv->gt_pm.rps.min_freq || + val > dev_priv->gt_pm.rps.max_freq || + val > slpc->max_unslice_freq) + return -EINVAL; + + intel_runtime_pm_get(dev_priv); + mutex_lock(&slpc->lock); + + slpc_set_param(slpc, + SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, + intel_gpu_freq(dev_priv, val)); + slpc_set_param(slpc, + SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ, + intel_gpu_freq(dev_priv, val)); + + host2guc_slpc_reset(slpc); + slpc->min_unslice_freq = val; + mutex_unlock(&slpc->lock); + intel_runtime_pm_put(dev_priv); return 0; } diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.h b/drivers/gpu/drm/i915/intel_guc_slpc.h index 87b504d..51189b3 100644 --- a/drivers/gpu/drm/i915/intel_guc_slpc.h +++ b/drivers/gpu/drm/i915/intel_guc_slpc.h @@ -12,6 +12,10 @@ struct intel_guc_slpc { /* Protects access to vma and SLPC actions */ struct mutex lock; struct i915_vma *vma; + + /* i915 cached SLPC frequency limits */ + u32 min_unslice_freq; + u32 max_unslice_freq; }; int intel_guc_slpc_task_control(struct intel_guc_slpc *slpc, u64 val, @@ -21,6 +25,8 @@ int intel_guc_slpc_task_status(struct intel_guc_slpc *slpc, u64 *val, int intel_guc_slpc_init(struct intel_guc_slpc *slpc); int intel_guc_slpc_enable(struct intel_guc_slpc *slpc); +int intel_guc_slpc_max_freq_set(struct intel_guc_slpc *slpc, u32 val); +int intel_guc_slpc_min_freq_set(struct intel_guc_slpc *slpc, u32 val); void intel_guc_slpc_handle_engine_reset(struct intel_guc_slpc *slpc); void intel_guc_slpc_disable(struct intel_guc_slpc *slpc); void intel_guc_slpc_fini(struct intel_guc_slpc *slpc);