Commit e8702d0b authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher
Browse files

drm/amd/display: add enable/disable dp link output to link_hwss



[why]
Factor enable/disable dp link output to link hwss.

Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Acked-by: default avatarWayne Lin <wayne.lin@amd.com>
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 2426d71c
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -4016,8 +4016,10 @@ static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pi
	decide_link_settings(stream, &link_settings);
	decide_link_settings(stream, &link_settings);
	stream->link->cur_link_settings = link_settings;
	stream->link->cur_link_settings = link_settings;


	/*  Enable clock, Configure lane count, and Enable Link Encoder*/
	if (link_hwss->ext.enable_dp_link_output)
	enable_dp_hpo_output(stream->link, &pipe_ctx->link_res, &stream->link->cur_link_settings);
		link_hwss->ext.enable_dp_link_output(stream->link, &pipe_ctx->link_res,
				stream->signal, pipe_ctx->clock_source->id,
				&link_settings);


#ifdef DIAGS_BUILD
#ifdef DIAGS_BUILD
	/* Workaround for FPGA HPO capture DP link data:
	/* Workaround for FPGA HPO capture DP link data:
+127 −129
Original line number Original line Diff line number Diff line
@@ -76,19 +76,15 @@ void dp_enable_link_phy(
	enum clock_source_id clock_source,
	enum clock_source_id clock_source,
	const struct dc_link_settings *link_settings)
	const struct dc_link_settings *link_settings)
{
{
	struct link_encoder *link_enc;
	struct dc  *dc = link->ctx->dc;
	struct dc  *dc = link->ctx->dc;
	struct dmcu *dmcu = dc->res_pool->dmcu;
	struct dmcu *dmcu = dc->res_pool->dmcu;

	struct pipe_ctx *pipes =
	struct pipe_ctx *pipes =
			link->dc->current_state->res_ctx.pipe_ctx;
			link->dc->current_state->res_ctx.pipe_ctx;
	struct clock_source *dp_cs =
	struct clock_source *dp_cs =
			link->dc->res_pool->dp_clock_source;
			link->dc->res_pool->dp_clock_source;
	const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
	unsigned int i;
	unsigned int i;


	link_enc = link_enc_cfg_get_link_enc(link);
	ASSERT(link_enc);

	if (link->connector_signal == SIGNAL_TYPE_EDP) {
	if (link->connector_signal == SIGNAL_TYPE_EDP) {
		link->dc->hwss.edp_power_control(link, true);
		link->dc->hwss.edp_power_control(link, true);
		link->dc->hwss.edp_wait_for_hpd_ready(link, true);
		link->dc->hwss.edp_wait_for_hpd_ready(link, true);
@@ -126,21 +122,9 @@ void dp_enable_link_phy(
	if (dmcu != NULL && dmcu->funcs->lock_phy)
	if (dmcu != NULL && dmcu->funcs->lock_phy)
		dmcu->funcs->lock_phy(dmcu);
		dmcu->funcs->lock_phy(dmcu);


	if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
	if (link_hwss->ext.enable_dp_link_output)
		enable_dp_hpo_output(link, link_res, link_settings);
		link_hwss->ext.enable_dp_link_output(link, link_res, signal,
	} else if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
				clock_source, link_settings);
		if (dc_is_dp_sst_signal(signal)) {
			link_enc->funcs->enable_dp_output(
					link_enc,
					link_settings,
					clock_source);
		} else {
			link_enc->funcs->enable_dp_mst_output(
					link_enc,
					link_settings,
					clock_source);
		}
	}


	if (dmcu != NULL && dmcu->funcs->unlock_phy)
	if (dmcu != NULL && dmcu->funcs->unlock_phy)
		dmcu->funcs->unlock_phy(dmcu);
		dmcu->funcs->unlock_phy(dmcu);
@@ -221,11 +205,7 @@ void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_
{
{
	struct dc  *dc = link->ctx->dc;
	struct dc  *dc = link->ctx->dc;
	struct dmcu *dmcu = dc->res_pool->dmcu;
	struct dmcu *dmcu = dc->res_pool->dmcu;
	struct hpo_dp_link_encoder *hpo_link_enc = link_res->hpo_dp_link_enc;
	const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
	struct link_encoder *link_enc;

	link_enc = link_enc_cfg_get_link_enc(link);
	ASSERT(link_enc);


	if (!link->wa_flags.dp_keep_receiver_powered)
	if (!link->wa_flags.dp_keep_receiver_powered)
		dp_receiver_power_ctrl(link, false);
		dp_receiver_power_ctrl(link, false);
@@ -234,20 +214,15 @@ void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_
		if (link->dc->hwss.edp_backlight_control)
		if (link->dc->hwss.edp_backlight_control)
			link->dc->hwss.edp_backlight_control(link, false);
			link->dc->hwss.edp_backlight_control(link, false);


		if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING)
		if (link_hwss->ext.disable_dp_link_output)
			disable_dp_hpo_output(link, link_res, signal);
			link_hwss->ext.disable_dp_link_output(link, link_res, signal);
		else
			link_enc->funcs->disable_output(link_enc, signal);
		link->dc->hwss.edp_power_control(link, false);
		link->dc->hwss.edp_power_control(link, false);
	} else {
	} else {
		if (dmcu != NULL && dmcu->funcs->lock_phy)
		if (dmcu != NULL && dmcu->funcs->lock_phy)
			dmcu->funcs->lock_phy(dmcu);
			dmcu->funcs->lock_phy(dmcu);


		if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING &&
		if (link_hwss->ext.disable_dp_link_output)
				hpo_link_enc)
			link_hwss->ext.disable_dp_link_output(link, link_res, signal);
			disable_dp_hpo_output(link, link_res, signal);
		else
			link_enc->funcs->disable_output(link_enc, signal);


		if (dmcu != NULL && dmcu->funcs->unlock_phy)
		if (dmcu != NULL && dmcu->funcs->unlock_phy)
			dmcu->funcs->unlock_phy(dmcu);
			dmcu->funcs->unlock_phy(dmcu);
@@ -702,88 +677,6 @@ static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link)
	}
	}
}
}


void enable_dp_hpo_output(struct dc_link *link,
		const struct link_resource *link_res,
		const struct dc_link_settings *link_settings)
{
	const struct dc *dc = link->dc;
	enum phyd32clk_clock_source phyd32clk;

	/* Enable PHY PLL at target bit rate
	 *   UHBR10 = 10Gbps (SYMCLK32 = 312.5MHz)
	 *   UBR13.5 = 13.5Gbps (SYMCLK32 = 421.875MHz)
	 *   UHBR20 = 20Gbps (SYMCLK32 = 625MHz)
	 */
	if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
		switch (link_settings->link_rate) {
		case LINK_RATE_UHBR10:
			dm_set_phyd32clk(dc->ctx, 312500);
			break;
		case LINK_RATE_UHBR13_5:
			dm_set_phyd32clk(dc->ctx, 412875);
			break;
		case LINK_RATE_UHBR20:
			dm_set_phyd32clk(dc->ctx, 625000);
			break;
		default:
			return;
		}
	} else {
		/* DP2.0 HW: call transmitter control to enable PHY */
		link_res->hpo_dp_link_enc->funcs->enable_link_phy(
				link_res->hpo_dp_link_enc,
				link_settings,
				link->link_enc->transmitter,
				link->link_enc->hpd_source);
	}

	/* DCCG muxing and DTBCLK DTO */
	if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
		dc->res_pool->dccg->funcs->set_physymclk(
				dc->res_pool->dccg,
				link->link_enc_hw_inst,
				PHYSYMCLK_FORCE_SRC_PHYD32CLK,
				true);

		phyd32clk = get_phyd32clk_src(link);
		dc->res_pool->dccg->funcs->enable_symclk32_le(
				dc->res_pool->dccg,
				link_res->hpo_dp_link_enc->inst,
				phyd32clk);
		link_res->hpo_dp_link_enc->funcs->link_enable(
				link_res->hpo_dp_link_enc,
				link_settings->lane_count);
	}
}

