drm/amdgpu/display: Prepare for new interfaces
authorLeung, Martin <Martin.Leung@amd.com>
Fri, 13 May 2022 21:40:42 +0000 (17:40 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 3 Jun 2022 20:43:36 +0000 (16:43 -0400)
why:
lut pipeline will be hooked up differently in some asics
need to add new interfaces

how:
add them

Reviewed-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com>
Acked-by: Jasdeep Dhillon <jdhillon@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Martin <martin.leung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h
drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h

index 70be67a..661a354 100644 (file)
@@ -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);
index a789ea8..55a8f58 100644 (file)
@@ -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) {
                /*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);
        }
 
@@ -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,7 +2005,8 @@ 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*/
-               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);
        }
 
index 03eedff..bea7717 100644 (file)
@@ -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,7 +7107,8 @@ void dp_enable_link_phy(
        unsigned int i;
 
        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);
        }
 
@@ -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);
                if (link_hwss->ext.disable_dp_link_output)
                        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 {
                if (dmcu != NULL && dmcu->funcs->lock_phy)
                        dmcu->funcs->lock_phy(dmcu);
index 817028d..11b02a9 100644 (file)
@@ -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 {
index 7eff781..a76523c 100644 (file)
@@ -1245,8 +1245,18 @@ 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)
-                       edp_receiver_ready_T9(link);
+               } 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,
index bbc58d1..4519ece 100644 (file)
@@ -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);
index 269cabb..f158c1e 100644 (file)
@@ -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,
index c702191..c1023cc 100644 (file)
@@ -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,
index f5fd2a0..5097037 100644 (file)
@@ -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,
index 8c2f190..d2cb0e7 100644 (file)
@@ -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);