drm/amd/powerplay: enable gpu_busy_percent sys interface for renoir (v2)

To get the value of gpu_busy_percent, it needs to realize
get_current_activity_percent and get_metrics_table.
The framework of renoir smu is different from old ones like raven. It
needs to realize get_current_activity_percent and get_metrics_table in
renoir_ppt.c like navi10.

v2: remove unused variable (Alex)

Signed-off-by: changzhu <Changfeng.Zhu@amd.com>
Reviewed-by: Evan Quan <evan.quan@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
changzhu 2019-11-13 17:17:09 +08:00 committed by Alex Deucher
parent 858a2bbad6
commit 30b2c0cae4
3 changed files with 113 additions and 0 deletions

View File

@ -62,6 +62,10 @@ int smu_v12_0_powergate_jpeg(struct smu_context *smu, bool gate);
int smu_v12_0_set_gfx_cgpg(struct smu_context *smu, bool enable);
int smu_v12_0_read_sensor(struct smu_context *smu,
enum amd_pp_sensors sensor,
void *data, uint32_t *size);
uint32_t smu_v12_0_get_gfxoff_status(struct smu_context *smu);
int smu_v12_0_gfx_off_control(struct smu_context *smu, bool enable);

View File

@ -139,6 +139,27 @@ static int renoir_get_smu_table_index(struct smu_context *smc, uint32_t index)
return mapping.map_to;
}
static int renoir_get_metrics_table(struct smu_context *smu,
SmuMetrics_t *metrics_table)
{
struct smu_table_context *smu_table= &smu->smu_table;
int ret = 0;
if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(100))) {
ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0,
(void *)smu_table->metrics_table, false);
if (ret) {
pr_info("Failed to export SMU metrics table!\n");
return ret;
}
smu_table->metrics_time = jiffies;
}
memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t));
return ret;
}
static int renoir_tables_init(struct smu_context *smu, struct smu_table *tables)
{
struct smu_table_context *smu_table = &smu->smu_table;
@ -154,6 +175,11 @@ static int renoir_tables_init(struct smu_context *smu, struct smu_table *tables)
if (!smu_table->clocks_table)
return -ENOMEM;
smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
if (!smu_table->metrics_table)
return -ENOMEM;
smu_table->metrics_time = 0;
return 0;
}
@ -386,6 +412,32 @@ static int renoir_unforce_dpm_levels(struct smu_context *smu) {
return ret;
}
static int renoir_get_current_activity_percent(struct smu_context *smu,
enum amd_pp_sensors sensor,
uint32_t *value)
{
int ret = 0;
SmuMetrics_t metrics;
if (!value)
return -EINVAL;
ret = renoir_get_metrics_table(smu, &metrics);
if (ret)
return ret;
switch (sensor) {
case AMDGPU_PP_SENSOR_GPU_LOAD:
*value = metrics.AverageGfxActivity;
break;
default:
pr_err("Invalid sensor for retrieving clock activity\n");
return -EINVAL;
}
return 0;
}
static int renoir_get_workload_type(struct smu_context *smu, uint32_t profile)
{
@ -699,6 +751,29 @@ static int renoir_get_power_profile_mode(struct smu_context *smu,
return size;
}
static int renoir_read_sensor(struct smu_context *smu,
enum amd_pp_sensors sensor,
void *data, uint32_t *size)
{
int ret = 0;
if (!data || !size)
return -EINVAL;
mutex_lock(&smu->sensor_lock);
switch (sensor) {
case AMDGPU_PP_SENSOR_GPU_LOAD:
ret = renoir_get_current_activity_percent(smu, sensor, (uint32_t *)data);
*size = 4;
break;
default:
ret = smu_v12_0_read_sensor(smu, sensor, data, size);
}
mutex_unlock(&smu->sensor_lock);
return ret;
}
static const struct pptable_funcs renoir_ppt_funcs = {
.get_smu_msg_index = renoir_get_smu_msg_index,
.get_smu_table_index = renoir_get_smu_table_index,
@ -719,6 +794,7 @@ static const struct pptable_funcs renoir_ppt_funcs = {
.get_dpm_clock_table = renoir_get_dpm_clock_table,
.set_watermarks_table = renoir_set_watermarks_table,
.get_power_profile_mode = renoir_get_power_profile_mode,
.read_sensor = renoir_read_sensor,
.check_fw_status = smu_v12_0_check_fw_status,
.check_fw_version = smu_v12_0_check_fw_version,
.powergate_sdma = smu_v12_0_powergate_sdma,

View File

@ -223,6 +223,39 @@ int smu_v12_0_set_gfx_cgpg(struct smu_context *smu, bool enable)
SMU_MSG_SetGfxCGPG, enable ? 1 : 0);
}
int smu_v12_0_read_sensor(struct smu_context *smu,
enum amd_pp_sensors sensor,
void *data, uint32_t *size)
{
int ret = 0;
if(!data || !size)
return -EINVAL;
switch (sensor) {
case AMDGPU_PP_SENSOR_GFX_MCLK:
ret = smu_get_current_clk_freq(smu, SMU_UCLK, (uint32_t *)data);
*size = 4;
break;
case AMDGPU_PP_SENSOR_GFX_SCLK:
ret = smu_get_current_clk_freq(smu, SMU_GFXCLK, (uint32_t *)data);
*size = 4;
break;
case AMDGPU_PP_SENSOR_MIN_FAN_RPM:
*(uint32_t *)data = 0;
*size = 4;
break;
default:
ret = smu_common_read_sensor(smu, sensor, data, size);
break;
}
if (ret)
*size = 0;
return ret;
}
/**
* smu_v12_0_get_gfxoff_status - get gfxoff status
*