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

Commit 968c0166 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon: properly lock disp in mc_stop/resume for evergreen+



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 2f86e2ed
Loading
Loading
Loading
Loading
+43 −4
Original line number Original line Diff line number Diff line
@@ -1575,18 +1575,14 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
				if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) {
				if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) {
					radeon_wait_for_vblank(rdev, i);
					radeon_wait_for_vblank(rdev, i);
					tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
					tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
					WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
					WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
				}
				}
			} else {
			} else {
				tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
				tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
				if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) {
				if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) {
					radeon_wait_for_vblank(rdev, i);
					radeon_wait_for_vblank(rdev, i);
					tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
					tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
					WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
					WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
				}
				}
			}
			}
			/* wait for the next frame */
			/* wait for the next frame */
@@ -1613,6 +1609,22 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
	}
	}
	/* wait for the MC to settle */
	/* wait for the MC to settle */
	udelay(100);
	udelay(100);

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


void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
@@ -1634,6 +1646,33 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
	WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start));
	WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start));
	WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
	WREG32(EVERGREEN_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(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i]);
			if ((tmp & 0x3) != 0) {
				tmp &= ~0x3;
				WREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i], tmp);
			}
			tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
			if (tmp & EVERGREEN_GRPH_UPDATE_LOCK) {
				tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK;
				WREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i], tmp);
			}
			tmp = RREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i]);
			if (tmp & 1) {
				tmp &= ~1;
				WREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
			}
			for (j = 0; j < rdev->usec_timeout; j++) {
				tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
				if ((tmp & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING) == 0)
					break;
				udelay(1);
			}
		}
	}

	/* unblackout the MC */
	/* unblackout the MC */
	tmp = RREG32(MC_SHARED_BLACKOUT_CNTL);
	tmp = RREG32(MC_SHARED_BLACKOUT_CNTL);
	tmp &= ~BLACKOUT_MODE_MASK;
	tmp &= ~BLACKOUT_MODE_MASK;
+2 −0
Original line number Original line Diff line number Diff line
@@ -226,6 +226,8 @@
#define EVERGREEN_CRTC_STATUS_HV_COUNT                  0x6ea0
#define EVERGREEN_CRTC_STATUS_HV_COUNT                  0x6ea0
#define EVERGREEN_MASTER_UPDATE_MODE                    0x6ef8
#define EVERGREEN_MASTER_UPDATE_MODE                    0x6ef8
#define EVERGREEN_CRTC_UPDATE_LOCK                      0x6ed4
#define EVERGREEN_CRTC_UPDATE_LOCK                      0x6ed4
#define EVERGREEN_MASTER_UPDATE_LOCK                    0x6ef4
#define EVERGREEN_MASTER_UPDATE_MODE                    0x6ef8


#define EVERGREEN_DC_GPIO_HPD_MASK                      0x64b0
#define EVERGREEN_DC_GPIO_HPD_MASK                      0x64b0
#define EVERGREEN_DC_GPIO_HPD_A                         0x64b4
#define EVERGREEN_DC_GPIO_HPD_A                         0x64b4