From ce93ba218ad070e0b1ae6f9823820fb4d2e14a8b Mon Sep 17 00:00:00 2001 From: Vinay Belgaumkar Date: Fri, 9 Jul 2021 18:20:18 -0700 Subject: [PATCH] drm/i915/guc/slpc: Add methods to set min/max frequency Add param set h2g helpers to set the min and max frequencies for use by SLPC. Signed-off-by: Sundaresan Sujaritha Signed-off-by: Vinay Belgaumkar --- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 94 +++++++++++++++++++++ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h | 2 + 2 files changed, 96 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c index e579408d1c197f..19cb264799426e 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -106,6 +106,19 @@ static int slpc_send(struct intel_guc_slpc *slpc, return intel_guc_send(guc, action, in_len); } +static int host2guc_slpc_set_param(struct intel_guc_slpc *slpc, + u32 id, u32 value) +{ + struct slpc_event_input data = {0}; + + data.header.value = SLPC_EVENT(SLPC_EVENT_PARAMETER_SET, 2); + data.args[0] = id; + data.args[1] = value; + + return slpc_send(slpc, &data, 4); +} + + static bool slpc_running(struct intel_guc_slpc *slpc) { struct slpc_shared_data *data; @@ -134,6 +147,19 @@ static int host2guc_slpc_query_task_state(struct intel_guc_slpc *slpc) return slpc_send(slpc, &data, 4); } +static int slpc_set_param(struct intel_guc_slpc *slpc, u32 id, u32 value) +{ + struct drm_i915_private *i915 = slpc_to_i915(slpc); + GEM_BUG_ON(id >= SLPC_MAX_PARAM); + + if (host2guc_slpc_set_param(slpc, id, value)) { + drm_err(&i915->drm, "Unable to set param %x", id); + return -EIO; + } + + return 0; +} + static int slpc_read_task_state(struct intel_guc_slpc *slpc) { return host2guc_slpc_query_task_state(slpc); @@ -218,6 +244,74 @@ int intel_guc_slpc_init(struct intel_guc_slpc *slpc) return slpc_shared_data_init(slpc); } +/** + * 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 for slice and unslice. + * + * Return: 0 on success, non-zero error code on failure. + */ +int intel_guc_slpc_set_max_freq(struct intel_guc_slpc *slpc, u32 val) +{ + int ret; + struct drm_i915_private *i915 = slpc_to_i915(slpc); + intel_wakeref_t wakeref; + + wakeref = intel_runtime_pm_get(&i915->runtime_pm); + + ret = slpc_set_param(slpc, + SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ, + val); + + if (ret) { + drm_err(&i915->drm, + "Set max frequency unslice returned %d", ret); + ret = -EIO; + goto done; + } + +done: + intel_runtime_pm_put(&i915->runtime_pm, wakeref); + return ret; +} + +/** + * 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_set_min_freq(struct intel_guc_slpc *slpc, u32 val) +{ + int ret; + struct intel_guc *guc = slpc_to_guc(slpc); + struct drm_i915_private *i915 = guc_to_gt(guc)->i915; + intel_wakeref_t wakeref; + + wakeref = intel_runtime_pm_get(&i915->runtime_pm); + + ret = slpc_set_param(slpc, + SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, + val); + if (ret) { + drm_err(&i915->drm, + "Set min frequency for unslice returned %d", ret); + ret = -EIO; + goto done; + } + +done: + intel_runtime_pm_put(&i915->runtime_pm, wakeref); + return ret; +} + /* * intel_guc_slpc_enable() - Start SLPC * @slpc: pointer to intel_guc_slpc. diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h index a2643b904165f5..a473e1ea7c1015 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h @@ -34,5 +34,7 @@ struct intel_guc_slpc { int intel_guc_slpc_init(struct intel_guc_slpc *slpc); int intel_guc_slpc_enable(struct intel_guc_slpc *slpc); void intel_guc_slpc_fini(struct intel_guc_slpc *slpc); +int intel_guc_slpc_set_max_freq(struct intel_guc_slpc *slpc, u32 val); +int intel_guc_slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 val); #endif