Commit 0c45249f authored by Jerome Glisse's avatar Jerome Glisse Committed by Dave Airlie

drm/radeon/kms: r600/r700 disable irq at suspend

To avoid hw doing anythings after we disabled PCIE GART, fully
disable IRQ at suspend. Also cleanup a bit the ih structure
and process function.
Signed-off-by: default avatarJerome Glisse <jglisse@redhat.com>
Reviewed-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@linux.ie>
parent 615e0cb6
...@@ -1954,6 +1954,7 @@ int r600_suspend(struct radeon_device *rdev) ...@@ -1954,6 +1954,7 @@ int r600_suspend(struct radeon_device *rdev)
/* FIXME: we should wait for ring to be empty */ /* FIXME: we should wait for ring to be empty */
r600_cp_stop(rdev); r600_cp_stop(rdev);
rdev->cp.ready = false; rdev->cp.ready = false;
r600_irq_suspend(rdev);
r600_wb_disable(rdev); r600_wb_disable(rdev);
r600_pcie_gart_disable(rdev); r600_pcie_gart_disable(rdev);
/* unpin shaders bo */ /* unpin shaders bo */
...@@ -2200,14 +2201,14 @@ void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size) ...@@ -2200,14 +2201,14 @@ void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size)
rb_bufsz = drm_order(ring_size / 4); rb_bufsz = drm_order(ring_size / 4);
ring_size = (1 << rb_bufsz) * 4; ring_size = (1 << rb_bufsz) * 4;
rdev->ih.ring_size = ring_size; rdev->ih.ring_size = ring_size;
rdev->ih.align_mask = 4 - 1; rdev->ih.ptr_mask = rdev->ih.ring_size - 1;
rdev->ih.rptr = 0;
} }
static int r600_ih_ring_alloc(struct radeon_device *rdev, unsigned ring_size) static int r600_ih_ring_alloc(struct radeon_device *rdev)
{ {
int r; int r;
rdev->ih.ring_size = ring_size;
/* Allocate ring buffer */ /* Allocate ring buffer */
if (rdev->ih.ring_obj == NULL) { if (rdev->ih.ring_obj == NULL) {
r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size, r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size,
...@@ -2237,9 +2238,6 @@ static int r600_ih_ring_alloc(struct radeon_device *rdev, unsigned ring_size) ...@@ -2237,9 +2238,6 @@ static int r600_ih_ring_alloc(struct radeon_device *rdev, unsigned ring_size)
return r; return r;
} }
} }
rdev->ih.ptr_mask = (rdev->cp.ring_size / 4) - 1;
rdev->ih.rptr = 0;
return 0; return 0;
} }
...@@ -2389,7 +2387,7 @@ int r600_irq_init(struct radeon_device *rdev) ...@@ -2389,7 +2387,7 @@ int r600_irq_init(struct radeon_device *rdev)
u32 interrupt_cntl, ih_cntl, ih_rb_cntl; u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
/* allocate ring */ /* allocate ring */
ret = r600_ih_ring_alloc(rdev, rdev->ih.ring_size); ret = r600_ih_ring_alloc(rdev);
if (ret) if (ret)
return ret; return ret;
...@@ -2452,10 +2450,15 @@ int r600_irq_init(struct radeon_device *rdev) ...@@ -2452,10 +2450,15 @@ int r600_irq_init(struct radeon_device *rdev)
return ret; return ret;
} }
void r600_irq_fini(struct radeon_device *rdev) void r600_irq_suspend(struct radeon_device *rdev)
{ {
r600_disable_interrupts(rdev); r600_disable_interrupts(rdev);
r600_rlc_stop(rdev); r600_rlc_stop(rdev);
}
void r600_irq_fini(struct radeon_device *rdev)
{
r600_irq_suspend(rdev);
r600_ih_ring_fini(rdev); r600_ih_ring_fini(rdev);
} }
...@@ -2648,9 +2651,7 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) ...@@ -2648,9 +2651,7 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev)
tmp |= IH_WPTR_OVERFLOW_CLEAR; tmp |= IH_WPTR_OVERFLOW_CLEAR;
WREG32(IH_RB_CNTL, tmp); WREG32(IH_RB_CNTL, tmp);
} }
wptr = wptr & WPTR_OFFSET_MASK; return (wptr & rdev->ih.ptr_mask);
return wptr;
} }
/* r600 IV Ring /* r600 IV Ring
...@@ -2686,7 +2687,6 @@ int r600_irq_process(struct radeon_device *rdev) ...@@ -2686,7 +2687,6 @@ int r600_irq_process(struct radeon_device *rdev)
u32 wptr = r600_get_ih_wptr(rdev); u32 wptr = r600_get_ih_wptr(rdev);
u32 rptr = rdev->ih.rptr; u32 rptr = rdev->ih.rptr;
u32 src_id, src_data; u32 src_id, src_data;
u32 last_entry = rdev->ih.ring_size - 16;
u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; u32 ring_index, disp_int, disp_int_cont, disp_int_cont2;
unsigned long flags; unsigned long flags;
bool queue_hotplug = false; bool queue_hotplug = false;
...@@ -2820,10 +2820,8 @@ int r600_irq_process(struct radeon_device *rdev) ...@@ -2820,10 +2820,8 @@ int r600_irq_process(struct radeon_device *rdev)
} }
/* wptr/rptr are in bytes! */ /* wptr/rptr are in bytes! */
if (rptr == last_entry) rptr += 16;
rptr = 0; rptr &= rdev->ih.ptr_mask;
else
rptr += 16;
} }
/* make sure wptr hasn't changed while processing */ /* make sure wptr hasn't changed while processing */
wptr = r600_get_ih_wptr(rdev); wptr = r600_get_ih_wptr(rdev);
......
...@@ -410,7 +410,6 @@ struct r600_ih { ...@@ -410,7 +410,6 @@ struct r600_ih {
unsigned wptr_old; unsigned wptr_old;
unsigned ring_size; unsigned ring_size;
uint64_t gpu_addr; uint64_t gpu_addr;
uint32_t align_mask;
uint32_t ptr_mask; uint32_t ptr_mask;
spinlock_t lock; spinlock_t lock;
bool enabled; bool enabled;
...@@ -1162,7 +1161,8 @@ extern int r600_irq_init(struct radeon_device *rdev); ...@@ -1162,7 +1161,8 @@ extern int r600_irq_init(struct radeon_device *rdev);
extern void r600_irq_fini(struct radeon_device *rdev); extern void r600_irq_fini(struct radeon_device *rdev);
extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size); extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size);
extern int r600_irq_set(struct radeon_device *rdev); extern int r600_irq_set(struct radeon_device *rdev);
extern void r600_irq_suspend(struct radeon_device *rdev);
/* r600 audio */
extern int r600_audio_init(struct radeon_device *rdev); extern int r600_audio_init(struct radeon_device *rdev);
extern int r600_audio_tmds_index(struct drm_encoder *encoder); extern int r600_audio_tmds_index(struct drm_encoder *encoder);
extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock); extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
......
...@@ -968,6 +968,7 @@ int rv770_suspend(struct radeon_device *rdev) ...@@ -968,6 +968,7 @@ int rv770_suspend(struct radeon_device *rdev)
/* FIXME: we should wait for ring to be empty */ /* FIXME: we should wait for ring to be empty */
r700_cp_stop(rdev); r700_cp_stop(rdev);
rdev->cp.ready = false; rdev->cp.ready = false;
r600_irq_suspend(rdev);
r600_wb_disable(rdev); r600_wb_disable(rdev);
rv770_pcie_gart_disable(rdev); rv770_pcie_gart_disable(rdev);
/* unpin shaders bo */ /* unpin shaders bo */
......
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