void disable_dp_hpo_output(struct dc_link *link,
		const struct link_resource *link_res,
		enum signal_type signal)
{
	const struct dc *dc = link->dc;

	link_res->hpo_dp_link_enc->funcs->link_disable(link_res->hpo_dp_link_enc);

	if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
		dc->res_pool->dccg->funcs->disable_symclk32_le(
					dc->res_pool->dccg,
					link_res->hpo_dp_link_enc->inst);

		dc->res_pool->dccg->funcs->set_physymclk(
					dc->res_pool->dccg,
					link->link_enc_hw_inst,
					PHYSYMCLK_FORCE_SRC_SYMCLK,
					false);

		dm_set_phyd32clk(dc->ctx, 0);
	} else {
		/* DP2.0 HW: call transmitter control to disable PHY */
		link_res->hpo_dp_link_enc->funcs->disable_link_phy(
				link_res->hpo_dp_link_enc,
				signal);
	}
}

static void virtual_setup_stream_encoder(struct pipe_ctx *pipe_ctx);
static void virtual_setup_stream_encoder(struct pipe_ctx *pipe_ctx);
static void virtual_reset_stream_encoder(struct pipe_ctx *pipe_ctx);
static void virtual_reset_stream_encoder(struct pipe_ctx *pipe_ctx);


