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

Commit 81ee8fb6 authored by Jerome Glisse's avatar Jerome Glisse Committed by Alex Deucher
Browse files

drm/radeon: do not reenable crtc after moving vram start address

It seems we can not update the crtc scanout address. After disabling
crtc, update to base address do not take effect after crtc being
reenable leading to at least frame being scanout from the old crtc
base address. Disabling crtc display request lead to same behavior.

So after changing the vram address if we don't keep crtc disabled
we will have the GPU trying to read some random system memory address
with some iommu this will broke the crtc engine and will lead to
broken display and iommu error message.

So to avoid this, disable crtc. For flicker less boot we will need
to avoid moving the vram start address.

This patch should also fix :

https://bugs.freedesktop.org/show_bug.cgi?id=42373



Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarJerome Glisse <jglisse@redhat.com>
parent 5b23c904
Loading
Loading
Loading
Loading
+0 −57
Original line number Diff line number Diff line
@@ -1229,24 +1229,8 @@ void evergreen_agp_enable(struct radeon_device *rdev)

void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
{
	save->vga_control[0] = RREG32(D1VGA_CONTROL);
	save->vga_control[1] = RREG32(D2VGA_CONTROL);
	save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
	save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
	save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET);
	save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
	if (rdev->num_crtc >= 4) {
		save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL);
		save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL);
		save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
		save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
	}
	if (rdev->num_crtc >= 6) {
		save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL);
		save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL);
		save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
		save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
	}

	/* Stop all video */
	WREG32(VGA_RENDER_CONTROL, 0);
@@ -1357,47 +1341,6 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
	/* Unlock host access */
	WREG32(VGA_HDP_CONTROL, save->vga_hdp_control);
	mdelay(1);
	/* Restore video state */
	WREG32(D1VGA_CONTROL, save->vga_control[0]);
	WREG32(D2VGA_CONTROL, save->vga_control[1]);
	if (rdev->num_crtc >= 4) {
		WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]);
		WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]);
	}
	if (rdev->num_crtc >= 6) {
		WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]);
		WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]);
	}
	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
	if (rdev->num_crtc >= 4) {
		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
	}
	if (rdev->num_crtc >= 6) {
		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
	}
	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]);
	WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]);
	if (rdev->num_crtc >= 4) {
		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]);
		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]);
	}
	if (rdev->num_crtc >= 6) {
		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]);
		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]);
	}
	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
	WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
	if (rdev->num_crtc >= 4) {
		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
	}
	if (rdev->num_crtc >= 6) {
		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
	}
	WREG32(VGA_RENDER_CONTROL, save->vga_render_control);
}

+2 −6
Original line number Diff line number Diff line
@@ -255,13 +255,10 @@ extern int rs690_mc_wait_for_idle(struct radeon_device *rdev);
 * rv515
 */
struct rv515_mc_save {
	u32 d1vga_control;
	u32 d2vga_control;
	u32 vga_render_control;
	u32 vga_hdp_control;
	u32 d1crtc_control;
	u32 d2crtc_control;
};

int rv515_init(struct radeon_device *rdev);
void rv515_fini(struct radeon_device *rdev);
uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg);
@@ -389,11 +386,10 @@ void r700_cp_fini(struct radeon_device *rdev);
 * evergreen
 */
struct evergreen_mc_save {
	u32 vga_control[6];
	u32 vga_render_control;
	u32 vga_hdp_control;
	u32 crtc_control[6];
};

void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev);
int evergreen_init(struct radeon_device *rdev);
void evergreen_fini(struct radeon_device *rdev);
+0 −13
Original line number Diff line number Diff line
@@ -281,12 +281,8 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev)

void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
{
	save->d1vga_control = RREG32(R_000330_D1VGA_CONTROL);
	save->d2vga_control = RREG32(R_000338_D2VGA_CONTROL);
	save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL);
	save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL);
	save->d1crtc_control = RREG32(R_006080_D1CRTC_CONTROL);
	save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL);

	/* Stop all video */
	WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
@@ -311,15 +307,6 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
	/* Unlock host access */
	WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control);
	mdelay(1);
	/* Restore video state */
	WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control);
	WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control);
	WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1);
	WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1);
	WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control);
	WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control);
	WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0);
	WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
	WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control);
}