]> www.infradead.org Git - users/hch/misc.git/commitdiff
drm/amd/display: misc for dio encoder refactor
authorPeichen Huang <PeiChen.Huang@amd.com>
Tue, 11 Feb 2025 06:41:11 +0000 (14:41 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 5 Mar 2025 15:39:20 +0000 (10:39 -0500)
[WHY]
These are left required changes for dio encoder refactor.

[HOW]
1. original logic is separated by config option
2. new link encoder dp enable/disable code for dcn35
3. process fec only for DP 8b10b encoding

Reviewed-by: Cruise Hung <cruise.hung@amd.com>
Signed-off-by: Peichen Huang <PeiChen.Huang@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
12 files changed:
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/core/dc_stream.c
drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.c
drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.h
drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dpia.c
drivers/gpu/drm/amd/display/dc/link/link_detection.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c

index df29d28d89c9d8b6a6b75d2825f0de94d9304523..af722519a1fa5309fec6491cae46eca9626cb7a1 100644 (file)
@@ -201,16 +201,26 @@ static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *
                struct pipe_ctx *pipe = safe_to_lower
                        ? &context->res_ctx.pipe_ctx[i]
                        : &dc->current_state->res_ctx.pipe_ctx[i];
+               struct link_encoder *new_pipe_link_enc = new_pipe->link_res.dio_link_enc;
+               struct link_encoder *pipe_link_enc = pipe->link_res.dio_link_enc;
                bool stream_changed_otg_dig_on = false;
                if (pipe->top_pipe || pipe->prev_odm_pipe)
                        continue;
+
+               if (!dc->config.unify_link_enc_assignment) {
+                       if (new_pipe->stream)
+                               new_pipe_link_enc = new_pipe->stream->link_enc;
+                       if (pipe->stream)
+                               pipe_link_enc = pipe->stream->link_enc;
+               }
+
                stream_changed_otg_dig_on = old_pipe->stream && new_pipe->stream &&
                old_pipe->stream != new_pipe->stream &&
                old_pipe->stream_res.tg == new_pipe->stream_res.tg &&
-               new_pipe->stream->link_enc && !new_pipe->stream->dpms_off &&
-               new_pipe->stream->link_enc->funcs->is_dig_enabled &&
-               new_pipe->stream->link_enc->funcs->is_dig_enabled(
-               new_pipe->stream->link_enc) &&
+               new_pipe_link_enc && !new_pipe->stream->dpms_off &&
+               new_pipe_link_enc->funcs->is_dig_enabled &&
+               new_pipe_link_enc->funcs->is_dig_enabled(
+               new_pipe_link_enc) &&
                new_pipe->stream_res.stream_enc &&
                new_pipe->stream_res.stream_enc->funcs->is_fifo_enabled &&
                new_pipe->stream_res.stream_enc->funcs->is_fifo_enabled(new_pipe->stream_res.stream_enc);
@@ -226,7 +236,7 @@ static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *
 
                if (!has_active_hpo && !dccg->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe) &&
                                        (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal) ||
-                                       !pipe->stream->link_enc) && !stream_changed_otg_dig_on)) {
+                                       !pipe_link_enc) && !stream_changed_otg_dig_on)) {
 
 
                        /* This w/a should not trigger when we have a dig active */
index a99ce7c86781726e13122bb4e19ca93fd40b20f6..fe59649d3e152038e47c3824e6108dc6e0e3be5d 100644 (file)
@@ -905,7 +905,8 @@ void dc_stream_set_static_screen_params(struct dc *dc,
 static void dc_destruct(struct dc *dc)
 {
        // reset link encoder assignment table on destruct
-       if (dc->res_pool && dc->res_pool->funcs->link_encs_assign)
+       if (dc->res_pool && dc->res_pool->funcs->link_encs_assign &&
+                       !dc->config.unify_link_enc_assignment)
                link_enc_cfg_init(dc, dc->current_state);
 
        if (dc->current_state) {
index 0f8a88220ec64c42a240fed0d34bbc1f4d77f765..ea404435c9b91682fdb5578c725c5c84333f799c 100644 (file)
@@ -4926,7 +4926,10 @@ bool pipe_need_reprogram(
                return true;
 
        /* DIG link encoder resource assignment for stream changed. */
-       if (pipe_ctx_old->stream->ctx->dc->res_pool->funcs->link_encs_assign) {
+       if (pipe_ctx_old->stream->ctx->dc->config.unify_link_enc_assignment) {
+               if (pipe_ctx_old->link_res.dio_link_enc != pipe_ctx->link_res.dio_link_enc)
+                       return true;
+       } else if (pipe_ctx_old->stream->ctx->dc->res_pool->funcs->link_encs_assign) {
                bool need_reprogram = false;
                struct dc *dc = pipe_ctx_old->stream->ctx->dc;
                struct link_encoder *link_enc_prev =
index e8134c47fe0dce6fd533bd7f79d52ce6c7ddf7c5..0478dd856d8c67deaecea8db347287b8a9cacf0c 100644 (file)
@@ -201,7 +201,8 @@ struct dc_stream_state *dc_copy_stream(const struct dc_stream_state *stream)
        dc_stream_assign_stream_id(new_stream);
 
        /* If using dynamic encoder assignment, wait till stream committed to assign encoder. */
-       if (new_stream->ctx->dc->res_pool->funcs->link_encs_assign)
+       if (new_stream->ctx->dc->res_pool->funcs->link_encs_assign &&
+                       !new_stream->ctx->dc->config.unify_link_enc_assignment)
                new_stream->link_enc = NULL;
 
        kref_init(&new_stream->refcount);
index ea0c9a9d0bd6a2e2b8c802d8ae000bbe098e1a61..9972911330b653d467cc3a5e7a9a7d35035f5d2a 100644 (file)
@@ -137,9 +137,9 @@ static const struct link_encoder_funcs dcn35_link_enc_funcs = {
        .hw_init = dcn35_link_encoder_init,
        .setup = dcn35_link_encoder_setup,
        .enable_tmds_output = dcn10_link_encoder_enable_tmds_output,
-       .enable_dp_output = dcn31_link_encoder_enable_dp_output,
-       .enable_dp_mst_output = dcn31_link_encoder_enable_dp_mst_output,
-       .disable_output = dcn31_link_encoder_disable_output,
+       .enable_dp_output = dcn35_link_encoder_enable_dp_output,
+       .enable_dp_mst_output = dcn35_link_encoder_enable_dp_mst_output,
+       .disable_output = dcn35_link_encoder_disable_output,
        .dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings,
        .dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern,
        .update_mst_stream_allocation_table =
@@ -297,6 +297,50 @@ static void link_encoder_disable(struct dcn10_link_encoder *enc10)
        REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, 0);
 }
 
+void dcn35_link_encoder_enable_dp_output(
+       struct link_encoder *enc,
+       const struct dc_link_settings *link_settings,
+       enum clock_source_id clock_source)
+{
+       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+
+       if (!enc->ctx->dc->config.unify_link_enc_assignment)
+               dcn31_link_encoder_enable_dp_output(enc, link_settings, clock_source);
+       else {
+               DC_LOG_DEBUG("%s: enc_id(%d)\n", __func__, enc->preferred_engine);
+               dcn20_link_encoder_enable_dp_output(enc, link_settings, clock_source);
+       }
+}
+
+void dcn35_link_encoder_enable_dp_mst_output(
+       struct link_encoder *enc,
+       const struct dc_link_settings *link_settings,
+       enum clock_source_id clock_source)
+{
+       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+
+       if (!enc->ctx->dc->config.unify_link_enc_assignment)
+               dcn31_link_encoder_enable_dp_mst_output(enc, link_settings, clock_source);
+       else {
+               DC_LOG_DEBUG("%s: enc_id(%d)\n", __func__, enc->preferred_engine);
+               dcn10_link_encoder_enable_dp_mst_output(enc, link_settings, clock_source);
+       }
+}
+
+void dcn35_link_encoder_disable_output(
+       struct link_encoder *enc,
+       enum signal_type signal)
+{
+       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+
+       if (!enc->ctx->dc->config.unify_link_enc_assignment)
+               dcn31_link_encoder_disable_output(enc, signal);
+       else {
+               DC_LOG_DEBUG("%s: enc_id(%d)\n", __func__, enc->preferred_engine);
+               dcn10_link_encoder_disable_output(enc, signal);
+       }
+}
+
 void dcn35_link_encoder_enable_dpia_output(
        struct link_encoder *enc,
        const struct dc_link_settings *link_settings,
index f9d4221f4b434431c8626c638258c74be24f967d..5712e6553fab01805d6d87a53bf710774acb6bf5 100644 (file)
@@ -144,6 +144,29 @@ bool dcn35_is_dig_enabled(struct link_encoder *enc);
 enum signal_type dcn35_get_dig_mode(struct link_encoder *enc);
 void dcn35_link_encoder_setup(struct link_encoder *enc, enum signal_type signal);
 
+/*
+ * Enable DP transmitter and its encoder.
+ */
+void dcn35_link_encoder_enable_dp_output(
+       struct link_encoder *enc,
+       const struct dc_link_settings *link_settings,
+       enum clock_source_id clock_source);
+
+/*
+ * Enable DP transmitter and its encoder in MST mode.
+ */
+void dcn35_link_encoder_enable_dp_mst_output(
+       struct link_encoder *enc,
+       const struct dc_link_settings *link_settings,
+       enum clock_source_id clock_source);
+
+/*
+ * Disable transmitter and its encoder.
+ */
+void dcn35_link_encoder_disable_output(
+       struct link_encoder *enc,
+       enum signal_type signal);
+
 /*
  * Enable DP transmitter and its encoder for dpia port.
  */
index f698062f1e904fafdb76b33800b0f107ecb19927..288e9dd9205d299999263da6b09b0c367e1315f9 100644 (file)
@@ -621,7 +621,8 @@ void dcn31_reset_hw_ctx_wrap(
        }
 
        /* New dc_state in the process of being applied to hardware. */
-       link_enc_cfg_set_transient_mode(dc, dc->current_state, context);
+       if (!dc->config.unify_link_enc_assignment)
+               link_enc_cfg_set_transient_mode(dc, dc->current_state, context);
 }
 
 void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable)
index 4a3578a9586ed98c1e923c0724dbde6fa9916c69..b68bcc9fca0a514112308ab51dfa2a4bcb9457dc 100644 (file)
@@ -328,7 +328,10 @@ static const struct link_hwss dio_link_hwss = {
 bool can_use_dio_link_hwss(const struct dc_link *link,
                const struct link_resource *link_res)
 {
-       return link->link_enc != NULL;
+       if (!link->dc->config.unify_link_enc_assignment)
+               return link->link_enc != NULL;
+       else
+               return link_res->dio_link_enc != NULL;
 }
 
 /**
index 81d5085e322f21bb215ae8a25972ed1b2df69213..81bf3c5e1fdf63565bace1073a060cf7e838cacd 100644 (file)
@@ -90,33 +90,27 @@ static void enable_dpia_link_output(struct dc_link *link,
                const struct dc_link_settings *link_settings)
 {
        struct link_encoder *link_enc = link_res->dio_link_enc;
+       DC_LOGGER_INIT(link->ctx->logger);
 
        if (!link->dc->config.unify_link_enc_assignment)
                link_enc = link_enc_cfg_get_link_enc(link);
 
        if (link_enc != NULL) {
-               if (link->dc->config.enable_dpia_pre_training && link_enc->funcs->enable_dpia_output) {
+               if (link->dc->config.enable_dpia_pre_training || link->dc->config.unify_link_enc_assignment) {
                        uint8_t fec_rdy = link->dc->link_srv->dp_should_enable_fec(link);
                        uint8_t digmode = dc_is_dp_sst_signal(signal) ? DIG_SST_MODE : DIG_MST_MODE;
 
-                       link_enc->funcs->enable_dpia_output(
-                                       link_enc,
-                                       link_settings,
-                                       link->ddc_hw_inst,
-                                       digmode,
-                                       fec_rdy);
-               } else {
-                       if (dc_is_dp_sst_signal(signal))
-                               link_enc->funcs->enable_dp_output(
+                       if (link_enc->funcs->enable_dpia_output)
+                               link_enc->funcs->enable_dpia_output(
                                                link_enc,
                                                link_settings,
-                                               clock_source);
+                                               link->ddc_hw_inst,
+                                               digmode,
+                                               fec_rdy);
                        else
-                               link_enc->funcs->enable_dp_mst_output(
-                                               link_enc,
-                                               link_settings,
-                                               clock_source);
-               }
+                               DC_LOG_ERROR("%s: link encoder does not support enable_dpia_output\n", __func__);
+               } else
+                       enable_dio_dp_link_output(link, link_res, signal, clock_source, link_settings);
 
        }
 
@@ -129,15 +123,19 @@ static void disable_dpia_link_output(struct dc_link *link,
                enum signal_type signal)
 {
        struct link_encoder *link_enc = link_res->dio_link_enc;
+       DC_LOGGER_INIT(link->ctx->logger);
 
        if (!link->dc->config.unify_link_enc_assignment)
                link_enc = link_enc_cfg_get_link_enc(link);
 
        if (link_enc != NULL) {
-               if (link->dc->config.enable_dpia_pre_training && link_enc->funcs->disable_dpia_output) {
+               if (link->dc->config.enable_dpia_pre_training || link->dc->config.unify_link_enc_assignment) {
                        uint8_t digmode = dc_is_dp_sst_signal(signal) ? DIG_SST_MODE : DIG_MST_MODE;
 
-                       link_enc->funcs->disable_dpia_output(link_enc, link->ddc_hw_inst, digmode);
+                       if (link_enc->funcs->disable_dpia_output)
+                               link_enc->funcs->disable_dpia_output(link_enc, link->ddc_hw_inst, digmode);
+                       else
+                               DC_LOG_ERROR("%s: link encoder does not support disable_dpia_output\n", __func__);
                } else
                        link_enc->funcs->disable_output(link_enc, signal);
        }
@@ -166,8 +164,10 @@ static const struct link_hwss dpia_link_hwss = {
 bool can_use_dpia_link_hwss(const struct dc_link *link,
                const struct link_resource *link_res)
 {
-       return link->is_dig_mapping_flexible &&
-                       link->dc->res_pool->funcs->link_encs_assign;
+       if (!link->dc->config.unify_link_enc_assignment)
+               return link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign;
+       else
+               return link->is_dig_mapping_flexible && link_res->dio_link_enc != NULL;
 }
 
 const struct link_hwss *get_dpia_link_hwss(void)
index 550e1a098fa21367f88c867de7b73bad4585e80c..cc9191a5c9e63116fec5ea1c9831b0f1e6d54851 100644 (file)
@@ -816,7 +816,10 @@ static bool should_verify_link_capability_destructively(struct dc_link *link,
 {
        bool destrictive = false;
        struct dc_link_settings max_link_cap;
-       bool is_link_enc_unavailable = link->link_enc &&
+       bool is_link_enc_unavailable = false;
+
+       if (!link->dc->config.unify_link_enc_assignment)
+               is_link_enc_unavailable = link->link_enc &&
                        link->dc->res_pool->funcs->link_encs_assign &&
                        !link_enc_cfg_is_link_enc_avail(
                                        link->ctx->dc,
index 40ac17ba94796dabb0e058e0e329ec0ae3b7b92f..613298d21d033c77b173f7b73f58229840c58a98 100644 (file)
@@ -1575,7 +1575,8 @@ enum link_training_result dp_perform_link_training(
 
        /* configure link prior to entering training mode */
        dpcd_configure_lttpr_mode(link, &lt_settings);
-       dp_set_fec_ready(link, link_res, lt_settings.should_set_fec_ready);
+       if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING)
+               dp_set_fec_ready(link, link_res, lt_settings.should_set_fec_ready);
        dpcd_configure_channel_coding(link, &lt_settings);
 
        /* enter training mode:
index 6e2d08cfc5463bc0ca8a5c6f1389f4f8ac6b139d..603537ffd1284df9aee0bfbbc2f7298c1570c633 100644 (file)
@@ -130,11 +130,14 @@ static enum link_training_result dpia_configure_link(
        if (status != DC_OK && link->is_hpd_pending)
                return LINK_TRAINING_ABORT;
 
-       if (link->preferred_training_settings.fec_enable != NULL)
-               fec_enable = *link->preferred_training_settings.fec_enable;
-       else
-               fec_enable = true;
-       status = dp_set_fec_ready(link, link_res, fec_enable);
+       if (link_dp_get_encoding_format(link_setting) == DP_8b_10b_ENCODING) {
+               if (link->preferred_training_settings.fec_enable != NULL)
+                       fec_enable = *link->preferred_training_settings.fec_enable;
+               else
+                       fec_enable = true;
+               status = dp_set_fec_ready(link, link_res, fec_enable);
+       }
+
        if (status != DC_OK && link->is_hpd_pending)
                return LINK_TRAINING_ABORT;