@@ -804,21 +697,10 @@ static void set_dio_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
				throttled_vcp_size);
				throttled_vcp_size);
}
}


static struct link_encoder *get_dio_link_encoder(const struct dc_link *link)
{
	/* Link encoder may have been dynamically assigned to non-physical display endpoint. */
	if (link->is_dig_mapping_flexible &&
			link->dc->res_pool->funcs->link_encs_assign)
		return link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
	else
		return link->link_enc;
}

static void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
static void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
{
{
	struct link_encoder *link_enc = get_dio_link_encoder(pipe_ctx->stream->link);
	struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);


	ASSERT(link_enc);
	link_enc->funcs->connect_dig_be_to_fe(link_enc,
	link_enc->funcs->connect_dig_be_to_fe(link_enc,
			pipe_ctx->stream_res.stream_enc->id, true);
			pipe_ctx->stream_res.stream_enc->id, true);
	if (dc_is_dp_signal(pipe_ctx->stream->signal))
	if (dc_is_dp_signal(pipe_ctx->stream->signal))
@@ -828,7 +710,7 @@ static void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)


static void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
static void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
{
{
	struct link_encoder *link_enc = get_dio_link_encoder(pipe_ctx->stream->link);
	struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);


	link_enc->funcs->connect_dig_be_to_fe(
	link_enc->funcs->connect_dig_be_to_fe(
			link_enc,
			link_enc,
@@ -840,11 +722,45 @@ static void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)


}
}


static void enable_dio_dp_link_output(struct dc_link *link,
		const struct link_resource *link_res,
		enum signal_type signal,
		enum clock_source_id clock_source,
		const struct dc_link_settings *link_settings)
{
	struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);

	if (dc_is_dp_sst_signal(signal))
		link_enc->funcs->enable_dp_output(
				link_enc,
				link_settings,
				clock_source);
	else
		link_enc->funcs->enable_dp_mst_output(
				link_enc,
				link_settings,
				clock_source);
	dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
}


static void disable_dio_dp_link_output(struct dc_link *link,
		const struct link_resource *link_res,
		enum signal_type signal)
{
	struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);

	link_enc->funcs->disable_output(link_enc, signal);
	dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
}

static const struct link_hwss dio_link_hwss = {
static const struct link_hwss dio_link_hwss = {
	.setup_stream_encoder = setup_dio_stream_encoder,
	.setup_stream_encoder = setup_dio_stream_encoder,
	.reset_stream_encoder = reset_dio_stream_encoder,
	.reset_stream_encoder = reset_dio_stream_encoder,
	.ext = {
	.ext = {
		.set_throttled_vcp_size = set_dio_throttled_vcp_size,
		.set_throttled_vcp_size = set_dio_throttled_vcp_size,
		.enable_dp_link_output = enable_dio_dp_link_output,
		.disable_dp_link_output = disable_dio_dp_link_output,
	},
	},
};
};


@@ -933,12 +849,92 @@ static void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx)
	dccg->funcs->disable_symclk32_se(dccg, stream_enc->inst);
	dccg->funcs->disable_symclk32_se(dccg, stream_enc->inst);
	dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst);
	dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst);
}
}

static void enable_hpo_dp_fpga_link_output(struct dc_link *link,
		const struct link_resource *link_res,
		enum signal_type signal,
		enum clock_source_id clock_source,
		const struct dc_link_settings *link_settings)
{
	const struct dc *dc = link->dc;
	enum phyd32clk_clock_source phyd32clk = get_phyd32clk_src(link);
	int phyd32clk_freq_khz = link_settings->link_rate == LINK_RATE_UHBR10 ? 312500 :
			link_settings->link_rate == LINK_RATE_UHBR13_5 ? 412875 :
			link_settings->link_rate == LINK_RATE_UHBR20 ? 625000 : 0;

	dm_set_phyd32clk(dc->ctx, phyd32clk_freq_khz);
	dc->res_pool->dccg->funcs->set_physymclk(
			dc->res_pool->dccg,
			link->link_enc_hw_inst,
			PHYSYMCLK_FORCE_SRC_PHYD32CLK,
			true);
	dc->res_pool->dccg->funcs->enable_symclk32_le(
			dc->res_pool->dccg,
			link_res->hpo_dp_link_enc->inst,
			phyd32clk);
	link_res->hpo_dp_link_enc->funcs->link_enable(
			link_res->hpo_dp_link_enc,
			link_settings->lane_count);

}

