提交 78c5560a 编写于 作者: A Alex Deucher 提交者: Dave Airlie

drm/radeon/kms: add some new ring params to better handle other ring types

Some rptr/wptrs fields have different offsets and not all rings are pm4
so add a new nop field.
Signed-off-by: NAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: NChristian König <deathsimple@vodafone.de>
Signed-off-by: NDave Airlie <airlied@redhat.com>
上级 ce954884
...@@ -3127,7 +3127,8 @@ static int evergreen_startup(struct radeon_device *rdev) ...@@ -3127,7 +3127,8 @@ static int evergreen_startup(struct radeon_device *rdev)
evergreen_irq_set(rdev); evergreen_irq_set(rdev);
r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, 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) if (r)
return r; return r;
r = evergreen_cp_load_microcode(rdev); r = evergreen_cp_load_microcode(rdev);
......
...@@ -1412,7 +1412,8 @@ static int cayman_startup(struct radeon_device *rdev) ...@@ -1412,7 +1412,8 @@ static int cayman_startup(struct radeon_device *rdev)
evergreen_irq_set(rdev); evergreen_irq_set(rdev);
r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, 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) if (r)
return r; return r;
r = cayman_cp_load_microcode(rdev); r = cayman_cp_load_microcode(rdev);
......
...@@ -1075,7 +1075,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) ...@@ -1075,7 +1075,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
ring_size = (1 << (rb_bufsz + 1)) * 4; ring_size = (1 << (rb_bufsz + 1)) * 4;
r100_cp_load_microcode(rdev); r100_cp_load_microcode(rdev);
r = radeon_ring_init(rdev, ring, ring_size, RADEON_WB_CP_RPTR_OFFSET, 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) { if (r) {
return r; return r;
} }
......
...@@ -2474,7 +2474,8 @@ int r600_startup(struct radeon_device *rdev) ...@@ -2474,7 +2474,8 @@ int r600_startup(struct radeon_device *rdev)
r600_irq_set(rdev); r600_irq_set(rdev);
r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, 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) if (r)
return r; return r;
......
...@@ -542,6 +542,9 @@ struct radeon_ring { ...@@ -542,6 +542,9 @@ struct radeon_ring {
uint32_t ptr_mask; uint32_t ptr_mask;
struct mutex mutex; struct mutex mutex;
bool ready; 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 ...@@ -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); 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_test(struct radeon_device *rdev, struct radeon_ring *cp);
int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, 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); void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp);
......
...@@ -305,10 +305,13 @@ int radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *ring) ...@@ -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) void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring)
{ {
u32 rptr;
if (rdev->wb.enabled) 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 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 */ /* 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->rptr + (ring->ring_size / 4));
ring->ring_free_dw -= ring->wptr; ring->ring_free_dw -= ring->wptr;
...@@ -362,10 +365,10 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) ...@@ -362,10 +365,10 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring)
count_dw_pad = (ring->align_mask + 1) - count_dw_pad = (ring->align_mask + 1) -
(ring->wptr & ring->align_mask); (ring->wptr & ring->align_mask);
for (i = 0; i < count_dw_pad; i++) { for (i = 0; i < count_dw_pad; i++) {
radeon_ring_write(ring, 2 << 30); radeon_ring_write(ring, ring->nop);
} }
DRM_MEMORYBARRIER(); 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); (void)RREG32(ring->wptr_reg);
} }
...@@ -382,7 +385,8 @@ void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *rin ...@@ -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, 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; int r;
...@@ -390,6 +394,9 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig ...@@ -390,6 +394,9 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig
ring->rptr_offs = rptr_offs; ring->rptr_offs = rptr_offs;
ring->rptr_reg = rptr_reg; ring->rptr_reg = rptr_reg;
ring->wptr_reg = wptr_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 */ /* Allocate ring buffer */
if (ring->ring_obj == NULL) { if (ring->ring_obj == NULL) {
r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true, r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true,
......
...@@ -1099,7 +1099,8 @@ static int rv770_startup(struct radeon_device *rdev) ...@@ -1099,7 +1099,8 @@ static int rv770_startup(struct radeon_device *rdev)
r600_irq_set(rdev); r600_irq_set(rdev);
r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, 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) if (r)
return r; return r;
r = rv770_cp_load_microcode(rdev); r = rv770_cp_load_microcode(rdev);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册