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