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: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Christian König <deathsimple@vodafone.de> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
ce95488437
commit
78c5560a08
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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 {
|
||||||
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
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
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)
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue