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

Commit 2f86e2ed authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon: properly lock disp in mc_stop/resume for r5xx-r7xx



Need to wait for the new addresses to take affect before
re-enabling the MC.

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
parent 10257a6d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -358,6 +358,7 @@
#define AVIVO_D1CRTC_STATUS_HV_COUNT                            0x60ac
#define AVIVO_D1CRTC_STEREO_CONTROL                             0x60c4

#define AVIVO_D1MODE_MASTER_UPDATE_LOCK                         0x60e0
#define AVIVO_D1MODE_MASTER_UPDATE_MODE                         0x60e4

/* master controls */
+43 −0
Original line number Diff line number Diff line
@@ -338,6 +338,22 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
	}
	/* wait for the MC to settle */
	udelay(100);

	/* lock double buffered regs */
	for (i = 0; i < rdev->num_crtc; i++) {
		if (save->crtc_enabled[i]) {
			tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]);
			if (!(tmp & AVIVO_D1GRPH_UPDATE_LOCK)) {
				tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
				WREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i], tmp);
			}
			tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i]);
			if (!(tmp & 1)) {
				tmp |= 1;
				WREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
			}
		}
	}
}

void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
@@ -367,6 +383,33 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
	}
	WREG32(R_000310_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);

	/* unlock regs and wait for update */
	for (i = 0; i < rdev->num_crtc; i++) {
		if (save->crtc_enabled[i]) {
			tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i]);
			if ((tmp & 0x3) != 0) {
				tmp &= ~0x3;
				WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i], tmp);
			}
			tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]);
			if (tmp & AVIVO_D1GRPH_UPDATE_LOCK) {
				tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK;
				WREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i], tmp);
			}
			tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i]);
			if (tmp & 1) {
				tmp &= ~1;
				WREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
			}
			for (j = 0; j < rdev->usec_timeout; j++) {
				tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]);
				if ((tmp & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING) == 0)
					break;
				udelay(1);
			}
		}
	}

	if (rdev->family >= CHIP_R600) {
		/* unblackout the MC */
		if (rdev->family >= CHIP_RV770)