Commit | Line | Data |
---|---|---|
e92a0370 RZ |
1 | /* |
2 | * Copyright 2015 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 "eventmgr.h" | |
25 | #include "eventinit.h" | |
26 | #include "eventmanagement.h" | |
27 | #include "eventmanager.h" | |
28 | #include "hardwaremanager.h" | |
29 | #include "eventtasks.h" | |
30 | #include "power_state.h" | |
31 | #include "hwmgr.h" | |
32 | #include "amd_powerplay.h" | |
33 | #include "psm.h" | |
34 | ||
2dfea9cd RZ |
35 | #define TEMP_RANGE_MIN (90 * 1000) |
36 | #define TEMP_RANGE_MAX (120 * 1000) | |
37 | ||
e92a0370 RZ |
38 | int pem_task_update_allowed_performance_levels(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) |
39 | { | |
40 | ||
41 | if (pem_is_hw_access_blocked(eventmgr)) | |
42 | return 0; | |
43 | ||
44 | phm_force_dpm_levels(eventmgr->hwmgr, AMD_DPM_FORCED_LEVEL_AUTO); | |
45 | ||
46 | return 0; | |
47 | } | |
48 | ||
49 | /* eventtasks_generic.c */ | |
50 | int pem_task_adjust_power_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
51 | { | |
52 | struct pp_hwmgr *hwmgr; | |
53 | ||
54 | if (pem_is_hw_access_blocked(eventmgr)) | |
55 | return 0; | |
56 | ||
57 | hwmgr = eventmgr->hwmgr; | |
58 | if (event_data->pnew_power_state != NULL) | |
59 | hwmgr->request_ps = event_data->pnew_power_state; | |
60 | ||
61 | if (phm_cap_enabled(eventmgr->platform_descriptor->platformCaps, PHM_PlatformCaps_DynamicPatchPowerState)) | |
62 | psm_adjust_power_state_dynamic(eventmgr, event_data->skip_state_adjust_rules); | |
63 | else | |
64 | psm_adjust_power_state_static(eventmgr, event_data->skip_state_adjust_rules); | |
65 | ||
66 | return 0; | |
67 | } | |
68 | ||
69 | int pem_task_power_down_asic(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
70 | { | |
e1d32e60 | 71 | return phm_power_down_asic(eventmgr->hwmgr); |
e92a0370 RZ |
72 | } |
73 | ||
74 | int pem_task_set_boot_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
75 | { | |
018462d0 RZ |
76 | if (pem_is_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID)) |
77 | return psm_set_states(eventmgr, &(event_data->requested_state_id)); | |
78 | ||
e92a0370 RZ |
79 | return 0; |
80 | } | |
81 | ||
82 | int pem_task_reset_boot_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
83 | { | |
84 | /* TODO */ | |
85 | return 0; | |
86 | } | |
87 | ||
88 | int pem_task_update_new_power_state_clocks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
89 | { | |
90 | /* TODO */ | |
91 | return 0; | |
92 | } | |
93 | ||
94 | int pem_task_system_shutdown(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
95 | { | |
96 | /* TODO */ | |
97 | return 0; | |
98 | } | |
99 | ||
100 | int pem_task_register_interrupts(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
101 | { | |
102 | /* TODO */ | |
103 | return 0; | |
104 | } | |
105 | ||
106 | int pem_task_unregister_interrupts(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
107 | { | |
108 | return pem_unregister_interrupts(eventmgr); | |
109 | } | |
110 | ||
e92a0370 RZ |
111 | int pem_task_get_boot_state_id(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) |
112 | { | |
113 | int result; | |
114 | ||
115 | result = psm_get_state_by_classification(eventmgr, | |
116 | PP_StateClassificationFlag_Boot, | |
117 | &(event_data->requested_state_id) | |
118 | ); | |
119 | ||
120 | if (0 == result) | |
121 | pem_set_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID); | |
122 | else | |
123 | pem_unset_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID); | |
124 | ||
125 | return result; | |
126 | } | |
127 | ||
128 | int pem_task_enable_dynamic_state_management(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
129 | { | |
130 | return phm_enable_dynamic_state_management(eventmgr->hwmgr); | |
131 | } | |
132 | ||
133 | int pem_task_disable_dynamic_state_management(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
134 | { | |
80597521 | 135 | return phm_disable_dynamic_state_management(eventmgr->hwmgr); |
e92a0370 RZ |
136 | } |
137 | ||
138 | int pem_task_enable_clock_power_gatings_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
139 | { | |
140 | return phm_enable_clock_power_gatings(eventmgr->hwmgr); | |
141 | } | |
142 | ||
143 | int pem_task_powerdown_uvd_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
144 | { | |
145 | return phm_powerdown_uvd(eventmgr->hwmgr); | |
146 | } | |
147 | ||
148 | int pem_task_powerdown_vce_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
149 | { | |
150 | phm_powergate_uvd(eventmgr->hwmgr, true); | |
151 | phm_powergate_vce(eventmgr->hwmgr, true); | |
152 | return 0; | |
153 | } | |
154 | ||
155 | int pem_task_disable_clock_power_gatings_tasks(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
156 | { | |
157 | /* TODO */ | |
158 | return 0; | |
159 | } | |
160 | ||
161 | int pem_task_start_asic_block_usage(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
162 | { | |
163 | /* TODO */ | |
164 | return 0; | |
165 | } | |
166 | ||
167 | int pem_task_stop_asic_block_usage(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
168 | { | |
169 | /* TODO */ | |
170 | return 0; | |
171 | } | |
172 | ||
173 | int pem_task_setup_asic(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
174 | { | |
175 | return phm_setup_asic(eventmgr->hwmgr); | |
176 | } | |
177 | ||
178 | int pem_task_cleanup_asic(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
179 | { | |
180 | /* TODO */ | |
181 | return 0; | |
182 | } | |
183 | ||
184 | int pem_task_store_dal_configuration(struct pp_eventmgr *eventmgr, const struct amd_display_configuration *display_config) | |
185 | { | |
186 | /* TODO */ | |
187 | return 0; | |
188 | /*phm_store_dal_configuration_data(eventmgr->hwmgr, display_config) */ | |
189 | } | |
190 | ||
191 | int pem_task_notify_hw_mgr_display_configuration_change(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
192 | { | |
2f4afc57 RZ |
193 | if (pem_is_hw_access_blocked(eventmgr)) |
194 | return 0; | |
195 | ||
196 | return phm_display_configuration_changed(eventmgr->hwmgr); | |
e92a0370 RZ |
197 | } |
198 | ||
199 | int pem_task_notify_hw_mgr_pre_display_configuration_change(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
200 | { | |
e92a0370 | 201 | return 0; |
2f4afc57 RZ |
202 | } |
203 | ||
204 | int pem_task_notify_smc_display_config_after_power_state_adjustment(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
205 | { | |
206 | if (pem_is_hw_access_blocked(eventmgr)) | |
207 | return 0; | |
208 | ||
209 | return phm_notify_smc_display_config_after_ps_adjustment(eventmgr->hwmgr); | |
e92a0370 RZ |
210 | } |
211 | ||
212 | int pem_task_block_adjust_power_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
213 | { | |
214 | eventmgr->block_adjust_power_state = true; | |
215 | /* to do PHM_ResetIPSCounter(pEventMgr->pHwMgr);*/ | |
216 | return 0; | |
217 | } | |
218 | ||
219 | int pem_task_unblock_adjust_power_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
220 | { | |
221 | eventmgr->block_adjust_power_state = false; | |
222 | return 0; | |
223 | } | |
224 | ||
225 | int pem_task_notify_power_state_change(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
226 | { | |
227 | /* TODO */ | |
228 | return 0; | |
229 | } | |
230 | ||
231 | int pem_task_block_hw_access(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
232 | { | |
233 | /* TODO */ | |
234 | return 0; | |
235 | } | |
236 | ||
237 | int pem_task_un_block_hw_access(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
238 | { | |
239 | /* TODO */ | |
240 | return 0; | |
241 | } | |
242 | ||
243 | int pem_task_reset_display_phys_access(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
244 | { | |
245 | /* TODO */ | |
246 | return 0; | |
247 | } | |
248 | ||
249 | int pem_task_set_cpu_power_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
250 | { | |
73afe621 | 251 | return phm_set_cpu_power_state(eventmgr->hwmgr); |
e92a0370 RZ |
252 | } |
253 | ||
254 | /*powersaving*/ | |
255 | ||
256 | int pem_task_set_power_source(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
257 | { | |
258 | /* TODO */ | |
259 | return 0; | |
260 | } | |
261 | ||
262 | int pem_task_notify_hw_of_power_source(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
263 | { | |
264 | /* TODO */ | |
265 | return 0; | |
266 | } | |
267 | ||
268 | int pem_task_get_power_saving_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
269 | { | |
270 | /* TODO */ | |
271 | return 0; | |
272 | } | |
273 | ||
274 | int pem_task_reset_power_saving_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
275 | { | |
276 | /* TODO */ | |
277 | return 0; | |
278 | } | |
279 | ||
280 | int pem_task_set_power_saving_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
281 | { | |
282 | /* TODO */ | |
283 | return 0; | |
284 | } | |
285 | ||
286 | int pem_task_set_screen_state_on(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
287 | { | |
288 | /* TODO */ | |
289 | return 0; | |
290 | } | |
291 | ||
292 | int pem_task_set_screen_state_off(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
293 | { | |
294 | /* TODO */ | |
295 | return 0; | |
296 | } | |
297 | ||
298 | int pem_task_enable_voltage_island_power_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
299 | { | |
300 | /* TODO */ | |
301 | return 0; | |
302 | } | |
303 | ||
304 | int pem_task_disable_voltage_island_power_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
305 | { | |
306 | /* TODO */ | |
307 | return 0; | |
308 | } | |
309 | ||
310 | int pem_task_enable_cgpg(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
311 | { | |
312 | /* TODO */ | |
313 | return 0; | |
314 | } | |
315 | ||
316 | int pem_task_disable_cgpg(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
317 | { | |
318 | /* TODO */ | |
319 | return 0; | |
320 | } | |
321 | ||
322 | int pem_task_enable_clock_power_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
323 | { | |
324 | /* TODO */ | |
325 | return 0; | |
326 | } | |
327 | ||
328 | ||
329 | int pem_task_enable_gfx_clock_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
330 | { | |
331 | /* TODO */ | |
332 | return 0; | |
333 | } | |
334 | ||
335 | int pem_task_disable_gfx_clock_gating(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
336 | { | |
337 | /* TODO */ | |
338 | return 0; | |
339 | } | |
340 | ||
341 | ||
342 | /* performance */ | |
343 | int pem_task_set_performance_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
344 | { | |
345 | if (pem_is_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID)) | |
018462d0 | 346 | return psm_set_states(eventmgr, &(event_data->requested_state_id)); |
e92a0370 RZ |
347 | |
348 | return 0; | |
349 | } | |
350 | ||
351 | int pem_task_conditionally_force_3d_performance_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
352 | { | |
353 | /* TODO */ | |
354 | return 0; | |
355 | } | |
356 | ||
357 | int pem_task_enable_stutter_mode(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
358 | { | |
359 | /* TODO */ | |
360 | return 0; | |
361 | } | |
362 | ||
363 | int pem_task_get_2D_performance_state_id(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
364 | { | |
365 | int result; | |
366 | ||
367 | if (eventmgr->features[PP_Feature_PowerPlay].supported && | |
368 | !(eventmgr->features[PP_Feature_PowerPlay].enabled)) | |
369 | result = psm_get_state_by_classification(eventmgr, | |
370 | PP_StateClassificationFlag_Boot, | |
371 | &(event_data->requested_state_id)); | |
372 | else if (eventmgr->features[PP_Feature_User2DPerformance].enabled) | |
373 | result = psm_get_state_by_classification(eventmgr, | |
374 | PP_StateClassificationFlag_User2DPerformance, | |
375 | &(event_data->requested_state_id)); | |
376 | else | |
377 | result = psm_get_ui_state(eventmgr, PP_StateUILabel_Performance, | |
378 | &(event_data->requested_state_id)); | |
379 | ||
380 | if (0 == result) | |
381 | pem_set_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID); | |
382 | else | |
383 | pem_unset_event_data_valid(event_data->valid_fields, PEM_EventDataValid_RequestedStateID); | |
384 | ||
385 | return result; | |
386 | } | |
387 | ||
388 | int pem_task_create_user_performance_state(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
389 | { | |
390 | struct pp_power_state *state; | |
391 | int table_entries; | |
392 | struct pp_hwmgr *hwmgr = eventmgr->hwmgr; | |
393 | int i; | |
394 | ||
395 | table_entries = hwmgr->num_ps; | |
396 | state = hwmgr->ps; | |
397 | ||
398 | restart_search: | |
399 | for (i = 0; i < table_entries; i++) { | |
400 | if (state->classification.ui_label & event_data->requested_ui_label) { | |
401 | event_data->pnew_power_state = state; | |
402 | return 0; | |
403 | } | |
09b7a986 | 404 | state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size); |
e92a0370 RZ |
405 | } |
406 | ||
407 | switch (event_data->requested_ui_label) { | |
408 | case PP_StateUILabel_Battery: | |
409 | case PP_StateUILabel_Balanced: | |
410 | event_data->requested_ui_label = PP_StateUILabel_Performance; | |
411 | goto restart_search; | |
412 | default: | |
413 | break; | |
414 | } | |
415 | return -1; | |
416 | } | |
417 | ||
2dfea9cd RZ |
418 | int pem_task_initialize_thermal_controller(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) |
419 | { | |
420 | struct PP_TemperatureRange range; | |
cae9b9c8 | 421 | |
2dfea9cd RZ |
422 | range.max = TEMP_RANGE_MAX; |
423 | range.min = TEMP_RANGE_MIN; | |
424 | ||
cae9b9c8 RZ |
425 | if (eventmgr == NULL || eventmgr->platform_descriptor == NULL) |
426 | return -EINVAL; | |
427 | ||
428 | if (phm_cap_enabled(eventmgr->platform_descriptor->platformCaps, PHM_PlatformCaps_ThermalController)) | |
429 | return phm_start_thermal_controller(eventmgr->hwmgr, &range); | |
430 | ||
431 | return 0; | |
2dfea9cd RZ |
432 | } |
433 | ||
434 | int pem_task_uninitialize_thermal_controller(struct pp_eventmgr *eventmgr, struct pem_event_data *event_data) | |
435 | { | |
436 | return phm_stop_thermal_controller(eventmgr->hwmgr); | |
09b7a986 | 437 | } |