Commit a8201902 authored by Leung, Martin's avatar Leung, Martin Committed by Alex Deucher
Browse files

drm/amdgpu/display: Prepare for new interfaces



why:
lut pipeline will be hooked up differently in some asics
need to add new interfaces

how:
add them

Reviewed-by: default avatarKrunoslav Kovac <Krunoslav.Kovac@amd.com>
Acked-by: default avatarJasdeep Dhillon <jdhillon@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarMartin <martin.leung@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 12d6c18c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1507,6 +1507,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
		DRM_INFO("Seamless boot condition check passed\n");
	}

	init_data.flags.enable_mipi_converter_optimization = true;

	INIT_LIST_HEAD(&adev->dm.da_list);
	/* Display Core create. */
	adev->dm.dc = dc_create(&init_data);
+15 −2
Original line number Diff line number Diff line
@@ -235,6 +235,7 @@ bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type)

	if (link->connector_signal == SIGNAL_TYPE_EDP) {
		/*in case it is not on*/
		if (!link->dc->config.edp_no_power_sequencing)
			link->dc->hwss.edp_power_control(link, true);
		link->dc->hwss.edp_wait_for_hpd_ready(link, true);
	}
@@ -1016,6 +1017,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
	bool same_edid = false;
	enum dc_edid_status edid_status;
	struct dc_context *dc_ctx = link->ctx;
	struct dc *dc = dc_ctx->dc;
	struct dc_sink *sink = NULL;
	struct dc_sink *prev_sink = NULL;
	struct dpcd_caps prev_dpcd_caps;
@@ -1095,6 +1097,16 @@ static bool detect_link_and_local_sink(struct dc_link *link,

			detect_edp_sink_caps(link);
			read_current_link_settings_on_detect(link);

			/* Disable power sequence on MIPI panel + converter
			 */
			if (dc->config.enable_mipi_converter_optimization &&
				dc_ctx->dce_version == DCN_VERSION_3_01 &&
				link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_0022B9 &&
				memcmp(&link->dpcd_caps.branch_dev_name, DP_SINK_BRANCH_DEV_NAME_7580,
					sizeof(link->dpcd_caps.branch_dev_name)) == 0)
				dc->config.edp_no_power_sequencing = true;

			sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
			sink_caps.signal = SIGNAL_TYPE_EDP;
			break;
@@ -1993,6 +2005,7 @@ static enum dc_status enable_link_dp(struct dc_state *state,

	if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
		/*in case it is not on*/
		if (!link->dc->config.edp_no_power_sequencing)
			link->dc->hwss.edp_power_control(link, true);
		link->dc->hwss.edp_wait_for_hpd_ready(link, true);
	}
+31 −21
Original line number Diff line number Diff line
@@ -2074,7 +2074,8 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
	uint32_t wait_time = 0;
	union lane_align_status_updated dpcd_lane_status_updated = {0};
	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
	enum link_training_result status = LINK_TRAINING_SUCCESS;
	enum dc_status status = DC_OK;
	enum link_training_result result = LINK_TRAINING_SUCCESS;
	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};

	/* Transmit 128b/132b_TPS1 over Main-Link */
