xref: /openbmc/linux/drivers/gpu/drm/amd/pm/amdgpu_dpm.c (revision ebfc2533)
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>
34*ebfc2533SEvan 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;
42e098bc96SEvan Quan 
43bc7d6c12SDarren Powell 	return pp_funcs->get_sclk((adev)->powerplay.pp_handle, (low));
44e098bc96SEvan Quan }
45e098bc96SEvan Quan 
46e098bc96SEvan Quan int amdgpu_dpm_get_mclk(struct amdgpu_device *adev, bool low)
47e098bc96SEvan Quan {
48bc7d6c12SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
49e098bc96SEvan Quan 
50bc7d6c12SDarren Powell 	return pp_funcs->get_mclk((adev)->powerplay.pp_handle, (low));
51e098bc96SEvan Quan }
52e098bc96SEvan Quan 
53e098bc96SEvan Quan int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block_type, bool gate)
54e098bc96SEvan Quan {
55e098bc96SEvan Quan 	int ret = 0;
56bc7d6c12SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
576ee27ee2SEvan Quan 	enum ip_power_state pwr_state = gate ? POWER_STATE_OFF : POWER_STATE_ON;
586ee27ee2SEvan Quan 
596ee27ee2SEvan Quan 	if (atomic_read(&adev->pm.pwr_state[block_type]) == pwr_state) {
606ee27ee2SEvan Quan 		dev_dbg(adev->dev, "IP block%d already in the target %s state!",
616ee27ee2SEvan Quan 				block_type, gate ? "gate" : "ungate");
626ee27ee2SEvan Quan 		return 0;
636ee27ee2SEvan Quan 	}
64e098bc96SEvan Quan 
65e098bc96SEvan Quan 	switch (block_type) {
66e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_UVD:
67e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_VCE:
68bc7d6c12SDarren Powell 		if (pp_funcs && pp_funcs->set_powergating_by_smu) {
69e098bc96SEvan Quan 			/*
70e098bc96SEvan Quan 			 * TODO: need a better lock mechanism
71e098bc96SEvan Quan 			 *
72e098bc96SEvan Quan 			 * Here adev->pm.mutex lock protection is enforced on
73e098bc96SEvan Quan 			 * UVD and VCE cases only. Since for other cases, there
74e098bc96SEvan Quan 			 * may be already lock protection in amdgpu_pm.c.
75e098bc96SEvan Quan 			 * This is a quick fix for the deadlock issue below.
76e098bc96SEvan Quan 			 *     NFO: task ocltst:2028 blocked for more than 120 seconds.
77e098bc96SEvan Quan 			 *     Tainted: G           OE     5.0.0-37-generic #40~18.04.1-Ubuntu
78e098bc96SEvan Quan 			 *     echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
79e098bc96SEvan Quan 			 *     cltst          D    0  2028   2026 0x00000000
80e098bc96SEvan Quan 			 *     all Trace:
81e098bc96SEvan Quan 			 *     __schedule+0x2c0/0x870
82e098bc96SEvan Quan 			 *     schedule+0x2c/0x70
83e098bc96SEvan Quan 			 *     schedule_preempt_disabled+0xe/0x10
84e098bc96SEvan Quan 			 *     __mutex_lock.isra.9+0x26d/0x4e0
85e098bc96SEvan Quan 			 *     __mutex_lock_slowpath+0x13/0x20
86e098bc96SEvan Quan 			 *     ? __mutex_lock_slowpath+0x13/0x20
87e098bc96SEvan Quan 			 *     mutex_lock+0x2f/0x40
88e098bc96SEvan Quan 			 *     amdgpu_dpm_set_powergating_by_smu+0x64/0xe0 [amdgpu]
89e098bc96SEvan Quan 			 *     gfx_v8_0_enable_gfx_static_mg_power_gating+0x3c/0x70 [amdgpu]
90e098bc96SEvan Quan 			 *     gfx_v8_0_set_powergating_state+0x66/0x260 [amdgpu]
91e098bc96SEvan Quan 			 *     amdgpu_device_ip_set_powergating_state+0x62/0xb0 [amdgpu]
92e098bc96SEvan Quan 			 *     pp_dpm_force_performance_level+0xe7/0x100 [amdgpu]
93e098bc96SEvan Quan 			 *     amdgpu_set_dpm_forced_performance_level+0x129/0x330 [amdgpu]
94e098bc96SEvan Quan 			 */
95e098bc96SEvan Quan 			mutex_lock(&adev->pm.mutex);
96bc7d6c12SDarren Powell 			ret = (pp_funcs->set_powergating_by_smu(
97e098bc96SEvan Quan 				(adev)->powerplay.pp_handle, block_type, gate));
98e098bc96SEvan Quan 			mutex_unlock(&adev->pm.mutex);
99e098bc96SEvan Quan 		}
100e098bc96SEvan Quan 		break;
101e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_GFX:
102e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_VCN:
103e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_SDMA:
104e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_JPEG:
105e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_GMC:
106e098bc96SEvan Quan 	case AMD_IP_BLOCK_TYPE_ACP:
107bc7d6c12SDarren Powell 		if (pp_funcs && pp_funcs->set_powergating_by_smu) {
108bc7d6c12SDarren Powell 			ret = (pp_funcs->set_powergating_by_smu(
109e098bc96SEvan Quan 				(adev)->powerplay.pp_handle, block_type, gate));
110bc7d6c12SDarren Powell 		}
111e098bc96SEvan Quan 		break;
112e098bc96SEvan Quan 	default:
113e098bc96SEvan Quan 		break;
114e098bc96SEvan Quan 	}
115e098bc96SEvan Quan 
1166ee27ee2SEvan Quan 	if (!ret)
1176ee27ee2SEvan Quan 		atomic_set(&adev->pm.pwr_state[block_type], pwr_state);
1186ee27ee2SEvan Quan 
119e098bc96SEvan Quan 	return ret;
120e098bc96SEvan Quan }
121e098bc96SEvan Quan 
122e098bc96SEvan Quan int amdgpu_dpm_baco_enter(struct amdgpu_device *adev)
123e098bc96SEvan Quan {
124e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
125e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
126e098bc96SEvan Quan 	int ret = 0;
127e098bc96SEvan Quan 
128e098bc96SEvan Quan 	if (!pp_funcs || !pp_funcs->set_asic_baco_state)
129e098bc96SEvan Quan 		return -ENOENT;
130e098bc96SEvan Quan 
131e098bc96SEvan Quan 	/* enter BACO state */
132e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
133e098bc96SEvan Quan 
134e098bc96SEvan Quan 	return ret;
135e098bc96SEvan Quan }
136e098bc96SEvan Quan 
137e098bc96SEvan Quan int amdgpu_dpm_baco_exit(struct amdgpu_device *adev)
138e098bc96SEvan Quan {
139e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
140e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
141e098bc96SEvan Quan 	int ret = 0;
142e098bc96SEvan Quan 
143e098bc96SEvan Quan 	if (!pp_funcs || !pp_funcs->set_asic_baco_state)
144e098bc96SEvan Quan 		return -ENOENT;
145e098bc96SEvan Quan 
146e098bc96SEvan Quan 	/* exit BACO state */
147e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
148e098bc96SEvan Quan 
149e098bc96SEvan Quan 	return ret;
150e098bc96SEvan Quan }
151e098bc96SEvan Quan 
152e098bc96SEvan Quan int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
153e098bc96SEvan Quan 			     enum pp_mp1_state mp1_state)
154e098bc96SEvan Quan {
155e098bc96SEvan Quan 	int ret = 0;
156bab0f602SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
157e098bc96SEvan Quan 
158bab0f602SDarren Powell 	if (pp_funcs && pp_funcs->set_mp1_state) {
159bab0f602SDarren Powell 		ret = pp_funcs->set_mp1_state(
160e098bc96SEvan Quan 				adev->powerplay.pp_handle,
161e098bc96SEvan Quan 				mp1_state);
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;
172e098bc96SEvan Quan 
173e098bc96SEvan Quan 	if (!pp_funcs || !pp_funcs->get_asic_baco_capability)
174e098bc96SEvan Quan 		return false;
175e098bc96SEvan Quan 
176e098bc96SEvan Quan 	if (pp_funcs->get_asic_baco_capability(pp_handle, &baco_cap))
177e098bc96SEvan Quan 		return false;
178e098bc96SEvan Quan 
1799ab5001aSDarren Powell 	return baco_cap;
180e098bc96SEvan Quan }
181e098bc96SEvan Quan 
182e098bc96SEvan Quan int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev)
183e098bc96SEvan Quan {
184e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
185e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
186e098bc96SEvan Quan 
187e098bc96SEvan Quan 	if (!pp_funcs || !pp_funcs->asic_reset_mode_2)
188e098bc96SEvan Quan 		return -ENOENT;
189e098bc96SEvan Quan 
190e098bc96SEvan Quan 	return pp_funcs->asic_reset_mode_2(pp_handle);
191e098bc96SEvan Quan }
192e098bc96SEvan Quan 
193e098bc96SEvan Quan int amdgpu_dpm_baco_reset(struct amdgpu_device *adev)
194e098bc96SEvan Quan {
195e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
196e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
197e098bc96SEvan Quan 	int ret = 0;
198e098bc96SEvan Quan 
1999ab5001aSDarren Powell 	if (!pp_funcs || !pp_funcs->set_asic_baco_state)
200e098bc96SEvan Quan 		return -ENOENT;
201e098bc96SEvan Quan 
202e098bc96SEvan Quan 	/* enter BACO state */
203e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
204e098bc96SEvan Quan 	if (ret)
205e098bc96SEvan Quan 		return ret;
206e098bc96SEvan Quan 
207e098bc96SEvan Quan 	/* exit BACO state */
208e098bc96SEvan Quan 	ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
209e098bc96SEvan Quan 	if (ret)
210e098bc96SEvan Quan 		return ret;
211e098bc96SEvan Quan 
212e098bc96SEvan Quan 	return 0;
213e098bc96SEvan Quan }
214e098bc96SEvan Quan 
215e098bc96SEvan Quan bool amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device *adev)
216e098bc96SEvan Quan {
217*ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
218e098bc96SEvan Quan 
219e098bc96SEvan Quan 	if (is_support_sw_smu(adev))
220e098bc96SEvan Quan 		return smu_mode1_reset_is_support(smu);
221e098bc96SEvan Quan 
222e098bc96SEvan Quan 	return false;
223e098bc96SEvan Quan }
224e098bc96SEvan Quan 
225e098bc96SEvan Quan int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev)
226e098bc96SEvan Quan {
227*ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
228e098bc96SEvan Quan 
229e098bc96SEvan Quan 	if (is_support_sw_smu(adev))
230e098bc96SEvan Quan 		return smu_mode1_reset(smu);
231e098bc96SEvan Quan 
232e098bc96SEvan Quan 	return -EOPNOTSUPP;
233e098bc96SEvan Quan }
234e098bc96SEvan Quan 
235e098bc96SEvan Quan int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
236e098bc96SEvan Quan 				    enum PP_SMC_POWER_PROFILE type,
237e098bc96SEvan Quan 				    bool en)
238e098bc96SEvan Quan {
239bab0f602SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
240e098bc96SEvan Quan 	int ret = 0;
241e098bc96SEvan Quan 
2427cf7a392SJingwen Chen 	if (amdgpu_sriov_vf(adev))
2437cf7a392SJingwen Chen 		return 0;
2447cf7a392SJingwen Chen 
245bab0f602SDarren Powell 	if (pp_funcs && pp_funcs->switch_power_profile)
246bab0f602SDarren Powell 		ret = pp_funcs->switch_power_profile(
247e098bc96SEvan Quan 			adev->powerplay.pp_handle, type, en);
248e098bc96SEvan Quan 
249e098bc96SEvan Quan 	return ret;
250e098bc96SEvan Quan }
251e098bc96SEvan Quan 
252e098bc96SEvan Quan int amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device *adev,
253e098bc96SEvan Quan 			       uint32_t pstate)
254e098bc96SEvan Quan {
255bab0f602SDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
256e098bc96SEvan Quan 	int ret = 0;
257e098bc96SEvan Quan 
258bab0f602SDarren Powell 	if (pp_funcs && pp_funcs->set_xgmi_pstate)
259bab0f602SDarren Powell 		ret = pp_funcs->set_xgmi_pstate(adev->powerplay.pp_handle,
260e098bc96SEvan Quan 								pstate);
261e098bc96SEvan Quan 
262e098bc96SEvan Quan 	return ret;
263e098bc96SEvan Quan }
264e098bc96SEvan Quan 
265e098bc96SEvan Quan int amdgpu_dpm_set_df_cstate(struct amdgpu_device *adev,
266e098bc96SEvan Quan 			     uint32_t cstate)
267e098bc96SEvan Quan {
268e098bc96SEvan Quan 	int ret = 0;
269e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
270e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
271e098bc96SEvan Quan 
272bab0f602SDarren Powell 	if (pp_funcs && pp_funcs->set_df_cstate)
273e098bc96SEvan Quan 		ret = pp_funcs->set_df_cstate(pp_handle, cstate);
274e098bc96SEvan Quan 
275e098bc96SEvan Quan 	return ret;
276e098bc96SEvan Quan }
277e098bc96SEvan Quan 
278e098bc96SEvan Quan int amdgpu_dpm_allow_xgmi_power_down(struct amdgpu_device *adev, bool en)
279e098bc96SEvan Quan {
280*ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
281e098bc96SEvan Quan 
282e098bc96SEvan Quan 	if (is_support_sw_smu(adev))
283e098bc96SEvan Quan 		return smu_allow_xgmi_power_down(smu, en);
284e098bc96SEvan Quan 
285e098bc96SEvan Quan 	return 0;
286e098bc96SEvan Quan }
287e098bc96SEvan Quan 
288e098bc96SEvan Quan int amdgpu_dpm_enable_mgpu_fan_boost(struct amdgpu_device *adev)
289e098bc96SEvan Quan {
290e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
291e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs =
292e098bc96SEvan Quan 			adev->powerplay.pp_funcs;
293e098bc96SEvan Quan 	int ret = 0;
294e098bc96SEvan Quan 
295bab0f602SDarren Powell 	if (pp_funcs && pp_funcs->enable_mgpu_fan_boost)
296e098bc96SEvan Quan 		ret = pp_funcs->enable_mgpu_fan_boost(pp_handle);
297e098bc96SEvan Quan 
298e098bc96SEvan Quan 	return ret;
299e098bc96SEvan Quan }
300e098bc96SEvan Quan 
301e098bc96SEvan Quan int amdgpu_dpm_set_clockgating_by_smu(struct amdgpu_device *adev,
302e098bc96SEvan Quan 				      uint32_t msg_id)
303e098bc96SEvan Quan {
304e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
305e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs =
306e098bc96SEvan Quan 			adev->powerplay.pp_funcs;
307e098bc96SEvan Quan 	int ret = 0;
308e098bc96SEvan Quan 
309e098bc96SEvan Quan 	if (pp_funcs && pp_funcs->set_clockgating_by_smu)
310e098bc96SEvan Quan 		ret = pp_funcs->set_clockgating_by_smu(pp_handle,
311e098bc96SEvan Quan 						       msg_id);
312e098bc96SEvan Quan 
313e098bc96SEvan Quan 	return ret;
314e098bc96SEvan Quan }
315e098bc96SEvan Quan 
316e098bc96SEvan Quan int amdgpu_dpm_smu_i2c_bus_access(struct amdgpu_device *adev,
317e098bc96SEvan Quan 				  bool acquire)
318e098bc96SEvan Quan {
319e098bc96SEvan Quan 	void *pp_handle = adev->powerplay.pp_handle;
320e098bc96SEvan Quan 	const struct amd_pm_funcs *pp_funcs =
321e098bc96SEvan Quan 			adev->powerplay.pp_funcs;
322e098bc96SEvan Quan 	int ret = -EOPNOTSUPP;
323e098bc96SEvan Quan 
324e098bc96SEvan Quan 	if (pp_funcs && pp_funcs->smu_i2c_bus_access)
325e098bc96SEvan Quan 		ret = pp_funcs->smu_i2c_bus_access(pp_handle,
326e098bc96SEvan Quan 						   acquire);
327e098bc96SEvan Quan 
328e098bc96SEvan Quan 	return ret;
329e098bc96SEvan Quan }
330e098bc96SEvan Quan 
331e098bc96SEvan Quan void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev)
332e098bc96SEvan Quan {
333e098bc96SEvan Quan 	if (adev->pm.dpm_enabled) {
334e098bc96SEvan Quan 		mutex_lock(&adev->pm.mutex);
335e098bc96SEvan Quan 		if (power_supply_is_system_supplied() > 0)
336e098bc96SEvan Quan 			adev->pm.ac_power = true;
337e098bc96SEvan Quan 		else
338e098bc96SEvan Quan 			adev->pm.ac_power = false;
339e098bc96SEvan Quan 		if (adev->powerplay.pp_funcs &&
340e098bc96SEvan Quan 		    adev->powerplay.pp_funcs->enable_bapm)
341e098bc96SEvan Quan 			amdgpu_dpm_enable_bapm(adev, adev->pm.ac_power);
342e098bc96SEvan Quan 		mutex_unlock(&adev->pm.mutex);
343e098bc96SEvan Quan 
344e098bc96SEvan Quan 		if (is_support_sw_smu(adev))
345*ebfc2533SEvan Quan 			smu_set_ac_dc(adev->powerplay.pp_handle);
346e098bc96SEvan Quan 	}
347e098bc96SEvan Quan }
348e098bc96SEvan Quan 
349e098bc96SEvan Quan int amdgpu_dpm_read_sensor(struct amdgpu_device *adev, enum amd_pp_sensors sensor,
350e098bc96SEvan Quan 			   void *data, uint32_t *size)
351e098bc96SEvan Quan {
3529ab5001aSDarren Powell 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
353e098bc96SEvan Quan 	int ret = 0;
354e098bc96SEvan Quan 
355e098bc96SEvan Quan 	if (!data || !size)
356e098bc96SEvan Quan 		return -EINVAL;
357e098bc96SEvan Quan 
3589ab5001aSDarren Powell 	if (pp_funcs && pp_funcs->read_sensor)
3599ab5001aSDarren Powell 		ret = pp_funcs->read_sensor((adev)->powerplay.pp_handle,
360e098bc96SEvan Quan 								    sensor, data, size);
361e098bc96SEvan Quan 	else
362e098bc96SEvan Quan 		ret = -EINVAL;
363e098bc96SEvan Quan 
364e098bc96SEvan Quan 	return ret;
365e098bc96SEvan Quan }
366e098bc96SEvan Quan 
36784176663SEvan Quan void amdgpu_dpm_compute_clocks(struct amdgpu_device *adev)
368e098bc96SEvan Quan {
3696ddbd37fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
370e098bc96SEvan Quan 
371e098bc96SEvan Quan 	if (!adev->pm.dpm_enabled)
372e098bc96SEvan Quan 		return;
373e098bc96SEvan Quan 
3746ddbd37fSEvan Quan 	if (!pp_funcs->pm_compute_clocks)
3756ddbd37fSEvan Quan 		return;
376e098bc96SEvan Quan 
3776ddbd37fSEvan Quan 	pp_funcs->pm_compute_clocks(adev->powerplay.pp_handle);
378e098bc96SEvan Quan }
379e098bc96SEvan Quan 
380e098bc96SEvan Quan void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
381e098bc96SEvan Quan {
382e098bc96SEvan Quan 	int ret = 0;
383e098bc96SEvan Quan 
384e098bc96SEvan Quan 	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable);
385e098bc96SEvan Quan 	if (ret)
386e098bc96SEvan Quan 		DRM_ERROR("Dpm %s uvd failed, ret = %d. \n",
387e098bc96SEvan Quan 			  enable ? "enable" : "disable", ret);
388e098bc96SEvan Quan }
389e098bc96SEvan Quan 
390e098bc96SEvan Quan void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
391e098bc96SEvan Quan {
392e098bc96SEvan Quan 	int ret = 0;
393e098bc96SEvan Quan 
394e098bc96SEvan Quan 	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable);
395e098bc96SEvan Quan 	if (ret)
396e098bc96SEvan Quan 		DRM_ERROR("Dpm %s vce failed, ret = %d. \n",
397e098bc96SEvan Quan 			  enable ? "enable" : "disable", ret);
398e098bc96SEvan Quan }
399e098bc96SEvan Quan 
400e098bc96SEvan Quan void amdgpu_dpm_enable_jpeg(struct amdgpu_device *adev, bool enable)
401e098bc96SEvan Quan {
402e098bc96SEvan Quan 	int ret = 0;
403e098bc96SEvan Quan 
404e098bc96SEvan Quan 	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_JPEG, !enable);
405e098bc96SEvan Quan 	if (ret)
406e098bc96SEvan Quan 		DRM_ERROR("Dpm %s jpeg failed, ret = %d. \n",
407e098bc96SEvan Quan 			  enable ? "enable" : "disable", ret);
408e098bc96SEvan Quan }
409e098bc96SEvan Quan 
410e098bc96SEvan Quan int amdgpu_pm_load_smu_firmware(struct amdgpu_device *adev, uint32_t *smu_version)
411e098bc96SEvan Quan {
412e098bc96SEvan Quan 	int r;
413e098bc96SEvan Quan 
414e098bc96SEvan Quan 	if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->load_firmware) {
415e098bc96SEvan Quan 		r = adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle);
416e098bc96SEvan Quan 		if (r) {
417e098bc96SEvan Quan 			pr_err("smu firmware loading failed\n");
418e098bc96SEvan Quan 			return r;
419e098bc96SEvan Quan 		}
4202e4b2f7bSEvan Quan 
4212e4b2f7bSEvan Quan 		if (smu_version)
422e098bc96SEvan Quan 			*smu_version = adev->pm.fw_version;
423e098bc96SEvan Quan 	}
4242e4b2f7bSEvan Quan 
425e098bc96SEvan Quan 	return 0;
426e098bc96SEvan Quan }
427bc143d8bSEvan Quan 
428bc143d8bSEvan Quan int amdgpu_dpm_handle_passthrough_sbr(struct amdgpu_device *adev, bool enable)
429bc143d8bSEvan Quan {
430*ebfc2533SEvan Quan 	return smu_handle_passthrough_sbr(adev->powerplay.pp_handle, enable);
431bc143d8bSEvan Quan }
432bc143d8bSEvan Quan 
433bc143d8bSEvan Quan int amdgpu_dpm_send_hbm_bad_pages_num(struct amdgpu_device *adev, uint32_t size)
434bc143d8bSEvan Quan {
435*ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
436*ebfc2533SEvan Quan 
437*ebfc2533SEvan Quan 	return smu_send_hbm_bad_pages_num(smu, size);
438bc143d8bSEvan Quan }
439bc143d8bSEvan Quan 
440bc143d8bSEvan Quan int amdgpu_dpm_get_dpm_freq_range(struct amdgpu_device *adev,
441bc143d8bSEvan Quan 				  enum pp_clock_type type,
442bc143d8bSEvan Quan 				  uint32_t *min,
443bc143d8bSEvan Quan 				  uint32_t *max)
444bc143d8bSEvan Quan {
445bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
446bc143d8bSEvan Quan 		return -EOPNOTSUPP;
447bc143d8bSEvan Quan 
448bc143d8bSEvan Quan 	switch (type) {
449bc143d8bSEvan Quan 	case PP_SCLK:
450*ebfc2533SEvan Quan 		return smu_get_dpm_freq_range(adev->powerplay.pp_handle, SMU_SCLK, min, max);
451bc143d8bSEvan Quan 	default:
452bc143d8bSEvan Quan 		return -EINVAL;
453bc143d8bSEvan Quan 	}
454bc143d8bSEvan Quan }
455bc143d8bSEvan Quan 
456bc143d8bSEvan Quan int amdgpu_dpm_set_soft_freq_range(struct amdgpu_device *adev,
457bc143d8bSEvan Quan 				   enum pp_clock_type type,
458bc143d8bSEvan Quan 				   uint32_t min,
459bc143d8bSEvan Quan 				   uint32_t max)
460bc143d8bSEvan Quan {
461*ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
462*ebfc2533SEvan Quan 
463bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
464bc143d8bSEvan Quan 		return -EOPNOTSUPP;
465bc143d8bSEvan Quan 
466bc143d8bSEvan Quan 	switch (type) {
467bc143d8bSEvan Quan 	case PP_SCLK:
468*ebfc2533SEvan Quan 		return smu_set_soft_freq_range(smu, SMU_SCLK, min, max);
469bc143d8bSEvan Quan 	default:
470bc143d8bSEvan Quan 		return -EINVAL;
471bc143d8bSEvan Quan 	}
472bc143d8bSEvan Quan }
473bc143d8bSEvan Quan 
47413f5dbd6SEvan Quan int amdgpu_dpm_write_watermarks_table(struct amdgpu_device *adev)
47513f5dbd6SEvan Quan {
476*ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
477*ebfc2533SEvan Quan 
47813f5dbd6SEvan Quan 	if (!is_support_sw_smu(adev))
47913f5dbd6SEvan Quan 		return 0;
48013f5dbd6SEvan Quan 
481*ebfc2533SEvan Quan 	return smu_write_watermarks_table(smu);
48213f5dbd6SEvan Quan }
48313f5dbd6SEvan Quan 
484bc143d8bSEvan Quan int amdgpu_dpm_wait_for_event(struct amdgpu_device *adev,
485bc143d8bSEvan Quan 			      enum smu_event_type event,
486bc143d8bSEvan Quan 			      uint64_t event_arg)
487bc143d8bSEvan Quan {
488*ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
489*ebfc2533SEvan Quan 
490bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
491bc143d8bSEvan Quan 		return -EOPNOTSUPP;
492bc143d8bSEvan Quan 
493*ebfc2533SEvan Quan 	return smu_wait_for_event(smu, event, event_arg);
494bc143d8bSEvan Quan }
495bc143d8bSEvan Quan 
496bc143d8bSEvan Quan int amdgpu_dpm_get_status_gfxoff(struct amdgpu_device *adev, uint32_t *value)
497bc143d8bSEvan Quan {
498*ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
499*ebfc2533SEvan Quan 
500bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
501bc143d8bSEvan Quan 		return -EOPNOTSUPP;
502bc143d8bSEvan Quan 
503*ebfc2533SEvan Quan 	return smu_get_status_gfxoff(smu, value);
504bc143d8bSEvan Quan }
505bc143d8bSEvan Quan 
506bc143d8bSEvan Quan uint64_t amdgpu_dpm_get_thermal_throttling_counter(struct amdgpu_device *adev)
507bc143d8bSEvan Quan {
508*ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
509*ebfc2533SEvan Quan 
510*ebfc2533SEvan Quan 	return atomic64_read(&smu->throttle_int_counter);
511bc143d8bSEvan Quan }
512bc143d8bSEvan Quan 
513bc143d8bSEvan Quan /* amdgpu_dpm_gfx_state_change - Handle gfx power state change set
514bc143d8bSEvan Quan  * @adev: amdgpu_device pointer
515bc143d8bSEvan Quan  * @state: gfx power state(1 -sGpuChangeState_D0Entry and 2 -sGpuChangeState_D3Entry)
516bc143d8bSEvan Quan  *
517bc143d8bSEvan Quan  */
518bc143d8bSEvan Quan void amdgpu_dpm_gfx_state_change(struct amdgpu_device *adev,
519bc143d8bSEvan Quan 				 enum gfx_change_state state)
520bc143d8bSEvan Quan {
521bc143d8bSEvan Quan 	mutex_lock(&adev->pm.mutex);
522bc143d8bSEvan Quan 	if (adev->powerplay.pp_funcs &&
523bc143d8bSEvan Quan 	    adev->powerplay.pp_funcs->gfx_state_change_set)
524bc143d8bSEvan Quan 		((adev)->powerplay.pp_funcs->gfx_state_change_set(
525bc143d8bSEvan Quan 			(adev)->powerplay.pp_handle, state));
526bc143d8bSEvan Quan 	mutex_unlock(&adev->pm.mutex);
527bc143d8bSEvan Quan }
528bc143d8bSEvan Quan 
529bc143d8bSEvan Quan int amdgpu_dpm_get_ecc_info(struct amdgpu_device *adev,
530bc143d8bSEvan Quan 			    void *umc_ecc)
531bc143d8bSEvan Quan {
532*ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
533*ebfc2533SEvan Quan 
534bc143d8bSEvan Quan 	if (!is_support_sw_smu(adev))
535bc143d8bSEvan Quan 		return -EOPNOTSUPP;
536bc143d8bSEvan Quan 
537*ebfc2533SEvan Quan 	return smu_get_ecc_info(smu, umc_ecc);
538bc143d8bSEvan Quan }
53979c65f3fSEvan Quan 
54079c65f3fSEvan Quan struct amd_vce_state *amdgpu_dpm_get_vce_clock_state(struct amdgpu_device *adev,
54179c65f3fSEvan Quan 						     uint32_t idx)
54279c65f3fSEvan Quan {
54379c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
54479c65f3fSEvan Quan 
54579c65f3fSEvan Quan 	if (!pp_funcs->get_vce_clock_state)
54679c65f3fSEvan Quan 		return NULL;
54779c65f3fSEvan Quan 
54879c65f3fSEvan Quan 	return pp_funcs->get_vce_clock_state(adev->powerplay.pp_handle,
54979c65f3fSEvan Quan 					     idx);
55079c65f3fSEvan Quan }
55179c65f3fSEvan Quan 
55279c65f3fSEvan Quan void amdgpu_dpm_get_current_power_state(struct amdgpu_device *adev,
55379c65f3fSEvan Quan 					enum amd_pm_state_type *state)
55479c65f3fSEvan Quan {
55579c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
55679c65f3fSEvan Quan 
55779c65f3fSEvan Quan 	if (!pp_funcs->get_current_power_state) {
55879c65f3fSEvan Quan 		*state = adev->pm.dpm.user_state;
55979c65f3fSEvan Quan 		return;
56079c65f3fSEvan Quan 	}
56179c65f3fSEvan Quan 
56279c65f3fSEvan Quan 	*state = pp_funcs->get_current_power_state(adev->powerplay.pp_handle);
56379c65f3fSEvan Quan 	if (*state < POWER_STATE_TYPE_DEFAULT ||
56479c65f3fSEvan Quan 	    *state > POWER_STATE_TYPE_INTERNAL_3DPERF)
56579c65f3fSEvan Quan 		*state = adev->pm.dpm.user_state;
56679c65f3fSEvan Quan }
56779c65f3fSEvan Quan 
56879c65f3fSEvan Quan void amdgpu_dpm_set_power_state(struct amdgpu_device *adev,
56979c65f3fSEvan Quan 				enum amd_pm_state_type state)
57079c65f3fSEvan Quan {
57179c65f3fSEvan Quan 	adev->pm.dpm.user_state = state;
57279c65f3fSEvan Quan 
57379c65f3fSEvan Quan 	if (is_support_sw_smu(adev))
57479c65f3fSEvan Quan 		return;
57579c65f3fSEvan Quan 
57679c65f3fSEvan Quan 	if (amdgpu_dpm_dispatch_task(adev,
57779c65f3fSEvan Quan 				     AMD_PP_TASK_ENABLE_USER_STATE,
57879c65f3fSEvan Quan 				     &state) == -EOPNOTSUPP)
57984176663SEvan Quan 		amdgpu_dpm_compute_clocks(adev);
58079c65f3fSEvan Quan }
58179c65f3fSEvan Quan 
58279c65f3fSEvan Quan enum amd_dpm_forced_level amdgpu_dpm_get_performance_level(struct amdgpu_device *adev)
58379c65f3fSEvan Quan {
58479c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
58579c65f3fSEvan Quan 	enum amd_dpm_forced_level level;
58679c65f3fSEvan Quan 
58779c65f3fSEvan Quan 	if (pp_funcs->get_performance_level)
58879c65f3fSEvan Quan 		level = pp_funcs->get_performance_level(adev->powerplay.pp_handle);
58979c65f3fSEvan Quan 	else
59079c65f3fSEvan Quan 		level = adev->pm.dpm.forced_level;
59179c65f3fSEvan Quan 
59279c65f3fSEvan Quan 	return level;
59379c65f3fSEvan Quan }
59479c65f3fSEvan Quan 
59579c65f3fSEvan Quan int amdgpu_dpm_force_performance_level(struct amdgpu_device *adev,
59679c65f3fSEvan Quan 				       enum amd_dpm_forced_level level)
59779c65f3fSEvan Quan {
59879c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
59979c65f3fSEvan Quan 
60079c65f3fSEvan Quan 	if (pp_funcs->force_performance_level) {
60179c65f3fSEvan Quan 		if (adev->pm.dpm.thermal_active)
60279c65f3fSEvan Quan 			return -EINVAL;
60379c65f3fSEvan Quan 
60479c65f3fSEvan Quan 		if (pp_funcs->force_performance_level(adev->powerplay.pp_handle,
60579c65f3fSEvan Quan 						      level))
60679c65f3fSEvan Quan 			return -EINVAL;
60779c65f3fSEvan Quan 
60879c65f3fSEvan Quan 		adev->pm.dpm.forced_level = level;
60979c65f3fSEvan Quan 	}
61079c65f3fSEvan Quan 
61179c65f3fSEvan Quan 	return 0;
61279c65f3fSEvan Quan }
61379c65f3fSEvan Quan 
61479c65f3fSEvan Quan int amdgpu_dpm_get_pp_num_states(struct amdgpu_device *adev,
61579c65f3fSEvan Quan 				 struct pp_states_info *states)
61679c65f3fSEvan Quan {
61779c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
61879c65f3fSEvan Quan 
61979c65f3fSEvan Quan 	if (!pp_funcs->get_pp_num_states)
62079c65f3fSEvan Quan 		return -EOPNOTSUPP;
62179c65f3fSEvan Quan 
62279c65f3fSEvan Quan 	return pp_funcs->get_pp_num_states(adev->powerplay.pp_handle, states);
62379c65f3fSEvan Quan }
62479c65f3fSEvan Quan 
62579c65f3fSEvan Quan int amdgpu_dpm_dispatch_task(struct amdgpu_device *adev,
62679c65f3fSEvan Quan 			      enum amd_pp_task task_id,
62779c65f3fSEvan Quan 			      enum amd_pm_state_type *user_state)
62879c65f3fSEvan Quan {
62979c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
63079c65f3fSEvan Quan 
63179c65f3fSEvan Quan 	if (!pp_funcs->dispatch_tasks)
63279c65f3fSEvan Quan 		return -EOPNOTSUPP;
63379c65f3fSEvan Quan 
63479c65f3fSEvan Quan 	return pp_funcs->dispatch_tasks(adev->powerplay.pp_handle, task_id, user_state);
63579c65f3fSEvan Quan }
63679c65f3fSEvan Quan 
63779c65f3fSEvan Quan int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char **table)
63879c65f3fSEvan Quan {
63979c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
64079c65f3fSEvan Quan 
64179c65f3fSEvan Quan 	if (!pp_funcs->get_pp_table)
64279c65f3fSEvan Quan 		return 0;
64379c65f3fSEvan Quan 
64479c65f3fSEvan Quan 	return pp_funcs->get_pp_table(adev->powerplay.pp_handle, table);
64579c65f3fSEvan Quan }
64679c65f3fSEvan Quan 
64779c65f3fSEvan Quan int amdgpu_dpm_set_fine_grain_clk_vol(struct amdgpu_device *adev,
64879c65f3fSEvan Quan 				      uint32_t type,
64979c65f3fSEvan Quan 				      long *input,
65079c65f3fSEvan Quan 				      uint32_t size)
65179c65f3fSEvan Quan {
65279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
65379c65f3fSEvan Quan 
65479c65f3fSEvan Quan 	if (!pp_funcs->set_fine_grain_clk_vol)
65579c65f3fSEvan Quan 		return 0;
65679c65f3fSEvan Quan 
65779c65f3fSEvan Quan 	return pp_funcs->set_fine_grain_clk_vol(adev->powerplay.pp_handle,
65879c65f3fSEvan Quan 						type,
65979c65f3fSEvan Quan 						input,
66079c65f3fSEvan Quan 						size);
66179c65f3fSEvan Quan }
66279c65f3fSEvan Quan 
66379c65f3fSEvan Quan int amdgpu_dpm_odn_edit_dpm_table(struct amdgpu_device *adev,
66479c65f3fSEvan Quan 				  uint32_t type,
66579c65f3fSEvan Quan 				  long *input,
66679c65f3fSEvan Quan 				  uint32_t size)
66779c65f3fSEvan Quan {
66879c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
66979c65f3fSEvan Quan 
67079c65f3fSEvan Quan 	if (!pp_funcs->odn_edit_dpm_table)
67179c65f3fSEvan Quan 		return 0;
67279c65f3fSEvan Quan 
67379c65f3fSEvan Quan 	return pp_funcs->odn_edit_dpm_table(adev->powerplay.pp_handle,
67479c65f3fSEvan Quan 					    type,
67579c65f3fSEvan Quan 					    input,
67679c65f3fSEvan Quan 					    size);
67779c65f3fSEvan Quan }
67879c65f3fSEvan Quan 
67979c65f3fSEvan Quan int amdgpu_dpm_print_clock_levels(struct amdgpu_device *adev,
68079c65f3fSEvan Quan 				  enum pp_clock_type type,
68179c65f3fSEvan Quan 				  char *buf)
68279c65f3fSEvan Quan {
68379c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
68479c65f3fSEvan Quan 
68579c65f3fSEvan Quan 	if (!pp_funcs->print_clock_levels)
68679c65f3fSEvan Quan 		return 0;
68779c65f3fSEvan Quan 
68879c65f3fSEvan Quan 	return pp_funcs->print_clock_levels(adev->powerplay.pp_handle,
68979c65f3fSEvan Quan 					    type,
69079c65f3fSEvan Quan 					    buf);
69179c65f3fSEvan Quan }
69279c65f3fSEvan Quan 
69379c65f3fSEvan Quan int amdgpu_dpm_set_ppfeature_status(struct amdgpu_device *adev,
69479c65f3fSEvan Quan 				    uint64_t ppfeature_masks)
69579c65f3fSEvan Quan {
69679c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
69779c65f3fSEvan Quan 
69879c65f3fSEvan Quan 	if (!pp_funcs->set_ppfeature_status)
69979c65f3fSEvan Quan 		return 0;
70079c65f3fSEvan Quan 
70179c65f3fSEvan Quan 	return pp_funcs->set_ppfeature_status(adev->powerplay.pp_handle,
70279c65f3fSEvan Quan 					      ppfeature_masks);
70379c65f3fSEvan Quan }
70479c65f3fSEvan Quan 
70579c65f3fSEvan Quan int amdgpu_dpm_get_ppfeature_status(struct amdgpu_device *adev, char *buf)
70679c65f3fSEvan Quan {
70779c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
70879c65f3fSEvan Quan 
70979c65f3fSEvan Quan 	if (!pp_funcs->get_ppfeature_status)
71079c65f3fSEvan Quan 		return 0;
71179c65f3fSEvan Quan 
71279c65f3fSEvan Quan 	return pp_funcs->get_ppfeature_status(adev->powerplay.pp_handle,
71379c65f3fSEvan Quan 					      buf);
71479c65f3fSEvan Quan }
71579c65f3fSEvan Quan 
71679c65f3fSEvan Quan int amdgpu_dpm_force_clock_level(struct amdgpu_device *adev,
71779c65f3fSEvan Quan 				 enum pp_clock_type type,
71879c65f3fSEvan Quan 				 uint32_t mask)
71979c65f3fSEvan Quan {
72079c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
72179c65f3fSEvan Quan 
72279c65f3fSEvan Quan 	if (!pp_funcs->force_clock_level)
72379c65f3fSEvan Quan 		return 0;
72479c65f3fSEvan Quan 
72579c65f3fSEvan Quan 	return pp_funcs->force_clock_level(adev->powerplay.pp_handle,
72679c65f3fSEvan Quan 					   type,
72779c65f3fSEvan Quan 					   mask);
72879c65f3fSEvan Quan }
72979c65f3fSEvan Quan 
73079c65f3fSEvan Quan int amdgpu_dpm_get_sclk_od(struct amdgpu_device *adev)
73179c65f3fSEvan Quan {
73279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
73379c65f3fSEvan Quan 
73479c65f3fSEvan Quan 	if (!pp_funcs->get_sclk_od)
73579c65f3fSEvan Quan 		return 0;
73679c65f3fSEvan Quan 
73779c65f3fSEvan Quan 	return pp_funcs->get_sclk_od(adev->powerplay.pp_handle);
73879c65f3fSEvan Quan }
73979c65f3fSEvan Quan 
74079c65f3fSEvan Quan int amdgpu_dpm_set_sclk_od(struct amdgpu_device *adev, uint32_t value)
74179c65f3fSEvan Quan {
74279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
74379c65f3fSEvan Quan 
74479c65f3fSEvan Quan 	if (is_support_sw_smu(adev))
74579c65f3fSEvan Quan 		return 0;
74679c65f3fSEvan Quan 
74779c65f3fSEvan Quan 	if (pp_funcs->set_sclk_od)
74879c65f3fSEvan Quan 		pp_funcs->set_sclk_od(adev->powerplay.pp_handle, value);
74979c65f3fSEvan Quan 
75079c65f3fSEvan Quan 	if (amdgpu_dpm_dispatch_task(adev,
75179c65f3fSEvan Quan 				     AMD_PP_TASK_READJUST_POWER_STATE,
75279c65f3fSEvan Quan 				     NULL) == -EOPNOTSUPP) {
75379c65f3fSEvan Quan 		adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
75484176663SEvan Quan 		amdgpu_dpm_compute_clocks(adev);
75579c65f3fSEvan Quan 	}
75679c65f3fSEvan Quan 
75779c65f3fSEvan Quan 	return 0;
75879c65f3fSEvan Quan }
75979c65f3fSEvan Quan 
76079c65f3fSEvan Quan int amdgpu_dpm_get_mclk_od(struct amdgpu_device *adev)
76179c65f3fSEvan Quan {
76279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
76379c65f3fSEvan Quan 
76479c65f3fSEvan Quan 	if (!pp_funcs->get_mclk_od)
76579c65f3fSEvan Quan 		return 0;
76679c65f3fSEvan Quan 
76779c65f3fSEvan Quan 	return pp_funcs->get_mclk_od(adev->powerplay.pp_handle);
76879c65f3fSEvan Quan }
76979c65f3fSEvan Quan 
77079c65f3fSEvan Quan int amdgpu_dpm_set_mclk_od(struct amdgpu_device *adev, uint32_t value)
77179c65f3fSEvan Quan {
77279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
77379c65f3fSEvan Quan 
77479c65f3fSEvan Quan 	if (is_support_sw_smu(adev))
77579c65f3fSEvan Quan 		return 0;
77679c65f3fSEvan Quan 
77779c65f3fSEvan Quan 	if (pp_funcs->set_mclk_od)
77879c65f3fSEvan Quan 		pp_funcs->set_mclk_od(adev->powerplay.pp_handle, value);
77979c65f3fSEvan Quan 
78079c65f3fSEvan Quan 	if (amdgpu_dpm_dispatch_task(adev,
78179c65f3fSEvan Quan 				     AMD_PP_TASK_READJUST_POWER_STATE,
78279c65f3fSEvan Quan 				     NULL) == -EOPNOTSUPP) {
78379c65f3fSEvan Quan 		adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
78484176663SEvan Quan 		amdgpu_dpm_compute_clocks(adev);
78579c65f3fSEvan Quan 	}
78679c65f3fSEvan Quan 
78779c65f3fSEvan Quan 	return 0;
78879c65f3fSEvan Quan }
78979c65f3fSEvan Quan 
79079c65f3fSEvan Quan int amdgpu_dpm_get_power_profile_mode(struct amdgpu_device *adev,
79179c65f3fSEvan Quan 				      char *buf)
79279c65f3fSEvan Quan {
79379c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
79479c65f3fSEvan Quan 
79579c65f3fSEvan Quan 	if (!pp_funcs->get_power_profile_mode)
79679c65f3fSEvan Quan 		return -EOPNOTSUPP;
79779c65f3fSEvan Quan 
79879c65f3fSEvan Quan 	return pp_funcs->get_power_profile_mode(adev->powerplay.pp_handle,
79979c65f3fSEvan Quan 						buf);
80079c65f3fSEvan Quan }
80179c65f3fSEvan Quan 
80279c65f3fSEvan Quan int amdgpu_dpm_set_power_profile_mode(struct amdgpu_device *adev,
80379c65f3fSEvan Quan 				      long *input, uint32_t size)
80479c65f3fSEvan Quan {
80579c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
80679c65f3fSEvan Quan 
80779c65f3fSEvan Quan 	if (!pp_funcs->set_power_profile_mode)
80879c65f3fSEvan Quan 		return 0;
80979c65f3fSEvan Quan 
81079c65f3fSEvan Quan 	return pp_funcs->set_power_profile_mode(adev->powerplay.pp_handle,
81179c65f3fSEvan Quan 						input,
81279c65f3fSEvan Quan 						size);
81379c65f3fSEvan Quan }
81479c65f3fSEvan Quan 
81579c65f3fSEvan Quan int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void **table)
81679c65f3fSEvan Quan {
81779c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
81879c65f3fSEvan Quan 
81979c65f3fSEvan Quan 	if (!pp_funcs->get_gpu_metrics)
82079c65f3fSEvan Quan 		return 0;
82179c65f3fSEvan Quan 
82279c65f3fSEvan Quan 	return pp_funcs->get_gpu_metrics(adev->powerplay.pp_handle, table);
82379c65f3fSEvan Quan }
82479c65f3fSEvan Quan 
82579c65f3fSEvan Quan int amdgpu_dpm_get_fan_control_mode(struct amdgpu_device *adev,
82679c65f3fSEvan Quan 				    uint32_t *fan_mode)
82779c65f3fSEvan Quan {
82879c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
82979c65f3fSEvan Quan 
83079c65f3fSEvan Quan 	if (!pp_funcs->get_fan_control_mode)
83179c65f3fSEvan Quan 		return -EOPNOTSUPP;
83279c65f3fSEvan Quan 
83379c65f3fSEvan Quan 	*fan_mode = pp_funcs->get_fan_control_mode(adev->powerplay.pp_handle);
83479c65f3fSEvan Quan 
83579c65f3fSEvan Quan 	return 0;
83679c65f3fSEvan Quan }
83779c65f3fSEvan Quan 
83879c65f3fSEvan Quan int amdgpu_dpm_set_fan_speed_pwm(struct amdgpu_device *adev,
83979c65f3fSEvan Quan 				 uint32_t speed)
84079c65f3fSEvan Quan {
84179c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
84279c65f3fSEvan Quan 
84379c65f3fSEvan Quan 	if (!pp_funcs->set_fan_speed_pwm)
84479c65f3fSEvan Quan 		return -EINVAL;
84579c65f3fSEvan Quan 
84679c65f3fSEvan Quan 	return pp_funcs->set_fan_speed_pwm(adev->powerplay.pp_handle, speed);
84779c65f3fSEvan Quan }
84879c65f3fSEvan Quan 
84979c65f3fSEvan Quan int amdgpu_dpm_get_fan_speed_pwm(struct amdgpu_device *adev,
85079c65f3fSEvan Quan 				 uint32_t *speed)
85179c65f3fSEvan Quan {
85279c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
85379c65f3fSEvan Quan 
85479c65f3fSEvan Quan 	if (!pp_funcs->get_fan_speed_pwm)
85579c65f3fSEvan Quan 		return -EINVAL;
85679c65f3fSEvan Quan 
85779c65f3fSEvan Quan 	return pp_funcs->get_fan_speed_pwm(adev->powerplay.pp_handle, speed);
85879c65f3fSEvan Quan }
85979c65f3fSEvan Quan 
86079c65f3fSEvan Quan int amdgpu_dpm_get_fan_speed_rpm(struct amdgpu_device *adev,
86179c65f3fSEvan Quan 				 uint32_t *speed)
86279c65f3fSEvan Quan {
86379c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
86479c65f3fSEvan Quan 
86579c65f3fSEvan Quan 	if (!pp_funcs->get_fan_speed_rpm)
86679c65f3fSEvan Quan 		return -EINVAL;
86779c65f3fSEvan Quan 
86879c65f3fSEvan Quan 	return pp_funcs->get_fan_speed_rpm(adev->powerplay.pp_handle, speed);
86979c65f3fSEvan Quan }
87079c65f3fSEvan Quan 
87179c65f3fSEvan Quan int amdgpu_dpm_set_fan_speed_rpm(struct amdgpu_device *adev,
87279c65f3fSEvan Quan 				 uint32_t speed)
87379c65f3fSEvan Quan {
87479c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
87579c65f3fSEvan Quan 
87679c65f3fSEvan Quan 	if (!pp_funcs->set_fan_speed_rpm)
87779c65f3fSEvan Quan 		return -EINVAL;
87879c65f3fSEvan Quan 
87979c65f3fSEvan Quan 	return pp_funcs->set_fan_speed_rpm(adev->powerplay.pp_handle, speed);
88079c65f3fSEvan Quan }
88179c65f3fSEvan Quan 
88279c65f3fSEvan Quan int amdgpu_dpm_set_fan_control_mode(struct amdgpu_device *adev,
88379c65f3fSEvan Quan 				    uint32_t mode)
88479c65f3fSEvan Quan {
88579c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
88679c65f3fSEvan Quan 
88779c65f3fSEvan Quan 	if (!pp_funcs->set_fan_control_mode)
88879c65f3fSEvan Quan 		return -EOPNOTSUPP;
88979c65f3fSEvan Quan 
89079c65f3fSEvan Quan 	pp_funcs->set_fan_control_mode(adev->powerplay.pp_handle, mode);
89179c65f3fSEvan Quan 
89279c65f3fSEvan Quan 	return 0;
89379c65f3fSEvan Quan }
89479c65f3fSEvan Quan 
89579c65f3fSEvan Quan int amdgpu_dpm_get_power_limit(struct amdgpu_device *adev,
89679c65f3fSEvan Quan 			       uint32_t *limit,
89779c65f3fSEvan Quan 			       enum pp_power_limit_level pp_limit_level,
89879c65f3fSEvan Quan 			       enum pp_power_type power_type)
89979c65f3fSEvan Quan {
90079c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
90179c65f3fSEvan Quan 
90279c65f3fSEvan Quan 	if (!pp_funcs->get_power_limit)
90379c65f3fSEvan Quan 		return -ENODATA;
90479c65f3fSEvan Quan 
90579c65f3fSEvan Quan 	return pp_funcs->get_power_limit(adev->powerplay.pp_handle,
90679c65f3fSEvan Quan 					 limit,
90779c65f3fSEvan Quan 					 pp_limit_level,
90879c65f3fSEvan Quan 					 power_type);
90979c65f3fSEvan Quan }
91079c65f3fSEvan Quan 
91179c65f3fSEvan Quan int amdgpu_dpm_set_power_limit(struct amdgpu_device *adev,
91279c65f3fSEvan Quan 			       uint32_t limit)
91379c65f3fSEvan Quan {
91479c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
91579c65f3fSEvan Quan 
91679c65f3fSEvan Quan 	if (!pp_funcs->set_power_limit)
91779c65f3fSEvan Quan 		return -EINVAL;
91879c65f3fSEvan Quan 
91979c65f3fSEvan Quan 	return pp_funcs->set_power_limit(adev->powerplay.pp_handle, limit);
92079c65f3fSEvan Quan }
92179c65f3fSEvan Quan 
92279c65f3fSEvan Quan int amdgpu_dpm_is_cclk_dpm_supported(struct amdgpu_device *adev)
92379c65f3fSEvan Quan {
92479c65f3fSEvan Quan 	if (!is_support_sw_smu(adev))
92579c65f3fSEvan Quan 		return false;
92679c65f3fSEvan Quan 
92779c65f3fSEvan Quan 	return is_support_cclk_dpm(adev);
92879c65f3fSEvan Quan }
92979c65f3fSEvan Quan 
93079c65f3fSEvan Quan int amdgpu_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev,
93179c65f3fSEvan Quan 						       struct seq_file *m)
93279c65f3fSEvan Quan {
93379c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
93479c65f3fSEvan Quan 
93579c65f3fSEvan Quan 	if (!pp_funcs->debugfs_print_current_performance_level)
93679c65f3fSEvan Quan 		return -EOPNOTSUPP;
93779c65f3fSEvan Quan 
93879c65f3fSEvan Quan 	pp_funcs->debugfs_print_current_performance_level(adev->powerplay.pp_handle,
93979c65f3fSEvan Quan 							  m);
94079c65f3fSEvan Quan 
94179c65f3fSEvan Quan 	return 0;
94279c65f3fSEvan Quan }
94379c65f3fSEvan Quan 
94479c65f3fSEvan Quan int amdgpu_dpm_get_smu_prv_buf_details(struct amdgpu_device *adev,
94579c65f3fSEvan Quan 				       void **addr,
94679c65f3fSEvan Quan 				       size_t *size)
94779c65f3fSEvan Quan {
94879c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
94979c65f3fSEvan Quan 
95079c65f3fSEvan Quan 	if (!pp_funcs->get_smu_prv_buf_details)
95179c65f3fSEvan Quan 		return -ENOSYS;
95279c65f3fSEvan Quan 
95379c65f3fSEvan Quan 	return pp_funcs->get_smu_prv_buf_details(adev->powerplay.pp_handle,
95479c65f3fSEvan Quan 						 addr,
95579c65f3fSEvan Quan 						 size);
95679c65f3fSEvan Quan }
95779c65f3fSEvan Quan 
95879c65f3fSEvan Quan int amdgpu_dpm_is_overdrive_supported(struct amdgpu_device *adev)
95979c65f3fSEvan Quan {
96079c65f3fSEvan Quan 	struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
961*ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
96279c65f3fSEvan Quan 
963*ebfc2533SEvan Quan 	if ((is_support_sw_smu(adev) && smu->od_enabled) ||
964*ebfc2533SEvan Quan 	    (is_support_sw_smu(adev) && smu->is_apu) ||
96579c65f3fSEvan Quan 		(!is_support_sw_smu(adev) && hwmgr->od_enabled))
96679c65f3fSEvan Quan 		return true;
96779c65f3fSEvan Quan 
96879c65f3fSEvan Quan 	return false;
96979c65f3fSEvan Quan }
97079c65f3fSEvan Quan 
97179c65f3fSEvan Quan int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev,
97279c65f3fSEvan Quan 			    const char *buf,
97379c65f3fSEvan Quan 			    size_t size)
97479c65f3fSEvan Quan {
97579c65f3fSEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
97679c65f3fSEvan Quan 
97779c65f3fSEvan Quan 	if (!pp_funcs->set_pp_table)
97879c65f3fSEvan Quan 		return -EOPNOTSUPP;
97979c65f3fSEvan Quan 
98079c65f3fSEvan Quan 	return pp_funcs->set_pp_table(adev->powerplay.pp_handle,
98179c65f3fSEvan Quan 				      buf,
98279c65f3fSEvan Quan 				      size);
98379c65f3fSEvan Quan }
98479c65f3fSEvan Quan 
98579c65f3fSEvan Quan int amdgpu_dpm_get_num_cpu_cores(struct amdgpu_device *adev)
98679c65f3fSEvan Quan {
987*ebfc2533SEvan Quan 	struct smu_context *smu = adev->powerplay.pp_handle;
988*ebfc2533SEvan Quan 
989*ebfc2533SEvan Quan 	return smu->cpu_core_num;
99079c65f3fSEvan Quan }
99179c65f3fSEvan Quan 
99279c65f3fSEvan Quan void amdgpu_dpm_stb_debug_fs_init(struct amdgpu_device *adev)
99379c65f3fSEvan Quan {
99479c65f3fSEvan Quan 	if (!is_support_sw_smu(adev))
99579c65f3fSEvan Quan 		return;
99679c65f3fSEvan Quan 
99779c65f3fSEvan Quan 	amdgpu_smu_stb_debug_fs_init(adev);
99879c65f3fSEvan Quan }
99913f5dbd6SEvan Quan 
100013f5dbd6SEvan Quan int amdgpu_dpm_display_configuration_change(struct amdgpu_device *adev,
100113f5dbd6SEvan Quan 					    const struct amd_pp_display_configuration *input)
100213f5dbd6SEvan Quan {
100313f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
100413f5dbd6SEvan Quan 
100513f5dbd6SEvan Quan 	if (!pp_funcs->display_configuration_change)
100613f5dbd6SEvan Quan 		return 0;
100713f5dbd6SEvan Quan 
100813f5dbd6SEvan Quan 	return pp_funcs->display_configuration_change(adev->powerplay.pp_handle,
100913f5dbd6SEvan Quan 						      input);
101013f5dbd6SEvan Quan }
101113f5dbd6SEvan Quan 
101213f5dbd6SEvan Quan int amdgpu_dpm_get_clock_by_type(struct amdgpu_device *adev,
101313f5dbd6SEvan Quan 				 enum amd_pp_clock_type type,
101413f5dbd6SEvan Quan 				 struct amd_pp_clocks *clocks)
101513f5dbd6SEvan Quan {
101613f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
101713f5dbd6SEvan Quan 
101813f5dbd6SEvan Quan 	if (!pp_funcs->get_clock_by_type)
101913f5dbd6SEvan Quan 		return 0;
102013f5dbd6SEvan Quan 
102113f5dbd6SEvan Quan 	return pp_funcs->get_clock_by_type(adev->powerplay.pp_handle,
102213f5dbd6SEvan Quan 					   type,
102313f5dbd6SEvan Quan 					   clocks);
102413f5dbd6SEvan Quan }
102513f5dbd6SEvan Quan 
102613f5dbd6SEvan Quan int amdgpu_dpm_get_display_mode_validation_clks(struct amdgpu_device *adev,
102713f5dbd6SEvan Quan 						struct amd_pp_simple_clock_info *clocks)
102813f5dbd6SEvan Quan {
102913f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
103013f5dbd6SEvan Quan 
103113f5dbd6SEvan Quan 	if (!pp_funcs->get_display_mode_validation_clocks)
103213f5dbd6SEvan Quan 		return 0;
103313f5dbd6SEvan Quan 
103413f5dbd6SEvan Quan 	return pp_funcs->get_display_mode_validation_clocks(adev->powerplay.pp_handle,
103513f5dbd6SEvan Quan 							    clocks);
103613f5dbd6SEvan Quan }
103713f5dbd6SEvan Quan 
103813f5dbd6SEvan Quan int amdgpu_dpm_get_clock_by_type_with_latency(struct amdgpu_device *adev,
103913f5dbd6SEvan Quan 					      enum amd_pp_clock_type type,
104013f5dbd6SEvan Quan 					      struct pp_clock_levels_with_latency *clocks)
104113f5dbd6SEvan Quan {
104213f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
104313f5dbd6SEvan Quan 
104413f5dbd6SEvan Quan 	if (!pp_funcs->get_clock_by_type_with_latency)
104513f5dbd6SEvan Quan 		return 0;
104613f5dbd6SEvan Quan 
104713f5dbd6SEvan Quan 	return pp_funcs->get_clock_by_type_with_latency(adev->powerplay.pp_handle,
104813f5dbd6SEvan Quan 							type,
104913f5dbd6SEvan Quan 							clocks);
105013f5dbd6SEvan Quan }
105113f5dbd6SEvan Quan 
105213f5dbd6SEvan Quan int amdgpu_dpm_get_clock_by_type_with_voltage(struct amdgpu_device *adev,
105313f5dbd6SEvan Quan 					      enum amd_pp_clock_type type,
105413f5dbd6SEvan Quan 					      struct pp_clock_levels_with_voltage *clocks)
105513f5dbd6SEvan Quan {
105613f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
105713f5dbd6SEvan Quan 
105813f5dbd6SEvan Quan 	if (!pp_funcs->get_clock_by_type_with_voltage)
105913f5dbd6SEvan Quan 		return 0;
106013f5dbd6SEvan Quan 
106113f5dbd6SEvan Quan 	return pp_funcs->get_clock_by_type_with_voltage(adev->powerplay.pp_handle,
106213f5dbd6SEvan Quan 							type,
106313f5dbd6SEvan Quan 							clocks);
106413f5dbd6SEvan Quan }
106513f5dbd6SEvan Quan 
106613f5dbd6SEvan Quan int amdgpu_dpm_set_watermarks_for_clocks_ranges(struct amdgpu_device *adev,
106713f5dbd6SEvan Quan 					       void *clock_ranges)
106813f5dbd6SEvan Quan {
106913f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
107013f5dbd6SEvan Quan 
107113f5dbd6SEvan Quan 	if (!pp_funcs->set_watermarks_for_clocks_ranges)
107213f5dbd6SEvan Quan 		return -EOPNOTSUPP;
107313f5dbd6SEvan Quan 
107413f5dbd6SEvan Quan 	return pp_funcs->set_watermarks_for_clocks_ranges(adev->powerplay.pp_handle,
107513f5dbd6SEvan Quan 							  clock_ranges);
107613f5dbd6SEvan Quan }
107713f5dbd6SEvan Quan 
107813f5dbd6SEvan Quan int amdgpu_dpm_display_clock_voltage_request(struct amdgpu_device *adev,
107913f5dbd6SEvan Quan 					     struct pp_display_clock_request *clock)
108013f5dbd6SEvan Quan {
108113f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
108213f5dbd6SEvan Quan 
108313f5dbd6SEvan Quan 	if (!pp_funcs->display_clock_voltage_request)
108413f5dbd6SEvan Quan 		return -EOPNOTSUPP;
108513f5dbd6SEvan Quan 
108613f5dbd6SEvan Quan 	return pp_funcs->display_clock_voltage_request(adev->powerplay.pp_handle,
108713f5dbd6SEvan Quan 						       clock);
108813f5dbd6SEvan Quan }
108913f5dbd6SEvan Quan 
109013f5dbd6SEvan Quan int amdgpu_dpm_get_current_clocks(struct amdgpu_device *adev,
109113f5dbd6SEvan Quan 				  struct amd_pp_clock_info *clocks)
109213f5dbd6SEvan Quan {
109313f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
109413f5dbd6SEvan Quan 
109513f5dbd6SEvan Quan 	if (!pp_funcs->get_current_clocks)
109613f5dbd6SEvan Quan 		return -EOPNOTSUPP;
109713f5dbd6SEvan Quan 
109813f5dbd6SEvan Quan 	return pp_funcs->get_current_clocks(adev->powerplay.pp_handle,
109913f5dbd6SEvan Quan 					    clocks);
110013f5dbd6SEvan Quan }
110113f5dbd6SEvan Quan 
110213f5dbd6SEvan Quan void amdgpu_dpm_notify_smu_enable_pwe(struct amdgpu_device *adev)
110313f5dbd6SEvan Quan {
110413f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
110513f5dbd6SEvan Quan 
110613f5dbd6SEvan Quan 	if (!pp_funcs->notify_smu_enable_pwe)
110713f5dbd6SEvan Quan 		return;
110813f5dbd6SEvan Quan 
110913f5dbd6SEvan Quan 	pp_funcs->notify_smu_enable_pwe(adev->powerplay.pp_handle);
111013f5dbd6SEvan Quan }
111113f5dbd6SEvan Quan 
111213f5dbd6SEvan Quan int amdgpu_dpm_set_active_display_count(struct amdgpu_device *adev,
111313f5dbd6SEvan Quan 					uint32_t count)
111413f5dbd6SEvan Quan {
111513f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
111613f5dbd6SEvan Quan 
111713f5dbd6SEvan Quan 	if (!pp_funcs->set_active_display_count)
111813f5dbd6SEvan Quan 		return -EOPNOTSUPP;
111913f5dbd6SEvan Quan 
112013f5dbd6SEvan Quan 	return pp_funcs->set_active_display_count(adev->powerplay.pp_handle,
112113f5dbd6SEvan Quan 						  count);
112213f5dbd6SEvan Quan }
112313f5dbd6SEvan Quan 
112413f5dbd6SEvan Quan int amdgpu_dpm_set_min_deep_sleep_dcefclk(struct amdgpu_device *adev,
112513f5dbd6SEvan Quan 					  uint32_t clock)
112613f5dbd6SEvan Quan {
112713f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
112813f5dbd6SEvan Quan 
112913f5dbd6SEvan Quan 	if (!pp_funcs->set_min_deep_sleep_dcefclk)
113013f5dbd6SEvan Quan 		return -EOPNOTSUPP;
113113f5dbd6SEvan Quan 
113213f5dbd6SEvan Quan 	return pp_funcs->set_min_deep_sleep_dcefclk(adev->powerplay.pp_handle,
113313f5dbd6SEvan Quan 						    clock);
113413f5dbd6SEvan Quan }
113513f5dbd6SEvan Quan 
113613f5dbd6SEvan Quan void amdgpu_dpm_set_hard_min_dcefclk_by_freq(struct amdgpu_device *adev,
113713f5dbd6SEvan Quan 					     uint32_t clock)
113813f5dbd6SEvan Quan {
113913f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
114013f5dbd6SEvan Quan 
114113f5dbd6SEvan Quan 	if (!pp_funcs->set_hard_min_dcefclk_by_freq)
114213f5dbd6SEvan Quan 		return;
114313f5dbd6SEvan Quan 
114413f5dbd6SEvan Quan 	pp_funcs->set_hard_min_dcefclk_by_freq(adev->powerplay.pp_handle,
114513f5dbd6SEvan Quan 					       clock);
114613f5dbd6SEvan Quan }
114713f5dbd6SEvan Quan 
114813f5dbd6SEvan Quan void amdgpu_dpm_set_hard_min_fclk_by_freq(struct amdgpu_device *adev,
114913f5dbd6SEvan Quan 					  uint32_t clock)
115013f5dbd6SEvan Quan {
115113f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
115213f5dbd6SEvan Quan 
115313f5dbd6SEvan Quan 	if (!pp_funcs->set_hard_min_fclk_by_freq)
115413f5dbd6SEvan Quan 		return;
115513f5dbd6SEvan Quan 
115613f5dbd6SEvan Quan 	pp_funcs->set_hard_min_fclk_by_freq(adev->powerplay.pp_handle,
115713f5dbd6SEvan Quan 					    clock);
115813f5dbd6SEvan Quan }
115913f5dbd6SEvan Quan 
116013f5dbd6SEvan Quan int amdgpu_dpm_display_disable_memory_clock_switch(struct amdgpu_device *adev,
116113f5dbd6SEvan Quan 						   bool disable_memory_clock_switch)
116213f5dbd6SEvan Quan {
116313f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
116413f5dbd6SEvan Quan 
116513f5dbd6SEvan Quan 	if (!pp_funcs->display_disable_memory_clock_switch)
116613f5dbd6SEvan Quan 		return 0;
116713f5dbd6SEvan Quan 
116813f5dbd6SEvan Quan 	return pp_funcs->display_disable_memory_clock_switch(adev->powerplay.pp_handle,
116913f5dbd6SEvan Quan 							     disable_memory_clock_switch);
117013f5dbd6SEvan Quan }
117113f5dbd6SEvan Quan 
117213f5dbd6SEvan Quan int amdgpu_dpm_get_max_sustainable_clocks_by_dc(struct amdgpu_device *adev,
117313f5dbd6SEvan Quan 						struct pp_smu_nv_clock_table *max_clocks)
117413f5dbd6SEvan Quan {
117513f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
117613f5dbd6SEvan Quan 
117713f5dbd6SEvan Quan 	if (!pp_funcs->get_max_sustainable_clocks_by_dc)
117813f5dbd6SEvan Quan 		return -EOPNOTSUPP;
117913f5dbd6SEvan Quan 
118013f5dbd6SEvan Quan 	return pp_funcs->get_max_sustainable_clocks_by_dc(adev->powerplay.pp_handle,
118113f5dbd6SEvan Quan 							  max_clocks);
118213f5dbd6SEvan Quan }
118313f5dbd6SEvan Quan 
118413f5dbd6SEvan Quan enum pp_smu_status amdgpu_dpm_get_uclk_dpm_states(struct amdgpu_device *adev,
118513f5dbd6SEvan Quan 						  unsigned int *clock_values_in_khz,
118613f5dbd6SEvan Quan 						  unsigned int *num_states)
118713f5dbd6SEvan Quan {
118813f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
118913f5dbd6SEvan Quan 
119013f5dbd6SEvan Quan 	if (!pp_funcs->get_uclk_dpm_states)
119113f5dbd6SEvan Quan 		return -EOPNOTSUPP;
119213f5dbd6SEvan Quan 
119313f5dbd6SEvan Quan 	return pp_funcs->get_uclk_dpm_states(adev->powerplay.pp_handle,
119413f5dbd6SEvan Quan 					     clock_values_in_khz,
119513f5dbd6SEvan Quan 					     num_states);
119613f5dbd6SEvan Quan }
119713f5dbd6SEvan Quan 
119813f5dbd6SEvan Quan int amdgpu_dpm_get_dpm_clock_table(struct amdgpu_device *adev,
119913f5dbd6SEvan Quan 				   struct dpm_clocks *clock_table)
120013f5dbd6SEvan Quan {
120113f5dbd6SEvan Quan 	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
120213f5dbd6SEvan Quan 
120313f5dbd6SEvan Quan 	if (!pp_funcs->get_dpm_clock_table)
120413f5dbd6SEvan Quan 		return -EOPNOTSUPP;
120513f5dbd6SEvan Quan 
120613f5dbd6SEvan Quan 	return pp_funcs->get_dpm_clock_table(adev->powerplay.pp_handle,
120713f5dbd6SEvan Quan 					     clock_table);
120813f5dbd6SEvan Quan }
1209