]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/amd/powerplay/amd_powerplay.c
dfd4fe6f0578d1ccea29c404824518c2351fd2ec
[karo-tx-linux.git] / drivers / gpu / drm / amd / powerplay / amd_powerplay.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 #include "pp_debug.h"
24 #include <linux/types.h>
25 #include <linux/kernel.h>
26 #include <linux/gfp.h>
27 #include <linux/slab.h>
28 #include "amd_shared.h"
29 #include "amd_powerplay.h"
30 #include "pp_instance.h"
31 #include "power_state.h"
32 #include "eventmanager.h"
33
34
35 static inline int pp_check(struct pp_instance *handle)
36 {
37         if (handle == NULL || handle->pp_valid != PP_VALID)
38                 return -EINVAL;
39
40         if (handle->smu_mgr == NULL || handle->smu_mgr->smumgr_funcs == NULL)
41                 return -EINVAL;
42
43         if (handle->pm_en == 0)
44                 return PP_DPM_DISABLED;
45
46         if (handle->hwmgr == NULL || handle->hwmgr->hwmgr_func == NULL
47                 || handle->eventmgr == NULL)
48                 return PP_DPM_DISABLED;
49
50         return 0;
51 }
52
53 static int pp_early_init(void *handle)
54 {
55         int ret;
56         struct pp_instance *pp_handle = (struct pp_instance *)handle;
57
58         ret = smum_early_init(pp_handle);
59         if (ret)
60                 return ret;
61
62         if ((pp_handle->pm_en == 0)
63                 || cgs_is_virtualization_enabled(pp_handle->device))
64                 return PP_DPM_DISABLED;
65
66         ret = hwmgr_early_init(pp_handle);
67         if (ret) {
68                 pp_handle->pm_en = 0;
69                 return PP_DPM_DISABLED;
70         }
71
72         ret = eventmgr_early_init(pp_handle);
73         if (ret) {
74                 kfree(pp_handle->hwmgr);
75                 pp_handle->hwmgr = NULL;
76                 pp_handle->pm_en = 0;
77                 return PP_DPM_DISABLED;
78         }
79
80         return 0;
81 }
82
83 static int pp_sw_init(void *handle)
84 {
85         struct pp_smumgr *smumgr;
86         int ret = 0;
87         struct pp_instance *pp_handle = (struct pp_instance *)handle;
88
89         ret = pp_check(pp_handle);
90
91         if (ret == 0 || ret == PP_DPM_DISABLED) {
92                 smumgr = pp_handle->smu_mgr;
93
94                 if (smumgr->smumgr_funcs->smu_init == NULL)
95                         return -EINVAL;
96
97                 ret = smumgr->smumgr_funcs->smu_init(smumgr);
98
99                 pr_info("amdgpu: powerplay sw initialized\n");
100         }
101         return ret;
102 }
103
104 static int pp_sw_fini(void *handle)
105 {
106         struct pp_smumgr *smumgr;
107         int ret = 0;
108         struct pp_instance *pp_handle = (struct pp_instance *)handle;
109
110         ret = pp_check(pp_handle);
111         if (ret == 0 || ret == PP_DPM_DISABLED) {
112                 smumgr = pp_handle->smu_mgr;
113
114                 if (smumgr->smumgr_funcs->smu_fini == NULL)
115                         return -EINVAL;
116
117                 ret = smumgr->smumgr_funcs->smu_fini(smumgr);
118         }
119         return ret;
120 }
121
122 static int pp_hw_init(void *handle)
123 {
124         struct pp_smumgr *smumgr;
125         struct pp_eventmgr *eventmgr;
126         int ret = 0;
127         struct pp_instance *pp_handle = (struct pp_instance *)handle;
128
129         ret = pp_check(pp_handle);
130
131         if (ret == 0 || ret == PP_DPM_DISABLED) {
132                 smumgr = pp_handle->smu_mgr;
133
134                 if (smumgr->smumgr_funcs->start_smu == NULL)
135                         return -EINVAL;
136
137                 if(smumgr->smumgr_funcs->start_smu(smumgr)) {
138                         pr_err("smc start failed\n");
139                         smumgr->smumgr_funcs->smu_fini(smumgr);
140                         return -EINVAL;;
141                 }
142                 if (ret == PP_DPM_DISABLED)
143                         return PP_DPM_DISABLED;
144         }
145
146         ret = hwmgr_hw_init(pp_handle);
147         if (ret)
148                 goto err;
149
150         eventmgr = pp_handle->eventmgr;
151         if (eventmgr->pp_eventmgr_init == NULL ||
152                 eventmgr->pp_eventmgr_init(eventmgr))
153                 goto err;
154
155         return 0;
156 err:
157         pp_handle->pm_en = 0;
158         kfree(pp_handle->eventmgr);
159         kfree(pp_handle->hwmgr);
160         pp_handle->hwmgr = NULL;
161         pp_handle->eventmgr = NULL;
162         return PP_DPM_DISABLED;
163 }
164
165 static int pp_hw_fini(void *handle)
166 {
167         struct pp_eventmgr *eventmgr;
168         struct pp_instance *pp_handle = (struct pp_instance *)handle;
169         int ret = 0;
170
171         ret = pp_check(pp_handle);
172
173         if (ret == 0) {
174                 eventmgr = pp_handle->eventmgr;
175
176                 if (eventmgr->pp_eventmgr_fini != NULL)
177                         eventmgr->pp_eventmgr_fini(eventmgr);
178
179                 hwmgr_hw_fini(pp_handle);
180         }
181         return 0;
182 }
183
184 static bool pp_is_idle(void *handle)
185 {
186         return false;
187 }
188
189 static int pp_wait_for_idle(void *handle)
190 {
191         return 0;
192 }
193
194 static int pp_sw_reset(void *handle)
195 {
196         return 0;
197 }
198
199
200 int amd_set_clockgating_by_smu(void *handle, uint32_t msg_id)
201 {
202         struct pp_hwmgr  *hwmgr;
203         struct pp_instance *pp_handle = (struct pp_instance *)handle;
204         int ret = 0;
205
206         ret = pp_check(pp_handle);
207
208         if (ret != 0)
209                 return ret;
210
211         hwmgr = pp_handle->hwmgr;
212
213         if (hwmgr->hwmgr_func->update_clock_gatings == NULL) {
214                 pr_info("%s was not implemented.\n", __func__);
215                 return 0;
216         }
217
218         return hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
219 }
220
221 static int pp_set_powergating_state(void *handle,
222                                     enum amd_powergating_state state)
223 {
224         struct pp_hwmgr  *hwmgr;
225         struct pp_instance *pp_handle = (struct pp_instance *)handle;
226         int ret = 0;
227
228         ret = pp_check(pp_handle);
229
230         if (ret != 0)
231                 return ret;
232
233         hwmgr = pp_handle->hwmgr;
234
235         if (hwmgr->hwmgr_func->enable_per_cu_power_gating == NULL) {
236                 pr_info("%s was not implemented.\n", __func__);
237                 return 0;
238         }
239
240         /* Enable/disable GFX per cu powergating through SMU */
241         return hwmgr->hwmgr_func->enable_per_cu_power_gating(hwmgr,
242                         state == AMD_PG_STATE_GATE);
243 }
244
245 static int pp_suspend(void *handle)
246 {
247         struct pp_eventmgr *eventmgr;
248         struct pem_event_data event_data = { {0} };
249         struct pp_instance *pp_handle = (struct pp_instance *)handle;
250         int ret = 0;
251
252         ret = pp_check(pp_handle);
253
254         if (ret != 0)
255                 return ret;
256
257         eventmgr = pp_handle->eventmgr;
258         pem_handle_event(eventmgr, AMD_PP_EVENT_SUSPEND, &event_data);
259
260         return 0;
261 }
262
263 static int pp_resume(void *handle)
264 {
265         struct pp_eventmgr *eventmgr;
266         struct pem_event_data event_data = { {0} };
267         struct pp_smumgr *smumgr;
268         int ret, ret1;
269         struct pp_instance *pp_handle = (struct pp_instance *)handle;
270
271         ret1 = pp_check(pp_handle);
272
273         if (ret1 != 0 && ret1 != PP_DPM_DISABLED)
274                 return ret1;
275
276         smumgr = pp_handle->smu_mgr;
277
278         if (smumgr->smumgr_funcs->start_smu == NULL)
279                 return -EINVAL;
280
281         ret = smumgr->smumgr_funcs->start_smu(smumgr);
282         if (ret) {
283                 pr_err("smc start failed\n");
284                 smumgr->smumgr_funcs->smu_fini(smumgr);
285                 return ret;
286         }
287
288         if (ret1 == PP_DPM_DISABLED)
289                 return 0;
290
291         eventmgr = pp_handle->eventmgr;
292
293         pem_handle_event(eventmgr, AMD_PP_EVENT_RESUME, &event_data);
294
295         return 0;
296 }
297
298 const struct amd_ip_funcs pp_ip_funcs = {
299         .name = "powerplay",
300         .early_init = pp_early_init,
301         .late_init = NULL,
302         .sw_init = pp_sw_init,
303         .sw_fini = pp_sw_fini,
304         .hw_init = pp_hw_init,
305         .hw_fini = pp_hw_fini,
306         .suspend = pp_suspend,
307         .resume = pp_resume,
308         .is_idle = pp_is_idle,
309         .wait_for_idle = pp_wait_for_idle,
310         .soft_reset = pp_sw_reset,
311         .set_clockgating_state = NULL,
312         .set_powergating_state = pp_set_powergating_state,
313 };
314
315 static int pp_dpm_load_fw(void *handle)
316 {
317         return 0;
318 }
319
320 static int pp_dpm_fw_loading_complete(void *handle)
321 {
322         return 0;
323 }
324
325 static int pp_dpm_force_performance_level(void *handle,
326                                         enum amd_dpm_forced_level level)
327 {
328         struct pp_hwmgr  *hwmgr;
329         struct pp_instance *pp_handle = (struct pp_instance *)handle;
330         int ret = 0;
331
332         ret = pp_check(pp_handle);
333
334         if (ret != 0)
335                 return ret;
336
337         hwmgr = pp_handle->hwmgr;
338
339         if (hwmgr->hwmgr_func->force_dpm_level == NULL) {
340                 pr_info("%s was not implemented.\n", __func__);
341                 return 0;
342         }
343
344         mutex_lock(&pp_handle->pp_lock);
345         hwmgr->hwmgr_func->force_dpm_level(hwmgr, level);
346         mutex_unlock(&pp_handle->pp_lock);
347         return 0;
348 }
349
350 static enum amd_dpm_forced_level pp_dpm_get_performance_level(
351                                                                 void *handle)
352 {
353         struct pp_hwmgr  *hwmgr;
354         struct pp_instance *pp_handle = (struct pp_instance *)handle;
355         int ret = 0;
356         enum amd_dpm_forced_level level;
357
358         ret = pp_check(pp_handle);
359
360         if (ret != 0)
361                 return ret;
362
363         hwmgr = pp_handle->hwmgr;
364         mutex_lock(&pp_handle->pp_lock);
365         level = hwmgr->dpm_level;
366         mutex_unlock(&pp_handle->pp_lock);
367         return level;
368 }
369
370 static int pp_dpm_get_sclk(void *handle, bool low)
371 {
372         struct pp_hwmgr  *hwmgr;
373         struct pp_instance *pp_handle = (struct pp_instance *)handle;
374         int ret = 0;
375
376         ret = pp_check(pp_handle);
377
378         if (ret != 0)
379                 return ret;
380
381         hwmgr = pp_handle->hwmgr;
382
383         if (hwmgr->hwmgr_func->get_sclk == NULL) {
384                 pr_info("%s was not implemented.\n", __func__);
385                 return 0;
386         }
387         mutex_lock(&pp_handle->pp_lock);
388         ret = hwmgr->hwmgr_func->get_sclk(hwmgr, low);
389         mutex_unlock(&pp_handle->pp_lock);
390         return ret;
391 }
392
393 static int pp_dpm_get_mclk(void *handle, bool low)
394 {
395         struct pp_hwmgr  *hwmgr;
396         struct pp_instance *pp_handle = (struct pp_instance *)handle;
397         int ret = 0;
398
399         ret = pp_check(pp_handle);
400
401         if (ret != 0)
402                 return ret;
403
404         hwmgr = pp_handle->hwmgr;
405
406         if (hwmgr->hwmgr_func->get_mclk == NULL) {
407                 pr_info("%s was not implemented.\n", __func__);
408                 return 0;
409         }
410         mutex_lock(&pp_handle->pp_lock);
411         ret = hwmgr->hwmgr_func->get_mclk(hwmgr, low);
412         mutex_unlock(&pp_handle->pp_lock);
413         return ret;
414 }
415
416 static int pp_dpm_powergate_vce(void *handle, bool gate)
417 {
418         struct pp_hwmgr  *hwmgr;
419         struct pp_instance *pp_handle = (struct pp_instance *)handle;
420         int ret = 0;
421
422         ret = pp_check(pp_handle);
423
424         if (ret != 0)
425                 return ret;
426
427         hwmgr = pp_handle->hwmgr;
428
429         if (hwmgr->hwmgr_func->powergate_vce == NULL) {
430                 pr_info("%s was not implemented.\n", __func__);
431                 return 0;
432         }
433         mutex_lock(&pp_handle->pp_lock);
434         ret = hwmgr->hwmgr_func->powergate_vce(hwmgr, gate);
435         mutex_unlock(&pp_handle->pp_lock);
436         return ret;
437 }
438
439 static int pp_dpm_powergate_uvd(void *handle, bool gate)
440 {
441         struct pp_hwmgr  *hwmgr;
442         struct pp_instance *pp_handle = (struct pp_instance *)handle;
443         int ret = 0;
444
445         ret = pp_check(pp_handle);
446
447         if (ret != 0)
448                 return ret;
449
450         hwmgr = pp_handle->hwmgr;
451
452         if (hwmgr->hwmgr_func->powergate_uvd == NULL) {
453                 pr_info("%s was not implemented.\n", __func__);
454                 return 0;
455         }
456         mutex_lock(&pp_handle->pp_lock);
457         ret = hwmgr->hwmgr_func->powergate_uvd(hwmgr, gate);
458         mutex_unlock(&pp_handle->pp_lock);
459         return ret;
460 }
461
462 static enum PP_StateUILabel power_state_convert(enum amd_pm_state_type  state)
463 {
464         switch (state) {
465         case POWER_STATE_TYPE_BATTERY:
466                 return PP_StateUILabel_Battery;
467         case POWER_STATE_TYPE_BALANCED:
468                 return PP_StateUILabel_Balanced;
469         case POWER_STATE_TYPE_PERFORMANCE:
470                 return PP_StateUILabel_Performance;
471         default:
472                 return PP_StateUILabel_None;
473         }
474 }
475
476 static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_event event_id,
477                 void *input, void *output)
478 {
479         int ret = 0;
480         struct pem_event_data data = { {0} };
481         struct pp_instance *pp_handle = (struct pp_instance *)handle;
482
483         ret = pp_check(pp_handle);
484
485         if (ret != 0)
486                 return ret;
487         mutex_lock(&pp_handle->pp_lock);
488         switch (event_id) {
489         case AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE:
490                 ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
491                 break;
492         case AMD_PP_EVENT_ENABLE_USER_STATE:
493         {
494                 enum amd_pm_state_type  ps;
495
496                 if (input == NULL)
497                         return -EINVAL;
498                 ps = *(unsigned long *)input;
499
500                 data.requested_ui_label = power_state_convert(ps);
501                 ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
502                 break;
503         }
504         case AMD_PP_EVENT_COMPLETE_INIT:
505                 ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
506                 break;
507         case AMD_PP_EVENT_READJUST_POWER_STATE:
508                 ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
509                 break;
510         default:
511                 break;
512         }
513         mutex_unlock(&pp_handle->pp_lock);
514         return ret;
515 }
516
517 static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle)
518 {
519         struct pp_hwmgr *hwmgr;
520         struct pp_power_state *state;
521         struct pp_instance *pp_handle = (struct pp_instance *)handle;
522         int ret = 0;
523         enum amd_pm_state_type pm_type;
524
525         ret = pp_check(pp_handle);
526
527         if (ret != 0)
528                 return ret;
529
530         hwmgr = pp_handle->hwmgr;
531
532         if (hwmgr->current_ps == NULL)
533                 return -EINVAL;
534
535         mutex_lock(&pp_handle->pp_lock);
536
537         state = hwmgr->current_ps;
538
539         switch (state->classification.ui_label) {
540         case PP_StateUILabel_Battery:
541                 pm_type = POWER_STATE_TYPE_BATTERY;
542         case PP_StateUILabel_Balanced:
543                 pm_type = POWER_STATE_TYPE_BALANCED;
544         case PP_StateUILabel_Performance:
545                 pm_type = POWER_STATE_TYPE_PERFORMANCE;
546         default:
547                 if (state->classification.flags & PP_StateClassificationFlag_Boot)
548                         pm_type = POWER_STATE_TYPE_INTERNAL_BOOT;
549                 else
550                         pm_type = POWER_STATE_TYPE_DEFAULT;
551         }
552         mutex_unlock(&pp_handle->pp_lock);
553
554         return pm_type;
555 }
556
557 static int pp_dpm_set_fan_control_mode(void *handle, uint32_t mode)
558 {
559         struct pp_hwmgr  *hwmgr;
560         struct pp_instance *pp_handle = (struct pp_instance *)handle;
561         int ret = 0;
562
563         ret = pp_check(pp_handle);
564
565         if (ret != 0)
566                 return ret;
567
568         hwmgr = pp_handle->hwmgr;
569
570         if (hwmgr->hwmgr_func->set_fan_control_mode == NULL) {
571                 pr_info("%s was not implemented.\n", __func__);
572                 return 0;
573         }
574         mutex_lock(&pp_handle->pp_lock);
575         ret = hwmgr->hwmgr_func->set_fan_control_mode(hwmgr, mode);
576         mutex_unlock(&pp_handle->pp_lock);
577         return ret;
578 }
579
580 static int pp_dpm_get_fan_control_mode(void *handle)
581 {
582         struct pp_hwmgr  *hwmgr;
583         struct pp_instance *pp_handle = (struct pp_instance *)handle;
584         int ret = 0;
585
586         ret = pp_check(pp_handle);
587
588         if (ret != 0)
589                 return ret;
590
591         hwmgr = pp_handle->hwmgr;
592
593         if (hwmgr->hwmgr_func->get_fan_control_mode == NULL) {
594                 pr_info("%s was not implemented.\n", __func__);
595                 return 0;
596         }
597         mutex_lock(&pp_handle->pp_lock);
598         ret = hwmgr->hwmgr_func->get_fan_control_mode(hwmgr);
599         mutex_unlock(&pp_handle->pp_lock);
600         return ret;
601 }
602
603 static int pp_dpm_set_fan_speed_percent(void *handle, uint32_t percent)
604 {
605         struct pp_hwmgr  *hwmgr;
606         struct pp_instance *pp_handle = (struct pp_instance *)handle;
607         int ret = 0;
608
609         ret = pp_check(pp_handle);
610
611         if (ret != 0)
612                 return ret;
613
614         hwmgr = pp_handle->hwmgr;
615
616         if (hwmgr->hwmgr_func->set_fan_speed_percent == NULL) {
617                 pr_info("%s was not implemented.\n", __func__);
618                 return 0;
619         }
620         mutex_lock(&pp_handle->pp_lock);
621         ret = hwmgr->hwmgr_func->set_fan_speed_percent(hwmgr, percent);
622         mutex_unlock(&pp_handle->pp_lock);
623         return ret;
624 }
625
626 static int pp_dpm_get_fan_speed_percent(void *handle, uint32_t *speed)
627 {
628         struct pp_hwmgr  *hwmgr;
629         struct pp_instance *pp_handle = (struct pp_instance *)handle;
630         int ret = 0;
631
632         ret = pp_check(pp_handle);
633
634         if (ret != 0)
635                 return ret;
636
637         hwmgr = pp_handle->hwmgr;
638
639         if (hwmgr->hwmgr_func->get_fan_speed_percent == NULL) {
640                 pr_info("%s was not implemented.\n", __func__);
641                 return 0;
642         }
643
644         mutex_lock(&pp_handle->pp_lock);
645         ret = hwmgr->hwmgr_func->get_fan_speed_percent(hwmgr, speed);
646         mutex_unlock(&pp_handle->pp_lock);
647         return ret;
648 }
649
650 static int pp_dpm_get_fan_speed_rpm(void *handle, uint32_t *rpm)
651 {
652         struct pp_hwmgr *hwmgr;
653         struct pp_instance *pp_handle = (struct pp_instance *)handle;
654         int ret = 0;
655
656         ret = pp_check(pp_handle);
657
658         if (ret != 0)
659                 return ret;
660
661         hwmgr = pp_handle->hwmgr;
662
663         if (hwmgr->hwmgr_func->get_fan_speed_rpm == NULL)
664                 return -EINVAL;
665
666         mutex_lock(&pp_handle->pp_lock);
667         ret = hwmgr->hwmgr_func->get_fan_speed_rpm(hwmgr, rpm);
668         mutex_unlock(&pp_handle->pp_lock);
669         return ret;
670 }
671
672 static int pp_dpm_get_temperature(void *handle)
673 {
674         struct pp_hwmgr  *hwmgr;
675         struct pp_instance *pp_handle = (struct pp_instance *)handle;
676         int ret = 0;
677
678         ret = pp_check(pp_handle);
679
680         if (ret != 0)
681                 return ret;
682
683         hwmgr = pp_handle->hwmgr;
684
685         if (hwmgr->hwmgr_func->get_temperature == NULL) {
686                 pr_info("%s was not implemented.\n", __func__);
687                 return 0;
688         }
689         mutex_lock(&pp_handle->pp_lock);
690         ret = hwmgr->hwmgr_func->get_temperature(hwmgr);
691         mutex_unlock(&pp_handle->pp_lock);
692         return ret;
693 }
694
695 static int pp_dpm_get_pp_num_states(void *handle,
696                 struct pp_states_info *data)
697 {
698         struct pp_hwmgr *hwmgr;
699         int i;
700         struct pp_instance *pp_handle = (struct pp_instance *)handle;
701         int ret = 0;
702
703         ret = pp_check(pp_handle);
704
705         if (ret != 0)
706                 return ret;
707
708         hwmgr = pp_handle->hwmgr;
709
710         if (hwmgr->ps == NULL)
711                 return -EINVAL;
712
713         mutex_lock(&pp_handle->pp_lock);
714
715         data->nums = hwmgr->num_ps;
716
717         for (i = 0; i < hwmgr->num_ps; i++) {
718                 struct pp_power_state *state = (struct pp_power_state *)
719                                 ((unsigned long)hwmgr->ps + i * hwmgr->ps_size);
720                 switch (state->classification.ui_label) {
721                 case PP_StateUILabel_Battery:
722                         data->states[i] = POWER_STATE_TYPE_BATTERY;
723                         break;
724                 case PP_StateUILabel_Balanced:
725                         data->states[i] = POWER_STATE_TYPE_BALANCED;
726                         break;
727                 case PP_StateUILabel_Performance:
728                         data->states[i] = POWER_STATE_TYPE_PERFORMANCE;
729                         break;
730                 default:
731                         if (state->classification.flags & PP_StateClassificationFlag_Boot)
732                                 data->states[i] = POWER_STATE_TYPE_INTERNAL_BOOT;
733                         else
734                                 data->states[i] = POWER_STATE_TYPE_DEFAULT;
735                 }
736         }
737         mutex_unlock(&pp_handle->pp_lock);
738         return 0;
739 }
740
741 static int pp_dpm_get_pp_table(void *handle, char **table)
742 {
743         struct pp_hwmgr *hwmgr;
744         struct pp_instance *pp_handle = (struct pp_instance *)handle;
745         int ret = 0;
746         int size = 0;
747
748         ret = pp_check(pp_handle);
749
750         if (ret != 0)
751                 return ret;
752
753         hwmgr = pp_handle->hwmgr;
754
755         if (!hwmgr->soft_pp_table)
756                 return -EINVAL;
757
758         mutex_lock(&pp_handle->pp_lock);
759         *table = (char *)hwmgr->soft_pp_table;
760         size = hwmgr->soft_pp_table_size;
761         mutex_unlock(&pp_handle->pp_lock);
762         return size;
763 }
764
765 static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size)
766 {
767         struct pp_hwmgr *hwmgr;
768         struct pp_instance *pp_handle = (struct pp_instance *)handle;
769         int ret = 0;
770
771         ret = pp_check(pp_handle);
772
773         if (ret != 0)
774                 return ret;
775
776         hwmgr = pp_handle->hwmgr;
777         mutex_lock(&pp_handle->pp_lock);
778         if (!hwmgr->hardcode_pp_table) {
779                 hwmgr->hardcode_pp_table = kmemdup(hwmgr->soft_pp_table,
780                                                    hwmgr->soft_pp_table_size,
781                                                    GFP_KERNEL);
782                 if (!hwmgr->hardcode_pp_table) {
783                         mutex_unlock(&pp_handle->pp_lock);
784                         return -ENOMEM;
785                 }
786         }
787
788         memcpy(hwmgr->hardcode_pp_table, buf, size);
789
790         hwmgr->soft_pp_table = hwmgr->hardcode_pp_table;
791         mutex_unlock(&pp_handle->pp_lock);
792
793         ret = amd_powerplay_reset(handle);
794         if (ret)
795                 return ret;
796
797         if (hwmgr->hwmgr_func->avfs_control) {
798                 ret = hwmgr->hwmgr_func->avfs_control(hwmgr, false);
799                 if (ret)
800                         return ret;
801         }
802
803         return 0;
804 }
805
806 static int pp_dpm_force_clock_level(void *handle,
807                 enum pp_clock_type type, uint32_t mask)
808 {
809         struct pp_hwmgr *hwmgr;
810         struct pp_instance *pp_handle = (struct pp_instance *)handle;
811         int ret = 0;
812
813         ret = pp_check(pp_handle);
814
815         if (ret != 0)
816                 return ret;
817
818         hwmgr = pp_handle->hwmgr;
819
820         if (hwmgr->hwmgr_func->force_clock_level == NULL) {
821                 pr_info("%s was not implemented.\n", __func__);
822                 return 0;
823         }
824         mutex_lock(&pp_handle->pp_lock);
825         hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask);
826         mutex_unlock(&pp_handle->pp_lock);
827         return ret;
828 }
829
830 static int pp_dpm_print_clock_levels(void *handle,
831                 enum pp_clock_type type, char *buf)
832 {
833         struct pp_hwmgr *hwmgr;
834         struct pp_instance *pp_handle = (struct pp_instance *)handle;
835         int ret = 0;
836
837         ret = pp_check(pp_handle);
838
839         if (ret != 0)
840                 return ret;
841
842         hwmgr = pp_handle->hwmgr;
843
844         if (hwmgr->hwmgr_func->print_clock_levels == NULL) {
845                 pr_info("%s was not implemented.\n", __func__);
846                 return 0;
847         }
848         mutex_lock(&pp_handle->pp_lock);
849         ret = hwmgr->hwmgr_func->print_clock_levels(hwmgr, type, buf);
850         mutex_unlock(&pp_handle->pp_lock);
851         return ret;
852 }
853
854 static int pp_dpm_get_sclk_od(void *handle)
855 {
856         struct pp_hwmgr *hwmgr;
857         struct pp_instance *pp_handle = (struct pp_instance *)handle;
858         int ret = 0;
859
860         ret = pp_check(pp_handle);
861
862         if (ret != 0)
863                 return ret;
864
865         hwmgr = pp_handle->hwmgr;
866
867         if (hwmgr->hwmgr_func->get_sclk_od == NULL) {
868                 pr_info("%s was not implemented.\n", __func__);
869                 return 0;
870         }
871         mutex_lock(&pp_handle->pp_lock);
872         ret = hwmgr->hwmgr_func->get_sclk_od(hwmgr);
873         mutex_unlock(&pp_handle->pp_lock);
874         return ret;
875 }
876
877 static int pp_dpm_set_sclk_od(void *handle, uint32_t value)
878 {
879         struct pp_hwmgr *hwmgr;
880         struct pp_instance *pp_handle = (struct pp_instance *)handle;
881         int ret = 0;
882
883         ret = pp_check(pp_handle);
884
885         if (ret != 0)
886                 return ret;
887
888         hwmgr = pp_handle->hwmgr;
889
890         if (hwmgr->hwmgr_func->set_sclk_od == NULL) {
891                 pr_info("%s was not implemented.\n", __func__);
892                 return 0;
893         }
894
895         mutex_lock(&pp_handle->pp_lock);
896         ret = hwmgr->hwmgr_func->set_sclk_od(hwmgr, value);
897         mutex_lock(&pp_handle->pp_lock);
898         return ret;
899 }
900
901 static int pp_dpm_get_mclk_od(void *handle)
902 {
903         struct pp_hwmgr *hwmgr;
904         struct pp_instance *pp_handle = (struct pp_instance *)handle;
905         int ret = 0;
906
907         ret = pp_check(pp_handle);
908
909         if (ret != 0)
910                 return ret;
911
912         hwmgr = pp_handle->hwmgr;
913
914         if (hwmgr->hwmgr_func->get_mclk_od == NULL) {
915                 pr_info("%s was not implemented.\n", __func__);
916                 return 0;
917         }
918         mutex_lock(&pp_handle->pp_lock);
919         ret = hwmgr->hwmgr_func->get_mclk_od(hwmgr);
920         mutex_unlock(&pp_handle->pp_lock);
921         return ret;
922 }
923
924 static int pp_dpm_set_mclk_od(void *handle, uint32_t value)
925 {
926         struct pp_hwmgr *hwmgr;
927         struct pp_instance *pp_handle = (struct pp_instance *)handle;
928         int ret = 0;
929
930         ret = pp_check(pp_handle);
931
932         if (ret != 0)
933                 return ret;
934
935         hwmgr = pp_handle->hwmgr;
936
937         if (hwmgr->hwmgr_func->set_mclk_od == NULL) {
938                 pr_info("%s was not implemented.\n", __func__);
939                 return 0;
940         }
941         mutex_lock(&pp_handle->pp_lock);
942         ret = hwmgr->hwmgr_func->set_mclk_od(hwmgr, value);
943         mutex_unlock(&pp_handle->pp_lock);
944         return ret;
945 }
946
947 static int pp_dpm_read_sensor(void *handle, int idx,
948                               void *value, int *size)
949 {
950         struct pp_hwmgr *hwmgr;
951         struct pp_instance *pp_handle = (struct pp_instance *)handle;
952         int ret = 0;
953
954         ret = pp_check(pp_handle);
955
956         if (ret != 0)
957                 return ret;
958
959         hwmgr = pp_handle->hwmgr;
960
961         if (hwmgr->hwmgr_func->read_sensor == NULL) {
962                 pr_info("%s was not implemented.\n", __func__);
963                 return 0;
964         }
965
966         mutex_lock(&pp_handle->pp_lock);
967         ret = hwmgr->hwmgr_func->read_sensor(hwmgr, idx, value, size);
968         mutex_unlock(&pp_handle->pp_lock);
969
970         return ret;
971 }
972
973 static struct amd_vce_state*
974 pp_dpm_get_vce_clock_state(void *handle, unsigned idx)
975 {
976         struct pp_hwmgr *hwmgr;
977         struct pp_instance *pp_handle = (struct pp_instance *)handle;
978         int ret = 0;
979
980         ret = pp_check(pp_handle);
981
982         if (ret != 0)
983                 return NULL;
984
985         hwmgr = pp_handle->hwmgr;
986
987         if (hwmgr && idx < hwmgr->num_vce_state_tables)
988                 return &hwmgr->vce_states[idx];
989         return NULL;
990 }
991
992 static int pp_dpm_reset_power_profile_state(void *handle,
993                 struct amd_pp_profile *request)
994 {
995         struct pp_hwmgr *hwmgr;
996         struct pp_instance *pp_handle = (struct pp_instance *)handle;
997
998         if (!request || pp_check(pp_handle))
999                 return -EINVAL;
1000
1001         hwmgr = pp_handle->hwmgr;
1002
1003         if (hwmgr->hwmgr_func->set_power_profile_state == NULL) {
1004                 pr_info("%s was not implemented.\n", __func__);
1005                 return 0;
1006         }
1007
1008         if (request->type == AMD_PP_GFX_PROFILE) {
1009                 hwmgr->gfx_power_profile = hwmgr->default_gfx_power_profile;
1010                 return hwmgr->hwmgr_func->set_power_profile_state(hwmgr,
1011                                 &hwmgr->gfx_power_profile);
1012         } else if (request->type == AMD_PP_COMPUTE_PROFILE) {
1013                 hwmgr->compute_power_profile =
1014                                 hwmgr->default_compute_power_profile;
1015                 return hwmgr->hwmgr_func->set_power_profile_state(hwmgr,
1016                                 &hwmgr->compute_power_profile);
1017         } else
1018                 return -EINVAL;
1019 }
1020
1021 static int pp_dpm_get_power_profile_state(void *handle,
1022                 struct amd_pp_profile *query)
1023 {
1024         struct pp_hwmgr *hwmgr;
1025         struct pp_instance *pp_handle = (struct pp_instance *)handle;
1026
1027         if (!query || pp_check(pp_handle))
1028                 return -EINVAL;
1029
1030         hwmgr = pp_handle->hwmgr;
1031
1032         if (query->type == AMD_PP_GFX_PROFILE)
1033                 memcpy(query, &hwmgr->gfx_power_profile,
1034                                 sizeof(struct amd_pp_profile));
1035         else if (query->type == AMD_PP_COMPUTE_PROFILE)
1036                 memcpy(query, &hwmgr->compute_power_profile,
1037                                 sizeof(struct amd_pp_profile));
1038         else
1039                 return -EINVAL;
1040
1041         return 0;
1042 }
1043
1044 static int pp_dpm_set_power_profile_state(void *handle,
1045                 struct amd_pp_profile *request)
1046 {
1047         struct pp_hwmgr *hwmgr;
1048         struct pp_instance *pp_handle = (struct pp_instance *)handle;
1049         int ret = -1;
1050
1051         if (!request || pp_check(pp_handle))
1052                 return -EINVAL;
1053
1054         hwmgr = pp_handle->hwmgr;
1055
1056         if (hwmgr->hwmgr_func->set_power_profile_state == NULL) {
1057                 pr_info("%s was not implemented.\n", __func__);
1058                 return 0;
1059         }
1060
1061         if (request->min_sclk ||
1062                 request->min_mclk ||
1063                 request->activity_threshold ||
1064                 request->up_hyst ||
1065                 request->down_hyst) {
1066                 if (request->type == AMD_PP_GFX_PROFILE)
1067                         memcpy(&hwmgr->gfx_power_profile, request,
1068                                         sizeof(struct amd_pp_profile));
1069                 else if (request->type == AMD_PP_COMPUTE_PROFILE)
1070                         memcpy(&hwmgr->compute_power_profile, request,
1071                                         sizeof(struct amd_pp_profile));
1072                 else
1073                         return -EINVAL;
1074
1075                 if (request->type == hwmgr->current_power_profile)
1076                         ret = hwmgr->hwmgr_func->set_power_profile_state(
1077                                         hwmgr,
1078                                         request);
1079         } else {
1080                 /* set power profile if it exists */
1081                 switch (request->type) {
1082                 case AMD_PP_GFX_PROFILE:
1083                         ret = hwmgr->hwmgr_func->set_power_profile_state(
1084                                         hwmgr,
1085                                         &hwmgr->gfx_power_profile);
1086                         break;
1087                 case AMD_PP_COMPUTE_PROFILE:
1088                         ret = hwmgr->hwmgr_func->set_power_profile_state(
1089                                         hwmgr,
1090                                         &hwmgr->compute_power_profile);
1091                         break;
1092                 default:
1093                         return -EINVAL;
1094                 }
1095         }
1096
1097         if (!ret)
1098                 hwmgr->current_power_profile = request->type;
1099
1100         return 0;
1101 }
1102
1103 static int pp_dpm_switch_power_profile(void *handle,
1104                 enum amd_pp_profile_type type)
1105 {
1106         struct pp_hwmgr *hwmgr;
1107         struct amd_pp_profile request = {0};
1108         struct pp_instance *pp_handle = (struct pp_instance *)handle;
1109
1110         if (pp_check(pp_handle))
1111                 return -EINVAL;
1112
1113         hwmgr = pp_handle->hwmgr;
1114
1115         if (hwmgr->current_power_profile != type) {
1116                 request.type = type;
1117                 pp_dpm_set_power_profile_state(handle, &request);
1118         }
1119
1120         return 0;
1121 }
1122
1123 const struct amd_powerplay_funcs pp_dpm_funcs = {
1124         .get_temperature = pp_dpm_get_temperature,
1125         .load_firmware = pp_dpm_load_fw,
1126         .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete,
1127         .force_performance_level = pp_dpm_force_performance_level,
1128         .get_performance_level = pp_dpm_get_performance_level,
1129         .get_current_power_state = pp_dpm_get_current_power_state,
1130         .get_sclk = pp_dpm_get_sclk,
1131         .get_mclk = pp_dpm_get_mclk,
1132         .powergate_vce = pp_dpm_powergate_vce,
1133         .powergate_uvd = pp_dpm_powergate_uvd,
1134         .dispatch_tasks = pp_dpm_dispatch_tasks,
1135         .set_fan_control_mode = pp_dpm_set_fan_control_mode,
1136         .get_fan_control_mode = pp_dpm_get_fan_control_mode,
1137         .set_fan_speed_percent = pp_dpm_set_fan_speed_percent,
1138         .get_fan_speed_percent = pp_dpm_get_fan_speed_percent,
1139         .get_fan_speed_rpm = pp_dpm_get_fan_speed_rpm,
1140         .get_pp_num_states = pp_dpm_get_pp_num_states,
1141         .get_pp_table = pp_dpm_get_pp_table,
1142         .set_pp_table = pp_dpm_set_pp_table,
1143         .force_clock_level = pp_dpm_force_clock_level,
1144         .print_clock_levels = pp_dpm_print_clock_levels,
1145         .get_sclk_od = pp_dpm_get_sclk_od,
1146         .set_sclk_od = pp_dpm_set_sclk_od,
1147         .get_mclk_od = pp_dpm_get_mclk_od,
1148         .set_mclk_od = pp_dpm_set_mclk_od,
1149         .read_sensor = pp_dpm_read_sensor,
1150         .get_vce_clock_state = pp_dpm_get_vce_clock_state,
1151         .reset_power_profile_state = pp_dpm_reset_power_profile_state,
1152         .get_power_profile_state = pp_dpm_get_power_profile_state,
1153         .set_power_profile_state = pp_dpm_set_power_profile_state,
1154         .switch_power_profile = pp_dpm_switch_power_profile,
1155 };
1156
1157 int amd_powerplay_create(struct amd_pp_init *pp_init,
1158                                 void **handle)
1159 {
1160         struct pp_instance *instance;
1161
1162         if (pp_init == NULL || handle == NULL)
1163                 return -EINVAL;
1164
1165         instance = kzalloc(sizeof(struct pp_instance), GFP_KERNEL);
1166         if (instance == NULL)
1167                 return -ENOMEM;
1168
1169         instance->pp_valid = PP_VALID;
1170         instance->chip_family = pp_init->chip_family;
1171         instance->chip_id = pp_init->chip_id;
1172         instance->pm_en = pp_init->pm_en;
1173         instance->feature_mask = pp_init->feature_mask;
1174         instance->device = pp_init->device;
1175         mutex_init(&instance->pp_lock);
1176         *handle = instance;
1177         return 0;
1178 }
1179
1180 int amd_powerplay_destroy(void *handle)
1181 {
1182         struct pp_instance *instance = (struct pp_instance *)handle;
1183
1184         if (instance->pm_en) {
1185                 kfree(instance->eventmgr);
1186                 kfree(instance->hwmgr);
1187                 instance->hwmgr = NULL;
1188                 instance->eventmgr = NULL;
1189         }
1190
1191         kfree(instance->smu_mgr);
1192         instance->smu_mgr = NULL;
1193         kfree(instance);
1194         instance = NULL;
1195         return 0;
1196 }
1197
1198 int amd_powerplay_reset(void *handle)
1199 {
1200         struct pp_instance *instance = (struct pp_instance *)handle;
1201         struct pp_eventmgr *eventmgr;
1202         struct pem_event_data event_data = { {0} };
1203         int ret;
1204
1205         if (cgs_is_virtualization_enabled(instance->smu_mgr->device))
1206                 return PP_DPM_DISABLED;
1207
1208         ret = pp_check(instance);
1209         if (ret != 0)
1210                 return ret;
1211
1212         ret = pp_hw_fini(handle);
1213         if (ret)
1214                 return ret;
1215
1216         ret = hwmgr_hw_init(instance);
1217         if (ret)
1218                 return PP_DPM_DISABLED;
1219
1220         eventmgr = instance->eventmgr;
1221
1222         if (eventmgr->pp_eventmgr_init == NULL)
1223                 return PP_DPM_DISABLED;
1224
1225         ret = eventmgr->pp_eventmgr_init(eventmgr);
1226         if (ret)
1227                 return ret;
1228
1229         return pem_handle_event(eventmgr, AMD_PP_EVENT_COMPLETE_INIT, &event_data);
1230 }
1231
1232 /* export this function to DAL */
1233
1234 int amd_powerplay_display_configuration_change(void *handle,
1235         const struct amd_pp_display_configuration *display_config)
1236 {
1237         struct pp_hwmgr  *hwmgr;
1238         struct pp_instance *pp_handle = (struct pp_instance *)handle;
1239         int ret = 0;
1240
1241         ret = pp_check(pp_handle);
1242
1243         if (ret != 0)
1244                 return ret;
1245
1246         hwmgr = pp_handle->hwmgr;
1247         mutex_lock(&pp_handle->pp_lock);
1248         phm_store_dal_configuration_data(hwmgr, display_config);
1249         mutex_unlock(&pp_handle->pp_lock);
1250         return 0;
1251 }
1252
1253 int amd_powerplay_get_display_power_level(void *handle,
1254                 struct amd_pp_simple_clock_info *output)
1255 {
1256         struct pp_hwmgr  *hwmgr;
1257         struct pp_instance *pp_handle = (struct pp_instance *)handle;
1258         int ret = 0;
1259
1260         ret = pp_check(pp_handle);
1261
1262         if (ret != 0)
1263                 return ret;
1264
1265         hwmgr = pp_handle->hwmgr;
1266
1267         if (output == NULL)
1268                 return -EINVAL;
1269
1270         mutex_lock(&pp_handle->pp_lock);
1271         ret = phm_get_dal_power_level(hwmgr, output);
1272         mutex_unlock(&pp_handle->pp_lock);
1273         return ret;
1274 }
1275
1276 int amd_powerplay_get_current_clocks(void *handle,
1277                 struct amd_pp_clock_info *clocks)
1278 {
1279         struct amd_pp_simple_clock_info simple_clocks;
1280         struct pp_clock_info hw_clocks;
1281         struct pp_hwmgr  *hwmgr;
1282         struct pp_instance *pp_handle = (struct pp_instance *)handle;
1283         int ret = 0;
1284
1285         ret = pp_check(pp_handle);
1286
1287         if (ret != 0)
1288                 return ret;
1289
1290         hwmgr = pp_handle->hwmgr;
1291
1292         mutex_lock(&pp_handle->pp_lock);
1293
1294         phm_get_dal_power_level(hwmgr, &simple_clocks);
1295
1296         if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
1297                                         PHM_PlatformCaps_PowerContainment))
1298                 ret = phm_get_clock_info(hwmgr, &hwmgr->current_ps->hardware,
1299                                         &hw_clocks, PHM_PerformanceLevelDesignation_PowerContainment);
1300         else
1301                 ret = phm_get_clock_info(hwmgr, &hwmgr->current_ps->hardware,
1302                                         &hw_clocks, PHM_PerformanceLevelDesignation_Activity);
1303
1304         if (ret != 0) {
1305                 pr_info("Error in phm_get_clock_info \n");
1306                 mutex_unlock(&pp_handle->pp_lock);
1307                 return -EINVAL;
1308         }
1309
1310         clocks->min_engine_clock = hw_clocks.min_eng_clk;
1311         clocks->max_engine_clock = hw_clocks.max_eng_clk;
1312         clocks->min_memory_clock = hw_clocks.min_mem_clk;
1313         clocks->max_memory_clock = hw_clocks.max_mem_clk;
1314         clocks->min_bus_bandwidth = hw_clocks.min_bus_bandwidth;
1315         clocks->max_bus_bandwidth = hw_clocks.max_bus_bandwidth;
1316
1317         clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk;
1318         clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk;
1319
1320         clocks->max_clocks_state = simple_clocks.level;
1321
1322         if (0 == phm_get_current_shallow_sleep_clocks(hwmgr, &hwmgr->current_ps->hardware, &hw_clocks)) {
1323                 clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk;
1324                 clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk;
1325         }
1326         mutex_unlock(&pp_handle->pp_lock);
1327         return 0;
1328 }
1329
1330 int amd_powerplay_get_clock_by_type(void *handle, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks)
1331 {
1332         struct pp_hwmgr  *hwmgr;
1333         struct pp_instance *pp_handle = (struct pp_instance *)handle;
1334         int ret = 0;
1335
1336         ret = pp_check(pp_handle);
1337
1338         if (ret != 0)
1339                 return ret;
1340
1341         hwmgr = pp_handle->hwmgr;
1342
1343         if (clocks == NULL)
1344                 return -EINVAL;
1345
1346         mutex_lock(&pp_handle->pp_lock);
1347         ret = phm_get_clock_by_type(hwmgr, type, clocks);
1348         mutex_unlock(&pp_handle->pp_lock);
1349         return ret;
1350 }
1351
1352 int amd_powerplay_get_clock_by_type_with_latency(void *handle,
1353                 enum amd_pp_clock_type type,
1354                 struct pp_clock_levels_with_latency *clocks)
1355 {
1356         struct pp_hwmgr *hwmgr;
1357         struct pp_instance *pp_handle = (struct pp_instance *)handle;
1358         int ret = 0;
1359
1360         ret = pp_check(pp_handle);
1361         if (ret != 0)
1362                 return ret;
1363
1364         if (!clocks)
1365                 return -EINVAL;
1366
1367         mutex_lock(&pp_handle->pp_lock);
1368         hwmgr = ((struct pp_instance *)handle)->hwmgr;
1369         ret = phm_get_clock_by_type_with_latency(hwmgr, type, clocks);
1370         mutex_unlock(&pp_handle->pp_lock);
1371         return ret;
1372 }
1373
1374 int amd_powerplay_get_clock_by_type_with_voltage(void *handle,
1375                 enum amd_pp_clock_type type,
1376                 struct pp_clock_levels_with_voltage *clocks)
1377 {
1378         struct pp_hwmgr *hwmgr;
1379         struct pp_instance *pp_handle = (struct pp_instance *)handle;
1380         int ret = 0;
1381
1382         ret = pp_check(pp_handle);
1383         if (ret != 0)
1384                 return ret;
1385
1386         if (!clocks)
1387                 return -EINVAL;
1388
1389         hwmgr = ((struct pp_instance *)handle)->hwmgr;
1390
1391         mutex_lock(&pp_handle->pp_lock);
1392
1393         ret = phm_get_clock_by_type_with_voltage(hwmgr, type, clocks);
1394
1395         mutex_unlock(&pp_handle->pp_lock);
1396         return ret;
1397 }
1398
1399 int amd_powerplay_set_watermarks_for_clocks_ranges(void *handle,
1400                 struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges)
1401 {
1402         struct pp_hwmgr *hwmgr;
1403         struct pp_instance *pp_handle = (struct pp_instance *)handle;
1404         int ret = 0;
1405
1406         ret = pp_check(pp_handle);
1407         if (ret != 0)
1408                 return ret;
1409
1410         if (!wm_with_clock_ranges)
1411                 return -EINVAL;
1412
1413         hwmgr = ((struct pp_instance *)handle)->hwmgr;
1414
1415         mutex_lock(&pp_handle->pp_lock);
1416         ret = phm_set_watermarks_for_clocks_ranges(hwmgr,
1417                         wm_with_clock_ranges);
1418         mutex_unlock(&pp_handle->pp_lock);
1419
1420         return ret;
1421 }
1422
1423 int amd_powerplay_display_clock_voltage_request(void *handle,
1424                 struct pp_display_clock_request *clock)
1425 {
1426         struct pp_hwmgr *hwmgr;
1427         struct pp_instance *pp_handle = (struct pp_instance *)handle;
1428         int ret = 0;
1429
1430         ret = pp_check(pp_handle);
1431         if (ret != 0)
1432                 return ret;
1433
1434         if (!clock)
1435                 return -EINVAL;
1436
1437         hwmgr = ((struct pp_instance *)handle)->hwmgr;
1438
1439         mutex_lock(&pp_handle->pp_lock);
1440         ret = phm_display_clock_voltage_request(hwmgr, clock);
1441         mutex_unlock(&pp_handle->pp_lock);
1442
1443         return ret;
1444 }
1445
1446 int amd_powerplay_get_display_mode_validation_clocks(void *handle,
1447                 struct amd_pp_simple_clock_info *clocks)
1448 {
1449         struct pp_hwmgr  *hwmgr;
1450         struct pp_instance *pp_handle = (struct pp_instance *)handle;
1451         int ret = 0;
1452
1453         ret = pp_check(pp_handle);
1454
1455         if (ret != 0)
1456                 return ret;
1457
1458         hwmgr = pp_handle->hwmgr;
1459
1460         if (clocks == NULL)
1461                 return -EINVAL;
1462
1463         mutex_lock(&pp_handle->pp_lock);
1464
1465         if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DynamicPatchPowerState))
1466                 ret = phm_get_max_high_clocks(hwmgr, clocks);
1467
1468         mutex_unlock(&pp_handle->pp_lock);
1469         return ret;
1470 }
1471