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

Commit 83c9b025 authored by Emily Deng's avatar Emily Deng Committed by Alex Deucher
Browse files

drm/amdgpu: Disable VGA render and crtc when init GMC.



For virtual display feature, when the GPU has DCE engine, need to disable
the VGA render and CRTC, or it will hang when initialize GMC.

Signed-off-by: default avatarEmily Deng <Emily.Deng@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 0bad1619
Loading
Loading
Loading
Loading
+41 −1
Original line number Diff line number Diff line
@@ -712,6 +712,45 @@ static void dce_v10_0_set_vga_render_state(struct amdgpu_device *adev,
	WREG32(mmVGA_RENDER_CONTROL, tmp);
}

static int dce_v10_0_get_num_crtc(struct amdgpu_device *adev)
{
	int num_crtc = 0;

	switch (adev->asic_type) {
	case CHIP_FIJI:
	case CHIP_TONGA:
		num_crtc = 6;
		break;
	default:
		num_crtc = 0;
	}
	return num_crtc;
}

void dce_v10_0_disable_dce(struct amdgpu_device *adev)
{
	/*Disable VGA render and enabled crtc, if has DCE engine*/
	if (amdgpu_atombios_has_dce_engine_info(adev)) {
		u32 tmp;
		int crtc_enabled, i;

		dce_v10_0_set_vga_render_state(adev, false);

		/*Disable crtc*/
		for (i = 0; i < dce_v10_0_get_num_crtc(adev); i++) {
			crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
									 CRTC_CONTROL, CRTC_MASTER_EN);
			if (crtc_enabled) {
				WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
				tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
				tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
				WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
				WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
			}
		}
	}
}

