[PATCH 8/8] drm/amdgpu/sdma4: Enable sdma poll mem addr on vega10 for SRIOV

Alex Deucher alexdeucher at gmail.com
Tue Jul 25 16:12:59 UTC 2017


On Tue, Jul 25, 2017 at 5:18 AM, Xiangliang.Yu <Xiangliang.Yu at amd.com> wrote:
> From: Frank Min <Frank.Min at amd.com>
>
> While doing flr on VFs, there is possibility to lost the doorbell
> writing for sdma, so enable poll mem for sdma, then sdma fw would
> check the pollmem holding wptr.
>
> Signed-off-by: Frank Min <Frank.Min at amd.com>
> Signed-off-by: Xiangliang.Yu <Xiangliang.Yu at amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h    |  3 +++
>  drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 48 ++++++++++++++++++++++++++++++++--
>  2 files changed, 49 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index d287621..79d46fd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -1208,6 +1208,9 @@ struct amdgpu_sdma_instance {
>
>         struct amdgpu_ring      ring;
>         bool                    burst_nop;
> +       struct amdgpu_bo        *poll_mem_bo;
> +       uint64_t                *poll_mem_cpuaddr;
> +       uint64_t                poll_mem_gpuaddr;
>  };
>
>  struct amdgpu_sdma {
> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
> index 591f3e7..563be32 100644
> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
> @@ -35,6 +35,7 @@
>  #include "vega10/MMHUB/mmhub_1_0_offset.h"
>  #include "vega10/MMHUB/mmhub_1_0_sh_mask.h"
>  #include "vega10/HDP/hdp_4_0_offset.h"
> +#include "vega10/NBIO/nbio_6_1_offset.h"
>  #include "raven1/SDMA0/sdma0_4_1_default.h"
>
>  #include "soc15_common.h"
> @@ -287,6 +288,7 @@ static uint64_t sdma_v4_0_ring_get_wptr(struct amdgpu_ring *ring)
>   */
>  static void sdma_v4_0_ring_set_wptr(struct amdgpu_ring *ring)
>  {
> +       int i;
>         struct amdgpu_device *adev = ring->adev;
>
>         DRM_DEBUG("Setting write pointer\n");
> @@ -303,6 +305,16 @@ static void sdma_v4_0_ring_set_wptr(struct amdgpu_ring *ring)
>                 adev->wb.wb[ring->wptr_offs + 1] = upper_32_bits(ring->wptr << 2);
>                 DRM_DEBUG("calling WDOORBELL64(0x%08x, 0x%016llx)\n",
>                                 ring->doorbell_index, ring->wptr << 2);
> +
> +               if (amdgpu_sriov_vf(adev)) {
> +                       for (i = 0; i < adev->sdma.num_instances; i++) {
> +                               if (&adev->sdma.instance[i].ring == ring) {
> +                                       *adev->sdma.instance[i].poll_mem_cpuaddr = ring->wptr << 2;
> +                                       WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
> +                                                                      mmBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL), 0);

Please use nbio_v6_1_hdp_flush() here rather than open coding it.


> +                               }
> +                       }
> +               }
>                 WDOORBELL64(ring->doorbell_index, ring->wptr << 2);
>         } else {
>                 int me = (ring == &ring->adev->sdma.instance[0].ring) ? 0 : 1;
> @@ -573,7 +585,7 @@ static void sdma_v4_0_enable(struct amdgpu_device *adev, bool enable)
>  static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev)
>  {
>         struct amdgpu_ring *ring;
> -       u32 rb_cntl, ib_cntl;
> +       u32 rb_cntl, ib_cntl, wptr_poll_addr_lo, wptr_poll_addr_hi, wptr_poll_cntl;
>         u32 rb_bufsz;
>         u32 wb_offset;
>         u32 doorbell;
> @@ -687,6 +699,19 @@ static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev)
>
>                 if (adev->mman.buffer_funcs_ring == ring)
>                         amdgpu_ttm_set_active_vram_size(adev, adev->mc.real_vram_size);
> +
> +               if (amdgpu_sriov_vf(adev)) {
> +                       wptr_poll_cntl = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL));
> +                       wptr_poll_addr_lo = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_LO));
> +                       wptr_poll_addr_lo = REG_SET_FIELD(wptr_poll_addr_lo, SDMA0_GFX_RB_WPTR_POLL_ADDR_LO, ADDR,
> +                                                               lower_32_bits(adev->sdma.instance[i].poll_mem_gpuaddr) >> 2);
> +                       wptr_poll_addr_hi = upper_32_bits(adev->sdma.instance[i].poll_mem_gpuaddr);
> +                       wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_GFX_RB_WPTR_POLL_CNTL, F32_POLL_ENABLE, 1);
> +
> +                       WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_LO), wptr_poll_addr_lo);
> +                       WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_HI), wptr_poll_addr_hi);

No need to add a separate bo for this.  Just use the wb buffer like we
do on gfx.  E.g.,

        wptr_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4);
    WREG32_SOC15(GC, 0, mmCP_RB_WPTR_POLL_ADDR_LO,
lower_32_bits(wptr_gpu_addr));
        WREG32_SOC15(GC, 0, mmCP_RB_WPTR_POLL_ADDR_HI,
upper_32_bits(wptr_gpu_addr));

so for SDMA it would just be:
wptr_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4);
WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_LO),
lower_32_bits(wptr_gpu_addr));
WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_HI),
upper_32_bits(wptr_gpu_addr));

Alex


> +                       WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL), wptr_poll_cntl);
> +               }
>         }
>
>         return 0;
> @@ -1247,6 +1272,20 @@ static int sdma_v4_0_sw_init(void *handle)
>                                      (i == 0) ?
>                                      AMDGPU_SDMA_IRQ_TRAP0 :
>                                      AMDGPU_SDMA_IRQ_TRAP1);
> +
> +               if (amdgpu_sriov_vf(adev)) {
> +                       r = amdgpu_bo_create_kernel(adev, 8, PAGE_SIZE,
> +                                               AMDGPU_GEM_DOMAIN_VRAM, &adev->sdma.instance[i].poll_mem_bo,
> +                                               &adev->sdma.instance[i].poll_mem_gpuaddr,
> +                                               (void **)&adev->sdma.instance[i].poll_mem_cpuaddr);
> +                       if (r) {
> +                               dev_err(adev->dev, "(%d) failed to allocate SDMA bo\n", r);
> +                               return r;
> +                       }
> +                       DRM_DEBUG("sdma%d polling memory gpu addr: 0x%llx cpu addr: 0x%p\n", i,
> +                               adev->sdma.instance[i].poll_mem_gpuaddr,
> +                               adev->sdma.instance[i].poll_mem_cpuaddr);
> +               }
>                 if (r)
>                         return r;
>         }
> @@ -1259,9 +1298,14 @@ static int sdma_v4_0_sw_fini(void *handle)
>         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
>         int i;
>
> -       for (i = 0; i < adev->sdma.num_instances; i++)
> +       for (i = 0; i < adev->sdma.num_instances; i++) {
>                 amdgpu_ring_fini(&adev->sdma.instance[i].ring);
>
> +               if (amdgpu_sriov_vf(adev))
> +                       amdgpu_bo_free_kernel(&adev->sdma.instance[i].poll_mem_bo,
> +                                       &adev->sdma.instance[i].poll_mem_gpuaddr,
> +                                       (void *)&adev->sdma.instance[i].poll_mem_cpuaddr);
> +       }
>         return 0;
>  }
>
> --
> 2.7.4
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list