[PATCH 24/29] drm/amdgpu: suspend for each vcn instance

Alex Deucher alexdeucher at gmail.com
Mon Oct 28 19:42:25 UTC 2024


On Thu, Oct 24, 2024 at 10:36 PM <boyuan.zhang at amd.com> wrote:
>
> From: Boyuan Zhang <boyuan.zhang at amd.com>
>
> Pass instance parameter to amdgpu_vcn_suspend(), and perform
> suspend ONLY for the given vcn instance, instead of for all
> vcn instances. Modify each vcn generation accordingly.
>
> v2: add vcn instance to amdgpu_vcn_save_vcpu_bo()
>
> Signed-off-by: Boyuan Zhang <boyuan.zhang at amd.com>

Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c | 13 ++++----
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c   | 38 +++++++++++------------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h   |  4 +--
>  drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c     |  7 +++--
>  drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c     |  6 ++--
>  drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c     |  6 ++--
>  drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c     |  6 ++--
>  drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c     |  6 ++--
>  drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c   |  6 ++--
>  drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c   |  6 ++--
>  drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c   |  6 ++--
>  11 files changed, 59 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
> index 24dae7cdbe95..4fc0ee01d56b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
> @@ -42,13 +42,14 @@ static int amdgpu_reset_xgmi_reset_on_init_suspend(struct amdgpu_device *adev)
>                 /* XXX handle errors */
>                 amdgpu_ip_block_suspend(&adev->ip_blocks[i]);
>                 adev->ip_blocks[i].status.hw = false;
> -       }
>
> -       /* VCN FW shared region is in frambuffer, there are some flags
> -        * initialized in that region during sw_init. Make sure the region is
> -        * backed up.
> -        */
> -       amdgpu_vcn_save_vcpu_bo(adev);
> +               /* VCN FW shared region is in frambuffer, there are some flags
> +               * initialized in that region during sw_init. Make sure the region is
> +               * backed up.
> +               */
> +               if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_VCN)
> +                       amdgpu_vcn_save_vcpu_bo(adev, adev->ip_blocks[i].instance);
> +       }
>
>         return 0;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
> index d515cfd2da79..50047c636904 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
> @@ -294,47 +294,45 @@ bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev, enum vcn_ring_type t
>         return ret;
>  }
>
> -int amdgpu_vcn_save_vcpu_bo(struct amdgpu_device *adev)
> +int amdgpu_vcn_save_vcpu_bo(struct amdgpu_device *adev, int inst)
>  {
>         unsigned int size;
>         void *ptr;
> -       int i, idx;
> +       int idx;
>
> -       for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
> -               if (adev->vcn.harvest_config & (1 << i))
> -                       continue;
> -               if (adev->vcn.inst[i].vcpu_bo == NULL)
> -                       return 0;
> +       if (adev->vcn.harvest_config & (1 << inst))
> +               return 0;
>
> -               size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo);
> -               ptr = adev->vcn.inst[i].cpu_addr;
> +       if (adev->vcn.inst[inst].vcpu_bo == NULL)
> +               return 0;
>
> -               adev->vcn.inst[i].saved_bo = kvmalloc(size, GFP_KERNEL);
> -               if (!adev->vcn.inst[i].saved_bo)
> -                       return -ENOMEM;
> +       size = amdgpu_bo_size(adev->vcn.inst[inst].vcpu_bo);
> +       ptr = adev->vcn.inst[inst].cpu_addr;
>
> -               if (drm_dev_enter(adev_to_drm(adev), &idx)) {
> -                       memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size);
> -                       drm_dev_exit(idx);
> -               }
> +       adev->vcn.inst[inst].saved_bo = kvmalloc(size, GFP_KERNEL);
> +       if (!adev->vcn.inst[inst].saved_bo)
> +               return -ENOMEM;
> +
> +       if (drm_dev_enter(adev_to_drm(adev), &idx)) {
> +               memcpy_fromio(adev->vcn.inst[inst].saved_bo, ptr, size);
> +               drm_dev_exit(idx);
>         }
>
>         return 0;
>  }
>
> -int amdgpu_vcn_suspend(struct amdgpu_device *adev)
> +int amdgpu_vcn_suspend(struct amdgpu_device *adev, int inst)
>  {
>         bool in_ras_intr = amdgpu_ras_intr_triggered();
>
> -       for (i = 0; i < adev->vcn.num_vcn_inst; ++i)
> -               cancel_delayed_work_sync(&adev->vcn.inst[i].idle_work);
> +       cancel_delayed_work_sync(&adev->vcn.inst[inst].idle_work);
>
>         /* err_event_athub will corrupt VCPU buffer, so we need to
>          * restore fw data and clear buffer in amdgpu_vcn_resume() */
>         if (in_ras_intr)
>                 return 0;
>
> -       return amdgpu_vcn_save_vcpu_bo(adev);
> +       return amdgpu_vcn_save_vcpu_bo(adev, inst);
>  }
>
>  int amdgpu_vcn_resume(struct amdgpu_device *adev)
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
> index ce8000ca11ef..be681bcab184 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
> @@ -486,7 +486,7 @@ enum vcn_ring_type {
>  int amdgpu_vcn_early_init(struct amdgpu_device *adev, int inst);
>  int amdgpu_vcn_sw_init(struct amdgpu_device *adev, int inst);
>  int amdgpu_vcn_sw_fini(struct amdgpu_device *adev, int inst);
> -int amdgpu_vcn_suspend(struct amdgpu_device *adev);
> +int amdgpu_vcn_suspend(struct amdgpu_device *adev, int inst);
>  int amdgpu_vcn_resume(struct amdgpu_device *adev);
>  void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring);
>  void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring);
> @@ -520,6 +520,6 @@ int amdgpu_vcn_ras_sw_init(struct amdgpu_device *adev);
>
>  int amdgpu_vcn_psp_update_sram(struct amdgpu_device *adev, int inst_idx,
>                                enum AMDGPU_UCODE_ID ucode_id);
> -int amdgpu_vcn_save_vcpu_bo(struct amdgpu_device *adev);
> +int amdgpu_vcn_save_vcpu_bo(struct amdgpu_device *adev, int inst);
>
>  #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
> index 44370949fa57..a3845e7747b0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
> @@ -226,7 +226,7 @@ static int vcn_v1_0_sw_fini(struct amdgpu_ip_block *ip_block)
>         int inst = ip_block->instance;
>         int r;
>
> -       r = amdgpu_vcn_suspend(adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>         if (r)
>                 return r;
>
> @@ -300,9 +300,10 @@ static int vcn_v1_0_hw_fini(struct amdgpu_ip_block *ip_block)
>   */
>  static int vcn_v1_0_suspend(struct amdgpu_ip_block *ip_block)
>  {
> -       int r;
>         struct amdgpu_device *adev = ip_block->adev;
> +       int inst = ip_block->instance;
>         bool idle_work_unexecuted;
> +       int r;
>
>         idle_work_unexecuted = cancel_delayed_work_sync(&adev->vcn.inst[0].idle_work);
>         if (idle_work_unexecuted) {
> @@ -314,7 +315,7 @@ static int vcn_v1_0_suspend(struct amdgpu_ip_block *ip_block)
>         if (r)
>                 return r;
>
> -       r = amdgpu_vcn_suspend(adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>
>         return r;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
> index 7b5f2696e60d..8e943d1fae17 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
> @@ -257,7 +257,7 @@ static int vcn_v2_0_sw_fini(struct amdgpu_ip_block *ip_block)
>
>         amdgpu_virt_free_mm_table(adev);
>
> -       r = amdgpu_vcn_suspend(adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>         if (r)
>                 return r;
>
> @@ -335,13 +335,15 @@ static int vcn_v2_0_hw_fini(struct amdgpu_ip_block *ip_block)
>   */
>  static int vcn_v2_0_suspend(struct amdgpu_ip_block *ip_block)
>  {
> +       struct amdgpu_device *adev = ip_block->adev;
> +       int inst = ip_block->instance;
>         int r;
>
>         r = vcn_v2_0_hw_fini(ip_block);
>         if (r)
>                 return r;
>
> -       r = amdgpu_vcn_suspend(ip_block->adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>
>         return r;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
> index 8ce3cea6cf44..9ca07e56b052 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
> @@ -316,7 +316,7 @@ static int vcn_v2_5_sw_fini(struct amdgpu_ip_block *ip_block)
>         if (amdgpu_sriov_vf(adev))
>                 amdgpu_virt_free_mm_table(adev);
>
> -       r = amdgpu_vcn_suspend(adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>         if (r)
>                 return r;
>
> @@ -412,13 +412,15 @@ static int vcn_v2_5_hw_fini(struct amdgpu_ip_block *ip_block)
>   */
>  static int vcn_v2_5_suspend(struct amdgpu_ip_block *ip_block)
>  {
> +       struct amdgpu_device *adev = ip_block->adev;
> +       int inst = ip_block->instance;
>         int r;
>
>         r = vcn_v2_5_hw_fini(ip_block);
>         if (r)
>                 return r;
>
> -       r = amdgpu_vcn_suspend(ip_block->adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>
>         return r;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
> index 36100c2612d9..a25d2b9784be 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
> @@ -325,7 +325,7 @@ static int vcn_v3_0_sw_fini(struct amdgpu_ip_block *ip_block)
>         if (amdgpu_sriov_vf(adev))
>                 amdgpu_virt_free_mm_table(adev);
>
> -       r = amdgpu_vcn_suspend(adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>         if (r)
>                 return r;
>
> @@ -444,13 +444,15 @@ static int vcn_v3_0_hw_fini(struct amdgpu_ip_block *ip_block)
>   */
>  static int vcn_v3_0_suspend(struct amdgpu_ip_block *ip_block)
>  {
> +       struct amdgpu_device *adev = ip_block->adev;
> +       int inst = ip_block->instance;
>         int r;
>
>         r = vcn_v3_0_hw_fini(ip_block);
>         if (r)
>                 return r;
>
> -       r = amdgpu_vcn_suspend(ip_block->adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>
>         return r;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
> index 00ff7affc647..fcf7b23cca90 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
> @@ -277,7 +277,7 @@ static int vcn_v4_0_sw_fini(struct amdgpu_ip_block *ip_block)
>         if (amdgpu_sriov_vf(adev))
>                 amdgpu_virt_free_mm_table(adev);
>
> -       r = amdgpu_vcn_suspend(adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>         if (r)
>                 return r;
>
> @@ -372,13 +372,15 @@ static int vcn_v4_0_hw_fini(struct amdgpu_ip_block *ip_block)
>   */
>  static int vcn_v4_0_suspend(struct amdgpu_ip_block *ip_block)
>  {
> +       struct amdgpu_device *adev = ip_block->adev;
> +       int inst = ip_block->instance;
>         int r;
>
>         r = vcn_v4_0_hw_fini(ip_block);
>         if (r)
>                 return r;
>
> -       r = amdgpu_vcn_suspend(ip_block->adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>
>         return r;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
> index feb373a96cfb..ece9b1df2743 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
> @@ -235,7 +235,7 @@ static int vcn_v4_0_3_sw_fini(struct amdgpu_ip_block *ip_block)
>         if (amdgpu_sriov_vf(adev))
>                 amdgpu_virt_free_mm_table(adev);
>
> -       r = amdgpu_vcn_suspend(adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>         if (r)
>                 return r;
>
> @@ -331,13 +331,15 @@ static int vcn_v4_0_3_hw_fini(struct amdgpu_ip_block *ip_block)
>   */
>  static int vcn_v4_0_3_suspend(struct amdgpu_ip_block *ip_block)
>  {
> +       struct amdgpu_device *adev = ip_block->adev;
> +       int inst = ip_block->instance;
>         int r;
>
>         r = vcn_v4_0_3_hw_fini(ip_block);
>         if (r)
>                 return r;
>
> -       r = amdgpu_vcn_suspend(ip_block->adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>
>         return r;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
> index fb1e1d5bcdbe..f1ec632a9eb8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
> @@ -246,7 +246,7 @@ static int vcn_v4_0_5_sw_fini(struct amdgpu_ip_block *ip_block)
>         if (amdgpu_sriov_vf(adev))
>                 amdgpu_virt_free_mm_table(adev);
>
> -       r = amdgpu_vcn_suspend(adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>         if (r)
>                 return r;
>
> @@ -323,13 +323,15 @@ static int vcn_v4_0_5_hw_fini(struct amdgpu_ip_block *ip_block)
>   */
>  static int vcn_v4_0_5_suspend(struct amdgpu_ip_block *ip_block)
>  {
> +       struct amdgpu_device *adev = ip_block->adev;
> +       int inst = ip_block->instance;
>         int r;
>
>         r = vcn_v4_0_5_hw_fini(ip_block);
>         if (r)
>                 return r;
>
> -       r = amdgpu_vcn_suspend(ip_block->adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>
>         return r;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
> index 137c3b452433..fdfb3084d54e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
> @@ -210,7 +210,7 @@ static int vcn_v5_0_0_sw_fini(struct amdgpu_ip_block *ip_block)
>                 drm_dev_exit(idx);
>         }
>
> -       r = amdgpu_vcn_suspend(adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>         if (r)
>                 return r;
>
> @@ -287,13 +287,15 @@ static int vcn_v5_0_0_hw_fini(struct amdgpu_ip_block *ip_block)
>   */
>  static int vcn_v5_0_0_suspend(struct amdgpu_ip_block *ip_block)
>  {
> +       struct amdgpu_device *adev = ip_block->adev;
> +       int inst = ip_block->instance;
>         int r;
>
>         r = vcn_v5_0_0_hw_fini(ip_block);
>         if (r)
>                 return r;
>
> -       r = amdgpu_vcn_suspend(ip_block->adev);
> +       r = amdgpu_vcn_suspend(adev, inst);
>
>         return r;
>  }
> --
> 2.34.1
>


More information about the amd-gfx mailing list