diff options
author | Rex Zhu <Rex.Zhu@amd.com> | 2018-01-10 13:48:06 +0300 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-02-19 22:17:52 +0300 |
commit | 6390258a2f1390e19dece30bb5231e73ce8a7dd0 (patch) | |
tree | c155dbc5c09b899b629b96be853d5bd1e7eaa7d8 /drivers/gpu/drm/amd | |
parent | 37c5c4dbf03b167b5ca68d4bbc7fb6c92a463fb4 (diff) | |
download | linux-6390258a2f1390e19dece30bb5231e73ce8a7dd0.tar.xz |
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>
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 38 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 81 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 3 |
4 files changed, 123 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 8859b6754545..5e2252127fe5 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -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, diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 7e6feedebd5b..65b771436463 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -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) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h index e8507ff8dbb3..689fe9f5e0b8 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h @@ -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 diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index f37f211e7624..800d77309a93 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -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 { |