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 /drivers/gpu/drm/radeon/r600.c | |
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>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 30 |
1 files changed, 14 insertions, 16 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); |