Commit 6ecf9773 authored by Hung, Cruise's avatar Hung, Cruise Committed by Alex Deucher
Browse files

drm/amd/display: Fix DMUB outbox trace in S4 (#4465)



[Why]
DMUB Outbox0 read/write pointer not sync after resumed from S4.
And that caused old traces were sent to outbox.

[How]
Disable DMUB Outbox0 interrupt
and clear DMUB Outbox0 read/write pointer when resumes from S4.
And then enable Outbox0 interrupt before starts DMCUB.

Reviewed-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: default avatarJasdeep Dhillon <jdhillon@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarCruise Hung <Cruise.Hung@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 92909cde
Loading
Loading
Loading
Loading
+29 −32
Original line number Diff line number Diff line
@@ -513,12 +513,10 @@ void dccg31_set_physymclk(
/* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
static void dccg31_set_dtbclk_dto(
		struct dccg *dccg,
		int dtbclk_inst,
		int req_dtbclk_khz,
		int num_odm_segments,
		const struct dc_crtc_timing *timing)
		struct dtbclk_dto_params *params)
{
	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
	int req_dtbclk_khz = params->pixclk_khz;
	uint32_t dtbdto_div;

	/* Mode	                DTBDTO Rate       DTBCLK_DTO<x>_DIV Register
@@ -529,57 +527,56 @@ static void dccg31_set_dtbclk_dto(
	 * DSC native 4:2:2     pixel rate/2      4
	 * Other modes          pixel rate        8
	 */
	if (num_odm_segments == 4) {
	if (params->num_odm_segments == 4) {
		dtbdto_div = 2;
		req_dtbclk_khz = req_dtbclk_khz / 4;
	} else if ((num_odm_segments == 2) ||
			(timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ||
			(timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
					&& !timing->dsc_cfg.ycbcr422_simple)) {
		req_dtbclk_khz = params->pixclk_khz / 4;
	} else if ((params->num_odm_segments == 2) ||
			(params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ||
			(params->timing->flags.DSC && params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
					&& !params->timing->dsc_cfg.ycbcr422_simple)) {
		dtbdto_div = 4;
		req_dtbclk_khz = req_dtbclk_khz / 2;
		req_dtbclk_khz = params->pixclk_khz / 2;
	} else
		dtbdto_div = 8;

	if (dccg->ref_dtbclk_khz && req_dtbclk_khz) {
	if (params->ref_dtbclk_khz && req_dtbclk_khz) {
		uint32_t modulo, phase;

		// phase / modulo = dtbclk / dtbclk ref
		modulo = dccg->ref_dtbclk_khz * 1000;
		phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + dccg->ref_dtbclk_khz - 1),
			dccg->ref_dtbclk_khz);
		modulo = params->ref_dtbclk_khz * 1000;
		phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + params->ref_dtbclk_khz - 1),
				params->ref_dtbclk_khz);

		REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
				DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div);
		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
				DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div);

		REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], modulo);
		REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], phase);
		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);

		REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
				DTBCLK_DTO_ENABLE[dtbclk_inst], 1);
		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
				DTBCLK_DTO_ENABLE[params->otg_inst], 1);

		REG_WAIT(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
				DTBCLKDTO_ENABLE_STATUS[dtbclk_inst], 1,
		REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
				DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
				1, 100);

		/* The recommended programming sequence to enable DTBCLK DTO to generate
		 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
		 * be set only after DTO is enabled
		 */
		REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
				PIPE_DTO_SRC_SEL[dtbclk_inst], 1);

		dccg->dtbclk_khz[dtbclk_inst] = req_dtbclk_khz;
		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
				PIPE_DTO_SRC_SEL[params->otg_inst], 1);
	} else {
		REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
				DTBCLK_DTO_ENABLE[dtbclk_inst], 0,
				PIPE_DTO_SRC_SEL[dtbclk_inst], 0,
				DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div);
		REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[params->otg_inst],
				DTBCLK_DTO_ENABLE[params->otg_inst], 0,
				PIPE_DTO_SRC_SEL[params->otg_inst], 0,
				DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div);

		REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], 0);
		REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], 0);

		dccg->dtbclk_khz[dtbclk_inst] = 0;
		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
	}
}

+2 −0
Original line number Diff line number Diff line
@@ -132,6 +132,8 @@ void dmub_dcn31_reset(struct dmub_srv *dmub)
	REG_WRITE(DMCUB_INBOX1_WPTR, 0);
	REG_WRITE(DMCUB_OUTBOX1_RPTR, 0);
	REG_WRITE(DMCUB_OUTBOX1_WPTR, 0);
	REG_WRITE(DMCUB_OUTBOX0_RPTR, 0);
	REG_WRITE(DMCUB_OUTBOX0_WPTR, 0);
	REG_WRITE(DMCUB_SCRATCH0, 0);

	/* Clear the GPINT command manually so we don't send anything during boot. */