|
@@ -1954,6 +1954,7 @@ int r600_suspend(struct radeon_device *rdev)
|
|
|
/* FIXME: we should wait for ring to be empty */
|
|
|
r600_cp_stop(rdev);
|
|
|
rdev->cp.ready = false;
|
|
|
+ r600_irq_suspend(rdev);
|
|
|
r600_wb_disable(rdev);
|
|
|
r600_pcie_gart_disable(rdev);
|
|
|
/* unpin shaders bo */
|
|
@@ -2200,14 +2201,14 @@ void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size)
|
|
|
rb_bufsz = drm_order(ring_size / 4);
|
|
|
ring_size = (1 << rb_bufsz) * 4;
|
|
|
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;
|
|
|
|
|
|
- rdev->ih.ring_size = ring_size;
|
|
|
/* Allocate ring buffer */
|
|
|
if (rdev->ih.ring_obj == NULL) {
|
|
|
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)
|
|
|
return r;
|
|
|
}
|
|
|
}
|
|
|
- rdev->ih.ptr_mask = (rdev->cp.ring_size / 4) - 1;
|
|
|
- rdev->ih.rptr = 0;
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2389,7 +2387,7 @@ int r600_irq_init(struct radeon_device *rdev)
|
|
|
u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
|
|
|
|
|
|
/* allocate ring */
|
|
|
- ret = r600_ih_ring_alloc(rdev, rdev->ih.ring_size);
|
|
|
+ ret = r600_ih_ring_alloc(rdev);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
@@ -2452,10 +2450,15 @@ int r600_irq_init(struct radeon_device *rdev)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-void r600_irq_fini(struct radeon_device *rdev)
|
|
|
+void r600_irq_suspend(struct radeon_device *rdev)
|
|
|
{
|
|
|
r600_disable_interrupts(rdev);
|
|
|
r600_rlc_stop(rdev);
|
|
|
+}
|
|
|
+
|
|
|
+void r600_irq_fini(struct radeon_device *rdev)
|
|
|
+{
|
|
|
+ r600_irq_suspend(rdev);
|
|
|
r600_ih_ring_fini(rdev);
|
|
|
}
|
|
|
|
|
@@ -2648,9 +2651,7 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev)
|
|
|
tmp |= IH_WPTR_OVERFLOW_CLEAR;
|
|
|
WREG32(IH_RB_CNTL, tmp);
|
|
|
}
|
|
|
- wptr = wptr & WPTR_OFFSET_MASK;
|
|
|
-
|
|
|
- return wptr;
|
|
|
+ return (wptr & rdev->ih.ptr_mask);
|
|
|
}
|
|
|
|
|
|
/* r600 IV Ring
|
|
@@ -2686,7 +2687,6 @@ int r600_irq_process(struct radeon_device *rdev)
|
|
|
u32 wptr = r600_get_ih_wptr(rdev);
|
|
|
u32 rptr = rdev->ih.rptr;
|
|
|
u32 src_id, src_data;
|
|
|
- u32 last_entry = rdev->ih.ring_size - 16;
|
|
|
u32 ring_index, disp_int, disp_int_cont, disp_int_cont2;
|
|
|
unsigned long flags;
|
|
|
bool queue_hotplug = false;
|
|
@@ -2820,10 +2820,8 @@ restart_ih:
|
|
|
}
|
|
|
|
|
|
/* wptr/rptr are in bytes! */
|
|
|
- if (rptr == last_entry)
|
|
|
- rptr = 0;
|
|
|
- else
|
|
|
- rptr += 16;
|
|
|
+ rptr += 16;
|
|
|
+ rptr &= rdev->ih.ptr_mask;
|
|
|
}
|
|
|
/* make sure wptr hasn't changed while processing */
|
|
|
wptr = r600_get_ih_wptr(rdev);
|