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

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
......@@ -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);
......
......@@ -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);
}
......
......@@ -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)
......
......@@ -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 {
......
......@@ -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,
......
......@@ -513,7 +513,7 @@ 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,
struct dtbclk_dto_params *params)
const struct dtbclk_dto_params *params)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
int req_dtbclk_khz = params->pixclk_khz;
......@@ -579,18 +579,17 @@ static void dccg31_set_dtbclk_dto(
void dccg31_set_audio_dtbclk_dto(
struct dccg *dccg,
uint32_t req_audio_dtbclk_khz)
const struct dtbclk_dto_params *params)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
if (dccg->ref_dtbclk_khz && req_audio_dtbclk_khz) {
if (params->ref_dtbclk_khz && params->req_audio_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_audio_dtbclk_khz) + dccg->ref_dtbclk_khz - 1),
dccg->ref_dtbclk_khz);
modulo = params->ref_dtbclk_khz * 1000;
phase = div_u64((((unsigned long long)modulo * params->req_audio_dtbclk_khz) + params->ref_dtbclk_khz - 1),
params->ref_dtbclk_khz);
REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, modulo);
REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, phase);
......
......@@ -192,7 +192,7 @@ void dccg31_set_physymclk(
void dccg31_set_audio_dtbclk_dto(
struct dccg *dccg,
uint32_t req_audio_dtbclk_khz);
const struct dtbclk_dto_params *params);
void dccg31_set_hdmistreamclk(
struct dccg *dccg,
......
......@@ -120,11 +120,11 @@ struct dccg_funcs {
void (*set_dtbclk_dto)(
struct dccg *dccg,
struct dtbclk_dto_params *dto_params);
const struct dtbclk_dto_params *params);
void (*set_audio_dtbclk_dto)(
struct dccg *dccg,
uint32_t req_audio_dtbclk_khz);
const struct dtbclk_dto_params *params);
void (*set_dispclk_change_mode)(
struct dccg *dccg,
......
......@@ -346,6 +346,11 @@ struct mpc_funcs {
int mpcc_id,
const struct mpc_grph_gamut_adjustment *adjust);
bool (*program_1dlut)(
struct mpc *mpc,
const struct pwl_params *params,
uint32_t rmu_idx);
bool (*program_shaper)(
struct mpc *mpc,
const struct pwl_params *params,
......
......@@ -140,6 +140,8 @@ struct hwseq_private_funcs {
const struct dc_plane_state *plane_state);
bool (*set_shaper_3dlut)(struct pipe_ctx *pipe_ctx,
const struct dc_plane_state *plane_state);
bool (*set_mcm_luts)(struct pipe_ctx *pipe_ctx,
const struct dc_plane_state *plane_state);
void (*PLAT_58856_wa)(struct dc_state *context,
struct pipe_ctx *pipe_ctx);
void (*setup_hpo_hw_control)(const struct dce_hwseq *hws, bool enable);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment