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

Commit aadd4e17 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie
Browse files

drm/radeon: some r420s have a CP race with the DMA engine.



This patch makes sure the CP doesn't DMA do VRAM while 2D
is active by inserting a CP resync token.

todo: port to kms.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 5a6e9f96
Loading
Loading
Loading
Loading
+23 −0
Original line number Original line Diff line number Diff line
@@ -616,6 +616,18 @@ static void radeon_do_cp_start(drm_radeon_private_t * dev_priv)


	dev_priv->cp_running = 1;
	dev_priv->cp_running = 1;


	/* on r420, any DMA from CP to system memory while 2D is active
	 * can cause a hang.  workaround is to queue a CP RESYNC token
	 */
	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) {
		BEGIN_RING(3);
		OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1));
		OUT_RING(5); /* scratch reg 5 */
		OUT_RING(0xdeadbeef);
		ADVANCE_RING();
		COMMIT_RING();
	}

	BEGIN_RING(8);
	BEGIN_RING(8);
	/* isync can only be written through cp on r5xx write it here */
	/* isync can only be written through cp on r5xx write it here */
	OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0));
	OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0));
@@ -653,8 +665,19 @@ static void radeon_do_cp_reset(drm_radeon_private_t * dev_priv)
 */
 */
static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
{
{
	RING_LOCALS;
	DRM_DEBUG("\n");
	DRM_DEBUG("\n");


	/* finish the pending CP_RESYNC token */
	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) {
		BEGIN_RING(2);
		OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
		OUT_RING(R300_RB3D_DC_FINISH);
		ADVANCE_RING();
		COMMIT_RING();
		radeon_do_wait_for_idle(dev_priv);
	}

	RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS);
	RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS);


	dev_priv->cp_running = 0;
	dev_priv->cp_running = 0;
+3 −0
Original line number Original line Diff line number Diff line
@@ -1099,6 +1099,9 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
#	define RADEON_CSQ_PRIBM_INDBM		(4 << 28)
#	define RADEON_CSQ_PRIBM_INDBM		(4 << 28)
#	define RADEON_CSQ_PRIPIO_INDPIO		(15 << 28)
#	define RADEON_CSQ_PRIPIO_INDPIO		(15 << 28)


#define R300_CP_RESYNC_ADDR		0x0778
#define R300_CP_RESYNC_DATA		0x077c

#define RADEON_AIC_CNTL			0x01d0
#define RADEON_AIC_CNTL			0x01d0
#	define RADEON_PCIGART_TRANSLATE_EN	(1 << 0)
#	define RADEON_PCIGART_TRANSLATE_EN	(1 << 0)
#	define RS400_MSI_REARM	                (1 << 3)
#	define RS400_MSI_REARM	                (1 << 3)