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