On Thu, Nov 2, 2017 at 1:21 AM, Felix Kuehling <Felix.Kuehling at amd.com> wrote: > Fix the SDMA load and unload sequence as suggested by HW document. > > Signed-off-by: shaoyun liu <shaoyun.liu at amd.com> > Signed-off-by: Felix Kuehling <Felix.Kuehling at amd.com> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 47 ++++++++++++++++------- > 1 file changed, 34 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c > index 47d1c13..1e3e9be 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c > @@ -379,29 +379,50 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd) > { > struct amdgpu_device *adev = get_amdgpu_device(kgd); > struct cik_sdma_rlc_registers *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_VIRTUAL_ADDR, > - m->sdma_rlc_virtual_addr); > + WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, > + m->sdma_rlc_rb_cntl & (~SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK)); > > - WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, > - m->sdma_rlc_rb_base); > + 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); > + } > > + WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, > + m->sdma_rlc_doorbell); > + WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, 0); > + WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0); > + WREG32(sdma_base_addr + mmSDMA0_RLC0_VIRTUAL_ADDR, > + m->sdma_rlc_virtual_addr); > + WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, m->sdma_rlc_rb_base); > WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE_HI, > m->sdma_rlc_rb_base_hi); > - > WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_LO, > m->sdma_rlc_rb_rptr_addr_lo); > - > WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_HI, > m->sdma_rlc_rb_rptr_addr_hi); > - > - WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, > - m->sdma_rlc_doorbell); > - > WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, > m->sdma_rlc_rb_cntl); > > @@ -574,9 +595,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); > > return 0; > } > -- > 2.7.4 > This patch is: Acked-by: Oded Gabbay <oded.gabbay at gmail.com>