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