* Skip SMU FW reloading in case of using BACO for runpm only, * as SMU is always alive. Above comment needs to be updated to cover BAMACO. Regards, Guchun -----Original Message----- From: amd-gfx <amd-gfx-bounces@xxxxxxxxxxxxxxxxxxxxx> On Behalf Of Kenneth Feng Sent: Tuesday, August 23, 2022 10:03 AM To: amd-gfx@xxxxxxxxxxxxxxxxxxxxx Cc: Feng, Kenneth <Kenneth.Feng@xxxxxxx> Subject: [PATCH] drm/amd/pm: improve BAMACO code for smu_v13_0 For runtime pm case: 1. prompt in dmesg for BAMACO feature test 2. set BACO by defatul and the user can select BAMACO Signed-off-by: Kenneth Feng <kenneth.feng@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 ++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 10 ++++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 3 ++- drivers/gpu/drm/amd/amdgpu/soc21.c | 1 + .../gpu/drm/amd/include/kgd_pp_interface.h | 1 + drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 23 +++++++++++++++++++ drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 2 ++ drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 16 +++++++++++++ drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 1 + drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h | 1 + .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 17 +++++++++++++- .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 1 + .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 1 + 14 files changed, 83 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 1372e2b47541..104bb62db830 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -598,6 +598,7 @@ struct amdgpu_asic_funcs { uint64_t (*get_pcie_replay_count)(struct amdgpu_device *adev); /* device supports BACO */ bool (*supports_baco)(struct amdgpu_device *adev); + bool (*supports_maco)(struct amdgpu_device *adev); /* pre asic_init quirks */ void (*pre_asic_init)(struct amdgpu_device *adev); /* enter/exit umd stable pstate */ @@ -1289,6 +1290,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev); #define amdgpu_asic_need_reset_on_init(adev) (adev)->asic_funcs->need_reset_on_init((adev)) #define amdgpu_asic_get_pcie_replay_count(adev) ((adev)->asic_funcs->get_pcie_replay_count((adev))) #define amdgpu_asic_supports_baco(adev) (adev)->asic_funcs->supports_baco((adev)) +#define amdgpu_asic_supports_maco(adev) +(adev)->asic_funcs->supports_maco((adev)) #define amdgpu_asic_pre_asic_init(adev) (adev)->asic_funcs->pre_asic_init((adev)) #define amdgpu_asic_update_umd_stable_pstate(adev, enter) \ ((adev)->asic_funcs->update_umd_stable_pstate ? (adev)->asic_funcs->update_umd_stable_pstate((adev), (enter)) : 0) @@ -1329,6 +1331,7 @@ bool amdgpu_device_supports_px(struct drm_device *dev); bool amdgpu_device_supports_boco(struct drm_device *dev); bool amdgpu_device_supports_smart_shift(struct drm_device *dev); bool amdgpu_device_supports_baco(struct drm_device *dev); +bool amdgpu_device_supports_maco(struct drm_device *dev); bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev, struct amdgpu_device *peer_adev); int amdgpu_device_baco_enter(struct drm_device *dev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index ebb722811dcf..a034295fae71 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -272,6 +272,13 @@ bool amdgpu_device_supports_baco(struct drm_device *dev) return amdgpu_asic_supports_baco(adev); } +bool amdgpu_device_supports_maco(struct drm_device *dev) { + struct amdgpu_device *adev = drm_to_adev(dev); + + return amdgpu_asic_supports_maco(adev); } + /** * amdgpu_device_supports_smart_shift - Is the device dGPU with * smart shift support diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 95bce47943bb..4c022785ded1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -171,13 +171,19 @@ int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags) adev->pm.rpm_mode = AMDGPU_RUNPM_BACO; break; default: - /* enable BACO as runpm mode on CI+ */ - adev->pm.rpm_mode = AMDGPU_RUNPM_BACO; + /* enable BACO/BAMACO as runpm mode on CI+ */ + if (amdgpu_runtime_pm == 2 && amdgpu_device_supports_maco(dev)) + adev->pm.rpm_mode = AMDGPU_RUNPM_BAMACO; + else + adev->pm.rpm_mode = AMDGPU_RUNPM_BACO; break; } if (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO) dev_info(adev->dev, "Using BACO for runtime pm\n"); + + if (adev->pm.rpm_mode == AMDGPU_RUNPM_BAMACO) + dev_info(adev->dev, "Using BAMACO for runtime pm\n"); } /* Call ACPI methods: require modeset init diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index b067ce45d226..b363c729b9b2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -2374,7 +2374,8 @@ static int psp_load_smu_fw(struct psp_context *psp) * Skip SMU FW reloading in case of using BACO for runpm only, * as SMU is always alive. */ - if (adev->in_runpm && (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO)) + if (adev->in_runpm && (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO || + adev->pm.rpm_mode == AMDGPU_RUNPM_BAMACO)) return 0; if (!ucode->fw || amdgpu_sriov_vf(psp->adev)) diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c index 1ff7fc7bb340..f21653fbe69c 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc21.c +++ b/drivers/gpu/drm/amd/amdgpu/soc21.c @@ -511,6 +511,7 @@ static const struct amdgpu_asic_funcs soc21_asic_funcs = .need_reset_on_init = &soc21_need_reset_on_init, .get_pcie_replay_count = &soc21_get_pcie_replay_count, .supports_baco = &amdgpu_dpm_is_baco_supported, + .supports_maco = &amdgpu_dpm_is_maco_supported, .pre_asic_init = &soc21_pre_asic_init, .query_video_codecs = &soc21_query_video_codecs, }; diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 7e3231c2191c..43635d238451 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -389,6 +389,7 @@ struct amd_pm_funcs { int (*set_hard_min_fclk_by_freq)(void *handle, uint32_t clock); int (*set_min_deep_sleep_dcefclk)(void *handle, uint32_t clock); int (*get_asic_baco_capability)(void *handle, bool *cap); + int (*get_asic_maco_capability)(void *handle, bool *cap); int (*get_asic_baco_state)(void *handle, int *state); int (*set_asic_baco_state)(void *handle, int state); int (*get_ppfeature_status)(void *handle, char *buf); diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c index 956b6ce81c84..b3e373046928 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -209,6 +209,29 @@ bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev) return ret ? false : baco_cap; } +bool amdgpu_dpm_is_maco_supported(struct amdgpu_device *adev) { + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; + void *pp_handle = adev->powerplay.pp_handle; + bool maco_cap; + int ret = 0; + + if (!pp_funcs || !pp_funcs->get_asic_maco_capability) + return false; + + if (adev->in_s3) + return false; + + mutex_lock(&adev->pm.mutex); + + ret = pp_funcs->get_asic_maco_capability(pp_handle, + &maco_cap); + + mutex_unlock(&adev->pm.mutex); + + return ret ? false : maco_cap; +} + int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev) { const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h index 65624d091ed2..911a293d95b2 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h @@ -50,6 +50,7 @@ enum amdgpu_runpm_mode { AMDGPU_RUNPM_PX, AMDGPU_RUNPM_BOCO, AMDGPU_RUNPM_BACO, + AMDGPU_RUNPM_BAMACO, }; struct amdgpu_ps { @@ -388,6 +389,7 @@ int amdgpu_dpm_baco_reset(struct amdgpu_device *adev); int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev); bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev); +bool amdgpu_dpm_is_maco_supported(struct amdgpu_device *adev); bool amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device *adev); int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 7510d470b864..11e611edb874 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -2723,6 +2723,21 @@ static int smu_get_baco_capability(void *handle, bool *cap) return 0; } +static int smu_get_maco_capability(void *handle, bool *cap) { + struct smu_context *smu = handle; + + *cap = false; + + if (!smu->pm_enabled) + return 0; + + if (smu->ppt_funcs && smu->ppt_funcs->maco_is_support) + *cap = smu->ppt_funcs->maco_is_support(smu); + + return 0; +} + static int smu_baco_set_state(void *handle, int state) { struct smu_context *smu = handle; @@ -2984,6 +2999,7 @@ static const struct amd_pm_funcs swsmu_pm_funcs = { .set_active_display_count = smu_set_display_count, .set_min_deep_sleep_dcefclk = smu_set_deep_sleep_dcefclk, .get_asic_baco_capability = smu_get_baco_capability, + .get_asic_maco_capability = smu_get_maco_capability, .set_asic_baco_state = smu_baco_set_state, .get_ppfeature_status = smu_sys_get_pp_feature_mask, .set_ppfeature_status = smu_sys_set_pp_feature_mask, diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h index b81c657c7386..6bd5777b8780 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -1134,6 +1134,7 @@ struct pptable_funcs { * @baco_is_support: Check if GPU supports BACO (Bus Active, Chip Off). */ bool (*baco_is_support)(struct smu_context *smu); + bool (*maco_is_support)(struct smu_context *smu); /** * @baco_get_state: Get the current BACO state. diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h index 6fe2fe92ebd7..f2f76fac28ea 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h @@ -218,6 +218,7 @@ int smu_v13_0_get_max_sustainable_clocks_by_dc(struct smu_context *smu, struct pp_smu_nv_clock_table *max_clocks); bool smu_v13_0_baco_is_support(struct smu_context *smu); +bool smu_v13_0_maco_is_support(struct smu_context *smu); enum smu_baco_state smu_v13_0_baco_get_state(struct smu_context *smu); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c index 3651f6f75068..6db051eb6aa5 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -2278,6 +2278,21 @@ bool smu_v13_0_baco_is_support(struct smu_context *smu) return true; } +bool smu_v13_0_maco_is_support(struct smu_context *smu) { + struct smu_baco_context *smu_baco = &smu->smu_baco; + + if (amdgpu_sriov_vf(smu->adev) || + !smu_baco->maco_support) + return false; + + if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_BACO_BIT) && + !smu_cmn_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT)) + return false; + + return true; +} + enum smu_baco_state smu_v13_0_baco_get_state(struct smu_context *smu) { struct smu_baco_context *smu_baco = &smu->smu_baco; @@ -2298,7 +2313,7 @@ int smu_v13_0_baco_set_state(struct smu_context *smu, if (state == SMU_BACO_STATE_ENTER) { ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, - smu_baco->maco_support ? + (adev->pm.rpm_mode == AMDGPU_RUNPM_BAMACO) ? BACO_SEQ_BAMACO : BACO_SEQ_BACO, NULL); } else { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index df4a47acd724..28d54e671a1a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -1845,6 +1845,7 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = { .deep_sleep_control = smu_v13_0_deep_sleep_control, .gfx_ulv_control = smu_v13_0_gfx_ulv_control, .baco_is_support = smu_v13_0_baco_is_support, + .maco_is_support = smu_v13_0_maco_is_support, .baco_get_state = smu_v13_0_baco_get_state, .baco_set_state = smu_v13_0_baco_set_state, .baco_enter = smu_v13_0_baco_enter, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index 1016d1c216d8..459a6096e552 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -1632,6 +1632,7 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = { .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, .set_pp_feature_mask = smu_cmn_set_pp_feature_mask, .baco_is_support = smu_v13_0_baco_is_support, + .maco_is_support = smu_v13_0_maco_is_support, .baco_get_state = smu_v13_0_baco_get_state, .baco_set_state = smu_v13_0_baco_set_state, .baco_enter = smu_v13_0_baco_enter, -- 2.25.1