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