aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1441-drm-amd-powerplay-implement-power_dpm_state-sys-inte.patch
diff options
context:
space:
mode:
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.patch295
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
+