Commit 985faf2c authored by Wesley Chalmers's avatar Wesley Chalmers Committed by Alex Deucher
Browse files

drm/amd/display: New sequence for HUBP blank



[WHY]
DCN30 has a bug where blanking HUBP blocks pstate allow unless
HUBP_DISABLE is toggled afterwards.

[HOW]
Create a HW sequence for blanking HUBP.
1. Wait for enter VBLANK
2. Set HUBP_BLANK
3. Make sure HUBP_IN_BLANK = 1
4. Toggle HUBP_DISABLE on and off to perform soft reset

All existing calls to hubp->funcs->set_blank should be replaced with
this new sequence.
In wait_for_mpcc_disconnect, only blank the pipe being disconnected, and
leave all other pipes unmodified.

Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarWesley Chalmers <Wesley.Chalmers@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 36ec5b16
Loading
Loading
Loading
Loading
+29 −7
Original line number Diff line number Diff line
@@ -2624,7 +2624,7 @@ static void dcn10_update_dchubp_dpp(
	hws->funcs.update_plane_addr(dc, pipe_ctx);

	if (is_pipe_tree_visible(pipe_ctx))
		hubp->funcs->set_blank(hubp, false);
		dc->hwss.set_hubp_blank(dc, pipe_ctx, false);
}

void dcn10_blank_pixel_data(
@@ -3135,13 +3135,16 @@ void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc)
	return;
}

static struct hubp *get_hubp_by_inst(struct resource_pool *res_pool, int mpcc_inst)
static struct pipe_ctx *get_pipe_ctx_by_hubp_inst(struct dc_state *context, int mpcc_inst)
{
	int i;

	for (i = 0; i < res_pool->pipe_count; i++) {
		if (res_pool->hubps[i]->inst == mpcc_inst)
			return res_pool->hubps[i];
	for (i = 0; i < MAX_PIPES; i++) {
		if (context->res_ctx.pipe_ctx[i].plane_res.hubp
				&& context->res_ctx.pipe_ctx[i].plane_res.hubp->inst == mpcc_inst) {
			return &context->res_ctx.pipe_ctx[i];
		}

	}
	ASSERT(false);
	return NULL;
@@ -3164,11 +3167,23 @@ void dcn10_wait_for_mpcc_disconnect(

	for (mpcc_inst = 0; mpcc_inst < MAX_PIPES; mpcc_inst++) {
		if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst]) {
			struct hubp *hubp = get_hubp_by_inst(res_pool, mpcc_inst);
			struct pipe_ctx *restore_bottom_pipe;
			struct pipe_ctx *restore_top_pipe;
			struct pipe_ctx *inst_pipe_ctx = get_pipe_ctx_by_hubp_inst(dc->current_state, mpcc_inst);

			ASSERT(inst_pipe_ctx);
			res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst);
			pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false;
			hubp->funcs->set_blank(hubp, true);
			/*
			 * Set top and bottom pipes NULL, as we don't want
			 * to blank those pipes when disconnecting from MPCC
			 */
			restore_bottom_pipe = inst_pipe_ctx->bottom_pipe;
			restore_top_pipe = inst_pipe_ctx->top_pipe;
			inst_pipe_ctx->top_pipe = inst_pipe_ctx->bottom_pipe = NULL;
			dc->hwss.set_hubp_blank(dc, inst_pipe_ctx, true);
			inst_pipe_ctx->top_pipe = restore_top_pipe;
			inst_pipe_ctx->bottom_pipe = restore_bottom_pipe;
		}
	}

@@ -3721,3 +3736,10 @@ void dcn10_get_clock(struct dc *dc,
				dc->clk_mgr->funcs->get_clock(dc->clk_mgr, context, clock_type, clock_cfg);

}

void dcn10_set_hubp_blank(const struct dc *dc,
				struct pipe_ctx *pipe_ctx,
				bool blank_enable)
{
	pipe_ctx->plane_res.hubp->funcs->set_blank(pipe_ctx->plane_res.hubp, blank_enable);
}
+3 −0
Original line number Diff line number Diff line
@@ -204,5 +204,8 @@ void dcn10_wait_for_pending_cleared(struct dc *dc,
		struct dc_state *context);
void dcn10_set_hdr_multiplier(struct pipe_ctx *pipe_ctx);
void dcn10_verify_allow_pstate_change_high(struct dc *dc);
void dcn10_set_hubp_blank(const struct dc *dc,
				struct pipe_ctx *pipe_ctx,
				bool blank_enable);

#endif /* __DC_HWSS_DCN10_H__ */
+1 −0
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
	.set_backlight_level = dce110_set_backlight_level,
	.set_abm_immediate_disable = dce110_set_abm_immediate_disable,
	.set_pipe = dce110_set_pipe,
	.set_hubp_blank = dcn10_set_hubp_blank,
};

static const struct hwseq_private_funcs dcn10_private_funcs = {
+1 −1
Original line number Diff line number Diff line
@@ -1571,7 +1571,7 @@ static void dcn20_update_dchubp_dpp(


	if (is_pipe_tree_visible(pipe_ctx))
		hubp->funcs->set_blank(hubp, false);
		dc->hwss.set_hubp_blank(dc, pipe_ctx, false);
}


+1 −0
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
	.optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft,
#endif
	.set_disp_pattern_generator = dcn20_set_disp_pattern_generator,
	.set_hubp_blank = dcn10_set_hubp_blank,
};

static const struct hwseq_private_funcs dcn20_private_funcs = {
Loading