Commit dd15640b authored by Becle Lee's avatar Becle Lee Committed by Alex Deucher
Browse files

drm/amd/display: Wait for hubp read line for Pollock



[Why]
Underflow occurred while hubp ret pipe read is idle and the
second pipe is powered up and added. Flickering and underflow
are only observed on Pollock.

[How]
Check the hubp ret pipe read prior to unlock pipes.

Reviewed-by: default avatarHersen Wu <hersenxs.wu@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarAgustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: default avatarBecle Lee <becle.lee@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 2716bc82
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -1311,6 +1311,20 @@ void hubp1_set_flip_int(struct hubp *hubp)
	return;
}

/**
 * hubp1_wait_pipe_read_start - wait for hubp ret path starting read.
 *
 * @hubp: hubp struct reference.
 */
void hubp1_wait_pipe_read_start(struct hubp *hubp)
{
	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);

	REG_WAIT(HUBPRET_READ_LINE_STATUS,
		PIPE_READ_VBLANK, 0,
		 1, 1000);
}

void hubp1_init(struct hubp *hubp)
{
	//do nothing
@@ -1345,6 +1359,7 @@ static const struct hubp_funcs dcn10_hubp_funcs = {
	.hubp_soft_reset = hubp1_soft_reset,
	.hubp_in_blank = hubp1_in_blank,
	.hubp_set_flip_int = hubp1_set_flip_int,
	.hubp_wait_pipe_read_start = hubp1_wait_pipe_read_start,
};

/*****************************************/
+4 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@
	SRI(DCSURF_SURFACE_CONTROL, HUBPREQ, id),\
	SRI(DCSURF_SURFACE_FLIP_INTERRUPT, HUBPREQ, id),\
	SRI(HUBPRET_CONTROL, HUBPRET, id),\
	SRI(HUBPRET_READ_LINE_STATUS, HUBPRET, id),\
	SRI(DCN_EXPANSION_MODE, HUBPREQ, id),\
	SRI(DCHUBP_REQ_SIZE_CONFIG, HUBP, id),\
	SRI(DCHUBP_REQ_SIZE_CONFIG_C, HUBP, id),\
@@ -186,6 +187,7 @@
	uint32_t DCSURF_SURFACE_CONTROL; \
	uint32_t DCSURF_SURFACE_FLIP_INTERRUPT; \
	uint32_t HUBPRET_CONTROL; \
	uint32_t HUBPRET_READ_LINE_STATUS; \
	uint32_t DCN_EXPANSION_MODE; \
	uint32_t DCHUBP_REQ_SIZE_CONFIG; \
	uint32_t DCHUBP_REQ_SIZE_CONFIG_C; \
@@ -338,6 +340,7 @@
	HUBP_SF(HUBPRET0_HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, mask_sh),\
	HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CB_B, mask_sh),\
	HUBP_SF(HUBPRET0_HUBPRET_CONTROL, CROSSBAR_SRC_CR_R, mask_sh),\
	HUBP_SF(HUBPRET0_HUBPRET_READ_LINE_STATUS, PIPE_READ_VBLANK, mask_sh),\
	HUBP_SF(HUBPREQ0_DCN_EXPANSION_MODE, DRQ_EXPANSION_MODE, mask_sh),\
	HUBP_SF(HUBPREQ0_DCN_EXPANSION_MODE, PRQ_EXPANSION_MODE, mask_sh),\
	HUBP_SF(HUBPREQ0_DCN_EXPANSION_MODE, MRQ_EXPANSION_MODE, mask_sh),\
@@ -538,6 +541,7 @@
	type DET_BUF_PLANE1_BASE_ADDRESS;\
	type CROSSBAR_SRC_CB_B;\
	type CROSSBAR_SRC_CR_R;\
	type PIPE_READ_VBLANK;\
	type DRQ_EXPANSION_MODE;\
	type PRQ_EXPANSION_MODE;\
	type MRQ_EXPANSION_MODE;\
+15 −0
Original line number Diff line number Diff line
@@ -863,6 +863,21 @@ static struct dce_hwseq *dcn10_hwseq_create(
		hws->wa.DEGVIDCN10_253 = true;
		hws->wa.false_optc_underflow = true;
		hws->wa.DEGVIDCN10_254 = true;

		if ((ctx->asic_id.chip_family == FAMILY_RV) &&
			ASICREV_IS_RAVEN2(ctx->asic_id.hw_internal_rev))
			switch (ctx->asic_id.pci_revision_id) {
			case PRID_POLLOCK_94:
			case PRID_POLLOCK_95:
			case PRID_POLLOCK_E9:
			case PRID_POLLOCK_EA:
			case PRID_POLLOCK_EB:
				hws->wa.wait_hubpret_read_start_during_mpo_transition = true;
				break;
			default:
				hws->wa.wait_hubpret_read_start_during_mpo_transition = false;
				break;
			}
	}
	return hws;
}
+10 −0
Original line number Diff line number Diff line
@@ -1739,6 +1739,16 @@ void dcn20_program_front_end_for_ctx(
					|| pipe->stream->update_flags.raw)
				&& hws->funcs.program_all_writeback_pipes_in_tree)
			hws->funcs.program_all_writeback_pipes_in_tree(dc, pipe->stream, context);

		/* Avoid underflow by check of pipe line read when adding 2nd plane. */
		if (hws->wa.wait_hubpret_read_start_during_mpo_transition &&
			!pipe->top_pipe &&
			pipe->stream &&
			pipe->plane_res.hubp->funcs->hubp_wait_pipe_read_start &&
			dc->current_state->stream_status[0].plane_count == 1 &&
			context->stream_status[0].plane_count > 1) {
			pipe->plane_res.hubp->funcs->hubp_wait_pipe_read_start(pipe->plane_res.hubp);
		}
	}
}

+1 −0
Original line number Diff line number Diff line
@@ -195,6 +195,7 @@ struct hubp_funcs {

	void (*hubp_set_flip_int)(struct hubp *hubp);

	void (*hubp_wait_pipe_read_start)(struct hubp *hubp);
};

#endif
Loading