drm/radeon/cik: use a mutex to properly lock srbm instanced registers
We need proper locking in the driver when accessing instanced registers on CIK. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
3744b248f9
commit
f61d5b4677
3 changed files with 13 additions and 0 deletions
|
@ -2587,9 +2587,11 @@ u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
|
||||||
if (rdev->wb.enabled) {
|
if (rdev->wb.enabled) {
|
||||||
rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
|
rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
|
||||||
} else {
|
} else {
|
||||||
|
mutex_lock(&rdev->srbm_mutex);
|
||||||
cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
|
cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
|
||||||
rptr = RREG32(CP_HQD_PQ_RPTR);
|
rptr = RREG32(CP_HQD_PQ_RPTR);
|
||||||
cik_srbm_select(rdev, 0, 0, 0, 0);
|
cik_srbm_select(rdev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&rdev->srbm_mutex);
|
||||||
}
|
}
|
||||||
rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
|
rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
|
||||||
|
|
||||||
|
@ -2604,9 +2606,11 @@ u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
|
||||||
if (rdev->wb.enabled) {
|
if (rdev->wb.enabled) {
|
||||||
wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]);
|
wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]);
|
||||||
} else {
|
} else {
|
||||||
|
mutex_lock(&rdev->srbm_mutex);
|
||||||
cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
|
cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
|
||||||
wptr = RREG32(CP_HQD_PQ_WPTR);
|
wptr = RREG32(CP_HQD_PQ_WPTR);
|
||||||
cik_srbm_select(rdev, 0, 0, 0, 0);
|
cik_srbm_select(rdev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&rdev->srbm_mutex);
|
||||||
}
|
}
|
||||||
wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
|
wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
|
||||||
|
|
||||||
|
@ -2897,6 +2901,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
|
||||||
WREG32(CP_CPF_DEBUG, tmp);
|
WREG32(CP_CPF_DEBUG, tmp);
|
||||||
|
|
||||||
/* init the pipes */
|
/* init the pipes */
|
||||||
|
mutex_lock(&rdev->srbm_mutex);
|
||||||
for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); i++) {
|
for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); i++) {
|
||||||
int me = (i < 4) ? 1 : 2;
|
int me = (i < 4) ? 1 : 2;
|
||||||
int pipe = (i < 4) ? i : (i - 4);
|
int pipe = (i < 4) ? i : (i - 4);
|
||||||
|
@ -2919,6 +2924,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
|
||||||
WREG32(CP_HPD_EOP_CONTROL, tmp);
|
WREG32(CP_HPD_EOP_CONTROL, tmp);
|
||||||
}
|
}
|
||||||
cik_srbm_select(rdev, 0, 0, 0, 0);
|
cik_srbm_select(rdev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&rdev->srbm_mutex);
|
||||||
|
|
||||||
/* init the queues. Just two for now. */
|
/* init the queues. Just two for now. */
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
|
@ -2972,6 +2978,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
|
||||||
mqd->static_thread_mgmt23[0] = 0xffffffff;
|
mqd->static_thread_mgmt23[0] = 0xffffffff;
|
||||||
mqd->static_thread_mgmt23[1] = 0xffffffff;
|
mqd->static_thread_mgmt23[1] = 0xffffffff;
|
||||||
|
|
||||||
|
mutex_lock(&rdev->srbm_mutex);
|
||||||
cik_srbm_select(rdev, rdev->ring[idx].me,
|
cik_srbm_select(rdev, rdev->ring[idx].me,
|
||||||
rdev->ring[idx].pipe,
|
rdev->ring[idx].pipe,
|
||||||
rdev->ring[idx].queue, 0);
|
rdev->ring[idx].queue, 0);
|
||||||
|
@ -3099,6 +3106,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
|
||||||
WREG32(CP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active);
|
WREG32(CP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active);
|
||||||
|
|
||||||
cik_srbm_select(rdev, 0, 0, 0, 0);
|
cik_srbm_select(rdev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&rdev->srbm_mutex);
|
||||||
|
|
||||||
radeon_bo_kunmap(rdev->ring[idx].mqd_obj);
|
radeon_bo_kunmap(rdev->ring[idx].mqd_obj);
|
||||||
radeon_bo_unreserve(rdev->ring[idx].mqd_obj);
|
radeon_bo_unreserve(rdev->ring[idx].mqd_obj);
|
||||||
|
@ -4320,6 +4328,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
|
||||||
|
|
||||||
/* XXX SH_MEM regs */
|
/* XXX SH_MEM regs */
|
||||||
/* where to put LDS, scratch, GPUVM in FSA64 space */
|
/* where to put LDS, scratch, GPUVM in FSA64 space */
|
||||||
|
mutex_lock(&rdev->srbm_mutex);
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
cik_srbm_select(rdev, 0, 0, 0, i);
|
cik_srbm_select(rdev, 0, 0, 0, i);
|
||||||
/* CP and shaders */
|
/* CP and shaders */
|
||||||
|
@ -4335,6 +4344,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
|
||||||
/* XXX SDMA RLC - todo */
|
/* XXX SDMA RLC - todo */
|
||||||
}
|
}
|
||||||
cik_srbm_select(rdev, 0, 0, 0, 0);
|
cik_srbm_select(rdev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&rdev->srbm_mutex);
|
||||||
|
|
||||||
cik_pcie_gart_tlb_flush(rdev);
|
cik_pcie_gart_tlb_flush(rdev);
|
||||||
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
|
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
|
||||||
|
|
|
@ -2095,6 +2095,8 @@ struct radeon_device {
|
||||||
/* ACPI interface */
|
/* ACPI interface */
|
||||||
struct radeon_atif atif;
|
struct radeon_atif atif;
|
||||||
struct radeon_atcs atcs;
|
struct radeon_atcs atcs;
|
||||||
|
/* srbm instance registers */
|
||||||
|
struct mutex srbm_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
int radeon_device_init(struct radeon_device *rdev,
|
int radeon_device_init(struct radeon_device *rdev,
|
||||||
|
|
|
@ -1163,6 +1163,7 @@ int radeon_device_init(struct radeon_device *rdev,
|
||||||
mutex_init(&rdev->gem.mutex);
|
mutex_init(&rdev->gem.mutex);
|
||||||
mutex_init(&rdev->pm.mutex);
|
mutex_init(&rdev->pm.mutex);
|
||||||
mutex_init(&rdev->gpu_clock_mutex);
|
mutex_init(&rdev->gpu_clock_mutex);
|
||||||
|
mutex_init(&rdev->srbm_mutex);
|
||||||
init_rwsem(&rdev->pm.mclk_lock);
|
init_rwsem(&rdev->pm.mclk_lock);
|
||||||
init_rwsem(&rdev->exclusive_lock);
|
init_rwsem(&rdev->exclusive_lock);
|
||||||
init_waitqueue_head(&rdev->irq.vblank_queue);
|
init_waitqueue_head(&rdev->irq.vblank_queue);
|
||||||
|
|
Loading…
Add table
Reference in a new issue