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

Commit 0c45249f authored by Jerome Glisse's avatar Jerome Glisse Committed by Dave Airlie
Browse files

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: default avatarJerome Glisse <jglisse@redhat.com>
Reviewed-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@linux.ie>
parent 615e0cb6
Loading
Loading
Loading
Loading
+14 −16
Original line number Diff line number Diff line
@@ -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 &= rdev->ih.ptr_mask;
	}
	/* make sure wptr hasn't changed while processing */
	wptr = r600_get_ih_wptr(rdev);
+2 −2
Original line number Diff line number Diff line
@@ -410,7 +410,6 @@ struct r600_ih {
	unsigned		wptr_old;
	unsigned		ring_size;
	uint64_t		gpu_addr;
	uint32_t		align_mask;
	uint32_t		ptr_mask;
	spinlock_t              lock;
	bool                    enabled;
@@ -1162,7 +1161,8 @@ extern int r600_irq_init(struct radeon_device *rdev);
extern void r600_irq_fini(struct radeon_device *rdev);
extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size);
extern int r600_irq_set(struct radeon_device *rdev);

extern void r600_irq_suspend(struct radeon_device *rdev);
/* r600 audio */
extern int r600_audio_init(struct radeon_device *rdev);
extern int r600_audio_tmds_index(struct drm_encoder *encoder);
extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
+1 −0
Original line number Diff line number Diff line
@@ -968,6 +968,7 @@ int rv770_suspend(struct radeon_device *rdev)
	/* FIXME: we should wait for ring to be empty */
	r700_cp_stop(rdev);
	rdev->cp.ready = false;
	r600_irq_suspend(rdev);
	r600_wb_disable(rdev);
	rv770_pcie_gart_disable(rdev);
	/* unpin shaders bo */