|
@@ -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;
|
|
|
}
|