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) ...@@ -1507,6 +1507,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
DRM_INFO("Seamless boot condition check passed\n"); DRM_INFO("Seamless boot condition check passed\n");
} }
init_data.flags.enable_mipi_converter_optimization = true;
INIT_LIST_HEAD(&adev->dm.da_list); INIT_LIST_HEAD(&adev->dm.da_list);
/* Display Core create. */ /* Display Core create. */
adev->dm.dc = dc_create(&init_data); adev->dm.dc = dc_create(&init_data);
......
...@@ -235,7 +235,8 @@ bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type) ...@@ -235,7 +235,8 @@ bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type)
if (link->connector_signal == SIGNAL_TYPE_EDP) { if (link->connector_signal == SIGNAL_TYPE_EDP) {
/*in case it is not on*/ /*in case it is not on*/
link->dc->hwss.edp_power_control(link, true); 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); 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, ...@@ -1016,6 +1017,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
bool same_edid = false; bool same_edid = false;
enum dc_edid_status edid_status; enum dc_edid_status edid_status;
struct dc_context *dc_ctx = link->ctx; struct dc_context *dc_ctx = link->ctx;
struct dc *dc = dc_ctx->dc;
struct dc_sink *sink = NULL; struct dc_sink *sink = NULL;
struct dc_sink *prev_sink = NULL; struct dc_sink *prev_sink = NULL;
struct dpcd_caps prev_dpcd_caps; struct dpcd_caps prev_dpcd_caps;
...@@ -1095,6 +1097,16 @@ static bool detect_link_and_local_sink(struct dc_link *link, ...@@ -1095,6 +1097,16 @@ static bool detect_link_and_local_sink(struct dc_link *link,
detect_edp_sink_caps(link); detect_edp_sink_caps(link);
read_current_link_settings_on_detect(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.transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
sink_caps.signal = SIGNAL_TYPE_EDP; sink_caps.signal = SIGNAL_TYPE_EDP;
break; break;
...@@ -1993,7 +2005,8 @@ static enum dc_status enable_link_dp(struct dc_state *state, ...@@ -1993,7 +2005,8 @@ static enum dc_status enable_link_dp(struct dc_state *state,
if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) { if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
/*in case it is not on*/ /*in case it is not on*/
link->dc->hwss.edp_power_control(link, true); 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); 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( ...@@ -2074,7 +2074,8 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
uint32_t wait_time = 0; uint32_t wait_time = 0;
union lane_align_status_updated dpcd_lane_status_updated = {0}; union lane_align_status_updated dpcd_lane_status_updated = {0};
union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {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}; union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
/* Transmit 128b/132b_TPS1 over Main-Link */ /* Transmit 128b/132b_TPS1 over Main-Link */
...@@ -2099,22 +2100,24 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence( ...@@ -2099,22 +2100,24 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
lt_settings->pattern_for_eq, DPRX); lt_settings->pattern_for_eq, DPRX);
/* poll for channel EQ done */ /* 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); dp_wait_for_training_aux_rd_interval(link, aux_rd_interval);
wait_time += 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); &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
dp_decide_lane_settings(lt_settings, dpcd_lane_adjust, dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
dpcd_128b_132b_get_aux_rd_interval(link, &aux_rd_interval); 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)) { dpcd_lane_status)) {
/* pass */ /* pass */
break; break;
} else if (loop_count >= lt_settings->eq_loop_count_limit) { } 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) { } else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) {
status = DP_128b_132b_LT_FAILED; result = DP_128b_132b_LT_FAILED;
} else { } else {
dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX); dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX);
dpcd_set_lane_settings(link, 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( ...@@ -2123,24 +2126,26 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
} }
/* poll for EQ interlane align done */ /* poll for EQ interlane align done */
while (status == LINK_TRAINING_SUCCESS) { while (result == LINK_TRAINING_SUCCESS) {
if (dpcd_lane_status_updated.bits.EQ_INTERLANE_ALIGN_DONE_128b_132b) { if (status != DC_OK) {
result = LINK_TRAINING_ABORT;
} else if (dpcd_lane_status_updated.bits.EQ_INTERLANE_ALIGN_DONE_128b_132b) {
/* pass */ /* pass */
break; break;
} else if (wait_time >= lt_settings->eq_wait_time_limit) { } 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) { } else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) {
status = DP_128b_132b_LT_FAILED; result = DP_128b_132b_LT_FAILED;
} else { } else {
dp_wait_for_training_aux_rd_interval(link, dp_wait_for_training_aux_rd_interval(link,
lt_settings->eq_pattern_time); lt_settings->eq_pattern_time);
wait_time += 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); &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
} }
} }
return status; return result;
} }
static enum link_training_result dp_perform_128b_132b_cds_done_sequence( 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( ...@@ -2149,7 +2154,8 @@ static enum link_training_result dp_perform_128b_132b_cds_done_sequence(
struct link_training_settings *lt_settings) struct link_training_settings *lt_settings)
{ {
/* Assumption: assume hardware has transmitted eq pattern */ /* 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_align_status_updated dpcd_lane_status_updated = {0};
union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0}; union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
union lane_adjust dpcd_lane_adjust[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( ...@@ -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); dpcd_set_training_pattern(link, lt_settings->pattern_for_cds);
/* poll for CDS interlane align done and symbol lock */ /* 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, dp_wait_for_training_aux_rd_interval(link,
lt_settings->cds_pattern_time); lt_settings->cds_pattern_time);
wait_time += 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); &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) { dpcd_lane_status_updated.bits.CDS_INTERLANE_ALIGN_DONE_128b_132b) {
/* pass */ /* pass */
break; break;
} else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) { } 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) { } 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( static enum link_training_result dp_perform_8b_10b_link_training(
...@@ -7099,7 +7107,8 @@ void dp_enable_link_phy( ...@@ -7099,7 +7107,8 @@ void dp_enable_link_phy(
unsigned int i; unsigned int i;
if (link->connector_signal == SIGNAL_TYPE_EDP) { if (link->connector_signal == SIGNAL_TYPE_EDP) {
link->dc->hwss.edp_power_control(link, true); 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); link->dc->hwss.edp_wait_for_hpd_ready(link, true);
} }
...@@ -7226,7 +7235,8 @@ void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_ ...@@ -7226,7 +7235,8 @@ void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_
link->dc->hwss.edp_backlight_control(link, false); link->dc->hwss.edp_backlight_control(link, false);
if (link_hwss->ext.disable_dp_link_output) if (link_hwss->ext.disable_dp_link_output)
link_hwss->ext.disable_dp_link_output(link, link_res, signal); link_hwss->ext.disable_dp_link_output(link, link_res, signal);
link->dc->hwss.edp_power_control(link, false); if (!link->dc->config.edp_no_power_sequencing)
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);
......
...@@ -337,6 +337,7 @@ struct dc_config { ...@@ -337,6 +337,7 @@ struct dc_config {
bool is_single_rank_dimm; bool is_single_rank_dimm;
bool use_pipe_ctx_sync_logic; bool use_pipe_ctx_sync_logic;
bool ignore_dpref_ss; bool ignore_dpref_ss;
bool enable_mipi_converter_optimization;
}; };
enum visual_confirm { enum visual_confirm {
......
...@@ -1245,8 +1245,18 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx) ...@@ -1245,8 +1245,18 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
* has changed or they enter protection state and hang. * has changed or they enter protection state and hang.
*/ */
msleep(60); msleep(60);
} else if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) } else if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) {
edp_receiver_ready_T9(link); 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( ...@@ -2181,15 +2191,18 @@ static void dce110_setup_audio_dto(
build_audio_output(context, pipe_ctx, &audio_output); build_audio_output(context, pipe_ctx, &audio_output);
if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->set_audio_dtbclk_dto) { if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->set_audio_dtbclk_dto) {
/* disable audio DTBCLK DTO */ struct dtbclk_dto_params dto_params = {0};
dc->res_pool->dccg->funcs->set_audio_dtbclk_dto(
dc->res_pool->dccg, 0);
pipe_ctx->stream_res.audio->funcs->wall_dto_setup( pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
pipe_ctx->stream_res.audio, pipe_ctx->stream_res.audio,
pipe_ctx->stream->signal, pipe_ctx->stream->signal,
&audio_output.crtc_info, &audio_output.crtc_info,
&audio_output.pll_info); &audio_output.pll_info);
dc->res_pool->dccg->funcs->set_audio_dtbclk_dto(
dc->res_pool->dccg,
&dto_params);
} else } else
pipe_ctx->stream_res.audio->funcs->wall_dto_setup( pipe_ctx->stream_res.audio->funcs->wall_dto_setup(
pipe_ctx->stream_res.audio, pipe_ctx->stream_res.audio,
......
...@@ -513,7 +513,7 @@ void dccg31_set_physymclk( ...@@ -513,7 +513,7 @@ void dccg31_set_physymclk(
/* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */ /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
static void dccg31_set_dtbclk_dto( static void dccg31_set_dtbclk_dto(
struct dccg *dccg, struct dccg *dccg,
struct dtbclk_dto_params *params) const struct dtbclk_dto_params *params)
{ {
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
int req_dtbclk_khz = params->pixclk_khz; int req_dtbclk_khz = params->pixclk_khz;
...@@ -579,18 +579,17 @@ static void dccg31_set_dtbclk_dto( ...@@ -579,18 +579,17 @@ static void dccg31_set_dtbclk_dto(
void dccg31_set_audio_dtbclk_dto( void dccg31_set_audio_dtbclk_dto(
struct dccg *dccg, struct dccg *dccg,
uint32_t req_audio_dtbclk_khz) const struct dtbclk_dto_params *params)
{ {
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 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; uint32_t modulo, phase;
// phase / modulo = dtbclk / dtbclk ref // phase / modulo = dtbclk / dtbclk ref
modulo = dccg->ref_dtbclk_khz * 1000; modulo = params->ref_dtbclk_khz * 1000;
phase = div_u64((((unsigned long long)modulo * req_audio_dtbclk_khz) + dccg->ref_dtbclk_khz - 1), phase = div_u64((((unsigned long long)modulo * params->req_audio_dtbclk_khz) + params->ref_dtbclk_khz - 1),
dccg->ref_dtbclk_khz); params->ref_dtbclk_khz);
REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, modulo); REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, modulo);
REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, phase); REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, phase);
......
...@@ -192,7 +192,7 @@ void dccg31_set_physymclk( ...@@ -192,7 +192,7 @@ void dccg31_set_physymclk(
void dccg31_set_audio_dtbclk_dto( void dccg31_set_audio_dtbclk_dto(
struct dccg *dccg, struct dccg *dccg,
uint32_t req_audio_dtbclk_khz); const struct dtbclk_dto_params *params);
void dccg31_set_hdmistreamclk( void dccg31_set_hdmistreamclk(
struct dccg *dccg, struct dccg *dccg,
......
...@@ -120,11 +120,11 @@ struct dccg_funcs { ...@@ -120,11 +120,11 @@ struct dccg_funcs {
void (*set_dtbclk_dto)( void (*set_dtbclk_dto)(
struct dccg *dccg, struct dccg *dccg,
struct dtbclk_dto_params *dto_params); const struct dtbclk_dto_params *params);
void (*set_audio_dtbclk_dto)( void (*set_audio_dtbclk_dto)(
struct dccg *dccg, struct dccg *dccg,
uint32_t req_audio_dtbclk_khz); const struct dtbclk_dto_params *params);
void (*set_dispclk_change_mode)( void (*set_dispclk_change_mode)(
struct dccg *dccg, struct dccg *dccg,
......
...@@ -346,6 +346,11 @@ struct mpc_funcs { ...@@ -346,6 +346,11 @@ struct mpc_funcs {
int mpcc_id, int mpcc_id,
const struct mpc_grph_gamut_adjustment *adjust); 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)( bool (*program_shaper)(
struct mpc *mpc, struct mpc *mpc,
const struct pwl_params *params, const struct pwl_params *params,
......
...@@ -140,6 +140,8 @@ struct hwseq_private_funcs { ...@@ -140,6 +140,8 @@ struct hwseq_private_funcs {
const struct dc_plane_state *plane_state); const struct dc_plane_state *plane_state);
bool (*set_shaper_3dlut)(struct pipe_ctx *pipe_ctx, bool (*set_shaper_3dlut)(struct pipe_ctx *pipe_ctx,
const struct dc_plane_state *plane_state); 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, void (*PLAT_58856_wa)(struct dc_state *context,
struct pipe_ctx *pipe_ctx); struct pipe_ctx *pipe_ctx);
void (*setup_hpo_hw_control)(const struct dce_hwseq *hws, bool enable); 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