[PATCH] drm/amd/pm: fix runpm hang when amdgpu loaded prior to sound driver
Pierre-Eric Pelloux-Prayer
pierre-eric.pelloux-prayer at amd.com
Fri Sep 10 08:47:15 UTC 2021
Tested-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Thanks!
On 10/09/2021 05:17, Evan Quan wrote:
> Current RUNPM mechanism relies on PMFW to master the timing for BACO
> in/exit. And that needs cooperation from sound driver for dstate
> change notification for function 1(audio). Otherwise(on sound driver
> missing), BACO cannot be kicked in correctly and hang will be observed
> on RUNPM exit.
>
> By switching back to legacy message way on sound driver missing,
> we are able to fix the runpm hang observed for the scenario below:
> amdgpu driver loaded -> runpm suspend kicked -> sound driver loaded
>
> Change-Id: I0e44fef11349b5e45e6102913eb46c8c7d279c65
> Signed-off-by: Evan Quan <evan.quan at amd.com>
> Reported-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
> ---
> .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 24 +++++++++++++++++--
> .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 4 ++--
> drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 21 ++++++++++++++++
> drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h | 2 ++
> 4 files changed, 47 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
> index 7bc90f841a11..bcafccf7f07a 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
> @@ -2272,7 +2272,27 @@ static int navi10_baco_enter(struct smu_context *smu)
> {
> struct amdgpu_device *adev = smu->adev;
>
> - if (adev->in_runpm)
> + /*
> + * This aims the case below:
> + * amdgpu driver loaded -> runpm suspend kicked -> sound driver loaded
> + *
> + * For NAVI10 and later ASICs, we rely on PMFW to handle the runpm. To
> + * make that possible, PMFW needs to acknowledge the dstate transition
> + * process for both gfx(function 0) and audio(function 1) function of
> + * the ASIC.
> + *
> + * The PCI device's initial runpm status is RUNPM_SUSPENDED. So as the
> + * device representing the audio function of the ASIC. And that means
> + * even if the sound driver(snd_hda_intel) was not loaded yet, it's still
> + * possible runpm suspend kicked on the ASIC. However without the dstate
> + * transition notification from audio function, pmfw cannot handle the
> + * BACO in/exit correctly. And that will cause driver hang on runpm
> + * resuming.
> + *
> + * To address this, we revert to legacy message way(driver masters the
> + * timing for BACO in/exit) on sound driver missing.
> + */
> + if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev))
> return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_BACO);
> else
> return smu_v11_0_baco_enter(smu);
> @@ -2282,7 +2302,7 @@ static int navi10_baco_exit(struct smu_context *smu)
> {
> struct amdgpu_device *adev = smu->adev;
>
> - if (adev->in_runpm) {
> + if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) {
> /* Wait for PMFW handling for the Dstate change */
> msleep(10);
> return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
> index 43c7580a4ea6..f9b730c5ba9e 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
> @@ -2361,7 +2361,7 @@ static int sienna_cichlid_baco_enter(struct smu_context *smu)
> {
> struct amdgpu_device *adev = smu->adev;
>
> - if (adev->in_runpm)
> + if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev))
> return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_BACO);
> else
> return smu_v11_0_baco_enter(smu);
> @@ -2371,7 +2371,7 @@ static int sienna_cichlid_baco_exit(struct smu_context *smu)
> {
> struct amdgpu_device *adev = smu->adev;
>
> - if (adev->in_runpm) {
> + if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) {
> /* Wait for PMFW handling for the Dstate change */
> msleep(10);
> return smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
> index 69da9a7b665f..d61403e917df 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
> @@ -1055,3 +1055,24 @@ int smu_cmn_set_mp1_state(struct smu_context *smu,
>
> return ret;
> }
> +
> +bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev)
> +{
> + struct pci_dev *p = NULL;
> + bool snd_driver_loaded;
> +
> + /*
> + * If the ASIC comes with no audio function, we always assume
> + * it is "enabled".
> + */
> + p = pci_get_domain_bus_and_slot(pci_domain_nr(adev->pdev->bus),
> + adev->pdev->bus->number, 1);
> + if (!p)
> + return true;
> +
> + snd_driver_loaded = pci_is_enabled(p) ? true : false;
> +
> + pci_dev_put(p);
> +
> + return snd_driver_loaded;
> +}
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
> index 16993daa2ae0..b1d41360a389 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
> @@ -110,5 +110,7 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev);
> int smu_cmn_set_mp1_state(struct smu_context *smu,
> enum pp_mp1_state mp1_state);
>
> +bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev);
> +
> #endif
> #endif
>
More information about the amd-gfx
mailing list