[PATCH 6/8] drm/amdgpu: Implement amdgpu SDMA functions for VI

Oded Gabbay oded.gabbay at gmail.com
Thu Nov 2 15:00:40 UTC 2017


On Thu, Nov 2, 2017 at 1:22 AM, Felix Kuehling <Felix.Kuehling at amd.com> wrote:
> From: Philip Cox <Philip.Cox at amd.com>
>
> Signed-off-by: Philip Cox <Philip.Cox at amd.com>
> Signed-off-by: shaoyun liu <shaoyun.liu at amd.com>
> Signed-off-by: Yong Zhao <yong.zhao at amd.com>
> Signed-off-by: Jay Cornwall <Jay.Cornwall at amd.com>
> Signed-off-by: Felix Kuehling <Felix.Kuehling at amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 85 ++++++++++++++++++++---
>  drivers/gpu/drm/amd/amdgpu/vid.h                  |  2 +
>  drivers/gpu/drm/amd/include/vi_structs.h          |  2 +
>  3 files changed, 78 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
> index 03c564d..1d989e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
> @@ -45,7 +45,7 @@ enum hqd_dequeue_request_type {
>         RESET_WAVES
>  };
>
> -struct cik_sdma_rlc_registers;
> +struct vi_sdma_mqd;
>
>  /*
>   * Register access functions
> @@ -269,9 +269,15 @@ static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id)
>         return 0;
>  }
>
> -static inline uint32_t get_sdma_base_addr(struct cik_sdma_rlc_registers *m)
> +static inline uint32_t get_sdma_base_addr(struct vi_sdma_mqd *m)
>  {
> -       return 0;
> +       uint32_t retval;
> +
> +       retval = m->sdma_engine_id * SDMA1_REGISTER_OFFSET +
> +               m->sdma_queue_id * KFD_VI_SDMA_QUEUE_OFFSET;
> +       pr_debug("kfd: sdma base address: 0x%x\n", retval);
> +
> +       return retval;
>  }
>
>  static inline struct vi_mqd *get_mqd(void *mqd)
> @@ -279,9 +285,9 @@ static inline struct vi_mqd *get_mqd(void *mqd)
>         return (struct vi_mqd *)mqd;
>  }
>
> -static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
> +static inline struct vi_sdma_mqd *get_sdma_mqd(void *mqd)
>  {
> -       return (struct cik_sdma_rlc_registers *)mqd;
> +       return (struct vi_sdma_mqd *)mqd;
>  }
>
>  static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
> @@ -362,6 +368,63 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
>  static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
>                              uint32_t __user *wptr, struct mm_struct *mm)
>  {
> +       struct amdgpu_device *adev = get_amdgpu_device(kgd);
> +       struct vi_sdma_mqd *m;
> +       unsigned long end_jiffies;
> +       uint32_t sdma_base_addr;
> +       uint32_t data;
> +
> +       m = get_sdma_mqd(mqd);
> +       sdma_base_addr = get_sdma_base_addr(m);
> +       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL,
> +               m->sdmax_rlcx_rb_cntl & (~SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK));
> +
> +       end_jiffies = msecs_to_jiffies(2000) + jiffies;
> +       while (true) {
> +               data = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS);
> +               if (data & SDMA0_RLC0_CONTEXT_STATUS__IDLE_MASK)
> +                       break;
> +               if (time_after(jiffies, end_jiffies))
> +                       return -ETIME;
> +               usleep_range(500, 1000);
> +       }
> +       if (m->sdma_engine_id) {
> +               data = RREG32(mmSDMA1_GFX_CONTEXT_CNTL);
> +               data = REG_SET_FIELD(data, SDMA1_GFX_CONTEXT_CNTL,
> +                               RESUME_CTX, 0);
> +               WREG32(mmSDMA1_GFX_CONTEXT_CNTL, data);
> +       } else {
> +               data = RREG32(mmSDMA0_GFX_CONTEXT_CNTL);
> +               data = REG_SET_FIELD(data, SDMA0_GFX_CONTEXT_CNTL,
> +                               RESUME_CTX, 0);
> +               WREG32(mmSDMA0_GFX_CONTEXT_CNTL, data);
> +       }
> +
> +       data = REG_SET_FIELD(m->sdmax_rlcx_doorbell, SDMA0_RLC0_DOORBELL,
> +                            ENABLE, 1);
> +       WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, data);
> +       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, m->sdmax_rlcx_rb_rptr);
> +
> +       if (read_user_wptr(mm, wptr, data))
> +               WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, data);
> +       else
> +               WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR,
> +                      m->sdmax_rlcx_rb_rptr);
> +
> +       WREG32(sdma_base_addr + mmSDMA0_RLC0_VIRTUAL_ADDR,
> +                               m->sdmax_rlcx_virtual_addr);
> +       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, m->sdmax_rlcx_rb_base);
> +       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE_HI,
> +                       m->sdmax_rlcx_rb_base_hi);
> +       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_LO,
> +                       m->sdmax_rlcx_rb_rptr_addr_lo);
> +       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_HI,
> +                       m->sdmax_rlcx_rb_rptr_addr_hi);
> +
> +       data = REG_SET_FIELD(m->sdmax_rlcx_rb_cntl, SDMA0_RLC0_RB_CNTL,
> +                            RB_ENABLE, 1);
> +       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, data);
> +
>         return 0;
>  }
>
> @@ -390,7 +453,7 @@ static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
>  static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
>  {
>         struct amdgpu_device *adev = get_amdgpu_device(kgd);
> -       struct cik_sdma_rlc_registers *m;
> +       struct vi_sdma_mqd *m;
>         uint32_t sdma_base_addr;
>         uint32_t sdma_rlc_rb_cntl;
>
> @@ -511,7 +574,7 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
>                                 unsigned int utimeout)
>  {
>         struct amdgpu_device *adev = get_amdgpu_device(kgd);
> -       struct cik_sdma_rlc_registers *m;
> +       struct vi_sdma_mqd *m;
>         uint32_t sdma_base_addr;
>         uint32_t temp;
>         unsigned long end_jiffies = (utimeout * HZ / 1000) + jiffies;
> @@ -525,7 +588,7 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
>
>         while (true) {
>                 temp = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS);
> -               if (temp & SDMA0_STATUS_REG__RB_CMD_IDLE__SHIFT)
> +               if (temp & SDMA0_RLC0_CONTEXT_STATUS__IDLE_MASK)
>                         break;
>                 if (time_after(jiffies, end_jiffies))
>                         return -ETIME;
> @@ -533,9 +596,9 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
>         }
>
>         WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, 0);
> -       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, 0);
> -       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0);
> -       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, 0);
> +       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL,
> +               RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL) |
> +               SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK);
>
>         m->sdmax_rlcx_rb_rptr = RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR);
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vid.h b/drivers/gpu/drm/amd/amdgpu/vid.h
> index dbf3703..19ddd23 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vid.h
> +++ b/drivers/gpu/drm/amd/amdgpu/vid.h
> @@ -27,6 +27,8 @@
>  #define SDMA1_REGISTER_OFFSET                             0x200 /* not a register */
>  #define SDMA_MAX_INSTANCE 2
>
> +#define KFD_VI_SDMA_QUEUE_OFFSET                      0x80 /* not a register */
> +
>  /* crtc instance offsets */
>  #define CRTC0_REGISTER_OFFSET                 (0x1b9c - 0x1b9c)
>  #define CRTC1_REGISTER_OFFSET                 (0x1d9c - 0x1b9c)
> diff --git a/drivers/gpu/drm/amd/include/vi_structs.h b/drivers/gpu/drm/amd/include/vi_structs.h
> index 2023482..717fbae 100644
> --- a/drivers/gpu/drm/amd/include/vi_structs.h
> +++ b/drivers/gpu/drm/amd/include/vi_structs.h
> @@ -153,6 +153,8 @@ struct vi_sdma_mqd {
>         uint32_t reserved_125;
>         uint32_t reserved_126;
>         uint32_t reserved_127;
> +       uint32_t sdma_engine_id;
> +       uint32_t sdma_queue_id;
>  };
>
>  struct vi_mqd {
> --
> 2.7.4
>

This patch is:
Acked-by: Oded Gabbay <oded.gabbay at gmail.com>


More information about the amd-gfx mailing list