@@ -2099,22 +2100,24 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
			lt_settings->pattern_for_eq, DPRX);

	/* poll for channel EQ done */
	while (status == LINK_TRAINING_SUCCESS) {
	while (result == LINK_TRAINING_SUCCESS) {
		dp_wait_for_training_aux_rd_interval(link, aux_rd_interval);
		wait_time += aux_rd_interval;
		dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
		status = dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
				&dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
		dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
			lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
		dpcd_128b_132b_get_aux_rd_interval(link, &aux_rd_interval);
		if (dp_is_ch_eq_done(lt_settings->link_settings.lane_count,
		if (status != DC_OK) {
			result = LINK_TRAINING_ABORT;
		} else if (dp_is_ch_eq_done(lt_settings->link_settings.lane_count,
				dpcd_lane_status)) {
			/* pass */
			break;
		} else if (loop_count >= lt_settings->eq_loop_count_limit) {
			status = DP_128b_132b_MAX_LOOP_COUNT_REACHED;
			result = DP_128b_132b_MAX_LOOP_COUNT_REACHED;
		} else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) {
			status = DP_128b_132b_LT_FAILED;
			result = DP_128b_132b_LT_FAILED;
		} else {
			dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX);
			dpcd_set_lane_settings(link, lt_settings, DPRX);
@@ -2123,24 +2126,26 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
	}

	/* poll for EQ interlane align done */
	while (status == LINK_TRAINING_SUCCESS) {
		if (dpcd_lane_status_updated.bits.EQ_INTERLANE_ALIGN_DONE_128b_132b) {
	while (result == LINK_TRAINING_SUCCESS) {
		if (status != DC_OK) {
			result = LINK_TRAINING_ABORT;
		} else if (dpcd_lane_status_updated.bits.EQ_INTERLANE_ALIGN_DONE_128b_132b) {
			/* pass */
			break;
		} else if (wait_time >= lt_settings->eq_wait_time_limit) {
			status = DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT;
			result = DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT;
		} else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) {
			status = DP_128b_132b_LT_FAILED;
			result = DP_128b_132b_LT_FAILED;
		} else {
			dp_wait_for_training_aux_rd_interval(link,
					lt_settings->eq_pattern_time);
			wait_time += lt_settings->eq_pattern_time;
			dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
			status = dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
					&dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
		}
	}

	return status;
	return result;
}

static enum link_training_result dp_perform_128b_132b_cds_done_sequence(
@@ -2149,7 +2154,8 @@ static enum link_training_result dp_perform_128b_132b_cds_done_sequence(
		struct link_training_settings *lt_settings)
{
	/* Assumption: assume hardware has transmitted eq pattern */
	enum link_training_result status = LINK_TRAINING_SUCCESS;
	enum dc_status status = DC_OK;
	enum link_training_result result = LINK_TRAINING_SUCCESS;
	union lane_align_status_updated dpcd_lane_status_updated = {0};
	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
@@ -2159,24 +2165,26 @@ static enum link_training_result dp_perform_128b_132b_cds_done_sequence(
	dpcd_set_training_pattern(link, lt_settings->pattern_for_cds);

	/* poll for CDS interlane align done and symbol lock */
	while (status == LINK_TRAINING_SUCCESS) {
	while (result  == LINK_TRAINING_SUCCESS) {
		dp_wait_for_training_aux_rd_interval(link,
				lt_settings->cds_pattern_time);
		wait_time += lt_settings->cds_pattern_time;
		dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
		status = dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
						&dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
		if (dp_is_symbol_locked(lt_settings->link_settings.lane_count, dpcd_lane_status) &&
		if (status != DC_OK) {
			result = LINK_TRAINING_ABORT;
		} else if (dp_is_symbol_locked(lt_settings->link_settings.lane_count, dpcd_lane_status) &&
				dpcd_lane_status_updated.bits.CDS_INTERLANE_ALIGN_DONE_128b_132b) {
			/* pass */
			break;
		} else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) {
			status = DP_128b_132b_LT_FAILED;
			result = DP_128b_132b_LT_FAILED;
		} else if (wait_time >= lt_settings->cds_wait_time_limit) {
			status = DP_128b_132b_CDS_DONE_TIMEOUT;
			result = DP_128b_132b_CDS_DONE_TIMEOUT;
		}
	}

	return status;
	return result;
}

static enum link_training_result dp_perform_8b_10b_link_training(
@@ -7099,6 +7107,7 @@ void dp_enable_link_phy(
	unsigned int i;

	if (link->connector_signal == SIGNAL_TYPE_EDP) {
		if (!link->dc->config.edp_no_power_sequencing)
			link->dc->hwss.edp_power_control(link, true);
		link->dc->hwss.edp_wait_for_hpd_ready(link, true);
	}
@@ -7226,6 +7235,7 @@ void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_
			link->dc->hwss.edp_backlight_control(link, false);
		if (link_hwss->ext.disable_dp_link_output)
			link_hwss->ext.disable_dp_link_output(link, link_res, signal);
		if (!link->dc->config.edp_no_power_sequencing)
			link->dc->hwss.edp_power_control(link, false);
	} else {
		if (dmcu != NULL && dmcu->funcs->lock_phy)
+1 −0
Original line number Diff line number Diff line
@@ -337,6 +337,7 @@ struct dc_config {
	bool is_single_rank_dimm;
	bool use_pipe_ctx_sync_logic;
	bool ignore_dpref_ss;
	bool enable_mipi_converter_optimization;
};

enum visual_confirm {
+18 −5
Original line number Diff line number Diff line
@@ -1245,9 +1245,19 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
			 * has changed or they enter protection state and hang.
			 */
			msleep(60);
		} else if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP)
		} else if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
			if (!link->dc->config.edp_no_power_sequencing) {
				/*
				 * Sometimes, DP receiver chip power-controlled externally by an
				 * Embedded Controller could be treated and used as eDP,
				 * if it drives mobile display. In this case,
				 * we shouldn't be doing power-sequencing, hence we can skip
				 * waiting for T9-ready.
				 */
				edp_receiver_ready_T9(link);
			}
		}
	}

}

@@ -2181,15 +2191,18 @@ static void dce110_setup_audio_dto(
			build_audio_output(context, pipe_ctx, &audio_output);

			if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->set_audio_dtbclk_dto) {
				/* disable audio DTBCLK DTO */
				dc->res_pool->dccg->funcs->set_audio_dtbclk_dto(
					dc->res_pool->dccg, 0);
				struct dtbclk_dto_params dto_params = {0};

				pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
						pipe_ctx->stream_res.audio,
						pipe_ctx->stream->signal,
						&audio_output.crtc_info,
						&audio_output.pll_info);

				dc->res_pool->dccg->funcs->set_audio_dtbclk_dto(
					dc->res_pool->dccg,
					&dto_params);

			} else
				pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
					pipe_ctx->stream_res.audio,
Loading