aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChengming Gui <Jack.Gui@amd.com>2019-01-04 04:42:09 -0500
committerAlex Deucher <alexander.deucher@amd.com>2019-03-19 16:03:59 -0400
commit8554e67d6e22b0bc3ba213b87a0b6e1ae0fd838c (patch)
tree7ac0b6f6f3e2330765c1ab7daf601ff32eda1b57
parentad88f0517b239a08b148fbd300de103e8f7a78ef (diff)
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> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c4
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h116
-rw-r--r--drivers/gpu/drm/amd/powerplay/smu_v11_0.c4
-rw-r--r--drivers/gpu/drm/amd/powerplay/vega20_ppt.c46
5 files changed, 175 insertions, 1 deletions
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 {
290#define amdgpu_dpm_get_current_power_state(adev) \ 290#define amdgpu_dpm_get_current_power_state(adev) \
291 ((adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle)) 291 ((adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle))
292 292
293#define amdgpu_smu_get_current_power_state(adev) \
294 ((adev)->smu.ppt_funcs->get_current_power_state(&((adev)->smu)))
295
296#define amdgpu_smu_set_power_state(adev) \
297 ((adev)->smu.ppt_funcs->set_power_state(&((adev)->smu)))
298
293#define amdgpu_dpm_get_pp_num_states(adev, data) \ 299#define amdgpu_dpm_get_pp_num_states(adev, data) \
294 ((adev)->powerplay.pp_funcs->get_pp_num_states((adev)->powerplay.pp_handle, data)) 300 ((adev)->powerplay.pp_funcs->get_pp_num_states((adev)->powerplay.pp_handle, data))
295 301
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,
144 struct amdgpu_device *adev = ddev->dev_private; 144 struct amdgpu_device *adev = ddev->dev_private;
145 enum amd_pm_state_type pm; 145 enum amd_pm_state_type pm;
146 146
147 if (adev->powerplay.pp_funcs->get_current_power_state) 147 if (adev->smu.ppt_funcs->get_current_power_state)
148 pm = amdgpu_smu_get_current_power_state(adev);
149 else if (adev->powerplay.pp_funcs->get_current_power_state)
148 pm = amdgpu_dpm_get_current_power_state(adev); 150 pm = amdgpu_dpm_get_current_power_state(adev);
149 else 151 else
150 pm = adev->pm.dpm.user_state; 152 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 @@
26#include "kgd_pp_interface.h" 26#include "kgd_pp_interface.h"
27#include "dm_pp_interface.h" 27#include "dm_pp_interface.h"
28 28
29struct smu_hw_power_state {
30 unsigned int magic;
31};
32
33struct smu_power_state;
34
35enum smu_state_ui_label {
36 SMU_STATE_UI_LABEL_NONE,
37 SMU_STATE_UI_LABEL_BATTERY,
38 SMU_STATE_UI_TABEL_MIDDLE_LOW,
39 SMU_STATE_UI_LABEL_BALLANCED,
40 SMU_STATE_UI_LABEL_MIDDLE_HIGHT,
41 SMU_STATE_UI_LABEL_PERFORMANCE,
42 SMU_STATE_UI_LABEL_BACO,
43};
44
45enum smu_state_classification_flag {
46 SMU_STATE_CLASSIFICATION_FLAG_BOOT = 0x0001,
47 SMU_STATE_CLASSIFICATION_FLAG_THERMAL = 0x0002,
48 SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE = 0x0004,
49 SMU_STATE_CLASSIFICATION_FLAG_RESET = 0x0008,
50 SMU_STATE_CLASSIFICATION_FLAG_FORCED = 0x0010,
51 SMU_STATE_CLASSIFICATION_FLAG_USER_3D_PERFORMANCE = 0x0020,
52 SMU_STATE_CLASSIFICATION_FLAG_USER_2D_PERFORMANCE = 0x0040,
53 SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE = 0x0080,
54 SMU_STATE_CLASSIFICATION_FLAG_AC_OVERDIRVER_TEMPLATE = 0x0100,
55 SMU_STATE_CLASSIFICATION_FLAG_UVD = 0x0200,
56 SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE_LOW = 0x0400,
57 SMU_STATE_CLASSIFICATION_FLAG_ACPI = 0x0800,
58 SMU_STATE_CLASSIFICATION_FLAG_HD2 = 0x1000,
59 SMU_STATE_CLASSIFICATION_FLAG_UVD_HD = 0x2000,
60 SMU_STATE_CLASSIFICATION_FLAG_UVD_SD = 0x4000,
61 SMU_STATE_CLASSIFICATION_FLAG_USER_DC_PERFORMANCE = 0x8000,
62 SMU_STATE_CLASSIFICATION_FLAG_DC_OVERDIRVER_TEMPLATE = 0x10000,
63 SMU_STATE_CLASSIFICATION_FLAG_BACO = 0x20000,
64 SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE2 = 0x40000,
65 SMU_STATE_CLASSIFICATION_FLAG_ULV = 0x80000,
66 SMU_STATE_CLASSIFICATION_FLAG_UVD_MVC = 0x100000,
67};
68
69struct smu_state_classification_block {
70 enum smu_state_ui_label ui_label;
71 enum smu_state_classification_flag flags;
72 int bios_index;
73 bool temporary_state;
74 bool to_be_deleted;
75};
76
77struct smu_state_pcie_block {
78 unsigned int lanes;
79};
80
81enum smu_refreshrate_source {
82 SMU_REFRESHRATE_SOURCE_EDID,
83 SMU_REFRESHRATE_SOURCE_EXPLICIT
84};
85
86struct smu_state_display_block {
87 bool disable_frame_modulation;
88 bool limit_refreshrate;
89 enum smu_refreshrate_source refreshrate_source;
90 int explicit_refreshrate;
91 int edid_refreshrate_index;
92 bool enable_vari_bright;
93};
94
95struct smu_state_memroy_block {
96 bool dll_off;
97 uint8_t m3arb;
98 uint8_t unused[3];
99};
100
101struct smu_state_software_algorithm_block {
102 bool disable_load_balancing;
103 bool enable_sleep_for_timestamps;
104};
105
106struct smu_temperature_range {
107 int min;
108 int max;
109};
110
111struct smu_state_validation_block {
112 bool single_display_only;
113 bool disallow_on_dc;
114 uint8_t supported_power_levels;
115};
116
117struct smu_uvd_clocks {
118 uint32_t vclk;
119 uint32_t dclk;
120};
121
122/**
123* Structure to hold a SMU Power State.
124*/
125struct smu_power_state {
126 uint32_t id;
127 struct list_head ordered_list;
128 struct list_head all_states_list;
129
130 struct smu_state_classification_block classification;
131 struct smu_state_validation_block validation;
132 struct smu_state_pcie_block pcie;
133 struct smu_state_display_block display;
134 struct smu_state_memroy_block memory;
135 struct smu_temperature_range temperatures;
136 struct smu_state_software_algorithm_block software;
137 struct smu_uvd_clocks uvd_clocks;
138 struct smu_hw_power_state hardware;
139};
140
29enum smu_message_type 141enum smu_message_type
30{ 142{
31 SMU_MSG_TestMessage = 0, 143 SMU_MSG_TestMessage = 0,
@@ -204,6 +316,8 @@ struct smu_dpm_context {
204 uint32_t dpm_context_size; 316 uint32_t dpm_context_size;
205 void *dpm_context; 317 void *dpm_context;
206 void *golden_dpm_context; 318 void *golden_dpm_context;
319 struct smu_power_state *dpm_request_power_state;
320 struct smu_power_state *dpm_current_power_state;
207}; 321};
208 322
209struct smu_power_context { 323struct smu_power_context {
@@ -257,7 +371,9 @@ struct pptable_funcs {
257 int (*get_smu_msg_index)(struct smu_context *smu, uint32_t index); 371 int (*get_smu_msg_index)(struct smu_context *smu, uint32_t index);
258 int (*run_afll_btc)(struct smu_context *smu); 372 int (*run_afll_btc)(struct smu_context *smu);
259 int (*get_unallowed_feature_mask)(struct smu_context *smu, uint32_t *feature_mask, uint32_t num); 373 int (*get_unallowed_feature_mask)(struct smu_context *smu, uint32_t *feature_mask, uint32_t num);
374 enum amd_pm_state_type (*get_current_power_state)(struct smu_context *smu);
260 int (*set_default_dpm_table)(struct smu_context *smu); 375 int (*set_default_dpm_table)(struct smu_context *smu);
376 int (*set_power_state)(struct smu_context *smu);
261 int (*populate_umd_state_clk)(struct smu_context *smu); 377 int (*populate_umd_state_clk)(struct smu_context *smu);
262 int (*print_clk_levels)(struct smu_context *smu, enum pp_clock_type type, char *buf); 378 int (*print_clk_levels)(struct smu_context *smu, enum pp_clock_type type, char *buf);
263 int (*force_clk_levels)(struct smu_context *smu, enum pp_clock_type type, uint32_t mask); 379 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)
273 273
274 kfree(smu_dpm->dpm_context); 274 kfree(smu_dpm->dpm_context);
275 kfree(smu_dpm->golden_dpm_context); 275 kfree(smu_dpm->golden_dpm_context);
276 kfree(smu_dpm->dpm_current_power_state);
277 kfree(smu_dpm->dpm_request_power_state);
276 smu_dpm->dpm_context = NULL; 278 smu_dpm->dpm_context = NULL;
277 smu_dpm->golden_dpm_context = NULL; 279 smu_dpm->golden_dpm_context = NULL;
278 smu_dpm->dpm_context_size = 0; 280 smu_dpm->dpm_context_size = 0;
281 smu_dpm->dpm_current_power_state = NULL;
282 smu_dpm->dpm_request_power_state = NULL;
279 283
280 return 0; 284 return 0;
281} 285}
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 @@
31#include "smu11_driver_if.h" 31#include "smu11_driver_if.h"
32#include "soc15_common.h" 32#include "soc15_common.h"
33#include "atom.h" 33#include "atom.h"
34#include "power_state.h"
34#include "vega20_ppt.h" 35#include "vega20_ppt.h"
35#include "vega20_pptable.h" 36#include "vega20_pptable.h"
36#include "vega20_ppsmc.h" 37#include "vega20_ppsmc.h"
@@ -154,6 +155,16 @@ static int vega20_allocate_dpm_context(struct smu_context *smu)
154 155
155 smu_dpm->dpm_context_size = sizeof(struct vega20_dpm_table); 156 smu_dpm->dpm_context_size = sizeof(struct vega20_dpm_table);
156 157
158 smu_dpm->dpm_current_power_state = kzalloc(sizeof(struct smu_power_state),
159 GFP_KERNEL);
160 if (!smu_dpm->dpm_current_power_state)
161 return -ENOMEM;
162
163 smu_dpm->dpm_request_power_state = kzalloc(sizeof(struct smu_power_state),
164 GFP_KERNEL);
165 if (!smu_dpm->dpm_request_power_state)
166 return -ENOMEM;
167
157 return 0; 168 return 0;
158} 169}
159 170
@@ -389,6 +400,39 @@ vega20_get_unallowed_feature_mask(struct smu_context *smu,
389 return 0; 400 return 0;
390} 401}
391 402
403static enum
404amd_pm_state_type vega20_get_current_power_state(struct smu_context *smu)
405{
406 enum amd_pm_state_type pm_type;
407 struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
408
409 if (!smu_dpm_ctx->dpm_context ||
410 !smu_dpm_ctx->dpm_current_power_state)
411 return -EINVAL;
412
413 mutex_lock(&(smu->mutex));
414 switch (smu_dpm_ctx->dpm_current_power_state->classification.ui_label) {
415 case SMU_STATE_UI_LABEL_BATTERY:
416 pm_type = POWER_STATE_TYPE_BATTERY;
417 break;
418 case SMU_STATE_UI_LABEL_BALLANCED:
419 pm_type = POWER_STATE_TYPE_BALANCED;
420 break;
421 case SMU_STATE_UI_LABEL_PERFORMANCE:
422 pm_type = POWER_STATE_TYPE_PERFORMANCE;
423 break;
424 default:
425 if (smu_dpm_ctx->dpm_current_power_state->classification.flags & SMU_STATE_CLASSIFICATION_FLAG_BOOT)
426 pm_type = POWER_STATE_TYPE_INTERNAL_BOOT;
427 else
428 pm_type = POWER_STATE_TYPE_DEFAULT;
429 break;
430 }
431 mutex_unlock(&(smu->mutex));
432
433 return pm_type;
434}
435
392static int 436static int
393vega20_set_single_dpm_table(struct smu_context *smu, 437vega20_set_single_dpm_table(struct smu_context *smu,
394 struct vega20_single_dpm_table *single_dpm_table, 438 struct vega20_single_dpm_table *single_dpm_table,
@@ -1263,7 +1307,9 @@ static const struct pptable_funcs vega20_ppt_funcs = {
1263 .get_smu_msg_index = vega20_get_smu_msg_index, 1307 .get_smu_msg_index = vega20_get_smu_msg_index,
1264 .run_afll_btc = vega20_run_btc_afll, 1308 .run_afll_btc = vega20_run_btc_afll,
1265 .get_unallowed_feature_mask = vega20_get_unallowed_feature_mask, 1309 .get_unallowed_feature_mask = vega20_get_unallowed_feature_mask,
1310 .get_current_power_state = vega20_get_current_power_state,
1266 .set_default_dpm_table = vega20_set_default_dpm_table, 1311 .set_default_dpm_table = vega20_set_default_dpm_table,
1312 .set_power_state = NULL,
1267 .populate_umd_state_clk = vega20_populate_umd_state_clk, 1313 .populate_umd_state_clk = vega20_populate_umd_state_clk,
1268 .print_clk_levels = vega20_print_clk_levels, 1314 .print_clk_levels = vega20_print_clk_levels,
1269 .force_clk_levels = vega20_force_clk_levels, 1315 .force_clk_levels = vega20_force_clk_levels,