static void enable_hpo_dp_link_output(struct dc_link *link,
		const struct link_resource *link_res,
		enum signal_type signal,
		enum clock_source_id clock_source,
		const struct dc_link_settings *link_settings)
{
	if (IS_FPGA_MAXIMUS_DC(link->dc->ctx->dce_environment))
		enable_hpo_dp_fpga_link_output(link, link_res, signal,
				clock_source, link_settings);
	else
		link_res->hpo_dp_link_enc->funcs->enable_link_phy(
				link_res->hpo_dp_link_enc,
				link_settings,
				link->link_enc->transmitter,
				link->link_enc->hpd_source);
}


static void disable_hpo_dp_fpga_link_output(struct dc_link *link,
		const struct link_resource *link_res,
		enum signal_type signal)
{
	const struct dc *dc = link->dc;

	link_res->hpo_dp_link_enc->funcs->link_disable(link_res->hpo_dp_link_enc);
	dc->res_pool->dccg->funcs->disable_symclk32_le(
			dc->res_pool->dccg,
			link_res->hpo_dp_link_enc->inst);
	dc->res_pool->dccg->funcs->set_physymclk(
			dc->res_pool->dccg,
			link->link_enc_hw_inst,
			PHYSYMCLK_FORCE_SRC_SYMCLK,
			false);
	dm_set_phyd32clk(dc->ctx, 0);
}

static void disable_hpo_dp_link_output(struct dc_link *link,
		const struct link_resource *link_res,
		enum signal_type signal)
{
	if (IS_FPGA_MAXIMUS_DC(link->dc->ctx->dce_environment)) {
		disable_hpo_dp_fpga_link_output(link, link_res, signal);
	} else {
		link_res->hpo_dp_link_enc->funcs->link_disable(link_res->hpo_dp_link_enc);
		link_res->hpo_dp_link_enc->funcs->disable_link_phy(
				link_res->hpo_dp_link_enc, signal);
	}
}

static const struct link_hwss hpo_dp_link_hwss = {
static const struct link_hwss hpo_dp_link_hwss = {
	.setup_stream_encoder = setup_hpo_dp_stream_encoder,
	.setup_stream_encoder = setup_hpo_dp_stream_encoder,
	.reset_stream_encoder = reset_hpo_dp_stream_encoder,
	.reset_stream_encoder = reset_hpo_dp_stream_encoder,
	.ext = {
	.ext = {
		.set_throttled_vcp_size = set_dp_hpo_throttled_vcp_size,
		.set_throttled_vcp_size = set_dp_hpo_throttled_vcp_size,
		.set_hblank_min_symbol_width = set_dp_hpo_hblank_min_symbol_width,
		.set_hblank_min_symbol_width = set_dp_hpo_hblank_min_symbol_width,
		.enable_dp_link_output = enable_hpo_dp_link_output,
		.disable_dp_link_output = disable_hpo_dp_link_output,
	},
	},
};
};
/*********************** below goes to dpia_link_hwss *************************/
/*********************** below goes to dpia_link_hwss *************************/
@@ -954,6 +950,8 @@ static const struct link_hwss dpia_link_hwss = {
	.reset_stream_encoder = reset_dio_stream_encoder,
	.reset_stream_encoder = reset_dio_stream_encoder,
	.ext = {
	.ext = {
		.set_throttled_vcp_size = set_dio_throttled_vcp_size,
		.set_throttled_vcp_size = set_dio_throttled_vcp_size,
		.enable_dp_link_output = enable_dio_dp_link_output,
		.disable_dp_link_output = disable_dio_dp_link_output,
	},
	},
};
};


+8 −0
Original line number Original line Diff line number Diff line
@@ -86,6 +86,14 @@ struct link_hwss_ext {
			struct fixed31_32 throttled_vcp_size);
			struct fixed31_32 throttled_vcp_size);
	void (*set_throttled_vcp_size)(struct pipe_ctx *pipe_ctx,
	void (*set_throttled_vcp_size)(struct pipe_ctx *pipe_ctx,
			struct fixed31_32 throttled_vcp_size);
			struct fixed31_32 throttled_vcp_size);
	void (*enable_dp_link_output)(struct dc_link *link,
			const struct link_resource *link_res,
			enum signal_type signal,
			enum clock_source_id clock_source,
			const struct dc_link_settings *link_settings);
	void (*disable_dp_link_output)(struct dc_link *link,
			const struct link_resource *link_res,
			enum signal_type signal);
};
};


struct link_hwss {
struct link_hwss {