1ad8b1aafSjsg /*
2ad8b1aafSjsg * Copyright 2011 Advanced Micro Devices, Inc.
3ad8b1aafSjsg *
4ad8b1aafSjsg * Permission is hereby granted, free of charge, to any person obtaining a
5ad8b1aafSjsg * copy of this software and associated documentation files (the "Software"),
6ad8b1aafSjsg * to deal in the Software without restriction, including without limitation
7ad8b1aafSjsg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8ad8b1aafSjsg * and/or sell copies of the Software, and to permit persons to whom the
9ad8b1aafSjsg * Software is furnished to do so, subject to the following conditions:
10ad8b1aafSjsg *
11ad8b1aafSjsg * The above copyright notice and this permission notice shall be included in
12ad8b1aafSjsg * all copies or substantial portions of the Software.
13ad8b1aafSjsg *
14ad8b1aafSjsg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15ad8b1aafSjsg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16ad8b1aafSjsg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17ad8b1aafSjsg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18ad8b1aafSjsg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ad8b1aafSjsg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20ad8b1aafSjsg * OTHER DEALINGS IN THE SOFTWARE.
21ad8b1aafSjsg *
22ad8b1aafSjsg * Authors: Alex Deucher
23ad8b1aafSjsg */
24ad8b1aafSjsg
25ad8b1aafSjsg #include "amdgpu.h"
26ad8b1aafSjsg #include "amdgpu_atombios.h"
27ad8b1aafSjsg #include "amdgpu_i2c.h"
28ad8b1aafSjsg #include "amdgpu_dpm.h"
29ad8b1aafSjsg #include "atom.h"
30ad8b1aafSjsg #include "amd_pcie.h"
31ad8b1aafSjsg #include "amdgpu_display.h"
32ad8b1aafSjsg #include "hwmgr.h"
33ad8b1aafSjsg #include <linux/power_supply.h>
341bb76ff1Sjsg #include "amdgpu_smu.h"
35ad8b1aafSjsg
361bb76ff1Sjsg #define amdgpu_dpm_enable_bapm(adev, e) \
371bb76ff1Sjsg ((adev)->powerplay.pp_funcs->enable_bapm((adev)->powerplay.pp_handle, (e)))
38ad8b1aafSjsg
390146cd80Sjsg #define amdgpu_dpm_is_legacy_dpm(adev) ((adev)->powerplay.pp_handle == (adev))
400146cd80Sjsg
amdgpu_dpm_get_sclk(struct amdgpu_device * adev,bool low)41ad8b1aafSjsg int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low)
42ad8b1aafSjsg {
435ca02815Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
441bb76ff1Sjsg int ret = 0;
45ad8b1aafSjsg
461bb76ff1Sjsg if (!pp_funcs->get_sclk)
471bb76ff1Sjsg return 0;
481bb76ff1Sjsg
491bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
501bb76ff1Sjsg ret = pp_funcs->get_sclk((adev)->powerplay.pp_handle,
511bb76ff1Sjsg low);
521bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
531bb76ff1Sjsg
541bb76ff1Sjsg return ret;
55ad8b1aafSjsg }
56ad8b1aafSjsg
amdgpu_dpm_get_mclk(struct amdgpu_device * adev,bool low)57ad8b1aafSjsg int amdgpu_dpm_get_mclk(struct amdgpu_device *adev, bool low)
58ad8b1aafSjsg {
595ca02815Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
601bb76ff1Sjsg int ret = 0;
61ad8b1aafSjsg
621bb76ff1Sjsg if (!pp_funcs->get_mclk)
631bb76ff1Sjsg return 0;
641bb76ff1Sjsg
651bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
661bb76ff1Sjsg ret = pp_funcs->get_mclk((adev)->powerplay.pp_handle,
671bb76ff1Sjsg low);
681bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
691bb76ff1Sjsg
701bb76ff1Sjsg return ret;
71ad8b1aafSjsg }
72ad8b1aafSjsg
amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device * adev,uint32_t block_type,bool gate)73ad8b1aafSjsg int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block_type, bool gate)
74ad8b1aafSjsg {
75ad8b1aafSjsg int ret = 0;
765ca02815Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
775ca02815Sjsg enum ip_power_state pwr_state = gate ? POWER_STATE_OFF : POWER_STATE_ON;
785ca02815Sjsg
795ca02815Sjsg if (atomic_read(&adev->pm.pwr_state[block_type]) == pwr_state) {
805ca02815Sjsg dev_dbg(adev->dev, "IP block%d already in the target %s state!",
815ca02815Sjsg block_type, gate ? "gate" : "ungate");
825ca02815Sjsg return 0;
835ca02815Sjsg }
84ad8b1aafSjsg
851bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
861bb76ff1Sjsg
87ad8b1aafSjsg switch (block_type) {
88ad8b1aafSjsg case AMD_IP_BLOCK_TYPE_UVD:
89ad8b1aafSjsg case AMD_IP_BLOCK_TYPE_VCE:
90ad8b1aafSjsg case AMD_IP_BLOCK_TYPE_GFX:
91ad8b1aafSjsg case AMD_IP_BLOCK_TYPE_VCN:
92ad8b1aafSjsg case AMD_IP_BLOCK_TYPE_SDMA:
93ad8b1aafSjsg case AMD_IP_BLOCK_TYPE_JPEG:
94ad8b1aafSjsg case AMD_IP_BLOCK_TYPE_GMC:
95ad8b1aafSjsg case AMD_IP_BLOCK_TYPE_ACP:
961bb76ff1Sjsg if (pp_funcs && pp_funcs->set_powergating_by_smu)
975ca02815Sjsg ret = (pp_funcs->set_powergating_by_smu(
98ad8b1aafSjsg (adev)->powerplay.pp_handle, block_type, gate));
99ad8b1aafSjsg break;
100ad8b1aafSjsg default:
101ad8b1aafSjsg break;
102ad8b1aafSjsg }
103ad8b1aafSjsg
1045ca02815Sjsg if (!ret)
1055ca02815Sjsg atomic_set(&adev->pm.pwr_state[block_type], pwr_state);
1065ca02815Sjsg
1071bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
1081bb76ff1Sjsg
1091bb76ff1Sjsg return ret;
1101bb76ff1Sjsg }
1111bb76ff1Sjsg
amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device * adev)1121bb76ff1Sjsg int amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device *adev)
1131bb76ff1Sjsg {
1141bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
1151bb76ff1Sjsg int ret = -EOPNOTSUPP;
1161bb76ff1Sjsg
1171bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
1181bb76ff1Sjsg ret = smu_set_gfx_power_up_by_imu(smu);
1191bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
1201bb76ff1Sjsg
1211bb76ff1Sjsg drm_msleep(10);
1221bb76ff1Sjsg
123ad8b1aafSjsg return ret;
124ad8b1aafSjsg }
125ad8b1aafSjsg
amdgpu_dpm_baco_enter(struct amdgpu_device * adev)126ad8b1aafSjsg int amdgpu_dpm_baco_enter(struct amdgpu_device *adev)
127ad8b1aafSjsg {
128ad8b1aafSjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
129ad8b1aafSjsg void *pp_handle = adev->powerplay.pp_handle;
130ad8b1aafSjsg int ret = 0;
131ad8b1aafSjsg
132ad8b1aafSjsg if (!pp_funcs || !pp_funcs->set_asic_baco_state)
133ad8b1aafSjsg return -ENOENT;
134ad8b1aafSjsg
1351bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
1361bb76ff1Sjsg
137ad8b1aafSjsg /* enter BACO state */
138ad8b1aafSjsg ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
139ad8b1aafSjsg
1401bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
1411bb76ff1Sjsg
142ad8b1aafSjsg return ret;
143ad8b1aafSjsg }
144ad8b1aafSjsg
amdgpu_dpm_baco_exit(struct amdgpu_device * adev)145ad8b1aafSjsg int amdgpu_dpm_baco_exit(struct amdgpu_device *adev)
146ad8b1aafSjsg {
147ad8b1aafSjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
148ad8b1aafSjsg void *pp_handle = adev->powerplay.pp_handle;
149ad8b1aafSjsg int ret = 0;
150ad8b1aafSjsg
151ad8b1aafSjsg if (!pp_funcs || !pp_funcs->set_asic_baco_state)
152ad8b1aafSjsg return -ENOENT;
153ad8b1aafSjsg
1541bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
1551bb76ff1Sjsg
156ad8b1aafSjsg /* exit BACO state */
157ad8b1aafSjsg ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
158ad8b1aafSjsg
1591bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
1601bb76ff1Sjsg
161ad8b1aafSjsg return ret;
162ad8b1aafSjsg }
163ad8b1aafSjsg
amdgpu_dpm_set_mp1_state(struct amdgpu_device * adev,enum pp_mp1_state mp1_state)164ad8b1aafSjsg int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
165ad8b1aafSjsg enum pp_mp1_state mp1_state)
166ad8b1aafSjsg {
167ad8b1aafSjsg int ret = 0;
1685ca02815Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
169ad8b1aafSjsg
1705ca02815Sjsg if (pp_funcs && pp_funcs->set_mp1_state) {
1711bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
1721bb76ff1Sjsg
1735ca02815Sjsg ret = pp_funcs->set_mp1_state(
174ad8b1aafSjsg adev->powerplay.pp_handle,
175ad8b1aafSjsg mp1_state);
1761bb76ff1Sjsg
1771bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
178ad8b1aafSjsg }
179ad8b1aafSjsg
180ad8b1aafSjsg return ret;
181ad8b1aafSjsg }
182ad8b1aafSjsg
amdgpu_dpm_is_baco_supported(struct amdgpu_device * adev)183ad8b1aafSjsg bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev)
184ad8b1aafSjsg {
185ad8b1aafSjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
186ad8b1aafSjsg void *pp_handle = adev->powerplay.pp_handle;
187ad8b1aafSjsg bool baco_cap;
1881bb76ff1Sjsg int ret = 0;
189ad8b1aafSjsg
190ad8b1aafSjsg if (!pp_funcs || !pp_funcs->get_asic_baco_capability)
191ad8b1aafSjsg return false;
1929d9f60c4Sjsg /* Don't use baco for reset in S3.
1939d9f60c4Sjsg * This is a workaround for some platforms
1949d9f60c4Sjsg * where entering BACO during suspend
1959d9f60c4Sjsg * seems to cause reboots or hangs.
1969d9f60c4Sjsg * This might be related to the fact that BACO controls
1979d9f60c4Sjsg * power to the whole GPU including devices like audio and USB.
1989d9f60c4Sjsg * Powering down/up everything may adversely affect these other
1999d9f60c4Sjsg * devices. Needs more investigation.
2009d9f60c4Sjsg */
2019d9f60c4Sjsg if (adev->in_s3)
2029d9f60c4Sjsg return false;
203ad8b1aafSjsg
2041bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
205ad8b1aafSjsg
2061bb76ff1Sjsg ret = pp_funcs->get_asic_baco_capability(pp_handle,
2071bb76ff1Sjsg &baco_cap);
2081bb76ff1Sjsg
2091bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
2101bb76ff1Sjsg
2111bb76ff1Sjsg return ret ? false : baco_cap;
212ad8b1aafSjsg }
213ad8b1aafSjsg
amdgpu_dpm_mode2_reset(struct amdgpu_device * adev)214ad8b1aafSjsg int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev)
215ad8b1aafSjsg {
216ad8b1aafSjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
217ad8b1aafSjsg void *pp_handle = adev->powerplay.pp_handle;
2181bb76ff1Sjsg int ret = 0;
219ad8b1aafSjsg
220ad8b1aafSjsg if (!pp_funcs || !pp_funcs->asic_reset_mode_2)
221ad8b1aafSjsg return -ENOENT;
222ad8b1aafSjsg
2231bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
2241bb76ff1Sjsg
2251bb76ff1Sjsg ret = pp_funcs->asic_reset_mode_2(pp_handle);
2261bb76ff1Sjsg
2271bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
2281bb76ff1Sjsg
2291bb76ff1Sjsg return ret;
230ad8b1aafSjsg }
231ad8b1aafSjsg
amdgpu_dpm_enable_gfx_features(struct amdgpu_device * adev)232*f005ef32Sjsg int amdgpu_dpm_enable_gfx_features(struct amdgpu_device *adev)
233*f005ef32Sjsg {
234*f005ef32Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
235*f005ef32Sjsg void *pp_handle = adev->powerplay.pp_handle;
236*f005ef32Sjsg int ret = 0;
237*f005ef32Sjsg
238*f005ef32Sjsg if (!pp_funcs || !pp_funcs->asic_reset_enable_gfx_features)
239*f005ef32Sjsg return -ENOENT;
240*f005ef32Sjsg
241*f005ef32Sjsg mutex_lock(&adev->pm.mutex);
242*f005ef32Sjsg
243*f005ef32Sjsg ret = pp_funcs->asic_reset_enable_gfx_features(pp_handle);
244*f005ef32Sjsg
245*f005ef32Sjsg mutex_unlock(&adev->pm.mutex);
246*f005ef32Sjsg
247*f005ef32Sjsg return ret;
248*f005ef32Sjsg }
249*f005ef32Sjsg
amdgpu_dpm_baco_reset(struct amdgpu_device * adev)250ad8b1aafSjsg int amdgpu_dpm_baco_reset(struct amdgpu_device *adev)
251ad8b1aafSjsg {
252ad8b1aafSjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
253ad8b1aafSjsg void *pp_handle = adev->powerplay.pp_handle;
254ad8b1aafSjsg int ret = 0;
255ad8b1aafSjsg
2565ca02815Sjsg if (!pp_funcs || !pp_funcs->set_asic_baco_state)
257ad8b1aafSjsg return -ENOENT;
258ad8b1aafSjsg
2591bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
2601bb76ff1Sjsg
261ad8b1aafSjsg /* enter BACO state */
262ad8b1aafSjsg ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
263ad8b1aafSjsg if (ret)
2641bb76ff1Sjsg goto out;
265ad8b1aafSjsg
266ad8b1aafSjsg /* exit BACO state */
267ad8b1aafSjsg ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
268ad8b1aafSjsg
2691bb76ff1Sjsg out:
2701bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
2711bb76ff1Sjsg return ret;
272ad8b1aafSjsg }
273ad8b1aafSjsg
amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device * adev)274ad8b1aafSjsg bool amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device *adev)
275ad8b1aafSjsg {
2761bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
2771bb76ff1Sjsg bool support_mode1_reset = false;
278ad8b1aafSjsg
2791bb76ff1Sjsg if (is_support_sw_smu(adev)) {
2801bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
2811bb76ff1Sjsg support_mode1_reset = smu_mode1_reset_is_support(smu);
2821bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
2831bb76ff1Sjsg }
284ad8b1aafSjsg
2851bb76ff1Sjsg return support_mode1_reset;
286ad8b1aafSjsg }
287ad8b1aafSjsg
amdgpu_dpm_mode1_reset(struct amdgpu_device * adev)288ad8b1aafSjsg int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev)
289ad8b1aafSjsg {
2901bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
2911bb76ff1Sjsg int ret = -EOPNOTSUPP;
292ad8b1aafSjsg
2931bb76ff1Sjsg if (is_support_sw_smu(adev)) {
2941bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
2951bb76ff1Sjsg ret = smu_mode1_reset(smu);
2961bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
2971bb76ff1Sjsg }
298ad8b1aafSjsg
2991bb76ff1Sjsg return ret;
300ad8b1aafSjsg }
301ad8b1aafSjsg
amdgpu_dpm_switch_power_profile(struct amdgpu_device * adev,enum PP_SMC_POWER_PROFILE type,bool en)302ad8b1aafSjsg int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
303ad8b1aafSjsg enum PP_SMC_POWER_PROFILE type,
304ad8b1aafSjsg bool en)
305ad8b1aafSjsg {
3065ca02815Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
307ad8b1aafSjsg int ret = 0;
308ad8b1aafSjsg
3095ca02815Sjsg if (amdgpu_sriov_vf(adev))
3105ca02815Sjsg return 0;
3115ca02815Sjsg
3121bb76ff1Sjsg if (pp_funcs && pp_funcs->switch_power_profile) {
3131bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
3145ca02815Sjsg ret = pp_funcs->switch_power_profile(
315ad8b1aafSjsg adev->powerplay.pp_handle, type, en);
3161bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
3171bb76ff1Sjsg }
318ad8b1aafSjsg
319ad8b1aafSjsg return ret;
320ad8b1aafSjsg }
321ad8b1aafSjsg
amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device * adev,uint32_t pstate)322ad8b1aafSjsg int amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device *adev,
323ad8b1aafSjsg uint32_t pstate)
324ad8b1aafSjsg {
3255ca02815Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
326ad8b1aafSjsg int ret = 0;
327ad8b1aafSjsg
3281bb76ff1Sjsg if (pp_funcs && pp_funcs->set_xgmi_pstate) {
3291bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
3305ca02815Sjsg ret = pp_funcs->set_xgmi_pstate(adev->powerplay.pp_handle,
331ad8b1aafSjsg pstate);
3321bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
3331bb76ff1Sjsg }
334ad8b1aafSjsg
335ad8b1aafSjsg return ret;
336ad8b1aafSjsg }
337ad8b1aafSjsg
amdgpu_dpm_set_df_cstate(struct amdgpu_device * adev,uint32_t cstate)338ad8b1aafSjsg int amdgpu_dpm_set_df_cstate(struct amdgpu_device *adev,
339ad8b1aafSjsg uint32_t cstate)
340ad8b1aafSjsg {
341ad8b1aafSjsg int ret = 0;
342ad8b1aafSjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
343ad8b1aafSjsg void *pp_handle = adev->powerplay.pp_handle;
344ad8b1aafSjsg
3451bb76ff1Sjsg if (pp_funcs && pp_funcs->set_df_cstate) {
3461bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
347ad8b1aafSjsg ret = pp_funcs->set_df_cstate(pp_handle, cstate);
3481bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
3491bb76ff1Sjsg }
350ad8b1aafSjsg
351ad8b1aafSjsg return ret;
352ad8b1aafSjsg }
353ad8b1aafSjsg
amdgpu_dpm_allow_xgmi_power_down(struct amdgpu_device * adev,bool en)354ad8b1aafSjsg int amdgpu_dpm_allow_xgmi_power_down(struct amdgpu_device *adev, bool en)
355ad8b1aafSjsg {
3561bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
3571bb76ff1Sjsg int ret = 0;
358ad8b1aafSjsg
3591bb76ff1Sjsg if (is_support_sw_smu(adev)) {
3601bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
3611bb76ff1Sjsg ret = smu_allow_xgmi_power_down(smu, en);
3621bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
3631bb76ff1Sjsg }
364ad8b1aafSjsg
3651bb76ff1Sjsg return ret;
366ad8b1aafSjsg }
367ad8b1aafSjsg
amdgpu_dpm_enable_mgpu_fan_boost(struct amdgpu_device * adev)368ad8b1aafSjsg int amdgpu_dpm_enable_mgpu_fan_boost(struct amdgpu_device *adev)
369ad8b1aafSjsg {
370ad8b1aafSjsg void *pp_handle = adev->powerplay.pp_handle;
371ad8b1aafSjsg const struct amd_pm_funcs *pp_funcs =
372ad8b1aafSjsg adev->powerplay.pp_funcs;
373ad8b1aafSjsg int ret = 0;
374ad8b1aafSjsg
3751bb76ff1Sjsg if (pp_funcs && pp_funcs->enable_mgpu_fan_boost) {
3761bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
377ad8b1aafSjsg ret = pp_funcs->enable_mgpu_fan_boost(pp_handle);
3781bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
3791bb76ff1Sjsg }
380ad8b1aafSjsg
381ad8b1aafSjsg return ret;
382ad8b1aafSjsg }
383ad8b1aafSjsg
amdgpu_dpm_set_clockgating_by_smu(struct amdgpu_device * adev,uint32_t msg_id)384ad8b1aafSjsg int amdgpu_dpm_set_clockgating_by_smu(struct amdgpu_device *adev,
385ad8b1aafSjsg uint32_t msg_id)
386ad8b1aafSjsg {
387ad8b1aafSjsg void *pp_handle = adev->powerplay.pp_handle;
388ad8b1aafSjsg const struct amd_pm_funcs *pp_funcs =
389ad8b1aafSjsg adev->powerplay.pp_funcs;
390ad8b1aafSjsg int ret = 0;
391ad8b1aafSjsg
3921bb76ff1Sjsg if (pp_funcs && pp_funcs->set_clockgating_by_smu) {
3931bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
394ad8b1aafSjsg ret = pp_funcs->set_clockgating_by_smu(pp_handle,
395ad8b1aafSjsg msg_id);
3961bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
3971bb76ff1Sjsg }
398ad8b1aafSjsg
399ad8b1aafSjsg return ret;
400ad8b1aafSjsg }
401ad8b1aafSjsg
amdgpu_dpm_smu_i2c_bus_access(struct amdgpu_device * adev,bool acquire)402ad8b1aafSjsg int amdgpu_dpm_smu_i2c_bus_access(struct amdgpu_device *adev,
403ad8b1aafSjsg bool acquire)
404ad8b1aafSjsg {
405ad8b1aafSjsg void *pp_handle = adev->powerplay.pp_handle;
406ad8b1aafSjsg const struct amd_pm_funcs *pp_funcs =
407ad8b1aafSjsg adev->powerplay.pp_funcs;
408ad8b1aafSjsg int ret = -EOPNOTSUPP;
409ad8b1aafSjsg
4101bb76ff1Sjsg if (pp_funcs && pp_funcs->smu_i2c_bus_access) {
4111bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
412ad8b1aafSjsg ret = pp_funcs->smu_i2c_bus_access(pp_handle,
413ad8b1aafSjsg acquire);
4141bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
4151bb76ff1Sjsg }
416ad8b1aafSjsg
417ad8b1aafSjsg return ret;
418ad8b1aafSjsg }
419ad8b1aafSjsg
amdgpu_pm_acpi_event_handler(struct amdgpu_device * adev)420ad8b1aafSjsg void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev)
421ad8b1aafSjsg {
422ad8b1aafSjsg if (adev->pm.dpm_enabled) {
423ad8b1aafSjsg mutex_lock(&adev->pm.mutex);
424ad8b1aafSjsg if (power_supply_is_system_supplied() > 0)
425ad8b1aafSjsg adev->pm.ac_power = true;
426ad8b1aafSjsg else
427ad8b1aafSjsg adev->pm.ac_power = false;
4281bb76ff1Sjsg
429ad8b1aafSjsg if (adev->powerplay.pp_funcs &&
430ad8b1aafSjsg adev->powerplay.pp_funcs->enable_bapm)
431ad8b1aafSjsg amdgpu_dpm_enable_bapm(adev, adev->pm.ac_power);
432ad8b1aafSjsg
433ad8b1aafSjsg if (is_support_sw_smu(adev))
4341bb76ff1Sjsg smu_set_ac_dc(adev->powerplay.pp_handle);
4351bb76ff1Sjsg
4361bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
437ad8b1aafSjsg }
438ad8b1aafSjsg }
439ad8b1aafSjsg
amdgpu_dpm_read_sensor(struct amdgpu_device * adev,enum amd_pp_sensors sensor,void * data,uint32_t * size)440ad8b1aafSjsg int amdgpu_dpm_read_sensor(struct amdgpu_device *adev, enum amd_pp_sensors sensor,
441ad8b1aafSjsg void *data, uint32_t *size)
442ad8b1aafSjsg {
4435ca02815Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
4441bb76ff1Sjsg int ret = -EINVAL;
445ad8b1aafSjsg
446ad8b1aafSjsg if (!data || !size)
447ad8b1aafSjsg return -EINVAL;
448ad8b1aafSjsg
4491bb76ff1Sjsg if (pp_funcs && pp_funcs->read_sensor) {
4501bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
4511bb76ff1Sjsg ret = pp_funcs->read_sensor(adev->powerplay.pp_handle,
4521bb76ff1Sjsg sensor,
4531bb76ff1Sjsg data,
4541bb76ff1Sjsg size);
4551bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
4561bb76ff1Sjsg }
457ad8b1aafSjsg
458ad8b1aafSjsg return ret;
459ad8b1aafSjsg }
460ad8b1aafSjsg
amdgpu_dpm_get_apu_thermal_limit(struct amdgpu_device * adev,uint32_t * limit)461*f005ef32Sjsg int amdgpu_dpm_get_apu_thermal_limit(struct amdgpu_device *adev, uint32_t *limit)
462*f005ef32Sjsg {
463*f005ef32Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
464*f005ef32Sjsg int ret = -EINVAL;
465*f005ef32Sjsg
466*f005ef32Sjsg if (pp_funcs && pp_funcs->get_apu_thermal_limit) {
467*f005ef32Sjsg mutex_lock(&adev->pm.mutex);
468*f005ef32Sjsg ret = pp_funcs->get_apu_thermal_limit(adev->powerplay.pp_handle, limit);
469*f005ef32Sjsg mutex_unlock(&adev->pm.mutex);
470*f005ef32Sjsg }
471*f005ef32Sjsg
472*f005ef32Sjsg return ret;
473*f005ef32Sjsg }
474*f005ef32Sjsg
amdgpu_dpm_set_apu_thermal_limit(struct amdgpu_device * adev,uint32_t limit)475*f005ef32Sjsg int amdgpu_dpm_set_apu_thermal_limit(struct amdgpu_device *adev, uint32_t limit)
476*f005ef32Sjsg {
477*f005ef32Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
478*f005ef32Sjsg int ret = -EINVAL;
479*f005ef32Sjsg
480*f005ef32Sjsg if (pp_funcs && pp_funcs->set_apu_thermal_limit) {
481*f005ef32Sjsg mutex_lock(&adev->pm.mutex);
482*f005ef32Sjsg ret = pp_funcs->set_apu_thermal_limit(adev->powerplay.pp_handle, limit);
483*f005ef32Sjsg mutex_unlock(&adev->pm.mutex);
484*f005ef32Sjsg }
485*f005ef32Sjsg
486*f005ef32Sjsg return ret;
487*f005ef32Sjsg }
488*f005ef32Sjsg
amdgpu_dpm_compute_clocks(struct amdgpu_device * adev)4891bb76ff1Sjsg void amdgpu_dpm_compute_clocks(struct amdgpu_device *adev)
490ad8b1aafSjsg {
4911bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
492ad8b1aafSjsg int i;
493ad8b1aafSjsg
494ad8b1aafSjsg if (!adev->pm.dpm_enabled)
495ad8b1aafSjsg return;
496ad8b1aafSjsg
4971bb76ff1Sjsg if (!pp_funcs->pm_compute_clocks)
4981bb76ff1Sjsg return;
4991bb76ff1Sjsg
500ad8b1aafSjsg if (adev->mode_info.num_crtc)
501ad8b1aafSjsg amdgpu_display_bandwidth_update(adev);
502ad8b1aafSjsg
503ad8b1aafSjsg for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
504ad8b1aafSjsg struct amdgpu_ring *ring = adev->rings[i];
505ad8b1aafSjsg if (ring && ring->sched.ready)
506ad8b1aafSjsg amdgpu_fence_wait_empty(ring);
507ad8b1aafSjsg }
508ad8b1aafSjsg
509ad8b1aafSjsg mutex_lock(&adev->pm.mutex);
5101bb76ff1Sjsg pp_funcs->pm_compute_clocks(adev->powerplay.pp_handle);
511ad8b1aafSjsg mutex_unlock(&adev->pm.mutex);
512ad8b1aafSjsg }
513ad8b1aafSjsg
amdgpu_dpm_enable_uvd(struct amdgpu_device * adev,bool enable)514ad8b1aafSjsg void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
515ad8b1aafSjsg {
516ad8b1aafSjsg int ret = 0;
517ad8b1aafSjsg
518ad8b1aafSjsg if (adev->family == AMDGPU_FAMILY_SI) {
519ad8b1aafSjsg mutex_lock(&adev->pm.mutex);
520ad8b1aafSjsg if (enable) {
521ad8b1aafSjsg adev->pm.dpm.uvd_active = true;
522ad8b1aafSjsg adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
523ad8b1aafSjsg } else {
524ad8b1aafSjsg adev->pm.dpm.uvd_active = false;
525ad8b1aafSjsg }
526ad8b1aafSjsg mutex_unlock(&adev->pm.mutex);
527ad8b1aafSjsg
5281bb76ff1Sjsg amdgpu_dpm_compute_clocks(adev);
5291bb76ff1Sjsg return;
5301bb76ff1Sjsg }
5311bb76ff1Sjsg
532ad8b1aafSjsg ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable);
533ad8b1aafSjsg if (ret)
534ad8b1aafSjsg DRM_ERROR("Dpm %s uvd failed, ret = %d. \n",
535ad8b1aafSjsg enable ? "enable" : "disable", ret);
536ad8b1aafSjsg }
537ad8b1aafSjsg
amdgpu_dpm_enable_vce(struct amdgpu_device * adev,bool enable)538ad8b1aafSjsg void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
539ad8b1aafSjsg {
540ad8b1aafSjsg int ret = 0;
541ad8b1aafSjsg
542ad8b1aafSjsg if (adev->family == AMDGPU_FAMILY_SI) {
543ad8b1aafSjsg mutex_lock(&adev->pm.mutex);
544ad8b1aafSjsg if (enable) {
545ad8b1aafSjsg adev->pm.dpm.vce_active = true;
546ad8b1aafSjsg /* XXX select vce level based on ring/task */
547ad8b1aafSjsg adev->pm.dpm.vce_level = AMD_VCE_LEVEL_AC_ALL;
548ad8b1aafSjsg } else {
549ad8b1aafSjsg adev->pm.dpm.vce_active = false;
550ad8b1aafSjsg }
551ad8b1aafSjsg mutex_unlock(&adev->pm.mutex);
552ad8b1aafSjsg
5531bb76ff1Sjsg amdgpu_dpm_compute_clocks(adev);
5541bb76ff1Sjsg return;
5551bb76ff1Sjsg }
5561bb76ff1Sjsg
557ad8b1aafSjsg ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable);
558ad8b1aafSjsg if (ret)
559ad8b1aafSjsg DRM_ERROR("Dpm %s vce failed, ret = %d. \n",
560ad8b1aafSjsg enable ? "enable" : "disable", ret);
561ad8b1aafSjsg }
562ad8b1aafSjsg
amdgpu_dpm_enable_jpeg(struct amdgpu_device * adev,bool enable)563ad8b1aafSjsg void amdgpu_dpm_enable_jpeg(struct amdgpu_device *adev, bool enable)
564ad8b1aafSjsg {
565ad8b1aafSjsg int ret = 0;
566ad8b1aafSjsg
567ad8b1aafSjsg ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_JPEG, !enable);
568ad8b1aafSjsg if (ret)
569ad8b1aafSjsg DRM_ERROR("Dpm %s jpeg failed, ret = %d. \n",
570ad8b1aafSjsg enable ? "enable" : "disable", ret);
571ad8b1aafSjsg }
572ad8b1aafSjsg
amdgpu_pm_load_smu_firmware(struct amdgpu_device * adev,uint32_t * smu_version)573ad8b1aafSjsg int amdgpu_pm_load_smu_firmware(struct amdgpu_device *adev, uint32_t *smu_version)
574ad8b1aafSjsg {
5751bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
5761bb76ff1Sjsg int r = 0;
577ad8b1aafSjsg
5781bb76ff1Sjsg if (!pp_funcs || !pp_funcs->load_firmware)
5791bb76ff1Sjsg return 0;
5801bb76ff1Sjsg
5811bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
5821bb76ff1Sjsg r = pp_funcs->load_firmware(adev->powerplay.pp_handle);
583ad8b1aafSjsg if (r) {
584ad8b1aafSjsg pr_err("smu firmware loading failed\n");
5851bb76ff1Sjsg goto out;
586ad8b1aafSjsg }
5875ca02815Sjsg
5885ca02815Sjsg if (smu_version)
589ad8b1aafSjsg *smu_version = adev->pm.fw_version;
5901bb76ff1Sjsg
5911bb76ff1Sjsg out:
5921bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
5931bb76ff1Sjsg return r;
5941bb76ff1Sjsg }
5951bb76ff1Sjsg
amdgpu_dpm_handle_passthrough_sbr(struct amdgpu_device * adev,bool enable)5961bb76ff1Sjsg int amdgpu_dpm_handle_passthrough_sbr(struct amdgpu_device *adev, bool enable)
5971bb76ff1Sjsg {
5981bb76ff1Sjsg int ret = 0;
5991bb76ff1Sjsg
6001bb76ff1Sjsg if (is_support_sw_smu(adev)) {
6011bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
6021bb76ff1Sjsg ret = smu_handle_passthrough_sbr(adev->powerplay.pp_handle,
6031bb76ff1Sjsg enable);
6041bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
6051bb76ff1Sjsg }
6061bb76ff1Sjsg
6071bb76ff1Sjsg return ret;
6081bb76ff1Sjsg }
6091bb76ff1Sjsg
amdgpu_dpm_send_hbm_bad_pages_num(struct amdgpu_device * adev,uint32_t size)6101bb76ff1Sjsg int amdgpu_dpm_send_hbm_bad_pages_num(struct amdgpu_device *adev, uint32_t size)
6111bb76ff1Sjsg {
6121bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
6131bb76ff1Sjsg int ret = 0;
6141bb76ff1Sjsg
6151bb76ff1Sjsg if (!is_support_sw_smu(adev))
6161bb76ff1Sjsg return -EOPNOTSUPP;
6171bb76ff1Sjsg
6181bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
6191bb76ff1Sjsg ret = smu_send_hbm_bad_pages_num(smu, size);
6201bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
6211bb76ff1Sjsg
6221bb76ff1Sjsg return ret;
6231bb76ff1Sjsg }
6241bb76ff1Sjsg
amdgpu_dpm_send_hbm_bad_channel_flag(struct amdgpu_device * adev,uint32_t size)6251bb76ff1Sjsg int amdgpu_dpm_send_hbm_bad_channel_flag(struct amdgpu_device *adev, uint32_t size)
6261bb76ff1Sjsg {
6271bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
6281bb76ff1Sjsg int ret = 0;
6291bb76ff1Sjsg
6301bb76ff1Sjsg if (!is_support_sw_smu(adev))
6311bb76ff1Sjsg return -EOPNOTSUPP;
6321bb76ff1Sjsg
6331bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
6341bb76ff1Sjsg ret = smu_send_hbm_bad_channel_flag(smu, size);
6351bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
6361bb76ff1Sjsg
6371bb76ff1Sjsg return ret;
6381bb76ff1Sjsg }
6391bb76ff1Sjsg
amdgpu_dpm_get_dpm_freq_range(struct amdgpu_device * adev,enum pp_clock_type type,uint32_t * min,uint32_t * max)6401bb76ff1Sjsg int amdgpu_dpm_get_dpm_freq_range(struct amdgpu_device *adev,
6411bb76ff1Sjsg enum pp_clock_type type,
6421bb76ff1Sjsg uint32_t *min,
6431bb76ff1Sjsg uint32_t *max)
6441bb76ff1Sjsg {
6451bb76ff1Sjsg int ret = 0;
6461bb76ff1Sjsg
6471bb76ff1Sjsg if (type != PP_SCLK)
6481bb76ff1Sjsg return -EINVAL;
6491bb76ff1Sjsg
6501bb76ff1Sjsg if (!is_support_sw_smu(adev))
6511bb76ff1Sjsg return -EOPNOTSUPP;
6521bb76ff1Sjsg
6531bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
6541bb76ff1Sjsg ret = smu_get_dpm_freq_range(adev->powerplay.pp_handle,
6551bb76ff1Sjsg SMU_SCLK,
6561bb76ff1Sjsg min,
6571bb76ff1Sjsg max);
6581bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
6591bb76ff1Sjsg
6601bb76ff1Sjsg return ret;
6611bb76ff1Sjsg }
6621bb76ff1Sjsg
amdgpu_dpm_set_soft_freq_range(struct amdgpu_device * adev,enum pp_clock_type type,uint32_t min,uint32_t max)6631bb76ff1Sjsg int amdgpu_dpm_set_soft_freq_range(struct amdgpu_device *adev,
6641bb76ff1Sjsg enum pp_clock_type type,
6651bb76ff1Sjsg uint32_t min,
6661bb76ff1Sjsg uint32_t max)
6671bb76ff1Sjsg {
6681bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
6691bb76ff1Sjsg int ret = 0;
6701bb76ff1Sjsg
6711bb76ff1Sjsg if (type != PP_SCLK)
6721bb76ff1Sjsg return -EINVAL;
6731bb76ff1Sjsg
6741bb76ff1Sjsg if (!is_support_sw_smu(adev))
6751bb76ff1Sjsg return -EOPNOTSUPP;
6761bb76ff1Sjsg
6771bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
6781bb76ff1Sjsg ret = smu_set_soft_freq_range(smu,
6791bb76ff1Sjsg SMU_SCLK,
6801bb76ff1Sjsg min,
6811bb76ff1Sjsg max);
6821bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
6831bb76ff1Sjsg
6841bb76ff1Sjsg return ret;
6851bb76ff1Sjsg }
6861bb76ff1Sjsg
amdgpu_dpm_write_watermarks_table(struct amdgpu_device * adev)6871bb76ff1Sjsg int amdgpu_dpm_write_watermarks_table(struct amdgpu_device *adev)
6881bb76ff1Sjsg {
6891bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
6901bb76ff1Sjsg int ret = 0;
6911bb76ff1Sjsg
6921bb76ff1Sjsg if (!is_support_sw_smu(adev))
6931bb76ff1Sjsg return 0;
6941bb76ff1Sjsg
6951bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
6961bb76ff1Sjsg ret = smu_write_watermarks_table(smu);
6971bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
6981bb76ff1Sjsg
6991bb76ff1Sjsg return ret;
7001bb76ff1Sjsg }
7011bb76ff1Sjsg
amdgpu_dpm_wait_for_event(struct amdgpu_device * adev,enum smu_event_type event,uint64_t event_arg)7021bb76ff1Sjsg int amdgpu_dpm_wait_for_event(struct amdgpu_device *adev,
7031bb76ff1Sjsg enum smu_event_type event,
7041bb76ff1Sjsg uint64_t event_arg)
7051bb76ff1Sjsg {
7061bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
7071bb76ff1Sjsg int ret = 0;
7081bb76ff1Sjsg
7091bb76ff1Sjsg if (!is_support_sw_smu(adev))
7101bb76ff1Sjsg return -EOPNOTSUPP;
7111bb76ff1Sjsg
7121bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
7131bb76ff1Sjsg ret = smu_wait_for_event(smu, event, event_arg);
7141bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
7151bb76ff1Sjsg
7161bb76ff1Sjsg return ret;
7171bb76ff1Sjsg }
7181bb76ff1Sjsg
amdgpu_dpm_set_residency_gfxoff(struct amdgpu_device * adev,bool value)7191bb76ff1Sjsg int amdgpu_dpm_set_residency_gfxoff(struct amdgpu_device *adev, bool value)
7201bb76ff1Sjsg {
7211bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
7221bb76ff1Sjsg int ret = 0;
7231bb76ff1Sjsg
7241bb76ff1Sjsg if (!is_support_sw_smu(adev))
7251bb76ff1Sjsg return -EOPNOTSUPP;
7261bb76ff1Sjsg
7271bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
7281bb76ff1Sjsg ret = smu_set_residency_gfxoff(smu, value);
7291bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
7301bb76ff1Sjsg
7311bb76ff1Sjsg return ret;
7321bb76ff1Sjsg }
7331bb76ff1Sjsg
amdgpu_dpm_get_residency_gfxoff(struct amdgpu_device * adev,u32 * value)7341bb76ff1Sjsg int amdgpu_dpm_get_residency_gfxoff(struct amdgpu_device *adev, u32 *value)
7351bb76ff1Sjsg {
7361bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
7371bb76ff1Sjsg int ret = 0;
7381bb76ff1Sjsg
7391bb76ff1Sjsg if (!is_support_sw_smu(adev))
7401bb76ff1Sjsg return -EOPNOTSUPP;
7411bb76ff1Sjsg
7421bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
7431bb76ff1Sjsg ret = smu_get_residency_gfxoff(smu, value);
7441bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
7451bb76ff1Sjsg
7461bb76ff1Sjsg return ret;
7471bb76ff1Sjsg }
7481bb76ff1Sjsg
amdgpu_dpm_get_entrycount_gfxoff(struct amdgpu_device * adev,u64 * value)7491bb76ff1Sjsg int amdgpu_dpm_get_entrycount_gfxoff(struct amdgpu_device *adev, u64 *value)
7501bb76ff1Sjsg {
7511bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
7521bb76ff1Sjsg int ret = 0;
7531bb76ff1Sjsg
7541bb76ff1Sjsg if (!is_support_sw_smu(adev))
7551bb76ff1Sjsg return -EOPNOTSUPP;
7561bb76ff1Sjsg
7571bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
7581bb76ff1Sjsg ret = smu_get_entrycount_gfxoff(smu, value);
7591bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
7601bb76ff1Sjsg
7611bb76ff1Sjsg return ret;
7621bb76ff1Sjsg }
7631bb76ff1Sjsg
amdgpu_dpm_get_status_gfxoff(struct amdgpu_device * adev,uint32_t * value)7641bb76ff1Sjsg int amdgpu_dpm_get_status_gfxoff(struct amdgpu_device *adev, uint32_t *value)
7651bb76ff1Sjsg {
7661bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
7671bb76ff1Sjsg int ret = 0;
7681bb76ff1Sjsg
7691bb76ff1Sjsg if (!is_support_sw_smu(adev))
7701bb76ff1Sjsg return -EOPNOTSUPP;
7711bb76ff1Sjsg
7721bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
7731bb76ff1Sjsg ret = smu_get_status_gfxoff(smu, value);
7741bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
7751bb76ff1Sjsg
7761bb76ff1Sjsg return ret;
7771bb76ff1Sjsg }
7781bb76ff1Sjsg
amdgpu_dpm_get_thermal_throttling_counter(struct amdgpu_device * adev)7791bb76ff1Sjsg uint64_t amdgpu_dpm_get_thermal_throttling_counter(struct amdgpu_device *adev)
7801bb76ff1Sjsg {
7811bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
7821bb76ff1Sjsg
7831bb76ff1Sjsg if (!is_support_sw_smu(adev))
7841bb76ff1Sjsg return 0;
7851bb76ff1Sjsg
7861bb76ff1Sjsg return atomic64_read(&smu->throttle_int_counter);
7871bb76ff1Sjsg }
7881bb76ff1Sjsg
7891bb76ff1Sjsg /* amdgpu_dpm_gfx_state_change - Handle gfx power state change set
7901bb76ff1Sjsg * @adev: amdgpu_device pointer
7911bb76ff1Sjsg * @state: gfx power state(1 -sGpuChangeState_D0Entry and 2 -sGpuChangeState_D3Entry)
7921bb76ff1Sjsg *
7931bb76ff1Sjsg */
amdgpu_dpm_gfx_state_change(struct amdgpu_device * adev,enum gfx_change_state state)7941bb76ff1Sjsg void amdgpu_dpm_gfx_state_change(struct amdgpu_device *adev,
7951bb76ff1Sjsg enum gfx_change_state state)
7961bb76ff1Sjsg {
7971bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
7981bb76ff1Sjsg if (adev->powerplay.pp_funcs &&
7991bb76ff1Sjsg adev->powerplay.pp_funcs->gfx_state_change_set)
8001bb76ff1Sjsg ((adev)->powerplay.pp_funcs->gfx_state_change_set(
8011bb76ff1Sjsg (adev)->powerplay.pp_handle, state));
8021bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
8031bb76ff1Sjsg }
8041bb76ff1Sjsg
amdgpu_dpm_get_ecc_info(struct amdgpu_device * adev,void * umc_ecc)8051bb76ff1Sjsg int amdgpu_dpm_get_ecc_info(struct amdgpu_device *adev,
8061bb76ff1Sjsg void *umc_ecc)
8071bb76ff1Sjsg {
8081bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
8091bb76ff1Sjsg int ret = 0;
8101bb76ff1Sjsg
8111bb76ff1Sjsg if (!is_support_sw_smu(adev))
8121bb76ff1Sjsg return -EOPNOTSUPP;
8131bb76ff1Sjsg
8141bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
8151bb76ff1Sjsg ret = smu_get_ecc_info(smu, umc_ecc);
8161bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
8171bb76ff1Sjsg
8181bb76ff1Sjsg return ret;
8191bb76ff1Sjsg }
8201bb76ff1Sjsg
amdgpu_dpm_get_vce_clock_state(struct amdgpu_device * adev,uint32_t idx)8211bb76ff1Sjsg struct amd_vce_state *amdgpu_dpm_get_vce_clock_state(struct amdgpu_device *adev,
8221bb76ff1Sjsg uint32_t idx)
8231bb76ff1Sjsg {
8241bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8251bb76ff1Sjsg struct amd_vce_state *vstate = NULL;
8261bb76ff1Sjsg
8271bb76ff1Sjsg if (!pp_funcs->get_vce_clock_state)
8281bb76ff1Sjsg return NULL;
8291bb76ff1Sjsg
8301bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
8311bb76ff1Sjsg vstate = pp_funcs->get_vce_clock_state(adev->powerplay.pp_handle,
8321bb76ff1Sjsg idx);
8331bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
8341bb76ff1Sjsg
8351bb76ff1Sjsg return vstate;
8361bb76ff1Sjsg }
8371bb76ff1Sjsg
amdgpu_dpm_get_current_power_state(struct amdgpu_device * adev,enum amd_pm_state_type * state)8381bb76ff1Sjsg void amdgpu_dpm_get_current_power_state(struct amdgpu_device *adev,
8391bb76ff1Sjsg enum amd_pm_state_type *state)
8401bb76ff1Sjsg {
8411bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8421bb76ff1Sjsg
8431bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
8441bb76ff1Sjsg
8451bb76ff1Sjsg if (!pp_funcs->get_current_power_state) {
8461bb76ff1Sjsg *state = adev->pm.dpm.user_state;
8471bb76ff1Sjsg goto out;
8481bb76ff1Sjsg }
8491bb76ff1Sjsg
8501bb76ff1Sjsg *state = pp_funcs->get_current_power_state(adev->powerplay.pp_handle);
8511bb76ff1Sjsg if (*state < POWER_STATE_TYPE_DEFAULT ||
8521bb76ff1Sjsg *state > POWER_STATE_TYPE_INTERNAL_3DPERF)
8531bb76ff1Sjsg *state = adev->pm.dpm.user_state;
8541bb76ff1Sjsg
8551bb76ff1Sjsg out:
8561bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
8571bb76ff1Sjsg }
8581bb76ff1Sjsg
amdgpu_dpm_set_power_state(struct amdgpu_device * adev,enum amd_pm_state_type state)8591bb76ff1Sjsg void amdgpu_dpm_set_power_state(struct amdgpu_device *adev,
8601bb76ff1Sjsg enum amd_pm_state_type state)
8611bb76ff1Sjsg {
8621bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
8631bb76ff1Sjsg adev->pm.dpm.user_state = state;
8641bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
8651bb76ff1Sjsg
8661bb76ff1Sjsg if (is_support_sw_smu(adev))
8671bb76ff1Sjsg return;
8681bb76ff1Sjsg
8691bb76ff1Sjsg if (amdgpu_dpm_dispatch_task(adev,
8701bb76ff1Sjsg AMD_PP_TASK_ENABLE_USER_STATE,
8711bb76ff1Sjsg &state) == -EOPNOTSUPP)
8721bb76ff1Sjsg amdgpu_dpm_compute_clocks(adev);
8731bb76ff1Sjsg }
8741bb76ff1Sjsg
amdgpu_dpm_get_performance_level(struct amdgpu_device * adev)8751bb76ff1Sjsg enum amd_dpm_forced_level amdgpu_dpm_get_performance_level(struct amdgpu_device *adev)
8761bb76ff1Sjsg {
8771bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8781bb76ff1Sjsg enum amd_dpm_forced_level level;
8791bb76ff1Sjsg
8801bb76ff1Sjsg if (!pp_funcs)
8811bb76ff1Sjsg return AMD_DPM_FORCED_LEVEL_AUTO;
8821bb76ff1Sjsg
8831bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
8841bb76ff1Sjsg if (pp_funcs->get_performance_level)
8851bb76ff1Sjsg level = pp_funcs->get_performance_level(adev->powerplay.pp_handle);
8861bb76ff1Sjsg else
8871bb76ff1Sjsg level = adev->pm.dpm.forced_level;
8881bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
8891bb76ff1Sjsg
8901bb76ff1Sjsg return level;
8911bb76ff1Sjsg }
8921bb76ff1Sjsg
amdgpu_dpm_force_performance_level(struct amdgpu_device * adev,enum amd_dpm_forced_level level)8931bb76ff1Sjsg int amdgpu_dpm_force_performance_level(struct amdgpu_device *adev,
8941bb76ff1Sjsg enum amd_dpm_forced_level level)
8951bb76ff1Sjsg {
8961bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
8971bb76ff1Sjsg enum amd_dpm_forced_level current_level;
8981bb76ff1Sjsg uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
8991bb76ff1Sjsg AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
9001bb76ff1Sjsg AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
9011bb76ff1Sjsg AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
9021bb76ff1Sjsg
9031bb76ff1Sjsg if (!pp_funcs || !pp_funcs->force_performance_level)
9041bb76ff1Sjsg return 0;
9051bb76ff1Sjsg
9061bb76ff1Sjsg if (adev->pm.dpm.thermal_active)
9071bb76ff1Sjsg return -EINVAL;
9081bb76ff1Sjsg
9091bb76ff1Sjsg current_level = amdgpu_dpm_get_performance_level(adev);
9101bb76ff1Sjsg if (current_level == level)
9111bb76ff1Sjsg return 0;
9121bb76ff1Sjsg
9131bb76ff1Sjsg if (adev->asic_type == CHIP_RAVEN) {
9141bb76ff1Sjsg if (!(adev->apu_flags & AMD_APU_IS_RAVEN2)) {
9151bb76ff1Sjsg if (current_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
9161bb76ff1Sjsg level == AMD_DPM_FORCED_LEVEL_MANUAL)
9171bb76ff1Sjsg amdgpu_gfx_off_ctrl(adev, false);
9181bb76ff1Sjsg else if (current_level == AMD_DPM_FORCED_LEVEL_MANUAL &&
9191bb76ff1Sjsg level != AMD_DPM_FORCED_LEVEL_MANUAL)
9201bb76ff1Sjsg amdgpu_gfx_off_ctrl(adev, true);
9211bb76ff1Sjsg }
9221bb76ff1Sjsg }
9231bb76ff1Sjsg
9241bb76ff1Sjsg if (!(current_level & profile_mode_mask) &&
9251bb76ff1Sjsg (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT))
9261bb76ff1Sjsg return -EINVAL;
9271bb76ff1Sjsg
9281bb76ff1Sjsg if (!(current_level & profile_mode_mask) &&
9291bb76ff1Sjsg (level & profile_mode_mask)) {
9301bb76ff1Sjsg /* enter UMD Pstate */
9311bb76ff1Sjsg amdgpu_device_ip_set_powergating_state(adev,
9321bb76ff1Sjsg AMD_IP_BLOCK_TYPE_GFX,
9331bb76ff1Sjsg AMD_PG_STATE_UNGATE);
9341bb76ff1Sjsg amdgpu_device_ip_set_clockgating_state(adev,
9351bb76ff1Sjsg AMD_IP_BLOCK_TYPE_GFX,
9361bb76ff1Sjsg AMD_CG_STATE_UNGATE);
9371bb76ff1Sjsg } else if ((current_level & profile_mode_mask) &&
9381bb76ff1Sjsg !(level & profile_mode_mask)) {
9391bb76ff1Sjsg /* exit UMD Pstate */
9401bb76ff1Sjsg amdgpu_device_ip_set_clockgating_state(adev,
9411bb76ff1Sjsg AMD_IP_BLOCK_TYPE_GFX,
9421bb76ff1Sjsg AMD_CG_STATE_GATE);
9431bb76ff1Sjsg amdgpu_device_ip_set_powergating_state(adev,
9441bb76ff1Sjsg AMD_IP_BLOCK_TYPE_GFX,
9451bb76ff1Sjsg AMD_PG_STATE_GATE);
9461bb76ff1Sjsg }
9471bb76ff1Sjsg
9481bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
9491bb76ff1Sjsg
9501bb76ff1Sjsg if (pp_funcs->force_performance_level(adev->powerplay.pp_handle,
9511bb76ff1Sjsg level)) {
9521bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
9531bb76ff1Sjsg return -EINVAL;
9541bb76ff1Sjsg }
9551bb76ff1Sjsg
9561bb76ff1Sjsg adev->pm.dpm.forced_level = level;
9571bb76ff1Sjsg
9581bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
9591bb76ff1Sjsg
9601bb76ff1Sjsg return 0;
9611bb76ff1Sjsg }
9621bb76ff1Sjsg
amdgpu_dpm_get_pp_num_states(struct amdgpu_device * adev,struct pp_states_info * states)9631bb76ff1Sjsg int amdgpu_dpm_get_pp_num_states(struct amdgpu_device *adev,
9641bb76ff1Sjsg struct pp_states_info *states)
9651bb76ff1Sjsg {
9661bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9671bb76ff1Sjsg int ret = 0;
9681bb76ff1Sjsg
9691bb76ff1Sjsg if (!pp_funcs->get_pp_num_states)
9701bb76ff1Sjsg return -EOPNOTSUPP;
9711bb76ff1Sjsg
9721bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
9731bb76ff1Sjsg ret = pp_funcs->get_pp_num_states(adev->powerplay.pp_handle,
9741bb76ff1Sjsg states);
9751bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
9761bb76ff1Sjsg
9771bb76ff1Sjsg return ret;
9781bb76ff1Sjsg }
9791bb76ff1Sjsg
amdgpu_dpm_dispatch_task(struct amdgpu_device * adev,enum amd_pp_task task_id,enum amd_pm_state_type * user_state)9801bb76ff1Sjsg int amdgpu_dpm_dispatch_task(struct amdgpu_device *adev,
9811bb76ff1Sjsg enum amd_pp_task task_id,
9821bb76ff1Sjsg enum amd_pm_state_type *user_state)
9831bb76ff1Sjsg {
9841bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
9851bb76ff1Sjsg int ret = 0;
9861bb76ff1Sjsg
9871bb76ff1Sjsg if (!pp_funcs->dispatch_tasks)
9881bb76ff1Sjsg return -EOPNOTSUPP;
9891bb76ff1Sjsg
9901bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
9911bb76ff1Sjsg ret = pp_funcs->dispatch_tasks(adev->powerplay.pp_handle,
9921bb76ff1Sjsg task_id,
9931bb76ff1Sjsg user_state);
9941bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
9951bb76ff1Sjsg
9961bb76ff1Sjsg return ret;
9971bb76ff1Sjsg }
9981bb76ff1Sjsg
amdgpu_dpm_get_pp_table(struct amdgpu_device * adev,char ** table)9991bb76ff1Sjsg int amdgpu_dpm_get_pp_table(struct amdgpu_device *adev, char **table)
10001bb76ff1Sjsg {
10011bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10021bb76ff1Sjsg int ret = 0;
10031bb76ff1Sjsg
10041bb76ff1Sjsg if (!pp_funcs->get_pp_table)
10051bb76ff1Sjsg return 0;
10061bb76ff1Sjsg
10071bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
10081bb76ff1Sjsg ret = pp_funcs->get_pp_table(adev->powerplay.pp_handle,
10091bb76ff1Sjsg table);
10101bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
10111bb76ff1Sjsg
10121bb76ff1Sjsg return ret;
10131bb76ff1Sjsg }
10141bb76ff1Sjsg
amdgpu_dpm_set_fine_grain_clk_vol(struct amdgpu_device * adev,uint32_t type,long * input,uint32_t size)10151bb76ff1Sjsg int amdgpu_dpm_set_fine_grain_clk_vol(struct amdgpu_device *adev,
10161bb76ff1Sjsg uint32_t type,
10171bb76ff1Sjsg long *input,
10181bb76ff1Sjsg uint32_t size)
10191bb76ff1Sjsg {
10201bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10211bb76ff1Sjsg int ret = 0;
10221bb76ff1Sjsg
10231bb76ff1Sjsg if (!pp_funcs->set_fine_grain_clk_vol)
10241bb76ff1Sjsg return 0;
10251bb76ff1Sjsg
10261bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
10271bb76ff1Sjsg ret = pp_funcs->set_fine_grain_clk_vol(adev->powerplay.pp_handle,
10281bb76ff1Sjsg type,
10291bb76ff1Sjsg input,
10301bb76ff1Sjsg size);
10311bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
10321bb76ff1Sjsg
10331bb76ff1Sjsg return ret;
10341bb76ff1Sjsg }
10351bb76ff1Sjsg
amdgpu_dpm_odn_edit_dpm_table(struct amdgpu_device * adev,uint32_t type,long * input,uint32_t size)10361bb76ff1Sjsg int amdgpu_dpm_odn_edit_dpm_table(struct amdgpu_device *adev,
10371bb76ff1Sjsg uint32_t type,
10381bb76ff1Sjsg long *input,
10391bb76ff1Sjsg uint32_t size)
10401bb76ff1Sjsg {
10411bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10421bb76ff1Sjsg int ret = 0;
10431bb76ff1Sjsg
10441bb76ff1Sjsg if (!pp_funcs->odn_edit_dpm_table)
10451bb76ff1Sjsg return 0;
10461bb76ff1Sjsg
10471bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
10481bb76ff1Sjsg ret = pp_funcs->odn_edit_dpm_table(adev->powerplay.pp_handle,
10491bb76ff1Sjsg type,
10501bb76ff1Sjsg input,
10511bb76ff1Sjsg size);
10521bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
10531bb76ff1Sjsg
10541bb76ff1Sjsg return ret;
10551bb76ff1Sjsg }
10561bb76ff1Sjsg
amdgpu_dpm_print_clock_levels(struct amdgpu_device * adev,enum pp_clock_type type,char * buf)10571bb76ff1Sjsg int amdgpu_dpm_print_clock_levels(struct amdgpu_device *adev,
10581bb76ff1Sjsg enum pp_clock_type type,
10591bb76ff1Sjsg char *buf)
10601bb76ff1Sjsg {
10611bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10621bb76ff1Sjsg int ret = 0;
10631bb76ff1Sjsg
10641bb76ff1Sjsg if (!pp_funcs->print_clock_levels)
10651bb76ff1Sjsg return 0;
10661bb76ff1Sjsg
10671bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
10681bb76ff1Sjsg ret = pp_funcs->print_clock_levels(adev->powerplay.pp_handle,
10691bb76ff1Sjsg type,
10701bb76ff1Sjsg buf);
10711bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
10721bb76ff1Sjsg
10731bb76ff1Sjsg return ret;
10741bb76ff1Sjsg }
10751bb76ff1Sjsg
amdgpu_dpm_emit_clock_levels(struct amdgpu_device * adev,enum pp_clock_type type,char * buf,int * offset)10761bb76ff1Sjsg int amdgpu_dpm_emit_clock_levels(struct amdgpu_device *adev,
10771bb76ff1Sjsg enum pp_clock_type type,
10781bb76ff1Sjsg char *buf,
10791bb76ff1Sjsg int *offset)
10801bb76ff1Sjsg {
10811bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
10821bb76ff1Sjsg int ret = 0;
10831bb76ff1Sjsg
10841bb76ff1Sjsg if (!pp_funcs->emit_clock_levels)
10851bb76ff1Sjsg return -ENOENT;
10861bb76ff1Sjsg
10871bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
10881bb76ff1Sjsg ret = pp_funcs->emit_clock_levels(adev->powerplay.pp_handle,
10891bb76ff1Sjsg type,
10901bb76ff1Sjsg buf,
10911bb76ff1Sjsg offset);
10921bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
10931bb76ff1Sjsg
10941bb76ff1Sjsg return ret;
10951bb76ff1Sjsg }
10961bb76ff1Sjsg
amdgpu_dpm_set_ppfeature_status(struct amdgpu_device * adev,uint64_t ppfeature_masks)10971bb76ff1Sjsg int amdgpu_dpm_set_ppfeature_status(struct amdgpu_device *adev,
10981bb76ff1Sjsg uint64_t ppfeature_masks)
10991bb76ff1Sjsg {
11001bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11011bb76ff1Sjsg int ret = 0;
11021bb76ff1Sjsg
11031bb76ff1Sjsg if (!pp_funcs->set_ppfeature_status)
11041bb76ff1Sjsg return 0;
11051bb76ff1Sjsg
11061bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
11071bb76ff1Sjsg ret = pp_funcs->set_ppfeature_status(adev->powerplay.pp_handle,
11081bb76ff1Sjsg ppfeature_masks);
11091bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
11101bb76ff1Sjsg
11111bb76ff1Sjsg return ret;
11121bb76ff1Sjsg }
11131bb76ff1Sjsg
amdgpu_dpm_get_ppfeature_status(struct amdgpu_device * adev,char * buf)11141bb76ff1Sjsg int amdgpu_dpm_get_ppfeature_status(struct amdgpu_device *adev, char *buf)
11151bb76ff1Sjsg {
11161bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11171bb76ff1Sjsg int ret = 0;
11181bb76ff1Sjsg
11191bb76ff1Sjsg if (!pp_funcs->get_ppfeature_status)
11201bb76ff1Sjsg return 0;
11211bb76ff1Sjsg
11221bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
11231bb76ff1Sjsg ret = pp_funcs->get_ppfeature_status(adev->powerplay.pp_handle,
11241bb76ff1Sjsg buf);
11251bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
11261bb76ff1Sjsg
11271bb76ff1Sjsg return ret;
11281bb76ff1Sjsg }
11291bb76ff1Sjsg
amdgpu_dpm_force_clock_level(struct amdgpu_device * adev,enum pp_clock_type type,uint32_t mask)11301bb76ff1Sjsg int amdgpu_dpm_force_clock_level(struct amdgpu_device *adev,
11311bb76ff1Sjsg enum pp_clock_type type,
11321bb76ff1Sjsg uint32_t mask)
11331bb76ff1Sjsg {
11341bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11351bb76ff1Sjsg int ret = 0;
11361bb76ff1Sjsg
11371bb76ff1Sjsg if (!pp_funcs->force_clock_level)
11381bb76ff1Sjsg return 0;
11391bb76ff1Sjsg
11401bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
11411bb76ff1Sjsg ret = pp_funcs->force_clock_level(adev->powerplay.pp_handle,
11421bb76ff1Sjsg type,
11431bb76ff1Sjsg mask);
11441bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
11451bb76ff1Sjsg
11461bb76ff1Sjsg return ret;
11471bb76ff1Sjsg }
11481bb76ff1Sjsg
amdgpu_dpm_get_sclk_od(struct amdgpu_device * adev)11491bb76ff1Sjsg int amdgpu_dpm_get_sclk_od(struct amdgpu_device *adev)
11501bb76ff1Sjsg {
11511bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11521bb76ff1Sjsg int ret = 0;
11531bb76ff1Sjsg
11541bb76ff1Sjsg if (!pp_funcs->get_sclk_od)
11551bb76ff1Sjsg return 0;
11561bb76ff1Sjsg
11571bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
11581bb76ff1Sjsg ret = pp_funcs->get_sclk_od(adev->powerplay.pp_handle);
11591bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
11601bb76ff1Sjsg
11611bb76ff1Sjsg return ret;
11621bb76ff1Sjsg }
11631bb76ff1Sjsg
amdgpu_dpm_set_sclk_od(struct amdgpu_device * adev,uint32_t value)11641bb76ff1Sjsg int amdgpu_dpm_set_sclk_od(struct amdgpu_device *adev, uint32_t value)
11651bb76ff1Sjsg {
11661bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11671bb76ff1Sjsg
11681bb76ff1Sjsg if (is_support_sw_smu(adev))
11691bb76ff1Sjsg return 0;
11701bb76ff1Sjsg
11711bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
11721bb76ff1Sjsg if (pp_funcs->set_sclk_od)
11731bb76ff1Sjsg pp_funcs->set_sclk_od(adev->powerplay.pp_handle, value);
11741bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
11751bb76ff1Sjsg
11761bb76ff1Sjsg if (amdgpu_dpm_dispatch_task(adev,
11771bb76ff1Sjsg AMD_PP_TASK_READJUST_POWER_STATE,
11781bb76ff1Sjsg NULL) == -EOPNOTSUPP) {
11791bb76ff1Sjsg adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
11801bb76ff1Sjsg amdgpu_dpm_compute_clocks(adev);
1181ad8b1aafSjsg }
11825ca02815Sjsg
1183ad8b1aafSjsg return 0;
1184ad8b1aafSjsg }
11851bb76ff1Sjsg
amdgpu_dpm_get_mclk_od(struct amdgpu_device * adev)11861bb76ff1Sjsg int amdgpu_dpm_get_mclk_od(struct amdgpu_device *adev)
11871bb76ff1Sjsg {
11881bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
11891bb76ff1Sjsg int ret = 0;
11901bb76ff1Sjsg
11911bb76ff1Sjsg if (!pp_funcs->get_mclk_od)
11921bb76ff1Sjsg return 0;
11931bb76ff1Sjsg
11941bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
11951bb76ff1Sjsg ret = pp_funcs->get_mclk_od(adev->powerplay.pp_handle);
11961bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
11971bb76ff1Sjsg
11981bb76ff1Sjsg return ret;
11991bb76ff1Sjsg }
12001bb76ff1Sjsg
amdgpu_dpm_set_mclk_od(struct amdgpu_device * adev,uint32_t value)12011bb76ff1Sjsg int amdgpu_dpm_set_mclk_od(struct amdgpu_device *adev, uint32_t value)
12021bb76ff1Sjsg {
12031bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12041bb76ff1Sjsg
12051bb76ff1Sjsg if (is_support_sw_smu(adev))
12061bb76ff1Sjsg return 0;
12071bb76ff1Sjsg
12081bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
12091bb76ff1Sjsg if (pp_funcs->set_mclk_od)
12101bb76ff1Sjsg pp_funcs->set_mclk_od(adev->powerplay.pp_handle, value);
12111bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
12121bb76ff1Sjsg
12131bb76ff1Sjsg if (amdgpu_dpm_dispatch_task(adev,
12141bb76ff1Sjsg AMD_PP_TASK_READJUST_POWER_STATE,
12151bb76ff1Sjsg NULL) == -EOPNOTSUPP) {
12161bb76ff1Sjsg adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
12171bb76ff1Sjsg amdgpu_dpm_compute_clocks(adev);
12181bb76ff1Sjsg }
12191bb76ff1Sjsg
12201bb76ff1Sjsg return 0;
12211bb76ff1Sjsg }
12221bb76ff1Sjsg
amdgpu_dpm_get_power_profile_mode(struct amdgpu_device * adev,char * buf)12231bb76ff1Sjsg int amdgpu_dpm_get_power_profile_mode(struct amdgpu_device *adev,
12241bb76ff1Sjsg char *buf)
12251bb76ff1Sjsg {
12261bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12271bb76ff1Sjsg int ret = 0;
12281bb76ff1Sjsg
12291bb76ff1Sjsg if (!pp_funcs->get_power_profile_mode)
12301bb76ff1Sjsg return -EOPNOTSUPP;
12311bb76ff1Sjsg
12321bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
12331bb76ff1Sjsg ret = pp_funcs->get_power_profile_mode(adev->powerplay.pp_handle,
12341bb76ff1Sjsg buf);
12351bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
12361bb76ff1Sjsg
12371bb76ff1Sjsg return ret;
12381bb76ff1Sjsg }
12391bb76ff1Sjsg
amdgpu_dpm_set_power_profile_mode(struct amdgpu_device * adev,long * input,uint32_t size)12401bb76ff1Sjsg int amdgpu_dpm_set_power_profile_mode(struct amdgpu_device *adev,
12411bb76ff1Sjsg long *input, uint32_t size)
12421bb76ff1Sjsg {
12431bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12441bb76ff1Sjsg int ret = 0;
12451bb76ff1Sjsg
12461bb76ff1Sjsg if (!pp_funcs->set_power_profile_mode)
12471bb76ff1Sjsg return 0;
12481bb76ff1Sjsg
12491bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
12501bb76ff1Sjsg ret = pp_funcs->set_power_profile_mode(adev->powerplay.pp_handle,
12511bb76ff1Sjsg input,
12521bb76ff1Sjsg size);
12531bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
12541bb76ff1Sjsg
12551bb76ff1Sjsg return ret;
12561bb76ff1Sjsg }
12571bb76ff1Sjsg
amdgpu_dpm_get_gpu_metrics(struct amdgpu_device * adev,void ** table)12581bb76ff1Sjsg int amdgpu_dpm_get_gpu_metrics(struct amdgpu_device *adev, void **table)
12591bb76ff1Sjsg {
12601bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12611bb76ff1Sjsg int ret = 0;
12621bb76ff1Sjsg
12631bb76ff1Sjsg if (!pp_funcs->get_gpu_metrics)
12641bb76ff1Sjsg return 0;
12651bb76ff1Sjsg
12661bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
12671bb76ff1Sjsg ret = pp_funcs->get_gpu_metrics(adev->powerplay.pp_handle,
12681bb76ff1Sjsg table);
12691bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
12701bb76ff1Sjsg
12711bb76ff1Sjsg return ret;
12721bb76ff1Sjsg }
12731bb76ff1Sjsg
amdgpu_dpm_get_fan_control_mode(struct amdgpu_device * adev,uint32_t * fan_mode)12741bb76ff1Sjsg int amdgpu_dpm_get_fan_control_mode(struct amdgpu_device *adev,
12751bb76ff1Sjsg uint32_t *fan_mode)
12761bb76ff1Sjsg {
12771bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12781bb76ff1Sjsg int ret = 0;
12791bb76ff1Sjsg
12801bb76ff1Sjsg if (!pp_funcs->get_fan_control_mode)
12811bb76ff1Sjsg return -EOPNOTSUPP;
12821bb76ff1Sjsg
12831bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
12841bb76ff1Sjsg ret = pp_funcs->get_fan_control_mode(adev->powerplay.pp_handle,
12851bb76ff1Sjsg fan_mode);
12861bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
12871bb76ff1Sjsg
12881bb76ff1Sjsg return ret;
12891bb76ff1Sjsg }
12901bb76ff1Sjsg
amdgpu_dpm_set_fan_speed_pwm(struct amdgpu_device * adev,uint32_t speed)12911bb76ff1Sjsg int amdgpu_dpm_set_fan_speed_pwm(struct amdgpu_device *adev,
12921bb76ff1Sjsg uint32_t speed)
12931bb76ff1Sjsg {
12941bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
12951bb76ff1Sjsg int ret = 0;
12961bb76ff1Sjsg
12971bb76ff1Sjsg if (!pp_funcs->set_fan_speed_pwm)
12981bb76ff1Sjsg return -EOPNOTSUPP;
12991bb76ff1Sjsg
13001bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
13011bb76ff1Sjsg ret = pp_funcs->set_fan_speed_pwm(adev->powerplay.pp_handle,
13021bb76ff1Sjsg speed);
13031bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
13041bb76ff1Sjsg
13051bb76ff1Sjsg return ret;
13061bb76ff1Sjsg }
13071bb76ff1Sjsg
amdgpu_dpm_get_fan_speed_pwm(struct amdgpu_device * adev,uint32_t * speed)13081bb76ff1Sjsg int amdgpu_dpm_get_fan_speed_pwm(struct amdgpu_device *adev,
13091bb76ff1Sjsg uint32_t *speed)
13101bb76ff1Sjsg {
13111bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13121bb76ff1Sjsg int ret = 0;
13131bb76ff1Sjsg
13141bb76ff1Sjsg if (!pp_funcs->get_fan_speed_pwm)
13151bb76ff1Sjsg return -EOPNOTSUPP;
13161bb76ff1Sjsg
13171bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
13181bb76ff1Sjsg ret = pp_funcs->get_fan_speed_pwm(adev->powerplay.pp_handle,
13191bb76ff1Sjsg speed);
13201bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
13211bb76ff1Sjsg
13221bb76ff1Sjsg return ret;
13231bb76ff1Sjsg }
13241bb76ff1Sjsg
amdgpu_dpm_get_fan_speed_rpm(struct amdgpu_device * adev,uint32_t * speed)13251bb76ff1Sjsg int amdgpu_dpm_get_fan_speed_rpm(struct amdgpu_device *adev,
13261bb76ff1Sjsg uint32_t *speed)
13271bb76ff1Sjsg {
13281bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13291bb76ff1Sjsg int ret = 0;
13301bb76ff1Sjsg
13311bb76ff1Sjsg if (!pp_funcs->get_fan_speed_rpm)
13321bb76ff1Sjsg return -EOPNOTSUPP;
13331bb76ff1Sjsg
13341bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
13351bb76ff1Sjsg ret = pp_funcs->get_fan_speed_rpm(adev->powerplay.pp_handle,
13361bb76ff1Sjsg speed);
13371bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
13381bb76ff1Sjsg
13391bb76ff1Sjsg return ret;
13401bb76ff1Sjsg }
13411bb76ff1Sjsg
amdgpu_dpm_set_fan_speed_rpm(struct amdgpu_device * adev,uint32_t speed)13421bb76ff1Sjsg int amdgpu_dpm_set_fan_speed_rpm(struct amdgpu_device *adev,
13431bb76ff1Sjsg uint32_t speed)
13441bb76ff1Sjsg {
13451bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13461bb76ff1Sjsg int ret = 0;
13471bb76ff1Sjsg
13481bb76ff1Sjsg if (!pp_funcs->set_fan_speed_rpm)
13491bb76ff1Sjsg return -EOPNOTSUPP;
13501bb76ff1Sjsg
13511bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
13521bb76ff1Sjsg ret = pp_funcs->set_fan_speed_rpm(adev->powerplay.pp_handle,
13531bb76ff1Sjsg speed);
13541bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
13551bb76ff1Sjsg
13561bb76ff1Sjsg return ret;
13571bb76ff1Sjsg }
13581bb76ff1Sjsg
amdgpu_dpm_set_fan_control_mode(struct amdgpu_device * adev,uint32_t mode)13591bb76ff1Sjsg int amdgpu_dpm_set_fan_control_mode(struct amdgpu_device *adev,
13601bb76ff1Sjsg uint32_t mode)
13611bb76ff1Sjsg {
13621bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13631bb76ff1Sjsg int ret = 0;
13641bb76ff1Sjsg
13651bb76ff1Sjsg if (!pp_funcs->set_fan_control_mode)
13661bb76ff1Sjsg return -EOPNOTSUPP;
13671bb76ff1Sjsg
13681bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
13691bb76ff1Sjsg ret = pp_funcs->set_fan_control_mode(adev->powerplay.pp_handle,
13701bb76ff1Sjsg mode);
13711bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
13721bb76ff1Sjsg
13731bb76ff1Sjsg return ret;
13741bb76ff1Sjsg }
13751bb76ff1Sjsg
amdgpu_dpm_get_power_limit(struct amdgpu_device * adev,uint32_t * limit,enum pp_power_limit_level pp_limit_level,enum pp_power_type power_type)13761bb76ff1Sjsg int amdgpu_dpm_get_power_limit(struct amdgpu_device *adev,
13771bb76ff1Sjsg uint32_t *limit,
13781bb76ff1Sjsg enum pp_power_limit_level pp_limit_level,
13791bb76ff1Sjsg enum pp_power_type power_type)
13801bb76ff1Sjsg {
13811bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
13821bb76ff1Sjsg int ret = 0;
13831bb76ff1Sjsg
13841bb76ff1Sjsg if (!pp_funcs->get_power_limit)
13851bb76ff1Sjsg return -ENODATA;
13861bb76ff1Sjsg
13871bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
13881bb76ff1Sjsg ret = pp_funcs->get_power_limit(adev->powerplay.pp_handle,
13891bb76ff1Sjsg limit,
13901bb76ff1Sjsg pp_limit_level,
13911bb76ff1Sjsg power_type);
13921bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
13931bb76ff1Sjsg
13941bb76ff1Sjsg return ret;
13951bb76ff1Sjsg }
13961bb76ff1Sjsg
amdgpu_dpm_set_power_limit(struct amdgpu_device * adev,uint32_t limit)13971bb76ff1Sjsg int amdgpu_dpm_set_power_limit(struct amdgpu_device *adev,
13981bb76ff1Sjsg uint32_t limit)
13991bb76ff1Sjsg {
14001bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14011bb76ff1Sjsg int ret = 0;
14021bb76ff1Sjsg
14031bb76ff1Sjsg if (!pp_funcs->set_power_limit)
14041bb76ff1Sjsg return -EINVAL;
14051bb76ff1Sjsg
14061bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
14071bb76ff1Sjsg ret = pp_funcs->set_power_limit(adev->powerplay.pp_handle,
14081bb76ff1Sjsg limit);
14091bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
14101bb76ff1Sjsg
14111bb76ff1Sjsg return ret;
14121bb76ff1Sjsg }
14131bb76ff1Sjsg
amdgpu_dpm_is_cclk_dpm_supported(struct amdgpu_device * adev)14141bb76ff1Sjsg int amdgpu_dpm_is_cclk_dpm_supported(struct amdgpu_device *adev)
14151bb76ff1Sjsg {
14161bb76ff1Sjsg bool cclk_dpm_supported = false;
14171bb76ff1Sjsg
14181bb76ff1Sjsg if (!is_support_sw_smu(adev))
14191bb76ff1Sjsg return false;
14201bb76ff1Sjsg
14211bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
14221bb76ff1Sjsg cclk_dpm_supported = is_support_cclk_dpm(adev);
14231bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
14241bb76ff1Sjsg
14251bb76ff1Sjsg return (int)cclk_dpm_supported;
14261bb76ff1Sjsg }
14271bb76ff1Sjsg
amdgpu_dpm_debugfs_print_current_performance_level(struct amdgpu_device * adev,struct seq_file * m)14281bb76ff1Sjsg int amdgpu_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev,
14291bb76ff1Sjsg struct seq_file *m)
14301bb76ff1Sjsg {
14311bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14321bb76ff1Sjsg
14331bb76ff1Sjsg if (!pp_funcs->debugfs_print_current_performance_level)
14341bb76ff1Sjsg return -EOPNOTSUPP;
14351bb76ff1Sjsg
14361bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
14371bb76ff1Sjsg pp_funcs->debugfs_print_current_performance_level(adev->powerplay.pp_handle,
14381bb76ff1Sjsg m);
14391bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
14401bb76ff1Sjsg
14411bb76ff1Sjsg return 0;
14421bb76ff1Sjsg }
14431bb76ff1Sjsg
amdgpu_dpm_get_smu_prv_buf_details(struct amdgpu_device * adev,void ** addr,size_t * size)14441bb76ff1Sjsg int amdgpu_dpm_get_smu_prv_buf_details(struct amdgpu_device *adev,
14451bb76ff1Sjsg void **addr,
14461bb76ff1Sjsg size_t *size)
14471bb76ff1Sjsg {
14481bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14491bb76ff1Sjsg int ret = 0;
14501bb76ff1Sjsg
14511bb76ff1Sjsg if (!pp_funcs->get_smu_prv_buf_details)
14521bb76ff1Sjsg return -ENOSYS;
14531bb76ff1Sjsg
14541bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
14551bb76ff1Sjsg ret = pp_funcs->get_smu_prv_buf_details(adev->powerplay.pp_handle,
14561bb76ff1Sjsg addr,
14571bb76ff1Sjsg size);
14581bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
14591bb76ff1Sjsg
14601bb76ff1Sjsg return ret;
14611bb76ff1Sjsg }
14621bb76ff1Sjsg
amdgpu_dpm_is_overdrive_supported(struct amdgpu_device * adev)14631bb76ff1Sjsg int amdgpu_dpm_is_overdrive_supported(struct amdgpu_device *adev)
14641bb76ff1Sjsg {
1465fef08ba1Sjsg if (is_support_sw_smu(adev)) {
14661bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
14671bb76ff1Sjsg
1468fef08ba1Sjsg return (smu->od_enabled || smu->is_apu);
1469fef08ba1Sjsg } else {
1470fef08ba1Sjsg struct pp_hwmgr *hwmgr;
14711bb76ff1Sjsg
14720146cd80Sjsg /*
14730146cd80Sjsg * dpm on some legacy asics don't carry od_enabled member
14740146cd80Sjsg * as its pp_handle is casted directly from adev.
14750146cd80Sjsg */
14760146cd80Sjsg if (amdgpu_dpm_is_legacy_dpm(adev))
14771bb76ff1Sjsg return false;
1478fef08ba1Sjsg
1479fef08ba1Sjsg hwmgr = (struct pp_hwmgr *)adev->powerplay.pp_handle;
1480fef08ba1Sjsg
1481fef08ba1Sjsg return hwmgr->od_enabled;
1482fef08ba1Sjsg }
14831bb76ff1Sjsg }
14841bb76ff1Sjsg
amdgpu_dpm_set_pp_table(struct amdgpu_device * adev,const char * buf,size_t size)14851bb76ff1Sjsg int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev,
14861bb76ff1Sjsg const char *buf,
14871bb76ff1Sjsg size_t size)
14881bb76ff1Sjsg {
14891bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
14901bb76ff1Sjsg int ret = 0;
14911bb76ff1Sjsg
14921bb76ff1Sjsg if (!pp_funcs->set_pp_table)
14931bb76ff1Sjsg return -EOPNOTSUPP;
14941bb76ff1Sjsg
14951bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
14961bb76ff1Sjsg ret = pp_funcs->set_pp_table(adev->powerplay.pp_handle,
14971bb76ff1Sjsg buf,
14981bb76ff1Sjsg size);
14991bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
15001bb76ff1Sjsg
15011bb76ff1Sjsg return ret;
15021bb76ff1Sjsg }
15031bb76ff1Sjsg
amdgpu_dpm_get_num_cpu_cores(struct amdgpu_device * adev)15041bb76ff1Sjsg int amdgpu_dpm_get_num_cpu_cores(struct amdgpu_device *adev)
15051bb76ff1Sjsg {
15061bb76ff1Sjsg struct smu_context *smu = adev->powerplay.pp_handle;
15071bb76ff1Sjsg
15081bb76ff1Sjsg if (!is_support_sw_smu(adev))
15091bb76ff1Sjsg return INT_MAX;
15101bb76ff1Sjsg
15111bb76ff1Sjsg return smu->cpu_core_num;
15121bb76ff1Sjsg }
15131bb76ff1Sjsg
amdgpu_dpm_stb_debug_fs_init(struct amdgpu_device * adev)15141bb76ff1Sjsg void amdgpu_dpm_stb_debug_fs_init(struct amdgpu_device *adev)
15151bb76ff1Sjsg {
15161bb76ff1Sjsg if (!is_support_sw_smu(adev))
15171bb76ff1Sjsg return;
15181bb76ff1Sjsg
15191bb76ff1Sjsg amdgpu_smu_stb_debug_fs_init(adev);
15201bb76ff1Sjsg }
15211bb76ff1Sjsg
amdgpu_dpm_display_configuration_change(struct amdgpu_device * adev,const struct amd_pp_display_configuration * input)15221bb76ff1Sjsg int amdgpu_dpm_display_configuration_change(struct amdgpu_device *adev,
15231bb76ff1Sjsg const struct amd_pp_display_configuration *input)
15241bb76ff1Sjsg {
15251bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15261bb76ff1Sjsg int ret = 0;
15271bb76ff1Sjsg
15281bb76ff1Sjsg if (!pp_funcs->display_configuration_change)
15291bb76ff1Sjsg return 0;
15301bb76ff1Sjsg
15311bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
15321bb76ff1Sjsg ret = pp_funcs->display_configuration_change(adev->powerplay.pp_handle,
15331bb76ff1Sjsg input);
15341bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
15351bb76ff1Sjsg
15361bb76ff1Sjsg return ret;
15371bb76ff1Sjsg }
15381bb76ff1Sjsg
amdgpu_dpm_get_clock_by_type(struct amdgpu_device * adev,enum amd_pp_clock_type type,struct amd_pp_clocks * clocks)15391bb76ff1Sjsg int amdgpu_dpm_get_clock_by_type(struct amdgpu_device *adev,
15401bb76ff1Sjsg enum amd_pp_clock_type type,
15411bb76ff1Sjsg struct amd_pp_clocks *clocks)
15421bb76ff1Sjsg {
15431bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15441bb76ff1Sjsg int ret = 0;
15451bb76ff1Sjsg
15461bb76ff1Sjsg if (!pp_funcs->get_clock_by_type)
15471bb76ff1Sjsg return 0;
15481bb76ff1Sjsg
15491bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
15501bb76ff1Sjsg ret = pp_funcs->get_clock_by_type(adev->powerplay.pp_handle,
15511bb76ff1Sjsg type,
15521bb76ff1Sjsg clocks);
15531bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
15541bb76ff1Sjsg
15551bb76ff1Sjsg return ret;
15561bb76ff1Sjsg }
15571bb76ff1Sjsg
amdgpu_dpm_get_display_mode_validation_clks(struct amdgpu_device * adev,struct amd_pp_simple_clock_info * clocks)15581bb76ff1Sjsg int amdgpu_dpm_get_display_mode_validation_clks(struct amdgpu_device *adev,
15591bb76ff1Sjsg struct amd_pp_simple_clock_info *clocks)
15601bb76ff1Sjsg {
15611bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15621bb76ff1Sjsg int ret = 0;
15631bb76ff1Sjsg
15641bb76ff1Sjsg if (!pp_funcs->get_display_mode_validation_clocks)
15651bb76ff1Sjsg return 0;
15661bb76ff1Sjsg
15671bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
15681bb76ff1Sjsg ret = pp_funcs->get_display_mode_validation_clocks(adev->powerplay.pp_handle,
15691bb76ff1Sjsg clocks);
15701bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
15711bb76ff1Sjsg
15721bb76ff1Sjsg return ret;
15731bb76ff1Sjsg }
15741bb76ff1Sjsg
amdgpu_dpm_get_clock_by_type_with_latency(struct amdgpu_device * adev,enum amd_pp_clock_type type,struct pp_clock_levels_with_latency * clocks)15751bb76ff1Sjsg int amdgpu_dpm_get_clock_by_type_with_latency(struct amdgpu_device *adev,
15761bb76ff1Sjsg enum amd_pp_clock_type type,
15771bb76ff1Sjsg struct pp_clock_levels_with_latency *clocks)
15781bb76ff1Sjsg {
15791bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15801bb76ff1Sjsg int ret = 0;
15811bb76ff1Sjsg
15821bb76ff1Sjsg if (!pp_funcs->get_clock_by_type_with_latency)
15831bb76ff1Sjsg return 0;
15841bb76ff1Sjsg
15851bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
15861bb76ff1Sjsg ret = pp_funcs->get_clock_by_type_with_latency(adev->powerplay.pp_handle,
15871bb76ff1Sjsg type,
15881bb76ff1Sjsg clocks);
15891bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
15901bb76ff1Sjsg
15911bb76ff1Sjsg return ret;
15921bb76ff1Sjsg }
15931bb76ff1Sjsg
amdgpu_dpm_get_clock_by_type_with_voltage(struct amdgpu_device * adev,enum amd_pp_clock_type type,struct pp_clock_levels_with_voltage * clocks)15941bb76ff1Sjsg int amdgpu_dpm_get_clock_by_type_with_voltage(struct amdgpu_device *adev,
15951bb76ff1Sjsg enum amd_pp_clock_type type,
15961bb76ff1Sjsg struct pp_clock_levels_with_voltage *clocks)
15971bb76ff1Sjsg {
15981bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
15991bb76ff1Sjsg int ret = 0;
16001bb76ff1Sjsg
16011bb76ff1Sjsg if (!pp_funcs->get_clock_by_type_with_voltage)
16021bb76ff1Sjsg return 0;
16031bb76ff1Sjsg
16041bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
16051bb76ff1Sjsg ret = pp_funcs->get_clock_by_type_with_voltage(adev->powerplay.pp_handle,
16061bb76ff1Sjsg type,
16071bb76ff1Sjsg clocks);
16081bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
16091bb76ff1Sjsg
16101bb76ff1Sjsg return ret;
16111bb76ff1Sjsg }
16121bb76ff1Sjsg
amdgpu_dpm_set_watermarks_for_clocks_ranges(struct amdgpu_device * adev,void * clock_ranges)16131bb76ff1Sjsg int amdgpu_dpm_set_watermarks_for_clocks_ranges(struct amdgpu_device *adev,
16141bb76ff1Sjsg void *clock_ranges)
16151bb76ff1Sjsg {
16161bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16171bb76ff1Sjsg int ret = 0;
16181bb76ff1Sjsg
16191bb76ff1Sjsg if (!pp_funcs->set_watermarks_for_clocks_ranges)
16201bb76ff1Sjsg return -EOPNOTSUPP;
16211bb76ff1Sjsg
16221bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
16231bb76ff1Sjsg ret = pp_funcs->set_watermarks_for_clocks_ranges(adev->powerplay.pp_handle,
16241bb76ff1Sjsg clock_ranges);
16251bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
16261bb76ff1Sjsg
16271bb76ff1Sjsg return ret;
16281bb76ff1Sjsg }
16291bb76ff1Sjsg
amdgpu_dpm_display_clock_voltage_request(struct amdgpu_device * adev,struct pp_display_clock_request * clock)16301bb76ff1Sjsg int amdgpu_dpm_display_clock_voltage_request(struct amdgpu_device *adev,
16311bb76ff1Sjsg struct pp_display_clock_request *clock)
16321bb76ff1Sjsg {
16331bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16341bb76ff1Sjsg int ret = 0;
16351bb76ff1Sjsg
16361bb76ff1Sjsg if (!pp_funcs->display_clock_voltage_request)
16371bb76ff1Sjsg return -EOPNOTSUPP;
16381bb76ff1Sjsg
16391bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
16401bb76ff1Sjsg ret = pp_funcs->display_clock_voltage_request(adev->powerplay.pp_handle,
16411bb76ff1Sjsg clock);
16421bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
16431bb76ff1Sjsg
16441bb76ff1Sjsg return ret;
16451bb76ff1Sjsg }
16461bb76ff1Sjsg
amdgpu_dpm_get_current_clocks(struct amdgpu_device * adev,struct amd_pp_clock_info * clocks)16471bb76ff1Sjsg int amdgpu_dpm_get_current_clocks(struct amdgpu_device *adev,
16481bb76ff1Sjsg struct amd_pp_clock_info *clocks)
16491bb76ff1Sjsg {
16501bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16511bb76ff1Sjsg int ret = 0;
16521bb76ff1Sjsg
16531bb76ff1Sjsg if (!pp_funcs->get_current_clocks)
16541bb76ff1Sjsg return -EOPNOTSUPP;
16551bb76ff1Sjsg
16561bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
16571bb76ff1Sjsg ret = pp_funcs->get_current_clocks(adev->powerplay.pp_handle,
16581bb76ff1Sjsg clocks);
16591bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
16601bb76ff1Sjsg
16611bb76ff1Sjsg return ret;
16621bb76ff1Sjsg }
16631bb76ff1Sjsg
amdgpu_dpm_notify_smu_enable_pwe(struct amdgpu_device * adev)16641bb76ff1Sjsg void amdgpu_dpm_notify_smu_enable_pwe(struct amdgpu_device *adev)
16651bb76ff1Sjsg {
16661bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16671bb76ff1Sjsg
16681bb76ff1Sjsg if (!pp_funcs->notify_smu_enable_pwe)
16691bb76ff1Sjsg return;
16701bb76ff1Sjsg
16711bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
16721bb76ff1Sjsg pp_funcs->notify_smu_enable_pwe(adev->powerplay.pp_handle);
16731bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
16741bb76ff1Sjsg }
16751bb76ff1Sjsg
amdgpu_dpm_set_active_display_count(struct amdgpu_device * adev,uint32_t count)16761bb76ff1Sjsg int amdgpu_dpm_set_active_display_count(struct amdgpu_device *adev,
16771bb76ff1Sjsg uint32_t count)
16781bb76ff1Sjsg {
16791bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16801bb76ff1Sjsg int ret = 0;
16811bb76ff1Sjsg
16821bb76ff1Sjsg if (!pp_funcs->set_active_display_count)
16831bb76ff1Sjsg return -EOPNOTSUPP;
16841bb76ff1Sjsg
16851bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
16861bb76ff1Sjsg ret = pp_funcs->set_active_display_count(adev->powerplay.pp_handle,
16871bb76ff1Sjsg count);
16881bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
16891bb76ff1Sjsg
16901bb76ff1Sjsg return ret;
16911bb76ff1Sjsg }
16921bb76ff1Sjsg
amdgpu_dpm_set_min_deep_sleep_dcefclk(struct amdgpu_device * adev,uint32_t clock)16931bb76ff1Sjsg int amdgpu_dpm_set_min_deep_sleep_dcefclk(struct amdgpu_device *adev,
16941bb76ff1Sjsg uint32_t clock)
16951bb76ff1Sjsg {
16961bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
16971bb76ff1Sjsg int ret = 0;
16981bb76ff1Sjsg
16991bb76ff1Sjsg if (!pp_funcs->set_min_deep_sleep_dcefclk)
17001bb76ff1Sjsg return -EOPNOTSUPP;
17011bb76ff1Sjsg
17021bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
17031bb76ff1Sjsg ret = pp_funcs->set_min_deep_sleep_dcefclk(adev->powerplay.pp_handle,
17041bb76ff1Sjsg clock);
17051bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
17061bb76ff1Sjsg
17071bb76ff1Sjsg return ret;
17081bb76ff1Sjsg }
17091bb76ff1Sjsg
amdgpu_dpm_set_hard_min_dcefclk_by_freq(struct amdgpu_device * adev,uint32_t clock)17101bb76ff1Sjsg void amdgpu_dpm_set_hard_min_dcefclk_by_freq(struct amdgpu_device *adev,
17111bb76ff1Sjsg uint32_t clock)
17121bb76ff1Sjsg {
17131bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
17141bb76ff1Sjsg
17151bb76ff1Sjsg if (!pp_funcs->set_hard_min_dcefclk_by_freq)
17161bb76ff1Sjsg return;
17171bb76ff1Sjsg
17181bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
17191bb76ff1Sjsg pp_funcs->set_hard_min_dcefclk_by_freq(adev->powerplay.pp_handle,
17201bb76ff1Sjsg clock);
17211bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
17221bb76ff1Sjsg }
17231bb76ff1Sjsg
amdgpu_dpm_set_hard_min_fclk_by_freq(struct amdgpu_device * adev,uint32_t clock)17241bb76ff1Sjsg void amdgpu_dpm_set_hard_min_fclk_by_freq(struct amdgpu_device *adev,
17251bb76ff1Sjsg uint32_t clock)
17261bb76ff1Sjsg {
17271bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
17281bb76ff1Sjsg
17291bb76ff1Sjsg if (!pp_funcs->set_hard_min_fclk_by_freq)
17301bb76ff1Sjsg return;
17311bb76ff1Sjsg
17321bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
17331bb76ff1Sjsg pp_funcs->set_hard_min_fclk_by_freq(adev->powerplay.pp_handle,
17341bb76ff1Sjsg clock);
17351bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
17361bb76ff1Sjsg }
17371bb76ff1Sjsg
amdgpu_dpm_display_disable_memory_clock_switch(struct amdgpu_device * adev,bool disable_memory_clock_switch)17381bb76ff1Sjsg int amdgpu_dpm_display_disable_memory_clock_switch(struct amdgpu_device *adev,
17391bb76ff1Sjsg bool disable_memory_clock_switch)
17401bb76ff1Sjsg {
17411bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
17421bb76ff1Sjsg int ret = 0;
17431bb76ff1Sjsg
17441bb76ff1Sjsg if (!pp_funcs->display_disable_memory_clock_switch)
17451bb76ff1Sjsg return 0;
17461bb76ff1Sjsg
17471bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
17481bb76ff1Sjsg ret = pp_funcs->display_disable_memory_clock_switch(adev->powerplay.pp_handle,
17491bb76ff1Sjsg disable_memory_clock_switch);
17501bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
17511bb76ff1Sjsg
17521bb76ff1Sjsg return ret;
17531bb76ff1Sjsg }
17541bb76ff1Sjsg
amdgpu_dpm_get_max_sustainable_clocks_by_dc(struct amdgpu_device * adev,struct pp_smu_nv_clock_table * max_clocks)17551bb76ff1Sjsg int amdgpu_dpm_get_max_sustainable_clocks_by_dc(struct amdgpu_device *adev,
17561bb76ff1Sjsg struct pp_smu_nv_clock_table *max_clocks)
17571bb76ff1Sjsg {
17581bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
17591bb76ff1Sjsg int ret = 0;
17601bb76ff1Sjsg
17611bb76ff1Sjsg if (!pp_funcs->get_max_sustainable_clocks_by_dc)
17621bb76ff1Sjsg return -EOPNOTSUPP;
17631bb76ff1Sjsg
17641bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
17651bb76ff1Sjsg ret = pp_funcs->get_max_sustainable_clocks_by_dc(adev->powerplay.pp_handle,
17661bb76ff1Sjsg max_clocks);
17671bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
17681bb76ff1Sjsg
17691bb76ff1Sjsg return ret;
17701bb76ff1Sjsg }
17711bb76ff1Sjsg
amdgpu_dpm_get_uclk_dpm_states(struct amdgpu_device * adev,unsigned int * clock_values_in_khz,unsigned int * num_states)17721bb76ff1Sjsg enum pp_smu_status amdgpu_dpm_get_uclk_dpm_states(struct amdgpu_device *adev,
17731bb76ff1Sjsg unsigned int *clock_values_in_khz,
17741bb76ff1Sjsg unsigned int *num_states)
17751bb76ff1Sjsg {
17761bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
17771bb76ff1Sjsg int ret = 0;
17781bb76ff1Sjsg
17791bb76ff1Sjsg if (!pp_funcs->get_uclk_dpm_states)
17801bb76ff1Sjsg return -EOPNOTSUPP;
17811bb76ff1Sjsg
17821bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
17831bb76ff1Sjsg ret = pp_funcs->get_uclk_dpm_states(adev->powerplay.pp_handle,
17841bb76ff1Sjsg clock_values_in_khz,
17851bb76ff1Sjsg num_states);
17861bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
17871bb76ff1Sjsg
17881bb76ff1Sjsg return ret;
17891bb76ff1Sjsg }
17901bb76ff1Sjsg
amdgpu_dpm_get_dpm_clock_table(struct amdgpu_device * adev,struct dpm_clocks * clock_table)17911bb76ff1Sjsg int amdgpu_dpm_get_dpm_clock_table(struct amdgpu_device *adev,
17921bb76ff1Sjsg struct dpm_clocks *clock_table)
17931bb76ff1Sjsg {
17941bb76ff1Sjsg const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
17951bb76ff1Sjsg int ret = 0;
17961bb76ff1Sjsg
17971bb76ff1Sjsg if (!pp_funcs->get_dpm_clock_table)
17981bb76ff1Sjsg return -EOPNOTSUPP;
17991bb76ff1Sjsg
18001bb76ff1Sjsg mutex_lock(&adev->pm.mutex);
18011bb76ff1Sjsg ret = pp_funcs->get_dpm_clock_table(adev->powerplay.pp_handle,
18021bb76ff1Sjsg clock_table);
18031bb76ff1Sjsg mutex_unlock(&adev->pm.mutex);
18041bb76ff1Sjsg
18051bb76ff1Sjsg return ret;
18061bb76ff1Sjsg }
1807