xref: /openbmc/linux/drivers/gpu/drm/amd/pm/amdgpu_dpm.c (revision 93dde6cc)
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 
39e098bc96SEvan Quan int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low)
40e098bc96SEvan Quan {
41bc7d6c12SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
423712e7a4SEvan Quan 	int ret = 0;
43e098bc96SEvan Quan 
443712e7a4SEvan Quan 	if (!pp_funcs->get_sclk)
453712e7a4SEvan Quan 		return 0;
463712e7a4SEvan Quan 
473712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
483712e7a4SEvan Quan 	ret = pp_funcs->get_sclk((adev)->powerplay.pp_handle,
493712e7a4SEvan Quan 				 low);
503712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
513712e7a4SEvan Quan 
523712e7a4SEvan Quan 	return ret;
53e098bc96SEvan Quan }
54e098bc96SEvan Quan 
55e098bc96SEvan Quan int amdgpu_dpm_get_mclk(struct amdgpu_device *adev, bool low)
56e098bc96SEvan Quan {
57bc7d6c12SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
583712e7a4SEvan Quan 	int ret = 0;
59e098bc96SEvan Quan 
603712e7a4SEvan Quan 	if (!pp_funcs->get_mclk)
613712e7a4SEvan Quan 		return 0;
623712e7a4SEvan Quan 
633712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
643712e7a4SEvan Quan 	ret = pp_funcs->get_mclk((adev)->powerplay.pp_handle,
653712e7a4SEvan Quan 				 low);
663712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
673712e7a4SEvan Quan 
683712e7a4SEvan Quan 	return ret;
69e098bc96SEvan Quan }
70e098bc96SEvan Quan 
71e098bc96SEvan Quan int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block_type, bool gate)
72e098bc96SEvan Quan {
73e098bc96SEvan Quan 	int ret = 0;
74bc7d6c12SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
756ee27ee2SEvan Quan 	enum ip_power_state pwr_state = gate ? POWER_STATE_OFF : POWER_STATE_ON;
766ee27ee2SEvan Quan 
776ee27ee2SEvan Quan 	if (atomic_read(&adev->pm.pwr_state[block_type]) == pwr_state) {
786ee27ee2SEvan Quan 		dev_dbg(adev->dev, "IP block%d already in the target %s state!",
796ee27ee2SEvan Quan 				block_type, gate ? "gate" : "ungate");
806ee27ee2SEvan Quan 		return 0;
816ee27ee2SEvan Quan 	}
82e098bc96SEvan Quan 
833712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
843712e7a4SEvan Quan 
85e098bc96SEvan Quan 	switch (block_type) {
86e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_UVD:
87e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_VCE:
88e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_GFX:
89e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_VCN:
90e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_SDMA:
91e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_JPEG:
92e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_GMC:
93e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_ACP:
943712e7a4SEvan Quan 		if (pp_funcs && pp_funcs->set_powergating_by_smu)
95bc7d6c12SDarren Powell 			ret = (pp_funcs->set_powergating_by_smu(
96e098bc96SEvan Quan 				(adev)->powerplay.pp_handle, block_type, gate));
97e098bc96SEvan Quan 		break;
98e098bc96SEvan Quan 	default:
99e098bc96SEvan Quan 		break;
100e098bc96SEvan Quan 	}
101e098bc96SEvan Quan 
1026ee27ee2SEvan Quan 	if (!ret)
1036ee27ee2SEvan Quan 		atomic_set(&adev->pm.pwr_state[block_type], pwr_state);
1046ee27ee2SEvan Quan 
1053712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
1063712e7a4SEvan Quan 
107e098bc96SEvan Quan 	return ret;
108e098bc96SEvan Quan }
109e098bc96SEvan Quan 
110e098bc96SEvan Quan int amdgpu_dpm_baco_enter(struct amdgpu_device *adev)
111e098bc96SEvan Quan {
112e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
113e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
114e098bc96SEvan Quan 	int ret = 0;
115e098bc96SEvan Quan 
116e098bc96SEvan Quan 	if (!pp_funcs || !pp_funcs->set_asic_baco_state)
117e098bc96SEvan Quan 		return -ENOENT;
118e098bc96SEvan Quan 
1193712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
1203712e7a4SEvan Quan 
121e098bc96SEvan Quan 	/* enter BACO state */
122e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
123e098bc96SEvan Quan 
1243712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
1253712e7a4SEvan Quan 
126e098bc96SEvan Quan 	return ret;
127e098bc96SEvan Quan }
128e098bc96SEvan Quan 
129e098bc96SEvan Quan int amdgpu_dpm_baco_exit(struct amdgpu_device *adev)
130e098bc96SEvan Quan {
131e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
132e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
133e098bc96SEvan Quan 	int ret = 0;
134e098bc96SEvan Quan 
135e098bc96SEvan Quan 	if (!pp_funcs || !pp_funcs->set_asic_baco_state)
136e098bc96SEvan Quan 		return -ENOENT;
137e098bc96SEvan Quan 
1383712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
1393712e7a4SEvan Quan 
140e098bc96SEvan Quan 	/* exit BACO state */
141e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
142e098bc96SEvan Quan 
1433712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
1443712e7a4SEvan Quan 
145e098bc96SEvan Quan 	return ret;
146e098bc96SEvan Quan }
147e098bc96SEvan Quan 
148e098bc96SEvan Quan int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
149e098bc96SEvan Quan 			     enum pp_mp1_state mp1_state)
150e098bc96SEvan Quan {
151e098bc96SEvan Quan 	int ret = 0;
152bab0f602SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
153e098bc96SEvan Quan 
154bab0f602SDarren Powell 	if (pp_funcs && pp_funcs->set_mp1_state) {
1553712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
1563712e7a4SEvan Quan 
157bab0f602SDarren Powell 		ret = pp_funcs->set_mp1_state(
158e098bc96SEvan Quan 				adev->powerplay.pp_handle,
159e098bc96SEvan Quan 				mp1_state);
1603712e7a4SEvan Quan 
1613712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
162e098bc96SEvan Quan 	}
163e098bc96SEvan Quan 
164e098bc96SEvan Quan 	return ret;
165e098bc96SEvan Quan }
166e098bc96SEvan Quan 
167e098bc96SEvan Quan bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev)
168e098bc96SEvan Quan {
169e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
170e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
171e098bc96SEvan Quan 	bool baco_cap;
1723712e7a4SEvan Quan 	int ret = 0;
173e098bc96SEvan Quan 
174e098bc96SEvan Quan 	if (!pp_funcs || !pp_funcs->get_asic_baco_capability)
175e098bc96SEvan Quan 		return false;
176e098bc96SEvan Quan 
1773712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
178e098bc96SEvan Quan 
1793712e7a4SEvan Quan 	ret = pp_funcs->get_asic_baco_capability(pp_handle,
1803712e7a4SEvan Quan 						 &baco_cap);
1813712e7a4SEvan Quan 
1823712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
1833712e7a4SEvan Quan 
1843712e7a4SEvan Quan 	return ret ? false : baco_cap;
185e098bc96SEvan Quan }
186e098bc96SEvan Quan 
187e098bc96SEvan Quan int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev)
188e098bc96SEvan Quan {
189e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
190e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
1913712e7a4SEvan Quan 	int ret = 0;
192e098bc96SEvan Quan 
193e098bc96SEvan Quan 	if (!pp_funcs || !pp_funcs->asic_reset_mode_2)
194e098bc96SEvan Quan 		return -ENOENT;
195e098bc96SEvan Quan 
1963712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
1973712e7a4SEvan Quan 
1983712e7a4SEvan Quan 	ret = pp_funcs->asic_reset_mode_2(pp_handle);
1993712e7a4SEvan Quan 
2003712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
2013712e7a4SEvan Quan 
2023712e7a4SEvan Quan 	return ret;
203e098bc96SEvan Quan }
204e098bc96SEvan Quan 
205e098bc96SEvan Quan int amdgpu_dpm_baco_reset(struct amdgpu_device *adev)
206e098bc96SEvan Quan {
207e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
208e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
209e098bc96SEvan Quan 	int ret = 0;
210e098bc96SEvan Quan 
2119ab5001aSDarren Powell 	if (!pp_funcs || !pp_funcs->set_asic_baco_state)
212e098bc96SEvan Quan 		return -ENOENT;
213e098bc96SEvan Quan 
2143712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
2153712e7a4SEvan Quan 
216e098bc96SEvan Quan 	/* enter BACO state */
217e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
218e098bc96SEvan Quan 	if (ret)
2193712e7a4SEvan Quan 		goto out;
220e098bc96SEvan Quan 
221e098bc96SEvan Quan 	/* exit BACO state */
222e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
223e098bc96SEvan Quan 
2243712e7a4SEvan Quan out:
2253712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
2263712e7a4SEvan Quan 	return ret;
227e098bc96SEvan Quan }
228e098bc96SEvan Quan 
229e098bc96SEvan Quan bool amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device *adev)
230e098bc96SEvan Quan {
231ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
2323712e7a4SEvan Quan 	bool support_mode1_reset = false;
233e098bc96SEvan Quan 
2343712e7a4SEvan Quan 	if (is_support_sw_smu(adev)) {
2353712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
2363712e7a4SEvan Quan 		support_mode1_reset = smu_mode1_reset_is_support(smu);
2373712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
2383712e7a4SEvan Quan 	}
239e098bc96SEvan Quan 
2403712e7a4SEvan Quan 	return support_mode1_reset;
241e098bc96SEvan Quan }
242e098bc96SEvan Quan 
243e098bc96SEvan Quan int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev)
244e098bc96SEvan Quan {
245ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
2463712e7a4SEvan Quan 	int ret = -EOPNOTSUPP;
247e098bc96SEvan Quan 
2483712e7a4SEvan Quan 	if (is_support_sw_smu(adev)) {
2493712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
2503712e7a4SEvan Quan 		ret = smu_mode1_reset(smu);
2513712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
2523712e7a4SEvan Quan 	}
253e098bc96SEvan Quan 
2543712e7a4SEvan Quan 	return ret;
255e098bc96SEvan Quan }
256e098bc96SEvan Quan 
257e098bc96SEvan Quan int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
258e098bc96SEvan Quan 				    enum PP_SMC_POWER_PROFILE type,
259e098bc96SEvan Quan 				    bool en)
260e098bc96SEvan Quan {
261bab0f602SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
262e098bc96SEvan Quan 	int ret = 0;
263e098bc96SEvan Quan 
2647cf7a392SJingwen Chen 	if (amdgpu_sriov_vf(adev))
2657cf7a392SJingwen Chen 		return 0;
2667cf7a392SJingwen Chen 
2673712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->switch_power_profile) {
2683712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
269bab0f602SDarren Powell 		ret = pp_funcs->switch_power_profile(
270e098bc96SEvan Quan 			adev->powerplay.pp_handle, type, en);
2713712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
2723712e7a4SEvan Quan 	}
273e098bc96SEvan Quan 
274e098bc96SEvan Quan 	return ret;
275e098bc96SEvan Quan }
276e098bc96SEvan Quan 
277e098bc96SEvan Quan int amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device *adev,
278e098bc96SEvan Quan 			       uint32_t pstate)
279e098bc96SEvan Quan {
280bab0f602SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
281e098bc96SEvan Quan 	int ret = 0;
282e098bc96SEvan Quan 
2833712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->set_xgmi_pstate) {
2843712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
285bab0f602SDarren Powell 		ret = pp_funcs->set_xgmi_pstate(adev->powerplay.pp_handle,
286e098bc96SEvan Quan 								pstate);
2873712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
2883712e7a4SEvan Quan 	}
289e098bc96SEvan Quan 
290e098bc96SEvan Quan 	return ret;
291e098bc96SEvan Quan }
292e098bc96SEvan Quan 
293e098bc96SEvan Quan int amdgpu_dpm_set_df_cstate(struct amdgpu_device *adev,
294e098bc96SEvan Quan 			     uint32_t cstate)
295e098bc96SEvan Quan {
296e098bc96SEvan Quan 	int ret = 0;
297e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
298e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
299e098bc96SEvan Quan 
3003712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->set_df_cstate) {
3013712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
302e098bc96SEvan Quan 		ret = pp_funcs->set_df_cstate(pp_handle, cstate);
3033712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3043712e7a4SEvan Quan 	}
305e098bc96SEvan Quan 
306e098bc96SEvan Quan 	return ret;
307e098bc96SEvan Quan }
308e098bc96SEvan Quan 
309e098bc96SEvan Quan int amdgpu_dpm_allow_xgmi_power_down(struct amdgpu_device *adev, bool en)
310e098bc96SEvan Quan {
311ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
3123712e7a4SEvan Quan 	int ret = 0;
313e098bc96SEvan Quan 
3143712e7a4SEvan Quan 	if (is_support_sw_smu(adev)) {
3153712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
3163712e7a4SEvan Quan 		ret = smu_allow_xgmi_power_down(smu, en);
3173712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3183712e7a4SEvan Quan 	}
319e098bc96SEvan Quan 
3203712e7a4SEvan Quan 	return ret;
321e098bc96SEvan Quan }
322e098bc96SEvan Quan 
323e098bc96SEvan Quan int amdgpu_dpm_enable_mgpu_fan_boost(struct amdgpu_device *adev)
324e098bc96SEvan Quan {
325e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
326e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs =
327e098bc96SEvan Quan 			adev->powerplay.pp_funcs;
328e098bc96SEvan Quan 	int ret = 0;
329e098bc96SEvan Quan 
3303712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->enable_mgpu_fan_boost) {
3313712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
332e098bc96SEvan Quan 		ret = pp_funcs->enable_mgpu_fan_boost(pp_handle);
3333712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3343712e7a4SEvan Quan 	}
335e098bc96SEvan Quan 
336e098bc96SEvan Quan 	return ret;
337e098bc96SEvan Quan }
338e098bc96SEvan Quan 
339e098bc96SEvan Quan int amdgpu_dpm_set_clockgating_by_smu(struct amdgpu_device *adev,
340e098bc96SEvan Quan 				      uint32_t msg_id)
341e098bc96SEvan Quan {
342e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
343e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs =
344e098bc96SEvan Quan 			adev->powerplay.pp_funcs;
345e098bc96SEvan Quan 	int ret = 0;
346e098bc96SEvan Quan 
3473712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->set_clockgating_by_smu) {
3483712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
349e098bc96SEvan Quan 		ret = pp_funcs->set_clockgating_by_smu(pp_handle,
350e098bc96SEvan Quan 						       msg_id);
3513712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3523712e7a4SEvan Quan 	}
353e098bc96SEvan Quan 
354e098bc96SEvan Quan 	return ret;
355e098bc96SEvan Quan }
356e098bc96SEvan Quan 
357e098bc96SEvan Quan int amdgpu_dpm_smu_i2c_bus_access(struct amdgpu_device *adev,
358e098bc96SEvan Quan 				  bool acquire)
359e098bc96SEvan Quan {
360e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
361e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs =
362e098bc96SEvan Quan 			adev->powerplay.pp_funcs;
363e098bc96SEvan Quan 	int ret = -EOPNOTSUPP;
364e098bc96SEvan Quan 
3653712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->smu_i2c_bus_access) {
3663712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
367e098bc96SEvan Quan 		ret = pp_funcs->smu_i2c_bus_access(pp_handle,
368e098bc96SEvan Quan 						   acquire);
3693712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3703712e7a4SEvan Quan 	}
371e098bc96SEvan Quan 
372e098bc96SEvan Quan 	return ret;
373e098bc96SEvan Quan }
374e098bc96SEvan Quan 
375e098bc96SEvan Quan void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev)
376e098bc96SEvan Quan {
377e098bc96SEvan Quan 	if (adev->pm.dpm_enabled) {
378e098bc96SEvan Quan 		mutex_lock(&adev->pm.mutex);
379e098bc96SEvan Quan 		if (power_supply_is_system_supplied() > 0)
380e098bc96SEvan Quan 			adev->pm.ac_power = true;
381e098bc96SEvan Quan 		else
382e098bc96SEvan Quan 			adev->pm.ac_power = false;
3833712e7a4SEvan Quan 
384e098bc96SEvan Quan 		if (adev->powerplay.pp_funcs &&
385e098bc96SEvan Quan 		    adev->powerplay.pp_funcs->enable_bapm)
386e098bc96SEvan Quan 			amdgpu_dpm_enable_bapm(adev, adev->pm.ac_power);
387e098bc96SEvan Quan 
388e098bc96SEvan Quan 		if (is_support_sw_smu(adev))
389ebfc2533SEvan Quan 			smu_set_ac_dc(adev->powerplay.pp_handle);
3903712e7a4SEvan Quan 
3913712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
392e098bc96SEvan Quan 	}
393e098bc96SEvan Quan }
394e098bc96SEvan Quan 
395e098bc96SEvan Quan int amdgpu_dpm_read_sensor(struct amdgpu_device *adev, enum amd_pp_sensors sensor,
396e098bc96SEvan Quan 			   void *data, uint32_t *size)
397e098bc96SEvan Quan {
3989ab5001aSDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
3993712e7a4SEvan Quan 	int ret = -EINVAL;
400e098bc96SEvan Quan 
401e098bc96SEvan Quan 	if (!data || !size)
402e098bc96SEvan Quan 		return -EINVAL;
403e098bc96SEvan Quan 
4043712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->read_sensor) {
4053712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
4063712e7a4SEvan Quan 		ret = pp_funcs->read_sensor(adev->powerplay.pp_handle,
4073712e7a4SEvan Quan 					    sensor,
4083712e7a4SEvan Quan 					    data,
4093712e7a4SEvan Quan 					    size);
4103712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
4113712e7a4SEvan Quan 	}
412e098bc96SEvan Quan 
413e098bc96SEvan Quan 	return ret;
414e098bc96SEvan Quan }
415e098bc96SEvan Quan 
41684176663SEvan Quan void amdgpu_dpm_compute_clocks(struct amdgpu_device *adev)
417e098bc96SEvan Quan {
4186ddbd37fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
419e098bc96SEvan Quan 
420e098bc96SEvan Quan 	if (!adev->pm.dpm_enabled)
421e098bc96SEvan Quan 		return;
422e098bc96SEvan Quan 
4236ddbd37fSEvan Quan 	if (!pp_funcs->pm_compute_clocks)
4246ddbd37fSEvan Quan 		return;
425e098bc96SEvan Quan 
4263712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
4276ddbd37fSEvan Quan 	pp_funcs->pm_compute_clocks(adev->powerplay.pp_handle);
4283712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
429e098bc96SEvan Quan }
430e098bc96SEvan Quan 
431e098bc96SEvan Quan void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
432e098bc96SEvan Quan {
433e098bc96SEvan Quan 	int ret = 0;
434e098bc96SEvan Quan 
435e098bc96SEvan Quan 	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable);
436e098bc96SEvan Quan 	if (ret)
437e098bc96SEvan Quan 		DRM_ERROR("Dpm %s uvd failed, ret = %d. \n",
438e098bc96SEvan Quan 			  enable ? "enable" : "disable", ret);
439e098bc96SEvan Quan }
440e098bc96SEvan Quan 
441e098bc96SEvan Quan void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
442e098bc96SEvan Quan {
443e098bc96SEvan Quan 	int ret = 0;
444e098bc96SEvan Quan 
445e098bc96SEvan Quan 	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable);
446e098bc96SEvan Quan 	if (ret)
447e098bc96SEvan Quan 		DRM_ERROR("Dpm %s vce failed, ret = %d. \n",
448e098bc96SEvan Quan 			  enable ? "enable" : "disable", ret);
449e098bc96SEvan Quan }
450e098bc96SEvan Quan 
451e098bc96SEvan Quan void amdgpu_dpm_enable_jpeg(struct amdgpu_device *adev, bool enable)
452e098bc96SEvan Quan {
453e098bc96SEvan Quan 	int ret = 0;
454e098bc96SEvan Quan 
455e098bc96SEvan Quan 	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_JPEG, !enable);
456e098bc96SEvan Quan 	if (ret)
457e098bc96SEvan Quan 		DRM_ERROR("Dpm %s jpeg failed, ret = %d. \n",
458e098bc96SEvan Quan 			  enable ? "enable" : "disable", ret);
459e098bc96SEvan Quan }
460e098bc96SEvan Quan 
461e098bc96SEvan Quan int amdgpu_pm_load_smu_firmware(struct amdgpu_device *adev, uint32_t *smu_version)
462e098bc96SEvan Quan {
4633712e7a4SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
4643712e7a4SEvan Quan 	int r = 0;
465e098bc96SEvan Quan 
4661613f346SFlora Cui 	if (!pp_funcs || !pp_funcs->load_firmware)
4673712e7a4SEvan Quan 		return 0;
4683712e7a4SEvan Quan 
4693712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
4703712e7a4SEvan Quan 	r = pp_funcs->load_firmware(adev->powerplay.pp_handle);
471e098bc96SEvan Quan 	if (r) {
472e098bc96SEvan Quan 		pr_err("smu firmware loading failed\n");
4733712e7a4SEvan Quan 		goto out;
474e098bc96SEvan Quan 	}
4752e4b2f7bSEvan Quan 
4762e4b2f7bSEvan Quan 	if (smu_version)
477e098bc96SEvan Quan 		*smu_version = adev->pm.fw_version;
4782e4b2f7bSEvan Quan 
4793712e7a4SEvan Quan out:
4803712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
4813712e7a4SEvan Quan 	return r;
482e098bc96SEvan Quan }
483bc143d8bSEvan Quan 
484bc143d8bSEvan Quan int amdgpu_dpm_handle_passthrough_sbr(struct amdgpu_device *adev, bool enable)
485bc143d8bSEvan Quan {
4863712e7a4SEvan Quan 	int ret = 0;
4873712e7a4SEvan Quan 
4883712e7a4SEvan Quan 	if (is_support_sw_smu(adev)) {
4893712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
4903712e7a4SEvan Quan 		ret = smu_handle_passthrough_sbr(adev->powerplay.pp_handle,
4913712e7a4SEvan Quan 						 enable);
4923712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
4933712e7a4SEvan Quan 	}
4943712e7a4SEvan Quan 
4953712e7a4SEvan Quan 	return ret;
496bc143d8bSEvan Quan }
497bc143d8bSEvan Quan 
498bc143d8bSEvan Quan int amdgpu_dpm_send_hbm_bad_pages_num(struct amdgpu_device *adev, uint32_t size)
499bc143d8bSEvan Quan {
500ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
5013712e7a4SEvan Quan 	int ret = 0;
502ebfc2533SEvan Quan 
503*93dde6ccSStanley.Yang 	if (!is_support_sw_smu(adev))
504*93dde6ccSStanley.Yang 		return -EOPNOTSUPP;
505*93dde6ccSStanley.Yang 
5063712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
5073712e7a4SEvan Quan 	ret = smu_send_hbm_bad_pages_num(smu, size);
5083712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
5093712e7a4SEvan Quan 
5103712e7a4SEvan Quan 	return ret;
511bc143d8bSEvan Quan }
512bc143d8bSEvan Quan 
513d510eccfSStanley.Yang int amdgpu_dpm_send_hbm_bad_channel_flag(struct amdgpu_device *adev, uint32_t size)
514d510eccfSStanley.Yang {
515d510eccfSStanley.Yang 	struct smu_context *smu = adev->powerplay.pp_handle;
516d510eccfSStanley.Yang 	int ret = 0;
517d510eccfSStanley.Yang 
518*93dde6ccSStanley.Yang 	if (!is_support_sw_smu(adev))
519*93dde6ccSStanley.Yang 		return -EOPNOTSUPP;
520*93dde6ccSStanley.Yang 
521d510eccfSStanley.Yang 	mutex_lock(&adev->pm.mutex);
522d510eccfSStanley.Yang 	ret = smu_send_hbm_bad_channel_flag(smu, size);
523d510eccfSStanley.Yang 	mutex_unlock(&adev->pm.mutex);
524d510eccfSStanley.Yang 
525d510eccfSStanley.Yang 	return ret;
526d510eccfSStanley.Yang }
527d510eccfSStanley.Yang 
528bc143d8bSEvan Quan int amdgpu_dpm_get_dpm_freq_range(struct amdgpu_device *adev,
529bc143d8bSEvan Quan 				  enum pp_clock_type type,
530bc143d8bSEvan Quan 				  uint32_t *min,
531bc143d8bSEvan Quan 				  uint32_t *max)
532bc143d8bSEvan Quan {
5333712e7a4SEvan Quan 	int ret = 0;
5343712e7a4SEvan Quan 
5353712e7a4SEvan Quan 	if (type != PP_SCLK)
5363712e7a4SEvan Quan 		return -EINVAL;
5373712e7a4SEvan Quan 
538bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
539bc143d8bSEvan Quan 		return -EOPNOTSUPP;
540bc143d8bSEvan Quan 
5413712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
5423712e7a4SEvan Quan 	ret = smu_get_dpm_freq_range(adev->powerplay.pp_handle,
5433712e7a4SEvan Quan 				     SMU_SCLK,
5443712e7a4SEvan Quan 				     min,
5453712e7a4SEvan Quan 				     max);
5463712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
5473712e7a4SEvan Quan 
5483712e7a4SEvan Quan 	return ret;
549bc143d8bSEvan Quan }
550bc143d8bSEvan Quan 
551bc143d8bSEvan Quan int amdgpu_dpm_set_soft_freq_range(struct amdgpu_device *adev,
552bc143d8bSEvan Quan 				   enum pp_clock_type type,
553bc143d8bSEvan Quan 				   uint32_t min,
554bc143d8bSEvan Quan 				   uint32_t max)
555bc143d8bSEvan Quan {
556ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
5573712e7a4SEvan Quan 	int ret = 0;
5583712e7a4SEvan Quan 
5593712e7a4SEvan Quan 	if (type != PP_SCLK)
5603712e7a4SEvan Quan 		return -EINVAL;
561ebfc2533SEvan Quan 
562bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
563bc143d8bSEvan Quan 		return -EOPNOTSUPP;
564bc143d8bSEvan Quan 
5653712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
5663712e7a4SEvan Quan 	ret = smu_set_soft_freq_range(smu,
5673712e7a4SEvan Quan 				      SMU_SCLK,
5683712e7a4SEvan Quan 				      min,
5693712e7a4SEvan Quan 				      max);
5703712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
5713712e7a4SEvan Quan 
5723712e7a4SEvan Quan 	return ret;
573bc143d8bSEvan Quan }
574bc143d8bSEvan Quan 
57513f5dbd6SEvan Quan int amdgpu_dpm_write_watermarks_table(struct amdgpu_device *adev)
57613f5dbd6SEvan Quan {
577ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
5783712e7a4SEvan Quan 	int ret = 0;
579ebfc2533SEvan Quan 
58013f5dbd6SEvan Quan 	if (!is_support_sw_smu(adev))
58113f5dbd6SEvan Quan 		return 0;
58213f5dbd6SEvan Quan 
5833712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
5843712e7a4SEvan Quan 	ret = smu_write_watermarks_table(smu);
5853712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
5863712e7a4SEvan Quan 
5873712e7a4SEvan Quan 	return ret;
58813f5dbd6SEvan Quan }
58913f5dbd6SEvan Quan 
590bc143d8bSEvan Quan int amdgpu_dpm_wait_for_event(struct amdgpu_device *adev,
591bc143d8bSEvan Quan 			      enum smu_event_type event,
592bc143d8bSEvan Quan 			      uint64_t event_arg)
593bc143d8bSEvan Quan {
594ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
5953712e7a4SEvan Quan 	int ret = 0;
596ebfc2533SEvan Quan 
597bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
598bc143d8bSEvan Quan 		return -EOPNOTSUPP;
599bc143d8bSEvan Quan 
6003712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
6013712e7a4SEvan Quan 	ret = smu_wait_for_event(smu, event, event_arg);
6023712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
6033712e7a4SEvan Quan 
6043712e7a4SEvan Quan 	return ret;
605bc143d8bSEvan Quan }
606bc143d8bSEvan Quan 
607bc143d8bSEvan Quan int amdgpu_dpm_get_status_gfxoff(struct amdgpu_device *adev, uint32_t *value)
608bc143d8bSEvan Quan {
609ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
6103712e7a4SEvan Quan 	int ret = 0;
611ebfc2533SEvan Quan 
612bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
613bc143d8bSEvan Quan 		return -EOPNOTSUPP;
614bc143d8bSEvan Quan 
6153712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
6163712e7a4SEvan Quan 	ret = smu_get_status_gfxoff(smu, value);
6173712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
6183712e7a4SEvan Quan 
6193712e7a4SEvan Quan 	return ret;
620bc143d8bSEvan Quan }
621bc143d8bSEvan Quan 
622bc143d8bSEvan Quan uint64_t amdgpu_dpm_get_thermal_throttling_counter(struct amdgpu_device *adev)
623bc143d8bSEvan Quan {
624ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
625ebfc2533SEvan Quan 
6263712e7a4SEvan Quan 	if (!is_support_sw_smu(adev))
6273712e7a4SEvan Quan 		return 0;
6283712e7a4SEvan Quan 
629ebfc2533SEvan Quan 	return atomic64_read(&smu->throttle_int_counter);
630bc143d8bSEvan Quan }
631bc143d8bSEvan Quan 
632bc143d8bSEvan Quan /* amdgpu_dpm_gfx_state_change - Handle gfx power state change set
633bc143d8bSEvan Quan  * @adev: amdgpu_device pointer
634bc143d8bSEvan Quan  * @state: gfx power state(1 -sGpuChangeState_D0Entry and 2 -sGpuChangeState_D3Entry)
635bc143d8bSEvan Quan  *
636bc143d8bSEvan Quan  */
637bc143d8bSEvan Quan void amdgpu_dpm_gfx_state_change(struct amdgpu_device *adev,
638bc143d8bSEvan Quan 				 enum gfx_change_state state)
639bc143d8bSEvan Quan {
640bc143d8bSEvan Quan 	mutex_lock(&adev->pm.mutex);
641bc143d8bSEvan Quan 	if (adev->powerplay.pp_funcs &&
642bc143d8bSEvan Quan 	    adev->powerplay.pp_funcs->gfx_state_change_set)
643bc143d8bSEvan Quan 		((adev)->powerplay.pp_funcs->gfx_state_change_set(
644bc143d8bSEvan Quan 			(adev)->powerplay.pp_handle, state));
645bc143d8bSEvan Quan 	mutex_unlock(&adev->pm.mutex);
646bc143d8bSEvan Quan }
647bc143d8bSEvan Quan 
648bc143d8bSEvan Quan int amdgpu_dpm_get_ecc_info(struct amdgpu_device *adev,
649bc143d8bSEvan Quan 			    void *umc_ecc)
650bc143d8bSEvan Quan {
651ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
652a29d44aeSStanley.Yang 	int ret = 0;
653ebfc2533SEvan Quan 
654bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
655bc143d8bSEvan Quan 		return -EOPNOTSUPP;
656bc143d8bSEvan Quan 
657a29d44aeSStanley.Yang 	mutex_lock(&adev->pm.mutex);
658a29d44aeSStanley.Yang 	ret = smu_get_ecc_info(smu, umc_ecc);
659a29d44aeSStanley.Yang 	mutex_unlock(&adev->pm.mutex);
660a29d44aeSStanley.Yang 
661a29d44aeSStanley.Yang 	return ret;
662bc143d8bSEvan Quan }
66379c65f3fSEvan Quan 
66479c65f3fSEvan Quan struct amd_vce_state *amdgpu_dpm_get_vce_clock_state(struct amdgpu_device *adev,
66579c65f3fSEvan Quan 						     uint32_t idx)
66679c65f3fSEvan Quan {
66779c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
6683712e7a4SEvan Quan 	struct amd_vce_state *vstate = NULL;
66979c65f3fSEvan Quan 
67079c65f3fSEvan Quan 	if (!pp_funcs->get_vce_clock_state)
67179c65f3fSEvan Quan 		return NULL;
67279c65f3fSEvan Quan 
6733712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
6743712e7a4SEvan Quan 	vstate = pp_funcs->get_vce_clock_state(adev->powerplay.pp_handle,
67579c65f3fSEvan Quan 					       idx);
6763712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
6773712e7a4SEvan Quan 
6783712e7a4SEvan Quan 	return vstate;
67979c65f3fSEvan Quan }
68079c65f3fSEvan Quan 
68179c65f3fSEvan Quan void amdgpu_dpm_get_current_power_state(struct amdgpu_device *adev,
68279c65f3fSEvan Quan 					enum amd_pm_state_type *state)
68379c65f3fSEvan Quan {
68479c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
68579c65f3fSEvan Quan 
6863712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
6873712e7a4SEvan Quan 
68879c65f3fSEvan Quan 	if (!pp_funcs->get_current_power_state) {
68979c65f3fSEvan Quan 		*state = adev->pm.dpm.user_state;
6903712e7a4SEvan Quan 		goto out;
69179c65f3fSEvan Quan 	}
69279c65f3fSEvan Quan 
69379c65f3fSEvan Quan 	*state = pp_funcs->get_current_power_state(adev->powerplay.pp_handle);
69479c65f3fSEvan Quan 	if (*state < POWER_STATE_TYPE_DEFAULT ||
69579c65f3fSEvan Quan 	    *state > POWER_STATE_TYPE_INTERNAL_3DPERF)
69679c65f3fSEvan Quan 		*state = adev->pm.dpm.user_state;
6973712e7a4SEvan Quan 
6983712e7a4SEvan Quan out:
6993712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
70079c65f3fSEvan Quan }
70179c65f3fSEvan Quan 
70279c65f3fSEvan Quan void amdgpu_dpm_set_power_state(struct amdgpu_device *adev,
70379c65f3fSEvan Quan 				enum amd_pm_state_type state)
70479c65f3fSEvan Quan {
7053712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
70679c65f3fSEvan Quan 	adev->pm.dpm.user_state = state;
7073712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
70879c65f3fSEvan Quan 
70979c65f3fSEvan Quan 	if (is_support_sw_smu(adev))
71079c65f3fSEvan Quan 		return;
71179c65f3fSEvan Quan 
71279c65f3fSEvan Quan 	if (amdgpu_dpm_dispatch_task(adev,
71379c65f3fSEvan Quan 				     AMD_PP_TASK_ENABLE_USER_STATE,
71479c65f3fSEvan Quan 				     &state) == -EOPNOTSUPP)
71584176663SEvan Quan 		amdgpu_dpm_compute_clocks(adev);
71679c65f3fSEvan Quan }
71779c65f3fSEvan Quan 
71875513bf5SEvan Quan enum amd_dpm_forced_level amdgpu_dpm_get_performance_level(struct amdgpu_device *adev)
71979c65f3fSEvan Quan {
72079c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
72179c65f3fSEvan Quan 	enum amd_dpm_forced_level level;
72279c65f3fSEvan Quan 
72375513bf5SEvan Quan 	mutex_lock(&adev->pm.mutex);
72479c65f3fSEvan Quan 	if (pp_funcs->get_performance_level)
72579c65f3fSEvan Quan 		level = pp_funcs->get_performance_level(adev->powerplay.pp_handle);
72679c65f3fSEvan Quan 	else
72779c65f3fSEvan Quan 		level = adev->pm.dpm.forced_level;
7283712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
72979c65f3fSEvan Quan 
73079c65f3fSEvan Quan 	return level;
73179c65f3fSEvan Quan }
73279c65f3fSEvan Quan 
73379c65f3fSEvan Quan int amdgpu_dpm_force_performance_level(struct amdgpu_device *adev,
73479c65f3fSEvan Quan 				       enum amd_dpm_forced_level level)
73579c65f3fSEvan Quan {
73679c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
73754c73b51SAlex Deucher 	enum amd_dpm_forced_level current_level;
73854c73b51SAlex Deucher 	uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
73954c73b51SAlex Deucher 					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
74054c73b51SAlex Deucher 					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
74154c73b51SAlex Deucher 					AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
74279c65f3fSEvan Quan 
7433712e7a4SEvan Quan 	if (!pp_funcs->force_performance_level)
7443712e7a4SEvan Quan 		return 0;
7453712e7a4SEvan Quan 
74675513bf5SEvan Quan 	if (adev->pm.dpm.thermal_active)
74775513bf5SEvan Quan 		return -EINVAL;
7483712e7a4SEvan Quan 
74975513bf5SEvan Quan 	current_level = amdgpu_dpm_get_performance_level(adev);
75075513bf5SEvan Quan 	if (current_level == level)
75175513bf5SEvan Quan 		return 0;
75254c73b51SAlex Deucher 
75354c73b51SAlex Deucher 	if (adev->asic_type == CHIP_RAVEN) {
75454c73b51SAlex Deucher 		if (!(adev->apu_flags & AMD_APU_IS_RAVEN2)) {
75554c73b51SAlex Deucher 			if (current_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
75654c73b51SAlex Deucher 			    level == AMD_DPM_FORCED_LEVEL_MANUAL)
75754c73b51SAlex Deucher 				amdgpu_gfx_off_ctrl(adev, false);
75854c73b51SAlex Deucher 			else if (current_level == AMD_DPM_FORCED_LEVEL_MANUAL &&
75954c73b51SAlex Deucher 				 level != AMD_DPM_FORCED_LEVEL_MANUAL)
76054c73b51SAlex Deucher 				amdgpu_gfx_off_ctrl(adev, true);
76154c73b51SAlex Deucher 		}
76254c73b51SAlex Deucher 	}
76354c73b51SAlex Deucher 
76454c73b51SAlex Deucher 	if (!(current_level & profile_mode_mask) &&
76575513bf5SEvan Quan 	    (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT))
76675513bf5SEvan Quan 		return -EINVAL;
76754c73b51SAlex Deucher 
76854c73b51SAlex Deucher 	if (!(current_level & profile_mode_mask) &&
76954c73b51SAlex Deucher 	      (level & profile_mode_mask)) {
77054c73b51SAlex Deucher 		/* enter UMD Pstate */
77154c73b51SAlex Deucher 		amdgpu_device_ip_set_powergating_state(adev,
77254c73b51SAlex Deucher 						       AMD_IP_BLOCK_TYPE_GFX,
77354c73b51SAlex Deucher 						       AMD_PG_STATE_UNGATE);
77454c73b51SAlex Deucher 		amdgpu_device_ip_set_clockgating_state(adev,
77554c73b51SAlex Deucher 						       AMD_IP_BLOCK_TYPE_GFX,
77654c73b51SAlex Deucher 						       AMD_CG_STATE_UNGATE);
77754c73b51SAlex Deucher 	} else if ((current_level & profile_mode_mask) &&
77854c73b51SAlex Deucher 		    !(level & profile_mode_mask)) {
77954c73b51SAlex Deucher 		/* exit UMD Pstate */
78054c73b51SAlex Deucher 		amdgpu_device_ip_set_clockgating_state(adev,
78154c73b51SAlex Deucher 						       AMD_IP_BLOCK_TYPE_GFX,
78254c73b51SAlex Deucher 						       AMD_CG_STATE_GATE);
78354c73b51SAlex Deucher 		amdgpu_device_ip_set_powergating_state(adev,
78454c73b51SAlex Deucher 						       AMD_IP_BLOCK_TYPE_GFX,
78554c73b51SAlex Deucher 						       AMD_PG_STATE_GATE);
78654c73b51SAlex Deucher 	}
78754c73b51SAlex Deucher 
78875513bf5SEvan Quan 	mutex_lock(&adev->pm.mutex);
78979c65f3fSEvan Quan 
79075513bf5SEvan Quan 	if (pp_funcs->force_performance_level(adev->powerplay.pp_handle,
79175513bf5SEvan Quan 					      level)) {
79275513bf5SEvan Quan 		mutex_unlock(&adev->pm.mutex);
79375513bf5SEvan Quan 		return -EINVAL;
79475513bf5SEvan Quan 	}
79575513bf5SEvan Quan 
79679c65f3fSEvan Quan 	adev->pm.dpm.forced_level = level;
79779c65f3fSEvan Quan 
7983712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
7993712e7a4SEvan Quan 
80075513bf5SEvan Quan 	return 0;
80179c65f3fSEvan Quan }
80279c65f3fSEvan Quan 
80379c65f3fSEvan Quan int amdgpu_dpm_get_pp_num_states(struct amdgpu_device *adev,
80479c65f3fSEvan Quan 				 struct pp_states_info *states)
80579c65f3fSEvan Quan {
80679c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8073712e7a4SEvan Quan 	int ret = 0;
80879c65f3fSEvan Quan 
80979c65f3fSEvan Quan 	if (!pp_funcs->get_pp_num_states)
81079c65f3fSEvan Quan 		return -EOPNOTSUPP;
81179c65f3fSEvan Quan 
8123712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
8133712e7a4SEvan Quan 	ret = pp_funcs->get_pp_num_states(adev->powerplay.pp_handle,
8143712e7a4SEvan Quan 					  states);
8153712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
8163712e7a4SEvan Quan 
8173712e7a4SEvan Quan 	return ret;
81879c65f3fSEvan Quan }
81979c65f3fSEvan Quan 
82079c65f3fSEvan Quan int amdgpu_dpm_dispatch_task(struct amdgpu_device *adev,
82179c65f3fSEvan Quan 			      enum amd_pp_task task_id,
82279c65f3fSEvan Quan 			      enum amd_pm_state_type *user_state)
82379c65f3fSEvan Quan {
82479c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8253712e7a4SEvan Quan 	int ret = 0;
82679c65f3fSEvan Quan 
82779c65f3fSEvan Quan 	if (!pp_funcs->dispatch_tasks)
82879c65f3fSEvan Quan 		return -EOPNOTSUPP;
82979c65f3fSEvan Quan 
8303712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
8313712e7a4SEvan Quan 	ret = pp_funcs->dispatch_tasks(adev->powerplay.pp_handle,
8323712e7a4SEvan Quan 				       task_id,
8333712e7a4SEvan Quan 				       user_state);
8343712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
8353712e7a4SEvan Quan 
8363712e7a4SEvan Quan 	return ret;
83779c65f3fSEvan Quan }
83879c65f3fSEvan Quan 
83979c65f3fSEvan Quan int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char **table)
84079c65f3fSEvan Quan {
84179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8423712e7a4SEvan Quan 	int ret = 0;
84379c65f3fSEvan Quan 
84479c65f3fSEvan Quan 	if (!pp_funcs->get_pp_table)
84579c65f3fSEvan Quan 		return 0;
84679c65f3fSEvan Quan 
8473712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
8483712e7a4SEvan Quan 	ret = pp_funcs->get_pp_table(adev->powerplay.pp_handle,
8493712e7a4SEvan Quan 				     table);
8503712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
8513712e7a4SEvan Quan 
8523712e7a4SEvan Quan 	return ret;
85379c65f3fSEvan Quan }
85479c65f3fSEvan Quan 
85579c65f3fSEvan Quan int amdgpu_dpm_set_fine_grain_clk_vol(struct amdgpu_device *adev,
85679c65f3fSEvan Quan 				      uint32_t type,
85779c65f3fSEvan Quan 				      long *input,
85879c65f3fSEvan Quan 				      uint32_t size)
85979c65f3fSEvan Quan {
86079c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8613712e7a4SEvan Quan 	int ret = 0;
86279c65f3fSEvan Quan 
86379c65f3fSEvan Quan 	if (!pp_funcs->set_fine_grain_clk_vol)
86479c65f3fSEvan Quan 		return 0;
86579c65f3fSEvan Quan 
8663712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
8673712e7a4SEvan Quan 	ret = pp_funcs->set_fine_grain_clk_vol(adev->powerplay.pp_handle,
86879c65f3fSEvan Quan 					       type,
86979c65f3fSEvan Quan 					       input,
87079c65f3fSEvan Quan 					       size);
8713712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
8723712e7a4SEvan Quan 
8733712e7a4SEvan Quan 	return ret;
87479c65f3fSEvan Quan }
87579c65f3fSEvan Quan 
87679c65f3fSEvan Quan int amdgpu_dpm_odn_edit_dpm_table(struct amdgpu_device *adev,
87779c65f3fSEvan Quan 				  uint32_t type,
87879c65f3fSEvan Quan 				  long *input,
87979c65f3fSEvan Quan 				  uint32_t size)
88079c65f3fSEvan Quan {
88179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8823712e7a4SEvan Quan 	int ret = 0;
88379c65f3fSEvan Quan 
88479c65f3fSEvan Quan 	if (!pp_funcs->odn_edit_dpm_table)
88579c65f3fSEvan Quan 		return 0;
88679c65f3fSEvan Quan 
8873712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
8883712e7a4SEvan Quan 	ret = pp_funcs->odn_edit_dpm_table(adev->powerplay.pp_handle,
88979c65f3fSEvan Quan 					   type,
89079c65f3fSEvan Quan 					   input,
89179c65f3fSEvan Quan 					   size);
8923712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
8933712e7a4SEvan Quan 
8943712e7a4SEvan Quan 	return ret;
89579c65f3fSEvan Quan }
89679c65f3fSEvan Quan 
89779c65f3fSEvan Quan int amdgpu_dpm_print_clock_levels(struct amdgpu_device *adev,
89879c65f3fSEvan Quan 				  enum pp_clock_type type,
89979c65f3fSEvan Quan 				  char *buf)
90079c65f3fSEvan Quan {
90179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9023712e7a4SEvan Quan 	int ret = 0;
90379c65f3fSEvan Quan 
90479c65f3fSEvan Quan 	if (!pp_funcs->print_clock_levels)
90579c65f3fSEvan Quan 		return 0;
90679c65f3fSEvan Quan 
9073712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
9083712e7a4SEvan Quan 	ret = pp_funcs->print_clock_levels(adev->powerplay.pp_handle,
90979c65f3fSEvan Quan 					   type,
91079c65f3fSEvan Quan 					   buf);
9113712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
9123712e7a4SEvan Quan 
9133712e7a4SEvan Quan 	return ret;
91479c65f3fSEvan Quan }
91579c65f3fSEvan Quan 
9165d64f9bbSDarren Powell int amdgpu_dpm_emit_clock_levels(struct amdgpu_device *adev,
9175d64f9bbSDarren Powell 				  enum pp_clock_type type,
9185d64f9bbSDarren Powell 				  char *buf,
9195d64f9bbSDarren Powell 				  int *offset)
9205d64f9bbSDarren Powell {
9215d64f9bbSDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9225d64f9bbSDarren Powell 	int ret = 0;
9235d64f9bbSDarren Powell 
9245d64f9bbSDarren Powell 	if (!pp_funcs->emit_clock_levels)
9255d64f9bbSDarren Powell 		return -ENOENT;
9265d64f9bbSDarren Powell 
9275d64f9bbSDarren Powell 	mutex_lock(&adev->pm.mutex);
9285d64f9bbSDarren Powell 	ret = pp_funcs->emit_clock_levels(adev->powerplay.pp_handle,
9295d64f9bbSDarren Powell 					   type,
9305d64f9bbSDarren Powell 					   buf,
9315d64f9bbSDarren Powell 					   offset);
9325d64f9bbSDarren Powell 	mutex_unlock(&adev->pm.mutex);
9335d64f9bbSDarren Powell 
9345d64f9bbSDarren Powell 	return ret;
9355d64f9bbSDarren Powell }
9365d64f9bbSDarren Powell 
93779c65f3fSEvan Quan int amdgpu_dpm_set_ppfeature_status(struct amdgpu_device *adev,
93879c65f3fSEvan Quan 				    uint64_t ppfeature_masks)
93979c65f3fSEvan Quan {
94079c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9413712e7a4SEvan Quan 	int ret = 0;
94279c65f3fSEvan Quan 
94379c65f3fSEvan Quan 	if (!pp_funcs->set_ppfeature_status)
94479c65f3fSEvan Quan 		return 0;
94579c65f3fSEvan Quan 
9463712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
9473712e7a4SEvan Quan 	ret = pp_funcs->set_ppfeature_status(adev->powerplay.pp_handle,
94879c65f3fSEvan Quan 					     ppfeature_masks);
9493712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
9503712e7a4SEvan Quan 
9513712e7a4SEvan Quan 	return ret;
95279c65f3fSEvan Quan }
95379c65f3fSEvan Quan 
95479c65f3fSEvan Quan int amdgpu_dpm_get_ppfeature_status(struct amdgpu_device *adev, char *buf)
95579c65f3fSEvan Quan {
95679c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9573712e7a4SEvan Quan 	int ret = 0;
95879c65f3fSEvan Quan 
95979c65f3fSEvan Quan 	if (!pp_funcs->get_ppfeature_status)
96079c65f3fSEvan Quan 		return 0;
96179c65f3fSEvan Quan 
9623712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
9633712e7a4SEvan Quan 	ret = pp_funcs->get_ppfeature_status(adev->powerplay.pp_handle,
96479c65f3fSEvan Quan 					     buf);
9653712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
9663712e7a4SEvan Quan 
9673712e7a4SEvan Quan 	return ret;
96879c65f3fSEvan Quan }
96979c65f3fSEvan Quan 
97079c65f3fSEvan Quan int amdgpu_dpm_force_clock_level(struct amdgpu_device *adev,
97179c65f3fSEvan Quan 				 enum pp_clock_type type,
97279c65f3fSEvan Quan 				 uint32_t mask)
97379c65f3fSEvan Quan {
97479c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9753712e7a4SEvan Quan 	int ret = 0;
97679c65f3fSEvan Quan 
97779c65f3fSEvan Quan 	if (!pp_funcs->force_clock_level)
97879c65f3fSEvan Quan 		return 0;
97979c65f3fSEvan Quan 
9803712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
9813712e7a4SEvan Quan 	ret = pp_funcs->force_clock_level(adev->powerplay.pp_handle,
98279c65f3fSEvan Quan 					  type,
98379c65f3fSEvan Quan 					  mask);
9843712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
9853712e7a4SEvan Quan 
9863712e7a4SEvan Quan 	return ret;
98779c65f3fSEvan Quan }
98879c65f3fSEvan Quan 
98979c65f3fSEvan Quan int amdgpu_dpm_get_sclk_od(struct amdgpu_device *adev)
99079c65f3fSEvan Quan {
99179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9923712e7a4SEvan Quan 	int ret = 0;
99379c65f3fSEvan Quan 
99479c65f3fSEvan Quan 	if (!pp_funcs->get_sclk_od)
99579c65f3fSEvan Quan 		return 0;
99679c65f3fSEvan Quan 
9973712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
9983712e7a4SEvan Quan 	ret = pp_funcs->get_sclk_od(adev->powerplay.pp_handle);
9993712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
10003712e7a4SEvan Quan 
10013712e7a4SEvan Quan 	return ret;
100279c65f3fSEvan Quan }
100379c65f3fSEvan Quan 
100479c65f3fSEvan Quan int amdgpu_dpm_set_sclk_od(struct amdgpu_device *adev, uint32_t value)
100579c65f3fSEvan Quan {
100679c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
100779c65f3fSEvan Quan 
100879c65f3fSEvan Quan 	if (is_support_sw_smu(adev))
100979c65f3fSEvan Quan 		return 0;
101079c65f3fSEvan Quan 
10113712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
101279c65f3fSEvan Quan 	if (pp_funcs->set_sclk_od)
101379c65f3fSEvan Quan 		pp_funcs->set_sclk_od(adev->powerplay.pp_handle, value);
10143712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
101579c65f3fSEvan Quan 
101679c65f3fSEvan Quan 	if (amdgpu_dpm_dispatch_task(adev,
101779c65f3fSEvan Quan 				     AMD_PP_TASK_READJUST_POWER_STATE,
101879c65f3fSEvan Quan 				     NULL) == -EOPNOTSUPP) {
101979c65f3fSEvan Quan 		adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
102084176663SEvan Quan 		amdgpu_dpm_compute_clocks(adev);
102179c65f3fSEvan Quan 	}
102279c65f3fSEvan Quan 
102379c65f3fSEvan Quan 	return 0;
102479c65f3fSEvan Quan }
102579c65f3fSEvan Quan 
102679c65f3fSEvan Quan int amdgpu_dpm_get_mclk_od(struct amdgpu_device *adev)
102779c65f3fSEvan Quan {
102879c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10293712e7a4SEvan Quan 	int ret = 0;
103079c65f3fSEvan Quan 
103179c65f3fSEvan Quan 	if (!pp_funcs->get_mclk_od)
103279c65f3fSEvan Quan 		return 0;
103379c65f3fSEvan Quan 
10343712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
10353712e7a4SEvan Quan 	ret = pp_funcs->get_mclk_od(adev->powerplay.pp_handle);
10363712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
10373712e7a4SEvan Quan 
10383712e7a4SEvan Quan 	return ret;
103979c65f3fSEvan Quan }
104079c65f3fSEvan Quan 
104179c65f3fSEvan Quan int amdgpu_dpm_set_mclk_od(struct amdgpu_device *adev, uint32_t value)
104279c65f3fSEvan Quan {
104379c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
104479c65f3fSEvan Quan 
104579c65f3fSEvan Quan 	if (is_support_sw_smu(adev))
104679c65f3fSEvan Quan 		return 0;
104779c65f3fSEvan Quan 
10483712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
104979c65f3fSEvan Quan 	if (pp_funcs->set_mclk_od)
105079c65f3fSEvan Quan 		pp_funcs->set_mclk_od(adev->powerplay.pp_handle, value);
10513712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
105279c65f3fSEvan Quan 
105379c65f3fSEvan Quan 	if (amdgpu_dpm_dispatch_task(adev,
105479c65f3fSEvan Quan 				     AMD_PP_TASK_READJUST_POWER_STATE,
105579c65f3fSEvan Quan 				     NULL) == -EOPNOTSUPP) {
105679c65f3fSEvan Quan 		adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
105784176663SEvan Quan 		amdgpu_dpm_compute_clocks(adev);
105879c65f3fSEvan Quan 	}
105979c65f3fSEvan Quan 
106079c65f3fSEvan Quan 	return 0;
106179c65f3fSEvan Quan }
106279c65f3fSEvan Quan 
106379c65f3fSEvan Quan int amdgpu_dpm_get_power_profile_mode(struct amdgpu_device *adev,
106479c65f3fSEvan Quan 				      char *buf)
106579c65f3fSEvan Quan {
106679c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10673712e7a4SEvan Quan 	int ret = 0;
106879c65f3fSEvan Quan 
106979c65f3fSEvan Quan 	if (!pp_funcs->get_power_profile_mode)
107079c65f3fSEvan Quan 		return -EOPNOTSUPP;
107179c65f3fSEvan Quan 
10723712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
10733712e7a4SEvan Quan 	ret = pp_funcs->get_power_profile_mode(adev->powerplay.pp_handle,
107479c65f3fSEvan Quan 					       buf);
10753712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
10763712e7a4SEvan Quan 
10773712e7a4SEvan Quan 	return ret;
107879c65f3fSEvan Quan }
107979c65f3fSEvan Quan 
108079c65f3fSEvan Quan int amdgpu_dpm_set_power_profile_mode(struct amdgpu_device *adev,
108179c65f3fSEvan Quan 				      long *input, uint32_t size)
108279c65f3fSEvan Quan {
108379c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10843712e7a4SEvan Quan 	int ret = 0;
108579c65f3fSEvan Quan 
108679c65f3fSEvan Quan 	if (!pp_funcs->set_power_profile_mode)
108779c65f3fSEvan Quan 		return 0;
108879c65f3fSEvan Quan 
10893712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
10903712e7a4SEvan Quan 	ret = pp_funcs->set_power_profile_mode(adev->powerplay.pp_handle,
109179c65f3fSEvan Quan 					       input,
109279c65f3fSEvan Quan 					       size);
10933712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
10943712e7a4SEvan Quan 
10953712e7a4SEvan Quan 	return ret;
109679c65f3fSEvan Quan }
109779c65f3fSEvan Quan 
109879c65f3fSEvan Quan int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void **table)
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->get_gpu_metrics)
110479c65f3fSEvan Quan 		return 0;
110579c65f3fSEvan Quan 
11063712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11073712e7a4SEvan Quan 	ret = pp_funcs->get_gpu_metrics(adev->powerplay.pp_handle,
11083712e7a4SEvan Quan 					table);
11093712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11103712e7a4SEvan Quan 
11113712e7a4SEvan Quan 	return ret;
111279c65f3fSEvan Quan }
111379c65f3fSEvan Quan 
111479c65f3fSEvan Quan int amdgpu_dpm_get_fan_control_mode(struct amdgpu_device *adev,
111579c65f3fSEvan Quan 				    uint32_t *fan_mode)
111679c65f3fSEvan Quan {
111779c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1118685fae24SEvan Quan 	int ret = 0;
111979c65f3fSEvan Quan 
112079c65f3fSEvan Quan 	if (!pp_funcs->get_fan_control_mode)
112179c65f3fSEvan Quan 		return -EOPNOTSUPP;
112279c65f3fSEvan Quan 
11233712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
1124685fae24SEvan Quan 	ret = pp_funcs->get_fan_control_mode(adev->powerplay.pp_handle,
1125685fae24SEvan Quan 					     fan_mode);
11263712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
112779c65f3fSEvan Quan 
1128685fae24SEvan Quan 	return ret;
112979c65f3fSEvan Quan }
113079c65f3fSEvan Quan 
113179c65f3fSEvan Quan int amdgpu_dpm_set_fan_speed_pwm(struct amdgpu_device *adev,
113279c65f3fSEvan Quan 				 uint32_t speed)
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->set_fan_speed_pwm)
1138685fae24SEvan Quan 		return -EOPNOTSUPP;
113979c65f3fSEvan Quan 
11403712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11413712e7a4SEvan Quan 	ret = pp_funcs->set_fan_speed_pwm(adev->powerplay.pp_handle,
11423712e7a4SEvan Quan 					  speed);
11433712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11443712e7a4SEvan Quan 
11453712e7a4SEvan Quan 	return ret;
114679c65f3fSEvan Quan }
114779c65f3fSEvan Quan 
114879c65f3fSEvan Quan int amdgpu_dpm_get_fan_speed_pwm(struct amdgpu_device *adev,
114979c65f3fSEvan Quan 				 uint32_t *speed)
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_fan_speed_pwm)
1155685fae24SEvan Quan 		return -EOPNOTSUPP;
115679c65f3fSEvan Quan 
11573712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11583712e7a4SEvan Quan 	ret = pp_funcs->get_fan_speed_pwm(adev->powerplay.pp_handle,
11593712e7a4SEvan Quan 					  speed);
11603712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11613712e7a4SEvan Quan 
11623712e7a4SEvan Quan 	return ret;
116379c65f3fSEvan Quan }
116479c65f3fSEvan Quan 
116579c65f3fSEvan Quan int amdgpu_dpm_get_fan_speed_rpm(struct amdgpu_device *adev,
116679c65f3fSEvan Quan 				 uint32_t *speed)
116779c65f3fSEvan Quan {
116879c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11693712e7a4SEvan Quan 	int ret = 0;
117079c65f3fSEvan Quan 
117179c65f3fSEvan Quan 	if (!pp_funcs->get_fan_speed_rpm)
1172685fae24SEvan Quan 		return -EOPNOTSUPP;
117379c65f3fSEvan Quan 
11743712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11753712e7a4SEvan Quan 	ret = pp_funcs->get_fan_speed_rpm(adev->powerplay.pp_handle,
11763712e7a4SEvan Quan 					  speed);
11773712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11783712e7a4SEvan Quan 
11793712e7a4SEvan Quan 	return ret;
118079c65f3fSEvan Quan }
118179c65f3fSEvan Quan 
118279c65f3fSEvan Quan int amdgpu_dpm_set_fan_speed_rpm(struct amdgpu_device *adev,
118379c65f3fSEvan Quan 				 uint32_t speed)
118479c65f3fSEvan Quan {
118579c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11863712e7a4SEvan Quan 	int ret = 0;
118779c65f3fSEvan Quan 
118879c65f3fSEvan Quan 	if (!pp_funcs->set_fan_speed_rpm)
1189685fae24SEvan Quan 		return -EOPNOTSUPP;
119079c65f3fSEvan Quan 
11913712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11923712e7a4SEvan Quan 	ret = pp_funcs->set_fan_speed_rpm(adev->powerplay.pp_handle,
11933712e7a4SEvan Quan 					  speed);
11943712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11953712e7a4SEvan Quan 
11963712e7a4SEvan Quan 	return ret;
119779c65f3fSEvan Quan }
119879c65f3fSEvan Quan 
119979c65f3fSEvan Quan int amdgpu_dpm_set_fan_control_mode(struct amdgpu_device *adev,
120079c65f3fSEvan Quan 				    uint32_t mode)
120179c65f3fSEvan Quan {
120279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1203685fae24SEvan Quan 	int ret = 0;
120479c65f3fSEvan Quan 
120579c65f3fSEvan Quan 	if (!pp_funcs->set_fan_control_mode)
120679c65f3fSEvan Quan 		return -EOPNOTSUPP;
120779c65f3fSEvan Quan 
12083712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
1209685fae24SEvan Quan 	ret = pp_funcs->set_fan_control_mode(adev->powerplay.pp_handle,
12103712e7a4SEvan Quan 					     mode);
12113712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
121279c65f3fSEvan Quan 
1213685fae24SEvan Quan 	return ret;
121479c65f3fSEvan Quan }
121579c65f3fSEvan Quan 
121679c65f3fSEvan Quan int amdgpu_dpm_get_power_limit(struct amdgpu_device *adev,
121779c65f3fSEvan Quan 			       uint32_t *limit,
121879c65f3fSEvan Quan 			       enum pp_power_limit_level pp_limit_level,
121979c65f3fSEvan Quan 			       enum pp_power_type power_type)
122079c65f3fSEvan Quan {
122179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12223712e7a4SEvan Quan 	int ret = 0;
122379c65f3fSEvan Quan 
122479c65f3fSEvan Quan 	if (!pp_funcs->get_power_limit)
122579c65f3fSEvan Quan 		return -ENODATA;
122679c65f3fSEvan Quan 
12273712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
12283712e7a4SEvan Quan 	ret = pp_funcs->get_power_limit(adev->powerplay.pp_handle,
122979c65f3fSEvan Quan 					limit,
123079c65f3fSEvan Quan 					pp_limit_level,
123179c65f3fSEvan Quan 					power_type);
12323712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
12333712e7a4SEvan Quan 
12343712e7a4SEvan Quan 	return ret;
123579c65f3fSEvan Quan }
123679c65f3fSEvan Quan 
123779c65f3fSEvan Quan int amdgpu_dpm_set_power_limit(struct amdgpu_device *adev,
123879c65f3fSEvan Quan 			       uint32_t limit)
123979c65f3fSEvan Quan {
124079c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12413712e7a4SEvan Quan 	int ret = 0;
124279c65f3fSEvan Quan 
124379c65f3fSEvan Quan 	if (!pp_funcs->set_power_limit)
124479c65f3fSEvan Quan 		return -EINVAL;
124579c65f3fSEvan Quan 
12463712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
12473712e7a4SEvan Quan 	ret = pp_funcs->set_power_limit(adev->powerplay.pp_handle,
12483712e7a4SEvan Quan 					limit);
12493712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
12503712e7a4SEvan Quan 
12513712e7a4SEvan Quan 	return ret;
125279c65f3fSEvan Quan }
125379c65f3fSEvan Quan 
125479c65f3fSEvan Quan int amdgpu_dpm_is_cclk_dpm_supported(struct amdgpu_device *adev)
125579c65f3fSEvan Quan {
12563712e7a4SEvan Quan 	bool cclk_dpm_supported = false;
12573712e7a4SEvan Quan 
125879c65f3fSEvan Quan 	if (!is_support_sw_smu(adev))
125979c65f3fSEvan Quan 		return false;
126079c65f3fSEvan Quan 
12613712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
12623712e7a4SEvan Quan 	cclk_dpm_supported = is_support_cclk_dpm(adev);
12633712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
12643712e7a4SEvan Quan 
12653712e7a4SEvan Quan 	return (int)cclk_dpm_supported;
126679c65f3fSEvan Quan }
126779c65f3fSEvan Quan 
126879c65f3fSEvan Quan int amdgpu_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev,
126979c65f3fSEvan Quan 						       struct seq_file *m)
127079c65f3fSEvan Quan {
127179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
127279c65f3fSEvan Quan 
127379c65f3fSEvan Quan 	if (!pp_funcs->debugfs_print_current_performance_level)
127479c65f3fSEvan Quan 		return -EOPNOTSUPP;
127579c65f3fSEvan Quan 
12763712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
127779c65f3fSEvan Quan 	pp_funcs->debugfs_print_current_performance_level(adev->powerplay.pp_handle,
127879c65f3fSEvan Quan 							  m);
12793712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
128079c65f3fSEvan Quan 
128179c65f3fSEvan Quan 	return 0;
128279c65f3fSEvan Quan }
128379c65f3fSEvan Quan 
128479c65f3fSEvan Quan int amdgpu_dpm_get_smu_prv_buf_details(struct amdgpu_device *adev,
128579c65f3fSEvan Quan 				       void **addr,
128679c65f3fSEvan Quan 				       size_t *size)
128779c65f3fSEvan Quan {
128879c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12893712e7a4SEvan Quan 	int ret = 0;
129079c65f3fSEvan Quan 
129179c65f3fSEvan Quan 	if (!pp_funcs->get_smu_prv_buf_details)
129279c65f3fSEvan Quan 		return -ENOSYS;
129379c65f3fSEvan Quan 
12943712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
12953712e7a4SEvan Quan 	ret = pp_funcs->get_smu_prv_buf_details(adev->powerplay.pp_handle,
129679c65f3fSEvan Quan 						addr,
129779c65f3fSEvan Quan 						size);
12983712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
12993712e7a4SEvan Quan 
13003712e7a4SEvan Quan 	return ret;
130179c65f3fSEvan Quan }
130279c65f3fSEvan Quan 
130379c65f3fSEvan Quan int amdgpu_dpm_is_overdrive_supported(struct amdgpu_device *adev)
130479c65f3fSEvan Quan {
130579c65f3fSEvan Quan 	struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
1306ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
130779c65f3fSEvan Quan 
1308ebfc2533SEvan Quan 	if ((is_support_sw_smu(adev) && smu->od_enabled) ||
1309ebfc2533SEvan Quan 	    (is_support_sw_smu(adev) && smu->is_apu) ||
131079c65f3fSEvan Quan 		(!is_support_sw_smu(adev) && hwmgr->od_enabled))
131179c65f3fSEvan Quan 		return true;
131279c65f3fSEvan Quan 
131379c65f3fSEvan Quan 	return false;
131479c65f3fSEvan Quan }
131579c65f3fSEvan Quan 
131679c65f3fSEvan Quan int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev,
131779c65f3fSEvan Quan 			    const char *buf,
131879c65f3fSEvan Quan 			    size_t size)
131979c65f3fSEvan Quan {
132079c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13213712e7a4SEvan Quan 	int ret = 0;
132279c65f3fSEvan Quan 
132379c65f3fSEvan Quan 	if (!pp_funcs->set_pp_table)
132479c65f3fSEvan Quan 		return -EOPNOTSUPP;
132579c65f3fSEvan Quan 
13263712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
13273712e7a4SEvan Quan 	ret = pp_funcs->set_pp_table(adev->powerplay.pp_handle,
132879c65f3fSEvan Quan 				     buf,
132979c65f3fSEvan Quan 				     size);
13303712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
13313712e7a4SEvan Quan 
13323712e7a4SEvan Quan 	return ret;
133379c65f3fSEvan Quan }
133479c65f3fSEvan Quan 
133579c65f3fSEvan Quan int amdgpu_dpm_get_num_cpu_cores(struct amdgpu_device *adev)
133679c65f3fSEvan Quan {
1337ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
1338ebfc2533SEvan Quan 
13393712e7a4SEvan Quan 	if (!is_support_sw_smu(adev))
13403712e7a4SEvan Quan 		return INT_MAX;
13413712e7a4SEvan Quan 
1342ebfc2533SEvan Quan 	return smu->cpu_core_num;
134379c65f3fSEvan Quan }
134479c65f3fSEvan Quan 
134579c65f3fSEvan Quan void amdgpu_dpm_stb_debug_fs_init(struct amdgpu_device *adev)
134679c65f3fSEvan Quan {
134779c65f3fSEvan Quan 	if (!is_support_sw_smu(adev))
134879c65f3fSEvan Quan 		return;
134979c65f3fSEvan Quan 
135079c65f3fSEvan Quan 	amdgpu_smu_stb_debug_fs_init(adev);
135179c65f3fSEvan Quan }
135213f5dbd6SEvan Quan 
135313f5dbd6SEvan Quan int amdgpu_dpm_display_configuration_change(struct amdgpu_device *adev,
135413f5dbd6SEvan Quan 					    const struct amd_pp_display_configuration *input)
135513f5dbd6SEvan Quan {
135613f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13573712e7a4SEvan Quan 	int ret = 0;
135813f5dbd6SEvan Quan 
135913f5dbd6SEvan Quan 	if (!pp_funcs->display_configuration_change)
136013f5dbd6SEvan Quan 		return 0;
136113f5dbd6SEvan Quan 
13623712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
13633712e7a4SEvan Quan 	ret = pp_funcs->display_configuration_change(adev->powerplay.pp_handle,
136413f5dbd6SEvan Quan 						     input);
13653712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
13663712e7a4SEvan Quan 
13673712e7a4SEvan Quan 	return ret;
136813f5dbd6SEvan Quan }
136913f5dbd6SEvan Quan 
137013f5dbd6SEvan Quan int amdgpu_dpm_get_clock_by_type(struct amdgpu_device *adev,
137113f5dbd6SEvan Quan 				 enum amd_pp_clock_type type,
137213f5dbd6SEvan Quan 				 struct amd_pp_clocks *clocks)
137313f5dbd6SEvan Quan {
137413f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13753712e7a4SEvan Quan 	int ret = 0;
137613f5dbd6SEvan Quan 
137713f5dbd6SEvan Quan 	if (!pp_funcs->get_clock_by_type)
137813f5dbd6SEvan Quan 		return 0;
137913f5dbd6SEvan Quan 
13803712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
13813712e7a4SEvan Quan 	ret = pp_funcs->get_clock_by_type(adev->powerplay.pp_handle,
138213f5dbd6SEvan Quan 					  type,
138313f5dbd6SEvan Quan 					  clocks);
13843712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
13853712e7a4SEvan Quan 
13863712e7a4SEvan Quan 	return ret;
138713f5dbd6SEvan Quan }
138813f5dbd6SEvan Quan 
138913f5dbd6SEvan Quan int amdgpu_dpm_get_display_mode_validation_clks(struct amdgpu_device *adev,
139013f5dbd6SEvan Quan 						struct amd_pp_simple_clock_info *clocks)
139113f5dbd6SEvan Quan {
139213f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13933712e7a4SEvan Quan 	int ret = 0;
139413f5dbd6SEvan Quan 
139513f5dbd6SEvan Quan 	if (!pp_funcs->get_display_mode_validation_clocks)
139613f5dbd6SEvan Quan 		return 0;
139713f5dbd6SEvan Quan 
13983712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
13993712e7a4SEvan Quan 	ret = pp_funcs->get_display_mode_validation_clocks(adev->powerplay.pp_handle,
140013f5dbd6SEvan Quan 							   clocks);
14013712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14023712e7a4SEvan Quan 
14033712e7a4SEvan Quan 	return ret;
140413f5dbd6SEvan Quan }
140513f5dbd6SEvan Quan 
140613f5dbd6SEvan Quan int amdgpu_dpm_get_clock_by_type_with_latency(struct amdgpu_device *adev,
140713f5dbd6SEvan Quan 					      enum amd_pp_clock_type type,
140813f5dbd6SEvan Quan 					      struct pp_clock_levels_with_latency *clocks)
140913f5dbd6SEvan Quan {
141013f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14113712e7a4SEvan Quan 	int ret = 0;
141213f5dbd6SEvan Quan 
141313f5dbd6SEvan Quan 	if (!pp_funcs->get_clock_by_type_with_latency)
141413f5dbd6SEvan Quan 		return 0;
141513f5dbd6SEvan Quan 
14163712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14173712e7a4SEvan Quan 	ret = pp_funcs->get_clock_by_type_with_latency(adev->powerplay.pp_handle,
141813f5dbd6SEvan Quan 						       type,
141913f5dbd6SEvan Quan 						       clocks);
14203712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14213712e7a4SEvan Quan 
14223712e7a4SEvan Quan 	return ret;
142313f5dbd6SEvan Quan }
142413f5dbd6SEvan Quan 
142513f5dbd6SEvan Quan int amdgpu_dpm_get_clock_by_type_with_voltage(struct amdgpu_device *adev,
142613f5dbd6SEvan Quan 					      enum amd_pp_clock_type type,
142713f5dbd6SEvan Quan 					      struct pp_clock_levels_with_voltage *clocks)
142813f5dbd6SEvan Quan {
142913f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14303712e7a4SEvan Quan 	int ret = 0;
143113f5dbd6SEvan Quan 
143213f5dbd6SEvan Quan 	if (!pp_funcs->get_clock_by_type_with_voltage)
143313f5dbd6SEvan Quan 		return 0;
143413f5dbd6SEvan Quan 
14353712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14363712e7a4SEvan Quan 	ret = pp_funcs->get_clock_by_type_with_voltage(adev->powerplay.pp_handle,
143713f5dbd6SEvan Quan 						       type,
143813f5dbd6SEvan Quan 						       clocks);
14393712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14403712e7a4SEvan Quan 
14413712e7a4SEvan Quan 	return ret;
144213f5dbd6SEvan Quan }
144313f5dbd6SEvan Quan 
144413f5dbd6SEvan Quan int amdgpu_dpm_set_watermarks_for_clocks_ranges(struct amdgpu_device *adev,
144513f5dbd6SEvan Quan 					       void *clock_ranges)
144613f5dbd6SEvan Quan {
144713f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14483712e7a4SEvan Quan 	int ret = 0;
144913f5dbd6SEvan Quan 
145013f5dbd6SEvan Quan 	if (!pp_funcs->set_watermarks_for_clocks_ranges)
145113f5dbd6SEvan Quan 		return -EOPNOTSUPP;
145213f5dbd6SEvan Quan 
14533712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14543712e7a4SEvan Quan 	ret = pp_funcs->set_watermarks_for_clocks_ranges(adev->powerplay.pp_handle,
145513f5dbd6SEvan Quan 							 clock_ranges);
14563712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14573712e7a4SEvan Quan 
14583712e7a4SEvan Quan 	return ret;
145913f5dbd6SEvan Quan }
146013f5dbd6SEvan Quan 
146113f5dbd6SEvan Quan int amdgpu_dpm_display_clock_voltage_request(struct amdgpu_device *adev,
146213f5dbd6SEvan Quan 					     struct pp_display_clock_request *clock)
146313f5dbd6SEvan Quan {
146413f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14653712e7a4SEvan Quan 	int ret = 0;
146613f5dbd6SEvan Quan 
146713f5dbd6SEvan Quan 	if (!pp_funcs->display_clock_voltage_request)
146813f5dbd6SEvan Quan 		return -EOPNOTSUPP;
146913f5dbd6SEvan Quan 
14703712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14713712e7a4SEvan Quan 	ret = pp_funcs->display_clock_voltage_request(adev->powerplay.pp_handle,
147213f5dbd6SEvan Quan 						      clock);
14733712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14743712e7a4SEvan Quan 
14753712e7a4SEvan Quan 	return ret;
147613f5dbd6SEvan Quan }
147713f5dbd6SEvan Quan 
147813f5dbd6SEvan Quan int amdgpu_dpm_get_current_clocks(struct amdgpu_device *adev,
147913f5dbd6SEvan Quan 				  struct amd_pp_clock_info *clocks)
148013f5dbd6SEvan Quan {
148113f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14823712e7a4SEvan Quan 	int ret = 0;
148313f5dbd6SEvan Quan 
148413f5dbd6SEvan Quan 	if (!pp_funcs->get_current_clocks)
148513f5dbd6SEvan Quan 		return -EOPNOTSUPP;
148613f5dbd6SEvan Quan 
14873712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14883712e7a4SEvan Quan 	ret = pp_funcs->get_current_clocks(adev->powerplay.pp_handle,
148913f5dbd6SEvan Quan 					   clocks);
14903712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14913712e7a4SEvan Quan 
14923712e7a4SEvan Quan 	return ret;
149313f5dbd6SEvan Quan }
149413f5dbd6SEvan Quan 
149513f5dbd6SEvan Quan void amdgpu_dpm_notify_smu_enable_pwe(struct amdgpu_device *adev)
149613f5dbd6SEvan Quan {
149713f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
149813f5dbd6SEvan Quan 
149913f5dbd6SEvan Quan 	if (!pp_funcs->notify_smu_enable_pwe)
150013f5dbd6SEvan Quan 		return;
150113f5dbd6SEvan Quan 
15023712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
150313f5dbd6SEvan Quan 	pp_funcs->notify_smu_enable_pwe(adev->powerplay.pp_handle);
15043712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
150513f5dbd6SEvan Quan }
150613f5dbd6SEvan Quan 
150713f5dbd6SEvan Quan int amdgpu_dpm_set_active_display_count(struct amdgpu_device *adev,
150813f5dbd6SEvan Quan 					uint32_t count)
150913f5dbd6SEvan Quan {
151013f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15113712e7a4SEvan Quan 	int ret = 0;
151213f5dbd6SEvan Quan 
151313f5dbd6SEvan Quan 	if (!pp_funcs->set_active_display_count)
151413f5dbd6SEvan Quan 		return -EOPNOTSUPP;
151513f5dbd6SEvan Quan 
15163712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
15173712e7a4SEvan Quan 	ret = pp_funcs->set_active_display_count(adev->powerplay.pp_handle,
151813f5dbd6SEvan Quan 						 count);
15193712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
15203712e7a4SEvan Quan 
15213712e7a4SEvan Quan 	return ret;
152213f5dbd6SEvan Quan }
152313f5dbd6SEvan Quan 
152413f5dbd6SEvan Quan int amdgpu_dpm_set_min_deep_sleep_dcefclk(struct amdgpu_device *adev,
152513f5dbd6SEvan Quan 					  uint32_t clock)
152613f5dbd6SEvan Quan {
152713f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15283712e7a4SEvan Quan 	int ret = 0;
152913f5dbd6SEvan Quan 
153013f5dbd6SEvan Quan 	if (!pp_funcs->set_min_deep_sleep_dcefclk)
153113f5dbd6SEvan Quan 		return -EOPNOTSUPP;
153213f5dbd6SEvan Quan 
15333712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
15343712e7a4SEvan Quan 	ret = pp_funcs->set_min_deep_sleep_dcefclk(adev->powerplay.pp_handle,
153513f5dbd6SEvan Quan 						   clock);
15363712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
15373712e7a4SEvan Quan 
15383712e7a4SEvan Quan 	return ret;
153913f5dbd6SEvan Quan }
154013f5dbd6SEvan Quan 
154113f5dbd6SEvan Quan void amdgpu_dpm_set_hard_min_dcefclk_by_freq(struct amdgpu_device *adev,
154213f5dbd6SEvan Quan 					     uint32_t clock)
154313f5dbd6SEvan Quan {
154413f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
154513f5dbd6SEvan Quan 
154613f5dbd6SEvan Quan 	if (!pp_funcs->set_hard_min_dcefclk_by_freq)
154713f5dbd6SEvan Quan 		return;
154813f5dbd6SEvan Quan 
15493712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
155013f5dbd6SEvan Quan 	pp_funcs->set_hard_min_dcefclk_by_freq(adev->powerplay.pp_handle,
155113f5dbd6SEvan Quan 					       clock);
15523712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
155313f5dbd6SEvan Quan }
155413f5dbd6SEvan Quan 
155513f5dbd6SEvan Quan void amdgpu_dpm_set_hard_min_fclk_by_freq(struct amdgpu_device *adev,
155613f5dbd6SEvan Quan 					  uint32_t clock)
155713f5dbd6SEvan Quan {
155813f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
155913f5dbd6SEvan Quan 
156013f5dbd6SEvan Quan 	if (!pp_funcs->set_hard_min_fclk_by_freq)
156113f5dbd6SEvan Quan 		return;
156213f5dbd6SEvan Quan 
15633712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
156413f5dbd6SEvan Quan 	pp_funcs->set_hard_min_fclk_by_freq(adev->powerplay.pp_handle,
156513f5dbd6SEvan Quan 					    clock);
15663712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
156713f5dbd6SEvan Quan }
156813f5dbd6SEvan Quan 
156913f5dbd6SEvan Quan int amdgpu_dpm_display_disable_memory_clock_switch(struct amdgpu_device *adev,
157013f5dbd6SEvan Quan 						   bool disable_memory_clock_switch)
157113f5dbd6SEvan Quan {
157213f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15733712e7a4SEvan Quan 	int ret = 0;
157413f5dbd6SEvan Quan 
157513f5dbd6SEvan Quan 	if (!pp_funcs->display_disable_memory_clock_switch)
157613f5dbd6SEvan Quan 		return 0;
157713f5dbd6SEvan Quan 
15783712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
15793712e7a4SEvan Quan 	ret = pp_funcs->display_disable_memory_clock_switch(adev->powerplay.pp_handle,
158013f5dbd6SEvan Quan 							    disable_memory_clock_switch);
15813712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
15823712e7a4SEvan Quan 
15833712e7a4SEvan Quan 	return ret;
158413f5dbd6SEvan Quan }
158513f5dbd6SEvan Quan 
158613f5dbd6SEvan Quan int amdgpu_dpm_get_max_sustainable_clocks_by_dc(struct amdgpu_device *adev,
158713f5dbd6SEvan Quan 						struct pp_smu_nv_clock_table *max_clocks)
158813f5dbd6SEvan Quan {
158913f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15903712e7a4SEvan Quan 	int ret = 0;
159113f5dbd6SEvan Quan 
159213f5dbd6SEvan Quan 	if (!pp_funcs->get_max_sustainable_clocks_by_dc)
159313f5dbd6SEvan Quan 		return -EOPNOTSUPP;
159413f5dbd6SEvan Quan 
15953712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
15963712e7a4SEvan Quan 	ret = pp_funcs->get_max_sustainable_clocks_by_dc(adev->powerplay.pp_handle,
159713f5dbd6SEvan Quan 							 max_clocks);
15983712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
15993712e7a4SEvan Quan 
16003712e7a4SEvan Quan 	return ret;
160113f5dbd6SEvan Quan }
160213f5dbd6SEvan Quan 
160313f5dbd6SEvan Quan enum pp_smu_status amdgpu_dpm_get_uclk_dpm_states(struct amdgpu_device *adev,
160413f5dbd6SEvan Quan 						  unsigned int *clock_values_in_khz,
160513f5dbd6SEvan Quan 						  unsigned int *num_states)
160613f5dbd6SEvan Quan {
160713f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16083712e7a4SEvan Quan 	int ret = 0;
160913f5dbd6SEvan Quan 
161013f5dbd6SEvan Quan 	if (!pp_funcs->get_uclk_dpm_states)
161113f5dbd6SEvan Quan 		return -EOPNOTSUPP;
161213f5dbd6SEvan Quan 
16133712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
16143712e7a4SEvan Quan 	ret = pp_funcs->get_uclk_dpm_states(adev->powerplay.pp_handle,
161513f5dbd6SEvan Quan 					    clock_values_in_khz,
161613f5dbd6SEvan Quan 					    num_states);
16173712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
16183712e7a4SEvan Quan 
16193712e7a4SEvan Quan 	return ret;
162013f5dbd6SEvan Quan }
162113f5dbd6SEvan Quan 
162213f5dbd6SEvan Quan int amdgpu_dpm_get_dpm_clock_table(struct amdgpu_device *adev,
162313f5dbd6SEvan Quan 				   struct dpm_clocks *clock_table)
162413f5dbd6SEvan Quan {
162513f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16263712e7a4SEvan Quan 	int ret = 0;
162713f5dbd6SEvan Quan 
162813f5dbd6SEvan Quan 	if (!pp_funcs->get_dpm_clock_table)
162913f5dbd6SEvan Quan 		return -EOPNOTSUPP;
163013f5dbd6SEvan Quan 
16313712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
16323712e7a4SEvan Quan 	ret = pp_funcs->get_dpm_clock_table(adev->powerplay.pp_handle,
163313f5dbd6SEvan Quan 					    clock_table);
16343712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
16353712e7a4SEvan Quan 
16363712e7a4SEvan Quan 	return ret;
163713f5dbd6SEvan Quan }
1638