drm/amd/pp: Add custom power profile mode support on Vega10
v2: delete uncessary blank line.
Add static const modifiers to an array
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
37c5c4dbf0
commit
6390258a2f
4 changed files with 123 additions and 0 deletions
|
|
@ -1081,6 +1081,42 @@ static int pp_dpm_get_power_profile_state(void *handle,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pp_get_power_profile_mode(void *handle, char *buf)
|
||||
{
|
||||
struct pp_hwmgr *hwmgr;
|
||||
struct pp_instance *pp_handle = (struct pp_instance *)handle;
|
||||
|
||||
if (!buf || pp_check(pp_handle))
|
||||
return -EINVAL;
|
||||
|
||||
hwmgr = pp_handle->hwmgr;
|
||||
|
||||
if (hwmgr->hwmgr_func->get_power_profile_mode == NULL) {
|
||||
pr_info("%s was not implemented.\n", __func__);
|
||||
return snprintf(buf, PAGE_SIZE, "\n");
|
||||
}
|
||||
|
||||
return hwmgr->hwmgr_func->get_power_profile_mode(hwmgr, buf);
|
||||
}
|
||||
|
||||
static int pp_set_power_profile_mode(void *handle, long *input, uint32_t size)
|
||||
{
|
||||
struct pp_hwmgr *hwmgr;
|
||||
struct pp_instance *pp_handle = (struct pp_instance *)handle;
|
||||
|
||||
if (pp_check(pp_handle))
|
||||
return -EINVAL;
|
||||
|
||||
hwmgr = pp_handle->hwmgr;
|
||||
|
||||
if (hwmgr->hwmgr_func->set_power_profile_mode == NULL) {
|
||||
pr_info("%s was not implemented.\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, input, size);
|
||||
}
|
||||
|
||||
static int pp_dpm_set_power_profile_state(void *handle,
|
||||
struct amd_pp_profile *request)
|
||||
{
|
||||
|
|
@ -1464,6 +1500,8 @@ const struct amd_pm_funcs pp_dpm_funcs = {
|
|||
.switch_power_profile = pp_dpm_switch_power_profile,
|
||||
.set_clockgating_by_smu = pp_set_clockgating_by_smu,
|
||||
.notify_smu_memory_info = pp_dpm_notify_smu_memory_info,
|
||||
.get_power_profile_mode = pp_get_power_profile_mode,
|
||||
.set_power_profile_mode = pp_set_power_profile_mode,
|
||||
/* export to DC */
|
||||
.get_sclk = pp_dpm_get_sclk,
|
||||
.get_mclk = pp_dpm_get_mclk,
|
||||
|
|
|
|||
|
|
@ -760,6 +760,8 @@ static int vega10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
|
|||
|
||||
hwmgr->backend = data;
|
||||
|
||||
hwmgr->power_profile_mode = PP_SMC_POWER_PROFILE_VIDEO;
|
||||
|
||||
vega10_set_default_registry_data(hwmgr);
|
||||
|
||||
data->disable_dpm_mask = 0xff;
|
||||
|
|
@ -3963,6 +3965,7 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
|
|||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -5021,6 +5024,82 @@ static int vega10_register_thermal_interrupt(struct pp_hwmgr *hwmgr,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vega10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf)
|
||||
{
|
||||
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
|
||||
uint32_t i, size = 0;
|
||||
static const uint8_t profile_mode_setting[5][4] = {{70, 60, 1, 3,},
|
||||
{90, 60, 0, 0,},
|
||||
{70, 60, 0, 0,},
|
||||
{70, 90, 0, 0,},
|
||||
{30, 60, 0, 6,},
|
||||
};
|
||||
static const char *profile_name[6] = {"3D_FULL_SCREEN",
|
||||
"POWER_SAVING",
|
||||
"VIDEO",
|
||||
"VR",
|
||||
"COMPUTER",
|
||||
"CUSTOM"};
|
||||
static const char *title[6] = {"NUM",
|
||||
"MODE_NAME",
|
||||
"BUSY_SET_POINT",
|
||||
"FPS",
|
||||
"USE_RLC_BUSY",
|
||||
"MIN_ACTIVE_LEVEL"};
|
||||
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
|
||||
size += sprintf(buf + size, "%s %16s %s %s %s %s\n",title[0],
|
||||
title[1], title[2], title[3], title[4], title[5]);
|
||||
|
||||
for (i = 0; i < PP_SMC_POWER_PROFILE_CUSTOM; i++)
|
||||
size += sprintf(buf + size, "%3d %14s%s: %14d %3d %10d %14d\n",
|
||||
i, profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " ",
|
||||
profile_mode_setting[i][0], profile_mode_setting[i][1],
|
||||
profile_mode_setting[i][2], profile_mode_setting[i][3]);
|
||||
size += sprintf(buf + size, "%3d %14s%s: %14d %3d %10d %14d\n", i,
|
||||
profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " ",
|
||||
data->custom_profile_mode[0], data->custom_profile_mode[1],
|
||||
data->custom_profile_mode[2], data->custom_profile_mode[3]);
|
||||
return size;
|
||||
}
|
||||
|
||||
static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint32_t size)
|
||||
{
|
||||
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
|
||||
uint8_t busy_set_point;
|
||||
uint8_t FPS;
|
||||
uint8_t use_rlc_busy;
|
||||
uint8_t min_active_level;
|
||||
|
||||
if (input[size] == PP_SMC_POWER_PROFILE_AUTO)
|
||||
return 0; /* TO DO auto wattman feature not enabled */
|
||||
|
||||
hwmgr->power_profile_mode = input[size];
|
||||
|
||||
smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask,
|
||||
1<<hwmgr->power_profile_mode);
|
||||
|
||||
if (hwmgr->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
|
||||
if (size == 0 || size > 4)
|
||||
return -EINVAL;
|
||||
|
||||
data->custom_profile_mode[0] = busy_set_point = input[0];
|
||||
data->custom_profile_mode[1] = FPS = input[1];
|
||||
data->custom_profile_mode[2] = use_rlc_busy = input[2];
|
||||
data->custom_profile_mode[3] = min_active_level = input[3];
|
||||
smum_send_msg_to_smc_with_parameter(hwmgr,
|
||||
PPSMC_MSG_SetCustomGfxDpmParameters,
|
||||
busy_set_point | FPS<<8 |
|
||||
use_rlc_busy << 16 | min_active_level<<24);
|
||||
pr_info("size is %d value is %x \n", size, busy_set_point | FPS<<8 |
|
||||
use_rlc_busy << 16 | min_active_level<<24);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pp_hwmgr_func vega10_hwmgr_funcs = {
|
||||
.backend_init = vega10_hwmgr_backend_init,
|
||||
.backend_fini = vega10_hwmgr_backend_fini,
|
||||
|
|
@ -5078,6 +5157,8 @@ static const struct pp_hwmgr_func vega10_hwmgr_funcs = {
|
|||
.get_thermal_temperature_range = vega10_get_thermal_temperature_range,
|
||||
.register_internal_thermal_interrupt = vega10_register_thermal_interrupt,
|
||||
.start_thermal_controller = vega10_start_thermal_controller,
|
||||
.get_power_profile_mode = vega10_get_power_profile_mode,
|
||||
.set_power_profile_mode = vega10_set_power_profile_mode,
|
||||
};
|
||||
|
||||
int vega10_hwmgr_init(struct pp_hwmgr *hwmgr)
|
||||
|
|
|
|||
|
|
@ -389,6 +389,7 @@ struct vega10_hwmgr {
|
|||
uint32_t config_telemetry;
|
||||
uint32_t acg_loop_state;
|
||||
uint32_t mem_channels;
|
||||
uint8_t custom_profile_mode[4];
|
||||
};
|
||||
|
||||
#define VEGA10_DPM2_NEAR_TDP_DEC 10
|
||||
|
|
|
|||
|
|
@ -342,6 +342,8 @@ struct pp_hwmgr_func {
|
|||
uint32_t size);
|
||||
int (*get_thermal_temperature_range)(struct pp_hwmgr *hwmgr,
|
||||
struct PP_TemperatureRange *range);
|
||||
int (*get_power_profile_mode)(struct pp_hwmgr *hwmgr, char *buf);
|
||||
int (*set_power_profile_mode)(struct pp_hwmgr *hwmgr, long *input, uint32_t size);
|
||||
};
|
||||
|
||||
struct pp_table_func {
|
||||
|
|
@ -750,6 +752,7 @@ struct pp_hwmgr {
|
|||
struct amd_pp_profile default_compute_power_profile;
|
||||
enum amd_pp_profile_type current_power_profile;
|
||||
bool en_umd_pstate;
|
||||
uint32_t power_profile_mode;
|
||||
};
|
||||
|
||||
struct cgs_irq_src_funcs {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue