drm/amdgpu: Fix SDMA load/unload sequence on HWS disabled mode
Fix the SDMA load and unload sequence as suggested by HW document. Signed-off-by: shaoyun liu <shaoyun.liu@amd.com> Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> Acked-by: Oded Gabbay <oded.gabbay@gmail.com> Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
This commit is contained in:
parent
c209101fc1
commit
cf21654b40
|
@ -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 amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||||
struct cik_sdma_rlc_registers *m;
|
struct cik_sdma_rlc_registers *m;
|
||||||
|
unsigned long end_jiffies;
|
||||||
uint32_t sdma_base_addr;
|
uint32_t sdma_base_addr;
|
||||||
|
uint32_t data;
|
||||||
|
|
||||||
m = get_sdma_mqd(mqd);
|
m = get_sdma_mqd(mqd);
|
||||||
sdma_base_addr = get_sdma_base_addr(m);
|
sdma_base_addr = get_sdma_base_addr(m);
|
||||||
|
|
||||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_VIRTUAL_ADDR,
|
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL,
|
||||||
m->sdma_rlc_virtual_addr);
|
m->sdma_rlc_rb_cntl & (~SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK));
|
||||||
|
|
||||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE,
|
end_jiffies = msecs_to_jiffies(2000) + jiffies;
|
||||||
m->sdma_rlc_rb_base);
|
while (true) {
|
||||||
|
data = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS);
|
||||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE_HI,
|
if (data & SDMA0_RLC0_CONTEXT_STATUS__IDLE_MASK)
|
||||||
m->sdma_rlc_rb_base_hi);
|
break;
|
||||||
|
if (time_after(jiffies, end_jiffies))
|
||||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_LO,
|
return -ETIME;
|
||||||
m->sdma_rlc_rb_rptr_addr_lo);
|
usleep_range(500, 1000);
|
||||||
|
}
|
||||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_HI,
|
if (m->sdma_engine_id) {
|
||||||
m->sdma_rlc_rb_rptr_addr_hi);
|
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,
|
WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL,
|
||||||
m->sdma_rlc_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_RB_CNTL,
|
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL,
|
||||||
m->sdma_rlc_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_DOORBELL, 0);
|
||||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, 0);
|
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL,
|
||||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0);
|
RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL) |
|
||||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, 0);
|
SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue