diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index ba19b9a697b0754a5d9082abb80532085af3d41d..6ff1180c7321e76dd83d03016e8b0bc50d43729b 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3127,7 +3127,8 @@ static int evergreen_startup(struct radeon_device *rdev) evergreen_irq_set(rdev); r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, - R600_CP_RB_RPTR, R600_CP_RB_WPTR); + R600_CP_RB_RPTR, R600_CP_RB_WPTR, + 0, 0xfffff, RADEON_CP_PACKET2); if (r) return r; r = evergreen_cp_load_microcode(rdev); diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index a9b0e615804f865078abcafabd63c22cdbc0d7b4..d0d23c547643995ac1d28e9bd35f4c3befdb618d 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1412,7 +1412,8 @@ static int cayman_startup(struct radeon_device *rdev) evergreen_irq_set(rdev); r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, - CP_RB0_RPTR, CP_RB0_WPTR); + CP_RB0_RPTR, CP_RB0_WPTR, + 0, 0xfffff, RADEON_CP_PACKET2); if (r) return r; r = cayman_cp_load_microcode(rdev); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index bed56c7b690b636e9221aba1e5cfc5d162c37ad9..3ef2c58b84071af92bedfd1a3e1dc8041b2f9dbd 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1075,7 +1075,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) ring_size = (1 << (rb_bufsz + 1)) * 4; r100_cp_load_microcode(rdev); r = radeon_ring_init(rdev, ring, ring_size, RADEON_WB_CP_RPTR_OFFSET, - RADEON_CP_RB_RPTR, RADEON_CP_RB_WPTR); + RADEON_CP_RB_RPTR, RADEON_CP_RB_WPTR, + 0, 0x7fffff, RADEON_CP_PACKET2); if (r) { return r; } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index f2deadfcd88f822ce806f72075576a7d3e7a917d..48bd8202b5c99dc5c82f276931fb6d07239d2523 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2474,7 +2474,8 @@ int r600_startup(struct radeon_device *rdev) r600_irq_set(rdev); r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, - R600_CP_RB_RPTR, R600_CP_RB_WPTR); + R600_CP_RB_RPTR, R600_CP_RB_WPTR, + 0, 0xfffff, RADEON_CP_PACKET2); if (r) return r; diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5777afb361de94f1b021fa2c975a0049c726c9ab..e5d5271d7a9c9817299de4a0f4f7792ce9f3b8cf 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -542,6 +542,9 @@ struct radeon_ring { uint32_t ptr_mask; struct mutex mutex; bool ready; + u32 ptr_reg_shift; + u32 ptr_reg_mask; + u32 nop; }; /* @@ -612,7 +615,8 @@ void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *c void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp); int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, - unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg); + unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, + u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop); void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp); diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index b39a1d9306e5be59666eda5e7c715429201f3024..133e2636cea08e13d34857a6dddfd0f2fc14ac01 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -305,10 +305,13 @@ int radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *ring) void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring) { + u32 rptr; + if (rdev->wb.enabled) - ring->rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); + rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); else - ring->rptr = RREG32(ring->rptr_reg); + rptr = RREG32(ring->rptr_reg); + ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; /* This works because ring_size is a power of 2 */ ring->ring_free_dw = (ring->rptr + (ring->ring_size / 4)); ring->ring_free_dw -= ring->wptr; @@ -362,10 +365,10 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) count_dw_pad = (ring->align_mask + 1) - (ring->wptr & ring->align_mask); for (i = 0; i < count_dw_pad; i++) { - radeon_ring_write(ring, 2 << 30); + radeon_ring_write(ring, ring->nop); } DRM_MEMORYBARRIER(); - WREG32(ring->wptr_reg, ring->wptr); + WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask); (void)RREG32(ring->wptr_reg); } @@ -382,7 +385,8 @@ void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *rin } int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size, - unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg) + unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, + u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop) { int r; @@ -390,6 +394,9 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig ring->rptr_offs = rptr_offs; ring->rptr_reg = rptr_reg; ring->wptr_reg = wptr_reg; + ring->ptr_reg_shift = ptr_reg_shift; + ring->ptr_reg_mask = ptr_reg_mask; + ring->nop = nop; /* Allocate ring buffer */ if (ring->ring_obj == NULL) { r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true, diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 0a1283d2402784f5dc3e5b58d8e5790e365ad0c5..d854fbfa5a52eb445885849c7963f72333007fd9 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -1099,7 +1099,8 @@ static int rv770_startup(struct radeon_device *rdev) r600_irq_set(rdev); r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, - R600_CP_RB_RPTR, R600_CP_RB_WPTR); + R600_CP_RB_RPTR, R600_CP_RB_WPTR, + 0, 0xfffff, RADEON_CP_PACKET2); if (r) return r; r = rv770_cp_load_microcode(rdev);