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