Path: blob/master/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c
26565 views
/*1* Copyright 2015 Advanced Micro Devices, Inc.2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice shall be included in11* all copies or substantial portions of the Software.12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR17* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,18* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR19* OTHER DEALINGS IN THE SOFTWARE.20*21*/2223#include "pp_debug.h"24#include <linux/delay.h>25#include <linux/kernel.h>26#include <linux/slab.h>27#include <linux/types.h>28#include <linux/pci.h>29#include <drm/amdgpu_drm.h>30#include "power_state.h"31#include "hwmgr.h"32#include "ppsmc.h"33#include "amd_acpi.h"34#include "pp_psm.h"35#include "vega10_hwmgr.h"3637extern const struct pp_smumgr_func ci_smu_funcs;38extern const struct pp_smumgr_func smu8_smu_funcs;39extern const struct pp_smumgr_func iceland_smu_funcs;40extern const struct pp_smumgr_func tonga_smu_funcs;41extern const struct pp_smumgr_func fiji_smu_funcs;42extern const struct pp_smumgr_func polaris10_smu_funcs;43extern const struct pp_smumgr_func vegam_smu_funcs;44extern const struct pp_smumgr_func vega10_smu_funcs;45extern const struct pp_smumgr_func vega12_smu_funcs;46extern const struct pp_smumgr_func smu10_smu_funcs;47extern const struct pp_smumgr_func vega20_smu_funcs;4849extern int smu10_init_function_pointers(struct pp_hwmgr *hwmgr);5051static int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr);52static void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr);53static int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr);54static int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr);55static int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr);56static int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr);57static int ci_set_asic_special_caps(struct pp_hwmgr *hwmgr);585960static void hwmgr_init_workload_prority(struct pp_hwmgr *hwmgr)61{62hwmgr->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;63hwmgr->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;64hwmgr->workload_prority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2;65hwmgr->workload_prority[PP_SMC_POWER_PROFILE_VIDEO] = 3;66hwmgr->workload_prority[PP_SMC_POWER_PROFILE_VR] = 4;67hwmgr->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5;6869hwmgr->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;70hwmgr->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D;71hwmgr->workload_setting[2] = PP_SMC_POWER_PROFILE_POWERSAVING;72hwmgr->workload_setting[3] = PP_SMC_POWER_PROFILE_VIDEO;73hwmgr->workload_setting[4] = PP_SMC_POWER_PROFILE_VR;74hwmgr->workload_setting[5] = PP_SMC_POWER_PROFILE_COMPUTE;75}7677int hwmgr_early_init(struct pp_hwmgr *hwmgr)78{79struct amdgpu_device *adev;8081if (!hwmgr)82return -EINVAL;8384hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;85hwmgr->pp_table_version = PP_TABLE_V1;86hwmgr->dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;87hwmgr->request_dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;88hwmgr_init_default_caps(hwmgr);89hwmgr_set_user_specify_caps(hwmgr);90hwmgr->fan_ctrl_is_in_default_mode = true;91hwmgr_init_workload_prority(hwmgr);92hwmgr->gfxoff_state_changed_by_workload = false;9394adev = hwmgr->adev;9596switch (hwmgr->chip_family) {97case AMDGPU_FAMILY_CI:98adev->pm.pp_feature &= ~PP_GFXOFF_MASK;99hwmgr->smumgr_funcs = &ci_smu_funcs;100ci_set_asic_special_caps(hwmgr);101hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK |102PP_ENABLE_GFX_CG_THRU_SMU |103PP_GFXOFF_MASK);104hwmgr->pp_table_version = PP_TABLE_V0;105hwmgr->od_enabled = false;106smu7_init_function_pointers(hwmgr);107break;108case AMDGPU_FAMILY_CZ:109adev->pm.pp_feature &= ~PP_GFXOFF_MASK;110hwmgr->od_enabled = false;111hwmgr->smumgr_funcs = &smu8_smu_funcs;112hwmgr->feature_mask &= ~PP_GFXOFF_MASK;113smu8_init_function_pointers(hwmgr);114break;115case AMDGPU_FAMILY_VI:116adev->pm.pp_feature &= ~PP_GFXOFF_MASK;117hwmgr->feature_mask &= ~PP_GFXOFF_MASK;118switch (hwmgr->chip_id) {119case CHIP_TOPAZ:120hwmgr->smumgr_funcs = &iceland_smu_funcs;121topaz_set_asic_special_caps(hwmgr);122hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK |123PP_ENABLE_GFX_CG_THRU_SMU);124hwmgr->pp_table_version = PP_TABLE_V0;125hwmgr->od_enabled = false;126break;127case CHIP_TONGA:128hwmgr->smumgr_funcs = &tonga_smu_funcs;129tonga_set_asic_special_caps(hwmgr);130hwmgr->feature_mask &= ~PP_VBI_TIME_SUPPORT_MASK;131break;132case CHIP_FIJI:133hwmgr->smumgr_funcs = &fiji_smu_funcs;134fiji_set_asic_special_caps(hwmgr);135hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK |136PP_ENABLE_GFX_CG_THRU_SMU);137break;138case CHIP_POLARIS11:139case CHIP_POLARIS10:140case CHIP_POLARIS12:141hwmgr->smumgr_funcs = &polaris10_smu_funcs;142polaris_set_asic_special_caps(hwmgr);143hwmgr->feature_mask &= ~(PP_UVD_HANDSHAKE_MASK);144break;145case CHIP_VEGAM:146hwmgr->smumgr_funcs = &vegam_smu_funcs;147polaris_set_asic_special_caps(hwmgr);148hwmgr->feature_mask &= ~(PP_UVD_HANDSHAKE_MASK);149break;150default:151return -EINVAL;152}153smu7_init_function_pointers(hwmgr);154break;155case AMDGPU_FAMILY_AI:156switch (hwmgr->chip_id) {157case CHIP_VEGA10:158adev->pm.pp_feature &= ~PP_GFXOFF_MASK;159hwmgr->feature_mask &= ~PP_GFXOFF_MASK;160hwmgr->smumgr_funcs = &vega10_smu_funcs;161vega10_hwmgr_init(hwmgr);162break;163case CHIP_VEGA12:164hwmgr->smumgr_funcs = &vega12_smu_funcs;165vega12_hwmgr_init(hwmgr);166break;167case CHIP_VEGA20:168adev->pm.pp_feature &= ~PP_GFXOFF_MASK;169hwmgr->feature_mask &= ~PP_GFXOFF_MASK;170hwmgr->smumgr_funcs = &vega20_smu_funcs;171vega20_hwmgr_init(hwmgr);172break;173default:174return -EINVAL;175}176break;177case AMDGPU_FAMILY_RV:178switch (hwmgr->chip_id) {179case CHIP_RAVEN:180hwmgr->od_enabled = false;181hwmgr->smumgr_funcs = &smu10_smu_funcs;182smu10_init_function_pointers(hwmgr);183break;184default:185return -EINVAL;186}187break;188default:189return -EINVAL;190}191192return 0;193}194195int hwmgr_sw_init(struct pp_hwmgr *hwmgr)196{197if (!hwmgr || !hwmgr->smumgr_funcs || !hwmgr->smumgr_funcs->smu_init)198return -EINVAL;199200phm_register_irq_handlers(hwmgr);201pr_info("hwmgr_sw_init smu backed is %s\n", hwmgr->smumgr_funcs->name);202203return hwmgr->smumgr_funcs->smu_init(hwmgr);204}205206207int hwmgr_sw_fini(struct pp_hwmgr *hwmgr)208{209if (hwmgr && hwmgr->smumgr_funcs && hwmgr->smumgr_funcs->smu_fini)210hwmgr->smumgr_funcs->smu_fini(hwmgr);211212return 0;213}214215int hwmgr_hw_init(struct pp_hwmgr *hwmgr)216{217int ret = 0;218219hwmgr->pp_one_vf = amdgpu_sriov_is_pp_one_vf((struct amdgpu_device *)hwmgr->adev);220hwmgr->pm_en = (amdgpu_dpm && (hwmgr->not_vf || hwmgr->pp_one_vf))221? true : false;222if (!hwmgr->pm_en)223return 0;224225if (!hwmgr->pptable_func ||226!hwmgr->pptable_func->pptable_init ||227!hwmgr->hwmgr_func->backend_init) {228hwmgr->pm_en = false;229pr_info("dpm not supported \n");230return 0;231}232233ret = hwmgr->pptable_func->pptable_init(hwmgr);234if (ret)235goto err;236237((struct amdgpu_device *)hwmgr->adev)->pm.no_fan =238hwmgr->thermal_controller.fanInfo.bNoFan;239240ret = hwmgr->hwmgr_func->backend_init(hwmgr);241if (ret)242goto err1;243/* make sure dc limits are valid */244if ((hwmgr->dyn_state.max_clock_voltage_on_dc.sclk == 0) ||245(hwmgr->dyn_state.max_clock_voltage_on_dc.mclk == 0))246hwmgr->dyn_state.max_clock_voltage_on_dc =247hwmgr->dyn_state.max_clock_voltage_on_ac;248249ret = psm_init_power_state_table(hwmgr);250if (ret)251goto err2;252253ret = phm_setup_asic(hwmgr);254if (ret)255goto err2;256257ret = phm_enable_dynamic_state_management(hwmgr);258if (ret)259goto err2;260ret = phm_start_thermal_controller(hwmgr);261ret |= psm_set_performance_states(hwmgr);262if (ret)263goto err2;264265((struct amdgpu_device *)hwmgr->adev)->pm.dpm_enabled = true;266267return 0;268err2:269if (hwmgr->hwmgr_func->backend_fini)270hwmgr->hwmgr_func->backend_fini(hwmgr);271err1:272if (hwmgr->pptable_func->pptable_fini)273hwmgr->pptable_func->pptable_fini(hwmgr);274err:275return ret;276}277278int hwmgr_hw_fini(struct pp_hwmgr *hwmgr)279{280if (!hwmgr || !hwmgr->pm_en || !hwmgr->not_vf)281return 0;282283phm_stop_thermal_controller(hwmgr);284psm_set_boot_states(hwmgr);285psm_adjust_power_state_dynamic(hwmgr, true, NULL);286phm_disable_dynamic_state_management(hwmgr);287phm_disable_clock_power_gatings(hwmgr);288289if (hwmgr->hwmgr_func->backend_fini)290hwmgr->hwmgr_func->backend_fini(hwmgr);291if (hwmgr->pptable_func->pptable_fini)292hwmgr->pptable_func->pptable_fini(hwmgr);293return psm_fini_power_state_table(hwmgr);294}295296int hwmgr_suspend(struct pp_hwmgr *hwmgr)297{298int ret = 0;299300if (!hwmgr || !hwmgr->pm_en || !hwmgr->not_vf)301return 0;302303phm_disable_smc_firmware_ctf(hwmgr);304ret = psm_set_boot_states(hwmgr);305if (ret)306return ret;307ret = psm_adjust_power_state_dynamic(hwmgr, true, NULL);308if (ret)309return ret;310ret = phm_power_down_asic(hwmgr);311312return ret;313}314315int hwmgr_resume(struct pp_hwmgr *hwmgr)316{317int ret = 0;318319if (!hwmgr)320return -EINVAL;321322if (!hwmgr->not_vf || !hwmgr->pm_en)323return 0;324325ret = phm_setup_asic(hwmgr);326if (ret)327return ret;328329ret = phm_enable_dynamic_state_management(hwmgr);330if (ret)331return ret;332ret = phm_start_thermal_controller(hwmgr);333ret |= psm_set_performance_states(hwmgr);334if (ret)335return ret;336337ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);338339return ret;340}341342static enum PP_StateUILabel power_state_convert(enum amd_pm_state_type state)343{344switch (state) {345case POWER_STATE_TYPE_BATTERY:346return PP_StateUILabel_Battery;347case POWER_STATE_TYPE_BALANCED:348return PP_StateUILabel_Balanced;349case POWER_STATE_TYPE_PERFORMANCE:350return PP_StateUILabel_Performance;351default:352return PP_StateUILabel_None;353}354}355356int hwmgr_handle_task(struct pp_hwmgr *hwmgr, enum amd_pp_task task_id,357enum amd_pm_state_type *user_state)358{359int ret = 0;360361if (hwmgr == NULL)362return -EINVAL;363364switch (task_id) {365case AMD_PP_TASK_DISPLAY_CONFIG_CHANGE:366if (!hwmgr->not_vf)367return ret;368ret = phm_pre_display_configuration_changed(hwmgr);369if (ret)370return ret;371ret = phm_set_cpu_power_state(hwmgr);372if (ret)373return ret;374ret = psm_set_performance_states(hwmgr);375if (ret)376return ret;377ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);378break;379case AMD_PP_TASK_ENABLE_USER_STATE:380{381enum PP_StateUILabel requested_ui_label;382struct pp_power_state *requested_ps = NULL;383384if (!hwmgr->not_vf)385return ret;386if (user_state == NULL) {387ret = -EINVAL;388break;389}390391requested_ui_label = power_state_convert(*user_state);392ret = psm_set_user_performance_state(hwmgr, requested_ui_label, &requested_ps);393if (ret)394return ret;395ret = psm_adjust_power_state_dynamic(hwmgr, true, requested_ps);396break;397}398case AMD_PP_TASK_COMPLETE_INIT:399case AMD_PP_TASK_READJUST_POWER_STATE:400ret = psm_adjust_power_state_dynamic(hwmgr, true, NULL);401break;402default:403break;404}405return ret;406}407408void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr)409{410phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);411412phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM);413phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEDPM);414415#if defined(CONFIG_ACPI)416if (amdgpu_acpi_is_pcie_performance_request_supported(hwmgr->adev))417phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);418#endif419420phm_cap_set(hwmgr->platform_descriptor.platformCaps,421PHM_PlatformCaps_DynamicPatchPowerState);422423phm_cap_set(hwmgr->platform_descriptor.platformCaps,424PHM_PlatformCaps_EnableSMU7ThermalManagement);425426phm_cap_set(hwmgr->platform_descriptor.platformCaps,427PHM_PlatformCaps_DynamicPowerManagement);428429phm_cap_set(hwmgr->platform_descriptor.platformCaps,430PHM_PlatformCaps_SMC);431432phm_cap_set(hwmgr->platform_descriptor.platformCaps,433PHM_PlatformCaps_DynamicUVDState);434435phm_cap_set(hwmgr->platform_descriptor.platformCaps,436PHM_PlatformCaps_FanSpeedInTableIsRPM);437return;438}439440int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr)441{442if (hwmgr->feature_mask & PP_SCLK_DEEP_SLEEP_MASK)443phm_cap_set(hwmgr->platform_descriptor.platformCaps,444PHM_PlatformCaps_SclkDeepSleep);445else446phm_cap_unset(hwmgr->platform_descriptor.platformCaps,447PHM_PlatformCaps_SclkDeepSleep);448449if (hwmgr->feature_mask & PP_POWER_CONTAINMENT_MASK) {450phm_cap_set(hwmgr->platform_descriptor.platformCaps,451PHM_PlatformCaps_PowerContainment);452phm_cap_set(hwmgr->platform_descriptor.platformCaps,453PHM_PlatformCaps_CAC);454} else {455phm_cap_unset(hwmgr->platform_descriptor.platformCaps,456PHM_PlatformCaps_PowerContainment);457phm_cap_unset(hwmgr->platform_descriptor.platformCaps,458PHM_PlatformCaps_CAC);459}460461if (hwmgr->feature_mask & PP_OVERDRIVE_MASK)462hwmgr->od_enabled = true;463464return 0;465}466467int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr)468{469phm_cap_set(hwmgr->platform_descriptor.platformCaps,470PHM_PlatformCaps_EVV);471phm_cap_set(hwmgr->platform_descriptor.platformCaps,472PHM_PlatformCaps_SQRamping);473phm_cap_set(hwmgr->platform_descriptor.platformCaps,474PHM_PlatformCaps_RegulatorHot);475476phm_cap_set(hwmgr->platform_descriptor.platformCaps,477PHM_PlatformCaps_MemorySpreadSpectrumSupport);478phm_cap_set(hwmgr->platform_descriptor.platformCaps,479PHM_PlatformCaps_EngineSpreadSpectrumSupport);480481phm_cap_set(hwmgr->platform_descriptor.platformCaps,482PHM_PlatformCaps_AutomaticDCTransition);483484if (((hwmgr->chip_id == CHIP_POLARIS11) && !hwmgr->is_kicker) ||485(hwmgr->chip_id == CHIP_POLARIS12))486phm_cap_set(hwmgr->platform_descriptor.platformCaps,487PHM_PlatformCaps_SPLLShutdownSupport);488489if (hwmgr->chip_id != CHIP_POLARIS11) {490phm_cap_set(hwmgr->platform_descriptor.platformCaps,491PHM_PlatformCaps_DBRamping);492phm_cap_set(hwmgr->platform_descriptor.platformCaps,493PHM_PlatformCaps_TDRamping);494phm_cap_set(hwmgr->platform_descriptor.platformCaps,495PHM_PlatformCaps_TCPRamping);496}497return 0;498}499500int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr)501{502phm_cap_set(hwmgr->platform_descriptor.platformCaps,503PHM_PlatformCaps_EVV);504phm_cap_unset(hwmgr->platform_descriptor.platformCaps,505PHM_PlatformCaps_SQRamping);506phm_cap_unset(hwmgr->platform_descriptor.platformCaps,507PHM_PlatformCaps_DBRamping);508phm_cap_unset(hwmgr->platform_descriptor.platformCaps,509PHM_PlatformCaps_TDRamping);510phm_cap_unset(hwmgr->platform_descriptor.platformCaps,511PHM_PlatformCaps_TCPRamping);512return 0;513}514515int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr)516{517phm_cap_set(hwmgr->platform_descriptor.platformCaps,518PHM_PlatformCaps_EVV);519phm_cap_unset(hwmgr->platform_descriptor.platformCaps,520PHM_PlatformCaps_SQRamping);521phm_cap_unset(hwmgr->platform_descriptor.platformCaps,522PHM_PlatformCaps_DBRamping);523phm_cap_unset(hwmgr->platform_descriptor.platformCaps,524PHM_PlatformCaps_TDRamping);525phm_cap_unset(hwmgr->platform_descriptor.platformCaps,526PHM_PlatformCaps_TCPRamping);527528phm_cap_unset(hwmgr->platform_descriptor.platformCaps,529PHM_PlatformCaps_UVDPowerGating);530phm_cap_unset(hwmgr->platform_descriptor.platformCaps,531PHM_PlatformCaps_VCEPowerGating);532return 0;533}534535int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr)536{537phm_cap_set(hwmgr->platform_descriptor.platformCaps,538PHM_PlatformCaps_EVV);539phm_cap_unset(hwmgr->platform_descriptor.platformCaps,540PHM_PlatformCaps_SQRamping);541phm_cap_unset(hwmgr->platform_descriptor.platformCaps,542PHM_PlatformCaps_DBRamping);543phm_cap_unset(hwmgr->platform_descriptor.platformCaps,544PHM_PlatformCaps_TDRamping);545phm_cap_unset(hwmgr->platform_descriptor.platformCaps,546PHM_PlatformCaps_TCPRamping);547return 0;548}549550int ci_set_asic_special_caps(struct pp_hwmgr *hwmgr)551{552phm_cap_unset(hwmgr->platform_descriptor.platformCaps,553PHM_PlatformCaps_SQRamping);554phm_cap_unset(hwmgr->platform_descriptor.platformCaps,555PHM_PlatformCaps_DBRamping);556phm_cap_unset(hwmgr->platform_descriptor.platformCaps,557PHM_PlatformCaps_TDRamping);558phm_cap_unset(hwmgr->platform_descriptor.platformCaps,559PHM_PlatformCaps_TCPRamping);560phm_cap_set(hwmgr->platform_descriptor.platformCaps,561PHM_PlatformCaps_MemorySpreadSpectrumSupport);562phm_cap_set(hwmgr->platform_descriptor.platformCaps,563PHM_PlatformCaps_EngineSpreadSpectrumSupport);564return 0;565}566567568