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