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