xref: /openbmc/linux/drivers/gpu/drm/amd/pm/amdgpu_dpm.c (revision eea5c7b3)
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;
17634452ac3SAlex Deucher 	/* Don't use baco for reset in S3.
17734452ac3SAlex Deucher 	 * This is a workaround for some platforms
17834452ac3SAlex Deucher 	 * where entering BACO during suspend
17934452ac3SAlex Deucher 	 * seems to cause reboots or hangs.
18034452ac3SAlex Deucher 	 * This might be related to the fact that BACO controls
18134452ac3SAlex Deucher 	 * power to the whole GPU including devices like audio and USB.
18234452ac3SAlex Deucher 	 * Powering down/up everything may adversely affect these other
18334452ac3SAlex Deucher 	 * devices.  Needs more investigation.
18434452ac3SAlex Deucher 	 */
18534452ac3SAlex Deucher 	if (adev->in_s3)
18634452ac3SAlex Deucher 		return false;
187e098bc96SEvan Quan 
1883712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
189e098bc96SEvan Quan 
1903712e7a4SEvan Quan 	ret = pp_funcs->get_asic_baco_capability(pp_handle,
1913712e7a4SEvan Quan 						 &baco_cap);
1923712e7a4SEvan Quan 
1933712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
1943712e7a4SEvan Quan 
1953712e7a4SEvan Quan 	return ret ? false : baco_cap;
196e098bc96SEvan Quan }
197e098bc96SEvan Quan 
198e098bc96SEvan Quan int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev)
199e098bc96SEvan Quan {
200e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
201e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
2023712e7a4SEvan Quan 	int ret = 0;
203e098bc96SEvan Quan 
204e098bc96SEvan Quan 	if (!pp_funcs || !pp_funcs->asic_reset_mode_2)
205e098bc96SEvan Quan 		return -ENOENT;
206e098bc96SEvan Quan 
2073712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
2083712e7a4SEvan Quan 
2093712e7a4SEvan Quan 	ret = pp_funcs->asic_reset_mode_2(pp_handle);
2103712e7a4SEvan Quan 
2113712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
2123712e7a4SEvan Quan 
2133712e7a4SEvan Quan 	return ret;
214e098bc96SEvan Quan }
215e098bc96SEvan Quan 
216e098bc96SEvan Quan int amdgpu_dpm_baco_reset(struct amdgpu_device *adev)
217e098bc96SEvan Quan {
218e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
219e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
220e098bc96SEvan Quan 	int ret = 0;
221e098bc96SEvan Quan 
2229ab5001aSDarren Powell 	if (!pp_funcs || !pp_funcs->set_asic_baco_state)
223e098bc96SEvan Quan 		return -ENOENT;
224e098bc96SEvan Quan 
2253712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
2263712e7a4SEvan Quan 
227e098bc96SEvan Quan 	/* enter BACO state */
228e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
229e098bc96SEvan Quan 	if (ret)
2303712e7a4SEvan Quan 		goto out;
231e098bc96SEvan Quan 
232e098bc96SEvan Quan 	/* exit BACO state */
233e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
234e098bc96SEvan Quan 
2353712e7a4SEvan Quan out:
2363712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
2373712e7a4SEvan Quan 	return ret;
238e098bc96SEvan Quan }
239e098bc96SEvan Quan 
240e098bc96SEvan Quan bool amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device *adev)
241e098bc96SEvan Quan {
242ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
2433712e7a4SEvan Quan 	bool support_mode1_reset = false;
244e098bc96SEvan Quan 
2453712e7a4SEvan Quan 	if (is_support_sw_smu(adev)) {
2463712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
2473712e7a4SEvan Quan 		support_mode1_reset = smu_mode1_reset_is_support(smu);
2483712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
2493712e7a4SEvan Quan 	}
250e098bc96SEvan Quan 
2513712e7a4SEvan Quan 	return support_mode1_reset;
252e098bc96SEvan Quan }
253e098bc96SEvan Quan 
254e098bc96SEvan Quan int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev)
255e098bc96SEvan Quan {
256ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
2573712e7a4SEvan Quan 	int ret = -EOPNOTSUPP;
258e098bc96SEvan Quan 
2593712e7a4SEvan Quan 	if (is_support_sw_smu(adev)) {
2603712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
2613712e7a4SEvan Quan 		ret = smu_mode1_reset(smu);
2623712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
2633712e7a4SEvan Quan 	}
264e098bc96SEvan Quan 
2653712e7a4SEvan Quan 	return ret;
266e098bc96SEvan Quan }
267e098bc96SEvan Quan 
268e098bc96SEvan Quan int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
269e098bc96SEvan Quan 				    enum PP_SMC_POWER_PROFILE type,
270e098bc96SEvan Quan 				    bool en)
271e098bc96SEvan Quan {
272bab0f602SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
273e098bc96SEvan Quan 	int ret = 0;
274e098bc96SEvan Quan 
2757cf7a392SJingwen Chen 	if (amdgpu_sriov_vf(adev))
2767cf7a392SJingwen Chen 		return 0;
2777cf7a392SJingwen Chen 
2783712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->switch_power_profile) {
2793712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
280bab0f602SDarren Powell 		ret = pp_funcs->switch_power_profile(
281e098bc96SEvan Quan 			adev->powerplay.pp_handle, type, en);
2823712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
2833712e7a4SEvan Quan 	}
284e098bc96SEvan Quan 
285e098bc96SEvan Quan 	return ret;
286e098bc96SEvan Quan }
287e098bc96SEvan Quan 
288e098bc96SEvan Quan int amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device *adev,
289e098bc96SEvan Quan 			       uint32_t pstate)
290e098bc96SEvan Quan {
291bab0f602SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
292e098bc96SEvan Quan 	int ret = 0;
293e098bc96SEvan Quan 
2943712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->set_xgmi_pstate) {
2953712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
296bab0f602SDarren Powell 		ret = pp_funcs->set_xgmi_pstate(adev->powerplay.pp_handle,
297e098bc96SEvan Quan 								pstate);
2983712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
2993712e7a4SEvan Quan 	}
300e098bc96SEvan Quan 
301e098bc96SEvan Quan 	return ret;
302e098bc96SEvan Quan }
303e098bc96SEvan Quan 
304e098bc96SEvan Quan int amdgpu_dpm_set_df_cstate(struct amdgpu_device *adev,
305e098bc96SEvan Quan 			     uint32_t cstate)
306e098bc96SEvan Quan {
307e098bc96SEvan Quan 	int ret = 0;
308e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
309e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
310e098bc96SEvan Quan 
3113712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->set_df_cstate) {
3123712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
313e098bc96SEvan Quan 		ret = pp_funcs->set_df_cstate(pp_handle, cstate);
3143712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3153712e7a4SEvan Quan 	}
316e098bc96SEvan Quan 
317e098bc96SEvan Quan 	return ret;
318e098bc96SEvan Quan }
319e098bc96SEvan Quan 
320e098bc96SEvan Quan int amdgpu_dpm_allow_xgmi_power_down(struct amdgpu_device *adev, bool en)
321e098bc96SEvan Quan {
322ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
3233712e7a4SEvan Quan 	int ret = 0;
324e098bc96SEvan Quan 
3253712e7a4SEvan Quan 	if (is_support_sw_smu(adev)) {
3263712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
3273712e7a4SEvan Quan 		ret = smu_allow_xgmi_power_down(smu, en);
3283712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3293712e7a4SEvan Quan 	}
330e098bc96SEvan Quan 
3313712e7a4SEvan Quan 	return ret;
332e098bc96SEvan Quan }
333e098bc96SEvan Quan 
334e098bc96SEvan Quan int amdgpu_dpm_enable_mgpu_fan_boost(struct amdgpu_device *adev)
335e098bc96SEvan Quan {
336e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
337e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs =
338e098bc96SEvan Quan 			adev->powerplay.pp_funcs;
339e098bc96SEvan Quan 	int ret = 0;
340e098bc96SEvan Quan 
3413712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->enable_mgpu_fan_boost) {
3423712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
343e098bc96SEvan Quan 		ret = pp_funcs->enable_mgpu_fan_boost(pp_handle);
3443712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3453712e7a4SEvan Quan 	}
346e098bc96SEvan Quan 
347e098bc96SEvan Quan 	return ret;
348e098bc96SEvan Quan }
349e098bc96SEvan Quan 
350e098bc96SEvan Quan int amdgpu_dpm_set_clockgating_by_smu(struct amdgpu_device *adev,
351e098bc96SEvan Quan 				      uint32_t msg_id)
352e098bc96SEvan Quan {
353e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
354e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs =
355e098bc96SEvan Quan 			adev->powerplay.pp_funcs;
356e098bc96SEvan Quan 	int ret = 0;
357e098bc96SEvan Quan 
3583712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->set_clockgating_by_smu) {
3593712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
360e098bc96SEvan Quan 		ret = pp_funcs->set_clockgating_by_smu(pp_handle,
361e098bc96SEvan Quan 						       msg_id);
3623712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3633712e7a4SEvan Quan 	}
364e098bc96SEvan Quan 
365e098bc96SEvan Quan 	return ret;
366e098bc96SEvan Quan }
367e098bc96SEvan Quan 
368e098bc96SEvan Quan int amdgpu_dpm_smu_i2c_bus_access(struct amdgpu_device *adev,
369e098bc96SEvan Quan 				  bool acquire)
370e098bc96SEvan Quan {
371e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
372e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs =
373e098bc96SEvan Quan 			adev->powerplay.pp_funcs;
374e098bc96SEvan Quan 	int ret = -EOPNOTSUPP;
375e098bc96SEvan Quan 
3763712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->smu_i2c_bus_access) {
3773712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
378e098bc96SEvan Quan 		ret = pp_funcs->smu_i2c_bus_access(pp_handle,
379e098bc96SEvan Quan 						   acquire);
3803712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
3813712e7a4SEvan Quan 	}
382e098bc96SEvan Quan 
383e098bc96SEvan Quan 	return ret;
384e098bc96SEvan Quan }
385e098bc96SEvan Quan 
386e098bc96SEvan Quan void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev)
387e098bc96SEvan Quan {
388e098bc96SEvan Quan 	if (adev->pm.dpm_enabled) {
389e098bc96SEvan Quan 		mutex_lock(&adev->pm.mutex);
390e098bc96SEvan Quan 		if (power_supply_is_system_supplied() > 0)
391e098bc96SEvan Quan 			adev->pm.ac_power = true;
392e098bc96SEvan Quan 		else
393e098bc96SEvan Quan 			adev->pm.ac_power = false;
3943712e7a4SEvan Quan 
395e098bc96SEvan Quan 		if (adev->powerplay.pp_funcs &&
396e098bc96SEvan Quan 		    adev->powerplay.pp_funcs->enable_bapm)
397e098bc96SEvan Quan 			amdgpu_dpm_enable_bapm(adev, adev->pm.ac_power);
398e098bc96SEvan Quan 
399e098bc96SEvan Quan 		if (is_support_sw_smu(adev))
400ebfc2533SEvan Quan 			smu_set_ac_dc(adev->powerplay.pp_handle);
4013712e7a4SEvan Quan 
4023712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
403e098bc96SEvan Quan 	}
404e098bc96SEvan Quan }
405e098bc96SEvan Quan 
406e098bc96SEvan Quan int amdgpu_dpm_read_sensor(struct amdgpu_device *adev, enum amd_pp_sensors sensor,
407e098bc96SEvan Quan 			   void *data, uint32_t *size)
408e098bc96SEvan Quan {
4099ab5001aSDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
4103712e7a4SEvan Quan 	int ret = -EINVAL;
411e098bc96SEvan Quan 
412e098bc96SEvan Quan 	if (!data || !size)
413e098bc96SEvan Quan 		return -EINVAL;
414e098bc96SEvan Quan 
4153712e7a4SEvan Quan 	if (pp_funcs && pp_funcs->read_sensor) {
4163712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
4173712e7a4SEvan Quan 		ret = pp_funcs->read_sensor(adev->powerplay.pp_handle,
4183712e7a4SEvan Quan 					    sensor,
4193712e7a4SEvan Quan 					    data,
4203712e7a4SEvan Quan 					    size);
4213712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
4223712e7a4SEvan Quan 	}
423e098bc96SEvan Quan 
424e098bc96SEvan Quan 	return ret;
425e098bc96SEvan Quan }
426e098bc96SEvan Quan 
42784176663SEvan Quan void amdgpu_dpm_compute_clocks(struct amdgpu_device *adev)
428e098bc96SEvan Quan {
4296ddbd37fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
430e098bc96SEvan Quan 
431e098bc96SEvan Quan 	if (!adev->pm.dpm_enabled)
432e098bc96SEvan Quan 		return;
433e098bc96SEvan Quan 
4346ddbd37fSEvan Quan 	if (!pp_funcs->pm_compute_clocks)
4356ddbd37fSEvan Quan 		return;
436e098bc96SEvan Quan 
4373712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
4386ddbd37fSEvan Quan 	pp_funcs->pm_compute_clocks(adev->powerplay.pp_handle);
4393712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
440e098bc96SEvan Quan }
441e098bc96SEvan Quan 
442e098bc96SEvan Quan void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
443e098bc96SEvan Quan {
444e098bc96SEvan Quan 	int ret = 0;
445e098bc96SEvan Quan 
446e098bc96SEvan Quan 	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable);
447e098bc96SEvan Quan 	if (ret)
448e098bc96SEvan Quan 		DRM_ERROR("Dpm %s uvd failed, ret = %d. \n",
449e098bc96SEvan Quan 			  enable ? "enable" : "disable", ret);
450e098bc96SEvan Quan }
451e098bc96SEvan Quan 
452e098bc96SEvan Quan void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
453e098bc96SEvan Quan {
454e098bc96SEvan Quan 	int ret = 0;
455e098bc96SEvan Quan 
456e098bc96SEvan Quan 	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable);
457e098bc96SEvan Quan 	if (ret)
458e098bc96SEvan Quan 		DRM_ERROR("Dpm %s vce failed, ret = %d. \n",
459e098bc96SEvan Quan 			  enable ? "enable" : "disable", ret);
460e098bc96SEvan Quan }
461e098bc96SEvan Quan 
462e098bc96SEvan Quan void amdgpu_dpm_enable_jpeg(struct amdgpu_device *adev, bool enable)
463e098bc96SEvan Quan {
464e098bc96SEvan Quan 	int ret = 0;
465e098bc96SEvan Quan 
466e098bc96SEvan Quan 	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_JPEG, !enable);
467e098bc96SEvan Quan 	if (ret)
468e098bc96SEvan Quan 		DRM_ERROR("Dpm %s jpeg failed, ret = %d. \n",
469e098bc96SEvan Quan 			  enable ? "enable" : "disable", ret);
470e098bc96SEvan Quan }
471e098bc96SEvan Quan 
472e098bc96SEvan Quan int amdgpu_pm_load_smu_firmware(struct amdgpu_device *adev, uint32_t *smu_version)
473e098bc96SEvan Quan {
4743712e7a4SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
4753712e7a4SEvan Quan 	int r = 0;
476e098bc96SEvan Quan 
4771613f346SFlora Cui 	if (!pp_funcs || !pp_funcs->load_firmware)
4783712e7a4SEvan Quan 		return 0;
4793712e7a4SEvan Quan 
4803712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
4813712e7a4SEvan Quan 	r = pp_funcs->load_firmware(adev->powerplay.pp_handle);
482e098bc96SEvan Quan 	if (r) {
483e098bc96SEvan Quan 		pr_err("smu firmware loading failed\n");
4843712e7a4SEvan Quan 		goto out;
485e098bc96SEvan Quan 	}
4862e4b2f7bSEvan Quan 
4872e4b2f7bSEvan Quan 	if (smu_version)
488e098bc96SEvan Quan 		*smu_version = adev->pm.fw_version;
4892e4b2f7bSEvan Quan 
4903712e7a4SEvan Quan out:
4913712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
4923712e7a4SEvan Quan 	return r;
493e098bc96SEvan Quan }
494bc143d8bSEvan Quan 
495bc143d8bSEvan Quan int amdgpu_dpm_handle_passthrough_sbr(struct amdgpu_device *adev, bool enable)
496bc143d8bSEvan Quan {
4973712e7a4SEvan Quan 	int ret = 0;
4983712e7a4SEvan Quan 
4993712e7a4SEvan Quan 	if (is_support_sw_smu(adev)) {
5003712e7a4SEvan Quan 		mutex_lock(&adev->pm.mutex);
5013712e7a4SEvan Quan 		ret = smu_handle_passthrough_sbr(adev->powerplay.pp_handle,
5023712e7a4SEvan Quan 						 enable);
5033712e7a4SEvan Quan 		mutex_unlock(&adev->pm.mutex);
5043712e7a4SEvan Quan 	}
5053712e7a4SEvan Quan 
5063712e7a4SEvan Quan 	return ret;
507bc143d8bSEvan Quan }
508bc143d8bSEvan Quan 
509bc143d8bSEvan Quan int amdgpu_dpm_send_hbm_bad_pages_num(struct amdgpu_device *adev, uint32_t size)
510bc143d8bSEvan Quan {
511ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
5123712e7a4SEvan Quan 	int ret = 0;
513ebfc2533SEvan Quan 
51493dde6ccSStanley.Yang 	if (!is_support_sw_smu(adev))
51593dde6ccSStanley.Yang 		return -EOPNOTSUPP;
51693dde6ccSStanley.Yang 
5173712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
5183712e7a4SEvan Quan 	ret = smu_send_hbm_bad_pages_num(smu, size);
5193712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
5203712e7a4SEvan Quan 
5213712e7a4SEvan Quan 	return ret;
522bc143d8bSEvan Quan }
523bc143d8bSEvan Quan 
524d510eccfSStanley.Yang int amdgpu_dpm_send_hbm_bad_channel_flag(struct amdgpu_device *adev, uint32_t size)
525d510eccfSStanley.Yang {
526d510eccfSStanley.Yang 	struct smu_context *smu = adev->powerplay.pp_handle;
527d510eccfSStanley.Yang 	int ret = 0;
528d510eccfSStanley.Yang 
52993dde6ccSStanley.Yang 	if (!is_support_sw_smu(adev))
53093dde6ccSStanley.Yang 		return -EOPNOTSUPP;
53193dde6ccSStanley.Yang 
532d510eccfSStanley.Yang 	mutex_lock(&adev->pm.mutex);
533d510eccfSStanley.Yang 	ret = smu_send_hbm_bad_channel_flag(smu, size);
534d510eccfSStanley.Yang 	mutex_unlock(&adev->pm.mutex);
535d510eccfSStanley.Yang 
536d510eccfSStanley.Yang 	return ret;
537d510eccfSStanley.Yang }
538d510eccfSStanley.Yang 
539bc143d8bSEvan Quan int amdgpu_dpm_get_dpm_freq_range(struct amdgpu_device *adev,
540bc143d8bSEvan Quan 				  enum pp_clock_type type,
541bc143d8bSEvan Quan 				  uint32_t *min,
542bc143d8bSEvan Quan 				  uint32_t *max)
543bc143d8bSEvan Quan {
5443712e7a4SEvan Quan 	int ret = 0;
5453712e7a4SEvan Quan 
5463712e7a4SEvan Quan 	if (type != PP_SCLK)
5473712e7a4SEvan Quan 		return -EINVAL;
5483712e7a4SEvan Quan 
549bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
550bc143d8bSEvan Quan 		return -EOPNOTSUPP;
551bc143d8bSEvan Quan 
5523712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
5533712e7a4SEvan Quan 	ret = smu_get_dpm_freq_range(adev->powerplay.pp_handle,
5543712e7a4SEvan Quan 				     SMU_SCLK,
5553712e7a4SEvan Quan 				     min,
5563712e7a4SEvan Quan 				     max);
5573712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
5583712e7a4SEvan Quan 
5593712e7a4SEvan Quan 	return ret;
560bc143d8bSEvan Quan }
561bc143d8bSEvan Quan 
562bc143d8bSEvan Quan int amdgpu_dpm_set_soft_freq_range(struct amdgpu_device *adev,
563bc143d8bSEvan Quan 				   enum pp_clock_type type,
564bc143d8bSEvan Quan 				   uint32_t min,
565bc143d8bSEvan Quan 				   uint32_t max)
566bc143d8bSEvan Quan {
567ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
5683712e7a4SEvan Quan 	int ret = 0;
5693712e7a4SEvan Quan 
5703712e7a4SEvan Quan 	if (type != PP_SCLK)
5713712e7a4SEvan Quan 		return -EINVAL;
572ebfc2533SEvan Quan 
573bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
574bc143d8bSEvan Quan 		return -EOPNOTSUPP;
575bc143d8bSEvan Quan 
5763712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
5773712e7a4SEvan Quan 	ret = smu_set_soft_freq_range(smu,
5783712e7a4SEvan Quan 				      SMU_SCLK,
5793712e7a4SEvan Quan 				      min,
5803712e7a4SEvan Quan 				      max);
5813712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
5823712e7a4SEvan Quan 
5833712e7a4SEvan Quan 	return ret;
584bc143d8bSEvan Quan }
585bc143d8bSEvan Quan 
58613f5dbd6SEvan Quan int amdgpu_dpm_write_watermarks_table(struct amdgpu_device *adev)
58713f5dbd6SEvan Quan {
588ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
5893712e7a4SEvan Quan 	int ret = 0;
590ebfc2533SEvan Quan 
59113f5dbd6SEvan Quan 	if (!is_support_sw_smu(adev))
59213f5dbd6SEvan Quan 		return 0;
59313f5dbd6SEvan Quan 
5943712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
5953712e7a4SEvan Quan 	ret = smu_write_watermarks_table(smu);
5963712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
5973712e7a4SEvan Quan 
5983712e7a4SEvan Quan 	return ret;
59913f5dbd6SEvan Quan }
60013f5dbd6SEvan Quan 
601bc143d8bSEvan Quan int amdgpu_dpm_wait_for_event(struct amdgpu_device *adev,
602bc143d8bSEvan Quan 			      enum smu_event_type event,
603bc143d8bSEvan Quan 			      uint64_t event_arg)
604bc143d8bSEvan Quan {
605ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
6063712e7a4SEvan Quan 	int ret = 0;
607ebfc2533SEvan Quan 
608bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
609bc143d8bSEvan Quan 		return -EOPNOTSUPP;
610bc143d8bSEvan Quan 
6113712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
6123712e7a4SEvan Quan 	ret = smu_wait_for_event(smu, event, event_arg);
6133712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
6143712e7a4SEvan Quan 
6153712e7a4SEvan Quan 	return ret;
616bc143d8bSEvan Quan }
617bc143d8bSEvan Quan 
618bc143d8bSEvan Quan int amdgpu_dpm_get_status_gfxoff(struct amdgpu_device *adev, uint32_t *value)
619bc143d8bSEvan Quan {
620ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
6213712e7a4SEvan Quan 	int ret = 0;
622ebfc2533SEvan Quan 
623bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
624bc143d8bSEvan Quan 		return -EOPNOTSUPP;
625bc143d8bSEvan Quan 
6263712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
6273712e7a4SEvan Quan 	ret = smu_get_status_gfxoff(smu, value);
6283712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
6293712e7a4SEvan Quan 
6303712e7a4SEvan Quan 	return ret;
631bc143d8bSEvan Quan }
632bc143d8bSEvan Quan 
633bc143d8bSEvan Quan uint64_t amdgpu_dpm_get_thermal_throttling_counter(struct amdgpu_device *adev)
634bc143d8bSEvan Quan {
635ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
636ebfc2533SEvan Quan 
6373712e7a4SEvan Quan 	if (!is_support_sw_smu(adev))
6383712e7a4SEvan Quan 		return 0;
6393712e7a4SEvan Quan 
640ebfc2533SEvan Quan 	return atomic64_read(&smu->throttle_int_counter);
641bc143d8bSEvan Quan }
642bc143d8bSEvan Quan 
643bc143d8bSEvan Quan /* amdgpu_dpm_gfx_state_change - Handle gfx power state change set
644bc143d8bSEvan Quan  * @adev: amdgpu_device pointer
645bc143d8bSEvan Quan  * @state: gfx power state(1 -sGpuChangeState_D0Entry and 2 -sGpuChangeState_D3Entry)
646bc143d8bSEvan Quan  *
647bc143d8bSEvan Quan  */
648bc143d8bSEvan Quan void amdgpu_dpm_gfx_state_change(struct amdgpu_device *adev,
649bc143d8bSEvan Quan 				 enum gfx_change_state state)
650bc143d8bSEvan Quan {
651bc143d8bSEvan Quan 	mutex_lock(&adev->pm.mutex);
652bc143d8bSEvan Quan 	if (adev->powerplay.pp_funcs &&
653bc143d8bSEvan Quan 	    adev->powerplay.pp_funcs->gfx_state_change_set)
654bc143d8bSEvan Quan 		((adev)->powerplay.pp_funcs->gfx_state_change_set(
655bc143d8bSEvan Quan 			(adev)->powerplay.pp_handle, state));
656bc143d8bSEvan Quan 	mutex_unlock(&adev->pm.mutex);
657bc143d8bSEvan Quan }
658bc143d8bSEvan Quan 
659bc143d8bSEvan Quan int amdgpu_dpm_get_ecc_info(struct amdgpu_device *adev,
660bc143d8bSEvan Quan 			    void *umc_ecc)
661bc143d8bSEvan Quan {
662ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
663a29d44aeSStanley.Yang 	int ret = 0;
664ebfc2533SEvan Quan 
665bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
666bc143d8bSEvan Quan 		return -EOPNOTSUPP;
667bc143d8bSEvan Quan 
668a29d44aeSStanley.Yang 	mutex_lock(&adev->pm.mutex);
669a29d44aeSStanley.Yang 	ret = smu_get_ecc_info(smu, umc_ecc);
670a29d44aeSStanley.Yang 	mutex_unlock(&adev->pm.mutex);
671a29d44aeSStanley.Yang 
672a29d44aeSStanley.Yang 	return ret;
673bc143d8bSEvan Quan }
67479c65f3fSEvan Quan 
67579c65f3fSEvan Quan struct amd_vce_state *amdgpu_dpm_get_vce_clock_state(struct amdgpu_device *adev,
67679c65f3fSEvan Quan 						     uint32_t idx)
67779c65f3fSEvan Quan {
67879c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
6793712e7a4SEvan Quan 	struct amd_vce_state *vstate = NULL;
68079c65f3fSEvan Quan 
68179c65f3fSEvan Quan 	if (!pp_funcs->get_vce_clock_state)
68279c65f3fSEvan Quan 		return NULL;
68379c65f3fSEvan Quan 
6843712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
6853712e7a4SEvan Quan 	vstate = pp_funcs->get_vce_clock_state(adev->powerplay.pp_handle,
68679c65f3fSEvan Quan 					       idx);
6873712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
6883712e7a4SEvan Quan 
6893712e7a4SEvan Quan 	return vstate;
69079c65f3fSEvan Quan }
69179c65f3fSEvan Quan 
69279c65f3fSEvan Quan void amdgpu_dpm_get_current_power_state(struct amdgpu_device *adev,
69379c65f3fSEvan Quan 					enum amd_pm_state_type *state)
69479c65f3fSEvan Quan {
69579c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
69679c65f3fSEvan Quan 
6973712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
6983712e7a4SEvan Quan 
69979c65f3fSEvan Quan 	if (!pp_funcs->get_current_power_state) {
70079c65f3fSEvan Quan 		*state = adev->pm.dpm.user_state;
7013712e7a4SEvan Quan 		goto out;
70279c65f3fSEvan Quan 	}
70379c65f3fSEvan Quan 
70479c65f3fSEvan Quan 	*state = pp_funcs->get_current_power_state(adev->powerplay.pp_handle);
70579c65f3fSEvan Quan 	if (*state < POWER_STATE_TYPE_DEFAULT ||
70679c65f3fSEvan Quan 	    *state > POWER_STATE_TYPE_INTERNAL_3DPERF)
70779c65f3fSEvan Quan 		*state = adev->pm.dpm.user_state;
7083712e7a4SEvan Quan 
7093712e7a4SEvan Quan out:
7103712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
71179c65f3fSEvan Quan }
71279c65f3fSEvan Quan 
71379c65f3fSEvan Quan void amdgpu_dpm_set_power_state(struct amdgpu_device *adev,
71479c65f3fSEvan Quan 				enum amd_pm_state_type state)
71579c65f3fSEvan Quan {
7163712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
71779c65f3fSEvan Quan 	adev->pm.dpm.user_state = state;
7183712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
71979c65f3fSEvan Quan 
72079c65f3fSEvan Quan 	if (is_support_sw_smu(adev))
72179c65f3fSEvan Quan 		return;
72279c65f3fSEvan Quan 
72379c65f3fSEvan Quan 	if (amdgpu_dpm_dispatch_task(adev,
72479c65f3fSEvan Quan 				     AMD_PP_TASK_ENABLE_USER_STATE,
72579c65f3fSEvan Quan 				     &state) == -EOPNOTSUPP)
72684176663SEvan Quan 		amdgpu_dpm_compute_clocks(adev);
72779c65f3fSEvan Quan }
72879c65f3fSEvan Quan 
72975513bf5SEvan Quan enum amd_dpm_forced_level amdgpu_dpm_get_performance_level(struct amdgpu_device *adev)
73079c65f3fSEvan Quan {
73179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
73279c65f3fSEvan Quan 	enum amd_dpm_forced_level level;
73379c65f3fSEvan Quan 
73475513bf5SEvan Quan 	mutex_lock(&adev->pm.mutex);
73579c65f3fSEvan Quan 	if (pp_funcs->get_performance_level)
73679c65f3fSEvan Quan 		level = pp_funcs->get_performance_level(adev->powerplay.pp_handle);
73779c65f3fSEvan Quan 	else
73879c65f3fSEvan Quan 		level = adev->pm.dpm.forced_level;
7393712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
74079c65f3fSEvan Quan 
74179c65f3fSEvan Quan 	return level;
74279c65f3fSEvan Quan }
74379c65f3fSEvan Quan 
74479c65f3fSEvan Quan int amdgpu_dpm_force_performance_level(struct amdgpu_device *adev,
74579c65f3fSEvan Quan 				       enum amd_dpm_forced_level level)
74679c65f3fSEvan Quan {
74779c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
74854c73b51SAlex Deucher 	enum amd_dpm_forced_level current_level;
74954c73b51SAlex Deucher 	uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
75054c73b51SAlex Deucher 					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
75154c73b51SAlex Deucher 					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
75254c73b51SAlex Deucher 					AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
75379c65f3fSEvan Quan 
754*eea5c7b3SHuang Rui 	if (!pp_funcs || !pp_funcs->force_performance_level)
7553712e7a4SEvan Quan 		return 0;
7563712e7a4SEvan Quan 
75775513bf5SEvan Quan 	if (adev->pm.dpm.thermal_active)
75875513bf5SEvan Quan 		return -EINVAL;
7593712e7a4SEvan Quan 
76075513bf5SEvan Quan 	current_level = amdgpu_dpm_get_performance_level(adev);
76175513bf5SEvan Quan 	if (current_level == level)
76275513bf5SEvan Quan 		return 0;
76354c73b51SAlex Deucher 
76454c73b51SAlex Deucher 	if (adev->asic_type == CHIP_RAVEN) {
76554c73b51SAlex Deucher 		if (!(adev->apu_flags & AMD_APU_IS_RAVEN2)) {
76654c73b51SAlex Deucher 			if (current_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
76754c73b51SAlex Deucher 			    level == AMD_DPM_FORCED_LEVEL_MANUAL)
76854c73b51SAlex Deucher 				amdgpu_gfx_off_ctrl(adev, false);
76954c73b51SAlex Deucher 			else if (current_level == AMD_DPM_FORCED_LEVEL_MANUAL &&
77054c73b51SAlex Deucher 				 level != AMD_DPM_FORCED_LEVEL_MANUAL)
77154c73b51SAlex Deucher 				amdgpu_gfx_off_ctrl(adev, true);
77254c73b51SAlex Deucher 		}
77354c73b51SAlex Deucher 	}
77454c73b51SAlex Deucher 
77554c73b51SAlex Deucher 	if (!(current_level & profile_mode_mask) &&
77675513bf5SEvan Quan 	    (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT))
77775513bf5SEvan Quan 		return -EINVAL;
77854c73b51SAlex Deucher 
77954c73b51SAlex Deucher 	if (!(current_level & profile_mode_mask) &&
78054c73b51SAlex Deucher 	      (level & profile_mode_mask)) {
78154c73b51SAlex Deucher 		/* enter UMD Pstate */
78254c73b51SAlex Deucher 		amdgpu_device_ip_set_powergating_state(adev,
78354c73b51SAlex Deucher 						       AMD_IP_BLOCK_TYPE_GFX,
78454c73b51SAlex Deucher 						       AMD_PG_STATE_UNGATE);
78554c73b51SAlex Deucher 		amdgpu_device_ip_set_clockgating_state(adev,
78654c73b51SAlex Deucher 						       AMD_IP_BLOCK_TYPE_GFX,
78754c73b51SAlex Deucher 						       AMD_CG_STATE_UNGATE);
78854c73b51SAlex Deucher 	} else if ((current_level & profile_mode_mask) &&
78954c73b51SAlex Deucher 		    !(level & profile_mode_mask)) {
79054c73b51SAlex Deucher 		/* exit UMD Pstate */
79154c73b51SAlex Deucher 		amdgpu_device_ip_set_clockgating_state(adev,
79254c73b51SAlex Deucher 						       AMD_IP_BLOCK_TYPE_GFX,
79354c73b51SAlex Deucher 						       AMD_CG_STATE_GATE);
79454c73b51SAlex Deucher 		amdgpu_device_ip_set_powergating_state(adev,
79554c73b51SAlex Deucher 						       AMD_IP_BLOCK_TYPE_GFX,
79654c73b51SAlex Deucher 						       AMD_PG_STATE_GATE);
79754c73b51SAlex Deucher 	}
79854c73b51SAlex Deucher 
79975513bf5SEvan Quan 	mutex_lock(&adev->pm.mutex);
80079c65f3fSEvan Quan 
80175513bf5SEvan Quan 	if (pp_funcs->force_performance_level(adev->powerplay.pp_handle,
80275513bf5SEvan Quan 					      level)) {
80375513bf5SEvan Quan 		mutex_unlock(&adev->pm.mutex);
80475513bf5SEvan Quan 		return -EINVAL;
80575513bf5SEvan Quan 	}
80675513bf5SEvan Quan 
80779c65f3fSEvan Quan 	adev->pm.dpm.forced_level = level;
80879c65f3fSEvan Quan 
8093712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
8103712e7a4SEvan Quan 
81175513bf5SEvan Quan 	return 0;
81279c65f3fSEvan Quan }
81379c65f3fSEvan Quan 
81479c65f3fSEvan Quan int amdgpu_dpm_get_pp_num_states(struct amdgpu_device *adev,
81579c65f3fSEvan Quan 				 struct pp_states_info *states)
81679c65f3fSEvan Quan {
81779c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8183712e7a4SEvan Quan 	int ret = 0;
81979c65f3fSEvan Quan 
82079c65f3fSEvan Quan 	if (!pp_funcs->get_pp_num_states)
82179c65f3fSEvan Quan 		return -EOPNOTSUPP;
82279c65f3fSEvan Quan 
8233712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
8243712e7a4SEvan Quan 	ret = pp_funcs->get_pp_num_states(adev->powerplay.pp_handle,
8253712e7a4SEvan Quan 					  states);
8263712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
8273712e7a4SEvan Quan 
8283712e7a4SEvan Quan 	return ret;
82979c65f3fSEvan Quan }
83079c65f3fSEvan Quan 
83179c65f3fSEvan Quan int amdgpu_dpm_dispatch_task(struct amdgpu_device *adev,
83279c65f3fSEvan Quan 			      enum amd_pp_task task_id,
83379c65f3fSEvan Quan 			      enum amd_pm_state_type *user_state)
83479c65f3fSEvan Quan {
83579c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8363712e7a4SEvan Quan 	int ret = 0;
83779c65f3fSEvan Quan 
83879c65f3fSEvan Quan 	if (!pp_funcs->dispatch_tasks)
83979c65f3fSEvan Quan 		return -EOPNOTSUPP;
84079c65f3fSEvan Quan 
8413712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
8423712e7a4SEvan Quan 	ret = pp_funcs->dispatch_tasks(adev->powerplay.pp_handle,
8433712e7a4SEvan Quan 				       task_id,
8443712e7a4SEvan Quan 				       user_state);
8453712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
8463712e7a4SEvan Quan 
8473712e7a4SEvan Quan 	return ret;
84879c65f3fSEvan Quan }
84979c65f3fSEvan Quan 
85079c65f3fSEvan Quan int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char **table)
85179c65f3fSEvan Quan {
85279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8533712e7a4SEvan Quan 	int ret = 0;
85479c65f3fSEvan Quan 
85579c65f3fSEvan Quan 	if (!pp_funcs->get_pp_table)
85679c65f3fSEvan Quan 		return 0;
85779c65f3fSEvan Quan 
8583712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
8593712e7a4SEvan Quan 	ret = pp_funcs->get_pp_table(adev->powerplay.pp_handle,
8603712e7a4SEvan Quan 				     table);
8613712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
8623712e7a4SEvan Quan 
8633712e7a4SEvan Quan 	return ret;
86479c65f3fSEvan Quan }
86579c65f3fSEvan Quan 
86679c65f3fSEvan Quan int amdgpu_dpm_set_fine_grain_clk_vol(struct amdgpu_device *adev,
86779c65f3fSEvan Quan 				      uint32_t type,
86879c65f3fSEvan Quan 				      long *input,
86979c65f3fSEvan Quan 				      uint32_t size)
87079c65f3fSEvan Quan {
87179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8723712e7a4SEvan Quan 	int ret = 0;
87379c65f3fSEvan Quan 
87479c65f3fSEvan Quan 	if (!pp_funcs->set_fine_grain_clk_vol)
87579c65f3fSEvan Quan 		return 0;
87679c65f3fSEvan Quan 
8773712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
8783712e7a4SEvan Quan 	ret = pp_funcs->set_fine_grain_clk_vol(adev->powerplay.pp_handle,
87979c65f3fSEvan Quan 					       type,
88079c65f3fSEvan Quan 					       input,
88179c65f3fSEvan Quan 					       size);
8823712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
8833712e7a4SEvan Quan 
8843712e7a4SEvan Quan 	return ret;
88579c65f3fSEvan Quan }
88679c65f3fSEvan Quan 
88779c65f3fSEvan Quan int amdgpu_dpm_odn_edit_dpm_table(struct amdgpu_device *adev,
88879c65f3fSEvan Quan 				  uint32_t type,
88979c65f3fSEvan Quan 				  long *input,
89079c65f3fSEvan Quan 				  uint32_t size)
89179c65f3fSEvan Quan {
89279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8933712e7a4SEvan Quan 	int ret = 0;
89479c65f3fSEvan Quan 
89579c65f3fSEvan Quan 	if (!pp_funcs->odn_edit_dpm_table)
89679c65f3fSEvan Quan 		return 0;
89779c65f3fSEvan Quan 
8983712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
8993712e7a4SEvan Quan 	ret = pp_funcs->odn_edit_dpm_table(adev->powerplay.pp_handle,
90079c65f3fSEvan Quan 					   type,
90179c65f3fSEvan Quan 					   input,
90279c65f3fSEvan Quan 					   size);
9033712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
9043712e7a4SEvan Quan 
9053712e7a4SEvan Quan 	return ret;
90679c65f3fSEvan Quan }
90779c65f3fSEvan Quan 
90879c65f3fSEvan Quan int amdgpu_dpm_print_clock_levels(struct amdgpu_device *adev,
90979c65f3fSEvan Quan 				  enum pp_clock_type type,
91079c65f3fSEvan Quan 				  char *buf)
91179c65f3fSEvan Quan {
91279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9133712e7a4SEvan Quan 	int ret = 0;
91479c65f3fSEvan Quan 
91579c65f3fSEvan Quan 	if (!pp_funcs->print_clock_levels)
91679c65f3fSEvan Quan 		return 0;
91779c65f3fSEvan Quan 
9183712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
9193712e7a4SEvan Quan 	ret = pp_funcs->print_clock_levels(adev->powerplay.pp_handle,
92079c65f3fSEvan Quan 					   type,
92179c65f3fSEvan Quan 					   buf);
9223712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
9233712e7a4SEvan Quan 
9243712e7a4SEvan Quan 	return ret;
92579c65f3fSEvan Quan }
92679c65f3fSEvan Quan 
9275d64f9bbSDarren Powell int amdgpu_dpm_emit_clock_levels(struct amdgpu_device *adev,
9285d64f9bbSDarren Powell 				  enum pp_clock_type type,
9295d64f9bbSDarren Powell 				  char *buf,
9305d64f9bbSDarren Powell 				  int *offset)
9315d64f9bbSDarren Powell {
9325d64f9bbSDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9335d64f9bbSDarren Powell 	int ret = 0;
9345d64f9bbSDarren Powell 
9355d64f9bbSDarren Powell 	if (!pp_funcs->emit_clock_levels)
9365d64f9bbSDarren Powell 		return -ENOENT;
9375d64f9bbSDarren Powell 
9385d64f9bbSDarren Powell 	mutex_lock(&adev->pm.mutex);
9395d64f9bbSDarren Powell 	ret = pp_funcs->emit_clock_levels(adev->powerplay.pp_handle,
9405d64f9bbSDarren Powell 					   type,
9415d64f9bbSDarren Powell 					   buf,
9425d64f9bbSDarren Powell 					   offset);
9435d64f9bbSDarren Powell 	mutex_unlock(&adev->pm.mutex);
9445d64f9bbSDarren Powell 
9455d64f9bbSDarren Powell 	return ret;
9465d64f9bbSDarren Powell }
9475d64f9bbSDarren Powell 
94879c65f3fSEvan Quan int amdgpu_dpm_set_ppfeature_status(struct amdgpu_device *adev,
94979c65f3fSEvan Quan 				    uint64_t ppfeature_masks)
95079c65f3fSEvan Quan {
95179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9523712e7a4SEvan Quan 	int ret = 0;
95379c65f3fSEvan Quan 
95479c65f3fSEvan Quan 	if (!pp_funcs->set_ppfeature_status)
95579c65f3fSEvan Quan 		return 0;
95679c65f3fSEvan Quan 
9573712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
9583712e7a4SEvan Quan 	ret = pp_funcs->set_ppfeature_status(adev->powerplay.pp_handle,
95979c65f3fSEvan Quan 					     ppfeature_masks);
9603712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
9613712e7a4SEvan Quan 
9623712e7a4SEvan Quan 	return ret;
96379c65f3fSEvan Quan }
96479c65f3fSEvan Quan 
96579c65f3fSEvan Quan int amdgpu_dpm_get_ppfeature_status(struct amdgpu_device *adev, char *buf)
96679c65f3fSEvan Quan {
96779c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9683712e7a4SEvan Quan 	int ret = 0;
96979c65f3fSEvan Quan 
97079c65f3fSEvan Quan 	if (!pp_funcs->get_ppfeature_status)
97179c65f3fSEvan Quan 		return 0;
97279c65f3fSEvan Quan 
9733712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
9743712e7a4SEvan Quan 	ret = pp_funcs->get_ppfeature_status(adev->powerplay.pp_handle,
97579c65f3fSEvan Quan 					     buf);
9763712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
9773712e7a4SEvan Quan 
9783712e7a4SEvan Quan 	return ret;
97979c65f3fSEvan Quan }
98079c65f3fSEvan Quan 
98179c65f3fSEvan Quan int amdgpu_dpm_force_clock_level(struct amdgpu_device *adev,
98279c65f3fSEvan Quan 				 enum pp_clock_type type,
98379c65f3fSEvan Quan 				 uint32_t mask)
98479c65f3fSEvan Quan {
98579c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9863712e7a4SEvan Quan 	int ret = 0;
98779c65f3fSEvan Quan 
98879c65f3fSEvan Quan 	if (!pp_funcs->force_clock_level)
98979c65f3fSEvan Quan 		return 0;
99079c65f3fSEvan Quan 
9913712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
9923712e7a4SEvan Quan 	ret = pp_funcs->force_clock_level(adev->powerplay.pp_handle,
99379c65f3fSEvan Quan 					  type,
99479c65f3fSEvan Quan 					  mask);
9953712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
9963712e7a4SEvan Quan 
9973712e7a4SEvan Quan 	return ret;
99879c65f3fSEvan Quan }
99979c65f3fSEvan Quan 
100079c65f3fSEvan Quan int amdgpu_dpm_get_sclk_od(struct amdgpu_device *adev)
100179c65f3fSEvan Quan {
100279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10033712e7a4SEvan Quan 	int ret = 0;
100479c65f3fSEvan Quan 
100579c65f3fSEvan Quan 	if (!pp_funcs->get_sclk_od)
100679c65f3fSEvan Quan 		return 0;
100779c65f3fSEvan Quan 
10083712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
10093712e7a4SEvan Quan 	ret = pp_funcs->get_sclk_od(adev->powerplay.pp_handle);
10103712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
10113712e7a4SEvan Quan 
10123712e7a4SEvan Quan 	return ret;
101379c65f3fSEvan Quan }
101479c65f3fSEvan Quan 
101579c65f3fSEvan Quan int amdgpu_dpm_set_sclk_od(struct amdgpu_device *adev, uint32_t value)
101679c65f3fSEvan Quan {
101779c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
101879c65f3fSEvan Quan 
101979c65f3fSEvan Quan 	if (is_support_sw_smu(adev))
102079c65f3fSEvan Quan 		return 0;
102179c65f3fSEvan Quan 
10223712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
102379c65f3fSEvan Quan 	if (pp_funcs->set_sclk_od)
102479c65f3fSEvan Quan 		pp_funcs->set_sclk_od(adev->powerplay.pp_handle, value);
10253712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
102679c65f3fSEvan Quan 
102779c65f3fSEvan Quan 	if (amdgpu_dpm_dispatch_task(adev,
102879c65f3fSEvan Quan 				     AMD_PP_TASK_READJUST_POWER_STATE,
102979c65f3fSEvan Quan 				     NULL) == -EOPNOTSUPP) {
103079c65f3fSEvan Quan 		adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
103184176663SEvan Quan 		amdgpu_dpm_compute_clocks(adev);
103279c65f3fSEvan Quan 	}
103379c65f3fSEvan Quan 
103479c65f3fSEvan Quan 	return 0;
103579c65f3fSEvan Quan }
103679c65f3fSEvan Quan 
103779c65f3fSEvan Quan int amdgpu_dpm_get_mclk_od(struct amdgpu_device *adev)
103879c65f3fSEvan Quan {
103979c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10403712e7a4SEvan Quan 	int ret = 0;
104179c65f3fSEvan Quan 
104279c65f3fSEvan Quan 	if (!pp_funcs->get_mclk_od)
104379c65f3fSEvan Quan 		return 0;
104479c65f3fSEvan Quan 
10453712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
10463712e7a4SEvan Quan 	ret = pp_funcs->get_mclk_od(adev->powerplay.pp_handle);
10473712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
10483712e7a4SEvan Quan 
10493712e7a4SEvan Quan 	return ret;
105079c65f3fSEvan Quan }
105179c65f3fSEvan Quan 
105279c65f3fSEvan Quan int amdgpu_dpm_set_mclk_od(struct amdgpu_device *adev, uint32_t value)
105379c65f3fSEvan Quan {
105479c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
105579c65f3fSEvan Quan 
105679c65f3fSEvan Quan 	if (is_support_sw_smu(adev))
105779c65f3fSEvan Quan 		return 0;
105879c65f3fSEvan Quan 
10593712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
106079c65f3fSEvan Quan 	if (pp_funcs->set_mclk_od)
106179c65f3fSEvan Quan 		pp_funcs->set_mclk_od(adev->powerplay.pp_handle, value);
10623712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
106379c65f3fSEvan Quan 
106479c65f3fSEvan Quan 	if (amdgpu_dpm_dispatch_task(adev,
106579c65f3fSEvan Quan 				     AMD_PP_TASK_READJUST_POWER_STATE,
106679c65f3fSEvan Quan 				     NULL) == -EOPNOTSUPP) {
106779c65f3fSEvan Quan 		adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
106884176663SEvan Quan 		amdgpu_dpm_compute_clocks(adev);
106979c65f3fSEvan Quan 	}
107079c65f3fSEvan Quan 
107179c65f3fSEvan Quan 	return 0;
107279c65f3fSEvan Quan }
107379c65f3fSEvan Quan 
107479c65f3fSEvan Quan int amdgpu_dpm_get_power_profile_mode(struct amdgpu_device *adev,
107579c65f3fSEvan Quan 				      char *buf)
107679c65f3fSEvan Quan {
107779c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10783712e7a4SEvan Quan 	int ret = 0;
107979c65f3fSEvan Quan 
108079c65f3fSEvan Quan 	if (!pp_funcs->get_power_profile_mode)
108179c65f3fSEvan Quan 		return -EOPNOTSUPP;
108279c65f3fSEvan Quan 
10833712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
10843712e7a4SEvan Quan 	ret = pp_funcs->get_power_profile_mode(adev->powerplay.pp_handle,
108579c65f3fSEvan Quan 					       buf);
10863712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
10873712e7a4SEvan Quan 
10883712e7a4SEvan Quan 	return ret;
108979c65f3fSEvan Quan }
109079c65f3fSEvan Quan 
109179c65f3fSEvan Quan int amdgpu_dpm_set_power_profile_mode(struct amdgpu_device *adev,
109279c65f3fSEvan Quan 				      long *input, uint32_t size)
109379c65f3fSEvan Quan {
109479c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10953712e7a4SEvan Quan 	int ret = 0;
109679c65f3fSEvan Quan 
109779c65f3fSEvan Quan 	if (!pp_funcs->set_power_profile_mode)
109879c65f3fSEvan Quan 		return 0;
109979c65f3fSEvan Quan 
11003712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11013712e7a4SEvan Quan 	ret = pp_funcs->set_power_profile_mode(adev->powerplay.pp_handle,
110279c65f3fSEvan Quan 					       input,
110379c65f3fSEvan Quan 					       size);
11043712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11053712e7a4SEvan Quan 
11063712e7a4SEvan Quan 	return ret;
110779c65f3fSEvan Quan }
110879c65f3fSEvan Quan 
110979c65f3fSEvan Quan int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void **table)
111079c65f3fSEvan Quan {
111179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11123712e7a4SEvan Quan 	int ret = 0;
111379c65f3fSEvan Quan 
111479c65f3fSEvan Quan 	if (!pp_funcs->get_gpu_metrics)
111579c65f3fSEvan Quan 		return 0;
111679c65f3fSEvan Quan 
11173712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11183712e7a4SEvan Quan 	ret = pp_funcs->get_gpu_metrics(adev->powerplay.pp_handle,
11193712e7a4SEvan Quan 					table);
11203712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11213712e7a4SEvan Quan 
11223712e7a4SEvan Quan 	return ret;
112379c65f3fSEvan Quan }
112479c65f3fSEvan Quan 
112579c65f3fSEvan Quan int amdgpu_dpm_get_fan_control_mode(struct amdgpu_device *adev,
112679c65f3fSEvan Quan 				    uint32_t *fan_mode)
112779c65f3fSEvan Quan {
112879c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1129685fae24SEvan Quan 	int ret = 0;
113079c65f3fSEvan Quan 
113179c65f3fSEvan Quan 	if (!pp_funcs->get_fan_control_mode)
113279c65f3fSEvan Quan 		return -EOPNOTSUPP;
113379c65f3fSEvan Quan 
11343712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
1135685fae24SEvan Quan 	ret = pp_funcs->get_fan_control_mode(adev->powerplay.pp_handle,
1136685fae24SEvan Quan 					     fan_mode);
11373712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
113879c65f3fSEvan Quan 
1139685fae24SEvan Quan 	return ret;
114079c65f3fSEvan Quan }
114179c65f3fSEvan Quan 
114279c65f3fSEvan Quan int amdgpu_dpm_set_fan_speed_pwm(struct amdgpu_device *adev,
114379c65f3fSEvan Quan 				 uint32_t speed)
114479c65f3fSEvan Quan {
114579c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11463712e7a4SEvan Quan 	int ret = 0;
114779c65f3fSEvan Quan 
114879c65f3fSEvan Quan 	if (!pp_funcs->set_fan_speed_pwm)
1149685fae24SEvan Quan 		return -EOPNOTSUPP;
115079c65f3fSEvan Quan 
11513712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11523712e7a4SEvan Quan 	ret = pp_funcs->set_fan_speed_pwm(adev->powerplay.pp_handle,
11533712e7a4SEvan Quan 					  speed);
11543712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11553712e7a4SEvan Quan 
11563712e7a4SEvan Quan 	return ret;
115779c65f3fSEvan Quan }
115879c65f3fSEvan Quan 
115979c65f3fSEvan Quan int amdgpu_dpm_get_fan_speed_pwm(struct amdgpu_device *adev,
116079c65f3fSEvan Quan 				 uint32_t *speed)
116179c65f3fSEvan Quan {
116279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11633712e7a4SEvan Quan 	int ret = 0;
116479c65f3fSEvan Quan 
116579c65f3fSEvan Quan 	if (!pp_funcs->get_fan_speed_pwm)
1166685fae24SEvan Quan 		return -EOPNOTSUPP;
116779c65f3fSEvan Quan 
11683712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11693712e7a4SEvan Quan 	ret = pp_funcs->get_fan_speed_pwm(adev->powerplay.pp_handle,
11703712e7a4SEvan Quan 					  speed);
11713712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11723712e7a4SEvan Quan 
11733712e7a4SEvan Quan 	return ret;
117479c65f3fSEvan Quan }
117579c65f3fSEvan Quan 
117679c65f3fSEvan Quan int amdgpu_dpm_get_fan_speed_rpm(struct amdgpu_device *adev,
117779c65f3fSEvan Quan 				 uint32_t *speed)
117879c65f3fSEvan Quan {
117979c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11803712e7a4SEvan Quan 	int ret = 0;
118179c65f3fSEvan Quan 
118279c65f3fSEvan Quan 	if (!pp_funcs->get_fan_speed_rpm)
1183685fae24SEvan Quan 		return -EOPNOTSUPP;
118479c65f3fSEvan Quan 
11853712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
11863712e7a4SEvan Quan 	ret = pp_funcs->get_fan_speed_rpm(adev->powerplay.pp_handle,
11873712e7a4SEvan Quan 					  speed);
11883712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
11893712e7a4SEvan Quan 
11903712e7a4SEvan Quan 	return ret;
119179c65f3fSEvan Quan }
119279c65f3fSEvan Quan 
119379c65f3fSEvan Quan int amdgpu_dpm_set_fan_speed_rpm(struct amdgpu_device *adev,
119479c65f3fSEvan Quan 				 uint32_t speed)
119579c65f3fSEvan Quan {
119679c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11973712e7a4SEvan Quan 	int ret = 0;
119879c65f3fSEvan Quan 
119979c65f3fSEvan Quan 	if (!pp_funcs->set_fan_speed_rpm)
1200685fae24SEvan Quan 		return -EOPNOTSUPP;
120179c65f3fSEvan Quan 
12023712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
12033712e7a4SEvan Quan 	ret = pp_funcs->set_fan_speed_rpm(adev->powerplay.pp_handle,
12043712e7a4SEvan Quan 					  speed);
12053712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
12063712e7a4SEvan Quan 
12073712e7a4SEvan Quan 	return ret;
120879c65f3fSEvan Quan }
120979c65f3fSEvan Quan 
121079c65f3fSEvan Quan int amdgpu_dpm_set_fan_control_mode(struct amdgpu_device *adev,
121179c65f3fSEvan Quan 				    uint32_t mode)
121279c65f3fSEvan Quan {
121379c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1214685fae24SEvan Quan 	int ret = 0;
121579c65f3fSEvan Quan 
121679c65f3fSEvan Quan 	if (!pp_funcs->set_fan_control_mode)
121779c65f3fSEvan Quan 		return -EOPNOTSUPP;
121879c65f3fSEvan Quan 
12193712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
1220685fae24SEvan Quan 	ret = pp_funcs->set_fan_control_mode(adev->powerplay.pp_handle,
12213712e7a4SEvan Quan 					     mode);
12223712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
122379c65f3fSEvan Quan 
1224685fae24SEvan Quan 	return ret;
122579c65f3fSEvan Quan }
122679c65f3fSEvan Quan 
122779c65f3fSEvan Quan int amdgpu_dpm_get_power_limit(struct amdgpu_device *adev,
122879c65f3fSEvan Quan 			       uint32_t *limit,
122979c65f3fSEvan Quan 			       enum pp_power_limit_level pp_limit_level,
123079c65f3fSEvan Quan 			       enum pp_power_type power_type)
123179c65f3fSEvan Quan {
123279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12333712e7a4SEvan Quan 	int ret = 0;
123479c65f3fSEvan Quan 
123579c65f3fSEvan Quan 	if (!pp_funcs->get_power_limit)
123679c65f3fSEvan Quan 		return -ENODATA;
123779c65f3fSEvan Quan 
12383712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
12393712e7a4SEvan Quan 	ret = pp_funcs->get_power_limit(adev->powerplay.pp_handle,
124079c65f3fSEvan Quan 					limit,
124179c65f3fSEvan Quan 					pp_limit_level,
124279c65f3fSEvan Quan 					power_type);
12433712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
12443712e7a4SEvan Quan 
12453712e7a4SEvan Quan 	return ret;
124679c65f3fSEvan Quan }
124779c65f3fSEvan Quan 
124879c65f3fSEvan Quan int amdgpu_dpm_set_power_limit(struct amdgpu_device *adev,
124979c65f3fSEvan Quan 			       uint32_t limit)
125079c65f3fSEvan Quan {
125179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12523712e7a4SEvan Quan 	int ret = 0;
125379c65f3fSEvan Quan 
125479c65f3fSEvan Quan 	if (!pp_funcs->set_power_limit)
125579c65f3fSEvan Quan 		return -EINVAL;
125679c65f3fSEvan Quan 
12573712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
12583712e7a4SEvan Quan 	ret = pp_funcs->set_power_limit(adev->powerplay.pp_handle,
12593712e7a4SEvan Quan 					limit);
12603712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
12613712e7a4SEvan Quan 
12623712e7a4SEvan Quan 	return ret;
126379c65f3fSEvan Quan }
126479c65f3fSEvan Quan 
126579c65f3fSEvan Quan int amdgpu_dpm_is_cclk_dpm_supported(struct amdgpu_device *adev)
126679c65f3fSEvan Quan {
12673712e7a4SEvan Quan 	bool cclk_dpm_supported = false;
12683712e7a4SEvan Quan 
126979c65f3fSEvan Quan 	if (!is_support_sw_smu(adev))
127079c65f3fSEvan Quan 		return false;
127179c65f3fSEvan Quan 
12723712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
12733712e7a4SEvan Quan 	cclk_dpm_supported = is_support_cclk_dpm(adev);
12743712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
12753712e7a4SEvan Quan 
12763712e7a4SEvan Quan 	return (int)cclk_dpm_supported;
127779c65f3fSEvan Quan }
127879c65f3fSEvan Quan 
127979c65f3fSEvan Quan int amdgpu_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev,
128079c65f3fSEvan Quan 						       struct seq_file *m)
128179c65f3fSEvan Quan {
128279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
128379c65f3fSEvan Quan 
128479c65f3fSEvan Quan 	if (!pp_funcs->debugfs_print_current_performance_level)
128579c65f3fSEvan Quan 		return -EOPNOTSUPP;
128679c65f3fSEvan Quan 
12873712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
128879c65f3fSEvan Quan 	pp_funcs->debugfs_print_current_performance_level(adev->powerplay.pp_handle,
128979c65f3fSEvan Quan 							  m);
12903712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
129179c65f3fSEvan Quan 
129279c65f3fSEvan Quan 	return 0;
129379c65f3fSEvan Quan }
129479c65f3fSEvan Quan 
129579c65f3fSEvan Quan int amdgpu_dpm_get_smu_prv_buf_details(struct amdgpu_device *adev,
129679c65f3fSEvan Quan 				       void **addr,
129779c65f3fSEvan Quan 				       size_t *size)
129879c65f3fSEvan Quan {
129979c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13003712e7a4SEvan Quan 	int ret = 0;
130179c65f3fSEvan Quan 
130279c65f3fSEvan Quan 	if (!pp_funcs->get_smu_prv_buf_details)
130379c65f3fSEvan Quan 		return -ENOSYS;
130479c65f3fSEvan Quan 
13053712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
13063712e7a4SEvan Quan 	ret = pp_funcs->get_smu_prv_buf_details(adev->powerplay.pp_handle,
130779c65f3fSEvan Quan 						addr,
130879c65f3fSEvan Quan 						size);
13093712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
13103712e7a4SEvan Quan 
13113712e7a4SEvan Quan 	return ret;
131279c65f3fSEvan Quan }
131379c65f3fSEvan Quan 
131479c65f3fSEvan Quan int amdgpu_dpm_is_overdrive_supported(struct amdgpu_device *adev)
131579c65f3fSEvan Quan {
131679c65f3fSEvan Quan 	struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
1317ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
131879c65f3fSEvan Quan 
1319ebfc2533SEvan Quan 	if ((is_support_sw_smu(adev) && smu->od_enabled) ||
1320ebfc2533SEvan Quan 	    (is_support_sw_smu(adev) && smu->is_apu) ||
132179c65f3fSEvan Quan 		(!is_support_sw_smu(adev) && hwmgr->od_enabled))
132279c65f3fSEvan Quan 		return true;
132379c65f3fSEvan Quan 
132479c65f3fSEvan Quan 	return false;
132579c65f3fSEvan Quan }
132679c65f3fSEvan Quan 
132779c65f3fSEvan Quan int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev,
132879c65f3fSEvan Quan 			    const char *buf,
132979c65f3fSEvan Quan 			    size_t size)
133079c65f3fSEvan Quan {
133179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13323712e7a4SEvan Quan 	int ret = 0;
133379c65f3fSEvan Quan 
133479c65f3fSEvan Quan 	if (!pp_funcs->set_pp_table)
133579c65f3fSEvan Quan 		return -EOPNOTSUPP;
133679c65f3fSEvan Quan 
13373712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
13383712e7a4SEvan Quan 	ret = pp_funcs->set_pp_table(adev->powerplay.pp_handle,
133979c65f3fSEvan Quan 				     buf,
134079c65f3fSEvan Quan 				     size);
13413712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
13423712e7a4SEvan Quan 
13433712e7a4SEvan Quan 	return ret;
134479c65f3fSEvan Quan }
134579c65f3fSEvan Quan 
134679c65f3fSEvan Quan int amdgpu_dpm_get_num_cpu_cores(struct amdgpu_device *adev)
134779c65f3fSEvan Quan {
1348ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
1349ebfc2533SEvan Quan 
13503712e7a4SEvan Quan 	if (!is_support_sw_smu(adev))
13513712e7a4SEvan Quan 		return INT_MAX;
13523712e7a4SEvan Quan 
1353ebfc2533SEvan Quan 	return smu->cpu_core_num;
135479c65f3fSEvan Quan }
135579c65f3fSEvan Quan 
135679c65f3fSEvan Quan void amdgpu_dpm_stb_debug_fs_init(struct amdgpu_device *adev)
135779c65f3fSEvan Quan {
135879c65f3fSEvan Quan 	if (!is_support_sw_smu(adev))
135979c65f3fSEvan Quan 		return;
136079c65f3fSEvan Quan 
136179c65f3fSEvan Quan 	amdgpu_smu_stb_debug_fs_init(adev);
136279c65f3fSEvan Quan }
136313f5dbd6SEvan Quan 
136413f5dbd6SEvan Quan int amdgpu_dpm_display_configuration_change(struct amdgpu_device *adev,
136513f5dbd6SEvan Quan 					    const struct amd_pp_display_configuration *input)
136613f5dbd6SEvan Quan {
136713f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13683712e7a4SEvan Quan 	int ret = 0;
136913f5dbd6SEvan Quan 
137013f5dbd6SEvan Quan 	if (!pp_funcs->display_configuration_change)
137113f5dbd6SEvan Quan 		return 0;
137213f5dbd6SEvan Quan 
13733712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
13743712e7a4SEvan Quan 	ret = pp_funcs->display_configuration_change(adev->powerplay.pp_handle,
137513f5dbd6SEvan Quan 						     input);
13763712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
13773712e7a4SEvan Quan 
13783712e7a4SEvan Quan 	return ret;
137913f5dbd6SEvan Quan }
138013f5dbd6SEvan Quan 
138113f5dbd6SEvan Quan int amdgpu_dpm_get_clock_by_type(struct amdgpu_device *adev,
138213f5dbd6SEvan Quan 				 enum amd_pp_clock_type type,
138313f5dbd6SEvan Quan 				 struct amd_pp_clocks *clocks)
138413f5dbd6SEvan Quan {
138513f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13863712e7a4SEvan Quan 	int ret = 0;
138713f5dbd6SEvan Quan 
138813f5dbd6SEvan Quan 	if (!pp_funcs->get_clock_by_type)
138913f5dbd6SEvan Quan 		return 0;
139013f5dbd6SEvan Quan 
13913712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
13923712e7a4SEvan Quan 	ret = pp_funcs->get_clock_by_type(adev->powerplay.pp_handle,
139313f5dbd6SEvan Quan 					  type,
139413f5dbd6SEvan Quan 					  clocks);
13953712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
13963712e7a4SEvan Quan 
13973712e7a4SEvan Quan 	return ret;
139813f5dbd6SEvan Quan }
139913f5dbd6SEvan Quan 
140013f5dbd6SEvan Quan int amdgpu_dpm_get_display_mode_validation_clks(struct amdgpu_device *adev,
140113f5dbd6SEvan Quan 						struct amd_pp_simple_clock_info *clocks)
140213f5dbd6SEvan Quan {
140313f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14043712e7a4SEvan Quan 	int ret = 0;
140513f5dbd6SEvan Quan 
140613f5dbd6SEvan Quan 	if (!pp_funcs->get_display_mode_validation_clocks)
140713f5dbd6SEvan Quan 		return 0;
140813f5dbd6SEvan Quan 
14093712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14103712e7a4SEvan Quan 	ret = pp_funcs->get_display_mode_validation_clocks(adev->powerplay.pp_handle,
141113f5dbd6SEvan Quan 							   clocks);
14123712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14133712e7a4SEvan Quan 
14143712e7a4SEvan Quan 	return ret;
141513f5dbd6SEvan Quan }
141613f5dbd6SEvan Quan 
141713f5dbd6SEvan Quan int amdgpu_dpm_get_clock_by_type_with_latency(struct amdgpu_device *adev,
141813f5dbd6SEvan Quan 					      enum amd_pp_clock_type type,
141913f5dbd6SEvan Quan 					      struct pp_clock_levels_with_latency *clocks)
142013f5dbd6SEvan Quan {
142113f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14223712e7a4SEvan Quan 	int ret = 0;
142313f5dbd6SEvan Quan 
142413f5dbd6SEvan Quan 	if (!pp_funcs->get_clock_by_type_with_latency)
142513f5dbd6SEvan Quan 		return 0;
142613f5dbd6SEvan Quan 
14273712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14283712e7a4SEvan Quan 	ret = pp_funcs->get_clock_by_type_with_latency(adev->powerplay.pp_handle,
142913f5dbd6SEvan Quan 						       type,
143013f5dbd6SEvan Quan 						       clocks);
14313712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14323712e7a4SEvan Quan 
14333712e7a4SEvan Quan 	return ret;
143413f5dbd6SEvan Quan }
143513f5dbd6SEvan Quan 
143613f5dbd6SEvan Quan int amdgpu_dpm_get_clock_by_type_with_voltage(struct amdgpu_device *adev,
143713f5dbd6SEvan Quan 					      enum amd_pp_clock_type type,
143813f5dbd6SEvan Quan 					      struct pp_clock_levels_with_voltage *clocks)
143913f5dbd6SEvan Quan {
144013f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14413712e7a4SEvan Quan 	int ret = 0;
144213f5dbd6SEvan Quan 
144313f5dbd6SEvan Quan 	if (!pp_funcs->get_clock_by_type_with_voltage)
144413f5dbd6SEvan Quan 		return 0;
144513f5dbd6SEvan Quan 
14463712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14473712e7a4SEvan Quan 	ret = pp_funcs->get_clock_by_type_with_voltage(adev->powerplay.pp_handle,
144813f5dbd6SEvan Quan 						       type,
144913f5dbd6SEvan Quan 						       clocks);
14503712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14513712e7a4SEvan Quan 
14523712e7a4SEvan Quan 	return ret;
145313f5dbd6SEvan Quan }
145413f5dbd6SEvan Quan 
145513f5dbd6SEvan Quan int amdgpu_dpm_set_watermarks_for_clocks_ranges(struct amdgpu_device *adev,
145613f5dbd6SEvan Quan 					       void *clock_ranges)
145713f5dbd6SEvan Quan {
145813f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14593712e7a4SEvan Quan 	int ret = 0;
146013f5dbd6SEvan Quan 
146113f5dbd6SEvan Quan 	if (!pp_funcs->set_watermarks_for_clocks_ranges)
146213f5dbd6SEvan Quan 		return -EOPNOTSUPP;
146313f5dbd6SEvan Quan 
14643712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14653712e7a4SEvan Quan 	ret = pp_funcs->set_watermarks_for_clocks_ranges(adev->powerplay.pp_handle,
146613f5dbd6SEvan Quan 							 clock_ranges);
14673712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14683712e7a4SEvan Quan 
14693712e7a4SEvan Quan 	return ret;
147013f5dbd6SEvan Quan }
147113f5dbd6SEvan Quan 
147213f5dbd6SEvan Quan int amdgpu_dpm_display_clock_voltage_request(struct amdgpu_device *adev,
147313f5dbd6SEvan Quan 					     struct pp_display_clock_request *clock)
147413f5dbd6SEvan Quan {
147513f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14763712e7a4SEvan Quan 	int ret = 0;
147713f5dbd6SEvan Quan 
147813f5dbd6SEvan Quan 	if (!pp_funcs->display_clock_voltage_request)
147913f5dbd6SEvan Quan 		return -EOPNOTSUPP;
148013f5dbd6SEvan Quan 
14813712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14823712e7a4SEvan Quan 	ret = pp_funcs->display_clock_voltage_request(adev->powerplay.pp_handle,
148313f5dbd6SEvan Quan 						      clock);
14843712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
14853712e7a4SEvan Quan 
14863712e7a4SEvan Quan 	return ret;
148713f5dbd6SEvan Quan }
148813f5dbd6SEvan Quan 
148913f5dbd6SEvan Quan int amdgpu_dpm_get_current_clocks(struct amdgpu_device *adev,
149013f5dbd6SEvan Quan 				  struct amd_pp_clock_info *clocks)
149113f5dbd6SEvan Quan {
149213f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14933712e7a4SEvan Quan 	int ret = 0;
149413f5dbd6SEvan Quan 
149513f5dbd6SEvan Quan 	if (!pp_funcs->get_current_clocks)
149613f5dbd6SEvan Quan 		return -EOPNOTSUPP;
149713f5dbd6SEvan Quan 
14983712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
14993712e7a4SEvan Quan 	ret = pp_funcs->get_current_clocks(adev->powerplay.pp_handle,
150013f5dbd6SEvan Quan 					   clocks);
15013712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
15023712e7a4SEvan Quan 
15033712e7a4SEvan Quan 	return ret;
150413f5dbd6SEvan Quan }
150513f5dbd6SEvan Quan 
150613f5dbd6SEvan Quan void amdgpu_dpm_notify_smu_enable_pwe(struct amdgpu_device *adev)
150713f5dbd6SEvan Quan {
150813f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
150913f5dbd6SEvan Quan 
151013f5dbd6SEvan Quan 	if (!pp_funcs->notify_smu_enable_pwe)
151113f5dbd6SEvan Quan 		return;
151213f5dbd6SEvan Quan 
15133712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
151413f5dbd6SEvan Quan 	pp_funcs->notify_smu_enable_pwe(adev->powerplay.pp_handle);
15153712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
151613f5dbd6SEvan Quan }
151713f5dbd6SEvan Quan 
151813f5dbd6SEvan Quan int amdgpu_dpm_set_active_display_count(struct amdgpu_device *adev,
151913f5dbd6SEvan Quan 					uint32_t count)
152013f5dbd6SEvan Quan {
152113f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15223712e7a4SEvan Quan 	int ret = 0;
152313f5dbd6SEvan Quan 
152413f5dbd6SEvan Quan 	if (!pp_funcs->set_active_display_count)
152513f5dbd6SEvan Quan 		return -EOPNOTSUPP;
152613f5dbd6SEvan Quan 
15273712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
15283712e7a4SEvan Quan 	ret = pp_funcs->set_active_display_count(adev->powerplay.pp_handle,
152913f5dbd6SEvan Quan 						 count);
15303712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
15313712e7a4SEvan Quan 
15323712e7a4SEvan Quan 	return ret;
153313f5dbd6SEvan Quan }
153413f5dbd6SEvan Quan 
153513f5dbd6SEvan Quan int amdgpu_dpm_set_min_deep_sleep_dcefclk(struct amdgpu_device *adev,
153613f5dbd6SEvan Quan 					  uint32_t clock)
153713f5dbd6SEvan Quan {
153813f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15393712e7a4SEvan Quan 	int ret = 0;
154013f5dbd6SEvan Quan 
154113f5dbd6SEvan Quan 	if (!pp_funcs->set_min_deep_sleep_dcefclk)
154213f5dbd6SEvan Quan 		return -EOPNOTSUPP;
154313f5dbd6SEvan Quan 
15443712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
15453712e7a4SEvan Quan 	ret = pp_funcs->set_min_deep_sleep_dcefclk(adev->powerplay.pp_handle,
154613f5dbd6SEvan Quan 						   clock);
15473712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
15483712e7a4SEvan Quan 
15493712e7a4SEvan Quan 	return ret;
155013f5dbd6SEvan Quan }
155113f5dbd6SEvan Quan 
155213f5dbd6SEvan Quan void amdgpu_dpm_set_hard_min_dcefclk_by_freq(struct amdgpu_device *adev,
155313f5dbd6SEvan Quan 					     uint32_t clock)
155413f5dbd6SEvan Quan {
155513f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
155613f5dbd6SEvan Quan 
155713f5dbd6SEvan Quan 	if (!pp_funcs->set_hard_min_dcefclk_by_freq)
155813f5dbd6SEvan Quan 		return;
155913f5dbd6SEvan Quan 
15603712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
156113f5dbd6SEvan Quan 	pp_funcs->set_hard_min_dcefclk_by_freq(adev->powerplay.pp_handle,
156213f5dbd6SEvan Quan 					       clock);
15633712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
156413f5dbd6SEvan Quan }
156513f5dbd6SEvan Quan 
156613f5dbd6SEvan Quan void amdgpu_dpm_set_hard_min_fclk_by_freq(struct amdgpu_device *adev,
156713f5dbd6SEvan Quan 					  uint32_t clock)
156813f5dbd6SEvan Quan {
156913f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
157013f5dbd6SEvan Quan 
157113f5dbd6SEvan Quan 	if (!pp_funcs->set_hard_min_fclk_by_freq)
157213f5dbd6SEvan Quan 		return;
157313f5dbd6SEvan Quan 
15743712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
157513f5dbd6SEvan Quan 	pp_funcs->set_hard_min_fclk_by_freq(adev->powerplay.pp_handle,
157613f5dbd6SEvan Quan 					    clock);
15773712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
157813f5dbd6SEvan Quan }
157913f5dbd6SEvan Quan 
158013f5dbd6SEvan Quan int amdgpu_dpm_display_disable_memory_clock_switch(struct amdgpu_device *adev,
158113f5dbd6SEvan Quan 						   bool disable_memory_clock_switch)
158213f5dbd6SEvan Quan {
158313f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15843712e7a4SEvan Quan 	int ret = 0;
158513f5dbd6SEvan Quan 
158613f5dbd6SEvan Quan 	if (!pp_funcs->display_disable_memory_clock_switch)
158713f5dbd6SEvan Quan 		return 0;
158813f5dbd6SEvan Quan 
15893712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
15903712e7a4SEvan Quan 	ret = pp_funcs->display_disable_memory_clock_switch(adev->powerplay.pp_handle,
159113f5dbd6SEvan Quan 							    disable_memory_clock_switch);
15923712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
15933712e7a4SEvan Quan 
15943712e7a4SEvan Quan 	return ret;
159513f5dbd6SEvan Quan }
159613f5dbd6SEvan Quan 
159713f5dbd6SEvan Quan int amdgpu_dpm_get_max_sustainable_clocks_by_dc(struct amdgpu_device *adev,
159813f5dbd6SEvan Quan 						struct pp_smu_nv_clock_table *max_clocks)
159913f5dbd6SEvan Quan {
160013f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16013712e7a4SEvan Quan 	int ret = 0;
160213f5dbd6SEvan Quan 
160313f5dbd6SEvan Quan 	if (!pp_funcs->get_max_sustainable_clocks_by_dc)
160413f5dbd6SEvan Quan 		return -EOPNOTSUPP;
160513f5dbd6SEvan Quan 
16063712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
16073712e7a4SEvan Quan 	ret = pp_funcs->get_max_sustainable_clocks_by_dc(adev->powerplay.pp_handle,
160813f5dbd6SEvan Quan 							 max_clocks);
16093712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
16103712e7a4SEvan Quan 
16113712e7a4SEvan Quan 	return ret;
161213f5dbd6SEvan Quan }
161313f5dbd6SEvan Quan 
161413f5dbd6SEvan Quan enum pp_smu_status amdgpu_dpm_get_uclk_dpm_states(struct amdgpu_device *adev,
161513f5dbd6SEvan Quan 						  unsigned int *clock_values_in_khz,
161613f5dbd6SEvan Quan 						  unsigned int *num_states)
161713f5dbd6SEvan Quan {
161813f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16193712e7a4SEvan Quan 	int ret = 0;
162013f5dbd6SEvan Quan 
162113f5dbd6SEvan Quan 	if (!pp_funcs->get_uclk_dpm_states)
162213f5dbd6SEvan Quan 		return -EOPNOTSUPP;
162313f5dbd6SEvan Quan 
16243712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
16253712e7a4SEvan Quan 	ret = pp_funcs->get_uclk_dpm_states(adev->powerplay.pp_handle,
162613f5dbd6SEvan Quan 					    clock_values_in_khz,
162713f5dbd6SEvan Quan 					    num_states);
16283712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
16293712e7a4SEvan Quan 
16303712e7a4SEvan Quan 	return ret;
163113f5dbd6SEvan Quan }
163213f5dbd6SEvan Quan 
163313f5dbd6SEvan Quan int amdgpu_dpm_get_dpm_clock_table(struct amdgpu_device *adev,
163413f5dbd6SEvan Quan 				   struct dpm_clocks *clock_table)
163513f5dbd6SEvan Quan {
163613f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16373712e7a4SEvan Quan 	int ret = 0;
163813f5dbd6SEvan Quan 
163913f5dbd6SEvan Quan 	if (!pp_funcs->get_dpm_clock_table)
164013f5dbd6SEvan Quan 		return -EOPNOTSUPP;
164113f5dbd6SEvan Quan 
16423712e7a4SEvan Quan 	mutex_lock(&adev->pm.mutex);
16433712e7a4SEvan Quan 	ret = pp_funcs->get_dpm_clock_table(adev->powerplay.pp_handle,
164413f5dbd6SEvan Quan 					    clock_table);
16453712e7a4SEvan Quan 	mutex_unlock(&adev->pm.mutex);
16463712e7a4SEvan Quan 
16473712e7a4SEvan Quan 	return ret;
164813f5dbd6SEvan Quan }
1649