Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55249baa authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Workaround erratum on i830 for TAIL pointer within last 2 cachelines



On i830 if the tail pointer is set to within 2 cachelines of the end of
the buffer, the chip may hang. So instead if the tail were to land in
that location, we pad the end of the buffer with NOPs, and start again
at the beginning.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 35c3047a
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -785,6 +785,14 @@ int intel_init_ring_buffer(struct drm_device *dev,
	if (ret)
		goto err_unmap;

	/* Workaround an erratum on the i830 which causes a hang if
	 * the TAIL pointer points to within the last 2 cachelines
	 * of the buffer.
	 */
	ring->effective_size = ring->size;
	if (IS_I830(ring->dev))
		ring->effective_size -= 128;

	return 0;

err_unmap:
@@ -827,8 +835,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring)
static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring)
{
	unsigned int *virt;
	int rem;
	rem = ring->size - ring->tail;
	int rem = ring->size - ring->tail;

	if (ring->space < rem) {
		int ret = intel_wait_ring_buffer(ring, rem);
@@ -895,7 +902,7 @@ int intel_ring_begin(struct intel_ring_buffer *ring,
	int n = 4*num_dwords;
	int ret;

	if (unlikely(ring->tail + n > ring->size)) {
	if (unlikely(ring->tail + n > ring->effective_size)) {
		ret = intel_wrap_ring_buffer(ring);
		if (unlikely(ret))
			return ret;
+1 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ struct intel_ring_buffer {
	u32		tail;
	int		space;
	int		size;
	int		effective_size;
	struct intel_hw_status_page status_page;

	u32		irq_seqno;		/* last seq seem at irq time */