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