aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-01-15 08:44:37 -0500
committerDave Airlie <airlied@linux.ie>2010-01-20 17:42:59 -0500
commit0c45249f419d8b86abe0e51c6627ca4b085e8c23 (patch)
treebb50e5f91fbb7c2db683a3d1e84965dc83612acc
parent615e0cb67968c94fd9e53797985843a5b816dec4 (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.c30
-rw-r--r--drivers/gpu/drm/radeon/radeon.h4
-rw-r--r--drivers/gpu/drm/radeon/rv770.c1
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
2206static int r600_ih_ring_alloc(struct radeon_device *rdev, unsigned ring_size) 2208static 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
2455void r600_irq_fini(struct radeon_device *rdev) 2453void 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
2459void 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);
1162extern void r600_irq_fini(struct radeon_device *rdev); 1161extern void r600_irq_fini(struct radeon_device *rdev);
1163extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size); 1162extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size);
1164extern int r600_irq_set(struct radeon_device *rdev); 1163extern int r600_irq_set(struct radeon_device *rdev);
1165 1164extern void r600_irq_suspend(struct radeon_device *rdev);
1165/* r600 audio */
1166extern int r600_audio_init(struct radeon_device *rdev); 1166extern int r600_audio_init(struct radeon_device *rdev);
1167extern int r600_audio_tmds_index(struct drm_encoder *encoder); 1167extern int r600_audio_tmds_index(struct drm_encoder *encoder);
1168extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock); 1168extern 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 */