static void dce_v10_0_program_fmt(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
@@ -2962,10 +3001,11 @@ static int dce_v10_0_early_init(void *handle)
	dce_v10_0_set_display_funcs(adev);
	dce_v10_0_set_irq_funcs(adev);

	adev->mode_info.num_crtc = dce_v10_0_get_num_crtc(adev);

	switch (adev->asic_type) {
	case CHIP_FIJI:
	case CHIP_TONGA:
		adev->mode_info.num_crtc = 6; /* XXX 7??? */
		adev->mode_info.num_hpd = 6;
		adev->mode_info.num_dig = 7;
		break;
+2 −0
Original line number Diff line number Diff line
@@ -26,4 +26,6 @@

extern const struct amd_ip_funcs dce_v10_0_ip_funcs;

void dce_v10_0_disable_dce(struct amdgpu_device *adev);

#endif
+49 −4
Original line number Diff line number Diff line
@@ -673,6 +673,53 @@ static void dce_v11_0_set_vga_render_state(struct amdgpu_device *adev,
	WREG32(mmVGA_RENDER_CONTROL, tmp);
}

static int dce_v11_0_get_num_crtc (struct amdgpu_device *adev)
{
	int num_crtc = 0;

	switch (adev->asic_type) {
	case CHIP_CARRIZO:
		num_crtc = 3;
		break;
	case CHIP_STONEY:
		num_crtc = 2;
		break;
	case CHIP_POLARIS10:
		num_crtc = 6;
		break;
	case CHIP_POLARIS11:
		num_crtc = 5;
		break;
	default:
		num_crtc = 0;
	}
	return num_crtc;
}

void dce_v11_0_disable_dce(struct amdgpu_device *adev)
{
	/*Disable VGA render and enabled crtc, if has DCE engine*/
	if (amdgpu_atombios_has_dce_engine_info(adev)) {
		u32 tmp;
		int crtc_enabled, i;

		dce_v11_0_set_vga_render_state(adev, false);

		/*Disable crtc*/
		for (i = 0; i < dce_v11_0_get_num_crtc(adev); i++) {
			crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
									 CRTC_CONTROL, CRTC_MASTER_EN);
			if (crtc_enabled) {
				WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
				tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
				tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
				WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
				WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
			}
		}
	}
}

static void dce_v11_0_program_fmt(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
@@ -2999,24 +3046,22 @@ static int dce_v11_0_early_init(void *handle)
	dce_v11_0_set_display_funcs(adev);
	dce_v11_0_set_irq_funcs(adev);

	adev->mode_info.num_crtc = dce_v11_0_get_num_crtc(adev);

	switch (adev->asic_type) {
	case CHIP_CARRIZO:
		adev->mode_info.num_crtc = 3;
		adev->mode_info.num_hpd = 6;
		adev->mode_info.num_dig = 9;
		break;
	case CHIP_STONEY:
		adev->mode_info.num_crtc = 2;
		adev->mode_info.num_hpd = 6;
		adev->mode_info.num_dig = 9;
		break;
	case CHIP_POLARIS10:
		adev->mode_info.num_crtc = 6;
		adev->mode_info.num_hpd = 6;
		adev->mode_info.num_dig = 6;
		break;
	case CHIP_POLARIS11:
		adev->mode_info.num_crtc = 5;
		adev->mode_info.num_hpd = 5;
		adev->mode_info.num_dig = 5;
		break;
+2 −0
Original line number Diff line number Diff line
@@ -26,4 +26,6 @@

extern const struct amd_ip_funcs dce_v11_0_ip_funcs;

void dce_v11_0_disable_dce(struct amdgpu_device *adev);

#endif
+48 −3
Original line number Diff line number Diff line
@@ -604,6 +604,52 @@ static void dce_v8_0_set_vga_render_state(struct amdgpu_device *adev,
	WREG32(mmVGA_RENDER_CONTROL, tmp);
}

static int dce_v8_0_get_num_crtc(struct amdgpu_device *adev)
{
	int num_crtc = 0;

	switch (adev->asic_type) {
	case CHIP_BONAIRE:
	case CHIP_HAWAII:
		num_crtc = 6;
		break;
	case CHIP_KAVERI:
		num_crtc = 4;
		break;
	case CHIP_KABINI:
	case CHIP_MULLINS:
		num_crtc = 2;
		break;
	default:
		num_crtc = 0;
	}
	return num_crtc;
}

void dce_v8_0_disable_dce(struct amdgpu_device *adev)
{
	/*Disable VGA render and enabled crtc, if has DCE engine*/
	if (amdgpu_atombios_has_dce_engine_info(adev)) {
		u32 tmp;
		int crtc_enabled, i;

		dce_v8_0_set_vga_render_state(adev, false);

		/*Disable crtc*/
		for (i = 0; i < dce_v8_0_get_num_crtc(adev); i++) {
			crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
									 CRTC_CONTROL, CRTC_MASTER_EN);
			if (crtc_enabled) {
				WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
				tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
				tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
				WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
				WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
			}
		}
	}
}

static void dce_v8_0_program_fmt(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
@@ -2803,21 +2849,20 @@ static int dce_v8_0_early_init(void *handle)
	dce_v8_0_set_display_funcs(adev);
	dce_v8_0_set_irq_funcs(adev);

	adev->mode_info.num_crtc = dce_v8_0_get_num_crtc(adev);

	switch (adev->asic_type) {
	case CHIP_BONAIRE:
	case CHIP_HAWAII:
		adev->mode_info.num_crtc = 6;
		adev->mode_info.num_hpd = 6;
		adev->mode_info.num_dig = 6;
		break;
	case CHIP_KAVERI:
		adev->mode_info.num_crtc = 4;
		adev->mode_info.num_hpd = 6;
		adev->mode_info.num_dig = 7;
		break;
	case CHIP_KABINI:
	case CHIP_MULLINS:
		adev->mode_info.num_crtc = 2;
		adev->mode_info.num_hpd = 6;
		adev->mode_info.num_dig = 6; /* ? */
		break;
Loading