Commit f93bdefe authored by Alex Deucher's avatar Alex Deucher

drm/radeon: use callbacks for ring pointer handling (v3)

Add callbacks to the radeon_asic struct to handle
rptr/wptr fetchs and wptr updates.
We currently use one version for all rings, but this
allows us to override with a ring specific versions.

Needed for compute rings on CIK.

v2: udpate as per Christian's comments
v3: fix some rebase cruft
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b556b12e
...@@ -1285,6 +1285,10 @@ struct radeon_asic { ...@@ -1285,6 +1285,10 @@ struct radeon_asic {
int (*ib_test)(struct radeon_device *rdev, struct radeon_ring *cp); int (*ib_test)(struct radeon_device *rdev, struct radeon_ring *cp);
bool (*is_lockup)(struct radeon_device *rdev, struct radeon_ring *cp); bool (*is_lockup)(struct radeon_device *rdev, struct radeon_ring *cp);
void (*vm_flush)(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); void (*vm_flush)(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
u32 (*get_rptr)(struct radeon_device *rdev, struct radeon_ring *ring);
u32 (*get_wptr)(struct radeon_device *rdev, struct radeon_ring *ring);
void (*set_wptr)(struct radeon_device *rdev, struct radeon_ring *ring);
} ring[RADEON_NUM_RINGS]; } ring[RADEON_NUM_RINGS];
/* irqs */ /* irqs */
struct { struct {
...@@ -1962,6 +1966,9 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); ...@@ -1962,6 +1966,9 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
#define radeon_ring_ib_parse(rdev, r, ib) (rdev)->asic->ring[(r)].ib_parse((rdev), (ib)) #define radeon_ring_ib_parse(rdev, r, ib) (rdev)->asic->ring[(r)].ib_parse((rdev), (ib))
#define radeon_ring_is_lockup(rdev, r, cp) (rdev)->asic->ring[(r)].is_lockup((rdev), (cp)) #define radeon_ring_is_lockup(rdev, r, cp) (rdev)->asic->ring[(r)].is_lockup((rdev), (cp))
#define radeon_ring_vm_flush(rdev, r, vm) (rdev)->asic->ring[(r)].vm_flush((rdev), (r), (vm)) #define radeon_ring_vm_flush(rdev, r, vm) (rdev)->asic->ring[(r)].vm_flush((rdev), (r), (vm))
#define radeon_ring_get_rptr(rdev, r) (rdev)->asic->ring[(r)->idx].get_rptr((rdev), (r))
#define radeon_ring_get_wptr(rdev, r) (rdev)->asic->ring[(r)->idx].get_wptr((rdev), (r))
#define radeon_ring_set_wptr(rdev, r) (rdev)->asic->ring[(r)->idx].set_wptr((rdev), (r))
#define radeon_irq_set(rdev) (rdev)->asic->irq.set((rdev)) #define radeon_irq_set(rdev) (rdev)->asic->irq.set((rdev))
#define radeon_irq_process(rdev) (rdev)->asic->irq.process((rdev)) #define radeon_irq_process(rdev) (rdev)->asic->irq.process((rdev))
#define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->display.get_vblank_counter((rdev), (crtc)) #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->display.get_vblank_counter((rdev), (crtc))
......
This diff is collapsed.
...@@ -47,6 +47,12 @@ u8 atombios_get_backlight_level(struct radeon_encoder *radeon_encoder); ...@@ -47,6 +47,12 @@ u8 atombios_get_backlight_level(struct radeon_encoder *radeon_encoder);
void radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level); void radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level);
u8 radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder); u8 radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder);
u32 radeon_ring_generic_get_rptr(struct radeon_device *rdev,
struct radeon_ring *ring);
u32 radeon_ring_generic_get_wptr(struct radeon_device *rdev,
struct radeon_ring *ring);
void radeon_ring_generic_set_wptr(struct radeon_device *rdev,
struct radeon_ring *ring);
/* /*
* r100,rv100,rs100,rv200,rs200 * r100,rv100,rs100,rv200,rs200
......
...@@ -357,6 +357,38 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev, ...@@ -357,6 +357,38 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev,
} }
} }
u32 radeon_ring_generic_get_rptr(struct radeon_device *rdev,
struct radeon_ring *ring)
{
u32 rptr;
if (rdev->wb.enabled && ring != &rdev->ring[R600_RING_TYPE_UVD_INDEX])
rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
else
rptr = RREG32(ring->rptr_reg);
rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
return rptr;
}
u32 radeon_ring_generic_get_wptr(struct radeon_device *rdev,
struct radeon_ring *ring)
{
u32 wptr;
wptr = RREG32(ring->wptr_reg);
wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
return wptr;
}
void radeon_ring_generic_set_wptr(struct radeon_device *rdev,
struct radeon_ring *ring)
{
WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask);
(void)RREG32(ring->wptr_reg);
}
/** /**
* radeon_ring_free_size - update the free size * radeon_ring_free_size - update the free size
* *
...@@ -367,13 +399,7 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev, ...@@ -367,13 +399,7 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev,
*/ */
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; ring->rptr = radeon_ring_get_rptr(rdev, ring);
if (rdev->wb.enabled && ring != &rdev->ring[R600_RING_TYPE_UVD_INDEX])
rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
else
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;
...@@ -458,8 +484,7 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) ...@@ -458,8 +484,7 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring)
radeon_ring_write(ring, ring->nop); radeon_ring_write(ring, ring->nop);
} }
DRM_MEMORYBARRIER(); DRM_MEMORYBARRIER();
WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask); radeon_ring_set_wptr(rdev, ring);
(void)RREG32(ring->wptr_reg);
} }
/** /**
...@@ -561,7 +586,6 @@ void radeon_ring_lockup_update(struct radeon_ring *ring) ...@@ -561,7 +586,6 @@ void radeon_ring_lockup_update(struct radeon_ring *ring)
bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring) bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
{ {
unsigned long cjiffies, elapsed; unsigned long cjiffies, elapsed;
uint32_t rptr;
cjiffies = jiffies; cjiffies = jiffies;
if (!time_after(cjiffies, ring->last_activity)) { if (!time_after(cjiffies, ring->last_activity)) {
...@@ -569,8 +593,7 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *rin ...@@ -569,8 +593,7 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *rin
radeon_ring_lockup_update(ring); radeon_ring_lockup_update(ring);
return false; return false;
} }
rptr = RREG32(ring->rptr_reg); ring->rptr = radeon_ring_get_rptr(rdev, ring);
ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
if (ring->rptr != ring->last_rptr) { if (ring->rptr != ring->last_rptr) {
/* CP is still working no lockup */ /* CP is still working no lockup */
radeon_ring_lockup_update(ring); radeon_ring_lockup_update(ring);
...@@ -797,9 +820,9 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data) ...@@ -797,9 +820,9 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data)
radeon_ring_free_size(rdev, ring); radeon_ring_free_size(rdev, ring);
count = (ring->ring_size / 4) - ring->ring_free_dw; count = (ring->ring_size / 4) - ring->ring_free_dw;
tmp = RREG32(ring->wptr_reg) >> ring->ptr_reg_shift; tmp = radeon_ring_get_wptr(rdev, ring);
seq_printf(m, "wptr(0x%04x): 0x%08x [%5d]\n", ring->wptr_reg, tmp, tmp); seq_printf(m, "wptr(0x%04x): 0x%08x [%5d]\n", ring->wptr_reg, tmp, tmp);
tmp = RREG32(ring->rptr_reg) >> ring->ptr_reg_shift; tmp = radeon_ring_get_rptr(rdev, ring);
seq_printf(m, "rptr(0x%04x): 0x%08x [%5d]\n", ring->rptr_reg, tmp, tmp); seq_printf(m, "rptr(0x%04x): 0x%08x [%5d]\n", ring->rptr_reg, tmp, tmp);
if (ring->rptr_save_reg) { if (ring->rptr_save_reg) {
seq_printf(m, "rptr next(0x%04x): 0x%08x\n", ring->rptr_save_reg, seq_printf(m, "rptr next(0x%04x): 0x%08x\n", ring->rptr_save_reg,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment