diff options
author | Chengming Gui <Jack.Gui@amd.com> | 2019-01-04 04:42:09 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-03-19 16:03:59 -0400 |
commit | 8554e67d6e22b0bc3ba213b87a0b6e1ae0fd838c (patch) | |
tree | 7ac0b6f6f3e2330765c1ab7daf601ff32eda1b57 | |
parent | ad88f0517b239a08b148fbd300de103e8f7a78ef (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.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 116 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 46 |
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 | ||
29 | struct smu_hw_power_state { | ||
30 | unsigned int magic; | ||
31 | }; | ||
32 | |||
33 | struct smu_power_state; | ||
34 | |||
35 | enum 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 | |||
45 | enum 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 | |||
69 | struct 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 | |||
77 | struct smu_state_pcie_block { | ||
78 | unsigned int lanes; | ||
79 | }; | ||
80 | |||
81 | enum smu_refreshrate_source { | ||
82 | SMU_REFRESHRATE_SOURCE_EDID, | ||
83 | SMU_REFRESHRATE_SOURCE_EXPLICIT | ||
84 | }; | ||
85 | |||
86 | struct 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 | |||
95 | struct smu_state_memroy_block { | ||
96 | bool dll_off; | ||
97 | uint8_t m3arb; | ||
98 | uint8_t unused[3]; | ||
99 | }; | ||
100 | |||
101 | struct smu_state_software_algorithm_block { | ||
102 | bool disable_load_balancing; | ||
103 | bool enable_sleep_for_timestamps; | ||
104 | }; | ||
105 | |||
106 | struct smu_temperature_range { | ||
107 | int min; | ||
108 | int max; | ||
109 | }; | ||
110 | |||
111 | struct smu_state_validation_block { | ||
112 | bool single_display_only; | ||
113 | bool disallow_on_dc; | ||
114 | uint8_t supported_power_levels; | ||
115 | }; | ||
116 | |||
117 | struct smu_uvd_clocks { | ||
118 | uint32_t vclk; | ||
119 | uint32_t dclk; | ||
120 | }; | ||
121 | |||
122 | /** | ||
123 | * Structure to hold a SMU Power State. | ||
124 | */ | ||
125 | struct 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 | |||
29 | enum smu_message_type | 141 | enum 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 | ||
209 | struct smu_power_context { | 323 | struct 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 | ||
403 | static enum | ||
404 | amd_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 | |||
392 | static int | 436 | static int |
393 | vega20_set_single_dpm_table(struct smu_context *smu, | 437 | vega20_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, |