diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1441-drm-amd-powerplay-implement-power_dpm_state-sys-inte.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1441-drm-amd-powerplay-implement-power_dpm_state-sys-inte.patch | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1441-drm-amd-powerplay-implement-power_dpm_state-sys-inte.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1441-drm-amd-powerplay-implement-power_dpm_state-sys-inte.patch new file mode 100644 index 00000000..fbe1f293 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1441-drm-amd-powerplay-implement-power_dpm_state-sys-inte.patch @@ -0,0 +1,295 @@ +From abf98be540597c17daa3ed948ece32a862c90836 Mon Sep 17 00:00:00 2001 +From: Chengming Gui <Jack.Gui@amd.com> +Date: Fri, 4 Jan 2019 17:42:09 +0800 +Subject: [PATCH 1441/2940] drm/amd/powerplay: implement power_dpm_state sys + interface for SMU11 + +Add functions to get/set dpm state for SMU11. + +Signed-off-by: Chengming Gui <Jack.Gui@amd.com> +Acked-by: Alex Deucher <alexander.deucher@amd.com> +Acked-by: Kevin Wang <kevin.wang@amd.com> +Reviewd-by: Evan Quan <evan.quan@amd.com> +Acked-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h | 6 + + drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 4 +- + .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 116 ++++++++++++++++++ + drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 4 + + drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 46 +++++++ + 5 files changed, 175 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h +index cc3f27e314e8..5b1539e72101 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h +@@ -290,6 +290,12 @@ enum amdgpu_pcie_gen { + #define amdgpu_dpm_get_current_power_state(adev) \ + ((adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle)) + ++#define amdgpu_smu_get_current_power_state(adev) \ ++ ((adev)->smu.ppt_funcs->get_current_power_state(&((adev)->smu))) ++ ++#define amdgpu_smu_set_power_state(adev) \ ++ ((adev)->smu.ppt_funcs->set_power_state(&((adev)->smu))) ++ + #define amdgpu_dpm_get_pp_num_states(adev, data) \ + ((adev)->powerplay.pp_funcs->get_pp_num_states((adev)->powerplay.pp_handle, data)) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +index 7fe0330ca319..f36e86b11880 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +@@ -144,7 +144,9 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev, + struct amdgpu_device *adev = ddev->dev_private; + enum amd_pm_state_type pm; + +- if (adev->powerplay.pp_funcs->get_current_power_state) ++ if (adev->smu.ppt_funcs->get_current_power_state) ++ pm = amdgpu_smu_get_current_power_state(adev); ++ else if (adev->powerplay.pp_funcs->get_current_power_state) + pm = amdgpu_dpm_get_current_power_state(adev); + else + pm = adev->pm.dpm.user_state; +diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +index bab7847b2143..c1357ebc6187 100644 +--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h ++++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +@@ -26,6 +26,118 @@ + #include "kgd_pp_interface.h" + #include "dm_pp_interface.h" + ++struct smu_hw_power_state { ++ unsigned int magic; ++}; ++ ++struct smu_power_state; ++ ++enum smu_state_ui_label { ++ SMU_STATE_UI_LABEL_NONE, ++ SMU_STATE_UI_LABEL_BATTERY, ++ SMU_STATE_UI_TABEL_MIDDLE_LOW, ++ SMU_STATE_UI_LABEL_BALLANCED, ++ SMU_STATE_UI_LABEL_MIDDLE_HIGHT, ++ SMU_STATE_UI_LABEL_PERFORMANCE, ++ SMU_STATE_UI_LABEL_BACO, ++}; ++ ++enum smu_state_classification_flag { ++ SMU_STATE_CLASSIFICATION_FLAG_BOOT = 0x0001, ++ SMU_STATE_CLASSIFICATION_FLAG_THERMAL = 0x0002, ++ SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE = 0x0004, ++ SMU_STATE_CLASSIFICATION_FLAG_RESET = 0x0008, ++ SMU_STATE_CLASSIFICATION_FLAG_FORCED = 0x0010, ++ SMU_STATE_CLASSIFICATION_FLAG_USER_3D_PERFORMANCE = 0x0020, ++ SMU_STATE_CLASSIFICATION_FLAG_USER_2D_PERFORMANCE = 0x0040, ++ SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE = 0x0080, ++ SMU_STATE_CLASSIFICATION_FLAG_AC_OVERDIRVER_TEMPLATE = 0x0100, ++ SMU_STATE_CLASSIFICATION_FLAG_UVD = 0x0200, ++ SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE_LOW = 0x0400, ++ SMU_STATE_CLASSIFICATION_FLAG_ACPI = 0x0800, ++ SMU_STATE_CLASSIFICATION_FLAG_HD2 = 0x1000, ++ SMU_STATE_CLASSIFICATION_FLAG_UVD_HD = 0x2000, ++ SMU_STATE_CLASSIFICATION_FLAG_UVD_SD = 0x4000, ++ SMU_STATE_CLASSIFICATION_FLAG_USER_DC_PERFORMANCE = 0x8000, ++ SMU_STATE_CLASSIFICATION_FLAG_DC_OVERDIRVER_TEMPLATE = 0x10000, ++ SMU_STATE_CLASSIFICATION_FLAG_BACO = 0x20000, ++ SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE2 = 0x40000, ++ SMU_STATE_CLASSIFICATION_FLAG_ULV = 0x80000, ++ SMU_STATE_CLASSIFICATION_FLAG_UVD_MVC = 0x100000, ++}; ++ ++struct smu_state_classification_block { ++ enum smu_state_ui_label ui_label; ++ enum smu_state_classification_flag flags; ++ int bios_index; ++ bool temporary_state; ++ bool to_be_deleted; ++}; ++ ++struct smu_state_pcie_block { ++ unsigned int lanes; ++}; ++ ++enum smu_refreshrate_source { ++ SMU_REFRESHRATE_SOURCE_EDID, ++ SMU_REFRESHRATE_SOURCE_EXPLICIT ++}; ++ ++struct smu_state_display_block { ++ bool disable_frame_modulation; ++ bool limit_refreshrate; ++ enum smu_refreshrate_source refreshrate_source; ++ int explicit_refreshrate; ++ int edid_refreshrate_index; ++ bool enable_vari_bright; ++}; ++ ++struct smu_state_memroy_block { ++ bool dll_off; ++ uint8_t m3arb; ++ uint8_t unused[3]; ++}; ++ ++struct smu_state_software_algorithm_block { ++ bool disable_load_balancing; ++ bool enable_sleep_for_timestamps; ++}; ++ ++struct smu_temperature_range { ++ int min; ++ int max; ++}; ++ ++struct smu_state_validation_block { ++ bool single_display_only; ++ bool disallow_on_dc; ++ uint8_t supported_power_levels; ++}; ++ ++struct smu_uvd_clocks { ++ uint32_t vclk; ++ uint32_t dclk; ++}; ++ ++/** ++* Structure to hold a SMU Power State. ++*/ ++struct smu_power_state { ++ uint32_t id; ++ struct list_head ordered_list; ++ struct list_head all_states_list; ++ ++ struct smu_state_classification_block classification; ++ struct smu_state_validation_block validation; ++ struct smu_state_pcie_block pcie; ++ struct smu_state_display_block display; ++ struct smu_state_memroy_block memory; ++ struct smu_temperature_range temperatures; ++ struct smu_state_software_algorithm_block software; ++ struct smu_uvd_clocks uvd_clocks; ++ struct smu_hw_power_state hardware; ++}; ++ + enum smu_message_type + { + SMU_MSG_TestMessage = 0, +@@ -204,6 +316,8 @@ struct smu_dpm_context { + uint32_t dpm_context_size; + void *dpm_context; + void *golden_dpm_context; ++ struct smu_power_state *dpm_request_power_state; ++ struct smu_power_state *dpm_current_power_state; + }; + + struct smu_power_context { +@@ -257,7 +371,9 @@ struct pptable_funcs { + int (*get_smu_msg_index)(struct smu_context *smu, uint32_t index); + int (*run_afll_btc)(struct smu_context *smu); + int (*get_unallowed_feature_mask)(struct smu_context *smu, uint32_t *feature_mask, uint32_t num); ++ enum amd_pm_state_type (*get_current_power_state)(struct smu_context *smu); + int (*set_default_dpm_table)(struct smu_context *smu); ++ int (*set_power_state)(struct smu_context *smu); + int (*populate_umd_state_clk)(struct smu_context *smu); + int (*print_clk_levels)(struct smu_context *smu, enum pp_clock_type type, char *buf); + int (*force_clk_levels)(struct smu_context *smu, enum pp_clock_type type, uint32_t mask); +diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +index 534319f24eb0..c1f394d9f3fc 100644 +--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c ++++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +@@ -273,9 +273,13 @@ static int smu_v11_0_fini_dpm_context(struct smu_context *smu) + + kfree(smu_dpm->dpm_context); + kfree(smu_dpm->golden_dpm_context); ++ kfree(smu_dpm->dpm_current_power_state); ++ kfree(smu_dpm->dpm_request_power_state); + smu_dpm->dpm_context = NULL; + smu_dpm->golden_dpm_context = NULL; + smu_dpm->dpm_context_size = 0; ++ smu_dpm->dpm_current_power_state = NULL; ++ smu_dpm->dpm_request_power_state = NULL; + + return 0; + } +diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +index b9f4e7b7b12b..04ff56143eba 100644 +--- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c ++++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +@@ -31,6 +31,7 @@ + #include "smu11_driver_if.h" + #include "soc15_common.h" + #include "atom.h" ++#include "power_state.h" + #include "vega20_ppt.h" + #include "vega20_pptable.h" + #include "vega20_ppsmc.h" +@@ -154,6 +155,16 @@ static int vega20_allocate_dpm_context(struct smu_context *smu) + + smu_dpm->dpm_context_size = sizeof(struct vega20_dpm_table); + ++ smu_dpm->dpm_current_power_state = kzalloc(sizeof(struct smu_power_state), ++ GFP_KERNEL); ++ if (!smu_dpm->dpm_current_power_state) ++ return -ENOMEM; ++ ++ smu_dpm->dpm_request_power_state = kzalloc(sizeof(struct smu_power_state), ++ GFP_KERNEL); ++ if (!smu_dpm->dpm_request_power_state) ++ return -ENOMEM; ++ + return 0; + } + +@@ -389,6 +400,39 @@ vega20_get_unallowed_feature_mask(struct smu_context *smu, + return 0; + } + ++static enum ++amd_pm_state_type vega20_get_current_power_state(struct smu_context *smu) ++{ ++ enum amd_pm_state_type pm_type; ++ struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); ++ ++ if (!smu_dpm_ctx->dpm_context || ++ !smu_dpm_ctx->dpm_current_power_state) ++ return -EINVAL; ++ ++ mutex_lock(&(smu->mutex)); ++ switch (smu_dpm_ctx->dpm_current_power_state->classification.ui_label) { ++ case SMU_STATE_UI_LABEL_BATTERY: ++ pm_type = POWER_STATE_TYPE_BATTERY; ++ break; ++ case SMU_STATE_UI_LABEL_BALLANCED: ++ pm_type = POWER_STATE_TYPE_BALANCED; ++ break; ++ case SMU_STATE_UI_LABEL_PERFORMANCE: ++ pm_type = POWER_STATE_TYPE_PERFORMANCE; ++ break; ++ default: ++ if (smu_dpm_ctx->dpm_current_power_state->classification.flags & SMU_STATE_CLASSIFICATION_FLAG_BOOT) ++ pm_type = POWER_STATE_TYPE_INTERNAL_BOOT; ++ else ++ pm_type = POWER_STATE_TYPE_DEFAULT; ++ break; ++ } ++ mutex_unlock(&(smu->mutex)); ++ ++ return pm_type; ++} ++ + static int + vega20_set_single_dpm_table(struct smu_context *smu, + struct vega20_single_dpm_table *single_dpm_table, +@@ -1263,7 +1307,9 @@ static const struct pptable_funcs vega20_ppt_funcs = { + .get_smu_msg_index = vega20_get_smu_msg_index, + .run_afll_btc = vega20_run_btc_afll, + .get_unallowed_feature_mask = vega20_get_unallowed_feature_mask, ++ .get_current_power_state = vega20_get_current_power_state, + .set_default_dpm_table = vega20_set_default_dpm_table, ++ .set_power_state = NULL, + .populate_umd_state_clk = vega20_populate_umd_state_clk, + .print_clk_levels = vega20_print_clk_levels, + .force_clk_levels = vega20_force_clk_levels, +-- +2.17.1 + |