xref: /openbmc/linux/drivers/gpu/drm/amd/pm/amdgpu_dpm.c (revision 936e95a4)
1e098bc96SEvan Quan /*
2e098bc96SEvan Quan  * Copyright 2011 Advanced Micro Devices, Inc.
3e098bc96SEvan Quan  *
4e098bc96SEvan Quan  * Permission is hereby granted, free of charge, to any person obtaining a
5e098bc96SEvan Quan  * copy of this software and associated documentation files (the "Software"),
6e098bc96SEvan Quan  * to deal in the Software without restriction, including without limitation
7e098bc96SEvan Quan  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8e098bc96SEvan Quan  * and/or sell copies of the Software, and to permit persons to whom the
9e098bc96SEvan Quan  * Software is furnished to do so, subject to the following conditions:
10e098bc96SEvan Quan  *
11e098bc96SEvan Quan  * The above copyright notice and this permission notice shall be included in
12e098bc96SEvan Quan  * all copies or substantial portions of the Software.
13e098bc96SEvan Quan  *
14e098bc96SEvan Quan  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15e098bc96SEvan Quan  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16e098bc96SEvan Quan  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17e098bc96SEvan Quan  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18e098bc96SEvan Quan  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19e098bc96SEvan Quan  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20e098bc96SEvan Quan  * OTHER DEALINGS IN THE SOFTWARE.
21e098bc96SEvan Quan  *
22e098bc96SEvan Quan  * Authors: Alex Deucher
23e098bc96SEvan Quan  */
24e098bc96SEvan Quan 
25e098bc96SEvan Quan #include "amdgpu.h"
26e098bc96SEvan Quan #include "amdgpu_atombios.h"
27e098bc96SEvan Quan #include "amdgpu_i2c.h"
28e098bc96SEvan Quan #include "amdgpu_dpm.h"
29e098bc96SEvan Quan #include "atom.h"
30e098bc96SEvan Quan #include "amd_pcie.h"
31e098bc96SEvan Quan #include "amdgpu_display.h"
32e098bc96SEvan Quan #include "hwmgr.h"
33e098bc96SEvan Quan #include <linux/power_supply.h>
34ebfc2533SEvan Quan #include "amdgpu_smu.h"
35e098bc96SEvan Quan 
36d4481576SEvan Quan #define amdgpu_dpm_enable_bapm(adev, e) \
37d4481576SEvan Quan 		((adev)->powerplay.pp_funcs->enable_bapm((adev)->powerplay.pp_handle, (e)))
38d4481576SEvan Quan 
39*936e95a4SGuchun Chen #define amdgpu_dpm_is_legacy_dpm(adev) ((adev)->powerplay.pp_handle == (adev))
40*936e95a4SGuchun Chen 
amdgpu_dpm_get_sclk(struct amdgpu_device * adev,bool low)41e098bc96SEvan Quan int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low)
42e098bc96SEvan Quan {
43bc7d6c12SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
443712e7a4SEvan Quan 	int ret = 0;
45e098bc96SEvan Quan 
463712e7a4SEvan Quan 	if (!pp_funcs->get_sclk)
473712e7a4SEvan Quan 		return 0;
483712e7a4SEvan Quan 
493712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
503712e7a4SEvan Quan 	ret = pp_funcs->get_sclk((adev)->powerplay.pp_handle,
513712e7a4SEvan Quan 				 low);
523712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
533712e7a4SEvan Quan 
543712e7a4SEvan Quan 	return ret;
55e098bc96SEvan Quan }
56e098bc96SEvan Quan 
amdgpu_dpm_get_mclk(struct amdgpu_device * adev,bool low)57e098bc96SEvan Quan int amdgpu_dpm_get_mclk(struct amdgpu_device *adev, bool low)
58e098bc96SEvan Quan {
59bc7d6c12SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
603712e7a4SEvan Quan 	int ret = 0;
61e098bc96SEvan Quan 
623712e7a4SEvan Quan 	if (!pp_funcs->get_mclk)
633712e7a4SEvan Quan 		return 0;
643712e7a4SEvan Quan 
653712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
663712e7a4SEvan Quan 	ret = pp_funcs->get_mclk((adev)->powerplay.pp_handle,
673712e7a4SEvan Quan 				 low);
683712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
693712e7a4SEvan Quan 
703712e7a4SEvan Quan 	return ret;
71e098bc96SEvan Quan }
72e098bc96SEvan Quan 
amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device * adev,uint32_t block_type,bool gate)73e098bc96SEvan Quan int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block_type, bool gate)
74e098bc96SEvan Quan {
75e098bc96SEvan Quan 	int ret = 0;
76bc7d6c12SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
776ee27ee2SEvan Quan 	enum ip_power_state pwr_state = gate ? POWER_STATE_OFF : POWER_STATE_ON;
786ee27ee2SEvan Quan 
796ee27ee2SEvan Quan 	if (atomic_read(&adev->pm.pwr_state[block_type]) == pwr_state) {
806ee27ee2SEvan Quan 		dev_dbg(adev->dev, "IP block%d already in the target %s state!",
816ee27ee2SEvan Quan 				block_type, gate ? "gate" : "ungate");
826ee27ee2SEvan Quan 		return 0;
836ee27ee2SEvan Quan 	}
84e098bc96SEvan Quan 
853712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
863712e7a4SEvan Quan 
87e098bc96SEvan Quan 	switch (block_type) {
88e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_UVD:
89e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_VCE:
90e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_GFX:
91e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_VCN:
92e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_SDMA:
93e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_JPEG:
94e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_GMC:
95e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_ACP:
963712e7a4SEvan Quan 		if (pp_funcs && pp_funcs->set_powergating_by_smu)
97bc7d6c12SDarren Powell 			ret = (pp_funcs->set_powergating_by_smu(
98e098bc96SEvan Quan 				(adev)->powerplay.pp_handle, block_type, gate));
99e098bc96SEvan Quan 		break;
100e098bc96SEvan Quan 	default:
101e098bc96SEvan Quan 		break;
102e098bc96SEvan Quan 	}
103e098bc96SEvan Quan 
1046ee27ee2SEvan Quan 	if (!ret)
1056ee27ee2SEvan Quan 		atomic_set(&adev->pm.pwr_state[block_type], pwr_state);
1066ee27ee2SEvan Quan 
1073712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
1083712e7a4SEvan Quan 
109e098bc96SEvan Quan 	return ret;
110e098bc96SEvan Quan }
111e098bc96SEvan Quan 
amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device * adev)1127101ab97SHuang Rui int amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device *adev)
1137101ab97SHuang Rui {
1147101ab97SHuang Rui 	struct smu_context *smu = adev->powerplay.pp_handle;
1157101ab97SHuang Rui 	int ret = -EOPNOTSUPP;
1167101ab97SHuang Rui 
1177101ab97SHuang Rui 	mutex_lock(&adev->pm.mutex);
1187101ab97SHuang Rui 	ret = smu_set_gfx_power_up_by_imu(smu);
1197101ab97SHuang Rui 	mutex_unlock(&adev->pm.mutex);
1207101ab97SHuang Rui 
1217101ab97SHuang Rui 	msleep(10);
1227101ab97SHuang Rui 
1237101ab97SHuang Rui 	return ret;
1247101ab97SHuang Rui }
1257101ab97SHuang Rui 
amdgpu_dpm_baco_enter(struct amdgpu_device * adev)126e098bc96SEvan Quan int amdgpu_dpm_baco_enter(struct amdgpu_device *adev)
127e098bc96SEvan Quan {
128e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
129e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
130e098bc96SEvan Quan 	int ret = 0;
131e098bc96SEvan Quan 
132e098bc96SEvan Quan 	if (!pp_funcs || !pp_funcs->set_asic_baco_state)
133e098bc96SEvan Quan 		return -ENOENT;
134e098bc96SEvan Quan 
1353712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
1363712e7a4SEvan Quan 
137e098bc96SEvan Quan 	/* enter BACO state */
138e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
139e098bc96SEvan Quan 
1403712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
1413712e7a4SEvan Quan 
142e098bc96SEvan Quan 	return ret;
143e098bc96SEvan Quan }
144e098bc96SEvan Quan 
amdgpu_dpm_baco_exit(struct amdgpu_device * adev)145e098bc96SEvan Quan int amdgpu_dpm_baco_exit(struct amdgpu_device *adev)
146e098bc96SEvan Quan {
147e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
148e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
149e098bc96SEvan Quan 	int ret = 0;
150e098bc96SEvan Quan 
151e098bc96SEvan Quan 	if (!pp_funcs || !pp_funcs->set_asic_baco_state)
152e098bc96SEvan Quan 		return -ENOENT;
153e098bc96SEvan Quan 
1543712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
1553712e7a4SEvan Quan 
156e098bc96SEvan Quan 	/* exit BACO state */
157e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
158e098bc96SEvan Quan 
1593712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
1603712e7a4SEvan Quan 
161e098bc96SEvan Quan 	return ret;
162e098bc96SEvan Quan }
163e098bc96SEvan Quan 
amdgpu_dpm_set_mp1_state(struct amdgpu_device * adev,enum pp_mp1_state mp1_state)164e098bc96SEvan Quan int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
165e098bc96SEvan Quan 			     enum pp_mp1_state mp1_state)
166e098bc96SEvan Quan {
167e098bc96SEvan Quan 	int ret = 0;
168bab0f602SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
169e098bc96SEvan Quan 
170bab0f602SDarren Powell 	if (pp_funcs && pp_funcs->set_mp1_state) {
1713712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
1723712e7a4SEvan Quan 
173bab0f602SDarren Powell 		ret = pp_funcs->set_mp1_state(
174e098bc96SEvan Quan 				adev->powerplay.pp_handle,
175e098bc96SEvan Quan 				mp1_state);
1763712e7a4SEvan Quan 
1773712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
178e098bc96SEvan Quan 	}
179e098bc96SEvan Quan 
180e098bc96SEvan Quan 	return ret;
181e098bc96SEvan Quan }
182e098bc96SEvan Quan 
amdgpu_dpm_is_baco_supported(struct amdgpu_device * adev)183e098bc96SEvan Quan bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev)
184e098bc96SEvan Quan {
185e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
186e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
187e098bc96SEvan Quan 	bool baco_cap;
1883712e7a4SEvan Quan 	int ret = 0;
189e098bc96SEvan Quan 
190e098bc96SEvan Quan 	if (!pp_funcs || !pp_funcs->get_asic_baco_capability)
191e098bc96SEvan Quan 		return false;
19234452ac3SAlex Deucher 	/* Don't use baco for reset in S3.
19334452ac3SAlex Deucher 	 * This is a workaround for some platforms
19434452ac3SAlex Deucher 	 * where entering BACO during suspend
19534452ac3SAlex Deucher 	 * seems to cause reboots or hangs.
19634452ac3SAlex Deucher 	 * This might be related to the fact that BACO controls
19734452ac3SAlex Deucher 	 * power to the whole GPU including devices like audio and USB.
19834452ac3SAlex Deucher 	 * Powering down/up everything may adversely affect these other
19934452ac3SAlex Deucher 	 * devices.  Needs more investigation.
20034452ac3SAlex Deucher 	 */
20134452ac3SAlex Deucher 	if (adev->in_s3)
20234452ac3SAlex Deucher 		return false;
203e098bc96SEvan Quan 
2043712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
205e098bc96SEvan Quan 
2063712e7a4SEvan Quan 	ret = pp_funcs->get_asic_baco_capability(pp_handle,
2073712e7a4SEvan Quan 						 &baco_cap);
2083712e7a4SEvan Quan 
2093712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
2103712e7a4SEvan Quan 
2113712e7a4SEvan Quan 	return ret ? false : baco_cap;
212e098bc96SEvan Quan }
213e098bc96SEvan Quan 
amdgpu_dpm_mode2_reset(struct amdgpu_device * adev)214e098bc96SEvan Quan int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev)
215e098bc96SEvan Quan {
216e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
217e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
2183712e7a4SEvan Quan 	int ret = 0;
219e098bc96SEvan Quan 
220e098bc96SEvan Quan 	if (!pp_funcs || !pp_funcs->asic_reset_mode_2)
221e098bc96SEvan Quan 		return -ENOENT;
222e098bc96SEvan Quan 
2233712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
2243712e7a4SEvan Quan 
2253712e7a4SEvan Quan 	ret = pp_funcs->asic_reset_mode_2(pp_handle);
2263712e7a4SEvan Quan 
2273712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
2283712e7a4SEvan Quan 
2293712e7a4SEvan Quan 	return ret;
230e098bc96SEvan Quan }
231e098bc96SEvan Quan 
amdgpu_dpm_enable_gfx_features(struct amdgpu_device * adev)232230dd6bbSKenneth Feng int amdgpu_dpm_enable_gfx_features(struct amdgpu_device *adev)
233230dd6bbSKenneth Feng {
234230dd6bbSKenneth Feng 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
235230dd6bbSKenneth Feng 	void *pp_handle = adev->powerplay.pp_handle;
236230dd6bbSKenneth Feng 	int ret = 0;
237230dd6bbSKenneth Feng 
238230dd6bbSKenneth Feng 	if (!pp_funcs || !pp_funcs->asic_reset_enable_gfx_features)
239230dd6bbSKenneth Feng 		return -ENOENT;
240230dd6bbSKenneth Feng 
241230dd6bbSKenneth Feng 	mutex_lock(&adev->pm.mutex);
242230dd6bbSKenneth Feng 
243230dd6bbSKenneth Feng 	ret = pp_funcs->asic_reset_enable_gfx_features(pp_handle);
244230dd6bbSKenneth Feng 
245230dd6bbSKenneth Feng 	mutex_unlock(&adev->pm.mutex);
246230dd6bbSKenneth Feng 
247230dd6bbSKenneth Feng 	return ret;
248230dd6bbSKenneth Feng }
249230dd6bbSKenneth Feng 
amdgpu_dpm_baco_reset(struct amdgpu_device * adev)250e098bc96SEvan Quan int amdgpu_dpm_baco_reset(struct amdgpu_device *adev)
251e098bc96SEvan Quan {
252e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
253e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
254e098bc96SEvan Quan 	int ret = 0;
255e098bc96SEvan Quan 
2569ab5001aSDarren Powell 	if (!pp_funcs || !pp_funcs->set_asic_baco_state)
257e098bc96SEvan Quan 		return -ENOENT;
258e098bc96SEvan Quan 
2593712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
2603712e7a4SEvan Quan 
261e098bc96SEvan Quan 	/* enter BACO state */
262e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
263e098bc96SEvan Quan 	if (ret)
2643712e7a4SEvan Quan 		goto out;
265e098bc96SEvan Quan 
266e098bc96SEvan Quan 	/* exit BACO state */
267e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
268e098bc96SEvan Quan 
2693712e7a4SEvan Quan out:
2703712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
2713712e7a4SEvan Quan 	return ret;
272e098bc96SEvan Quan }
273e098bc96SEvan Quan 
amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device * adev)274e098bc96SEvan Quan bool amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device *adev)
275e098bc96SEvan Quan {
276ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
2773712e7a4SEvan Quan 	bool support_mode1_reset = false;
278e098bc96SEvan Quan 
2793712e7a4SEvan Quan 	if (is_support_sw_smu(adev)) {
2803712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
2813712e7a4SEvan Quan 		support_mode1_reset = smu_mode1_reset_is_support(smu);
2823712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
2833712e7a4SEvan Quan 	}
284e098bc96SEvan Quan 
2853712e7a4SEvan Quan 	return support_mode1_reset;
286e098bc96SEvan Quan }
287e098bc96SEvan Quan 
amdgpu_dpm_mode1_reset(struct amdgpu_device * adev)288e098bc96SEvan Quan int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev)
289e098bc96SEvan Quan {
290ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
2913712e7a4SEvan Quan 	int ret = -EOPNOTSUPP;
292e098bc96SEvan Quan 
2933712e7a4SEvan Quan 	if (is_support_sw_smu(adev)) {
2943712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
2953712e7a4SEvan Quan 		ret = smu_mode1_reset(smu);
2963712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
2973712e7a4SEvan Quan 	}
298e098bc96SEvan Quan 
2993712e7a4SEvan Quan 	return ret;
300e098bc96SEvan Quan }
301e098bc96SEvan Quan 
amdgpu_dpm_switch_power_profile(struct amdgpu_device * adev,enum PP_SMC_POWER_PROFILE type,bool en)302e098bc96SEvan Quan int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
303e098bc96SEvan Quan 				    enum PP_SMC_POWER_PROFILE type,
304e098bc96SEvan Quan 				    bool en)
305e098bc96SEvan Quan {
306bab0f602SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
307e098bc96SEvan Quan 	int ret = 0;
308e098bc96SEvan Quan 
3097cf7a392SJingwen Chen 	if (amdgpu_sriov_vf(adev))
3107cf7a392SJingwen Chen 		return 0;
3117cf7a392SJingwen Chen 
3123712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->switch_power_profile) {
3133712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
314bab0f602SDarren Powell 		ret = pp_funcs->switch_power_profile(
315e098bc96SEvan Quan 			adev->powerplay.pp_handle, type, en);
3163712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3173712e7a4SEvan Quan 	}
318e098bc96SEvan Quan 
319e098bc96SEvan Quan 	return ret;
320e098bc96SEvan Quan }
321e098bc96SEvan Quan 
amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device * adev,uint32_t pstate)322e098bc96SEvan Quan int amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device *adev,
323e098bc96SEvan Quan 			       uint32_t pstate)
324e098bc96SEvan Quan {
325bab0f602SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
326e098bc96SEvan Quan 	int ret = 0;
327e098bc96SEvan Quan 
3283712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->set_xgmi_pstate) {
3293712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
330bab0f602SDarren Powell 		ret = pp_funcs->set_xgmi_pstate(adev->powerplay.pp_handle,
331e098bc96SEvan Quan 								pstate);
3323712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3333712e7a4SEvan Quan 	}
334e098bc96SEvan Quan 
335e098bc96SEvan Quan 	return ret;
336e098bc96SEvan Quan }
337e098bc96SEvan Quan 
amdgpu_dpm_set_df_cstate(struct amdgpu_device * adev,uint32_t cstate)338e098bc96SEvan Quan int amdgpu_dpm_set_df_cstate(struct amdgpu_device *adev,
339e098bc96SEvan Quan 			     uint32_t cstate)
340e098bc96SEvan Quan {
341e098bc96SEvan Quan 	int ret = 0;
342e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
343e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
344e098bc96SEvan Quan 
3453712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->set_df_cstate) {
3463712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
347e098bc96SEvan Quan 		ret = pp_funcs->set_df_cstate(pp_handle, cstate);
3483712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3493712e7a4SEvan Quan 	}
350e098bc96SEvan Quan 
351e098bc96SEvan Quan 	return ret;
352e098bc96SEvan Quan }
353e098bc96SEvan Quan 
amdgpu_dpm_allow_xgmi_power_down(struct amdgpu_device * adev,bool en)354e098bc96SEvan Quan int amdgpu_dpm_allow_xgmi_power_down(struct amdgpu_device *adev, bool en)
355e098bc96SEvan Quan {
356ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
3573712e7a4SEvan Quan 	int ret = 0;
358e098bc96SEvan Quan 
3593712e7a4SEvan Quan 	if (is_support_sw_smu(adev)) {
3603712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
3613712e7a4SEvan Quan 		ret = smu_allow_xgmi_power_down(smu, en);
3623712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3633712e7a4SEvan Quan 	}
364e098bc96SEvan Quan 
3653712e7a4SEvan Quan 	return ret;
366e098bc96SEvan Quan }
367e098bc96SEvan Quan 
amdgpu_dpm_enable_mgpu_fan_boost(struct amdgpu_device * adev)368e098bc96SEvan Quan int amdgpu_dpm_enable_mgpu_fan_boost(struct amdgpu_device *adev)
369e098bc96SEvan Quan {
370e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
371e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs =
372e098bc96SEvan Quan 			adev->powerplay.pp_funcs;
373e098bc96SEvan Quan 	int ret = 0;
374e098bc96SEvan Quan 
3753712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->enable_mgpu_fan_boost) {
3763712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
377e098bc96SEvan Quan 		ret = pp_funcs->enable_mgpu_fan_boost(pp_handle);
3783712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3793712e7a4SEvan Quan 	}
380e098bc96SEvan Quan 
381e098bc96SEvan Quan 	return ret;
382e098bc96SEvan Quan }
383e098bc96SEvan Quan 
amdgpu_dpm_set_clockgating_by_smu(struct amdgpu_device * adev,uint32_t msg_id)384e098bc96SEvan Quan int amdgpu_dpm_set_clockgating_by_smu(struct amdgpu_device *adev,
385e098bc96SEvan Quan 				      uint32_t msg_id)
386e098bc96SEvan Quan {
387e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
388e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs =
389e098bc96SEvan Quan 			adev->powerplay.pp_funcs;
390e098bc96SEvan Quan 	int ret = 0;
391e098bc96SEvan Quan 
3923712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->set_clockgating_by_smu) {
3933712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
394e098bc96SEvan Quan 		ret = pp_funcs->set_clockgating_by_smu(pp_handle,
395e098bc96SEvan Quan 						       msg_id);
3963712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3973712e7a4SEvan Quan 	}
398e098bc96SEvan Quan 
399e098bc96SEvan Quan 	return ret;
400e098bc96SEvan Quan }
401e098bc96SEvan Quan 
amdgpu_dpm_smu_i2c_bus_access(struct amdgpu_device * adev,bool acquire)402e098bc96SEvan Quan int amdgpu_dpm_smu_i2c_bus_access(struct amdgpu_device *adev,
403e098bc96SEvan Quan 				  bool acquire)
404e098bc96SEvan Quan {
405e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
406e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs =
407e098bc96SEvan Quan 			adev->powerplay.pp_funcs;
408e098bc96SEvan Quan 	int ret = -EOPNOTSUPP;
409e098bc96SEvan Quan 
4103712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->smu_i2c_bus_access) {
4113712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
412e098bc96SEvan Quan 		ret = pp_funcs->smu_i2c_bus_access(pp_handle,
413e098bc96SEvan Quan 						   acquire);
4143712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
4153712e7a4SEvan Quan 	}
416e098bc96SEvan Quan 
417e098bc96SEvan Quan 	return ret;
418e098bc96SEvan Quan }
419e098bc96SEvan Quan 
amdgpu_pm_acpi_event_handler(struct amdgpu_device * adev)420e098bc96SEvan Quan void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev)
421e098bc96SEvan Quan {
422e098bc96SEvan Quan 	if (adev->pm.dpm_enabled) {
423e098bc96SEvan Quan 		mutex_lock(&adev->pm.mutex);
424e098bc96SEvan Quan 		if (power_supply_is_system_supplied() > 0)
425e098bc96SEvan Quan 			adev->pm.ac_power = true;
426e098bc96SEvan Quan 		else
427e098bc96SEvan Quan 			adev->pm.ac_power = false;
4283712e7a4SEvan Quan 
429e098bc96SEvan Quan 		if (adev->powerplay.pp_funcs &&
430e098bc96SEvan Quan 		    adev->powerplay.pp_funcs->enable_bapm)
431e098bc96SEvan Quan 			amdgpu_dpm_enable_bapm(adev, adev->pm.ac_power);
432e098bc96SEvan Quan 
433e098bc96SEvan Quan 		if (is_support_sw_smu(adev))
434ebfc2533SEvan Quan 			smu_set_ac_dc(adev->powerplay.pp_handle);
4353712e7a4SEvan Quan 
4363712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
437e098bc96SEvan Quan 	}
438e098bc96SEvan Quan }
439e098bc96SEvan Quan 
amdgpu_dpm_read_sensor(struct amdgpu_device * adev,enum amd_pp_sensors sensor,void * data,uint32_t * size)440e098bc96SEvan Quan int amdgpu_dpm_read_sensor(struct amdgpu_device *adev, enum amd_pp_sensors sensor,
441e098bc96SEvan Quan 			   void *data, uint32_t *size)
442e098bc96SEvan Quan {
4439ab5001aSDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
4443712e7a4SEvan Quan 	int ret = -EINVAL;
445e098bc96SEvan Quan 
446e098bc96SEvan Quan 	if (!data || !size)
447e098bc96SEvan Quan 		return -EINVAL;
448e098bc96SEvan Quan 
4493712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->read_sensor) {
4503712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
4513712e7a4SEvan Quan 		ret = pp_funcs->read_sensor(adev->powerplay.pp_handle,
4523712e7a4SEvan Quan 					    sensor,
4533712e7a4SEvan Quan 					    data,
4543712e7a4SEvan Quan 					    size);
4553712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
4563712e7a4SEvan Quan 	}
457e098bc96SEvan Quan 
458e098bc96SEvan Quan 	return ret;
459e098bc96SEvan Quan }
460e098bc96SEvan Quan 
amdgpu_dpm_get_apu_thermal_limit(struct amdgpu_device * adev,uint32_t * limit)461c3ed0e72SKun Liu int amdgpu_dpm_get_apu_thermal_limit(struct amdgpu_device *adev, uint32_t *limit)
462c3ed0e72SKun Liu {
463c3ed0e72SKun Liu 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
464c3ed0e72SKun Liu 	int ret = -EINVAL;
465c3ed0e72SKun Liu 
466c3ed0e72SKun Liu 	if (pp_funcs && pp_funcs->get_apu_thermal_limit) {
467c3ed0e72SKun Liu 		mutex_lock(&adev->pm.mutex);
468c3ed0e72SKun Liu 		ret = pp_funcs->get_apu_thermal_limit(adev->powerplay.pp_handle, limit);
469c3ed0e72SKun Liu 		mutex_unlock(&adev->pm.mutex);
470c3ed0e72SKun Liu 	}
471c3ed0e72SKun Liu 
472c3ed0e72SKun Liu 	return ret;
473c3ed0e72SKun Liu }
474c3ed0e72SKun Liu 
amdgpu_dpm_set_apu_thermal_limit(struct amdgpu_device * adev,uint32_t limit)475c3ed0e72SKun Liu int amdgpu_dpm_set_apu_thermal_limit(struct amdgpu_device *adev, uint32_t limit)
476c3ed0e72SKun Liu {
477c3ed0e72SKun Liu 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
478c3ed0e72SKun Liu 	int ret = -EINVAL;
479c3ed0e72SKun Liu 
480c3ed0e72SKun Liu 	if (pp_funcs && pp_funcs->set_apu_thermal_limit) {
481c3ed0e72SKun Liu 		mutex_lock(&adev->pm.mutex);
482c3ed0e72SKun Liu 		ret = pp_funcs->set_apu_thermal_limit(adev->powerplay.pp_handle, limit);
483c3ed0e72SKun Liu 		mutex_unlock(&adev->pm.mutex);
484c3ed0e72SKun Liu 	}
485c3ed0e72SKun Liu 
486c3ed0e72SKun Liu 	return ret;
487c3ed0e72SKun Liu }
488c3ed0e72SKun Liu 
amdgpu_dpm_compute_clocks(struct amdgpu_device * adev)48984176663SEvan Quan void amdgpu_dpm_compute_clocks(struct amdgpu_device *adev)
490e098bc96SEvan Quan {
4916ddbd37fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
492a71849cdSEvan Quan 	int i;
493e098bc96SEvan Quan 
494e098bc96SEvan Quan 	if (!adev->pm.dpm_enabled)
495e098bc96SEvan Quan 		return;
496e098bc96SEvan Quan 
4976ddbd37fSEvan Quan 	if (!pp_funcs->pm_compute_clocks)
4986ddbd37fSEvan Quan 		return;
499e098bc96SEvan Quan 
500a71849cdSEvan Quan 	if (adev->mode_info.num_crtc)
501a71849cdSEvan Quan 		amdgpu_display_bandwidth_update(adev);
502a71849cdSEvan Quan 
503a71849cdSEvan Quan 	for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
504a71849cdSEvan Quan 		struct amdgpu_ring *ring = adev->rings[i];
505a71849cdSEvan Quan 		if (ring && ring->sched.ready)
506a71849cdSEvan Quan 			amdgpu_fence_wait_empty(ring);
507a71849cdSEvan Quan 	}
508a71849cdSEvan Quan 
5093712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
5106ddbd37fSEvan Quan 	pp_funcs->pm_compute_clocks(adev->powerplay.pp_handle);
5113712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
512e098bc96SEvan Quan }
513e098bc96SEvan Quan 
amdgpu_dpm_enable_uvd(struct amdgpu_device * adev,bool enable)514e098bc96SEvan Quan void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
515e098bc96SEvan Quan {
516e098bc96SEvan Quan 	int ret = 0;
517e098bc96SEvan Quan 
518a71849cdSEvan Quan 	if (adev->family == AMDGPU_FAMILY_SI) {
519a71849cdSEvan Quan 		mutex_lock(&adev->pm.mutex);
520a71849cdSEvan Quan 		if (enable) {
521a71849cdSEvan Quan 			adev->pm.dpm.uvd_active = true;
522a71849cdSEvan Quan 			adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
523a71849cdSEvan Quan 		} else {
524a71849cdSEvan Quan 			adev->pm.dpm.uvd_active = false;
525a71849cdSEvan Quan 		}
526a71849cdSEvan Quan 		mutex_unlock(&adev->pm.mutex);
527a71849cdSEvan Quan 
528a71849cdSEvan Quan 		amdgpu_dpm_compute_clocks(adev);
529a71849cdSEvan Quan 		return;
530a71849cdSEvan Quan 	}
531a71849cdSEvan Quan 
532e098bc96SEvan Quan 	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable);
533e098bc96SEvan Quan 	if (ret)
534e098bc96SEvan Quan 		DRM_ERROR("Dpm %s uvd failed, ret = %d. \n",
535e098bc96SEvan Quan 			  enable ? "enable" : "disable", ret);
536e098bc96SEvan Quan }
537e098bc96SEvan Quan 
amdgpu_dpm_enable_vce(struct amdgpu_device * adev,bool enable)538e098bc96SEvan Quan void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
539e098bc96SEvan Quan {
540e098bc96SEvan Quan 	int ret = 0;
541e098bc96SEvan Quan 
542a71849cdSEvan Quan 	if (adev->family == AMDGPU_FAMILY_SI) {
543a71849cdSEvan Quan 		mutex_lock(&adev->pm.mutex);
544a71849cdSEvan Quan 		if (enable) {
545a71849cdSEvan Quan 			adev->pm.dpm.vce_active = true;
546a71849cdSEvan Quan 			/* XXX select vce level based on ring/task */
547a71849cdSEvan Quan 			adev->pm.dpm.vce_level = AMD_VCE_LEVEL_AC_ALL;
548a71849cdSEvan Quan 		} else {
549a71849cdSEvan Quan 			adev->pm.dpm.vce_active = false;
550a71849cdSEvan Quan 		}
551a71849cdSEvan Quan 		mutex_unlock(&adev->pm.mutex);
552a71849cdSEvan Quan 
553a71849cdSEvan Quan 		amdgpu_dpm_compute_clocks(adev);
554a71849cdSEvan Quan 		return;
555a71849cdSEvan Quan 	}
556a71849cdSEvan Quan 
557e098bc96SEvan Quan 	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable);
558e098bc96SEvan Quan 	if (ret)
559e098bc96SEvan Quan 		DRM_ERROR("Dpm %s vce failed, ret = %d. \n",
560e098bc96SEvan Quan 			  enable ? "enable" : "disable", ret);
561e098bc96SEvan Quan }
562e098bc96SEvan Quan 
amdgpu_dpm_enable_jpeg(struct amdgpu_device * adev,bool enable)563e098bc96SEvan Quan void amdgpu_dpm_enable_jpeg(struct amdgpu_device *adev, bool enable)
564e098bc96SEvan Quan {
565e098bc96SEvan Quan 	int ret = 0;
566e098bc96SEvan Quan 
567e098bc96SEvan Quan 	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_JPEG, !enable);
568e098bc96SEvan Quan 	if (ret)
569e098bc96SEvan Quan 		DRM_ERROR("Dpm %s jpeg failed, ret = %d. \n",
570e098bc96SEvan Quan 			  enable ? "enable" : "disable", ret);
571e098bc96SEvan Quan }
572e098bc96SEvan Quan 
amdgpu_pm_load_smu_firmware(struct amdgpu_device * adev,uint32_t * smu_version)573e098bc96SEvan Quan int amdgpu_pm_load_smu_firmware(struct amdgpu_device *adev, uint32_t *smu_version)
574e098bc96SEvan Quan {
5753712e7a4SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
5763712e7a4SEvan Quan 	int r = 0;
577e098bc96SEvan Quan 
5781613f346SFlora Cui 	if (!pp_funcs || !pp_funcs->load_firmware)
5793712e7a4SEvan Quan 		return 0;
5803712e7a4SEvan Quan 
5813712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
5823712e7a4SEvan Quan 	r = pp_funcs->load_firmware(adev->powerplay.pp_handle);
583e098bc96SEvan Quan 	if (r) {
584e098bc96SEvan Quan 		pr_err("smu firmware loading failed\n");
5853712e7a4SEvan Quan 		goto out;
586e098bc96SEvan Quan 	}
5872e4b2f7bSEvan Quan 
5882e4b2f7bSEvan Quan 	if (smu_version)
589e098bc96SEvan Quan 		*smu_version = adev->pm.fw_version;
5902e4b2f7bSEvan Quan 
5913712e7a4SEvan Quan out:
5923712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
5933712e7a4SEvan Quan 	return r;
594e098bc96SEvan Quan }
595bc143d8bSEvan Quan 
amdgpu_dpm_handle_passthrough_sbr(struct amdgpu_device * adev,bool enable)596bc143d8bSEvan Quan int amdgpu_dpm_handle_passthrough_sbr(struct amdgpu_device *adev, bool enable)
597bc143d8bSEvan Quan {
5983712e7a4SEvan Quan 	int ret = 0;
5993712e7a4SEvan Quan 
6003712e7a4SEvan Quan 	if (is_support_sw_smu(adev)) {
6013712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
6023712e7a4SEvan Quan 		ret = smu_handle_passthrough_sbr(adev->powerplay.pp_handle,
6033712e7a4SEvan Quan 						 enable);
6043712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
6053712e7a4SEvan Quan 	}
6063712e7a4SEvan Quan 
6073712e7a4SEvan Quan 	return ret;
608bc143d8bSEvan Quan }
609bc143d8bSEvan Quan 
amdgpu_dpm_send_hbm_bad_pages_num(struct amdgpu_device * adev,uint32_t size)610bc143d8bSEvan Quan int amdgpu_dpm_send_hbm_bad_pages_num(struct amdgpu_device *adev, uint32_t size)
611bc143d8bSEvan Quan {
612ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
6133712e7a4SEvan Quan 	int ret = 0;
614ebfc2533SEvan Quan 
61593dde6ccSStanley.Yang 	if (!is_support_sw_smu(adev))
61693dde6ccSStanley.Yang 		return -EOPNOTSUPP;
61793dde6ccSStanley.Yang 
6183712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
6193712e7a4SEvan Quan 	ret = smu_send_hbm_bad_pages_num(smu, size);
6203712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
6213712e7a4SEvan Quan 
6223712e7a4SEvan Quan 	return ret;
623bc143d8bSEvan Quan }
624bc143d8bSEvan Quan 
amdgpu_dpm_send_hbm_bad_channel_flag(struct amdgpu_device * adev,uint32_t size)625d510eccfSStanley.Yang int amdgpu_dpm_send_hbm_bad_channel_flag(struct amdgpu_device *adev, uint32_t size)
626d510eccfSStanley.Yang {
627d510eccfSStanley.Yang 	struct smu_context *smu = adev->powerplay.pp_handle;
628d510eccfSStanley.Yang 	int ret = 0;
629d510eccfSStanley.Yang 
63093dde6ccSStanley.Yang 	if (!is_support_sw_smu(adev))
63193dde6ccSStanley.Yang 		return -EOPNOTSUPP;
63293dde6ccSStanley.Yang 
633d510eccfSStanley.Yang 	mutex_lock(&adev->pm.mutex);
634d510eccfSStanley.Yang 	ret = smu_send_hbm_bad_channel_flag(smu, size);
635d510eccfSStanley.Yang 	mutex_unlock(&adev->pm.mutex);
636d510eccfSStanley.Yang 
637d510eccfSStanley.Yang 	return ret;
638d510eccfSStanley.Yang }
639d510eccfSStanley.Yang 
amdgpu_dpm_get_dpm_freq_range(struct amdgpu_device * adev,enum pp_clock_type type,uint32_t * min,uint32_t * max)640bc143d8bSEvan Quan int amdgpu_dpm_get_dpm_freq_range(struct amdgpu_device *adev,
641bc143d8bSEvan Quan 				  enum pp_clock_type type,
642bc143d8bSEvan Quan 				  uint32_t *min,
643bc143d8bSEvan Quan 				  uint32_t *max)
644bc143d8bSEvan Quan {
6453712e7a4SEvan Quan 	int ret = 0;
6463712e7a4SEvan Quan 
6473712e7a4SEvan Quan 	if (type != PP_SCLK)
6483712e7a4SEvan Quan 		return -EINVAL;
6493712e7a4SEvan Quan 
650bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
651bc143d8bSEvan Quan 		return -EOPNOTSUPP;
652bc143d8bSEvan Quan 
6533712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
6543712e7a4SEvan Quan 	ret = smu_get_dpm_freq_range(adev->powerplay.pp_handle,
6553712e7a4SEvan Quan 				     SMU_SCLK,
6563712e7a4SEvan Quan 				     min,
6573712e7a4SEvan Quan 				     max);
6583712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
6593712e7a4SEvan Quan 
6603712e7a4SEvan Quan 	return ret;
661bc143d8bSEvan Quan }
662bc143d8bSEvan Quan 
amdgpu_dpm_set_soft_freq_range(struct amdgpu_device * adev,enum pp_clock_type type,uint32_t min,uint32_t max)663bc143d8bSEvan Quan int amdgpu_dpm_set_soft_freq_range(struct amdgpu_device *adev,
664bc143d8bSEvan Quan 				   enum pp_clock_type type,
665bc143d8bSEvan Quan 				   uint32_t min,
666bc143d8bSEvan Quan 				   uint32_t max)
667bc143d8bSEvan Quan {
668ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
6693712e7a4SEvan Quan 	int ret = 0;
6703712e7a4SEvan Quan 
6713712e7a4SEvan Quan 	if (type != PP_SCLK)
6723712e7a4SEvan Quan 		return -EINVAL;
673ebfc2533SEvan Quan 
674bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
675bc143d8bSEvan Quan 		return -EOPNOTSUPP;
676bc143d8bSEvan Quan 
6773712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
6783712e7a4SEvan Quan 	ret = smu_set_soft_freq_range(smu,
6793712e7a4SEvan Quan 				      SMU_SCLK,
6803712e7a4SEvan Quan 				      min,
6813712e7a4SEvan Quan 				      max);
6823712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
6833712e7a4SEvan Quan 
6843712e7a4SEvan Quan 	return ret;
685bc143d8bSEvan Quan }
686bc143d8bSEvan Quan 
amdgpu_dpm_write_watermarks_table(struct amdgpu_device * adev)68713f5dbd6SEvan Quan int amdgpu_dpm_write_watermarks_table(struct amdgpu_device *adev)
68813f5dbd6SEvan Quan {
689ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
6903712e7a4SEvan Quan 	int ret = 0;
691ebfc2533SEvan Quan 
69213f5dbd6SEvan Quan 	if (!is_support_sw_smu(adev))
69313f5dbd6SEvan Quan 		return 0;
69413f5dbd6SEvan Quan 
6953712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
6963712e7a4SEvan Quan 	ret = smu_write_watermarks_table(smu);
6973712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
6983712e7a4SEvan Quan 
6993712e7a4SEvan Quan 	return ret;
70013f5dbd6SEvan Quan }
70113f5dbd6SEvan Quan 
amdgpu_dpm_wait_for_event(struct amdgpu_device * adev,enum smu_event_type event,uint64_t event_arg)702bc143d8bSEvan Quan int amdgpu_dpm_wait_for_event(struct amdgpu_device *adev,
703bc143d8bSEvan Quan 			      enum smu_event_type event,
704bc143d8bSEvan Quan 			      uint64_t event_arg)
705bc143d8bSEvan Quan {
706ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
7073712e7a4SEvan Quan 	int ret = 0;
708ebfc2533SEvan Quan 
709bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
710bc143d8bSEvan Quan 		return -EOPNOTSUPP;
711bc143d8bSEvan Quan 
7123712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
7133712e7a4SEvan Quan 	ret = smu_wait_for_event(smu, event, event_arg);
7143712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
7153712e7a4SEvan Quan 
7163712e7a4SEvan Quan 	return ret;
717bc143d8bSEvan Quan }
718bc143d8bSEvan Quan 
amdgpu_dpm_set_residency_gfxoff(struct amdgpu_device * adev,bool value)7190ad7347aSAndré Almeida int amdgpu_dpm_set_residency_gfxoff(struct amdgpu_device *adev, bool value)
7200ad7347aSAndré Almeida {
7210ad7347aSAndré Almeida 	struct smu_context *smu = adev->powerplay.pp_handle;
7220ad7347aSAndré Almeida 	int ret = 0;
7230ad7347aSAndré Almeida 
7240ad7347aSAndré Almeida 	if (!is_support_sw_smu(adev))
7250ad7347aSAndré Almeida 		return -EOPNOTSUPP;
7260ad7347aSAndré Almeida 
7270ad7347aSAndré Almeida 	mutex_lock(&adev->pm.mutex);
7280ad7347aSAndré Almeida 	ret = smu_set_residency_gfxoff(smu, value);
7290ad7347aSAndré Almeida 	mutex_unlock(&adev->pm.mutex);
7300ad7347aSAndré Almeida 
7310ad7347aSAndré Almeida 	return ret;
7320ad7347aSAndré Almeida }
7330ad7347aSAndré Almeida 
amdgpu_dpm_get_residency_gfxoff(struct amdgpu_device * adev,u32 * value)7340ad7347aSAndré Almeida int amdgpu_dpm_get_residency_gfxoff(struct amdgpu_device *adev, u32 *value)
7350ad7347aSAndré Almeida {
7360ad7347aSAndré Almeida 	struct smu_context *smu = adev->powerplay.pp_handle;
7370ad7347aSAndré Almeida 	int ret = 0;
7380ad7347aSAndré Almeida 
7390ad7347aSAndré Almeida 	if (!is_support_sw_smu(adev))
7400ad7347aSAndré Almeida 		return -EOPNOTSUPP;
7410ad7347aSAndré Almeida 
7420ad7347aSAndré Almeida 	mutex_lock(&adev->pm.mutex);
7430ad7347aSAndré Almeida 	ret = smu_get_residency_gfxoff(smu, value);
7440ad7347aSAndré Almeida 	mutex_unlock(&adev->pm.mutex);
7450ad7347aSAndré Almeida 
7460ad7347aSAndré Almeida 	return ret;
7470ad7347aSAndré Almeida }
7480ad7347aSAndré Almeida 
amdgpu_dpm_get_entrycount_gfxoff(struct amdgpu_device * adev,u64 * value)7490ad7347aSAndré Almeida int amdgpu_dpm_get_entrycount_gfxoff(struct amdgpu_device *adev, u64 *value)
7500ad7347aSAndré Almeida {
7510ad7347aSAndré Almeida 	struct smu_context *smu = adev->powerplay.pp_handle;
7520ad7347aSAndré Almeida 	int ret = 0;
7530ad7347aSAndré Almeida 
7540ad7347aSAndré Almeida 	if (!is_support_sw_smu(adev))
7550ad7347aSAndré Almeida 		return -EOPNOTSUPP;
7560ad7347aSAndré Almeida 
7570ad7347aSAndré Almeida 	mutex_lock(&adev->pm.mutex);
7580ad7347aSAndré Almeida 	ret = smu_get_entrycount_gfxoff(smu, value);
7590ad7347aSAndré Almeida 	mutex_unlock(&adev->pm.mutex);
7600ad7347aSAndré Almeida 
7610ad7347aSAndré Almeida 	return ret;
7620ad7347aSAndré Almeida }
7630ad7347aSAndré Almeida 
amdgpu_dpm_get_status_gfxoff(struct amdgpu_device * adev,uint32_t * value)764bc143d8bSEvan Quan int amdgpu_dpm_get_status_gfxoff(struct amdgpu_device *adev, uint32_t *value)
765bc143d8bSEvan Quan {
766ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
7673712e7a4SEvan Quan 	int ret = 0;
768ebfc2533SEvan Quan 
769bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
770bc143d8bSEvan Quan 		return -EOPNOTSUPP;
771bc143d8bSEvan Quan 
7723712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
7733712e7a4SEvan Quan 	ret = smu_get_status_gfxoff(smu, value);
7743712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
7753712e7a4SEvan Quan 
7763712e7a4SEvan Quan 	return ret;
777bc143d8bSEvan Quan }
778bc143d8bSEvan Quan 
amdgpu_dpm_get_thermal_throttling_counter(struct amdgpu_device * adev)779bc143d8bSEvan Quan uint64_t amdgpu_dpm_get_thermal_throttling_counter(struct amdgpu_device *adev)
780bc143d8bSEvan Quan {
781ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
782ebfc2533SEvan Quan 
7833712e7a4SEvan Quan 	if (!is_support_sw_smu(adev))
7843712e7a4SEvan Quan 		return 0;
7853712e7a4SEvan Quan 
786ebfc2533SEvan Quan 	return atomic64_read(&smu->throttle_int_counter);
787bc143d8bSEvan Quan }
788bc143d8bSEvan Quan 
789bc143d8bSEvan Quan /* amdgpu_dpm_gfx_state_change - Handle gfx power state change set
790bc143d8bSEvan Quan  * @adev: amdgpu_device pointer
791bc143d8bSEvan Quan  * @state: gfx power state(1 -sGpuChangeState_D0Entry and 2 -sGpuChangeState_D3Entry)
792bc143d8bSEvan Quan  *
793bc143d8bSEvan Quan  */
amdgpu_dpm_gfx_state_change(struct amdgpu_device * adev,enum gfx_change_state state)794bc143d8bSEvan Quan void amdgpu_dpm_gfx_state_change(struct amdgpu_device *adev,
795bc143d8bSEvan Quan 				 enum gfx_change_state state)
796bc143d8bSEvan Quan {
797bc143d8bSEvan Quan 	mutex_lock(&adev->pm.mutex);
798bc143d8bSEvan Quan 	if (adev->powerplay.pp_funcs &&
799bc143d8bSEvan Quan 	    adev->powerplay.pp_funcs->gfx_state_change_set)
800bc143d8bSEvan Quan 		((adev)->powerplay.pp_funcs->gfx_state_change_set(
801bc143d8bSEvan Quan 			(adev)->powerplay.pp_handle, state));
802bc143d8bSEvan Quan 	mutex_unlock(&adev->pm.mutex);
803bc143d8bSEvan Quan }
804bc143d8bSEvan Quan 
amdgpu_dpm_get_ecc_info(struct amdgpu_device * adev,void * umc_ecc)805bc143d8bSEvan Quan int amdgpu_dpm_get_ecc_info(struct amdgpu_device *adev,
806bc143d8bSEvan Quan 			    void *umc_ecc)
807bc143d8bSEvan Quan {
808ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
809a29d44aeSStanley.Yang 	int ret = 0;
810ebfc2533SEvan Quan 
811bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
812bc143d8bSEvan Quan 		return -EOPNOTSUPP;
813bc143d8bSEvan Quan 
814a29d44aeSStanley.Yang 	mutex_lock(&adev->pm.mutex);
815a29d44aeSStanley.Yang 	ret = smu_get_ecc_info(smu, umc_ecc);
816a29d44aeSStanley.Yang 	mutex_unlock(&adev->pm.mutex);
817a29d44aeSStanley.Yang 
818a29d44aeSStanley.Yang 	return ret;
819bc143d8bSEvan Quan }
82079c65f3fSEvan Quan 
amdgpu_dpm_get_vce_clock_state(struct amdgpu_device * adev,uint32_t idx)82179c65f3fSEvan Quan struct amd_vce_state *amdgpu_dpm_get_vce_clock_state(struct amdgpu_device *adev,
82279c65f3fSEvan Quan 						     uint32_t idx)
82379c65f3fSEvan Quan {
82479c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8253712e7a4SEvan Quan 	struct amd_vce_state *vstate = NULL;
82679c65f3fSEvan Quan 
82779c65f3fSEvan Quan 	if (!pp_funcs->get_vce_clock_state)
82879c65f3fSEvan Quan 		return NULL;
82979c65f3fSEvan Quan 
8303712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
8313712e7a4SEvan Quan 	vstate = pp_funcs->get_vce_clock_state(adev->powerplay.pp_handle,
83279c65f3fSEvan Quan 					       idx);
8333712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
8343712e7a4SEvan Quan 
8353712e7a4SEvan Quan 	return vstate;
83679c65f3fSEvan Quan }
83779c65f3fSEvan Quan 
amdgpu_dpm_get_current_power_state(struct amdgpu_device * adev,enum amd_pm_state_type * state)83879c65f3fSEvan Quan void amdgpu_dpm_get_current_power_state(struct amdgpu_device *adev,
83979c65f3fSEvan Quan 					enum amd_pm_state_type *state)
84079c65f3fSEvan Quan {
84179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
84279c65f3fSEvan Quan 
8433712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
8443712e7a4SEvan Quan 
84579c65f3fSEvan Quan 	if (!pp_funcs->get_current_power_state) {
84679c65f3fSEvan Quan 		*state = adev->pm.dpm.user_state;
8473712e7a4SEvan Quan 		goto out;
84879c65f3fSEvan Quan 	}
84979c65f3fSEvan Quan 
85079c65f3fSEvan Quan 	*state = pp_funcs->get_current_power_state(adev->powerplay.pp_handle);
85179c65f3fSEvan Quan 	if (*state < POWER_STATE_TYPE_DEFAULT ||
85279c65f3fSEvan Quan 	    *state > POWER_STATE_TYPE_INTERNAL_3DPERF)
85379c65f3fSEvan Quan 		*state = adev->pm.dpm.user_state;
8543712e7a4SEvan Quan 
8553712e7a4SEvan Quan out:
8563712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
85779c65f3fSEvan Quan }
85879c65f3fSEvan Quan 
amdgpu_dpm_set_power_state(struct amdgpu_device * adev,enum amd_pm_state_type state)85979c65f3fSEvan Quan void amdgpu_dpm_set_power_state(struct amdgpu_device *adev,
86079c65f3fSEvan Quan 				enum amd_pm_state_type state)
86179c65f3fSEvan Quan {
8623712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
86379c65f3fSEvan Quan 	adev->pm.dpm.user_state = state;
8643712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
86579c65f3fSEvan Quan 
86679c65f3fSEvan Quan 	if (is_support_sw_smu(adev))
86779c65f3fSEvan Quan 		return;
86879c65f3fSEvan Quan 
86979c65f3fSEvan Quan 	if (amdgpu_dpm_dispatch_task(adev,
87079c65f3fSEvan Quan 				     AMD_PP_TASK_ENABLE_USER_STATE,
87179c65f3fSEvan Quan 				     &state) == -EOPNOTSUPP)
87284176663SEvan Quan 		amdgpu_dpm_compute_clocks(adev);
87379c65f3fSEvan Quan }
87479c65f3fSEvan Quan 
amdgpu_dpm_get_performance_level(struct amdgpu_device * adev)87575513bf5SEvan Quan enum amd_dpm_forced_level amdgpu_dpm_get_performance_level(struct amdgpu_device *adev)
87679c65f3fSEvan Quan {
87779c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
87879c65f3fSEvan Quan 	enum amd_dpm_forced_level level;
87979c65f3fSEvan Quan 
88039dbde65SLijo Lazar 	if (!pp_funcs)
88139dbde65SLijo Lazar 		return AMD_DPM_FORCED_LEVEL_AUTO;
88239dbde65SLijo Lazar 
88375513bf5SEvan Quan 	mutex_lock(&adev->pm.mutex);
88479c65f3fSEvan Quan 	if (pp_funcs->get_performance_level)
88579c65f3fSEvan Quan 		level = pp_funcs->get_performance_level(adev->powerplay.pp_handle);
88679c65f3fSEvan Quan 	else
88779c65f3fSEvan Quan 		level = adev->pm.dpm.forced_level;
8883712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
88979c65f3fSEvan Quan 
89079c65f3fSEvan Quan 	return level;
89179c65f3fSEvan Quan }
89279c65f3fSEvan Quan 
amdgpu_dpm_force_performance_level(struct amdgpu_device * adev,enum amd_dpm_forced_level level)89379c65f3fSEvan Quan int amdgpu_dpm_force_performance_level(struct amdgpu_device *adev,
89479c65f3fSEvan Quan 				       enum amd_dpm_forced_level level)
89579c65f3fSEvan Quan {
89679c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
89754c73b51SAlex Deucher 	enum amd_dpm_forced_level current_level;
89854c73b51SAlex Deucher 	uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
89954c73b51SAlex Deucher 					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
90054c73b51SAlex Deucher 					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
90154c73b51SAlex Deucher 					AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
90279c65f3fSEvan Quan 
903eea5c7b3SHuang Rui 	if (!pp_funcs || !pp_funcs->force_performance_level)
9043712e7a4SEvan Quan 		return 0;
9053712e7a4SEvan Quan 
90675513bf5SEvan Quan 	if (adev->pm.dpm.thermal_active)
90775513bf5SEvan Quan 		return -EINVAL;
9083712e7a4SEvan Quan 
90975513bf5SEvan Quan 	current_level = amdgpu_dpm_get_performance_level(adev);
91075513bf5SEvan Quan 	if (current_level == level)
91175513bf5SEvan Quan 		return 0;
91254c73b51SAlex Deucher 
91354c73b51SAlex Deucher 	if (adev->asic_type == CHIP_RAVEN) {
91454c73b51SAlex Deucher 		if (!(adev->apu_flags & AMD_APU_IS_RAVEN2)) {
91554c73b51SAlex Deucher 			if (current_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
91654c73b51SAlex Deucher 			    level == AMD_DPM_FORCED_LEVEL_MANUAL)
91754c73b51SAlex Deucher 				amdgpu_gfx_off_ctrl(adev, false);
91854c73b51SAlex Deucher 			else if (current_level == AMD_DPM_FORCED_LEVEL_MANUAL &&
91954c73b51SAlex Deucher 				 level != AMD_DPM_FORCED_LEVEL_MANUAL)
92054c73b51SAlex Deucher 				amdgpu_gfx_off_ctrl(adev, true);
92154c73b51SAlex Deucher 		}
92254c73b51SAlex Deucher 	}
92354c73b51SAlex Deucher 
92454c73b51SAlex Deucher 	if (!(current_level & profile_mode_mask) &&
92575513bf5SEvan Quan 	    (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT))
92675513bf5SEvan Quan 		return -EINVAL;
92754c73b51SAlex Deucher 
92854c73b51SAlex Deucher 	if (!(current_level & profile_mode_mask) &&
92954c73b51SAlex Deucher 	      (level & profile_mode_mask)) {
93054c73b51SAlex Deucher 		/* enter UMD Pstate */
93154c73b51SAlex Deucher 		amdgpu_device_ip_set_powergating_state(adev,
93254c73b51SAlex Deucher 						       AMD_IP_BLOCK_TYPE_GFX,
93354c73b51SAlex Deucher 						       AMD_PG_STATE_UNGATE);
93454c73b51SAlex Deucher 		amdgpu_device_ip_set_clockgating_state(adev,
93554c73b51SAlex Deucher 						       AMD_IP_BLOCK_TYPE_GFX,
93654c73b51SAlex Deucher 						       AMD_CG_STATE_UNGATE);
93754c73b51SAlex Deucher 	} else if ((current_level & profile_mode_mask) &&
93854c73b51SAlex Deucher 		    !(level & profile_mode_mask)) {
93954c73b51SAlex Deucher 		/* exit UMD Pstate */
94054c73b51SAlex Deucher 		amdgpu_device_ip_set_clockgating_state(adev,
94154c73b51SAlex Deucher 						       AMD_IP_BLOCK_TYPE_GFX,
94254c73b51SAlex Deucher 						       AMD_CG_STATE_GATE);
94354c73b51SAlex Deucher 		amdgpu_device_ip_set_powergating_state(adev,
94454c73b51SAlex Deucher 						       AMD_IP_BLOCK_TYPE_GFX,
94554c73b51SAlex Deucher 						       AMD_PG_STATE_GATE);
94654c73b51SAlex Deucher 	}
94754c73b51SAlex Deucher 
94875513bf5SEvan Quan 	mutex_lock(&adev->pm.mutex);
94979c65f3fSEvan Quan 
95075513bf5SEvan Quan 	if (pp_funcs->force_performance_level(adev->powerplay.pp_handle,
95175513bf5SEvan Quan 					      level)) {
95275513bf5SEvan Quan 		mutex_unlock(&adev->pm.mutex);
95375513bf5SEvan Quan 		return -EINVAL;
95475513bf5SEvan Quan 	}
95575513bf5SEvan Quan 
95679c65f3fSEvan Quan 	adev->pm.dpm.forced_level = level;
95779c65f3fSEvan Quan 
9583712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
9593712e7a4SEvan Quan 
96075513bf5SEvan Quan 	return 0;
96179c65f3fSEvan Quan }
96279c65f3fSEvan Quan 
amdgpu_dpm_get_pp_num_states(struct amdgpu_device * adev,struct pp_states_info * states)96379c65f3fSEvan Quan int amdgpu_dpm_get_pp_num_states(struct amdgpu_device *adev,
96479c65f3fSEvan Quan 				 struct pp_states_info *states)
96579c65f3fSEvan Quan {
96679c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9673712e7a4SEvan Quan 	int ret = 0;
96879c65f3fSEvan Quan 
96979c65f3fSEvan Quan 	if (!pp_funcs->get_pp_num_states)
97079c65f3fSEvan Quan 		return -EOPNOTSUPP;
97179c65f3fSEvan Quan 
9723712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
9733712e7a4SEvan Quan 	ret = pp_funcs->get_pp_num_states(adev->powerplay.pp_handle,
9743712e7a4SEvan Quan 					  states);
9753712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
9763712e7a4SEvan Quan 
9773712e7a4SEvan Quan 	return ret;
97879c65f3fSEvan Quan }
97979c65f3fSEvan Quan 
amdgpu_dpm_dispatch_task(struct amdgpu_device * adev,enum amd_pp_task task_id,enum amd_pm_state_type * user_state)98079c65f3fSEvan Quan int amdgpu_dpm_dispatch_task(struct amdgpu_device *adev,
98179c65f3fSEvan Quan 			      enum amd_pp_task task_id,
98279c65f3fSEvan Quan 			      enum amd_pm_state_type *user_state)
98379c65f3fSEvan Quan {
98479c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9853712e7a4SEvan Quan 	int ret = 0;
98679c65f3fSEvan Quan 
98779c65f3fSEvan Quan 	if (!pp_funcs->dispatch_tasks)
98879c65f3fSEvan Quan 		return -EOPNOTSUPP;
98979c65f3fSEvan Quan 
9903712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
9913712e7a4SEvan Quan 	ret = pp_funcs->dispatch_tasks(adev->powerplay.pp_handle,
9923712e7a4SEvan Quan 				       task_id,
9933712e7a4SEvan Quan 				       user_state);
9943712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
9953712e7a4SEvan Quan 
9963712e7a4SEvan Quan 	return ret;
99779c65f3fSEvan Quan }
99879c65f3fSEvan Quan 
amdgpu_dpm_get_pp_table(struct amdgpu_device * adev,char ** table)99979c65f3fSEvan Quan int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char **table)
100079c65f3fSEvan Quan {
100179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10023712e7a4SEvan Quan 	int ret = 0;
100379c65f3fSEvan Quan 
100479c65f3fSEvan Quan 	if (!pp_funcs->get_pp_table)
100579c65f3fSEvan Quan 		return 0;
100679c65f3fSEvan Quan 
10073712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
10083712e7a4SEvan Quan 	ret = pp_funcs->get_pp_table(adev->powerplay.pp_handle,
10093712e7a4SEvan Quan 				     table);
10103712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
10113712e7a4SEvan Quan 
10123712e7a4SEvan Quan 	return ret;
101379c65f3fSEvan Quan }
101479c65f3fSEvan Quan 
amdgpu_dpm_set_fine_grain_clk_vol(struct amdgpu_device * adev,uint32_t type,long * input,uint32_t size)101579c65f3fSEvan Quan int amdgpu_dpm_set_fine_grain_clk_vol(struct amdgpu_device *adev,
101679c65f3fSEvan Quan 				      uint32_t type,
101779c65f3fSEvan Quan 				      long *input,
101879c65f3fSEvan Quan 				      uint32_t size)
101979c65f3fSEvan Quan {
102079c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10213712e7a4SEvan Quan 	int ret = 0;
102279c65f3fSEvan Quan 
102379c65f3fSEvan Quan 	if (!pp_funcs->set_fine_grain_clk_vol)
102479c65f3fSEvan Quan 		return 0;
102579c65f3fSEvan Quan 
10263712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
10273712e7a4SEvan Quan 	ret = pp_funcs->set_fine_grain_clk_vol(adev->powerplay.pp_handle,
102879c65f3fSEvan Quan 					       type,
102979c65f3fSEvan Quan 					       input,
103079c65f3fSEvan Quan 					       size);
10313712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
10323712e7a4SEvan Quan 
10333712e7a4SEvan Quan 	return ret;
103479c65f3fSEvan Quan }
103579c65f3fSEvan Quan 
amdgpu_dpm_odn_edit_dpm_table(struct amdgpu_device * adev,uint32_t type,long * input,uint32_t size)103679c65f3fSEvan Quan int amdgpu_dpm_odn_edit_dpm_table(struct amdgpu_device *adev,
103779c65f3fSEvan Quan 				  uint32_t type,
103879c65f3fSEvan Quan 				  long *input,
103979c65f3fSEvan Quan 				  uint32_t size)
104079c65f3fSEvan Quan {
104179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10423712e7a4SEvan Quan 	int ret = 0;
104379c65f3fSEvan Quan 
104479c65f3fSEvan Quan 	if (!pp_funcs->odn_edit_dpm_table)
104579c65f3fSEvan Quan 		return 0;
104679c65f3fSEvan Quan 
10473712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
10483712e7a4SEvan Quan 	ret = pp_funcs->odn_edit_dpm_table(adev->powerplay.pp_handle,
104979c65f3fSEvan Quan 					   type,
105079c65f3fSEvan Quan 					   input,
105179c65f3fSEvan Quan 					   size);
10523712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
10533712e7a4SEvan Quan 
10543712e7a4SEvan Quan 	return ret;
105579c65f3fSEvan Quan }
105679c65f3fSEvan Quan 
amdgpu_dpm_print_clock_levels(struct amdgpu_device * adev,enum pp_clock_type type,char * buf)105779c65f3fSEvan Quan int amdgpu_dpm_print_clock_levels(struct amdgpu_device *adev,
105879c65f3fSEvan Quan 				  enum pp_clock_type type,
105979c65f3fSEvan Quan 				  char *buf)
106079c65f3fSEvan Quan {
106179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10623712e7a4SEvan Quan 	int ret = 0;
106379c65f3fSEvan Quan 
106479c65f3fSEvan Quan 	if (!pp_funcs->print_clock_levels)
106579c65f3fSEvan Quan 		return 0;
106679c65f3fSEvan Quan 
10673712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
10683712e7a4SEvan Quan 	ret = pp_funcs->print_clock_levels(adev->powerplay.pp_handle,
106979c65f3fSEvan Quan 					   type,
107079c65f3fSEvan Quan 					   buf);
10713712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
10723712e7a4SEvan Quan 
10733712e7a4SEvan Quan 	return ret;
107479c65f3fSEvan Quan }
107579c65f3fSEvan Quan 
amdgpu_dpm_emit_clock_levels(struct amdgpu_device * adev,enum pp_clock_type type,char * buf,int * offset)10765d64f9bbSDarren Powell int amdgpu_dpm_emit_clock_levels(struct amdgpu_device *adev,
10775d64f9bbSDarren Powell 				  enum pp_clock_type type,
10785d64f9bbSDarren Powell 				  char *buf,
10795d64f9bbSDarren Powell 				  int *offset)
10805d64f9bbSDarren Powell {
10815d64f9bbSDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10825d64f9bbSDarren Powell 	int ret = 0;
10835d64f9bbSDarren Powell 
10845d64f9bbSDarren Powell 	if (!pp_funcs->emit_clock_levels)
10855d64f9bbSDarren Powell 		return -ENOENT;
10865d64f9bbSDarren Powell 
10875d64f9bbSDarren Powell 	mutex_lock(&adev->pm.mutex);
10885d64f9bbSDarren Powell 	ret = pp_funcs->emit_clock_levels(adev->powerplay.pp_handle,
10895d64f9bbSDarren Powell 					   type,
10905d64f9bbSDarren Powell 					   buf,
10915d64f9bbSDarren Powell 					   offset);
10925d64f9bbSDarren Powell 	mutex_unlock(&adev->pm.mutex);
10935d64f9bbSDarren Powell 
10945d64f9bbSDarren Powell 	return ret;
10955d64f9bbSDarren Powell }
10965d64f9bbSDarren Powell 
amdgpu_dpm_set_ppfeature_status(struct amdgpu_device * adev,uint64_t ppfeature_masks)109779c65f3fSEvan Quan int amdgpu_dpm_set_ppfeature_status(struct amdgpu_device *adev,
109879c65f3fSEvan Quan 				    uint64_t ppfeature_masks)
109979c65f3fSEvan Quan {
110079c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11013712e7a4SEvan Quan 	int ret = 0;
110279c65f3fSEvan Quan 
110379c65f3fSEvan Quan 	if (!pp_funcs->set_ppfeature_status)
110479c65f3fSEvan Quan 		return 0;
110579c65f3fSEvan Quan 
11063712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11073712e7a4SEvan Quan 	ret = pp_funcs->set_ppfeature_status(adev->powerplay.pp_handle,
110879c65f3fSEvan Quan 					     ppfeature_masks);
11093712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11103712e7a4SEvan Quan 
11113712e7a4SEvan Quan 	return ret;
111279c65f3fSEvan Quan }
111379c65f3fSEvan Quan 
amdgpu_dpm_get_ppfeature_status(struct amdgpu_device * adev,char * buf)111479c65f3fSEvan Quan int amdgpu_dpm_get_ppfeature_status(struct amdgpu_device *adev, char *buf)
111579c65f3fSEvan Quan {
111679c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11173712e7a4SEvan Quan 	int ret = 0;
111879c65f3fSEvan Quan 
111979c65f3fSEvan Quan 	if (!pp_funcs->get_ppfeature_status)
112079c65f3fSEvan Quan 		return 0;
112179c65f3fSEvan Quan 
11223712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11233712e7a4SEvan Quan 	ret = pp_funcs->get_ppfeature_status(adev->powerplay.pp_handle,
112479c65f3fSEvan Quan 					     buf);
11253712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11263712e7a4SEvan Quan 
11273712e7a4SEvan Quan 	return ret;
112879c65f3fSEvan Quan }
112979c65f3fSEvan Quan 
amdgpu_dpm_force_clock_level(struct amdgpu_device * adev,enum pp_clock_type type,uint32_t mask)113079c65f3fSEvan Quan int amdgpu_dpm_force_clock_level(struct amdgpu_device *adev,
113179c65f3fSEvan Quan 				 enum pp_clock_type type,
113279c65f3fSEvan Quan 				 uint32_t mask)
113379c65f3fSEvan Quan {
113479c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11353712e7a4SEvan Quan 	int ret = 0;
113679c65f3fSEvan Quan 
113779c65f3fSEvan Quan 	if (!pp_funcs->force_clock_level)
113879c65f3fSEvan Quan 		return 0;
113979c65f3fSEvan Quan 
11403712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11413712e7a4SEvan Quan 	ret = pp_funcs->force_clock_level(adev->powerplay.pp_handle,
114279c65f3fSEvan Quan 					  type,
114379c65f3fSEvan Quan 					  mask);
11443712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11453712e7a4SEvan Quan 
11463712e7a4SEvan Quan 	return ret;
114779c65f3fSEvan Quan }
114879c65f3fSEvan Quan 
amdgpu_dpm_get_sclk_od(struct amdgpu_device * adev)114979c65f3fSEvan Quan int amdgpu_dpm_get_sclk_od(struct amdgpu_device *adev)
115079c65f3fSEvan Quan {
115179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11523712e7a4SEvan Quan 	int ret = 0;
115379c65f3fSEvan Quan 
115479c65f3fSEvan Quan 	if (!pp_funcs->get_sclk_od)
115579c65f3fSEvan Quan 		return 0;
115679c65f3fSEvan Quan 
11573712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11583712e7a4SEvan Quan 	ret = pp_funcs->get_sclk_od(adev->powerplay.pp_handle);
11593712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11603712e7a4SEvan Quan 
11613712e7a4SEvan Quan 	return ret;
116279c65f3fSEvan Quan }
116379c65f3fSEvan Quan 
amdgpu_dpm_set_sclk_od(struct amdgpu_device * adev,uint32_t value)116479c65f3fSEvan Quan int amdgpu_dpm_set_sclk_od(struct amdgpu_device *adev, uint32_t value)
116579c65f3fSEvan Quan {
116679c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
116779c65f3fSEvan Quan 
116879c65f3fSEvan Quan 	if (is_support_sw_smu(adev))
116979c65f3fSEvan Quan 		return 0;
117079c65f3fSEvan Quan 
11713712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
117279c65f3fSEvan Quan 	if (pp_funcs->set_sclk_od)
117379c65f3fSEvan Quan 		pp_funcs->set_sclk_od(adev->powerplay.pp_handle, value);
11743712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
117579c65f3fSEvan Quan 
117679c65f3fSEvan Quan 	if (amdgpu_dpm_dispatch_task(adev,
117779c65f3fSEvan Quan 				     AMD_PP_TASK_READJUST_POWER_STATE,
117879c65f3fSEvan Quan 				     NULL) == -EOPNOTSUPP) {
117979c65f3fSEvan Quan 		adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
118084176663SEvan Quan 		amdgpu_dpm_compute_clocks(adev);
118179c65f3fSEvan Quan 	}
118279c65f3fSEvan Quan 
118379c65f3fSEvan Quan 	return 0;
118479c65f3fSEvan Quan }
118579c65f3fSEvan Quan 
amdgpu_dpm_get_mclk_od(struct amdgpu_device * adev)118679c65f3fSEvan Quan int amdgpu_dpm_get_mclk_od(struct amdgpu_device *adev)
118779c65f3fSEvan Quan {
118879c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11893712e7a4SEvan Quan 	int ret = 0;
119079c65f3fSEvan Quan 
119179c65f3fSEvan Quan 	if (!pp_funcs->get_mclk_od)
119279c65f3fSEvan Quan 		return 0;
119379c65f3fSEvan Quan 
11943712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11953712e7a4SEvan Quan 	ret = pp_funcs->get_mclk_od(adev->powerplay.pp_handle);
11963712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11973712e7a4SEvan Quan 
11983712e7a4SEvan Quan 	return ret;
119979c65f3fSEvan Quan }
120079c65f3fSEvan Quan 
amdgpu_dpm_set_mclk_od(struct amdgpu_device * adev,uint32_t value)120179c65f3fSEvan Quan int amdgpu_dpm_set_mclk_od(struct amdgpu_device *adev, uint32_t value)
120279c65f3fSEvan Quan {
120379c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
120479c65f3fSEvan Quan 
120579c65f3fSEvan Quan 	if (is_support_sw_smu(adev))
120679c65f3fSEvan Quan 		return 0;
120779c65f3fSEvan Quan 
12083712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
120979c65f3fSEvan Quan 	if (pp_funcs->set_mclk_od)
121079c65f3fSEvan Quan 		pp_funcs->set_mclk_od(adev->powerplay.pp_handle, value);
12113712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
121279c65f3fSEvan Quan 
121379c65f3fSEvan Quan 	if (amdgpu_dpm_dispatch_task(adev,
121479c65f3fSEvan Quan 				     AMD_PP_TASK_READJUST_POWER_STATE,
121579c65f3fSEvan Quan 				     NULL) == -EOPNOTSUPP) {
121679c65f3fSEvan Quan 		adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
121784176663SEvan Quan 		amdgpu_dpm_compute_clocks(adev);
121879c65f3fSEvan Quan 	}
121979c65f3fSEvan Quan 
122079c65f3fSEvan Quan 	return 0;
122179c65f3fSEvan Quan }
122279c65f3fSEvan Quan 
amdgpu_dpm_get_power_profile_mode(struct amdgpu_device * adev,char * buf)122379c65f3fSEvan Quan int amdgpu_dpm_get_power_profile_mode(struct amdgpu_device *adev,
122479c65f3fSEvan Quan 				      char *buf)
122579c65f3fSEvan Quan {
122679c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12273712e7a4SEvan Quan 	int ret = 0;
122879c65f3fSEvan Quan 
122979c65f3fSEvan Quan 	if (!pp_funcs->get_power_profile_mode)
123079c65f3fSEvan Quan 		return -EOPNOTSUPP;
123179c65f3fSEvan Quan 
12323712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
12333712e7a4SEvan Quan 	ret = pp_funcs->get_power_profile_mode(adev->powerplay.pp_handle,
123479c65f3fSEvan Quan 					       buf);
12353712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
12363712e7a4SEvan Quan 
12373712e7a4SEvan Quan 	return ret;
123879c65f3fSEvan Quan }
123979c65f3fSEvan Quan 
amdgpu_dpm_set_power_profile_mode(struct amdgpu_device * adev,long * input,uint32_t size)124079c65f3fSEvan Quan int amdgpu_dpm_set_power_profile_mode(struct amdgpu_device *adev,
124179c65f3fSEvan Quan 				      long *input, uint32_t size)
124279c65f3fSEvan Quan {
124379c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12443712e7a4SEvan Quan 	int ret = 0;
124579c65f3fSEvan Quan 
124679c65f3fSEvan Quan 	if (!pp_funcs->set_power_profile_mode)
124779c65f3fSEvan Quan 		return 0;
124879c65f3fSEvan Quan 
12493712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
12503712e7a4SEvan Quan 	ret = pp_funcs->set_power_profile_mode(adev->powerplay.pp_handle,
125179c65f3fSEvan Quan 					       input,
125279c65f3fSEvan Quan 					       size);
12533712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
12543712e7a4SEvan Quan 
12553712e7a4SEvan Quan 	return ret;
125679c65f3fSEvan Quan }
125779c65f3fSEvan Quan 
amdgpu_dpm_get_gpu_metrics(struct amdgpu_device * adev,void ** table)125879c65f3fSEvan Quan int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void **table)
125979c65f3fSEvan Quan {
126079c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12613712e7a4SEvan Quan 	int ret = 0;
126279c65f3fSEvan Quan 
126379c65f3fSEvan Quan 	if (!pp_funcs->get_gpu_metrics)
126479c65f3fSEvan Quan 		return 0;
126579c65f3fSEvan Quan 
12663712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
12673712e7a4SEvan Quan 	ret = pp_funcs->get_gpu_metrics(adev->powerplay.pp_handle,
12683712e7a4SEvan Quan 					table);
12693712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
12703712e7a4SEvan Quan 
12713712e7a4SEvan Quan 	return ret;
127279c65f3fSEvan Quan }
127379c65f3fSEvan Quan 
amdgpu_dpm_get_fan_control_mode(struct amdgpu_device * adev,uint32_t * fan_mode)127479c65f3fSEvan Quan int amdgpu_dpm_get_fan_control_mode(struct amdgpu_device *adev,
127579c65f3fSEvan Quan 				    uint32_t *fan_mode)
127679c65f3fSEvan Quan {
127779c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1278685fae24SEvan Quan 	int ret = 0;
127979c65f3fSEvan Quan 
128079c65f3fSEvan Quan 	if (!pp_funcs->get_fan_control_mode)
128179c65f3fSEvan Quan 		return -EOPNOTSUPP;
128279c65f3fSEvan Quan 
12833712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
1284685fae24SEvan Quan 	ret = pp_funcs->get_fan_control_mode(adev->powerplay.pp_handle,
1285685fae24SEvan Quan 					     fan_mode);
12863712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
128779c65f3fSEvan Quan 
1288685fae24SEvan Quan 	return ret;
128979c65f3fSEvan Quan }
129079c65f3fSEvan Quan 
amdgpu_dpm_set_fan_speed_pwm(struct amdgpu_device * adev,uint32_t speed)129179c65f3fSEvan Quan int amdgpu_dpm_set_fan_speed_pwm(struct amdgpu_device *adev,
129279c65f3fSEvan Quan 				 uint32_t speed)
129379c65f3fSEvan Quan {
129479c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12953712e7a4SEvan Quan 	int ret = 0;
129679c65f3fSEvan Quan 
129779c65f3fSEvan Quan 	if (!pp_funcs->set_fan_speed_pwm)
1298685fae24SEvan Quan 		return -EOPNOTSUPP;
129979c65f3fSEvan Quan 
13003712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
13013712e7a4SEvan Quan 	ret = pp_funcs->set_fan_speed_pwm(adev->powerplay.pp_handle,
13023712e7a4SEvan Quan 					  speed);
13033712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
13043712e7a4SEvan Quan 
13053712e7a4SEvan Quan 	return ret;
130679c65f3fSEvan Quan }
130779c65f3fSEvan Quan 
amdgpu_dpm_get_fan_speed_pwm(struct amdgpu_device * adev,uint32_t * speed)130879c65f3fSEvan Quan int amdgpu_dpm_get_fan_speed_pwm(struct amdgpu_device *adev,
130979c65f3fSEvan Quan 				 uint32_t *speed)
131079c65f3fSEvan Quan {
131179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13123712e7a4SEvan Quan 	int ret = 0;
131379c65f3fSEvan Quan 
131479c65f3fSEvan Quan 	if (!pp_funcs->get_fan_speed_pwm)
1315685fae24SEvan Quan 		return -EOPNOTSUPP;
131679c65f3fSEvan Quan 
13173712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
13183712e7a4SEvan Quan 	ret = pp_funcs->get_fan_speed_pwm(adev->powerplay.pp_handle,
13193712e7a4SEvan Quan 					  speed);
13203712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
13213712e7a4SEvan Quan 
13223712e7a4SEvan Quan 	return ret;
132379c65f3fSEvan Quan }
132479c65f3fSEvan Quan 
amdgpu_dpm_get_fan_speed_rpm(struct amdgpu_device * adev,uint32_t * speed)132579c65f3fSEvan Quan int amdgpu_dpm_get_fan_speed_rpm(struct amdgpu_device *adev,
132679c65f3fSEvan Quan 				 uint32_t *speed)
132779c65f3fSEvan Quan {
132879c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13293712e7a4SEvan Quan 	int ret = 0;
133079c65f3fSEvan Quan 
133179c65f3fSEvan Quan 	if (!pp_funcs->get_fan_speed_rpm)
1332685fae24SEvan Quan 		return -EOPNOTSUPP;
133379c65f3fSEvan Quan 
13343712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
13353712e7a4SEvan Quan 	ret = pp_funcs->get_fan_speed_rpm(adev->powerplay.pp_handle,
13363712e7a4SEvan Quan 					  speed);
13373712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
13383712e7a4SEvan Quan 
13393712e7a4SEvan Quan 	return ret;
134079c65f3fSEvan Quan }
134179c65f3fSEvan Quan 
amdgpu_dpm_set_fan_speed_rpm(struct amdgpu_device * adev,uint32_t speed)134279c65f3fSEvan Quan int amdgpu_dpm_set_fan_speed_rpm(struct amdgpu_device *adev,
134379c65f3fSEvan Quan 				 uint32_t speed)
134479c65f3fSEvan Quan {
134579c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13463712e7a4SEvan Quan 	int ret = 0;
134779c65f3fSEvan Quan 
134879c65f3fSEvan Quan 	if (!pp_funcs->set_fan_speed_rpm)
1349685fae24SEvan Quan 		return -EOPNOTSUPP;
135079c65f3fSEvan Quan 
13513712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
13523712e7a4SEvan Quan 	ret = pp_funcs->set_fan_speed_rpm(adev->powerplay.pp_handle,
13533712e7a4SEvan Quan 					  speed);
13543712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
13553712e7a4SEvan Quan 
13563712e7a4SEvan Quan 	return ret;
135779c65f3fSEvan Quan }
135879c65f3fSEvan Quan 
amdgpu_dpm_set_fan_control_mode(struct amdgpu_device * adev,uint32_t mode)135979c65f3fSEvan Quan int amdgpu_dpm_set_fan_control_mode(struct amdgpu_device *adev,
136079c65f3fSEvan Quan 				    uint32_t mode)
136179c65f3fSEvan Quan {
136279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1363685fae24SEvan Quan 	int ret = 0;
136479c65f3fSEvan Quan 
136579c65f3fSEvan Quan 	if (!pp_funcs->set_fan_control_mode)
136679c65f3fSEvan Quan 		return -EOPNOTSUPP;
136779c65f3fSEvan Quan 
13683712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
1369685fae24SEvan Quan 	ret = pp_funcs->set_fan_control_mode(adev->powerplay.pp_handle,
13703712e7a4SEvan Quan 					     mode);
13713712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
137279c65f3fSEvan Quan 
1373685fae24SEvan Quan 	return ret;
137479c65f3fSEvan Quan }
137579c65f3fSEvan Quan 
amdgpu_dpm_get_power_limit(struct amdgpu_device * adev,uint32_t * limit,enum pp_power_limit_level pp_limit_level,enum pp_power_type power_type)137679c65f3fSEvan Quan int amdgpu_dpm_get_power_limit(struct amdgpu_device *adev,
137779c65f3fSEvan Quan 			       uint32_t *limit,
137879c65f3fSEvan Quan 			       enum pp_power_limit_level pp_limit_level,
137979c65f3fSEvan Quan 			       enum pp_power_type power_type)
138079c65f3fSEvan Quan {
138179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13823712e7a4SEvan Quan 	int ret = 0;
138379c65f3fSEvan Quan 
138479c65f3fSEvan Quan 	if (!pp_funcs->get_power_limit)
138579c65f3fSEvan Quan 		return -ENODATA;
138679c65f3fSEvan Quan 
13873712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
13883712e7a4SEvan Quan 	ret = pp_funcs->get_power_limit(adev->powerplay.pp_handle,
138979c65f3fSEvan Quan 					limit,
139079c65f3fSEvan Quan 					pp_limit_level,
139179c65f3fSEvan Quan 					power_type);
13923712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
13933712e7a4SEvan Quan 
13943712e7a4SEvan Quan 	return ret;
139579c65f3fSEvan Quan }
139679c65f3fSEvan Quan 
amdgpu_dpm_set_power_limit(struct amdgpu_device * adev,uint32_t limit)139779c65f3fSEvan Quan int amdgpu_dpm_set_power_limit(struct amdgpu_device *adev,
139879c65f3fSEvan Quan 			       uint32_t limit)
139979c65f3fSEvan Quan {
140079c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14013712e7a4SEvan Quan 	int ret = 0;
140279c65f3fSEvan Quan 
140379c65f3fSEvan Quan 	if (!pp_funcs->set_power_limit)
140479c65f3fSEvan Quan 		return -EINVAL;
140579c65f3fSEvan Quan 
14063712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14073712e7a4SEvan Quan 	ret = pp_funcs->set_power_limit(adev->powerplay.pp_handle,
14083712e7a4SEvan Quan 					limit);
14093712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14103712e7a4SEvan Quan 
14113712e7a4SEvan Quan 	return ret;
141279c65f3fSEvan Quan }
141379c65f3fSEvan Quan 
amdgpu_dpm_is_cclk_dpm_supported(struct amdgpu_device * adev)141479c65f3fSEvan Quan int amdgpu_dpm_is_cclk_dpm_supported(struct amdgpu_device *adev)
141579c65f3fSEvan Quan {
14163712e7a4SEvan Quan 	bool cclk_dpm_supported = false;
14173712e7a4SEvan Quan 
141879c65f3fSEvan Quan 	if (!is_support_sw_smu(adev))
141979c65f3fSEvan Quan 		return false;
142079c65f3fSEvan Quan 
14213712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14223712e7a4SEvan Quan 	cclk_dpm_supported = is_support_cclk_dpm(adev);
14233712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14243712e7a4SEvan Quan 
14253712e7a4SEvan Quan 	return (int)cclk_dpm_supported;
142679c65f3fSEvan Quan }
142779c65f3fSEvan Quan 
amdgpu_dpm_debugfs_print_current_performance_level(struct amdgpu_device * adev,struct seq_file * m)142879c65f3fSEvan Quan int amdgpu_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev,
142979c65f3fSEvan Quan 						       struct seq_file *m)
143079c65f3fSEvan Quan {
143179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
143279c65f3fSEvan Quan 
143379c65f3fSEvan Quan 	if (!pp_funcs->debugfs_print_current_performance_level)
143479c65f3fSEvan Quan 		return -EOPNOTSUPP;
143579c65f3fSEvan Quan 
14363712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
143779c65f3fSEvan Quan 	pp_funcs->debugfs_print_current_performance_level(adev->powerplay.pp_handle,
143879c65f3fSEvan Quan 							  m);
14393712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
144079c65f3fSEvan Quan 
144179c65f3fSEvan Quan 	return 0;
144279c65f3fSEvan Quan }
144379c65f3fSEvan Quan 
amdgpu_dpm_get_smu_prv_buf_details(struct amdgpu_device * adev,void ** addr,size_t * size)144479c65f3fSEvan Quan int amdgpu_dpm_get_smu_prv_buf_details(struct amdgpu_device *adev,
144579c65f3fSEvan Quan 				       void **addr,
144679c65f3fSEvan Quan 				       size_t *size)
144779c65f3fSEvan Quan {
144879c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14493712e7a4SEvan Quan 	int ret = 0;
145079c65f3fSEvan Quan 
145179c65f3fSEvan Quan 	if (!pp_funcs->get_smu_prv_buf_details)
145279c65f3fSEvan Quan 		return -ENOSYS;
145379c65f3fSEvan Quan 
14543712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14553712e7a4SEvan Quan 	ret = pp_funcs->get_smu_prv_buf_details(adev->powerplay.pp_handle,
145679c65f3fSEvan Quan 						addr,
145779c65f3fSEvan Quan 						size);
14583712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14593712e7a4SEvan Quan 
14603712e7a4SEvan Quan 	return ret;
146179c65f3fSEvan Quan }
146279c65f3fSEvan Quan 
amdgpu_dpm_is_overdrive_supported(struct amdgpu_device * adev)146379c65f3fSEvan Quan int amdgpu_dpm_is_overdrive_supported(struct amdgpu_device *adev)
146479c65f3fSEvan Quan {
14659d7a348dSGuchun Chen 	if (is_support_sw_smu(adev)) {
1466ebfc2533SEvan Quan 		struct smu_context *smu = adev->powerplay.pp_handle;
146779c65f3fSEvan Quan 
14689d7a348dSGuchun Chen 		return (smu->od_enabled || smu->is_apu);
14699d7a348dSGuchun Chen 	} else {
14709d7a348dSGuchun Chen 		struct pp_hwmgr *hwmgr;
147179c65f3fSEvan Quan 
1472*936e95a4SGuchun Chen 		/*
1473*936e95a4SGuchun Chen 		 * dpm on some legacy asics don't carry od_enabled member
1474*936e95a4SGuchun Chen 		 * as its pp_handle is casted directly from adev.
1475*936e95a4SGuchun Chen 		 */
1476*936e95a4SGuchun Chen 		if (amdgpu_dpm_is_legacy_dpm(adev))
147779c65f3fSEvan Quan 			return false;
14789d7a348dSGuchun Chen 
14799d7a348dSGuchun Chen 		hwmgr = (struct pp_hwmgr *)adev->powerplay.pp_handle;
14809d7a348dSGuchun Chen 
14819d7a348dSGuchun Chen 		return hwmgr->od_enabled;
14829d7a348dSGuchun Chen 	}
148379c65f3fSEvan Quan }
148479c65f3fSEvan Quan 
amdgpu_dpm_set_pp_table(struct amdgpu_device * adev,const char * buf,size_t size)148579c65f3fSEvan Quan int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev,
148679c65f3fSEvan Quan 			    const char *buf,
148779c65f3fSEvan Quan 			    size_t size)
148879c65f3fSEvan Quan {
148979c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14903712e7a4SEvan Quan 	int ret = 0;
149179c65f3fSEvan Quan 
149279c65f3fSEvan Quan 	if (!pp_funcs->set_pp_table)
149379c65f3fSEvan Quan 		return -EOPNOTSUPP;
149479c65f3fSEvan Quan 
14953712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14963712e7a4SEvan Quan 	ret = pp_funcs->set_pp_table(adev->powerplay.pp_handle,
149779c65f3fSEvan Quan 				     buf,
149879c65f3fSEvan Quan 				     size);
14993712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
15003712e7a4SEvan Quan 
15013712e7a4SEvan Quan 	return ret;
150279c65f3fSEvan Quan }
150379c65f3fSEvan Quan 
amdgpu_dpm_get_num_cpu_cores(struct amdgpu_device * adev)150479c65f3fSEvan Quan int amdgpu_dpm_get_num_cpu_cores(struct amdgpu_device *adev)
150579c65f3fSEvan Quan {
1506ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
1507ebfc2533SEvan Quan 
15083712e7a4SEvan Quan 	if (!is_support_sw_smu(adev))
15093712e7a4SEvan Quan 		return INT_MAX;
15103712e7a4SEvan Quan 
1511ebfc2533SEvan Quan 	return smu->cpu_core_num;
151279c65f3fSEvan Quan }
151379c65f3fSEvan Quan 
amdgpu_dpm_stb_debug_fs_init(struct amdgpu_device * adev)151479c65f3fSEvan Quan void amdgpu_dpm_stb_debug_fs_init(struct amdgpu_device *adev)
151579c65f3fSEvan Quan {
151679c65f3fSEvan Quan 	if (!is_support_sw_smu(adev))
151779c65f3fSEvan Quan 		return;
151879c65f3fSEvan Quan 
151979c65f3fSEvan Quan 	amdgpu_smu_stb_debug_fs_init(adev);
152079c65f3fSEvan Quan }
152113f5dbd6SEvan Quan 
amdgpu_dpm_display_configuration_change(struct amdgpu_device * adev,const struct amd_pp_display_configuration * input)152213f5dbd6SEvan Quan int amdgpu_dpm_display_configuration_change(struct amdgpu_device *adev,
152313f5dbd6SEvan Quan 					    const struct amd_pp_display_configuration *input)
152413f5dbd6SEvan Quan {
152513f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15263712e7a4SEvan Quan 	int ret = 0;
152713f5dbd6SEvan Quan 
152813f5dbd6SEvan Quan 	if (!pp_funcs->display_configuration_change)
152913f5dbd6SEvan Quan 		return 0;
153013f5dbd6SEvan Quan 
15313712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
15323712e7a4SEvan Quan 	ret = pp_funcs->display_configuration_change(adev->powerplay.pp_handle,
153313f5dbd6SEvan Quan 						     input);
15343712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
15353712e7a4SEvan Quan 
15363712e7a4SEvan Quan 	return ret;
153713f5dbd6SEvan Quan }
153813f5dbd6SEvan Quan 
amdgpu_dpm_get_clock_by_type(struct amdgpu_device * adev,enum amd_pp_clock_type type,struct amd_pp_clocks * clocks)153913f5dbd6SEvan Quan int amdgpu_dpm_get_clock_by_type(struct amdgpu_device *adev,
154013f5dbd6SEvan Quan 				 enum amd_pp_clock_type type,
154113f5dbd6SEvan Quan 				 struct amd_pp_clocks *clocks)
154213f5dbd6SEvan Quan {
154313f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15443712e7a4SEvan Quan 	int ret = 0;
154513f5dbd6SEvan Quan 
154613f5dbd6SEvan Quan 	if (!pp_funcs->get_clock_by_type)
154713f5dbd6SEvan Quan 		return 0;
154813f5dbd6SEvan Quan 
15493712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
15503712e7a4SEvan Quan 	ret = pp_funcs->get_clock_by_type(adev->powerplay.pp_handle,
155113f5dbd6SEvan Quan 					  type,
155213f5dbd6SEvan Quan 					  clocks);
15533712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
15543712e7a4SEvan Quan 
15553712e7a4SEvan Quan 	return ret;
155613f5dbd6SEvan Quan }
155713f5dbd6SEvan Quan 
amdgpu_dpm_get_display_mode_validation_clks(struct amdgpu_device * adev,struct amd_pp_simple_clock_info * clocks)155813f5dbd6SEvan Quan int amdgpu_dpm_get_display_mode_validation_clks(struct amdgpu_device *adev,
155913f5dbd6SEvan Quan 						struct amd_pp_simple_clock_info *clocks)
156013f5dbd6SEvan Quan {
156113f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15623712e7a4SEvan Quan 	int ret = 0;
156313f5dbd6SEvan Quan 
156413f5dbd6SEvan Quan 	if (!pp_funcs->get_display_mode_validation_clocks)
156513f5dbd6SEvan Quan 		return 0;
156613f5dbd6SEvan Quan 
15673712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
15683712e7a4SEvan Quan 	ret = pp_funcs->get_display_mode_validation_clocks(adev->powerplay.pp_handle,
156913f5dbd6SEvan Quan 							   clocks);
15703712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
15713712e7a4SEvan Quan 
15723712e7a4SEvan Quan 	return ret;
157313f5dbd6SEvan Quan }
157413f5dbd6SEvan Quan 
amdgpu_dpm_get_clock_by_type_with_latency(struct amdgpu_device * adev,enum amd_pp_clock_type type,struct pp_clock_levels_with_latency * clocks)157513f5dbd6SEvan Quan int amdgpu_dpm_get_clock_by_type_with_latency(struct amdgpu_device *adev,
157613f5dbd6SEvan Quan 					      enum amd_pp_clock_type type,
157713f5dbd6SEvan Quan 					      struct pp_clock_levels_with_latency *clocks)
157813f5dbd6SEvan Quan {
157913f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15803712e7a4SEvan Quan 	int ret = 0;
158113f5dbd6SEvan Quan 
158213f5dbd6SEvan Quan 	if (!pp_funcs->get_clock_by_type_with_latency)
158313f5dbd6SEvan Quan 		return 0;
158413f5dbd6SEvan Quan 
15853712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
15863712e7a4SEvan Quan 	ret = pp_funcs->get_clock_by_type_with_latency(adev->powerplay.pp_handle,
158713f5dbd6SEvan Quan 						       type,
158813f5dbd6SEvan Quan 						       clocks);
15893712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
15903712e7a4SEvan Quan 
15913712e7a4SEvan Quan 	return ret;
159213f5dbd6SEvan Quan }
159313f5dbd6SEvan Quan 
amdgpu_dpm_get_clock_by_type_with_voltage(struct amdgpu_device * adev,enum amd_pp_clock_type type,struct pp_clock_levels_with_voltage * clocks)159413f5dbd6SEvan Quan int amdgpu_dpm_get_clock_by_type_with_voltage(struct amdgpu_device *adev,
159513f5dbd6SEvan Quan 					      enum amd_pp_clock_type type,
159613f5dbd6SEvan Quan 					      struct pp_clock_levels_with_voltage *clocks)
159713f5dbd6SEvan Quan {
159813f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15993712e7a4SEvan Quan 	int ret = 0;
160013f5dbd6SEvan Quan 
160113f5dbd6SEvan Quan 	if (!pp_funcs->get_clock_by_type_with_voltage)
160213f5dbd6SEvan Quan 		return 0;
160313f5dbd6SEvan Quan 
16043712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
16053712e7a4SEvan Quan 	ret = pp_funcs->get_clock_by_type_with_voltage(adev->powerplay.pp_handle,
160613f5dbd6SEvan Quan 						       type,
160713f5dbd6SEvan Quan 						       clocks);
16083712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
16093712e7a4SEvan Quan 
16103712e7a4SEvan Quan 	return ret;
161113f5dbd6SEvan Quan }
161213f5dbd6SEvan Quan 
amdgpu_dpm_set_watermarks_for_clocks_ranges(struct amdgpu_device * adev,void * clock_ranges)161313f5dbd6SEvan Quan int amdgpu_dpm_set_watermarks_for_clocks_ranges(struct amdgpu_device *adev,
161413f5dbd6SEvan Quan 					       void *clock_ranges)
161513f5dbd6SEvan Quan {
161613f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16173712e7a4SEvan Quan 	int ret = 0;
161813f5dbd6SEvan Quan 
161913f5dbd6SEvan Quan 	if (!pp_funcs->set_watermarks_for_clocks_ranges)
162013f5dbd6SEvan Quan 		return -EOPNOTSUPP;
162113f5dbd6SEvan Quan 
16223712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
16233712e7a4SEvan Quan 	ret = pp_funcs->set_watermarks_for_clocks_ranges(adev->powerplay.pp_handle,
162413f5dbd6SEvan Quan 							 clock_ranges);
16253712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
16263712e7a4SEvan Quan 
16273712e7a4SEvan Quan 	return ret;
162813f5dbd6SEvan Quan }
162913f5dbd6SEvan Quan 
amdgpu_dpm_display_clock_voltage_request(struct amdgpu_device * adev,struct pp_display_clock_request * clock)163013f5dbd6SEvan Quan int amdgpu_dpm_display_clock_voltage_request(struct amdgpu_device *adev,
163113f5dbd6SEvan Quan 					     struct pp_display_clock_request *clock)
163213f5dbd6SEvan Quan {
163313f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16343712e7a4SEvan Quan 	int ret = 0;
163513f5dbd6SEvan Quan 
163613f5dbd6SEvan Quan 	if (!pp_funcs->display_clock_voltage_request)
163713f5dbd6SEvan Quan 		return -EOPNOTSUPP;
163813f5dbd6SEvan Quan 
16393712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
16403712e7a4SEvan Quan 	ret = pp_funcs->display_clock_voltage_request(adev->powerplay.pp_handle,
164113f5dbd6SEvan Quan 						      clock);
16423712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
16433712e7a4SEvan Quan 
16443712e7a4SEvan Quan 	return ret;
164513f5dbd6SEvan Quan }
164613f5dbd6SEvan Quan 
amdgpu_dpm_get_current_clocks(struct amdgpu_device * adev,struct amd_pp_clock_info * clocks)164713f5dbd6SEvan Quan int amdgpu_dpm_get_current_clocks(struct amdgpu_device *adev,
164813f5dbd6SEvan Quan 				  struct amd_pp_clock_info *clocks)
164913f5dbd6SEvan Quan {
165013f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16513712e7a4SEvan Quan 	int ret = 0;
165213f5dbd6SEvan Quan 
165313f5dbd6SEvan Quan 	if (!pp_funcs->get_current_clocks)
165413f5dbd6SEvan Quan 		return -EOPNOTSUPP;
165513f5dbd6SEvan Quan 
16563712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
16573712e7a4SEvan Quan 	ret = pp_funcs->get_current_clocks(adev->powerplay.pp_handle,
165813f5dbd6SEvan Quan 					   clocks);
16593712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
16603712e7a4SEvan Quan 
16613712e7a4SEvan Quan 	return ret;
166213f5dbd6SEvan Quan }
166313f5dbd6SEvan Quan 
amdgpu_dpm_notify_smu_enable_pwe(struct amdgpu_device * adev)166413f5dbd6SEvan Quan void amdgpu_dpm_notify_smu_enable_pwe(struct amdgpu_device *adev)
166513f5dbd6SEvan Quan {
166613f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
166713f5dbd6SEvan Quan 
166813f5dbd6SEvan Quan 	if (!pp_funcs->notify_smu_enable_pwe)
166913f5dbd6SEvan Quan 		return;
167013f5dbd6SEvan Quan 
16713712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
167213f5dbd6SEvan Quan 	pp_funcs->notify_smu_enable_pwe(adev->powerplay.pp_handle);
16733712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
167413f5dbd6SEvan Quan }
167513f5dbd6SEvan Quan 
amdgpu_dpm_set_active_display_count(struct amdgpu_device * adev,uint32_t count)167613f5dbd6SEvan Quan int amdgpu_dpm_set_active_display_count(struct amdgpu_device *adev,
167713f5dbd6SEvan Quan 					uint32_t count)
167813f5dbd6SEvan Quan {
167913f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16803712e7a4SEvan Quan 	int ret = 0;
168113f5dbd6SEvan Quan 
168213f5dbd6SEvan Quan 	if (!pp_funcs->set_active_display_count)
168313f5dbd6SEvan Quan 		return -EOPNOTSUPP;
168413f5dbd6SEvan Quan 
16853712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
16863712e7a4SEvan Quan 	ret = pp_funcs->set_active_display_count(adev->powerplay.pp_handle,
168713f5dbd6SEvan Quan 						 count);
16883712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
16893712e7a4SEvan Quan 
16903712e7a4SEvan Quan 	return ret;
169113f5dbd6SEvan Quan }
169213f5dbd6SEvan Quan 
amdgpu_dpm_set_min_deep_sleep_dcefclk(struct amdgpu_device * adev,uint32_t clock)169313f5dbd6SEvan Quan int amdgpu_dpm_set_min_deep_sleep_dcefclk(struct amdgpu_device *adev,
169413f5dbd6SEvan Quan 					  uint32_t clock)
169513f5dbd6SEvan Quan {
169613f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16973712e7a4SEvan Quan 	int ret = 0;
169813f5dbd6SEvan Quan 
169913f5dbd6SEvan Quan 	if (!pp_funcs->set_min_deep_sleep_dcefclk)
170013f5dbd6SEvan Quan 		return -EOPNOTSUPP;
170113f5dbd6SEvan Quan 
17023712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
17033712e7a4SEvan Quan 	ret = pp_funcs->set_min_deep_sleep_dcefclk(adev->powerplay.pp_handle,
170413f5dbd6SEvan Quan 						   clock);
17053712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
17063712e7a4SEvan Quan 
17073712e7a4SEvan Quan 	return ret;
170813f5dbd6SEvan Quan }
170913f5dbd6SEvan Quan 
amdgpu_dpm_set_hard_min_dcefclk_by_freq(struct amdgpu_device * adev,uint32_t clock)171013f5dbd6SEvan Quan void amdgpu_dpm_set_hard_min_dcefclk_by_freq(struct amdgpu_device *adev,
171113f5dbd6SEvan Quan 					     uint32_t clock)
171213f5dbd6SEvan Quan {
171313f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
171413f5dbd6SEvan Quan 
171513f5dbd6SEvan Quan 	if (!pp_funcs->set_hard_min_dcefclk_by_freq)
171613f5dbd6SEvan Quan 		return;
171713f5dbd6SEvan Quan 
17183712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
171913f5dbd6SEvan Quan 	pp_funcs->set_hard_min_dcefclk_by_freq(adev->powerplay.pp_handle,
172013f5dbd6SEvan Quan 					       clock);
17213712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
172213f5dbd6SEvan Quan }
172313f5dbd6SEvan Quan 
amdgpu_dpm_set_hard_min_fclk_by_freq(struct amdgpu_device * adev,uint32_t clock)172413f5dbd6SEvan Quan void amdgpu_dpm_set_hard_min_fclk_by_freq(struct amdgpu_device *adev,
172513f5dbd6SEvan Quan 					  uint32_t clock)
172613f5dbd6SEvan Quan {
172713f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
172813f5dbd6SEvan Quan 
172913f5dbd6SEvan Quan 	if (!pp_funcs->set_hard_min_fclk_by_freq)
173013f5dbd6SEvan Quan 		return;
173113f5dbd6SEvan Quan 
17323712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
173313f5dbd6SEvan Quan 	pp_funcs->set_hard_min_fclk_by_freq(adev->powerplay.pp_handle,
173413f5dbd6SEvan Quan 					    clock);
17353712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
173613f5dbd6SEvan Quan }
173713f5dbd6SEvan Quan 
amdgpu_dpm_display_disable_memory_clock_switch(struct amdgpu_device * adev,bool disable_memory_clock_switch)173813f5dbd6SEvan Quan int amdgpu_dpm_display_disable_memory_clock_switch(struct amdgpu_device *adev,
173913f5dbd6SEvan Quan 						   bool disable_memory_clock_switch)
174013f5dbd6SEvan Quan {
174113f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
17423712e7a4SEvan Quan 	int ret = 0;
174313f5dbd6SEvan Quan 
174413f5dbd6SEvan Quan 	if (!pp_funcs->display_disable_memory_clock_switch)
174513f5dbd6SEvan Quan 		return 0;
174613f5dbd6SEvan Quan 
17473712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
17483712e7a4SEvan Quan 	ret = pp_funcs->display_disable_memory_clock_switch(adev->powerplay.pp_handle,
174913f5dbd6SEvan Quan 							    disable_memory_clock_switch);
17503712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
17513712e7a4SEvan Quan 
17523712e7a4SEvan Quan 	return ret;
175313f5dbd6SEvan Quan }
175413f5dbd6SEvan Quan 
amdgpu_dpm_get_max_sustainable_clocks_by_dc(struct amdgpu_device * adev,struct pp_smu_nv_clock_table * max_clocks)175513f5dbd6SEvan Quan int amdgpu_dpm_get_max_sustainable_clocks_by_dc(struct amdgpu_device *adev,
175613f5dbd6SEvan Quan 						struct pp_smu_nv_clock_table *max_clocks)
175713f5dbd6SEvan Quan {
175813f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
17593712e7a4SEvan Quan 	int ret = 0;
176013f5dbd6SEvan Quan 
176113f5dbd6SEvan Quan 	if (!pp_funcs->get_max_sustainable_clocks_by_dc)
176213f5dbd6SEvan Quan 		return -EOPNOTSUPP;
176313f5dbd6SEvan Quan 
17643712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
17653712e7a4SEvan Quan 	ret = pp_funcs->get_max_sustainable_clocks_by_dc(adev->powerplay.pp_handle,
176613f5dbd6SEvan Quan 							 max_clocks);
17673712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
17683712e7a4SEvan Quan 
17693712e7a4SEvan Quan 	return ret;
177013f5dbd6SEvan Quan }
177113f5dbd6SEvan Quan 
amdgpu_dpm_get_uclk_dpm_states(struct amdgpu_device * adev,unsigned int * clock_values_in_khz,unsigned int * num_states)177213f5dbd6SEvan Quan enum pp_smu_status amdgpu_dpm_get_uclk_dpm_states(struct amdgpu_device *adev,
177313f5dbd6SEvan Quan 						  unsigned int *clock_values_in_khz,
177413f5dbd6SEvan Quan 						  unsigned int *num_states)
177513f5dbd6SEvan Quan {
177613f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
17773712e7a4SEvan Quan 	int ret = 0;
177813f5dbd6SEvan Quan 
177913f5dbd6SEvan Quan 	if (!pp_funcs->get_uclk_dpm_states)
178013f5dbd6SEvan Quan 		return -EOPNOTSUPP;
178113f5dbd6SEvan Quan 
17823712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
17833712e7a4SEvan Quan 	ret = pp_funcs->get_uclk_dpm_states(adev->powerplay.pp_handle,
178413f5dbd6SEvan Quan 					    clock_values_in_khz,
178513f5dbd6SEvan Quan 					    num_states);
17863712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
17873712e7a4SEvan Quan 
17883712e7a4SEvan Quan 	return ret;
178913f5dbd6SEvan Quan }
179013f5dbd6SEvan Quan 
amdgpu_dpm_get_dpm_clock_table(struct amdgpu_device * adev,struct dpm_clocks * clock_table)179113f5dbd6SEvan Quan int amdgpu_dpm_get_dpm_clock_table(struct amdgpu_device *adev,
179213f5dbd6SEvan Quan 				   struct dpm_clocks *clock_table)
179313f5dbd6SEvan Quan {
179413f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
17953712e7a4SEvan Quan 	int ret = 0;
179613f5dbd6SEvan Quan 
179713f5dbd6SEvan Quan 	if (!pp_funcs->get_dpm_clock_table)
179813f5dbd6SEvan Quan 		return -EOPNOTSUPP;
179913f5dbd6SEvan Quan 
18003712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
18013712e7a4SEvan Quan 	ret = pp_funcs->get_dpm_clock_table(adev->powerplay.pp_handle,
180213f5dbd6SEvan Quan 					    clock_table);
18033712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
18043712e7a4SEvan Quan 
18053712e7a4SEvan Quan 	return ret;
180613f5dbd6SEvan Quan }
1807