From d018772748fc474b2265ce333a704620b17df3fd Mon Sep 17 00:00:00 2001 From: Eric Huang Date: Mon, 6 Mar 2017 13:13:48 -0500 Subject: [PATCH] drm/amd/powerplay: add some display/powerplay interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit New interfaces needed to handle the new clock trees and bandwidth requirements on vega10. Acked-by: Christian König Signed-off-by: Eric Huang Acked-by: Alex Deucher Acked-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 94 +++++++++++++++++++ .../drm/amd/powerplay/hwmgr/hardwaremanager.c | 49 ++++++++++ .../gpu/drm/amd/powerplay/inc/amd_powerplay.h | 28 +++++- .../drm/amd/powerplay/inc/hardwaremanager.h | 11 +++ drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 10 ++ 5 files changed, 191 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 6e1e695f97c5..dfd4fe6f0578 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -1349,6 +1349,100 @@ int amd_powerplay_get_clock_by_type(void *handle, enum amd_pp_clock_type type, s return ret; } +int amd_powerplay_get_clock_by_type_with_latency(void *handle, + enum amd_pp_clock_type type, + struct pp_clock_levels_with_latency *clocks) +{ + struct pp_hwmgr *hwmgr; + struct pp_instance *pp_handle = (struct pp_instance *)handle; + int ret = 0; + + ret = pp_check(pp_handle); + if (ret != 0) + return ret; + + if (!clocks) + return -EINVAL; + + mutex_lock(&pp_handle->pp_lock); + hwmgr = ((struct pp_instance *)handle)->hwmgr; + ret = phm_get_clock_by_type_with_latency(hwmgr, type, clocks); + mutex_unlock(&pp_handle->pp_lock); + return ret; +} + +int amd_powerplay_get_clock_by_type_with_voltage(void *handle, + enum amd_pp_clock_type type, + struct pp_clock_levels_with_voltage *clocks) +{ + struct pp_hwmgr *hwmgr; + struct pp_instance *pp_handle = (struct pp_instance *)handle; + int ret = 0; + + ret = pp_check(pp_handle); + if (ret != 0) + return ret; + + if (!clocks) + return -EINVAL; + + hwmgr = ((struct pp_instance *)handle)->hwmgr; + + mutex_lock(&pp_handle->pp_lock); + + ret = phm_get_clock_by_type_with_voltage(hwmgr, type, clocks); + + mutex_unlock(&pp_handle->pp_lock); + return ret; +} + +int amd_powerplay_set_watermarks_for_clocks_ranges(void *handle, + struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges) +{ + struct pp_hwmgr *hwmgr; + struct pp_instance *pp_handle = (struct pp_instance *)handle; + int ret = 0; + + ret = pp_check(pp_handle); + if (ret != 0) + return ret; + + if (!wm_with_clock_ranges) + return -EINVAL; + + hwmgr = ((struct pp_instance *)handle)->hwmgr; + + mutex_lock(&pp_handle->pp_lock); + ret = phm_set_watermarks_for_clocks_ranges(hwmgr, + wm_with_clock_ranges); + mutex_unlock(&pp_handle->pp_lock); + + return ret; +} + +int amd_powerplay_display_clock_voltage_request(void *handle, + struct pp_display_clock_request *clock) +{ + struct pp_hwmgr *hwmgr; + struct pp_instance *pp_handle = (struct pp_instance *)handle; + int ret = 0; + + ret = pp_check(pp_handle); + if (ret != 0) + return ret; + + if (!clock) + return -EINVAL; + + hwmgr = ((struct pp_instance *)handle)->hwmgr; + + mutex_lock(&pp_handle->pp_lock); + ret = phm_display_clock_voltage_request(hwmgr, clock); + mutex_unlock(&pp_handle->pp_lock); + + return ret; +} + int amd_powerplay_get_display_mode_validation_clocks(void *handle, struct amd_pp_simple_clock_info *clocks) { diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c index 6646e1402a13..23bba2c8b18e 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c @@ -443,6 +443,55 @@ int phm_get_clock_by_type(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type type, s } +int phm_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr, + enum amd_pp_clock_type type, + struct pp_clock_levels_with_latency *clocks) +{ + PHM_FUNC_CHECK(hwmgr); + + if (hwmgr->hwmgr_func->get_clock_by_type_with_latency == NULL) + return -EINVAL; + + return hwmgr->hwmgr_func->get_clock_by_type_with_latency(hwmgr, type, clocks); + +} + +int phm_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr, + enum amd_pp_clock_type type, + struct pp_clock_levels_with_voltage *clocks) +{ + PHM_FUNC_CHECK(hwmgr); + + if (hwmgr->hwmgr_func->get_clock_by_type_with_voltage == NULL) + return -EINVAL; + + return hwmgr->hwmgr_func->get_clock_by_type_with_voltage(hwmgr, type, clocks); + +} + +int phm_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, + struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges) +{ + PHM_FUNC_CHECK(hwmgr); + + if (!hwmgr->hwmgr_func->set_watermarks_for_clocks_ranges) + return -EINVAL; + + return hwmgr->hwmgr_func->set_watermarks_for_clocks_ranges(hwmgr, + wm_with_clock_ranges); +} + +int phm_display_clock_voltage_request(struct pp_hwmgr *hwmgr, + struct pp_display_clock_request *clock) +{ + PHM_FUNC_CHECK(hwmgr); + + if (!hwmgr->hwmgr_func->display_clock_voltage_request) + return -EINVAL; + + return hwmgr->hwmgr_func->display_clock_voltage_request(hwmgr, clock); +} + int phm_get_max_high_clocks(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks) { PHM_FUNC_CHECK(hwmgr); diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index c0bf3af6846d..4e39f35bb745 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h @@ -28,6 +28,7 @@ #include #include "amd_shared.h" #include "cgs_common.h" +#include "dm_pp_interface.h" extern const struct amd_ip_funcs pp_ip_funcs; extern const struct amd_powerplay_funcs pp_dpm_funcs; @@ -226,6 +227,8 @@ struct amd_pp_display_configuration { * higher latency not allowed. */ uint32_t dce_tolerable_mclk_in_active_latency; + uint32_t min_dcef_set_clk; + uint32_t min_dcef_deep_sleep_set_clk; }; struct amd_pp_simple_clock_info { @@ -266,7 +269,11 @@ struct amd_pp_clock_info { enum amd_pp_clock_type { amd_pp_disp_clock = 1, amd_pp_sys_clock, - amd_pp_mem_clock + amd_pp_mem_clock, + amd_pp_dcef_clock, + amd_pp_soc_clock, + amd_pp_pixel_clock, + amd_pp_phy_clock }; #define MAX_NUM_CLOCKS 16 @@ -303,6 +310,11 @@ struct pp_gpu_power { uint32_t average_gpu_power; }; +struct pp_display_clock_request { + enum amd_pp_clock_type clock_type; + uint32_t clock_freq_in_khz; +}; + #define PP_GROUP_MASK 0xF0000000 #define PP_GROUP_SHIFT 28 @@ -405,6 +417,20 @@ int amd_powerplay_get_clock_by_type(void *handle, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks); +int amd_powerplay_get_clock_by_type_with_latency(void *handle, + enum amd_pp_clock_type type, + struct pp_clock_levels_with_latency *clocks); + +int amd_powerplay_get_clock_by_type_with_voltage(void *handle, + enum amd_pp_clock_type type, + struct pp_clock_levels_with_voltage *clocks); + +int amd_powerplay_set_watermarks_for_clocks_ranges(void *handle, + struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges); + +int amd_powerplay_display_clock_voltage_request(void *handle, + struct pp_display_clock_request *clock); + int amd_powerplay_get_display_mode_validation_clocks(void *handle, struct amd_pp_simple_clock_info *output); diff --git a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h index b485bec678fd..5345b50761f4 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h @@ -419,6 +419,17 @@ extern int phm_get_current_shallow_sleep_clocks(struct pp_hwmgr *hwmgr, const st extern int phm_get_clock_by_type(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks); +extern int phm_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr, + enum amd_pp_clock_type type, + struct pp_clock_levels_with_latency *clocks); +extern int phm_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr, + enum amd_pp_clock_type type, + struct pp_clock_levels_with_voltage *clocks); +extern int phm_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, + struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges); +extern int phm_display_clock_voltage_request(struct pp_hwmgr *hwmgr, + struct pp_display_clock_request *clock); + extern int phm_get_max_high_clocks(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks); #endif /* _HARDWARE_MANAGER_H_ */ diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 02185d49ff8d..7de9beabb35d 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -347,6 +347,16 @@ struct pp_hwmgr_func { int (*get_current_shallow_sleep_clocks)(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, struct pp_clock_info *clock_info); int (*get_clock_by_type)(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks); + int (*get_clock_by_type_with_latency)(struct pp_hwmgr *hwmgr, + enum amd_pp_clock_type type, + struct pp_clock_levels_with_latency *clocks); + int (*get_clock_by_type_with_voltage)(struct pp_hwmgr *hwmgr, + enum amd_pp_clock_type type, + struct pp_clock_levels_with_voltage *clocks); + int (*set_watermarks_for_clocks_ranges)(struct pp_hwmgr *hwmgr, + struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges); + int (*display_clock_voltage_request)(struct pp_hwmgr *hwmgr, + struct pp_display_clock_request *clock); int (*get_max_high_clocks)(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks); int (*power_off_asic)(struct pp_hwmgr *hwmgr); int (*force_clock_level)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, uint32_t mask); -- 2.20.1