diff options
author | Evan Quan <evan.quan@amd.com> | 2018-03-19 15:16:14 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-03-21 15:36:55 -0400 |
commit | d33edb6428dfbb8296d53aeb39d710d600cbbd5b (patch) | |
tree | 8a4bcc4b759d14003bed5ae9c9766e80f56a0961 | |
parent | 3503d588e72fae1ef2f1d5a6fa9f86da85cf1e85 (diff) |
drm/amd/powerplay: add new pp_psm infrastructure for vega12 (v2)
New psm infrastructure for vega12.
v2: rebase (Alex)
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-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/powerplay/hwmgr/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c | 244 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_legacy.c | 262 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_legacy.h | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_new.c | 76 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_new.h | 40 |
6 files changed, 452 insertions, 212 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile b/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile index f868b955da92..c1249e03c912 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile | |||
@@ -31,7 +31,7 @@ HARDWARE_MGR = hwmgr.o processpptables.o \ | |||
31 | smu7_clockpowergating.o \ | 31 | smu7_clockpowergating.o \ |
32 | vega10_processpptables.o vega10_hwmgr.o vega10_powertune.o \ | 32 | vega10_processpptables.o vega10_hwmgr.o vega10_powertune.o \ |
33 | vega10_thermal.o smu10_hwmgr.o pp_psm.o\ | 33 | vega10_thermal.o smu10_hwmgr.o pp_psm.o\ |
34 | pp_overdriver.o smu_helper.o | 34 | pp_overdriver.o smu_helper.o pp_psm_legacy.o pp_psm_new.o |
35 | 35 | ||
36 | AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR)) | 36 | AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR)) |
37 | 37 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c index d0ef8f9c1361..295ab9fed3f0 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c | |||
@@ -21,243 +21,65 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/types.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include "pp_psm.h" | 24 | #include "pp_psm.h" |
25 | #include "pp_psm_legacy.h" | ||
26 | #include "pp_psm_new.h" | ||
28 | 27 | ||
29 | int psm_init_power_state_table(struct pp_hwmgr *hwmgr) | 28 | int psm_init_power_state_table(struct pp_hwmgr *hwmgr) |
30 | { | 29 | { |
31 | int result; | 30 | if (hwmgr->chip_id != CHIP_VEGA12) |
32 | unsigned int i; | 31 | return psm_legacy_init_power_state_table(hwmgr); |
33 | unsigned int table_entries; | 32 | else |
34 | struct pp_power_state *state; | 33 | return psm_new_init_power_state_table(hwmgr); |
35 | int size; | ||
36 | |||
37 | if (hwmgr->hwmgr_func->get_num_of_pp_table_entries == NULL) | ||
38 | return -EINVAL; | ||
39 | |||
40 | if (hwmgr->hwmgr_func->get_power_state_size == NULL) | ||
41 | return -EINVAL; | ||
42 | |||
43 | hwmgr->num_ps = table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr); | ||
44 | |||
45 | hwmgr->ps_size = size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) + | ||
46 | sizeof(struct pp_power_state); | ||
47 | |||
48 | hwmgr->ps = kzalloc(size * table_entries, GFP_KERNEL); | ||
49 | if (hwmgr->ps == NULL) | ||
50 | return -ENOMEM; | ||
51 | |||
52 | hwmgr->request_ps = kzalloc(size, GFP_KERNEL); | ||
53 | if (hwmgr->request_ps == NULL) { | ||
54 | kfree(hwmgr->ps); | ||
55 | hwmgr->ps = NULL; | ||
56 | return -ENOMEM; | ||
57 | } | ||
58 | |||
59 | hwmgr->current_ps = kzalloc(size, GFP_KERNEL); | ||
60 | if (hwmgr->current_ps == NULL) { | ||
61 | kfree(hwmgr->request_ps); | ||
62 | kfree(hwmgr->ps); | ||
63 | hwmgr->request_ps = NULL; | ||
64 | hwmgr->ps = NULL; | ||
65 | return -ENOMEM; | ||
66 | } | ||
67 | |||
68 | state = hwmgr->ps; | ||
69 | |||
70 | for (i = 0; i < table_entries; i++) { | ||
71 | result = hwmgr->hwmgr_func->get_pp_table_entry(hwmgr, i, state); | ||
72 | |||
73 | if (state->classification.flags & PP_StateClassificationFlag_Boot) { | ||
74 | hwmgr->boot_ps = state; | ||
75 | memcpy(hwmgr->current_ps, state, size); | ||
76 | memcpy(hwmgr->request_ps, state, size); | ||
77 | } | ||
78 | |||
79 | state->id = i + 1; /* assigned unique num for every power state id */ | ||
80 | |||
81 | if (state->classification.flags & PP_StateClassificationFlag_Uvd) | ||
82 | hwmgr->uvd_ps = state; | ||
83 | state = (struct pp_power_state *)((unsigned long)state + size); | ||
84 | } | ||
85 | |||
86 | return 0; | ||
87 | } | 34 | } |
88 | 35 | ||
89 | int psm_fini_power_state_table(struct pp_hwmgr *hwmgr) | 36 | int psm_fini_power_state_table(struct pp_hwmgr *hwmgr) |
90 | { | 37 | { |
91 | if (hwmgr == NULL) | 38 | if (hwmgr->chip_id != CHIP_VEGA12) |
92 | return -EINVAL; | 39 | return psm_legacy_fini_power_state_table(hwmgr); |
93 | 40 | else | |
94 | kfree(hwmgr->current_ps); | 41 | return psm_new_fini_power_state_table(hwmgr); |
95 | kfree(hwmgr->request_ps); | ||
96 | kfree(hwmgr->ps); | ||
97 | hwmgr->request_ps = NULL; | ||
98 | hwmgr->ps = NULL; | ||
99 | hwmgr->current_ps = NULL; | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int psm_get_ui_state(struct pp_hwmgr *hwmgr, | ||
104 | enum PP_StateUILabel ui_label, | ||
105 | unsigned long *state_id) | ||
106 | { | ||
107 | struct pp_power_state *state; | ||
108 | int table_entries; | ||
109 | int i; | ||
110 | |||
111 | table_entries = hwmgr->num_ps; | ||
112 | state = hwmgr->ps; | ||
113 | |||
114 | for (i = 0; i < table_entries; i++) { | ||
115 | if (state->classification.ui_label & ui_label) { | ||
116 | *state_id = state->id; | ||
117 | return 0; | ||
118 | } | ||
119 | state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size); | ||
120 | } | ||
121 | return -EINVAL; | ||
122 | } | ||
123 | |||
124 | static int psm_get_state_by_classification(struct pp_hwmgr *hwmgr, | ||
125 | enum PP_StateClassificationFlag flag, | ||
126 | unsigned long *state_id) | ||
127 | { | ||
128 | struct pp_power_state *state; | ||
129 | int table_entries; | ||
130 | int i; | ||
131 | |||
132 | table_entries = hwmgr->num_ps; | ||
133 | state = hwmgr->ps; | ||
134 | |||
135 | for (i = 0; i < table_entries; i++) { | ||
136 | if (state->classification.flags & flag) { | ||
137 | *state_id = state->id; | ||
138 | return 0; | ||
139 | } | ||
140 | state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size); | ||
141 | } | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | |||
145 | static int psm_set_states(struct pp_hwmgr *hwmgr, unsigned long state_id) | ||
146 | { | ||
147 | struct pp_power_state *state; | ||
148 | int table_entries; | ||
149 | int i; | ||
150 | |||
151 | table_entries = hwmgr->num_ps; | ||
152 | |||
153 | state = hwmgr->ps; | ||
154 | |||
155 | for (i = 0; i < table_entries; i++) { | ||
156 | if (state->id == state_id) { | ||
157 | memcpy(hwmgr->request_ps, state, hwmgr->ps_size); | ||
158 | return 0; | ||
159 | } | ||
160 | state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size); | ||
161 | } | ||
162 | return -EINVAL; | ||
163 | } | 42 | } |
164 | 43 | ||
165 | int psm_set_boot_states(struct pp_hwmgr *hwmgr) | 44 | int psm_set_boot_states(struct pp_hwmgr *hwmgr) |
166 | { | 45 | { |
167 | unsigned long state_id; | 46 | if (hwmgr->chip_id != CHIP_VEGA12) |
168 | int ret = -EINVAL; | 47 | return psm_legacy_set_boot_states(hwmgr); |
169 | 48 | else | |
170 | if (!psm_get_state_by_classification(hwmgr, PP_StateClassificationFlag_Boot, | 49 | return psm_new_set_boot_states(hwmgr); |
171 | &state_id)) | ||
172 | ret = psm_set_states(hwmgr, state_id); | ||
173 | |||
174 | return ret; | ||
175 | } | 50 | } |
176 | 51 | ||
177 | int psm_set_performance_states(struct pp_hwmgr *hwmgr) | 52 | int psm_set_performance_states(struct pp_hwmgr *hwmgr) |
178 | { | 53 | { |
179 | unsigned long state_id; | 54 | if (hwmgr->chip_id != CHIP_VEGA12) |
180 | int ret = -EINVAL; | 55 | return psm_legacy_set_performance_states(hwmgr); |
181 | 56 | else | |
182 | if (!psm_get_ui_state(hwmgr, PP_StateUILabel_Performance, | 57 | return psm_new_set_performance_states(hwmgr); |
183 | &state_id)) | ||
184 | ret = psm_set_states(hwmgr, state_id); | ||
185 | |||
186 | return ret; | ||
187 | } | 58 | } |
188 | 59 | ||
189 | int psm_set_user_performance_state(struct pp_hwmgr *hwmgr, | 60 | int psm_set_user_performance_state(struct pp_hwmgr *hwmgr, |
190 | enum PP_StateUILabel label_id, | 61 | enum PP_StateUILabel label_id, |
191 | struct pp_power_state **state) | 62 | struct pp_power_state **state) |
192 | { | 63 | { |
193 | int table_entries; | 64 | if (hwmgr->chip_id != CHIP_VEGA12) |
194 | int i; | 65 | return psm_legacy_set_user_performance_state(hwmgr, |
195 | 66 | label_id, | |
196 | table_entries = hwmgr->num_ps; | 67 | state); |
197 | *state = hwmgr->ps; | 68 | else |
198 | 69 | return psm_new_set_user_performance_state(hwmgr, | |
199 | restart_search: | 70 | label_id, |
200 | for (i = 0; i < table_entries; i++) { | 71 | state); |
201 | if ((*state)->classification.ui_label & label_id) | ||
202 | return 0; | ||
203 | *state = (struct pp_power_state *)((uintptr_t)*state + hwmgr->ps_size); | ||
204 | } | ||
205 | |||
206 | switch (label_id) { | ||
207 | case PP_StateUILabel_Battery: | ||
208 | case PP_StateUILabel_Balanced: | ||
209 | label_id = PP_StateUILabel_Performance; | ||
210 | goto restart_search; | ||
211 | default: | ||
212 | break; | ||
213 | } | ||
214 | return -EINVAL; | ||
215 | } | 72 | } |
216 | 73 | ||
217 | int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip, | 74 | int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip, |
218 | struct pp_power_state *new_ps) | 75 | struct pp_power_state *new_ps) |
219 | { | 76 | { |
220 | struct pp_power_state *pcurrent; | 77 | if (hwmgr->chip_id != CHIP_VEGA12) |
221 | struct pp_power_state *requested; | 78 | return psm_legacy_adjust_power_state_dynamic(hwmgr, |
222 | bool equal; | 79 | skip, |
223 | uint32_t index; | 80 | new_ps); |
224 | long workload; | ||
225 | |||
226 | if (skip) | ||
227 | return 0; | ||
228 | |||
229 | phm_display_configuration_changed(hwmgr); | ||
230 | |||
231 | if (new_ps != NULL) | ||
232 | requested = new_ps; | ||
233 | else | 81 | else |
234 | requested = hwmgr->request_ps; | 82 | return psm_new_adjust_power_state_dynamic(hwmgr, |
235 | 83 | skip, | |
236 | pcurrent = hwmgr->current_ps; | 84 | new_ps); |
237 | |||
238 | phm_apply_state_adjust_rules(hwmgr, requested, pcurrent); | ||
239 | if (pcurrent == NULL || (0 != phm_check_states_equal(hwmgr, | ||
240 | &pcurrent->hardware, &requested->hardware, &equal))) | ||
241 | equal = false; | ||
242 | |||
243 | if (!equal || phm_check_smc_update_required_for_display_configuration(hwmgr)) { | ||
244 | phm_set_power_state(hwmgr, &pcurrent->hardware, &requested->hardware); | ||
245 | memcpy(hwmgr->current_ps, hwmgr->request_ps, hwmgr->ps_size); | ||
246 | } | ||
247 | |||
248 | phm_notify_smc_display_config_after_ps_adjustment(hwmgr); | ||
249 | if (!phm_force_dpm_levels(hwmgr, hwmgr->request_dpm_level)) | ||
250 | hwmgr->dpm_level = hwmgr->request_dpm_level; | ||
251 | |||
252 | if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { | ||
253 | index = fls(hwmgr->workload_mask); | ||
254 | index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; | ||
255 | workload = hwmgr->workload_setting[index]; | ||
256 | |||
257 | if (hwmgr->power_profile_mode != workload && hwmgr->hwmgr_func->set_power_profile_mode) | ||
258 | hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); | ||
259 | } | ||
260 | |||
261 | return 0; | ||
262 | } | 85 | } |
263 | |||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_legacy.c b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_legacy.c new file mode 100644 index 000000000000..e3ac52820641 --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_legacy.c | |||
@@ -0,0 +1,262 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/types.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include "pp_psm_legacy.h" | ||
28 | |||
29 | int psm_legacy_init_power_state_table(struct pp_hwmgr *hwmgr) | ||
30 | { | ||
31 | int result; | ||
32 | unsigned int i; | ||
33 | unsigned int table_entries; | ||
34 | struct pp_power_state *state; | ||
35 | int size; | ||
36 | |||
37 | if (hwmgr->hwmgr_func->get_num_of_pp_table_entries == NULL) | ||
38 | return -EINVAL; | ||
39 | |||
40 | if (hwmgr->hwmgr_func->get_power_state_size == NULL) | ||
41 | return -EINVAL; | ||
42 | |||
43 | hwmgr->num_ps = table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr); | ||
44 | |||
45 | hwmgr->ps_size = size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) + | ||
46 | sizeof(struct pp_power_state); | ||
47 | |||
48 | hwmgr->ps = kzalloc(size * table_entries, GFP_KERNEL); | ||
49 | if (hwmgr->ps == NULL) | ||
50 | return -ENOMEM; | ||
51 | |||
52 | hwmgr->request_ps = kzalloc(size, GFP_KERNEL); | ||
53 | if (hwmgr->request_ps == NULL) { | ||
54 | kfree(hwmgr->ps); | ||
55 | hwmgr->ps = NULL; | ||
56 | return -ENOMEM; | ||
57 | } | ||
58 | |||
59 | hwmgr->current_ps = kzalloc(size, GFP_KERNEL); | ||
60 | if (hwmgr->current_ps == NULL) { | ||
61 | kfree(hwmgr->request_ps); | ||
62 | kfree(hwmgr->ps); | ||
63 | hwmgr->request_ps = NULL; | ||
64 | hwmgr->ps = NULL; | ||
65 | return -ENOMEM; | ||
66 | } | ||
67 | |||
68 | state = hwmgr->ps; | ||
69 | |||
70 | for (i = 0; i < table_entries; i++) { | ||
71 | result = hwmgr->hwmgr_func->get_pp_table_entry(hwmgr, i, state); | ||
72 | |||
73 | if (state->classification.flags & PP_StateClassificationFlag_Boot) { | ||
74 | hwmgr->boot_ps = state; | ||
75 | memcpy(hwmgr->current_ps, state, size); | ||
76 | memcpy(hwmgr->request_ps, state, size); | ||
77 | } | ||
78 | |||
79 | state->id = i + 1; /* assigned unique num for every power state id */ | ||
80 | |||
81 | if (state->classification.flags & PP_StateClassificationFlag_Uvd) | ||
82 | hwmgr->uvd_ps = state; | ||
83 | state = (struct pp_power_state *)((unsigned long)state + size); | ||
84 | } | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | int psm_legacy_fini_power_state_table(struct pp_hwmgr *hwmgr) | ||
90 | { | ||
91 | if (hwmgr == NULL) | ||
92 | return -EINVAL; | ||
93 | |||
94 | kfree(hwmgr->current_ps); | ||
95 | kfree(hwmgr->request_ps); | ||
96 | kfree(hwmgr->ps); | ||
97 | hwmgr->request_ps = NULL; | ||
98 | hwmgr->ps = NULL; | ||
99 | hwmgr->current_ps = NULL; | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int get_ui_state(struct pp_hwmgr *hwmgr, | ||
104 | enum PP_StateUILabel ui_label, | ||
105 | unsigned long *state_id) | ||
106 | { | ||
107 | struct pp_power_state *state; | ||
108 | int table_entries; | ||
109 | int i; | ||
110 | |||
111 | table_entries = hwmgr->num_ps; | ||
112 | state = hwmgr->ps; | ||
113 | |||
114 | for (i = 0; i < table_entries; i++) { | ||
115 | if (state->classification.ui_label & ui_label) { | ||
116 | *state_id = state->id; | ||
117 | return 0; | ||
118 | } | ||
119 | state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size); | ||
120 | } | ||
121 | return -EINVAL; | ||
122 | } | ||
123 | |||
124 | static int get_state_by_classification(struct pp_hwmgr *hwmgr, | ||
125 | enum PP_StateClassificationFlag flag, | ||
126 | unsigned long *state_id) | ||
127 | { | ||
128 | struct pp_power_state *state; | ||
129 | int table_entries; | ||
130 | int i; | ||
131 | |||
132 | table_entries = hwmgr->num_ps; | ||
133 | state = hwmgr->ps; | ||
134 | |||
135 | for (i = 0; i < table_entries; i++) { | ||
136 | if (state->classification.flags & flag) { | ||
137 | *state_id = state->id; | ||
138 | return 0; | ||
139 | } | ||
140 | state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size); | ||
141 | } | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | |||
145 | static int set_states(struct pp_hwmgr *hwmgr, unsigned long state_id) | ||
146 | { | ||
147 | struct pp_power_state *state; | ||
148 | int table_entries; | ||
149 | int i; | ||
150 | |||
151 | table_entries = hwmgr->num_ps; | ||
152 | |||
153 | state = hwmgr->ps; | ||
154 | |||
155 | for (i = 0; i < table_entries; i++) { | ||
156 | if (state->id == state_id) { | ||
157 | memcpy(hwmgr->request_ps, state, hwmgr->ps_size); | ||
158 | return 0; | ||
159 | } | ||
160 | state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size); | ||
161 | } | ||
162 | return -EINVAL; | ||
163 | } | ||
164 | |||
165 | int psm_legacy_set_boot_states(struct pp_hwmgr *hwmgr) | ||
166 | { | ||
167 | unsigned long state_id; | ||
168 | int ret = -EINVAL; | ||
169 | |||
170 | if (!get_state_by_classification(hwmgr, PP_StateClassificationFlag_Boot, | ||
171 | &state_id)) | ||
172 | ret = set_states(hwmgr, state_id); | ||
173 | |||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | int psm_legacy_set_performance_states(struct pp_hwmgr *hwmgr) | ||
178 | { | ||
179 | unsigned long state_id; | ||
180 | int ret = -EINVAL; | ||
181 | |||
182 | if (!get_ui_state(hwmgr, PP_StateUILabel_Performance, | ||
183 | &state_id)) | ||
184 | ret = set_states(hwmgr, state_id); | ||
185 | |||
186 | return ret; | ||
187 | } | ||
188 | |||
189 | int psm_legacy_set_user_performance_state(struct pp_hwmgr *hwmgr, | ||
190 | enum PP_StateUILabel label_id, | ||
191 | struct pp_power_state **state) | ||
192 | { | ||
193 | int table_entries; | ||
194 | int i; | ||
195 | |||
196 | table_entries = hwmgr->num_ps; | ||
197 | *state = hwmgr->ps; | ||
198 | |||
199 | restart_search: | ||
200 | for (i = 0; i < table_entries; i++) { | ||
201 | if ((*state)->classification.ui_label & label_id) | ||
202 | return 0; | ||
203 | *state = (struct pp_power_state *)((uintptr_t)*state + hwmgr->ps_size); | ||
204 | } | ||
205 | |||
206 | switch (label_id) { | ||
207 | case PP_StateUILabel_Battery: | ||
208 | case PP_StateUILabel_Balanced: | ||
209 | label_id = PP_StateUILabel_Performance; | ||
210 | goto restart_search; | ||
211 | default: | ||
212 | break; | ||
213 | } | ||
214 | return -EINVAL; | ||
215 | } | ||
216 | |||
217 | int psm_legacy_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip, | ||
218 | struct pp_power_state *new_ps) | ||
219 | { | ||
220 | struct pp_power_state *pcurrent; | ||
221 | struct pp_power_state *requested; | ||
222 | bool equal; | ||
223 | uint32_t index; | ||
224 | long workload; | ||
225 | |||
226 | if (skip) | ||
227 | return 0; | ||
228 | |||
229 | phm_display_configuration_changed(hwmgr); | ||
230 | |||
231 | if (new_ps != NULL) | ||
232 | requested = new_ps; | ||
233 | else | ||
234 | requested = hwmgr->request_ps; | ||
235 | |||
236 | pcurrent = hwmgr->current_ps; | ||
237 | |||
238 | phm_apply_state_adjust_rules(hwmgr, requested, pcurrent); | ||
239 | if (pcurrent == NULL || (0 != phm_check_states_equal(hwmgr, | ||
240 | &pcurrent->hardware, &requested->hardware, &equal))) | ||
241 | equal = false; | ||
242 | |||
243 | if (!equal || phm_check_smc_update_required_for_display_configuration(hwmgr)) { | ||
244 | phm_set_power_state(hwmgr, &pcurrent->hardware, &requested->hardware); | ||
245 | memcpy(hwmgr->current_ps, hwmgr->request_ps, hwmgr->ps_size); | ||
246 | } | ||
247 | |||
248 | phm_notify_smc_display_config_after_ps_adjustment(hwmgr); | ||
249 | if (!phm_force_dpm_levels(hwmgr, hwmgr->request_dpm_level)) | ||
250 | hwmgr->dpm_level = hwmgr->request_dpm_level; | ||
251 | |||
252 | if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { | ||
253 | index = fls(hwmgr->workload_mask); | ||
254 | index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; | ||
255 | workload = hwmgr->workload_setting[index]; | ||
256 | |||
257 | if (hwmgr->power_profile_mode != workload && hwmgr->hwmgr_func->set_power_profile_mode) | ||
258 | hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); | ||
259 | } | ||
260 | |||
261 | return 0; | ||
262 | } | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_legacy.h b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_legacy.h new file mode 100644 index 000000000000..bc99411c1a46 --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_legacy.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifndef PP_PSM_LEGACY_H | ||
25 | #define PP_PSM_LEGACY_H | ||
26 | |||
27 | #include "hwmgr.h" | ||
28 | |||
29 | int psm_legacy_init_power_state_table(struct pp_hwmgr *hwmgr); | ||
30 | int psm_legacy_fini_power_state_table(struct pp_hwmgr *hwmgr); | ||
31 | int psm_legacy_set_boot_states(struct pp_hwmgr *hwmgr); | ||
32 | int psm_legacy_set_performance_states(struct pp_hwmgr *hwmgr); | ||
33 | int psm_legacy_set_user_performance_state(struct pp_hwmgr *hwmgr, | ||
34 | enum PP_StateUILabel label_id, | ||
35 | struct pp_power_state **state); | ||
36 | int psm_legacy_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, | ||
37 | bool skip, | ||
38 | struct pp_power_state *new_ps); | ||
39 | |||
40 | #endif | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_new.c b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_new.c new file mode 100644 index 000000000000..9eba8a1f2855 --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_new.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/types.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include "pp_psm_new.h" | ||
28 | |||
29 | int psm_new_init_power_state_table(struct pp_hwmgr *hwmgr) | ||
30 | { | ||
31 | hwmgr->ps_size = 0; | ||
32 | hwmgr->num_ps = 0; | ||
33 | hwmgr->ps = NULL; | ||
34 | hwmgr->request_ps = NULL; | ||
35 | hwmgr->current_ps = NULL; | ||
36 | hwmgr->boot_ps = NULL; | ||
37 | hwmgr->uvd_ps = NULL; | ||
38 | |||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | int psm_new_fini_power_state_table(struct pp_hwmgr *hwmgr) | ||
43 | { | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | int psm_new_set_boot_states(struct pp_hwmgr *hwmgr) | ||
48 | { | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | int psm_new_set_performance_states(struct pp_hwmgr *hwmgr) | ||
53 | { | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | int psm_new_set_user_performance_state(struct pp_hwmgr *hwmgr, | ||
58 | enum PP_StateUILabel label_id, | ||
59 | struct pp_power_state **state) | ||
60 | { | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | int psm_new_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, | ||
65 | bool skip, | ||
66 | struct pp_power_state *new_ps) | ||
67 | { | ||
68 | if (skip) | ||
69 | return 0; | ||
70 | |||
71 | phm_display_configuration_changed(hwmgr); | ||
72 | |||
73 | phm_notify_smc_display_config_after_ps_adjustment(hwmgr); | ||
74 | |||
75 | return 0; | ||
76 | } | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_new.h b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_new.h new file mode 100644 index 000000000000..5c4fabcd8a15 --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm_new.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifndef PP_PSM_NEW_H | ||
25 | #define PP_PSM_NEW_H | ||
26 | |||
27 | #include "hwmgr.h" | ||
28 | |||
29 | int psm_new_init_power_state_table(struct pp_hwmgr *hwmgr); | ||
30 | int psm_new_fini_power_state_table(struct pp_hwmgr *hwmgr); | ||
31 | int psm_new_set_boot_states(struct pp_hwmgr *hwmgr); | ||
32 | int psm_new_set_performance_states(struct pp_hwmgr *hwmgr); | ||
33 | int psm_new_set_user_performance_state(struct pp_hwmgr *hwmgr, | ||
34 | enum PP_StateUILabel label_id, | ||
35 | struct pp_power_state **state); | ||
36 | int psm_new_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, | ||
37 | bool skip, | ||
38 | struct pp_power_state *new_ps); | ||
39 | |||
40 | #endif | ||