diff options
author | Jerome Glisse <jglisse@redhat.com> | 2010-01-15 08:44:37 -0500 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2010-01-20 17:42:59 -0500 |
commit | 0c45249f419d8b86abe0e51c6627ca4b085e8c23 (patch) | |
tree | bb50e5f91fbb7c2db683a3d1e84965dc83612acc | |
parent | 615e0cb67968c94fd9e53797985843a5b816dec4 (diff) |
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: Jerome Glisse <jglisse@redhat.com>
Reviewed-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@linux.ie>
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 30 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770.c | 1 |
3 files changed, 17 insertions, 18 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index b3713f61964c..a6a23a9f9a5c 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -1954,6 +1954,7 @@ int r600_suspend(struct radeon_device *rdev) | |||
1954 | /* FIXME: we should wait for ring to be empty */ | 1954 | /* FIXME: we should wait for ring to be empty */ |
1955 | r600_cp_stop(rdev); | 1955 | r600_cp_stop(rdev); |
1956 | rdev->cp.ready = false; | 1956 | rdev->cp.ready = false; |
1957 | r600_irq_suspend(rdev); | ||
1957 | r600_wb_disable(rdev); | 1958 | r600_wb_disable(rdev); |
1958 | r600_pcie_gart_disable(rdev); | 1959 | r600_pcie_gart_disable(rdev); |
1959 | /* unpin shaders bo */ | 1960 | /* unpin shaders bo */ |
@@ -2200,14 +2201,14 @@ void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size) | |||
2200 | rb_bufsz = drm_order(ring_size / 4); | 2201 | rb_bufsz = drm_order(ring_size / 4); |
2201 | ring_size = (1 << rb_bufsz) * 4; | 2202 | ring_size = (1 << rb_bufsz) * 4; |
2202 | rdev->ih.ring_size = ring_size; | 2203 | rdev->ih.ring_size = ring_size; |
2203 | rdev->ih.align_mask = 4 - 1; | 2204 | rdev->ih.ptr_mask = rdev->ih.ring_size - 1; |
2205 | rdev->ih.rptr = 0; | ||
2204 | } | 2206 | } |
2205 | 2207 | ||
2206 | static int r600_ih_ring_alloc(struct radeon_device *rdev, unsigned ring_size) | 2208 | static int r600_ih_ring_alloc(struct radeon_device *rdev) |
2207 | { | 2209 | { |
2208 | int r; | 2210 | int r; |
2209 | 2211 | ||
2210 | rdev->ih.ring_size = ring_size; | ||
2211 | /* Allocate ring buffer */ | 2212 | /* Allocate ring buffer */ |
2212 | if (rdev->ih.ring_obj == NULL) { | 2213 | if (rdev->ih.ring_obj == NULL) { |
2213 | r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size, | 2214 | 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 | return r; | 2238 | return r; |
2238 | } | 2239 | } |
2239 | } | 2240 | } |
2240 | rdev->ih.ptr_mask = (rdev->cp.ring_size / 4) - 1; | ||
2241 | rdev->ih.rptr = 0; | ||
2242 | |||
2243 | return 0; | 2241 | return 0; |
2244 | } | 2242 | } |
2245 | 2243 | ||
@@ -2389,7 +2387,7 @@ int r600_irq_init(struct radeon_device *rdev) | |||
2389 | u32 interrupt_cntl, ih_cntl, ih_rb_cntl; | 2387 | u32 interrupt_cntl, ih_cntl, ih_rb_cntl; |
2390 | 2388 | ||
2391 | /* allocate ring */ | 2389 | /* allocate ring */ |
2392 | ret = r600_ih_ring_alloc(rdev, rdev->ih.ring_size); | 2390 | ret = r600_ih_ring_alloc(rdev); |
2393 | if (ret) | 2391 | if (ret) |
2394 | return ret; | 2392 | return ret; |
2395 | 2393 | ||
@@ -2452,10 +2450,15 @@ int r600_irq_init(struct radeon_device *rdev) | |||
2452 | return ret; | 2450 | return ret; |
2453 | } | 2451 | } |
2454 | 2452 | ||
2455 | void r600_irq_fini(struct radeon_device *rdev) | 2453 | void r600_irq_suspend(struct radeon_device *rdev) |
2456 | { | 2454 | { |
2457 | r600_disable_interrupts(rdev); | 2455 | r600_disable_interrupts(rdev); |
2458 | r600_rlc_stop(rdev); | 2456 | r600_rlc_stop(rdev); |
2457 | } | ||
2458 | |||
2459 | void r600_irq_fini(struct radeon_device *rdev) | ||
2460 | { | ||
2461 | r600_irq_suspend(rdev); | ||
2459 | r600_ih_ring_fini(rdev); | 2462 | r600_ih_ring_fini(rdev); |
2460 | } | 2463 | } |
2461 | 2464 | ||
@@ -2648,9 +2651,7 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) | |||
2648 | tmp |= IH_WPTR_OVERFLOW_CLEAR; | 2651 | tmp |= IH_WPTR_OVERFLOW_CLEAR; |
2649 | WREG32(IH_RB_CNTL, tmp); | 2652 | WREG32(IH_RB_CNTL, tmp); |
2650 | } | 2653 | } |
2651 | wptr = wptr & WPTR_OFFSET_MASK; | 2654 | return (wptr & rdev->ih.ptr_mask); |
2652 | |||
2653 | return wptr; | ||
2654 | } | 2655 | } |
2655 | 2656 | ||
2656 | /* r600 IV Ring | 2657 | /* r600 IV Ring |
@@ -2686,7 +2687,6 @@ int r600_irq_process(struct radeon_device *rdev) | |||
2686 | u32 wptr = r600_get_ih_wptr(rdev); | 2687 | u32 wptr = r600_get_ih_wptr(rdev); |
2687 | u32 rptr = rdev->ih.rptr; | 2688 | u32 rptr = rdev->ih.rptr; |
2688 | u32 src_id, src_data; | 2689 | u32 src_id, src_data; |
2689 | u32 last_entry = rdev->ih.ring_size - 16; | ||
2690 | u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; | 2690 | u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; |
2691 | unsigned long flags; | 2691 | unsigned long flags; |
2692 | bool queue_hotplug = false; | 2692 | bool queue_hotplug = false; |
@@ -2820,10 +2820,8 @@ restart_ih: | |||
2820 | } | 2820 | } |
2821 | 2821 | ||
2822 | /* wptr/rptr are in bytes! */ | 2822 | /* wptr/rptr are in bytes! */ |
2823 | if (rptr == last_entry) | 2823 | rptr += 16; |
2824 | rptr = 0; | 2824 | rptr &= rdev->ih.ptr_mask; |
2825 | else | ||
2826 | rptr += 16; | ||
2827 | } | 2825 | } |
2828 | /* make sure wptr hasn't changed while processing */ | 2826 | /* make sure wptr hasn't changed while processing */ |
2829 | wptr = r600_get_ih_wptr(rdev); | 2827 | wptr = r600_get_ih_wptr(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index c23278240a4e..09c655f3843b 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -410,7 +410,6 @@ struct r600_ih { | |||
410 | unsigned wptr_old; | 410 | unsigned wptr_old; |
411 | unsigned ring_size; | 411 | unsigned ring_size; |
412 | uint64_t gpu_addr; | 412 | uint64_t gpu_addr; |
413 | uint32_t align_mask; | ||
414 | uint32_t ptr_mask; | 413 | uint32_t ptr_mask; |
415 | spinlock_t lock; | 414 | spinlock_t lock; |
416 | bool enabled; | 415 | bool enabled; |
@@ -1162,7 +1161,8 @@ extern int r600_irq_init(struct radeon_device *rdev); | |||
1162 | extern void r600_irq_fini(struct radeon_device *rdev); | 1161 | extern void r600_irq_fini(struct radeon_device *rdev); |
1163 | extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size); | 1162 | extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size); |
1164 | extern int r600_irq_set(struct radeon_device *rdev); | 1163 | extern int r600_irq_set(struct radeon_device *rdev); |
1165 | 1164 | extern void r600_irq_suspend(struct radeon_device *rdev); | |
1165 | /* r600 audio */ | ||
1166 | extern int r600_audio_init(struct radeon_device *rdev); | 1166 | extern int r600_audio_init(struct radeon_device *rdev); |
1167 | extern int r600_audio_tmds_index(struct drm_encoder *encoder); | 1167 | extern int r600_audio_tmds_index(struct drm_encoder *encoder); |
1168 | extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock); | 1168 | extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock); |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index eb065bbe1eeb..c8cf2bc2b911 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -968,6 +968,7 @@ int rv770_suspend(struct radeon_device *rdev) | |||
968 | /* FIXME: we should wait for ring to be empty */ | 968 | /* FIXME: we should wait for ring to be empty */ |
969 | r700_cp_stop(rdev); | 969 | r700_cp_stop(rdev); |
970 | rdev->cp.ready = false; | 970 | rdev->cp.ready = false; |
971 | r600_irq_suspend(rdev); | ||
971 | r600_wb_disable(rdev); | 972 | r600_wb_disable(rdev); |
972 | rv770_pcie_gart_disable(rdev); | 973 | rv770_pcie_gart_disable(rdev); |
973 | /* unpin shaders bo */ | 974 | /* unpin shaders bo */ |