Commit 5d64f9bb authored by Darren Powell's avatar Darren Powell Committed by Alex Deucher

amdgpu/pm: Implement new API function "emit" that accepts buffer base and write offset

   (v3)
     Rewrote patchset to order patches as (API, hw impl, usecase)

     - added API for new power management function emit_clk_levels
       This function should duplicate the functionality of print_clk_levels,
       but this solution passes the buffer base and write offset down the stack.
     - new powerplay function emit_clock_levels, implemented by smu_emit_ppclk_levels()
       This function parallels the implementation of smu_print_ppclk_levels and
       calls emit_clk_levels, and allows the returns of errors
     - new helper function smu_convert_to_smuclk called by smu_print_ppclk_levels and
       smu_emit_ppclk_levels
Signed-off-by: default avatarDarren Powell <darren.powell@amd.com>
Reviewed-By: default avatarEvan Quan <evan.quan@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4f860ede
...@@ -321,6 +321,7 @@ struct amd_pm_funcs { ...@@ -321,6 +321,7 @@ struct amd_pm_funcs {
int (*get_fan_speed_pwm)(void *handle, u32 *speed); int (*get_fan_speed_pwm)(void *handle, u32 *speed);
int (*force_clock_level)(void *handle, enum pp_clock_type type, uint32_t mask); 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 (*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 (*force_performance_level)(void *handle, enum amd_dpm_forced_level level);
int (*get_sclk_od)(void *handle); int (*get_sclk_od)(void *handle);
int (*set_sclk_od)(void *handle, uint32_t value); int (*set_sclk_od)(void *handle, uint32_t value);
......
...@@ -890,6 +890,27 @@ int amdgpu_dpm_print_clock_levels(struct amdgpu_device *adev, ...@@ -890,6 +890,27 @@ int amdgpu_dpm_print_clock_levels(struct amdgpu_device *adev,
return ret; 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, int amdgpu_dpm_set_ppfeature_status(struct amdgpu_device *adev,
uint64_t ppfeature_masks) uint64_t ppfeature_masks)
{ {
......
...@@ -441,6 +441,10 @@ int amdgpu_dpm_odn_edit_dpm_table(struct amdgpu_device *adev, ...@@ -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, int amdgpu_dpm_print_clock_levels(struct amdgpu_device *adev,
enum pp_clock_type type, enum pp_clock_type type,
char *buf); 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, int amdgpu_dpm_set_ppfeature_status(struct amdgpu_device *adev,
uint64_t ppfeature_masks); uint64_t ppfeature_masks);
int amdgpu_dpm_get_ppfeature_status(struct amdgpu_device *adev, char *buf); int amdgpu_dpm_get_ppfeature_status(struct amdgpu_device *adev, char *buf);
......
...@@ -2216,11 +2216,8 @@ static int smu_print_smuclk_levels(struct smu_context *smu, enum smu_clk_type cl ...@@ -2216,11 +2216,8 @@ static int smu_print_smuclk_levels(struct smu_context *smu, enum smu_clk_type cl
return ret; return ret;
} }
static int smu_print_ppclk_levels(void *handle, static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type type)
enum pp_clock_type type,
char *buf)
{ {
struct smu_context *smu = handle;
enum smu_clk_type clk_type; enum smu_clk_type clk_type;
switch (type) { switch (type) {
...@@ -2253,12 +2250,46 @@ static int smu_print_ppclk_levels(void *handle, ...@@ -2253,12 +2250,46 @@ static int smu_print_ppclk_levels(void *handle,
case OD_CCLK: case OD_CCLK:
clk_type = SMU_OD_CCLK; break; clk_type = SMU_OD_CCLK; break;
default: 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); 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, static int smu_od_edit_dpm_table(void *handle,
enum PP_OD_DPM_TABLE_COMMAND type, enum PP_OD_DPM_TABLE_COMMAND type,
long *input, uint32_t size) long *input, uint32_t size)
...@@ -2824,6 +2855,7 @@ static const struct amd_pm_funcs swsmu_pm_funcs = { ...@@ -2824,6 +2855,7 @@ static const struct amd_pm_funcs swsmu_pm_funcs = {
.get_fan_speed_pwm = smu_get_fan_speed_pwm, .get_fan_speed_pwm = smu_get_fan_speed_pwm,
.force_clock_level = smu_force_ppclk_levels, .force_clock_level = smu_force_ppclk_levels,
.print_clock_levels = smu_print_ppclk_levels, .print_clock_levels = smu_print_ppclk_levels,
.emit_clock_levels = smu_emit_ppclk_levels,
.force_performance_level = smu_force_performance_level, .force_performance_level = smu_force_performance_level,
.read_sensor = smu_read_sensor, .read_sensor = smu_read_sensor,
.get_performance_level = smu_get_performance_level, .get_performance_level = smu_get_performance_level,
......
...@@ -605,9 +605,23 @@ struct pptable_funcs { ...@@ -605,9 +605,23 @@ struct pptable_funcs {
* to buffer. Star current level. * to buffer. Star current level.
* *
* Used for sysfs interfaces. * 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); 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 * @force_clk_levels: Set a range of allowed DPM levels for a clock
* domain. * domain.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment