diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/amd/include/kgd_pp_interface.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 42 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 14 |
5 files changed, 77 insertions, 5 deletions
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 387120099493..a4c267f15959 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -321,6 +321,7 @@ struct amd_pm_funcs { int (*get_fan_speed_pwm)(void *handle, u32 *speed); int (*force_clock_level)(void *handle, enum pp_clock_type type, uint32_t mask); int (*print_clock_levels)(void *handle, enum pp_clock_type type, char *buf); + int (*emit_clock_levels)(void *handle, enum pp_clock_type type, char *buf, int *offset); int (*force_performance_level)(void *handle, enum amd_dpm_forced_level level); int (*get_sclk_od)(void *handle); int (*set_sclk_od)(void *handle, uint32_t value); diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c index ef574c96b41c..1d63f1e8884c 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -890,6 +890,27 @@ int amdgpu_dpm_print_clock_levels(struct amdgpu_device *adev, return ret; } +int amdgpu_dpm_emit_clock_levels(struct amdgpu_device *adev, + enum pp_clock_type type, + char *buf, + int *offset) +{ + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; + int ret = 0; + + if (!pp_funcs->emit_clock_levels) + return -ENOENT; + + mutex_lock(&adev->pm.mutex); + ret = pp_funcs->emit_clock_levels(adev->powerplay.pp_handle, + type, + buf, + offset); + mutex_unlock(&adev->pm.mutex); + + return ret; +} + int amdgpu_dpm_set_ppfeature_status(struct amdgpu_device *adev, uint64_t ppfeature_masks) { diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h index 5cc05110cdae..1ed0ef898eb0 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h @@ -441,6 +441,10 @@ int amdgpu_dpm_odn_edit_dpm_table(struct amdgpu_device *adev, int amdgpu_dpm_print_clock_levels(struct amdgpu_device *adev, enum pp_clock_type type, char *buf); +int amdgpu_dpm_emit_clock_levels(struct amdgpu_device *adev, + enum pp_clock_type type, + char *buf, + int *offset); int amdgpu_dpm_set_ppfeature_status(struct amdgpu_device *adev, uint64_t ppfeature_masks); int amdgpu_dpm_get_ppfeature_status(struct amdgpu_device *adev, char *buf); diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 9861d70a5dad..af368aa1fd0a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -2216,11 +2216,8 @@ static int smu_print_smuclk_levels(struct smu_context *smu, enum smu_clk_type cl return ret; } -static int smu_print_ppclk_levels(void *handle, - enum pp_clock_type type, - char *buf) +static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type type) { - struct smu_context *smu = handle; enum smu_clk_type clk_type; switch (type) { @@ -2253,12 +2250,46 @@ static int smu_print_ppclk_levels(void *handle, case OD_CCLK: clk_type = SMU_OD_CCLK; break; default: - return -EINVAL; + clk_type = SMU_CLK_COUNT; break; } + return clk_type; +} + +static int smu_print_ppclk_levels(void *handle, + enum pp_clock_type type, + char *buf) +{ + struct smu_context *smu = handle; + enum smu_clk_type clk_type; + + clk_type = smu_convert_to_smuclk(type); + if (clk_type == SMU_CLK_COUNT) + return -EINVAL; + return smu_print_smuclk_levels(smu, clk_type, buf); } +static int smu_emit_ppclk_levels(void *handle, enum pp_clock_type type, char *buf, int *offset) +{ + struct smu_context *smu = handle; + enum smu_clk_type clk_type; + int ret = 0; + + clk_type = smu_convert_to_smuclk(type); + if (clk_type == SMU_CLK_COUNT) + return -EINVAL; + + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) + return -EOPNOTSUPP; + + if (!smu->ppt_funcs->emit_clk_levels) + ret = -ENOENT; + + return smu->ppt_funcs->emit_clk_levels(smu, clk_type, buf, offset); + +} + static int smu_od_edit_dpm_table(void *handle, enum PP_OD_DPM_TABLE_COMMAND type, long *input, uint32_t size) @@ -2824,6 +2855,7 @@ static const struct amd_pm_funcs swsmu_pm_funcs = { .get_fan_speed_pwm = smu_get_fan_speed_pwm, .force_clock_level = smu_force_ppclk_levels, .print_clock_levels = smu_print_ppclk_levels, + .emit_clock_levels = smu_emit_ppclk_levels, .force_performance_level = smu_force_performance_level, .read_sensor = smu_read_sensor, .get_performance_level = smu_get_performance_level, diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h index 4c585241ef66..79c7cb1a92d7 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -605,10 +605,24 @@ struct pptable_funcs { * to buffer. Star current level. * * Used for sysfs interfaces. + * Return: Number of characters written to the buffer */ int (*print_clk_levels)(struct smu_context *smu, enum smu_clk_type clk_type, char *buf); /** + * @emit_clk_levels: Print DPM clock levels for a clock domain + * to buffer using sysfs_emit_at. Star current level. + * + * Used for sysfs interfaces. + * &buf: sysfs buffer + * &offset: offset within buffer to start printing, which is updated by the + * function. + * + * Return: 0 on Success or Negative to indicate an error occurred. + */ + int (*emit_clk_levels)(struct smu_context *smu, enum smu_clk_type clk_type, char *buf, int *offset); + + /** * @force_clk_levels: Set a range of allowed DPM levels for a clock * domain. * &clk_type: Clock domain. |