Merge tag 'drm-misc-next-2023-01-19' of git://anongit.freedesktop.org/drm/drm-misc...
[platform/kernel/linux-starfive.git] / drivers / gpu / drm / amd / pm / 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 <linux/firmware.h>
29 #include "amd_shared.h"
30 #include "amd_powerplay.h"
31 #include "power_state.h"
32 #include "amdgpu.h"
33 #include "hwmgr.h"
34 #include "amdgpu_dpm_internal.h"
35 #include "amdgpu_display.h"
36
37 static const struct amd_pm_funcs pp_dpm_funcs;
38
39 static int amd_powerplay_create(struct amdgpu_device *adev)
40 {
41         struct pp_hwmgr *hwmgr;
42
43         if (adev == NULL)
44                 return -EINVAL;
45
46         hwmgr = kzalloc(sizeof(struct pp_hwmgr), GFP_KERNEL);
47         if (hwmgr == NULL)
48                 return -ENOMEM;
49
50         hwmgr->adev = adev;
51         hwmgr->not_vf = !amdgpu_sriov_vf(adev);
52         hwmgr->device = amdgpu_cgs_create_device(adev);
53         mutex_init(&hwmgr->msg_lock);
54         hwmgr->chip_family = adev->family;
55         hwmgr->chip_id = adev->asic_type;
56         hwmgr->feature_mask = adev->pm.pp_feature;
57         hwmgr->display_config = &adev->pm.pm_display_cfg;
58         adev->powerplay.pp_handle = hwmgr;
59         adev->powerplay.pp_funcs = &pp_dpm_funcs;
60         return 0;
61 }
62
63
64 static void amd_powerplay_destroy(struct amdgpu_device *adev)
65 {
66         struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
67
68         mutex_destroy(&hwmgr->msg_lock);
69
70         kfree(hwmgr->hardcode_pp_table);
71         hwmgr->hardcode_pp_table = NULL;
72
73         kfree(hwmgr);
74         hwmgr = NULL;
75 }
76
77 static int pp_early_init(void *handle)
78 {
79         int ret;
80         struct amdgpu_device *adev = handle;
81
82         ret = amd_powerplay_create(adev);
83
84         if (ret != 0)
85                 return ret;
86
87         ret = hwmgr_early_init(adev->powerplay.pp_handle);
88         if (ret)
89                 return -EINVAL;
90
91         return 0;
92 }
93
94 static int pp_sw_init(void *handle)
95 {
96         struct amdgpu_device *adev = handle;
97         struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
98         int ret = 0;
99
100         ret = hwmgr_sw_init(hwmgr);
101
102         pr_debug("powerplay sw init %s\n", ret ? "failed" : "successfully");
103
104         return ret;
105 }
106
107 static int pp_sw_fini(void *handle)
108 {
109         struct amdgpu_device *adev = handle;
110         struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
111
112         hwmgr_sw_fini(hwmgr);
113
114         amdgpu_ucode_release(&adev->pm.fw);
115
116         return 0;
117 }
118
119 static int pp_hw_init(void *handle)
120 {
121         int ret = 0;
122         struct amdgpu_device *adev = handle;
123         struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
124
125         ret = hwmgr_hw_init(hwmgr);
126
127         if (ret)
128                 pr_err("powerplay hw init failed\n");
129
130         return ret;
131 }
132
133 static int pp_hw_fini(void *handle)
134 {
135         struct amdgpu_device *adev = handle;
136         struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
137
138         hwmgr_hw_fini(hwmgr);
139
140         return 0;
141 }
142
143 static void pp_reserve_vram_for_smu(struct amdgpu_device *adev)
144 {
145         int r = -EINVAL;
146         void *cpu_ptr = NULL;
147         uint64_t gpu_addr;
148         struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
149
150         if (amdgpu_bo_create_kernel(adev, adev->pm.smu_prv_buffer_size,
151                                                 PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
152                                                 &adev->pm.smu_prv_buffer,
153                                                 &gpu_addr,
154                                                 &cpu_ptr)) {
155                 DRM_ERROR("amdgpu: failed to create smu prv buffer\n");
156                 return;
157         }
158
159         if (hwmgr->hwmgr_func->notify_cac_buffer_info)
160                 r = hwmgr->hwmgr_func->notify_cac_buffer_info(hwmgr,
161                                         lower_32_bits((unsigned long)cpu_ptr),
162                                         upper_32_bits((unsigned long)cpu_ptr),
163                                         lower_32_bits(gpu_addr),
164                                         upper_32_bits(gpu_addr),
165                                         adev->pm.smu_prv_buffer_size);
166
167         if (r) {
168                 amdgpu_bo_free_kernel(&adev->pm.smu_prv_buffer, NULL, NULL);
169                 adev->pm.smu_prv_buffer = NULL;
170                 DRM_ERROR("amdgpu: failed to notify SMU buffer address\n");
171         }
172 }
173
174 static int pp_late_init(void *handle)
175 {
176         struct amdgpu_device *adev = handle;
177         struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
178
179         if (hwmgr && hwmgr->pm_en)
180                 hwmgr_handle_task(hwmgr,
181                                         AMD_PP_TASK_COMPLETE_INIT, NULL);
182         if (adev->pm.smu_prv_buffer_size != 0)
183                 pp_reserve_vram_for_smu(adev);
184
185         return 0;
186 }
187
188 static void pp_late_fini(void *handle)
189 {
190         struct amdgpu_device *adev = handle;
191
192         if (adev->pm.smu_prv_buffer)
193                 amdgpu_bo_free_kernel(&adev->pm.smu_prv_buffer, NULL, NULL);
194         amd_powerplay_destroy(adev);
195 }
196
197
198 static bool pp_is_idle(void *handle)
199 {
200         return false;
201 }
202
203 static int pp_wait_for_idle(void *handle)
204 {
205         return 0;
206 }
207
208 static int pp_sw_reset(void *handle)
209 {
210         return 0;
211 }
212
213 static int pp_set_powergating_state(void *handle,
214                                     enum amd_powergating_state state)
215 {
216         return 0;
217 }
218
219 static int pp_suspend(void *handle)
220 {
221         struct amdgpu_device *adev = handle;
222         struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
223
224         return hwmgr_suspend(hwmgr);
225 }
226
227 static int pp_resume(void *handle)
228 {
229         struct amdgpu_device *adev = handle;
230         struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
231
232         return hwmgr_resume(hwmgr);
233 }
234
235 static int pp_set_clockgating_state(void *handle,
236                                           enum amd_clockgating_state state)
237 {
238         return 0;
239 }
240
241 static const struct amd_ip_funcs pp_ip_funcs = {
242         .name = "powerplay",
243         .early_init = pp_early_init,
244         .late_init = pp_late_init,
245         .sw_init = pp_sw_init,
246         .sw_fini = pp_sw_fini,
247         .hw_init = pp_hw_init,
248         .hw_fini = pp_hw_fini,
249         .late_fini = pp_late_fini,
250         .suspend = pp_suspend,
251         .resume = pp_resume,
252         .is_idle = pp_is_idle,
253         .wait_for_idle = pp_wait_for_idle,
254         .soft_reset = pp_sw_reset,
255         .set_clockgating_state = pp_set_clockgating_state,
256         .set_powergating_state = pp_set_powergating_state,
257 };
258
259 const struct amdgpu_ip_block_version pp_smu_ip_block =
260 {
261         .type = AMD_IP_BLOCK_TYPE_SMC,
262         .major = 1,
263         .minor = 0,
264         .rev = 0,
265         .funcs = &pp_ip_funcs,
266 };
267
268 /* This interface only be supported On Vi,
269  * because only smu7/8 can help to load gfx/sdma fw,
270  * smu need to be enabled before load other ip's fw.
271  * so call start smu to load smu7 fw and other ip's fw
272  */
273 static int pp_dpm_load_fw(void *handle)
274 {
275         struct pp_hwmgr *hwmgr = handle;
276
277         if (!hwmgr || !hwmgr->smumgr_funcs || !hwmgr->smumgr_funcs->start_smu)
278                 return -EINVAL;
279
280         if (hwmgr->smumgr_funcs->start_smu(hwmgr)) {
281                 pr_err("fw load failed\n");
282                 return -EINVAL;
283         }
284
285         return 0;
286 }
287
288 static int pp_dpm_fw_loading_complete(void *handle)
289 {
290         return 0;
291 }
292
293 static int pp_set_clockgating_by_smu(void *handle, uint32_t msg_id)
294 {
295         struct pp_hwmgr *hwmgr = handle;
296
297         if (!hwmgr || !hwmgr->pm_en)
298                 return -EINVAL;
299
300         if (hwmgr->hwmgr_func->update_clock_gatings == NULL) {
301                 pr_info_ratelimited("%s was not implemented.\n", __func__);
302                 return 0;
303         }
304
305         return hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
306 }
307
308 static void pp_dpm_en_umd_pstate(struct pp_hwmgr  *hwmgr,
309                                                 enum amd_dpm_forced_level *level)
310 {
311         uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
312                                         AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
313                                         AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
314                                         AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
315
316         if (!(hwmgr->dpm_level & profile_mode_mask)) {
317                 /* enter umd pstate, save current level, disable gfx cg*/
318                 if (*level & profile_mode_mask) {
319                         hwmgr->saved_dpm_level = hwmgr->dpm_level;
320                         hwmgr->en_umd_pstate = true;
321                 }
322         } else {
323                 /* exit umd pstate, restore level, enable gfx cg*/
324                 if (!(*level & profile_mode_mask)) {
325                         if (*level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT)
326                                 *level = hwmgr->saved_dpm_level;
327                         hwmgr->en_umd_pstate = false;
328                 }
329         }
330 }
331
332 static int pp_dpm_force_performance_level(void *handle,
333                                         enum amd_dpm_forced_level level)
334 {
335         struct pp_hwmgr *hwmgr = handle;
336
337         if (!hwmgr || !hwmgr->pm_en)
338                 return -EINVAL;
339
340         if (level == hwmgr->dpm_level)
341                 return 0;
342
343         pp_dpm_en_umd_pstate(hwmgr, &level);
344         hwmgr->request_dpm_level = level;
345         hwmgr_handle_task(hwmgr, AMD_PP_TASK_READJUST_POWER_STATE, NULL);
346
347         return 0;
348 }
349
350 static enum amd_dpm_forced_level pp_dpm_get_performance_level(
351                                                                 void *handle)
352 {
353         struct pp_hwmgr *hwmgr = handle;
354
355         if (!hwmgr || !hwmgr->pm_en)
356                 return -EINVAL;
357
358         return hwmgr->dpm_level;
359 }
360
361 static uint32_t pp_dpm_get_sclk(void *handle, bool low)
362 {
363         struct pp_hwmgr *hwmgr = handle;
364
365         if (!hwmgr || !hwmgr->pm_en)
366                 return 0;
367
368         if (hwmgr->hwmgr_func->get_sclk == NULL) {
369                 pr_info_ratelimited("%s was not implemented.\n", __func__);
370                 return 0;
371         }
372         return hwmgr->hwmgr_func->get_sclk(hwmgr, low);
373 }
374
375 static uint32_t pp_dpm_get_mclk(void *handle, bool low)
376 {
377         struct pp_hwmgr *hwmgr = handle;
378
379         if (!hwmgr || !hwmgr->pm_en)
380                 return 0;
381
382         if (hwmgr->hwmgr_func->get_mclk == NULL) {
383                 pr_info_ratelimited("%s was not implemented.\n", __func__);
384                 return 0;
385         }
386         return hwmgr->hwmgr_func->get_mclk(hwmgr, low);
387 }
388
389 static void pp_dpm_powergate_vce(void *handle, bool gate)
390 {
391         struct pp_hwmgr *hwmgr = handle;
392
393         if (!hwmgr || !hwmgr->pm_en)
394                 return;
395
396         if (hwmgr->hwmgr_func->powergate_vce == NULL) {
397                 pr_info_ratelimited("%s was not implemented.\n", __func__);
398                 return;
399         }
400         hwmgr->hwmgr_func->powergate_vce(hwmgr, gate);
401 }
402
403 static void pp_dpm_powergate_uvd(void *handle, bool gate)
404 {
405         struct pp_hwmgr *hwmgr = handle;
406
407         if (!hwmgr || !hwmgr->pm_en)
408                 return;
409
410         if (hwmgr->hwmgr_func->powergate_uvd == NULL) {
411                 pr_info_ratelimited("%s was not implemented.\n", __func__);
412                 return;
413         }
414         hwmgr->hwmgr_func->powergate_uvd(hwmgr, gate);
415 }
416
417 static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_task task_id,
418                 enum amd_pm_state_type *user_state)
419 {
420         struct pp_hwmgr *hwmgr = handle;
421
422         if (!hwmgr || !hwmgr->pm_en)
423                 return -EINVAL;
424
425         return hwmgr_handle_task(hwmgr, task_id, user_state);
426 }
427
428 static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle)
429 {
430         struct pp_hwmgr *hwmgr = handle;
431         struct pp_power_state *state;
432         enum amd_pm_state_type pm_type;
433
434         if (!hwmgr || !hwmgr->pm_en || !hwmgr->current_ps)
435                 return -EINVAL;
436
437         state = hwmgr->current_ps;
438
439         switch (state->classification.ui_label) {
440         case PP_StateUILabel_Battery:
441                 pm_type = POWER_STATE_TYPE_BATTERY;
442                 break;
443         case PP_StateUILabel_Balanced:
444                 pm_type = POWER_STATE_TYPE_BALANCED;
445                 break;
446         case PP_StateUILabel_Performance:
447                 pm_type = POWER_STATE_TYPE_PERFORMANCE;
448                 break;
449         default:
450                 if (state->classification.flags & PP_StateClassificationFlag_Boot)
451                         pm_type = POWER_STATE_TYPE_INTERNAL_BOOT;
452                 else
453                         pm_type = POWER_STATE_TYPE_DEFAULT;
454                 break;
455         }
456
457         return pm_type;
458 }
459
460 static int pp_dpm_set_fan_control_mode(void *handle, uint32_t mode)
461 {
462         struct pp_hwmgr *hwmgr = handle;
463
464         if (!hwmgr || !hwmgr->pm_en)
465                 return -EOPNOTSUPP;
466
467         if (hwmgr->hwmgr_func->set_fan_control_mode == NULL)
468                 return -EOPNOTSUPP;
469
470         if (mode == U32_MAX)
471                 return -EINVAL;
472
473         hwmgr->hwmgr_func->set_fan_control_mode(hwmgr, mode);
474
475         return 0;
476 }
477
478 static int pp_dpm_get_fan_control_mode(void *handle, uint32_t *fan_mode)
479 {
480         struct pp_hwmgr *hwmgr = handle;
481
482         if (!hwmgr || !hwmgr->pm_en)
483                 return -EOPNOTSUPP;
484
485         if (hwmgr->hwmgr_func->get_fan_control_mode == NULL)
486                 return -EOPNOTSUPP;
487
488         if (!fan_mode)
489                 return -EINVAL;
490
491         *fan_mode = hwmgr->hwmgr_func->get_fan_control_mode(hwmgr);
492         return 0;
493 }
494
495 static int pp_dpm_set_fan_speed_pwm(void *handle, uint32_t speed)
496 {
497         struct pp_hwmgr *hwmgr = handle;
498
499         if (!hwmgr || !hwmgr->pm_en)
500                 return -EOPNOTSUPP;
501
502         if (hwmgr->hwmgr_func->set_fan_speed_pwm == NULL)
503                 return -EOPNOTSUPP;
504
505         if (speed == U32_MAX)
506                 return -EINVAL;
507
508         return hwmgr->hwmgr_func->set_fan_speed_pwm(hwmgr, speed);
509 }
510
511 static int pp_dpm_get_fan_speed_pwm(void *handle, uint32_t *speed)
512 {
513         struct pp_hwmgr *hwmgr = handle;
514
515         if (!hwmgr || !hwmgr->pm_en)
516                 return -EOPNOTSUPP;
517
518         if (hwmgr->hwmgr_func->get_fan_speed_pwm == NULL)
519                 return -EOPNOTSUPP;
520
521         if (!speed)
522                 return -EINVAL;
523
524         return hwmgr->hwmgr_func->get_fan_speed_pwm(hwmgr, speed);
525 }
526
527 static int pp_dpm_get_fan_speed_rpm(void *handle, uint32_t *rpm)
528 {
529         struct pp_hwmgr *hwmgr = handle;
530
531         if (!hwmgr || !hwmgr->pm_en)
532                 return -EOPNOTSUPP;
533
534         if (hwmgr->hwmgr_func->get_fan_speed_rpm == NULL)
535                 return -EOPNOTSUPP;
536
537         if (!rpm)
538                 return -EINVAL;
539
540         return hwmgr->hwmgr_func->get_fan_speed_rpm(hwmgr, rpm);
541 }
542
543 static int pp_dpm_set_fan_speed_rpm(void *handle, uint32_t rpm)
544 {
545         struct pp_hwmgr *hwmgr = handle;
546
547         if (!hwmgr || !hwmgr->pm_en)
548                 return -EOPNOTSUPP;
549
550         if (hwmgr->hwmgr_func->set_fan_speed_rpm == NULL)
551                 return -EOPNOTSUPP;
552
553         if (rpm == U32_MAX)
554                 return -EINVAL;
555
556         return hwmgr->hwmgr_func->set_fan_speed_rpm(hwmgr, rpm);
557 }
558
559 static int pp_dpm_get_pp_num_states(void *handle,
560                 struct pp_states_info *data)
561 {
562         struct pp_hwmgr *hwmgr = handle;
563         int i;
564
565         memset(data, 0, sizeof(*data));
566
567         if (!hwmgr || !hwmgr->pm_en ||!hwmgr->ps)
568                 return -EINVAL;
569
570         data->nums = hwmgr->num_ps;
571
572         for (i = 0; i < hwmgr->num_ps; i++) {
573                 struct pp_power_state *state = (struct pp_power_state *)
574                                 ((unsigned long)hwmgr->ps + i * hwmgr->ps_size);
575                 switch (state->classification.ui_label) {
576                 case PP_StateUILabel_Battery:
577                         data->states[i] = POWER_STATE_TYPE_BATTERY;
578                         break;
579                 case PP_StateUILabel_Balanced:
580                         data->states[i] = POWER_STATE_TYPE_BALANCED;
581                         break;
582                 case PP_StateUILabel_Performance:
583                         data->states[i] = POWER_STATE_TYPE_PERFORMANCE;
584                         break;
585                 default:
586                         if (state->classification.flags & PP_StateClassificationFlag_Boot)
587                                 data->states[i] = POWER_STATE_TYPE_INTERNAL_BOOT;
588                         else
589                                 data->states[i] = POWER_STATE_TYPE_DEFAULT;
590                 }
591         }
592         return 0;
593 }
594
595 static int pp_dpm_get_pp_table(void *handle, char **table)
596 {
597         struct pp_hwmgr *hwmgr = handle;
598
599         if (!hwmgr || !hwmgr->pm_en ||!hwmgr->soft_pp_table)
600                 return -EINVAL;
601
602         *table = (char *)hwmgr->soft_pp_table;
603         return hwmgr->soft_pp_table_size;
604 }
605
606 static int amd_powerplay_reset(void *handle)
607 {
608         struct pp_hwmgr *hwmgr = handle;
609         int ret;
610
611         ret = hwmgr_hw_fini(hwmgr);
612         if (ret)
613                 return ret;
614
615         ret = hwmgr_hw_init(hwmgr);
616         if (ret)
617                 return ret;
618
619         return hwmgr_handle_task(hwmgr, AMD_PP_TASK_COMPLETE_INIT, NULL);
620 }
621
622 static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size)
623 {
624         struct pp_hwmgr *hwmgr = handle;
625         int ret = -ENOMEM;
626
627         if (!hwmgr || !hwmgr->pm_en)
628                 return -EINVAL;
629
630         if (!hwmgr->hardcode_pp_table) {
631                 hwmgr->hardcode_pp_table = kmemdup(hwmgr->soft_pp_table,
632                                                    hwmgr->soft_pp_table_size,
633                                                    GFP_KERNEL);
634                 if (!hwmgr->hardcode_pp_table)
635                         return ret;
636         }
637
638         memcpy(hwmgr->hardcode_pp_table, buf, size);
639
640         hwmgr->soft_pp_table = hwmgr->hardcode_pp_table;
641
642         ret = amd_powerplay_reset(handle);
643         if (ret)
644                 return ret;
645
646         if (hwmgr->hwmgr_func->avfs_control)
647                 ret = hwmgr->hwmgr_func->avfs_control(hwmgr, false);
648
649         return ret;
650 }
651
652 static int pp_dpm_force_clock_level(void *handle,
653                 enum pp_clock_type type, uint32_t mask)
654 {
655         struct pp_hwmgr *hwmgr = handle;
656
657         if (!hwmgr || !hwmgr->pm_en)
658                 return -EINVAL;
659
660         if (hwmgr->hwmgr_func->force_clock_level == NULL) {
661                 pr_info_ratelimited("%s was not implemented.\n", __func__);
662                 return 0;
663         }
664
665         if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {
666                 pr_debug("force clock level is for dpm manual mode only.\n");
667                 return -EINVAL;
668         }
669
670         return hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask);
671 }
672
673 static int pp_dpm_emit_clock_levels(void *handle,
674                                     enum pp_clock_type type,
675                                     char *buf,
676                                     int *offset)
677 {
678         struct pp_hwmgr *hwmgr = handle;
679
680         if (!hwmgr || !hwmgr->pm_en)
681                 return -EOPNOTSUPP;
682
683         if (!hwmgr->hwmgr_func->emit_clock_levels)
684                 return -ENOENT;
685
686         return hwmgr->hwmgr_func->emit_clock_levels(hwmgr, type, buf, offset);
687 }
688
689 static int pp_dpm_print_clock_levels(void *handle,
690                 enum pp_clock_type type, char *buf)
691 {
692         struct pp_hwmgr *hwmgr = handle;
693
694         if (!hwmgr || !hwmgr->pm_en)
695                 return -EINVAL;
696
697         if (hwmgr->hwmgr_func->print_clock_levels == NULL) {
698                 pr_info_ratelimited("%s was not implemented.\n", __func__);
699                 return 0;
700         }
701         return hwmgr->hwmgr_func->print_clock_levels(hwmgr, type, buf);
702 }
703
704 static int pp_dpm_get_sclk_od(void *handle)
705 {
706         struct pp_hwmgr *hwmgr = handle;
707
708         if (!hwmgr || !hwmgr->pm_en)
709                 return -EINVAL;
710
711         if (hwmgr->hwmgr_func->get_sclk_od == NULL) {
712                 pr_info_ratelimited("%s was not implemented.\n", __func__);
713                 return 0;
714         }
715         return hwmgr->hwmgr_func->get_sclk_od(hwmgr);
716 }
717
718 static int pp_dpm_set_sclk_od(void *handle, uint32_t value)
719 {
720         struct pp_hwmgr *hwmgr = handle;
721
722         if (!hwmgr || !hwmgr->pm_en)
723                 return -EINVAL;
724
725         if (hwmgr->hwmgr_func->set_sclk_od == NULL) {
726                 pr_info_ratelimited("%s was not implemented.\n", __func__);
727                 return 0;
728         }
729
730         return hwmgr->hwmgr_func->set_sclk_od(hwmgr, value);
731 }
732
733 static int pp_dpm_get_mclk_od(void *handle)
734 {
735         struct pp_hwmgr *hwmgr = handle;
736
737         if (!hwmgr || !hwmgr->pm_en)
738                 return -EINVAL;
739
740         if (hwmgr->hwmgr_func->get_mclk_od == NULL) {
741                 pr_info_ratelimited("%s was not implemented.\n", __func__);
742                 return 0;
743         }
744         return hwmgr->hwmgr_func->get_mclk_od(hwmgr);
745 }
746
747 static int pp_dpm_set_mclk_od(void *handle, uint32_t value)
748 {
749         struct pp_hwmgr *hwmgr = handle;
750
751         if (!hwmgr || !hwmgr->pm_en)
752                 return -EINVAL;
753
754         if (hwmgr->hwmgr_func->set_mclk_od == NULL) {
755                 pr_info_ratelimited("%s was not implemented.\n", __func__);
756                 return 0;
757         }
758         return hwmgr->hwmgr_func->set_mclk_od(hwmgr, value);
759 }
760
761 static int pp_dpm_read_sensor(void *handle, int idx,
762                               void *value, int *size)
763 {
764         struct pp_hwmgr *hwmgr = handle;
765
766         if (!hwmgr || !hwmgr->pm_en || !value)
767                 return -EINVAL;
768
769         switch (idx) {
770         case AMDGPU_PP_SENSOR_STABLE_PSTATE_SCLK:
771                 *((uint32_t *)value) = hwmgr->pstate_sclk * 100;
772                 return 0;
773         case AMDGPU_PP_SENSOR_STABLE_PSTATE_MCLK:
774                 *((uint32_t *)value) = hwmgr->pstate_mclk * 100;
775                 return 0;
776         case AMDGPU_PP_SENSOR_PEAK_PSTATE_SCLK:
777                 *((uint32_t *)value) = hwmgr->pstate_sclk_peak * 100;
778                 return 0;
779         case AMDGPU_PP_SENSOR_PEAK_PSTATE_MCLK:
780                 *((uint32_t *)value) = hwmgr->pstate_mclk_peak * 100;
781                 return 0;
782         case AMDGPU_PP_SENSOR_MIN_FAN_RPM:
783                 *((uint32_t *)value) = hwmgr->thermal_controller.fanInfo.ulMinRPM;
784                 return 0;
785         case AMDGPU_PP_SENSOR_MAX_FAN_RPM:
786                 *((uint32_t *)value) = hwmgr->thermal_controller.fanInfo.ulMaxRPM;
787                 return 0;
788         default:
789                 return hwmgr->hwmgr_func->read_sensor(hwmgr, idx, value, size);
790         }
791 }
792
793 static struct amd_vce_state*
794 pp_dpm_get_vce_clock_state(void *handle, unsigned idx)
795 {
796         struct pp_hwmgr *hwmgr = handle;
797
798         if (!hwmgr || !hwmgr->pm_en)
799                 return NULL;
800
801         if (idx < hwmgr->num_vce_state_tables)
802                 return &hwmgr->vce_states[idx];
803         return NULL;
804 }
805
806 static int pp_get_power_profile_mode(void *handle, char *buf)
807 {
808         struct pp_hwmgr *hwmgr = handle;
809
810         if (!hwmgr || !hwmgr->pm_en || !hwmgr->hwmgr_func->get_power_profile_mode)
811                 return -EOPNOTSUPP;
812         if (!buf)
813                 return -EINVAL;
814
815         return hwmgr->hwmgr_func->get_power_profile_mode(hwmgr, buf);
816 }
817
818 static int pp_set_power_profile_mode(void *handle, long *input, uint32_t size)
819 {
820         struct pp_hwmgr *hwmgr = handle;
821
822         if (!hwmgr || !hwmgr->pm_en || !hwmgr->hwmgr_func->set_power_profile_mode)
823                 return -EOPNOTSUPP;
824
825         if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {
826                 pr_debug("power profile setting is for manual dpm mode only.\n");
827                 return -EINVAL;
828         }
829
830         return hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, input, size);
831 }
832
833 static int pp_set_fine_grain_clk_vol(void *handle, uint32_t type, long *input, uint32_t size)
834 {
835         struct pp_hwmgr *hwmgr = handle;
836
837         if (!hwmgr || !hwmgr->pm_en)
838                 return -EINVAL;
839
840         if (hwmgr->hwmgr_func->set_fine_grain_clk_vol == NULL)
841                 return 0;
842
843         return hwmgr->hwmgr_func->set_fine_grain_clk_vol(hwmgr, type, input, size);
844 }
845
846 static int pp_odn_edit_dpm_table(void *handle, enum PP_OD_DPM_TABLE_COMMAND type,
847                                  long *input, uint32_t size)
848 {
849         struct pp_hwmgr *hwmgr = handle;
850
851         if (!hwmgr || !hwmgr->pm_en)
852                 return -EINVAL;
853
854         if (hwmgr->hwmgr_func->odn_edit_dpm_table == NULL) {
855                 pr_info_ratelimited("%s was not implemented.\n", __func__);
856                 return 0;
857         }
858
859         return hwmgr->hwmgr_func->odn_edit_dpm_table(hwmgr, type, input, size);
860 }
861
862 static int pp_dpm_set_mp1_state(void *handle, enum pp_mp1_state mp1_state)
863 {
864         struct pp_hwmgr *hwmgr = handle;
865
866         if (!hwmgr)
867                 return -EINVAL;
868
869         if (!hwmgr->pm_en)
870                 return 0;
871
872         if (hwmgr->hwmgr_func->set_mp1_state)
873                 return hwmgr->hwmgr_func->set_mp1_state(hwmgr, mp1_state);
874
875         return 0;
876 }
877
878 static int pp_dpm_switch_power_profile(void *handle,
879                 enum PP_SMC_POWER_PROFILE type, bool en)
880 {
881         struct pp_hwmgr *hwmgr = handle;
882         long workload;
883         uint32_t index;
884
885         if (!hwmgr || !hwmgr->pm_en)
886                 return -EINVAL;
887
888         if (hwmgr->hwmgr_func->set_power_profile_mode == NULL) {
889                 pr_info_ratelimited("%s was not implemented.\n", __func__);
890                 return -EINVAL;
891         }
892
893         if (!(type < PP_SMC_POWER_PROFILE_CUSTOM))
894                 return -EINVAL;
895
896         if (!en) {
897                 hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]);
898                 index = fls(hwmgr->workload_mask);
899                 index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0;
900                 workload = hwmgr->workload_setting[index];
901         } else {
902                 hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]);
903                 index = fls(hwmgr->workload_mask);
904                 index = index <= Workload_Policy_Max ? index - 1 : 0;
905                 workload = hwmgr->workload_setting[index];
906         }
907
908         if (type == PP_SMC_POWER_PROFILE_COMPUTE &&
909                 hwmgr->hwmgr_func->disable_power_features_for_compute_performance) {
910                         if (hwmgr->hwmgr_func->disable_power_features_for_compute_performance(hwmgr, en))
911                                 return -EINVAL;
912         }
913
914         if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
915                 hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0);
916
917         return 0;
918 }
919
920 static int pp_set_power_limit(void *handle, uint32_t limit)
921 {
922         struct pp_hwmgr *hwmgr = handle;
923         uint32_t max_power_limit;
924
925         if (!hwmgr || !hwmgr->pm_en)
926                 return -EINVAL;
927
928         if (hwmgr->hwmgr_func->set_power_limit == NULL) {
929                 pr_info_ratelimited("%s was not implemented.\n", __func__);
930                 return -EINVAL;
931         }
932
933         if (limit == 0)
934                 limit = hwmgr->default_power_limit;
935
936         max_power_limit = hwmgr->default_power_limit;
937         if (hwmgr->od_enabled) {
938                 max_power_limit *= (100 + hwmgr->platform_descriptor.TDPODLimit);
939                 max_power_limit /= 100;
940         }
941
942         if (limit > max_power_limit)
943                 return -EINVAL;
944
945         hwmgr->hwmgr_func->set_power_limit(hwmgr, limit);
946         hwmgr->power_limit = limit;
947         return 0;
948 }
949
950 static int pp_get_power_limit(void *handle, uint32_t *limit,
951                               enum pp_power_limit_level pp_limit_level,
952                               enum pp_power_type power_type)
953 {
954         struct pp_hwmgr *hwmgr = handle;
955         int ret = 0;
956
957         if (!hwmgr || !hwmgr->pm_en ||!limit)
958                 return -EINVAL;
959
960         if (power_type != PP_PWR_TYPE_SUSTAINED)
961                 return -EOPNOTSUPP;
962
963         switch (pp_limit_level) {
964                 case PP_PWR_LIMIT_CURRENT:
965                         *limit = hwmgr->power_limit;
966                         break;
967                 case PP_PWR_LIMIT_DEFAULT:
968                         *limit = hwmgr->default_power_limit;
969                         break;
970                 case PP_PWR_LIMIT_MAX:
971                         *limit = hwmgr->default_power_limit;
972                         if (hwmgr->od_enabled) {
973                                 *limit *= (100 + hwmgr->platform_descriptor.TDPODLimit);
974                                 *limit /= 100;
975                         }
976                         break;
977                 default:
978                         ret = -EOPNOTSUPP;
979                         break;
980         }
981
982         return ret;
983 }
984
985 static int pp_display_configuration_change(void *handle,
986         const struct amd_pp_display_configuration *display_config)
987 {
988         struct pp_hwmgr *hwmgr = handle;
989
990         if (!hwmgr || !hwmgr->pm_en)
991                 return -EINVAL;
992
993         phm_store_dal_configuration_data(hwmgr, display_config);
994         return 0;
995 }
996
997 static int pp_get_display_power_level(void *handle,
998                 struct amd_pp_simple_clock_info *output)
999 {
1000         struct pp_hwmgr *hwmgr = handle;
1001
1002         if (!hwmgr || !hwmgr->pm_en ||!output)
1003                 return -EINVAL;
1004
1005         return phm_get_dal_power_level(hwmgr, output);
1006 }
1007
1008 static int pp_get_current_clocks(void *handle,
1009                 struct amd_pp_clock_info *clocks)
1010 {
1011         struct amd_pp_simple_clock_info simple_clocks = { 0 };
1012         struct pp_clock_info hw_clocks;
1013         struct pp_hwmgr *hwmgr = handle;
1014         int ret = 0;
1015
1016         if (!hwmgr || !hwmgr->pm_en)
1017                 return -EINVAL;
1018
1019         phm_get_dal_power_level(hwmgr, &simple_clocks);
1020
1021         if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
1022                                         PHM_PlatformCaps_PowerContainment))
1023                 ret = phm_get_clock_info(hwmgr, &hwmgr->current_ps->hardware,
1024                                         &hw_clocks, PHM_PerformanceLevelDesignation_PowerContainment);
1025         else
1026                 ret = phm_get_clock_info(hwmgr, &hwmgr->current_ps->hardware,
1027                                         &hw_clocks, PHM_PerformanceLevelDesignation_Activity);
1028
1029         if (ret) {
1030                 pr_debug("Error in phm_get_clock_info \n");
1031                 return -EINVAL;
1032         }
1033
1034         clocks->min_engine_clock = hw_clocks.min_eng_clk;
1035         clocks->max_engine_clock = hw_clocks.max_eng_clk;
1036         clocks->min_memory_clock = hw_clocks.min_mem_clk;
1037         clocks->max_memory_clock = hw_clocks.max_mem_clk;
1038         clocks->min_bus_bandwidth = hw_clocks.min_bus_bandwidth;
1039         clocks->max_bus_bandwidth = hw_clocks.max_bus_bandwidth;
1040
1041         clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk;
1042         clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk;
1043
1044         if (simple_clocks.level == 0)
1045                 clocks->max_clocks_state = PP_DAL_POWERLEVEL_7;
1046         else
1047                 clocks->max_clocks_state = simple_clocks.level;
1048
1049         if (0 == phm_get_current_shallow_sleep_clocks(hwmgr, &hwmgr->current_ps->hardware, &hw_clocks)) {
1050                 clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk;
1051                 clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk;
1052         }
1053         return 0;
1054 }
1055
1056 static int pp_get_clock_by_type(void *handle, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks)
1057 {
1058         struct pp_hwmgr *hwmgr = handle;
1059
1060         if (!hwmgr || !hwmgr->pm_en)
1061                 return -EINVAL;
1062
1063         if (clocks == NULL)
1064                 return -EINVAL;
1065
1066         return phm_get_clock_by_type(hwmgr, type, clocks);
1067 }
1068
1069 static int pp_get_clock_by_type_with_latency(void *handle,
1070                 enum amd_pp_clock_type type,
1071                 struct pp_clock_levels_with_latency *clocks)
1072 {
1073         struct pp_hwmgr *hwmgr = handle;
1074
1075         if (!hwmgr || !hwmgr->pm_en ||!clocks)
1076                 return -EINVAL;
1077
1078         return phm_get_clock_by_type_with_latency(hwmgr, type, clocks);
1079 }
1080
1081 static int pp_get_clock_by_type_with_voltage(void *handle,
1082                 enum amd_pp_clock_type type,
1083                 struct pp_clock_levels_with_voltage *clocks)
1084 {
1085         struct pp_hwmgr *hwmgr = handle;
1086
1087         if (!hwmgr || !hwmgr->pm_en ||!clocks)
1088                 return -EINVAL;
1089
1090         return phm_get_clock_by_type_with_voltage(hwmgr, type, clocks);
1091 }
1092
1093 static int pp_set_watermarks_for_clocks_ranges(void *handle,
1094                 void *clock_ranges)
1095 {
1096         struct pp_hwmgr *hwmgr = handle;
1097
1098         if (!hwmgr || !hwmgr->pm_en || !clock_ranges)
1099                 return -EINVAL;
1100
1101         return phm_set_watermarks_for_clocks_ranges(hwmgr,
1102                                                     clock_ranges);
1103 }
1104
1105 static int pp_display_clock_voltage_request(void *handle,
1106                 struct pp_display_clock_request *clock)
1107 {
1108         struct pp_hwmgr *hwmgr = handle;
1109
1110         if (!hwmgr || !hwmgr->pm_en ||!clock)
1111                 return -EINVAL;
1112
1113         return phm_display_clock_voltage_request(hwmgr, clock);
1114 }
1115
1116 static int pp_get_display_mode_validation_clocks(void *handle,
1117                 struct amd_pp_simple_clock_info *clocks)
1118 {
1119         struct pp_hwmgr *hwmgr = handle;
1120         int ret = 0;
1121
1122         if (!hwmgr || !hwmgr->pm_en ||!clocks)
1123                 return -EINVAL;
1124
1125         clocks->level = PP_DAL_POWERLEVEL_7;
1126
1127         if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DynamicPatchPowerState))
1128                 ret = phm_get_max_high_clocks(hwmgr, clocks);
1129
1130         return ret;
1131 }
1132
1133 static int pp_dpm_powergate_mmhub(void *handle)
1134 {
1135         struct pp_hwmgr *hwmgr = handle;
1136
1137         if (!hwmgr || !hwmgr->pm_en)
1138                 return -EINVAL;
1139
1140         if (hwmgr->hwmgr_func->powergate_mmhub == NULL) {
1141                 pr_info_ratelimited("%s was not implemented.\n", __func__);
1142                 return 0;
1143         }
1144
1145         return hwmgr->hwmgr_func->powergate_mmhub(hwmgr);
1146 }
1147
1148 static int pp_dpm_powergate_gfx(void *handle, bool gate)
1149 {
1150         struct pp_hwmgr *hwmgr = handle;
1151
1152         if (!hwmgr || !hwmgr->pm_en)
1153                 return 0;
1154
1155         if (hwmgr->hwmgr_func->powergate_gfx == NULL) {
1156                 pr_info_ratelimited("%s was not implemented.\n", __func__);
1157                 return 0;
1158         }
1159
1160         return hwmgr->hwmgr_func->powergate_gfx(hwmgr, gate);
1161 }
1162
1163 static void pp_dpm_powergate_acp(void *handle, bool gate)
1164 {
1165         struct pp_hwmgr *hwmgr = handle;
1166
1167         if (!hwmgr || !hwmgr->pm_en)
1168                 return;
1169
1170         if (hwmgr->hwmgr_func->powergate_acp == NULL) {
1171                 pr_info_ratelimited("%s was not implemented.\n", __func__);
1172                 return;
1173         }
1174
1175         hwmgr->hwmgr_func->powergate_acp(hwmgr, gate);
1176 }
1177
1178 static void pp_dpm_powergate_sdma(void *handle, bool gate)
1179 {
1180         struct pp_hwmgr *hwmgr = handle;
1181
1182         if (!hwmgr)
1183                 return;
1184
1185         if (hwmgr->hwmgr_func->powergate_sdma == NULL) {
1186                 pr_info_ratelimited("%s was not implemented.\n", __func__);
1187                 return;
1188         }
1189
1190         hwmgr->hwmgr_func->powergate_sdma(hwmgr, gate);
1191 }
1192
1193 static int pp_set_powergating_by_smu(void *handle,
1194                                 uint32_t block_type, bool gate)
1195 {
1196         int ret = 0;
1197
1198         switch (block_type) {
1199         case AMD_IP_BLOCK_TYPE_UVD:
1200         case AMD_IP_BLOCK_TYPE_VCN:
1201                 pp_dpm_powergate_uvd(handle, gate);
1202                 break;
1203         case AMD_IP_BLOCK_TYPE_VCE:
1204                 pp_dpm_powergate_vce(handle, gate);
1205                 break;
1206         case AMD_IP_BLOCK_TYPE_GMC:
1207                 /*
1208                  * For now, this is only used on PICASSO.
1209                  * And only "gate" operation is supported.
1210                  */
1211                 if (gate)
1212                         pp_dpm_powergate_mmhub(handle);
1213                 break;
1214         case AMD_IP_BLOCK_TYPE_GFX:
1215                 ret = pp_dpm_powergate_gfx(handle, gate);
1216                 break;
1217         case AMD_IP_BLOCK_TYPE_ACP:
1218                 pp_dpm_powergate_acp(handle, gate);
1219                 break;
1220         case AMD_IP_BLOCK_TYPE_SDMA:
1221                 pp_dpm_powergate_sdma(handle, gate);
1222                 break;
1223         default:
1224                 break;
1225         }
1226         return ret;
1227 }
1228
1229 static int pp_notify_smu_enable_pwe(void *handle)
1230 {
1231         struct pp_hwmgr *hwmgr = handle;
1232
1233         if (!hwmgr || !hwmgr->pm_en)
1234                 return -EINVAL;
1235
1236         if (hwmgr->hwmgr_func->smus_notify_pwe == NULL) {
1237                 pr_info_ratelimited("%s was not implemented.\n", __func__);
1238                 return -EINVAL;
1239         }
1240
1241         hwmgr->hwmgr_func->smus_notify_pwe(hwmgr);
1242
1243         return 0;
1244 }
1245
1246 static int pp_enable_mgpu_fan_boost(void *handle)
1247 {
1248         struct pp_hwmgr *hwmgr = handle;
1249
1250         if (!hwmgr)
1251                 return -EINVAL;
1252
1253         if (!hwmgr->pm_en ||
1254              hwmgr->hwmgr_func->enable_mgpu_fan_boost == NULL)
1255                 return 0;
1256
1257         hwmgr->hwmgr_func->enable_mgpu_fan_boost(hwmgr);
1258
1259         return 0;
1260 }
1261
1262 static int pp_set_min_deep_sleep_dcefclk(void *handle, uint32_t clock)
1263 {
1264         struct pp_hwmgr *hwmgr = handle;
1265
1266         if (!hwmgr || !hwmgr->pm_en)
1267                 return -EINVAL;
1268
1269         if (hwmgr->hwmgr_func->set_min_deep_sleep_dcefclk == NULL) {
1270                 pr_debug("%s was not implemented.\n", __func__);
1271                 return -EINVAL;
1272         }
1273
1274         hwmgr->hwmgr_func->set_min_deep_sleep_dcefclk(hwmgr, clock);
1275
1276         return 0;
1277 }
1278
1279 static int pp_set_hard_min_dcefclk_by_freq(void *handle, uint32_t clock)
1280 {
1281         struct pp_hwmgr *hwmgr = handle;
1282
1283         if (!hwmgr || !hwmgr->pm_en)
1284                 return -EINVAL;
1285
1286         if (hwmgr->hwmgr_func->set_hard_min_dcefclk_by_freq == NULL) {
1287                 pr_debug("%s was not implemented.\n", __func__);
1288                 return -EINVAL;
1289         }
1290
1291         hwmgr->hwmgr_func->set_hard_min_dcefclk_by_freq(hwmgr, clock);
1292
1293         return 0;
1294 }
1295
1296 static int pp_set_hard_min_fclk_by_freq(void *handle, uint32_t clock)
1297 {
1298         struct pp_hwmgr *hwmgr = handle;
1299
1300         if (!hwmgr || !hwmgr->pm_en)
1301                 return -EINVAL;
1302
1303         if (hwmgr->hwmgr_func->set_hard_min_fclk_by_freq == NULL) {
1304                 pr_debug("%s was not implemented.\n", __func__);
1305                 return -EINVAL;
1306         }
1307
1308         hwmgr->hwmgr_func->set_hard_min_fclk_by_freq(hwmgr, clock);
1309
1310         return 0;
1311 }
1312
1313 static int pp_set_active_display_count(void *handle, uint32_t count)
1314 {
1315         struct pp_hwmgr *hwmgr = handle;
1316
1317         if (!hwmgr || !hwmgr->pm_en)
1318                 return -EINVAL;
1319
1320         return phm_set_active_display_count(hwmgr, count);
1321 }
1322
1323 static int pp_get_asic_baco_capability(void *handle, bool *cap)
1324 {
1325         struct pp_hwmgr *hwmgr = handle;
1326
1327         *cap = false;
1328         if (!hwmgr)
1329                 return -EINVAL;
1330
1331         if (!(hwmgr->not_vf && amdgpu_dpm) ||
1332                 !hwmgr->hwmgr_func->get_asic_baco_capability)
1333                 return 0;
1334
1335         hwmgr->hwmgr_func->get_asic_baco_capability(hwmgr, cap);
1336
1337         return 0;
1338 }
1339
1340 static int pp_get_asic_baco_state(void *handle, int *state)
1341 {
1342         struct pp_hwmgr *hwmgr = handle;
1343
1344         if (!hwmgr)
1345                 return -EINVAL;
1346
1347         if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_asic_baco_state)
1348                 return 0;
1349
1350         hwmgr->hwmgr_func->get_asic_baco_state(hwmgr, (enum BACO_STATE *)state);
1351
1352         return 0;
1353 }
1354
1355 static int pp_set_asic_baco_state(void *handle, int state)
1356 {
1357         struct pp_hwmgr *hwmgr = handle;
1358
1359         if (!hwmgr)
1360                 return -EINVAL;
1361
1362         if (!(hwmgr->not_vf && amdgpu_dpm) ||
1363                 !hwmgr->hwmgr_func->set_asic_baco_state)
1364                 return 0;
1365
1366         hwmgr->hwmgr_func->set_asic_baco_state(hwmgr, (enum BACO_STATE)state);
1367
1368         return 0;
1369 }
1370
1371 static int pp_get_ppfeature_status(void *handle, char *buf)
1372 {
1373         struct pp_hwmgr *hwmgr = handle;
1374
1375         if (!hwmgr || !hwmgr->pm_en || !buf)
1376                 return -EINVAL;
1377
1378         if (hwmgr->hwmgr_func->get_ppfeature_status == NULL) {
1379                 pr_info_ratelimited("%s was not implemented.\n", __func__);
1380                 return -EINVAL;
1381         }
1382
1383         return hwmgr->hwmgr_func->get_ppfeature_status(hwmgr, buf);
1384 }
1385
1386 static int pp_set_ppfeature_status(void *handle, uint64_t ppfeature_masks)
1387 {
1388         struct pp_hwmgr *hwmgr = handle;
1389
1390         if (!hwmgr || !hwmgr->pm_en)
1391                 return -EINVAL;
1392
1393         if (hwmgr->hwmgr_func->set_ppfeature_status == NULL) {
1394                 pr_info_ratelimited("%s was not implemented.\n", __func__);
1395                 return -EINVAL;
1396         }
1397
1398         return hwmgr->hwmgr_func->set_ppfeature_status(hwmgr, ppfeature_masks);
1399 }
1400
1401 static int pp_asic_reset_mode_2(void *handle)
1402 {
1403         struct pp_hwmgr *hwmgr = handle;
1404
1405         if (!hwmgr || !hwmgr->pm_en)
1406                 return -EINVAL;
1407
1408         if (hwmgr->hwmgr_func->asic_reset == NULL) {
1409                 pr_info_ratelimited("%s was not implemented.\n", __func__);
1410                 return -EINVAL;
1411         }
1412
1413         return hwmgr->hwmgr_func->asic_reset(hwmgr, SMU_ASIC_RESET_MODE_2);
1414 }
1415
1416 static int pp_smu_i2c_bus_access(void *handle, bool acquire)
1417 {
1418         struct pp_hwmgr *hwmgr = handle;
1419
1420         if (!hwmgr || !hwmgr->pm_en)
1421                 return -EINVAL;
1422
1423         if (hwmgr->hwmgr_func->smu_i2c_bus_access == NULL) {
1424                 pr_info_ratelimited("%s was not implemented.\n", __func__);
1425                 return -EINVAL;
1426         }
1427
1428         return hwmgr->hwmgr_func->smu_i2c_bus_access(hwmgr, acquire);
1429 }
1430
1431 static int pp_set_df_cstate(void *handle, enum pp_df_cstate state)
1432 {
1433         struct pp_hwmgr *hwmgr = handle;
1434
1435         if (!hwmgr)
1436                 return -EINVAL;
1437
1438         if (!hwmgr->pm_en || !hwmgr->hwmgr_func->set_df_cstate)
1439                 return 0;
1440
1441         hwmgr->hwmgr_func->set_df_cstate(hwmgr, state);
1442
1443         return 0;
1444 }
1445
1446 static int pp_set_xgmi_pstate(void *handle, uint32_t pstate)
1447 {
1448         struct pp_hwmgr *hwmgr = handle;
1449
1450         if (!hwmgr)
1451                 return -EINVAL;
1452
1453         if (!hwmgr->pm_en || !hwmgr->hwmgr_func->set_xgmi_pstate)
1454                 return 0;
1455
1456         hwmgr->hwmgr_func->set_xgmi_pstate(hwmgr, pstate);
1457
1458         return 0;
1459 }
1460
1461 static ssize_t pp_get_gpu_metrics(void *handle, void **table)
1462 {
1463         struct pp_hwmgr *hwmgr = handle;
1464
1465         if (!hwmgr)
1466                 return -EINVAL;
1467
1468         if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_gpu_metrics)
1469                 return -EOPNOTSUPP;
1470
1471         return hwmgr->hwmgr_func->get_gpu_metrics(hwmgr, table);
1472 }
1473
1474 static int pp_gfx_state_change_set(void *handle, uint32_t state)
1475 {
1476         struct pp_hwmgr *hwmgr = handle;
1477
1478         if (!hwmgr || !hwmgr->pm_en)
1479                 return -EINVAL;
1480
1481         if (hwmgr->hwmgr_func->gfx_state_change == NULL) {
1482                 pr_info_ratelimited("%s was not implemented.\n", __func__);
1483                 return -EINVAL;
1484         }
1485
1486         hwmgr->hwmgr_func->gfx_state_change(hwmgr, state);
1487         return 0;
1488 }
1489
1490 static int pp_get_prv_buffer_details(void *handle, void **addr, size_t *size)
1491 {
1492         struct pp_hwmgr *hwmgr = handle;
1493         struct amdgpu_device *adev = hwmgr->adev;
1494         int err;
1495
1496         if (!addr || !size)
1497                 return -EINVAL;
1498
1499         *addr = NULL;
1500         *size = 0;
1501         if (adev->pm.smu_prv_buffer) {
1502                 err = amdgpu_bo_kmap(adev->pm.smu_prv_buffer, addr);
1503                 if (err)
1504                         return err;
1505                 *size = adev->pm.smu_prv_buffer_size;
1506         }
1507
1508         return 0;
1509 }
1510
1511 static void pp_pm_compute_clocks(void *handle)
1512 {
1513         struct pp_hwmgr *hwmgr = handle;
1514         struct amdgpu_device *adev = hwmgr->adev;
1515
1516         if (!adev->dc_enabled) {
1517                 amdgpu_dpm_get_active_displays(adev);
1518                 adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtc_count;
1519                 adev->pm.pm_display_cfg.vrefresh = amdgpu_dpm_get_vrefresh(adev);
1520                 adev->pm.pm_display_cfg.min_vblank_time = amdgpu_dpm_get_vblank_time(adev);
1521                 /* we have issues with mclk switching with
1522                  * refresh rates over 120 hz on the non-DC code.
1523                  */
1524                 if (adev->pm.pm_display_cfg.vrefresh > 120)
1525                         adev->pm.pm_display_cfg.min_vblank_time = 0;
1526
1527                 pp_display_configuration_change(handle,
1528                                                 &adev->pm.pm_display_cfg);
1529         }
1530
1531         pp_dpm_dispatch_tasks(handle,
1532                               AMD_PP_TASK_DISPLAY_CONFIG_CHANGE,
1533                               NULL);
1534 }
1535
1536 static const struct amd_pm_funcs pp_dpm_funcs = {
1537         .load_firmware = pp_dpm_load_fw,
1538         .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete,
1539         .force_performance_level = pp_dpm_force_performance_level,
1540         .get_performance_level = pp_dpm_get_performance_level,
1541         .get_current_power_state = pp_dpm_get_current_power_state,
1542         .dispatch_tasks = pp_dpm_dispatch_tasks,
1543         .set_fan_control_mode = pp_dpm_set_fan_control_mode,
1544         .get_fan_control_mode = pp_dpm_get_fan_control_mode,
1545         .set_fan_speed_pwm = pp_dpm_set_fan_speed_pwm,
1546         .get_fan_speed_pwm = pp_dpm_get_fan_speed_pwm,
1547         .get_fan_speed_rpm = pp_dpm_get_fan_speed_rpm,
1548         .set_fan_speed_rpm = pp_dpm_set_fan_speed_rpm,
1549         .get_pp_num_states = pp_dpm_get_pp_num_states,
1550         .get_pp_table = pp_dpm_get_pp_table,
1551         .set_pp_table = pp_dpm_set_pp_table,
1552         .force_clock_level = pp_dpm_force_clock_level,
1553         .emit_clock_levels = pp_dpm_emit_clock_levels,
1554         .print_clock_levels = pp_dpm_print_clock_levels,
1555         .get_sclk_od = pp_dpm_get_sclk_od,
1556         .set_sclk_od = pp_dpm_set_sclk_od,
1557         .get_mclk_od = pp_dpm_get_mclk_od,
1558         .set_mclk_od = pp_dpm_set_mclk_od,
1559         .read_sensor = pp_dpm_read_sensor,
1560         .get_vce_clock_state = pp_dpm_get_vce_clock_state,
1561         .switch_power_profile = pp_dpm_switch_power_profile,
1562         .set_clockgating_by_smu = pp_set_clockgating_by_smu,
1563         .set_powergating_by_smu = pp_set_powergating_by_smu,
1564         .get_power_profile_mode = pp_get_power_profile_mode,
1565         .set_power_profile_mode = pp_set_power_profile_mode,
1566         .set_fine_grain_clk_vol = pp_set_fine_grain_clk_vol,
1567         .odn_edit_dpm_table = pp_odn_edit_dpm_table,
1568         .set_mp1_state = pp_dpm_set_mp1_state,
1569         .set_power_limit = pp_set_power_limit,
1570         .get_power_limit = pp_get_power_limit,
1571 /* export to DC */
1572         .get_sclk = pp_dpm_get_sclk,
1573         .get_mclk = pp_dpm_get_mclk,
1574         .display_configuration_change = pp_display_configuration_change,
1575         .get_display_power_level = pp_get_display_power_level,
1576         .get_current_clocks = pp_get_current_clocks,
1577         .get_clock_by_type = pp_get_clock_by_type,
1578         .get_clock_by_type_with_latency = pp_get_clock_by_type_with_latency,
1579         .get_clock_by_type_with_voltage = pp_get_clock_by_type_with_voltage,
1580         .set_watermarks_for_clocks_ranges = pp_set_watermarks_for_clocks_ranges,
1581         .display_clock_voltage_request = pp_display_clock_voltage_request,
1582         .get_display_mode_validation_clocks = pp_get_display_mode_validation_clocks,
1583         .notify_smu_enable_pwe = pp_notify_smu_enable_pwe,
1584         .enable_mgpu_fan_boost = pp_enable_mgpu_fan_boost,
1585         .set_active_display_count = pp_set_active_display_count,
1586         .set_min_deep_sleep_dcefclk = pp_set_min_deep_sleep_dcefclk,
1587         .set_hard_min_dcefclk_by_freq = pp_set_hard_min_dcefclk_by_freq,
1588         .set_hard_min_fclk_by_freq = pp_set_hard_min_fclk_by_freq,
1589         .get_asic_baco_capability = pp_get_asic_baco_capability,
1590         .get_asic_baco_state = pp_get_asic_baco_state,
1591         .set_asic_baco_state = pp_set_asic_baco_state,
1592         .get_ppfeature_status = pp_get_ppfeature_status,
1593         .set_ppfeature_status = pp_set_ppfeature_status,
1594         .asic_reset_mode_2 = pp_asic_reset_mode_2,
1595         .smu_i2c_bus_access = pp_smu_i2c_bus_access,
1596         .set_df_cstate = pp_set_df_cstate,
1597         .set_xgmi_pstate = pp_set_xgmi_pstate,
1598         .get_gpu_metrics = pp_get_gpu_metrics,
1599         .gfx_state_change_set = pp_gfx_state_change_set,
1600         .get_smu_prv_buf_details = pp_get_prv_buffer_details,
1601         .pm_compute_clocks = pp_pm_compute_clocks,
1602 };