Commit ab23db6d authored by Alexandre Demers's avatar Alexandre Demers Committed by Alex Deucher
Browse files

drm/amdgpu: add dce_v6_0_soft_reset() to DCE6



DCE6 was missing soft reset, but it was easily identifiable under radeon.
This should be it, pretty much as it is done under DCE8 and DCE10.

Signed-off-by: default avatarAlexandre Demers <alexandre.f.demers@gmail.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5f6021d5
Loading
Loading
Loading
Loading
+51 −2
Original line number Diff line number Diff line
@@ -371,13 +371,41 @@ static u32 dce_v6_0_hpd_get_gpio_reg(struct amdgpu_device *adev)
	return mmDC_GPIO_HPD_A;
}

static bool dce_v6_0_is_display_hung(struct amdgpu_device *adev)
{
	u32 crtc_hung = 0;
	u32 crtc_status[6];
	u32 i, j, tmp;

	for (i = 0; i < adev->mode_info.num_crtc; i++) {
		if (RREG32(mmCRTC_CONTROL + crtc_offsets[i]) & CRTC_CONTROL__CRTC_MASTER_EN_MASK) {
			crtc_status[i] = RREG32(mmCRTC_STATUS_HV_COUNT + crtc_offsets[i]);
			crtc_hung |= (1 << i);
		}
	}

	for (j = 0; j < 10; j++) {
		for (i = 0; i < adev->mode_info.num_crtc; i++) {
			if (crtc_hung & (1 << i)) {
				tmp = RREG32(mmCRTC_STATUS_HV_COUNT + crtc_offsets[i]);
				if (tmp != crtc_status[i])
					crtc_hung &= ~(1 << i);
			}
		}
		if (crtc_hung == 0)
			return false;
		udelay(100);
	}

	return true;
}

static void dce_v6_0_set_vga_render_state(struct amdgpu_device *adev,
					  bool render)
{
	if (!render)
		WREG32(mmVGA_RENDER_CONTROL,
			RREG32(mmVGA_RENDER_CONTROL) & VGA_VSTATUS_CNTL);

}

static int dce_v6_0_get_num_crtc(struct amdgpu_device *adev)
@@ -2886,7 +2914,28 @@ static bool dce_v6_0_is_idle(struct amdgpu_ip_block *ip_block)

static int dce_v6_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
	DRM_INFO("xxxx: dce_v6_0_soft_reset --- no impl!!\n");
	u32 srbm_soft_reset = 0, tmp;
	struct amdgpu_device *adev = ip_block->adev;

	if (dce_v6_0_is_display_hung(adev))
		srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_DC_MASK;

	if (srbm_soft_reset) {
		tmp = RREG32(mmSRBM_SOFT_RESET);
		tmp |= srbm_soft_reset;
		dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
		WREG32(mmSRBM_SOFT_RESET, tmp);
		tmp = RREG32(mmSRBM_SOFT_RESET);

		udelay(50);

		tmp &= ~srbm_soft_reset;
		WREG32(mmSRBM_SOFT_RESET, tmp);
		tmp = RREG32(mmSRBM_SOFT_RESET);

		/* Wait a little for things to settle down */
		udelay(50);
	}
	return 0;
}