drm/amd/display: convert link.h functions to function pointer style
authorWenjing Liu <wenjing.liu@amd.com>
Thu, 23 Feb 2023 22:04:47 +0000 (17:04 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 14 Mar 2023 19:35:03 +0000 (15:35 -0400)
[Why & How]
All dc subcomponents should call another dc component via function pointers
stored in a component structure. This is part of dc coding convention since
the beginning. The reason behind this is to improve encapsulation and
polymorphism. The function contract is extracted into a single link service
structure defined in link.h header file and implemented only in link_factory.c instead
of spreading across multiple files in link component file structure.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
52 files changed:
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c
drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
drivers/gpu/drm/amd/display/dc/core/dc_resource.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/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
drivers/gpu/drm/amd/display/dc/inc/link.h
drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.c
drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_trace.h
drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c
drivers/gpu/drm/amd/display/dc/link/link_detection.c
drivers/gpu/drm/amd/display/dc/link/link_detection.h
drivers/gpu/drm/amd/display/dc/link/link_dpms.c
drivers/gpu/drm/amd/display/dc/link/link_dpms.h
drivers/gpu/drm/amd/display/dc/link/link_factory.c
drivers/gpu/drm/amd/display/dc/link/link_factory.h
drivers/gpu/drm/amd/display/dc/link/link_resource.h
drivers/gpu/drm/amd/display/dc/link/link_validation.c
drivers/gpu/drm/amd/display/dc/link/link_validation.h
drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h
drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.h

index 1629a75..e0b7ef6 100644 (file)
@@ -7184,13 +7184,14 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
        struct edid *edid = amdgpu_dm_connector->edid;
        struct dc_link_settings *verified_link_cap =
                        &amdgpu_dm_connector->dc_link->verified_link_cap;
+       const struct dc *dc = amdgpu_dm_connector->dc_link->dc;
 
        encoder = amdgpu_dm_connector_to_encoder(connector);
 
        if (!drm_edid_is_valid(edid)) {
                amdgpu_dm_connector->num_modes =
                                drm_add_modes_noedid(connector, 640, 480);
-               if (link_dp_get_encoding_format(verified_link_cap) == DP_128b_132b_ENCODING)
+               if (dc->link_srv->dp_get_encoding_format(verified_link_cap) == DP_128b_132b_ENCODING)
                        amdgpu_dm_connector->num_modes +=
                                drm_add_modes_noedid(connector, 1920, 1080);
        } else {
index f669f8a..827fcb4 100644 (file)
@@ -2802,7 +2802,7 @@ static int psr_read_residency(void *data, u64 *val)
        struct dc_link *link = connector->dc_link;
        u32 residency;
 
-       link_get_psr_residency(link, &residency);
+       link->dc->link_srv->edp_get_psr_residency(link, &residency);
 
        *val = (u64)residency;
 
index ee81d36..6127d60 100644 (file)
@@ -116,7 +116,7 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m
                        if (!edp_link->psr_settings.psr_feature_enabled)
                                continue;
                        clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active;
-                       dc_link_set_psr_allow_active(edp_link, &allow_active, false, false, NULL);
+                       dc->link_srv->edp_set_psr_allow_active(edp_link, &allow_active, false, false, NULL);
                }
        }
 
@@ -135,7 +135,7 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr)
                        edp_link = edp_links[panel_inst];
                        if (!edp_link->psr_settings.psr_feature_enabled)
                                continue;
-                       dc_link_set_psr_allow_active(edp_link,
+                       dc->link_srv->edp_set_psr_allow_active(edp_link,
                                        &clk_mgr->psr_allow_active_cache, false, false, NULL);
                }
        }
index a5f2f88..ae5f1b7 100644 (file)
@@ -148,7 +148,7 @@ static void destroy_links(struct dc *dc)
 
        for (i = 0; i < dc->link_count; i++) {
                if (NULL != dc->links[i])
-                       link_destroy(&dc->links[i]);
+                       dc->link_srv->destroy_link(&dc->links[i]);
        }
 }
 
@@ -217,7 +217,7 @@ static bool create_links(
                link_init_params.connector_index = i;
                link_init_params.link_index = dc->link_count;
                link_init_params.dc = dc;
-               link = link_create(&link_init_params);
+               link = dc->link_srv->create_link(&link_init_params);
 
                if (link) {
                        dc->links[dc->link_count] = link;
@@ -239,7 +239,7 @@ static bool create_links(
                link_init_params.dc = dc;
                link_init_params.is_dpia_link = true;
 
-               link = link_create(&link_init_params);
+               link = dc->link_srv->create_link(&link_init_params);
                if (link) {
                        dc->links[dc->link_count] = link;
                        link->dc = dc;
@@ -823,6 +823,9 @@ static void dc_destruct(struct dc *dc)
 
        dc_destroy_resource_pool(dc);
 
+       if (dc->link_srv)
+               link_destroy_link_service(&dc->link_srv);
+
        if (dc->ctx->gpio_service)
                dal_gpio_service_destroy(&dc->ctx->gpio_service);
 
@@ -982,7 +985,7 @@ static bool dc_construct(struct dc *dc,
                goto fail;
        }
 
-       dc->link_srv = link_get_link_service();
+       dc->link_srv = link_create_link_service();
 
        dc->res_pool = dc_create_resource_pool(dc, init_params, dc_ctx->dce_version);
        if (!dc->res_pool)
@@ -1263,7 +1266,7 @@ static void disable_vbios_mode_if_required(
                                                pipe->stream_res.pix_clk_params.requested_pix_clk_100hz;
 
                                        if (pix_clk_100hz != requested_pix_clk_100hz) {
-                                               link_set_dpms_off(pipe);
+                                               dc->link_srv->set_dpms_off(pipe);
                                                pipe->stream->dpms_off = false;
                                        }
                                }
@@ -1718,7 +1721,7 @@ bool dc_validate_boot_timing(const struct dc *dc,
                return false;
        }
 
-       if (link_is_edp_ilr_optimization_required(link, crtc_timing)) {
+       if (dc->link_srv->edp_is_ilr_optimization_required(link, crtc_timing)) {
                DC_LOG_EVENT_LINK_TRAINING("Seamless boot disabled to optimize eDP link rate\n");
                return false;
        }
@@ -3192,7 +3195,9 @@ static void commit_planes_do_stream_update(struct dc *dc,
                                dc->hwss.update_info_frame(pipe_ctx);
 
                                if (dc_is_dp_signal(pipe_ctx->stream->signal))
-                                       link_dp_source_sequence_trace(pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
+                                       dc->link_srv->dp_trace_source_sequence(
+                                                       pipe_ctx->stream->link,
+                                                       DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
                        }
 
                        if (stream_update->hdr_static_metadata &&
@@ -3228,13 +3233,15 @@ static void commit_planes_do_stream_update(struct dc *dc,
                                continue;
 
                        if (stream_update->dsc_config)
-                               link_update_dsc_config(pipe_ctx);
+                               dc->link_srv->update_dsc_config(pipe_ctx);
 
                        if (stream_update->mst_bw_update) {
                                if (stream_update->mst_bw_update->is_increase)
-                                       link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+                                       dc->link_srv->increase_mst_payload(pipe_ctx,
+                                                       stream_update->mst_bw_update->mst_stream_bw);
                                else
-                                       link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw);
+                                       dc->link_srv->reduce_mst_payload(pipe_ctx,
+                                                       stream_update->mst_bw_update->mst_stream_bw);
                        }
 
                        if (stream_update->pending_test_pattern) {
@@ -3248,7 +3255,7 @@ static void commit_planes_do_stream_update(struct dc *dc,
 
                        if (stream_update->dpms_off) {
                                if (*stream_update->dpms_off) {
-                                       link_set_dpms_off(pipe_ctx);
+                                       dc->link_srv->set_dpms_off(pipe_ctx);
                                        /* for dpms, keep acquired resources*/
                                        if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only)
                                                pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
@@ -3258,7 +3265,7 @@ static void commit_planes_do_stream_update(struct dc *dc,
                                } else {
                                        if (get_seamless_boot_stream_count(context) == 0)
                                                dc->hwss.prepare_bandwidth(dc, dc->current_state);
-                                       link_set_dpms_on(dc->current_state, pipe_ctx);
+                                       dc->link_srv->set_dpms_on(dc->current_state, pipe_ctx);
                                }
                        }
 
@@ -4322,7 +4329,7 @@ void dc_resume(struct dc *dc)
        uint32_t i;
 
        for (i = 0; i < dc->link_count; i++)
-               link_resume(dc->links[i]);
+               dc->link_srv->resume(dc->links[i]);
 }
 
 bool dc_is_dmcu_initialized(struct dc *dc)
index 74e465b..41198c7 100644 (file)
@@ -48,7 +48,7 @@ static bool is_dig_link_enc_stream(struct dc_stream_state *stream)
                                        /* DIGs do not support DP2.0 streams with 128b/132b encoding. */
                                        struct dc_link_settings link_settings = {0};
 
-                                       link_decide_link_settings(stream, &link_settings);
+                                       stream->ctx->dc->link_srv->dp_decide_link_settings(stream, &link_settings);
                                        if ((link_settings.link_rate >= LINK_RATE_LOW) &&
                                                        link_settings.link_rate <= LINK_RATE_HIGH3) {
                                                is_dig_stream = true;
index 217c80d..58fa911 100644 (file)
@@ -80,67 +80,63 @@ bool dc_get_edp_link_panel_inst(const struct dc *dc,
 
 bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
 {
-       return link_detect(link, reason);
+       return link->dc->link_srv->detect_link(link, reason);
 }
 
 bool dc_link_detect_connection_type(struct dc_link *link,
                enum dc_connection_type *type)
 {
-       return link_detect_connection_type(link, type);
+       return link->dc->link_srv->detect_connection_type(link, type);
 }
 
 const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
 {
-       return link_get_status(link);
+       return link->dc->link_srv->get_status(link);
 }
 
 /* return true if the connected receiver supports the hdcp version */
 bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal)
 {
-       return link_is_hdcp14(link, signal);
+       return link->dc->link_srv->is_hdcp1x_supported(link, signal);
 }
 
 bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal)
 {
-       return link_is_hdcp22(link, signal);
+       return link->dc->link_srv->is_hdcp2x_supported(link, signal);
 }
 
 void dc_link_clear_dprx_states(struct dc_link *link)
 {
-       link_clear_dprx_states(link);
+       link->dc->link_srv->clear_dprx_states(link);
 }
 
 bool dc_link_reset_cur_dp_mst_topology(struct dc_link *link)
 {
-       return link_reset_cur_dp_mst_topology(link);
+       return link->dc->link_srv->reset_cur_dp_mst_topology(link);
 }
 
 uint32_t dc_link_bandwidth_kbps(
        const struct dc_link *link,
        const struct dc_link_settings *link_settings)
 {
-       return dp_link_bandwidth_kbps(link, link_settings);
-}
-
-uint32_t dc_bandwidth_in_kbps_from_timing(
-       const struct dc_crtc_timing *timing)
-{
-       return link_timing_bandwidth_kbps(timing);
+       return link->dc->link_srv->dp_link_bandwidth_kbps(link, link_settings);
 }
 
 void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map)
 {
-       link_get_cur_res_map(dc, map);
+       dc->link_srv->get_cur_res_map(dc, map);
 }
 
 void dc_restore_link_res_map(const struct dc *dc, uint32_t *map)
 {
-       link_restore_res_map(dc, map);
+       dc->link_srv->restore_res_map(dc, map);
 }
 
 bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx)
 {
-       return link_update_dsc_config(pipe_ctx);
+       struct dc_link *link = pipe_ctx->stream->link;
+
+       return link->dc->link_srv->update_dsc_config(pipe_ctx);
 }
 
 bool dc_is_oem_i2c_device_present(
@@ -210,8 +206,8 @@ void dc_link_set_drive_settings(struct dc *dc,
 {
        struct link_resource link_res;
 
-       link_get_cur_link_res(link, &link_res);
-       dp_set_drive_settings(link, &link_res, lt_settings);
+       dc->link_srv->get_cur_link_res(link, &link_res);
+       dc->link_srv->dp_set_drive_settings(link, &link_res, lt_settings);
 }
 
 void dc_link_set_preferred_link_settings(struct dc *dc,
index 2e3b2fd..85d54bf 100644 (file)
@@ -2213,7 +2213,7 @@ enum dc_status dc_remove_stream_from_ctx(
                        del_pipe->stream_res.stream_enc,
                        false);
 
-       if (link_is_dp_128b_132b_signal(del_pipe)) {
+       if (dc->link_srv->dp_is_128b_132b_signal(del_pipe)) {
                update_hpo_dp_stream_engine_usage(
                        &new_ctx->res_ctx, dc->res_pool,
                        del_pipe->stream_res.hpo_dp_stream_enc,
@@ -2513,9 +2513,10 @@ enum dc_status resource_map_pool_resources(
         * and link settings
         */
        if (dc_is_dp_signal(stream->signal)) {
-               if (!link_decide_link_settings(stream, &pipe_ctx->link_config.dp_link_settings))
+               if (!dc->link_srv->dp_decide_link_settings(stream, &pipe_ctx->link_config.dp_link_settings))
                        return DC_FAIL_DP_LINK_BANDWIDTH;
-               if (link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) {
+               if (dc->link_srv->dp_get_encoding_format(
+                               &pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) {
                        pipe_ctx->stream_res.hpo_dp_stream_enc =
                                        find_first_free_match_hpo_dp_stream_enc_for_link(
                                                        &context->res_ctx, pool, stream);
@@ -3685,7 +3686,7 @@ enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
        /* TODO: validate audio ASIC caps, encoder */
 
        if (res == DC_OK)
-               res = link_validate_mode_timing(stream,
+               res = dc->link_srv->validate_mode_timing(stream,
                      link,
                      &stream->timing);
 
@@ -3812,7 +3813,7 @@ bool get_temp_dp_link_res(struct dc_link *link,
 
        memset(link_res, 0, sizeof(*link_res));
 
-       if (link_dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
+       if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
                link_res->hpo_dp_link_enc = get_temp_hpo_dp_link_enc(res_ctx,
                                dc->res_pool, link);
                if (!link_res->hpo_dp_link_enc)
@@ -4046,7 +4047,7 @@ enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,
                struct dc_state *context,
                struct pipe_ctx *pipe_ctx)
 {
-       if (link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) {
+       if (dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) {
                if (pipe_ctx->stream_res.hpo_dp_stream_enc == NULL) {
                        pipe_ctx->stream_res.hpo_dp_stream_enc =
                                        find_first_free_match_hpo_dp_stream_enc_for_link(
index ccc27d4..3f25a16 100644 (file)
@@ -889,7 +889,7 @@ struct dc {
 
        uint8_t link_count;
        struct dc_link *links[MAX_PIPES * 2];
-       const struct link_service *link_srv;
+       struct link_service *link_srv;
 
        struct dc_state *current_state;
        struct resource_pool *res_pool;
@@ -1370,6 +1370,11 @@ struct dc_plane_state *dc_get_surface_for_mpcc(struct dc *dc,
 
 uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane);
 
+/* The function returns minimum bandwidth required to drive a given timing
+ * return - minimum required timing bandwidth in kbps.
+ */
+uint32_t dc_bandwidth_in_kbps_from_timing(const struct dc_crtc_timing *timing);
+
 /* Link Interfaces */
 /*
  * A link contains one or more sinks and their connected status.
@@ -1724,12 +1729,6 @@ uint32_t dc_link_bandwidth_kbps(
        const struct dc_link *link,
        const struct dc_link_settings *link_setting);
 
-/* The function returns minimum bandwidth required to drive a given timing
- * return - minimum required timing bandwidth in kbps.
- */
-uint32_t dc_bandwidth_in_kbps_from_timing(
-       const struct dc_crtc_timing *timing);
-
 /* The function takes a snapshot of current link resource allocation state
  * @dc: pointer to dc of the dm calling this
  * @map: a dc link resource snapshot defined internally to dc.
index cb3bb54..9fe0ce9 100644 (file)
@@ -741,7 +741,7 @@ void dce110_edp_wait_for_hpd_ready(
 
        /* obtain HPD */
        /* TODO what to do with this? */
-       hpd = link_get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service);
+       hpd = ctx->dc->link_srv->get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service);
 
        if (!hpd) {
                BREAK_TO_DEBUGGER();
@@ -809,19 +809,19 @@ void dce110_edp_power_control(
                                div64_u64(dm_get_elapse_time_in_ns(
                                                ctx,
                                                current_ts,
-                                               link_dp_trace_get_edp_poweroff_timestamp(link)), 1000000);
+                                               ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link)), 1000000);
                unsigned long long time_since_edp_poweron_ms =
                                div64_u64(dm_get_elapse_time_in_ns(
                                                ctx,
                                                current_ts,
-                                               link_dp_trace_get_edp_poweron_timestamp(link)), 1000000);
+                                               ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link)), 1000000);
                DC_LOG_HW_RESUME_S3(
                                "%s: transition: power_up=%d current_ts=%llu edp_poweroff=%llu edp_poweron=%llu time_since_edp_poweroff_ms=%llu time_since_edp_poweron_ms=%llu",
                                __func__,
                                power_up,
                                current_ts,
-                               link_dp_trace_get_edp_poweroff_timestamp(link),
-                               link_dp_trace_get_edp_poweron_timestamp(link),
+                               ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link),
+                               ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link),
                                time_since_edp_poweroff_ms,
                                time_since_edp_poweron_ms);
 
@@ -836,7 +836,7 @@ void dce110_edp_power_control(
                                        link->panel_config.pps.extra_t12_ms;
 
                        /* Adjust remaining_min_edp_poweroff_time_ms if this is not the first time. */
-                       if (link_dp_trace_get_edp_poweroff_timestamp(link) != 0) {
+                       if (ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link) != 0) {
                                if (time_since_edp_poweroff_ms < remaining_min_edp_poweroff_time_ms)
                                        remaining_min_edp_poweroff_time_ms =
                                                remaining_min_edp_poweroff_time_ms - time_since_edp_poweroff_ms;
@@ -896,13 +896,13 @@ void dce110_edp_power_control(
                                __func__, (power_up ? "On":"Off"),
                                bp_result);
 
-               link_dp_trace_set_edp_power_timestamp(link, power_up);
+               ctx->dc->link_srv->dp_trace_set_edp_power_timestamp(link, power_up);
 
                DC_LOG_HW_RESUME_S3(
                                "%s: updated values: edp_poweroff=%llu edp_poweron=%llu\n",
                                __func__,
-                               link_dp_trace_get_edp_poweroff_timestamp(link),
-                               link_dp_trace_get_edp_poweron_timestamp(link));
+                               ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link),
+                               ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link));
 
                if (bp_result != BP_RESULT_OK)
                        DC_LOG_ERROR(
@@ -930,14 +930,14 @@ void dce110_edp_wait_for_T12(
                return;
 
        if (!link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl) &&
-                       link_dp_trace_get_edp_poweroff_timestamp(link) != 0) {
+                       ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link) != 0) {
                unsigned int t12_duration = 500; // Default T12 as per spec
                unsigned long long current_ts = dm_get_timestamp(ctx);
                unsigned long long time_since_edp_poweroff_ms =
                                div64_u64(dm_get_elapse_time_in_ns(
                                                ctx,
                                                current_ts,
-                                               link_dp_trace_get_edp_poweroff_timestamp(link)), 1000000);
+                                               ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link)), 1000000);
 
                t12_duration += link->panel_config.pps.extra_t12_ms; // Add extra T12
 
@@ -1018,7 +1018,7 @@ void dce110_edp_backlight_control(
                 * we shouldn't be doing power-sequencing, hence we can skip
                 * waiting for T7-ready.
                 */
-                       link_edp_receiver_ready_T7(link);
+                       ctx->dc->link_srv->edp_receiver_ready_T7(link);
                else
                        DC_LOG_DC("edp_receiver_ready_T7 skipped\n");
        }
@@ -1049,7 +1049,7 @@ void dce110_edp_backlight_control(
        if (link->dpcd_sink_ext_caps.bits.oled ||
                link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 ||
                link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)
-               link_backlight_enable_aux(link, enable);
+               ctx->dc->link_srv->edp_backlight_enable_aux(link, enable);
 
        /*edp 1.2*/
        if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) {
@@ -1061,7 +1061,7 @@ void dce110_edp_backlight_control(
                 * we shouldn't be doing power-sequencing, hence we can skip
                 * waiting for T9-ready.
                 */
-                       link_edp_add_delay_for_T9(link);
+                       ctx->dc->link_srv->edp_add_delay_for_T9(link);
                else
                        DC_LOG_DC("edp_receiver_ready_T9 skipped\n");
        }
@@ -1161,7 +1161,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
                        pipe_ctx->stream_res.stream_enc);
        }
 
-       if (link_is_dp_128b_132b_signal(pipe_ctx)) {
+       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
                pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->stop_dp_info_packets(
                                        pipe_ctx->stream_res.hpo_dp_stream_enc);
        } else if (dc_is_dp_signal(pipe_ctx->stream->signal))
@@ -1172,7 +1172,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
 
        link_hwss->reset_stream_encoder(pipe_ctx);
 
-       if (link_is_dp_128b_132b_signal(pipe_ctx)) {
+       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
                dto_params.otg_inst = tg->inst;
                dto_params.timing = &pipe_ctx->stream->timing;
                dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
@@ -1181,7 +1181,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
                dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst);
        }
 
-       if (link_is_dp_128b_132b_signal(pipe_ctx)) {
+       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
                /* TODO: This looks like a bug to me as we are disabling HPO IO when
                 * we are just disabling a single HPO stream. Shouldn't we disable HPO
                 * HW control only when HPOs for all streams are disabled?
@@ -1223,7 +1223,7 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
                link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
        }
 
-       if (link_is_dp_128b_132b_signal(pipe_ctx)) {
+       if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
                /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
                pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_blank(
                                pipe_ctx->stream_res.hpo_dp_stream_enc);
@@ -1245,7 +1245,7 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
                                 * we shouldn't be doing power-sequencing, hence we can skip
                                 * waiting for T9-ready.
                                 */
-                               link_edp_receiver_ready_T9(link);
+                               link->dc->link_srv->edp_receiver_ready_T9(link);
                        }
                }
        }
@@ -1428,7 +1428,7 @@ static enum dc_status dce110_enable_stream_timing(
                if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
                                pipe_ctx->clock_source,
                                &pipe_ctx->stream_res.pix_clk_params,
-                               link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings),
+                               dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings),
                                &pipe_ctx->pll_settings)) {
                        BREAK_TO_DEBUGGER();
                        return DC_ERROR_UNEXPECTED;
@@ -1532,7 +1532,7 @@ static enum dc_status apply_single_controller_ctx_to_hw(
         * To do so, move calling function enable_stream_timing to only be done AFTER calling
         * function core_link_enable_stream
         */
-       if (!(hws->wa.dp_hpo_and_otg_sequence && link_is_dp_128b_132b_signal(pipe_ctx)))
+       if (!(hws->wa.dp_hpo_and_otg_sequence && dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)))
                /*  */
                /* Do not touch stream timing on seamless boot optimization. */
                if (!pipe_ctx->stream->apply_seamless_boot_optimization)
@@ -1564,17 +1564,17 @@ static enum dc_status apply_single_controller_ctx_to_hw(
                        pipe_ctx->stream_res.tg->inst);
 
        if (dc_is_dp_signal(pipe_ctx->stream->signal))
-               link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG);
+               dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG);
 
        if (!stream->dpms_off)
-               link_set_dpms_on(context, pipe_ctx);
+               dc->link_srv->set_dpms_on(context, pipe_ctx);
 
        /* DCN3.1 FPGA Workaround
         * Need to enable HPO DP Stream Encoder before setting OTG master enable.
         * To do so, move calling function enable_stream_timing to only be done AFTER calling
         * function core_link_enable_stream
         */
-       if (hws->wa.dp_hpo_and_otg_sequence && link_is_dp_128b_132b_signal(pipe_ctx)) {
+       if (hws->wa.dp_hpo_and_otg_sequence && dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
                if (!pipe_ctx->stream->apply_seamless_boot_optimization)
                        hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
        }
@@ -1600,7 +1600,7 @@ static void power_down_encoders(struct dc *dc)
        for (i = 0; i < dc->link_count; i++) {
                enum signal_type signal = dc->links[i]->connector_signal;
 
-               link_blank_dp_stream(dc->links[i], false);
+               dc->link_srv->blank_dp_stream(dc->links[i], false);
 
                if (signal != SIGNAL_TYPE_EDP)
                        signal = SIGNAL_TYPE_NONE;
@@ -2083,7 +2083,7 @@ static void dce110_reset_hw_ctx_wrap(
                         * disabled already, no need to disable again.
                         */
                        if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) {
-                               link_set_dpms_off(pipe_ctx_old);
+                               dc->link_srv->set_dpms_off(pipe_ctx_old);
 
                                /* free acquired resources*/
                                if (pipe_ctx_old->stream_res.audio) {
@@ -3054,13 +3054,13 @@ void dce110_enable_dp_link_output(
                                pipes[i].clock_source->funcs->program_pix_clk(
                                                pipes[i].clock_source,
                                                &pipes[i].stream_res.pix_clk_params,
-                                               link_dp_get_encoding_format(link_settings),
+                                               dc->link_srv->dp_get_encoding_format(link_settings),
                                                &pipes[i].pll_settings);
                        }
                }
        }
 
-       if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
+       if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
                if (dc->clk_mgr->funcs->notify_link_rate_change)
                        dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
        }
@@ -3077,7 +3077,7 @@ void dce110_enable_dp_link_output(
        if (dmcu != NULL && dmcu->funcs->unlock_phy)
                dmcu->funcs->unlock_phy(dmcu);
 
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
+       dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
 }
 
 void dce110_disable_link_output(struct dc_link *link,
@@ -3102,7 +3102,7 @@ void dce110_disable_link_output(struct dc_link *link,
                link->dc->hwss.edp_power_control(link, false);
        else if (dmcu != NULL && dmcu->funcs->lock_phy)
                dmcu->funcs->unlock_phy(dmcu);
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
+       dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
 }
 
 static const struct hw_sequencer_funcs dce110_funcs = {
index 5b34066..7f9cceb 100644 (file)
@@ -919,7 +919,7 @@ enum dc_status dcn10_enable_stream_timing(
        if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
                        pipe_ctx->clock_source,
                        &pipe_ctx->stream_res.pix_clk_params,
-                       link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings),
+                       dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings),
                        &pipe_ctx->pll_settings)) {
                BREAK_TO_DEBUGGER();
                return DC_ERROR_UNEXPECTED;
@@ -1017,7 +1017,7 @@ static void dcn10_reset_back_end_for_pipe(
                 * VBIOS lit up eDP, so check link status too.
                 */
                if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
-                       link_set_dpms_off(pipe_ctx);
+                       dc->link_srv->set_dpms_off(pipe_ctx);
                else if (pipe_ctx->stream_res.audio)
                        dc->hwss.disable_audio_stream(pipe_ctx);
 
@@ -1564,7 +1564,7 @@ void dcn10_init_hw(struct dc *dc)
        }
 
        /* we want to turn off all dp displays before doing detection */
-       link_blank_all_dp_displays(dc);
+       dc->link_srv->blank_all_dp_displays(dc);
 
        if (hws->funcs.enable_power_gating_plane)
                hws->funcs.enable_power_gating_plane(dc->hwseq, true);
index 2e5f8dc..f496e95 100644 (file)
@@ -933,7 +933,7 @@ void enc1_stream_encoder_dp_blank(
        /* disable DP stream */
        REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0);
 
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_DP_VID_STREAM);
+       link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_DP_VID_STREAM);
 
        /* the encoder stops sending the video stream
         * at the start of the vertical blanking.
@@ -952,7 +952,7 @@ void enc1_stream_encoder_dp_blank(
 
        REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, true);
 
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_FIFO_STEER_RESET);
+       link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_FIFO_STEER_RESET);
 }
 
 /* output video stream to link encoder */
@@ -1025,7 +1025,8 @@ void enc1_stream_encoder_dp_unblank(
 
        REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true);
 
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
+       link->dc->link_srv->dp_trace_source_sequence(link,
+                       DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
 }
 
 void enc1_stream_encoder_set_avmute(
index 8b5181f..53669f8 100644 (file)
@@ -720,7 +720,7 @@ enum dc_status dcn20_enable_stream_timing(
        if (false == pipe_ctx->clock_source->funcs->program_pix_clk(
                        pipe_ctx->clock_source,
                        &pipe_ctx->stream_res.pix_clk_params,
-                       link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings),
+                       dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings),
                        &pipe_ctx->pll_settings)) {
                BREAK_TO_DEBUGGER();
                return DC_ERROR_UNEXPECTED;
@@ -2405,7 +2405,7 @@ void dcn20_unblank_stream(struct pipe_ctx *pipe_ctx,
 
        params.link_settings.link_rate = link_settings->link_rate;
 
-       if (link_is_dp_128b_132b_signal(pipe_ctx)) {
+       if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
                /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
                pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_unblank(
                                pipe_ctx->stream_res.hpo_dp_stream_enc,
@@ -2458,7 +2458,7 @@ static void dcn20_reset_back_end_for_pipe(
                 * VBIOS lit up eDP, so check link status too.
                 */
                if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
-                       link_set_dpms_off(pipe_ctx);
+                       dc->link_srv->set_dpms_off(pipe_ctx);
                else if (pipe_ctx->stream_res.audio)
                        dc->hwss.disable_audio_stream(pipe_ctx);
 
@@ -2478,7 +2478,7 @@ static void dcn20_reset_back_end_for_pipe(
                }
        }
        else if (pipe_ctx->stream_res.dsc) {
-               link_set_dsc_enable(pipe_ctx, false);
+               dc->link_srv->set_dsc_enable(pipe_ctx, false);
        }
 
        /* by upper caller loop, parent pipe: pipe0, will be reset last.
@@ -2713,12 +2713,12 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
        unsigned int k1_div = PIXEL_RATE_DIV_NA;
        unsigned int k2_div = PIXEL_RATE_DIV_NA;
 
-       if (link_is_dp_128b_132b_signal(pipe_ctx)) {
+       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
                if (dc->hwseq->funcs.setup_hpo_hw_control)
                        dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, true);
        }
 
-       if (link_is_dp_128b_132b_signal(pipe_ctx)) {
+       if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
                dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
                dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, dp_hpo_inst);
 
@@ -2752,7 +2752,7 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
        dc->hwss.update_info_frame(pipe_ctx);
 
        if (dc_is_dp_signal(pipe_ctx->stream->signal))
-               link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
+               dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
 
        /* enable early control to avoid corruption on DP monitor*/
        active_total_with_borders =
index 00668df..77ef474 100644 (file)
@@ -1211,8 +1211,11 @@ static void dcn20_resource_destruct(struct dcn20_resource_pool *pool)
        if (pool->base.pp_smu != NULL)
                dcn20_pp_smu_destroy(&pool->base.pp_smu);
 
-       if (pool->base.oem_device != NULL)
-               link_destroy_ddc_service(&pool->base.oem_device);
+       if (pool->base.oem_device != NULL) {
+               struct dc *dc = pool->base.oem_device->ctx->dc;
+
+               dc->link_srv->destroy_ddc_service(&pool->base.oem_device);
+       }
 }
 
 struct hubp *dcn20_hubp_create(
@@ -2763,7 +2766,7 @@ static bool dcn20_resource_construct(
                ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
                ddc_init_data.id.enum_id = 0;
                ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
-               pool->base.oem_device = link_create_ddc_service(&ddc_init_data);
+               pool->base.oem_device = dc->link_srv->create_ddc_service(&ddc_init_data);
        } else {
                pool->base.oem_device = NULL;
        }
index 42865d6..0b47aeb 100644 (file)
@@ -546,7 +546,8 @@ void enc2_stream_encoder_dp_unblank(
 
        REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true);
 
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
+       link->dc->link_srv->dp_trace_source_sequence(link,
+                       DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
 }
 
 static void enc2_dp_set_odm_combine(
index 15475c7..2a182c2 100644 (file)
@@ -132,8 +132,8 @@ void dcn21_PLAT_58856_wa(struct dc_state *context, struct pipe_ctx *pipe_ctx)
                return;
 
        pipe_ctx->stream->dpms_off = false;
-       link_set_dpms_on(context, pipe_ctx);
-       link_set_dpms_off(pipe_ctx);
+       pipe_ctx->stream->ctx->dc->link_srv->set_dpms_on(context, pipe_ctx);
+       pipe_ctx->stream->ctx->dc->link_srv->set_dpms_off(pipe_ctx);
        pipe_ctx->stream->dpms_off = true;
 }
 
index f8733ff..586de81 100644 (file)
@@ -532,7 +532,7 @@ void dcn30_init_hw(struct dc *dc)
        }
 
        /* we want to turn off all dp displays before doing detection */
-       link_blank_all_dp_displays(dc);
+       dc->link_srv->blank_all_dp_displays(dc);
 
        if (hws->funcs.enable_power_gating_plane)
                hws->funcs.enable_power_gating_plane(dc->hwseq, true);
index d60c17d..c9e45da 100644 (file)
@@ -1205,8 +1205,11 @@ static void dcn30_resource_destruct(struct dcn30_resource_pool *pool)
        if (pool->base.dccg != NULL)
                dcn_dccg_destroy(&pool->base.dccg);
 
-       if (pool->base.oem_device != NULL)
-               link_destroy_ddc_service(&pool->base.oem_device);
+       if (pool->base.oem_device != NULL) {
+               struct dc *dc = pool->base.oem_device->ctx->dc;
+
+               dc->link_srv->destroy_ddc_service(&pool->base.oem_device);
+       }
 }
 
 static struct hubp *dcn30_hubp_create(
@@ -2590,7 +2593,7 @@ static bool dcn30_resource_construct(
                ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
                ddc_init_data.id.enum_id = 0;
                ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
-               pool->base.oem_device = link_create_ddc_service(&ddc_init_data);
+               pool->base.oem_device = dc->link_srv->create_ddc_service(&ddc_init_data);
        } else {
                pool->base.oem_device = NULL;
        }
index 6ccad53..9f93c43 100644 (file)
@@ -1125,8 +1125,11 @@ static void dcn302_resource_destruct(struct resource_pool *pool)
        if (pool->dccg != NULL)
                dcn_dccg_destroy(&pool->dccg);
 
-       if (pool->oem_device != NULL)
-               link_destroy_ddc_service(&pool->oem_device);
+       if (pool->oem_device != NULL) {
+               struct dc *dc = pool->oem_device->ctx->dc;
+
+               dc->link_srv->destroy_ddc_service(&pool->oem_device);
+       }
 }
 
 static void dcn302_destroy_resource_pool(struct resource_pool **pool)
@@ -1506,7 +1509,7 @@ static bool dcn302_resource_construct(
                ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
                ddc_init_data.id.enum_id = 0;
                ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
-               pool->oem_device = link_create_ddc_service(&ddc_init_data);
+               pool->oem_device = dc->link_srv->create_ddc_service(&ddc_init_data);
        } else {
                pool->oem_device = NULL;
        }
index 5c28f71..7f72ef8 100644 (file)
@@ -1051,8 +1051,11 @@ static void dcn303_resource_destruct(struct resource_pool *pool)
        if (pool->dccg != NULL)
                dcn_dccg_destroy(&pool->dccg);
 
-       if (pool->oem_device != NULL)
-               link_destroy_ddc_service(&pool->oem_device);
+       if (pool->oem_device != NULL) {
+               struct dc *dc = pool->oem_device->ctx->dc;
+
+               dc->link_srv->destroy_ddc_service(&pool->oem_device);
+       }
 }
 
 static void dcn303_destroy_resource_pool(struct resource_pool **pool)
@@ -1417,7 +1420,7 @@ static bool dcn303_resource_construct(
                ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
                ddc_init_data.id.enum_id = 0;
                ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
-               pool->oem_device = link_create_ddc_service(&ddc_init_data);
+               pool->oem_device = dc->link_srv->create_ddc_service(&ddc_init_data);
        } else {
                pool->oem_device = NULL;
        }
index 80a0c5a..10e3cc1 100644 (file)
@@ -202,7 +202,7 @@ void dcn31_init_hw(struct dc *dc)
                dmub_enable_outbox_notification(dc->ctx->dmub_srv);
 
        /* we want to turn off all dp displays before doing detection */
-       link_blank_all_dp_displays(dc);
+       dc->link_srv->blank_all_dp_displays(dc);
 
        if (hws->funcs.enable_power_gating_plane)
                hws->funcs.enable_power_gating_plane(dc->hwseq, true);
@@ -230,7 +230,7 @@ void dcn31_init_hw(struct dc *dc)
                                }
 
                                if (num_opps > 1) {
-                                       link_blank_all_edp_displays(dc);
+                                       dc->link_srv->blank_all_edp_displays(dc);
                                        break;
                                }
                        }
@@ -414,7 +414,7 @@ void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx)
                pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets(
                        pipe_ctx->stream_res.stream_enc,
                        &pipe_ctx->stream_res.encoder_info_frame);
-       else if (link_is_dp_128b_132b_signal(pipe_ctx)) {
+       else if (pipe_ctx->stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
                pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->update_dp_info_packets(
                                pipe_ctx->stream_res.hpo_dp_stream_enc,
                                &pipe_ctx->stream_res.encoder_info_frame);
@@ -565,7 +565,7 @@ static void dcn31_reset_back_end_for_pipe(
                 * VBIOS lit up eDP, so check link status too.
                 */
                if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
-                       link_set_dpms_off(pipe_ctx);
+                       dc->link_srv->set_dpms_off(pipe_ctx);
                else if (pipe_ctx->stream_res.audio)
                        dc->hwss.disable_audio_stream(pipe_ctx);
 
@@ -584,7 +584,7 @@ static void dcn31_reset_back_end_for_pipe(
                        }
                }
        } else if (pipe_ctx->stream_res.dsc) {
-                       link_set_dsc_enable(pipe_ctx, false);
+               dc->link_srv->set_dsc_enable(pipe_ctx, false);
        }
 
        pipe_ctx->stream = NULL;
index 742e43c..467509a 100644 (file)
@@ -372,7 +372,7 @@ static void enc314_stream_encoder_dp_unblank(
         */
        enc314_enable_fifo(enc);
 
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
+       link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
 }
 
 /* Set DSC-related configuration.
index 575d350..bcc0342 100644 (file)
@@ -346,7 +346,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
        two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing);
        odm_combine_factor = get_odm_config(pipe_ctx, NULL);
 
-       if (link_is_dp_128b_132b_signal(pipe_ctx)) {
+       if (stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
                *k1_div = PIXEL_RATE_DIV_BY_1;
                *k2_div = PIXEL_RATE_DIV_BY_1;
        } else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
index ccf6b18..c724481 100644 (file)
@@ -371,7 +371,7 @@ static void enc32_stream_encoder_dp_unblank(
 
        REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true);
 
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
+       link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
 }
 
 /* Set DSC-related configuration.
index f87db22..5016b13 100644 (file)
@@ -801,7 +801,7 @@ void dcn32_init_hw(struct dc *dc)
                hws->funcs.enable_power_gating_plane(dc->hwseq, true);
 
        /* we want to turn off all dp displays before doing detection */
-       link_blank_all_dp_displays(dc);
+       dc->link_srv->blank_all_dp_displays(dc);
 
        /* If taking control over from VBIOS, we may want to optimize our first
         * mode set, so we need to skip powering down pipes until we know which
@@ -1102,7 +1102,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign
        two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing);
        odm_combine_factor = get_odm_config(pipe_ctx, NULL);
 
-       if (link_is_dp_128b_132b_signal(pipe_ctx)) {
+       if (stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
                *k1_div = PIXEL_RATE_DIV_BY_1;
                *k2_div = PIXEL_RATE_DIV_BY_1;
        } else if (dc_is_hdmi_tmds_signal(stream->signal) || dc_is_dvi_signal(stream->signal)) {
@@ -1166,7 +1166,7 @@ void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx,
 
        params.link_settings.link_rate = link_settings->link_rate;
 
-       if (link_is_dp_128b_132b_signal(pipe_ctx)) {
+       if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
                /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
                pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_unblank(
                                pipe_ctx->stream_res.hpo_dp_stream_enc,
@@ -1193,7 +1193,7 @@ bool dcn32_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx)
        if (!is_h_timing_divisible_by_2(pipe_ctx->stream))
                return false;
 
-       if (dc_is_dp_signal(pipe_ctx->stream->signal) && !link_is_dp_128b_132b_signal(pipe_ctx) &&
+       if (dc_is_dp_signal(pipe_ctx->stream->signal) && !dc->link_srv->dp_is_128b_132b_signal(pipe_ctx) &&
                dc->debug.enable_dp_dig_pixel_rate_div_policy)
                return true;
        return false;
@@ -1227,7 +1227,8 @@ static void apply_symclk_on_tx_off_wa(struct dc_link *link)
                                pipe_ctx->clock_source->funcs->program_pix_clk(
                                                pipe_ctx->clock_source,
                                                &pipe_ctx->stream_res.pix_clk_params,
-                                               link_dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings),
+                                               dc->link_srv->dp_get_encoding_format(
+                                                               &pipe_ctx->link_config.dp_link_settings),
                                                &pipe_ctx->pll_settings);
                                link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
                                break;
@@ -1259,7 +1260,7 @@ void dcn32_disable_link_output(struct dc_link *link,
        else if (dmcu != NULL && dmcu->funcs->lock_phy)
                dmcu->funcs->unlock_phy(dmcu);
 
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
+       dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
 
        apply_symclk_on_tx_off_wa(link);
 }
index 100b6df..f6f72e7 100644 (file)
@@ -1505,8 +1505,11 @@ static void dcn32_resource_destruct(struct dcn32_resource_pool *pool)
        if (pool->base.dccg != NULL)
                dcn_dccg_destroy(&pool->base.dccg);
 
-       if (pool->base.oem_device != NULL)
-               link_destroy_ddc_service(&pool->base.oem_device);
+       if (pool->base.oem_device != NULL) {
+               struct dc *dc = pool->base.oem_device->ctx->dc;
+
+               dc->link_srv->destroy_ddc_service(&pool->base.oem_device);
+       }
 }
 
 
@@ -2451,7 +2454,7 @@ static bool dcn32_resource_construct(
                ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
                ddc_init_data.id.enum_id = 0;
                ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
-               pool->base.oem_device = link_create_ddc_service(&ddc_init_data);
+               pool->base.oem_device = dc->link_srv->create_ddc_service(&ddc_init_data);
        } else {
                pool->base.oem_device = NULL;
        }
index 0f477d5..c6a0e84 100644 (file)
@@ -1490,8 +1490,11 @@ static void dcn321_resource_destruct(struct dcn321_resource_pool *pool)
        if (pool->base.dccg != NULL)
                dcn_dccg_destroy(&pool->base.dccg);
 
-       if (pool->base.oem_device != NULL)
-               link_destroy_ddc_service(&pool->base.oem_device);
+       if (pool->base.oem_device != NULL) {
+               struct dc *dc = pool->base.oem_device->ctx->dc;
+
+               dc->link_srv->destroy_ddc_service(&pool->base.oem_device);
+       }
 }
 
 
@@ -1995,7 +1998,7 @@ static bool dcn321_resource_construct(
                ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
                ddc_init_data.id.enum_id = 0;
                ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
-               pool->base.oem_device = link_create_ddc_service(&ddc_init_data);
+               pool->base.oem_device = dc->link_srv->create_ddc_service(&ddc_init_data);
        } else {
                pool->base.oem_device = NULL;
        }
index f3cfc14..38d1f2b 100644 (file)
@@ -938,7 +938,7 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
        for (i = 0; i < dc->res_pool->pipe_count; i++) {
                if (!context->res_ctx.pipe_ctx[i].stream)
                        continue;
-               if (link_is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
+               if (dc->link_srv->dp_is_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
                        return true;
        }
        return false;
@@ -1341,7 +1341,7 @@ int dcn20_populate_dml_pipes_from_context(
                case SIGNAL_TYPE_DISPLAY_PORT_MST:
                case SIGNAL_TYPE_DISPLAY_PORT:
                        pipes[pipe_cnt].dout.output_type = dm_dp;
-                       if (link_is_dp_128b_132b_signal(&res_ctx->pipe_ctx[i]))
+                       if (dc->link_srv->dp_is_128b_132b_signal(&res_ctx->pipe_ctx[i]))
                                pipes[pipe_cnt].dout.output_type = dm_dp2p0;
                        break;
                case SIGNAL_TYPE_EDP:
index 077674b..6b29d3a 100644 (file)
@@ -1270,7 +1270,7 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
        for (i = 0; i < dc->res_pool->pipe_count; i++) {
                if (!context->res_ctx.pipe_ctx[i].stream)
                        continue;
-               if (link_is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
+               if (dc->link_srv->dp_is_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
                        return true;
        }
        return false;
index d9622a0..2bdc476 100644 (file)
@@ -47,6 +47,59 @@ static bool dsc_policy_disable_dsc_stream_overhead;
 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
 #endif
 
+uint32_t dc_bandwidth_in_kbps_from_timing(
+       const struct dc_crtc_timing *timing)
+{
+       uint32_t bits_per_channel = 0;
+       uint32_t kbps;
+
+       if (timing->flags.DSC)
+               return dc_dsc_stream_bandwidth_in_kbps(timing,
+                               timing->dsc_cfg.bits_per_pixel,
+                               timing->dsc_cfg.num_slices_h,
+                               timing->dsc_cfg.is_dp);
+
+       switch (timing->display_color_depth) {
+       case COLOR_DEPTH_666:
+               bits_per_channel = 6;
+               break;
+       case COLOR_DEPTH_888:
+               bits_per_channel = 8;
+               break;
+       case COLOR_DEPTH_101010:
+               bits_per_channel = 10;
+               break;
+       case COLOR_DEPTH_121212:
+               bits_per_channel = 12;
+               break;
+       case COLOR_DEPTH_141414:
+               bits_per_channel = 14;
+               break;
+       case COLOR_DEPTH_161616:
+               bits_per_channel = 16;
+               break;
+       default:
+               ASSERT(bits_per_channel != 0);
+               bits_per_channel = 8;
+               break;
+       }
+
+       kbps = timing->pix_clk_100hz / 10;
+       kbps *= bits_per_channel;
+
+       if (timing->flags.Y_ONLY != 1) {
+               /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/
+               kbps *= 3;
+               if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
+                       kbps /= 2;
+               else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
+                       kbps = kbps * 2 / 3;
+       }
+
+       return kbps;
+}
+
+
 /* Forward Declerations */
 static bool decide_dsc_bandwidth_range(
                const uint32_t min_bpp_x16,
index 45cdf3b..11aaa7a 100644 (file)
 
 /* FILE POLICY AND INTENDED USAGE:
  *
- * This header declares link functions exposed to dc. All functions must use
- * function pointers. This header is strictly private in dc and should never be
- * included by DM. If DM needs to call a new link function, it needs to be
- * translated by dc_link_exports.c.
+ * This header defines link component function interfaces aka link_service.
+ * link_service provides the only entry point to link functions with function
+ * pointer style. This header is strictly private in dc and should never be
+ * included by DM because it exposes too much dc detail including all dc
+ * private types defined in core_types.h. Otherwise it will break DM - DC
+ * encapsulation and turn DM into a maintenance nightmare.
+ *
+ * The following shows a link component relation map.
+ *
+ * DM to DC:
+ * DM includes dc.h
+ * dc_link_exports.c or other dc files implement dc.h
+ *
+ * DC to Link:
+ * dc_link_exports.c or other dc files include link.h
+ * link_factory.c implements link.h
+ *
+ * Link sub-component to Link sub-component:
+ * link_factory.c includes --> link_xxx.h
+ * link_xxx.c implements link_xxx.h
+
+ * As you can see if you ever need to add a new dc link function and call it on
+ * DM/dc side, it is very difficult because you will need layers of translation.
+ * The most appropriate approach to implement new requirements on DM/dc side is
+ * to extend or generalize the functionality of existing link function
+ * interfaces so minimal modification is needed outside link component to
+ * achieve your new requirements. This approach reduces or even eliminates the
+ * effort needed outside link component to support a new link feature. This also
+ * reduces code discrepancy among DMs to support the same link feature. If we
+ * test full code path on one version of DM, and there is no feature specific
+ * modification required on other DMs, then we can have higher confidence that
+ * the feature will run on other DMs and produce the same result. The following
+ * are some good examples to start with:
+ *
+ * - detect_link --> to add new link detection or capability retrieval routines
+ *
+ * - validate_mode_timing --> to add new timing validation conditions
+ *
+ * - set_dpms_on/set_dpms_off --> to include new link enablement sequences
+ *
+ * If you must add new link functions, you will need to:
+ * 1. declare the function pointer here under the suitable commented category.
+ * 2. Implement your function in the suitable link_xxx.c file.
+ * 3. Assign the function to link_service in link_factory.c
+ * 4. NEVER include link_xxx.h headers outside link component.
+ * 5. NEVER include link.h on DM side.
  */
 #include "core_types.h"
 
+struct link_service *link_create_link_service(void);
+void link_destroy_link_service(struct link_service **link_srv);
+
 struct link_init_data {
        const struct dc *dc;
        struct dc_context *ctx; /* TODO: remove 'dal' when DC is complete. */
@@ -44,8 +89,24 @@ struct link_init_data {
        bool is_dpia_link;
 };
 
+struct ddc_service_init_data {
+       struct graphics_object_id id;
+       struct dc_context *ctx;
+       struct dc_link *link;
+       bool is_dpia_link;
+};
+
 struct link_service {
-       /* Detection */
+       /************************** Factory ***********************************/
+       struct dc_link *(*create_link)(
+                       const struct link_init_data *init_params);
+       void (*destroy_link)(struct dc_link **link);
+
+
+       /************************** Detection *********************************/
+       bool (*detect_link)(struct dc_link *link, enum dc_detect_reason reason);
+       bool (*detect_connection_type)(struct dc_link *link,
+                       enum dc_connection_type *type);
        struct dc_sink *(*add_remote_sink)(
                        struct dc_link *link,
                        const uint8_t *edid,
@@ -53,24 +114,90 @@ struct link_service {
                        struct dc_sink_init_data *init_data);
        void (*remove_remote_sink)(struct dc_link *link, struct dc_sink *sink);
        bool (*get_hpd_state)(struct dc_link *link);
+       struct gpio *(*get_hpd_gpio)(struct dc_bios *dcb,
+                       struct graphics_object_id link_id,
+                       struct gpio_service *gpio_service);
        void (*enable_hpd)(const struct dc_link *link);
        void (*disable_hpd)(const struct dc_link *link);
        void (*enable_hpd_filter)(struct dc_link *link, bool enable);
+       bool (*reset_cur_dp_mst_topology)(struct dc_link *link);
+       const struct dc_link_status *(*get_status)(const struct dc_link *link);
+       bool (*is_hdcp1x_supported)(struct dc_link *link,
+                       enum signal_type signal);
+       bool (*is_hdcp2x_supported)(struct dc_link *link,
+                       enum signal_type signal);
+       void (*clear_dprx_states)(struct dc_link *link);
+
+
+       /*************************** Resource *********************************/
+       void (*get_cur_res_map)(const struct dc *dc, uint32_t *map);
+       void (*restore_res_map)(const struct dc *dc, uint32_t *map);
+       void (*get_cur_link_res)(const struct dc_link *link,
+                       struct link_resource *link_res);
+
+
+       /*************************** Validation *******************************/
+       enum dc_status (*validate_mode_timing)(
+                       const struct dc_stream_state *stream,
+                       struct dc_link *link,
+                       const struct dc_crtc_timing *timing);
+       uint32_t (*dp_link_bandwidth_kbps)(
+               const struct dc_link *link,
+               const struct dc_link_settings *link_settings);
+
+
+       /*************************** DPMS *************************************/
+       void (*set_dpms_on)(struct dc_state *state, struct pipe_ctx *pipe_ctx);
+       void (*set_dpms_off)(struct pipe_ctx *pipe_ctx);
+       void (*resume)(struct dc_link *link);
+       void (*blank_all_dp_displays)(struct dc *dc);
+       void (*blank_all_edp_displays)(struct dc *dc);
+       void (*blank_dp_stream)(struct dc_link *link, bool hw_init);
+       enum dc_status (*increase_mst_payload)(
+                       struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+       enum dc_status (*reduce_mst_payload)(
+                       struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+       void (*set_dsc_on_stream)(struct pipe_ctx *pipe_ctx, bool enable);
+       bool (*set_dsc_enable)(struct pipe_ctx *pipe_ctx, bool enable);
+       bool (*update_dsc_config)(struct pipe_ctx *pipe_ctx);
 
-       /* DDC */
+
+       /*************************** DDC **************************************/
+       struct ddc_service *(*create_ddc_service)(
+                       struct ddc_service_init_data *ddc_init_data);
+       void (*destroy_ddc_service)(struct ddc_service **ddc);
+       bool (*query_ddc_data)(
+                       struct ddc_service *ddc,
+                       uint32_t address,
+                       uint8_t *write_buf,
+                       uint32_t write_size,
+                       uint8_t *read_buf,
+                       uint32_t read_size);
        int (*aux_transfer_raw)(struct ddc_service *ddc,
                        struct aux_payload *payload,
                        enum aux_return_code_type *operation_result);
+       bool (*aux_transfer_with_retries_no_mutex)(struct ddc_service *ddc,
+                       struct aux_payload *payload);
+       bool (*is_in_aux_transaction_mode)(struct ddc_service *ddc);
+       uint32_t (*get_aux_defer_delay)(struct ddc_service *ddc);
+
 
-       /* DP Capability */
+       /*************************** DP Capability ****************************/
        bool (*dp_is_sink_present)(struct dc_link *link);
        bool (*dp_is_fec_supported)(const struct dc_link *link);
+       bool (*dp_is_128b_132b_signal)(struct pipe_ctx *pipe_ctx);
        bool (*dp_get_max_link_enc_cap)(const struct dc_link *link,
                        struct dc_link_settings *max_link_enc_cap);
        const struct dc_link_settings *(*dp_get_verified_link_cap)(
                        const struct dc_link *link);
+       enum dp_link_encoding (*dp_get_encoding_format)(
+                       const struct dc_link_settings *link_settings);
        bool (*dp_should_enable_fec)(const struct dc_link *link);
-       enum dp_link_encoding (*mst_decide_link_encoding_format)(const struct dc_link *link);
+       bool (*dp_decide_link_settings)(
+               struct dc_stream_state *stream,
+               struct dc_link_settings *link_setting);
+       enum dp_link_encoding (*mst_decide_link_encoding_format)(
+                       const struct dc_link *link);
        bool (*edp_decide_link_settings)(struct dc_link *link,
                        struct dc_link_settings *link_setting, uint32_t req_bw);
        uint32_t (*bw_kbps_from_raw_frl_link_rate_data)(uint8_t bw);
@@ -78,12 +205,20 @@ struct link_service {
        enum lttpr_mode (*dp_decide_lttpr_mode)(struct dc_link *link,
                        struct dc_link_settings *link_setting);
 
-       /* DP DPIA/PHY */
-       int (*dpia_handle_usb4_bandwidth_allocation_for_link)(struct dc_link *link, int peak_bw);
-       void (*dpia_handle_bw_alloc_response)(struct dc_link *link, uint8_t bw, uint8_t result);
+
+       /*************************** DP DPIA/PHY ******************************/
+       int (*dpia_handle_usb4_bandwidth_allocation_for_link)(
+                       struct dc_link *link, int peak_bw);
+       void (*dpia_handle_bw_alloc_response)(
+                       struct dc_link *link, uint8_t bw, uint8_t result);
+       void (*dp_set_drive_settings)(
+               struct dc_link *link,
+               const struct link_resource *link_res,
+               struct link_training_settings *lt_settings);
        void (*dpcd_write_rx_power_ctrl)(struct dc_link *link, bool on);
 
-       /* DP IRQ Handler */
+
+       /*************************** DP IRQ Handler ***************************/
        bool (*dp_parse_link_loss_status)(
                struct dc_link *link,
                union hpd_irq_data *hpd_irq_dpcd_data);
@@ -93,11 +228,14 @@ struct link_service {
                struct dc_link *link,
                union hpd_irq_data *irq_data);
        bool (*dp_handle_hpd_rx_irq)(struct dc_link *link,
-                       union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss,
+                       union hpd_irq_data *out_hpd_irq_dpcd_data,
+                       bool *out_link_loss,
                        bool defer_handling, bool *has_left_work);
 
-       /* eDP Panel Control */
-       void (*edp_panel_backlight_power_on)(struct dc_link *link, bool wait_for_hpd);
+
+       /*************************** eDP Panel Control ************************/
+       void (*edp_panel_backlight_power_on)(
+                       struct dc_link *link, bool wait_for_hpd);
        int (*edp_get_backlight_level)(const struct dc_link *link);
        bool (*edp_get_backlight_level_nits)(struct dc_link *link,
                        uint32_t *backlight_millinits_avg,
@@ -110,16 +248,35 @@ struct link_service {
                        uint32_t backlight_millinits,
                        uint32_t transition_time_in_ms);
        int (*edp_get_target_backlight_pwm)(const struct dc_link *link);
-       bool (*edp_get_psr_state)(const struct dc_link *link, enum dc_psr_state *state);
-       bool (*edp_set_psr_allow_active)(struct dc_link *link, const bool *allow_active,
-                       bool wait, bool force_static, const unsigned int *power_opts);
+       bool (*edp_get_psr_state)(
+                       const struct dc_link *link, enum dc_psr_state *state);
+       bool (*edp_set_psr_allow_active)(
+                       struct dc_link *link,
+                       const bool *allow_active,
+                       bool wait,
+                       bool force_static,
+                       const unsigned int *power_opts);
        bool (*edp_setup_psr)(struct dc_link *link,
                        const struct dc_stream_state *stream,
                        struct psr_config *psr_config,
                        struct psr_context *psr_context);
+       bool (*edp_set_sink_vtotal_in_psr_active)(
+                       const struct dc_link *link,
+                       uint16_t psr_vtotal_idle,
+                       uint16_t psr_vtotal_su);
+       void (*edp_get_psr_residency)(
+                       const struct dc_link *link, uint32_t *residency);
        bool (*edp_wait_for_t12)(struct dc_link *link);
+       bool (*edp_is_ilr_optimization_required)(struct dc_link *link,
+                       struct dc_crtc_timing *crtc_timing);
+       bool (*edp_backlight_enable_aux)(struct dc_link *link, bool enable);
+       void (*edp_add_delay_for_T9)(struct dc_link *link);
+       bool (*edp_receiver_ready_T9)(struct dc_link *link);
+       bool (*edp_receiver_ready_T7)(struct dc_link *link);
+       bool (*edp_power_alpm_dpcd_enable)(struct dc_link *link, bool enable);
 
-       /* DP CTS */
+
+       /*************************** DP CTS ************************************/
        void (*dp_handle_automated_test)(struct dc_link *link);
        bool (*dp_set_test_pattern)(
                        struct dc_link *link,
@@ -137,7 +294,8 @@ struct link_service {
                        struct dc_link *link,
                        bool skip_immediate_retrain);
 
-       /* DP Trace */
+
+       /*************************** DP Trace *********************************/
        bool (*dp_trace_is_initialized)(struct dc_link *link);
        void (*dp_trace_set_is_logged_flag)(struct dc_link *link,
                        bool in_detection,
@@ -148,115 +306,11 @@ struct link_service {
        const struct dp_trace_lt_counts *(*dp_trace_get_lt_counts)(
                        struct dc_link *link, bool in_detection);
        unsigned int (*dp_trace_get_link_loss_count)(struct dc_link *link);
+       void (*dp_trace_set_edp_power_timestamp)(struct dc_link *link,
+                       bool power_up);
+       uint64_t (*dp_trace_get_edp_poweron_timestamp)(struct dc_link *link);
+       uint64_t (*dp_trace_get_edp_poweroff_timestamp)(struct dc_link *link);
+       void (*dp_trace_source_sequence)(
+                       struct dc_link *link, uint8_t dp_test_mode);
 };
-
-struct dc_link *link_create(const struct link_init_data *init_params);
-void link_destroy(struct dc_link **link);
-const struct link_service *link_get_link_service(void);
-
-// TODO - convert any function declarations below to function pointers
-struct gpio *link_get_hpd_gpio(struct dc_bios *dcb,
-               struct graphics_object_id link_id,
-               struct gpio_service *gpio_service);
-
-struct ddc_service_init_data {
-       struct graphics_object_id id;
-       struct dc_context *ctx;
-       struct dc_link *link;
-       bool is_dpia_link;
-};
-
-struct ddc_service *link_create_ddc_service(
-               struct ddc_service_init_data *ddc_init_data);
-
-void link_destroy_ddc_service(struct ddc_service **ddc);
-
-bool link_is_in_aux_transaction_mode(struct ddc_service *ddc);
-
-bool link_query_ddc_data(
-               struct ddc_service *ddc,
-               uint32_t address,
-               uint8_t *write_buf,
-               uint32_t write_size,
-               uint8_t *read_buf,
-               uint32_t read_size);
-
-
-/* Attempt to submit an aux payload, retrying on timeouts, defers, and busy
- * states as outlined in the DP spec.  Returns true if the request was
- * successful.
- *
- * NOTE: The function requires explicit mutex on DM side in order to prevent
- * potential race condition. DC components should call the dpcd read/write
- * function in dm_helpers in order to access dpcd safely
- */
-bool link_aux_transfer_with_retries_no_mutex(struct ddc_service *ddc,
-               struct aux_payload *payload);
-
-uint32_t link_get_aux_defer_delay(struct ddc_service *ddc);
-
-bool link_is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx);
-
-enum dp_link_encoding link_dp_get_encoding_format(
-               const struct dc_link_settings *link_settings);
-
-bool link_decide_link_settings(
-       struct dc_stream_state *stream,
-       struct dc_link_settings *link_setting);
-
-void link_dp_trace_set_edp_power_timestamp(struct dc_link *link,
-               bool power_up);
-uint64_t link_dp_trace_get_edp_poweron_timestamp(struct dc_link *link);
-uint64_t link_dp_trace_get_edp_poweroff_timestamp(struct dc_link *link);
-
-bool link_is_edp_ilr_optimization_required(struct dc_link *link,
-               struct dc_crtc_timing *crtc_timing);
-
-bool link_backlight_enable_aux(struct dc_link *link, bool enable);
-void link_edp_add_delay_for_T9(struct dc_link *link);
-bool link_edp_receiver_ready_T9(struct dc_link *link);
-bool link_edp_receiver_ready_T7(struct dc_link *link);
-bool link_power_alpm_dpcd_enable(struct dc_link *link, bool enable);
-bool link_set_sink_vtotal_in_psr_active(const struct dc_link *link,
-               uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su);
-void link_get_psr_residency(const struct dc_link *link, uint32_t *residency);
-enum dc_status link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
-enum dc_status link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
-void link_blank_all_dp_displays(struct dc *dc);
-void link_blank_all_edp_displays(struct dc *dc);
-void link_blank_dp_stream(struct dc_link *link, bool hw_init);
-void link_resume(struct dc_link *link);
-void link_set_dpms_on(
-               struct dc_state *state,
-               struct pipe_ctx *pipe_ctx);
-void link_set_dpms_off(struct pipe_ctx *pipe_ctx);
-void link_dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode);
-void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
-bool link_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable);
-bool link_update_dsc_config(struct pipe_ctx *pipe_ctx);
-enum dc_status link_validate_mode_timing(
-               const struct dc_stream_state *stream,
-               struct dc_link *link,
-               const struct dc_crtc_timing *timing);
-bool link_detect(struct dc_link *link, enum dc_detect_reason reason);
-bool link_detect_connection_type(struct dc_link *link,
-               enum dc_connection_type *type);
-const struct dc_link_status *link_get_status(const struct dc_link *link);
-/* return true if the connected receiver supports the hdcp version */
-bool link_is_hdcp14(struct dc_link *link, enum signal_type signal);
-bool link_is_hdcp22(struct dc_link *link, enum signal_type signal);
-void link_clear_dprx_states(struct dc_link *link);
-bool link_reset_cur_dp_mst_topology(struct dc_link *link);
-uint32_t dp_link_bandwidth_kbps(
-       const struct dc_link *link,
-       const struct dc_link_settings *link_settings);
-uint32_t link_timing_bandwidth_kbps(const struct dc_crtc_timing *timing);
-void link_get_cur_res_map(const struct dc *dc, uint32_t *map);
-void link_restore_res_map(const struct dc *dc, uint32_t *map);
-void link_get_cur_link_res(const struct dc_link *link,
-               struct link_resource *link_res);
-void dp_set_drive_settings(
-       struct dc_link *link,
-       const struct link_resource *link_res,
-       struct link_training_settings *lt_settings);
 #endif /* __DC_LINK_HPD_H__ */
index 704373d..db9f1ba 100644 (file)
@@ -28,6 +28,7 @@
 #include "link/protocols/link_dp_training.h"
 #include "link/protocols/link_dp_phy.h"
 #include "link/protocols/link_dp_training_fixed_vs_pe_retimer.h"
+#include "link/protocols/link_dp_capability.h"
 #include "link/link_dpms.h"
 #include "resource.h"
 #include "dm_helpers.h"
index 277fe91..fbcd8fb 100644 (file)
@@ -145,7 +145,7 @@ unsigned int dp_trace_get_link_loss_count(struct dc_link *link)
        return link->dp_trace.link_loss_count;
 }
 
-void link_dp_trace_set_edp_power_timestamp(struct dc_link *link,
+void dp_trace_set_edp_power_timestamp(struct dc_link *link,
                bool power_up)
 {
        if (!power_up)
@@ -155,17 +155,17 @@ void link_dp_trace_set_edp_power_timestamp(struct dc_link *link,
                link->dp_trace.edp_trace_power_timestamps.poweron = dm_get_timestamp(link->dc->ctx);
 }
 
-uint64_t link_dp_trace_get_edp_poweron_timestamp(struct dc_link *link)
+uint64_t dp_trace_get_edp_poweron_timestamp(struct dc_link *link)
 {
        return link->dp_trace.edp_trace_power_timestamps.poweron;
 }
 
-uint64_t link_dp_trace_get_edp_poweroff_timestamp(struct dc_link *link)
+uint64_t dp_trace_get_edp_poweroff_timestamp(struct dc_link *link)
 {
        return link->dp_trace.edp_trace_power_timestamps.poweroff;
 }
 
-void link_dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode)
+void dp_trace_source_sequence(struct dc_link *link, uint8_t dp_test_mode)
 {
        if (link != NULL && link->dc->debug.enable_driver_sequence_debug)
                core_link_write_dpcd(link, DP_SOURCE_SEQUENCE,
index 9a0aff8..ab437a0 100644 (file)
@@ -54,5 +54,10 @@ unsigned long long dp_trace_get_lt_end_timestamp(struct dc_link *link,
 const struct dp_trace_lt_counts *dp_trace_get_lt_counts(struct dc_link *link,
                bool in_detection);
 unsigned int dp_trace_get_link_loss_count(struct dc_link *link);
+void dp_trace_set_edp_power_timestamp(struct dc_link *link,
+               bool power_up);
+uint64_t dp_trace_get_edp_poweron_timestamp(struct dc_link *link);
+uint64_t dp_trace_get_edp_poweroff_timestamp(struct dc_link *link);
+void dp_trace_source_sequence(struct dc_link *link, uint8_t dp_test_mode);
 
 #endif /* __LINK_DP_TRACE_H__ */
index b092b00..bebf9c4 100644 (file)
@@ -44,7 +44,7 @@ void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
        link_enc->funcs->connect_dig_be_to_fe(link_enc,
                        pipe_ctx->stream_res.stream_enc->id, true);
        if (dc_is_dp_signal(pipe_ctx->stream->signal))
-               link_dp_source_sequence_trace(pipe_ctx->stream->link,
+               pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence(pipe_ctx->stream->link,
                                DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
        if (stream_enc->funcs->enable_fifo)
                stream_enc->funcs->enable_fifo(stream_enc);
@@ -63,7 +63,8 @@ void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
                        pipe_ctx->stream_res.stream_enc->id,
                        false);
        if (dc_is_dp_signal(pipe_ctx->stream->signal))
-               link_dp_source_sequence_trace(pipe_ctx->stream->link,
+               pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence(
+                               pipe_ctx->stream->link,
                                DPCD_SOURCE_SEQ_AFTER_DISCONNECT_DIG_FE_BE);
 
 }
@@ -105,7 +106,8 @@ void setup_dio_stream_attribute(struct pipe_ctx *pipe_ctx)
                                &stream->timing);
 
        if (dc_is_dp_signal(stream->signal))
-               link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR);
+               link->dc->link_srv->dp_trace_source_sequence(link,
+                               DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR);
 }
 
 void enable_dio_dp_link_output(struct dc_link *link,
@@ -126,7 +128,8 @@ void enable_dio_dp_link_output(struct dc_link *link,
                                link_enc,
                                link_settings,
                                clock_source);
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
+       link->dc->link_srv->dp_trace_source_sequence(link,
+                       DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
 }
 
 void disable_dio_link_output(struct dc_link *link,
@@ -136,7 +139,8 @@ void disable_dio_link_output(struct dc_link *link,
        struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
 
        link_enc->funcs->disable_output(link_enc, signal);
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
+       link->dc->link_srv->dp_trace_source_sequence(link,
+                       DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
 }
 
 void set_dio_dp_link_test_pattern(struct dc_link *link,
@@ -146,7 +150,7 @@ void set_dio_dp_link_test_pattern(struct dc_link *link,
        struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
 
        link_enc->funcs->dp_set_phy_pattern(link_enc, tp_params);
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
+       link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
 }
 
 void set_dio_dp_lane_settings(struct dc_link *link,
@@ -195,7 +199,8 @@ void enable_dio_audio_packet(struct pipe_ctx *pipe_ctx)
                        pipe_ctx->stream_res.stream_enc, false);
 
        if (dc_is_dp_signal(pipe_ctx->stream->signal))
-               link_dp_source_sequence_trace(pipe_ctx->stream->link,
+               pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence(
+                               pipe_ctx->stream->link,
                                DPCD_SOURCE_SEQ_AFTER_ENABLE_AUDIO_STREAM);
 }
 
@@ -214,7 +219,8 @@ void disable_dio_audio_packet(struct pipe_ctx *pipe_ctx)
        }
 
        if (dc_is_dp_signal(pipe_ctx->stream->signal))
-               link_dp_source_sequence_trace(pipe_ctx->stream->link,
+               pipe_ctx->stream->ctx->dc->link_srv->dp_trace_source_sequence(
+                               pipe_ctx->stream->link,
                                DPCD_SOURCE_SEQ_AFTER_DISABLE_AUDIO_STREAM);
 }
 
index aa1c5e2..edd7d02 100644 (file)
@@ -68,7 +68,8 @@ static void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx,
        struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
        struct fixed31_32 h_blank_in_ms, time_slot_in_ms, mtp_cnt_per_h_blank;
        uint32_t link_bw_in_kbps =
-                       dc_link_bandwidth_kbps(pipe_ctx->stream->link, link_settings);
+                       hpo_dp_stream_encoder->ctx->dc->link_srv->dp_link_bandwidth_kbps(
+                                       pipe_ctx->stream->link, link_settings);
        uint16_t hblank_min_symbol_width = 0;
 
        if (link_bw_in_kbps > 0) {
@@ -115,7 +116,8 @@ static void setup_hpo_dp_stream_attribute(struct pipe_ctx *pipe_ctx)
                        stream->use_vsc_sdp_for_colorimetry,
                        stream->timing.flags.DSC,
                        false);
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR);
+       link->dc->link_srv->dp_trace_source_sequence(link,
+                       DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR);
 }
 
 static void enable_hpo_dp_fpga_link_output(struct dc_link *link,
@@ -201,7 +203,7 @@ static void set_hpo_dp_link_test_pattern(struct dc_link *link,
 {
        link_res->hpo_dp_link_enc->funcs->set_link_test_pattern(
                        link_res->hpo_dp_link_enc, tp_params);
-       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
+       link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
 }
 
 static void set_hpo_dp_lane_settings(struct dc_link *link,
index a51f761..13e5222 100644 (file)
@@ -876,7 +876,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
                return true;
        }
 
-       if (!dc_link_detect_connection_type(link, &new_connection_type)) {
+       if (!link_detect_connection_type(link, &new_connection_type)) {
                BREAK_TO_DEBUGGER();
                return false;
        }
index 4b1731c..7da0507 100644 (file)
 #ifndef __DC_LINK_DETECTION_H__
 #define __DC_LINK_DETECTION_H__
 #include "link.h"
+bool link_detect(struct dc_link *link, enum dc_detect_reason reason);
+bool link_detect_connection_type(struct dc_link *link,
+               enum dc_connection_type *type);
 struct dc_sink *link_add_remote_sink(
                struct dc_link *link,
                const uint8_t *edid,
                int len,
                struct dc_sink_init_data *init_data);
 void link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink);
-
+bool link_reset_cur_dp_mst_topology(struct dc_link *link);
+const struct dc_link_status *link_get_status(const struct dc_link *link);
+bool link_is_hdcp14(struct dc_link *link, enum signal_type signal);
+bool link_is_hdcp22(struct dc_link *link, enum signal_type signal);
+void link_clear_dprx_states(struct dc_link *link);
 #endif /* __DC_LINK_DETECTION_H__ */
index 00d441c..020d668 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "link_dpms.h"
 #include "link_hwss.h"
+#include "link_validation.h"
 #include "accessories/link_fpga.h"
 #include "accessories/link_dp_trace.h"
 #include "protocols/link_dpcd.h"
@@ -672,7 +673,7 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
 
        /* stream encoder index */
        config.stream_enc_idx = pipe_ctx->stream_res.stream_enc->id - ENGINE_ID_DIGA;
-       if (link_is_dp_128b_132b_signal(pipe_ctx))
+       if (dp_is_128b_132b_signal(pipe_ctx))
                config.stream_enc_idx =
                                pipe_ctx->stream_res.hpo_dp_stream_enc->id - ENGINE_ID_HPO_DP_0;
 
@@ -681,7 +682,7 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
 
        /* link encoder index */
        config.link_enc_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
-       if (link_is_dp_128b_132b_signal(pipe_ctx))
+       if (dp_is_128b_132b_signal(pipe_ctx))
                config.link_enc_idx = pipe_ctx->link_res.hpo_dp_link_enc->inst;
 
        /* dio output index is dpia index for DPIA endpoint & dcio index by default */
@@ -702,7 +703,7 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
        config.assr_enabled = (panel_mode == DP_PANEL_MODE_EDP) ? 1 : 0;
        config.mst_enabled = (pipe_ctx->stream->signal ==
                        SIGNAL_TYPE_DISPLAY_PORT_MST) ? 1 : 0;
-       config.dp2_enabled = link_is_dp_128b_132b_signal(pipe_ctx) ? 1 : 0;
+       config.dp2_enabled = dp_is_128b_132b_signal(pipe_ctx) ? 1 : 0;
        config.usb4_enabled = (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) ?
                        1 : 0;
        config.dpms_off = dpms_off;
@@ -816,7 +817,7 @@ void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 
                /* Enable DSC in encoder */
                if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)
-                               && !link_is_dp_128b_132b_signal(pipe_ctx)) {
+                               && !dp_is_128b_132b_signal(pipe_ctx)) {
                        DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id);
                        dsc_optc_config_log(dsc, &dsc_optc_cfg);
                        pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
@@ -842,7 +843,7 @@ void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 
                /* disable DSC in stream encoder */
                if (dc_is_dp_signal(stream->signal)) {
-                       if (link_is_dp_128b_132b_signal(pipe_ctx))
+                       if (dp_is_128b_132b_signal(pipe_ctx))
                                pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
                                                                                pipe_ctx->stream_res.hpo_dp_stream_enc,
                                                                                false,
@@ -901,7 +902,7 @@ bool link_set_dsc_pps_packet(struct pipe_ctx *pipe_ctx, bool enable, bool immedi
                memcpy(&stream->dsc_packed_pps[0], &dsc_packed_pps[0], sizeof(stream->dsc_packed_pps));
                if (dc_is_dp_signal(stream->signal)) {
                        DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id);
-                       if (link_is_dp_128b_132b_signal(pipe_ctx))
+                       if (dp_is_128b_132b_signal(pipe_ctx))
                                pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
                                                                                pipe_ctx->stream_res.hpo_dp_stream_enc,
                                                                                true,
@@ -918,7 +919,7 @@ bool link_set_dsc_pps_packet(struct pipe_ctx *pipe_ctx, bool enable, bool immedi
                /* disable DSC PPS in stream encoder */
                memset(&stream->dsc_packed_pps[0], 0, sizeof(stream->dsc_packed_pps));
                if (dc_is_dp_signal(stream->signal)) {
-                       if (link_is_dp_128b_132b_signal(pipe_ctx))
+                       if (dp_is_128b_132b_signal(pipe_ctx))
                                pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
                                                                                pipe_ctx->stream_res.hpo_dp_stream_enc,
                                                                                false,
@@ -1043,7 +1044,7 @@ static void log_vcp_x_y(const struct dc_link *link, struct fixed31_32 avg_time_s
 static struct fixed31_32 get_pbn_per_slot(struct dc_stream_state *stream)
 {
        struct fixed31_32 mbytes_per_sec;
-       uint32_t link_rate_in_mbytes_per_sec = dc_link_bandwidth_kbps(stream->link,
+       uint32_t link_rate_in_mbytes_per_sec = dp_link_bandwidth_kbps(stream->link,
                        &stream->link->cur_link_settings);
        link_rate_in_mbytes_per_sec /= 8000; /* Kbits to MBytes */
 
@@ -1534,7 +1535,7 @@ struct fixed31_32 link_calculate_sst_avg_time_slots_per_mtp(
 {
        struct fixed31_32 link_bw_effective =
                        dc_fixpt_from_int(
-                                       dc_link_bandwidth_kbps(link, &link->cur_link_settings));
+                                       dp_link_bandwidth_kbps(link, &link->cur_link_settings));
        struct fixed31_32 timeslot_bw_effective =
                        dc_fixpt_div_int(link_bw_effective, MAX_MTP_SLOT_COUNT);
        struct fixed31_32 timing_bw =
@@ -2122,7 +2123,7 @@ static enum dc_status enable_link_dp(struct dc_state *state,
                set_default_brightness_aux(link); // TODO: use cached if known
                if (link->dpcd_sink_ext_caps.bits.oled == 1)
                        msleep(bl_oled_enable_delay);
-               link_backlight_enable_aux(link, true);
+               edp_backlight_enable_aux(link, true);
        }
 
        return status;
@@ -2242,7 +2243,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
 
        ASSERT(is_master_pipe_for_link(link, pipe_ctx));
 
-       if (link_is_dp_128b_132b_signal(pipe_ctx))
+       if (dp_is_128b_132b_signal(pipe_ctx))
                vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg;
 
        DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
@@ -2273,7 +2274,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
        if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
                deallocate_mst_payload(pipe_ctx);
        else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
-                       link_is_dp_128b_132b_signal(pipe_ctx))
+                       dp_is_128b_132b_signal(pipe_ctx))
                update_sst_payload(pipe_ctx, false);
 
        if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
@@ -2302,7 +2303,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
        }
 
        if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
-                       !link_is_dp_128b_132b_signal(pipe_ctx)) {
+                       !dp_is_128b_132b_signal(pipe_ctx)) {
 
                /* In DP1.x SST mode, our encoder will go to TPS1
                 * when link is on but stream is off.
@@ -2322,7 +2323,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
                if (dc_is_dp_signal(pipe_ctx->stream->signal))
                        link_set_dsc_enable(pipe_ctx, false);
        }
-       if (link_is_dp_128b_132b_signal(pipe_ctx)) {
+       if (dp_is_128b_132b_signal(pipe_ctx)) {
                if (pipe_ctx->stream_res.tg->funcs->set_out_mux)
                        pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, OUT_MUX_DIO);
        }
@@ -2346,7 +2347,7 @@ void link_set_dpms_on(
 
        ASSERT(is_master_pipe_for_link(link, pipe_ctx));
 
-       if (link_is_dp_128b_132b_signal(pipe_ctx))
+       if (dp_is_128b_132b_signal(pipe_ctx))
                vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg;
 
        DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
@@ -2368,7 +2369,7 @@ void link_set_dpms_on(
        ASSERT(link_enc);
 
        if (!dc_is_virtual_signal(pipe_ctx->stream->signal)
-                       && !link_is_dp_128b_132b_signal(pipe_ctx)) {
+                       && !dp_is_128b_132b_signal(pipe_ctx)) {
                if (link_enc)
                        link_enc->funcs->setup(
                                link_enc,
@@ -2378,7 +2379,7 @@ void link_set_dpms_on(
        pipe_ctx->stream->link->link_state_valid = true;
 
        if (pipe_ctx->stream_res.tg->funcs->set_out_mux) {
-               if (link_is_dp_128b_132b_signal(pipe_ctx))
+               if (dp_is_128b_132b_signal(pipe_ctx))
                        otg_out_dest = OUT_MUX_HPO_DP;
                else
                        otg_out_dest = OUT_MUX_DIO;
@@ -2401,7 +2402,7 @@ void link_set_dpms_on(
                dc->hwss.update_info_frame(pipe_ctx);
 
                if (dc_is_dp_signal(pipe_ctx->stream->signal))
-                       link_dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
+                       dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME);
 
                /* Do not touch link on seamless boot optimization. */
                if (pipe_ctx->stream->apply_seamless_boot_optimization) {
@@ -2476,7 +2477,7 @@ void link_set_dpms_on(
                 * from transmitter control.
                 */
                if (!(dc_is_virtual_signal(pipe_ctx->stream->signal) ||
-                               link_is_dp_128b_132b_signal(pipe_ctx)))
+                               dp_is_128b_132b_signal(pipe_ctx)))
                        if (link_enc)
                                link_enc->funcs->setup(
                                        link_enc,
@@ -2496,7 +2497,7 @@ void link_set_dpms_on(
                if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
                        allocate_mst_payload(pipe_ctx);
                else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
-                               link_is_dp_128b_132b_signal(pipe_ctx))
+                               dp_is_128b_132b_signal(pipe_ctx))
                        update_sst_payload(pipe_ctx, true);
 
                dc->hwss.unblank_stream(pipe_ctx,
@@ -2512,7 +2513,7 @@ void link_set_dpms_on(
                dc->hwss.enable_audio_stream(pipe_ctx);
 
        } else { // if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
-               if (link_is_dp_128b_132b_signal(pipe_ctx))
+               if (dp_is_128b_132b_signal(pipe_ctx))
                        dp_fpga_hpo_enable_link_and_stream(state, pipe_ctx);
                if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
                                dc_is_virtual_signal(pipe_ctx->stream->signal))
index 33d312d..9398f9c 100644 (file)
 #define __DC_LINK_DPMS_H__
 
 #include "link.h"
-bool link_set_dsc_pps_packet(struct pipe_ctx *pipe_ctx,
-               bool enable, bool immediate_update);
-struct fixed31_32 link_calculate_sst_avg_time_slots_per_mtp(
-               const struct dc_stream_state *stream,
-               const struct dc_link *link);
+void link_set_dpms_on(
+               struct dc_state *state,
+               struct pipe_ctx *pipe_ctx);
+void link_set_dpms_off(struct pipe_ctx *pipe_ctx);
+void link_resume(struct dc_link *link);
+void link_blank_all_dp_displays(struct dc *dc);
+void link_blank_all_edp_displays(struct dc *dc);
+void link_blank_dp_stream(struct dc_link *link, bool hw_init);
 void link_set_all_streams_dpms_off_for_link(struct dc_link *link);
 void link_get_master_pipes_with_dpms_on(const struct dc_link *link,
                struct dc_state *state,
                uint8_t *count,
                struct pipe_ctx *pipes[MAX_PIPES]);
+enum dc_status link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+enum dc_status link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn);
+bool link_set_dsc_pps_packet(struct pipe_ctx *pipe_ctx,
+               bool enable, bool immediate_update);
+struct fixed31_32 link_calculate_sst_avg_time_slots_per_mtp(
+               const struct dc_stream_state *stream,
+               const struct dc_link *link);
+void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
+bool link_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable);
+bool link_update_dsc_config(struct pipe_ctx *pipe_ctx);
 #endif /* __DC_LINK_DPMS_H__ */
index d9ce83f..995032a 100644 (file)
@@ -28,6 +28,9 @@
  */
 #include "link_factory.h"
 #include "link_detection.h"
+#include "link_resource.h"
+#include "link_validation.h"
+#include "link_dpms.h"
 #include "accessories/link_dp_cts.h"
 #include "accessories/link_dp_trace.h"
 #include "accessories/link_fpga.h"
        DC_LOG_HW_HOTPLUG(  \
                __VA_ARGS__)
 
-static struct link_service link_srv = {
-       /* Detection */
-       .add_remote_sink = link_add_remote_sink,
-       .remove_remote_sink = link_remove_remote_sink,
-       .get_hpd_state = link_get_hpd_state,
-       .enable_hpd = link_enable_hpd,
-       .disable_hpd = link_disable_hpd,
-       .enable_hpd_filter = link_enable_hpd_filter,
-
-       /* DDC */
-       .aux_transfer_raw = link_aux_transfer_raw,
-
-       /* DP Capability */
-       .dp_is_sink_present = dp_is_sink_present,
-       .dp_is_fec_supported = dp_is_fec_supported,
-       .dp_get_max_link_enc_cap = dp_get_max_link_enc_cap,
-       .dp_get_verified_link_cap = dp_get_verified_link_cap,
-       .dp_should_enable_fec = dp_should_enable_fec,
-       .mst_decide_link_encoding_format = mst_decide_link_encoding_format,
-       .edp_decide_link_settings = edp_decide_link_settings,
-       .bw_kbps_from_raw_frl_link_rate_data = link_bw_kbps_from_raw_frl_link_rate_data,
-       .dp_overwrite_extended_receiver_cap = dp_overwrite_extended_receiver_cap,
-       .dp_decide_lttpr_mode = dp_decide_lttpr_mode,
-
-       /* DP DPIA/PHY */
-       .dpia_handle_usb4_bandwidth_allocation_for_link = dpia_handle_usb4_bandwidth_allocation_for_link,
-       .dpia_handle_bw_alloc_response = dpia_handle_bw_alloc_response,
-       /* DP IRQ Handler */
-       .dp_parse_link_loss_status = dp_parse_link_loss_status,
-       .dp_should_allow_hpd_rx_irq = dp_should_allow_hpd_rx_irq,
-       .dp_handle_link_loss = dp_handle_link_loss,
-       .dp_read_hpd_rx_irq_data = dp_read_hpd_rx_irq_data,
-       .dp_handle_hpd_rx_irq = dp_handle_hpd_rx_irq,
-       .dpcd_write_rx_power_ctrl = dpcd_write_rx_power_ctrl,
-
-       /* eDP Panel Control */
-       .edp_panel_backlight_power_on = edp_panel_backlight_power_on,
-       .edp_get_backlight_level = edp_get_backlight_level,
-       .edp_get_backlight_level_nits = edp_get_backlight_level_nits,
-       .edp_set_backlight_level = edp_set_backlight_level,
-       .edp_set_backlight_level_nits = edp_set_backlight_level_nits,
-       .edp_get_target_backlight_pwm = edp_get_target_backlight_pwm,
-       .edp_get_psr_state = edp_get_psr_state,
-       .edp_set_psr_allow_active = edp_set_psr_allow_active,
-       .edp_setup_psr = edp_setup_psr,
-       .edp_wait_for_t12 = edp_wait_for_t12,
-
-       /* DP CTS */
-       .dp_handle_automated_test = dp_handle_automated_test,
-       .dp_set_test_pattern = dp_set_test_pattern,
-       .dp_set_preferred_link_settings = dp_set_preferred_link_settings,
-       .dp_set_preferred_training_settings = dp_set_preferred_training_settings,
-
-       /* DP Trace */
-       .dp_trace_is_initialized = dp_trace_is_initialized,
-       .dp_trace_set_is_logged_flag = dp_trace_set_is_logged_flag,
-       .dp_trace_is_logged = dp_trace_is_logged,
-       .dp_trace_get_lt_end_timestamp = dp_trace_get_lt_end_timestamp,
-       .dp_trace_get_lt_counts = dp_trace_get_lt_counts,
-       .dp_trace_get_link_loss_count = dp_trace_get_link_loss_count,
-};
-
-static enum transmitter translate_encoder_to_transmitter(struct graphics_object_id encoder)
+/* link factory owns the creation/destruction of link structures. */
+static void construct_link_service_factory(struct link_service *link_srv)
+{
+
+       link_srv->create_link = link_create;
+       link_srv->destroy_link = link_destroy;
+}
+
+/* link_detection manages link detection states and receiver states by using
+ * various link protocols. It also provides helper functions to interpret
+ * certain capabilities or status based on the states it manages or retrieve
+ * them directly from connected receivers.
+ */
+static void construct_link_service_detection(struct link_service *link_srv)
+{
+       link_srv->detect_link = link_detect;
+       link_srv->detect_connection_type = link_detect_connection_type;
+       link_srv->add_remote_sink = link_add_remote_sink;
+       link_srv->remove_remote_sink = link_remove_remote_sink;
+       link_srv->get_hpd_state = link_get_hpd_state;
+       link_srv->get_hpd_gpio = link_get_hpd_gpio;
+       link_srv->enable_hpd = link_enable_hpd;
+       link_srv->disable_hpd = link_disable_hpd;
+       link_srv->enable_hpd_filter = link_enable_hpd_filter;
+       link_srv->reset_cur_dp_mst_topology = link_reset_cur_dp_mst_topology;
+       link_srv->get_status = link_get_status;
+       link_srv->is_hdcp1x_supported = link_is_hdcp14;
+       link_srv->is_hdcp2x_supported = link_is_hdcp22;
+       link_srv->clear_dprx_states = link_clear_dprx_states;
+}
+
+/* link resource implements accessors to link resource. */
+static void construct_link_service_resource(struct link_service *link_srv)
+{
+       link_srv->get_cur_res_map = link_get_cur_res_map;
+       link_srv->restore_res_map = link_restore_res_map;
+       link_srv->get_cur_link_res = link_get_cur_link_res;
+}
+
+/* link validation owns timing validation against various link limitations. (ex.
+ * link bandwidth, receiver capability or our hardware capability) It also
+ * provides helper functions exposing bandwidth formulas used in validation.
+ */
+static void construct_link_service_validation(struct link_service *link_srv)
+{
+       link_srv->validate_mode_timing = link_validate_mode_timing;
+       link_srv->dp_link_bandwidth_kbps = dp_link_bandwidth_kbps;
+}
+
+/* link dpms owns the programming sequence of stream's dpms state associated
+ * with the link and link's enable/disable sequences as result of the stream's
+ * dpms state change.
+ */
+static void construct_link_service_dpms(struct link_service *link_srv)
+{
+       link_srv->set_dpms_on = link_set_dpms_on;
+       link_srv->set_dpms_off = link_set_dpms_off;
+       link_srv->resume = link_resume;
+       link_srv->blank_all_dp_displays = link_blank_all_dp_displays;
+       link_srv->blank_all_edp_displays = link_blank_all_edp_displays;
+       link_srv->blank_dp_stream = link_blank_dp_stream;
+       link_srv->increase_mst_payload = link_increase_mst_payload;
+       link_srv->reduce_mst_payload = link_reduce_mst_payload;
+       link_srv->set_dsc_on_stream = link_set_dsc_on_stream;
+       link_srv->set_dsc_enable = link_set_dsc_enable;
+       link_srv->update_dsc_config = link_update_dsc_config;
+}
+
+/* link ddc implements generic display communication protocols such as i2c, aux
+ * and scdc. It should not contain any specific applications of these
+ * protocols such as display capability query, detection, or handshaking such as
+ * link training.
+ */
+static void construct_link_service_ddc(struct link_service *link_srv)
+{
+       link_srv->create_ddc_service = link_create_ddc_service;
+       link_srv->destroy_ddc_service = link_destroy_ddc_service;
+       link_srv->query_ddc_data = link_query_ddc_data;
+       link_srv->aux_transfer_raw = link_aux_transfer_raw;
+       link_srv->aux_transfer_with_retries_no_mutex =
+                       link_aux_transfer_with_retries_no_mutex;
+       link_srv->is_in_aux_transaction_mode = link_is_in_aux_transaction_mode;
+       link_srv->get_aux_defer_delay = link_get_aux_defer_delay;
+}
+
+/* link dp capability implements dp specific link capability retrieval sequence.
+ * It is responsible for retrieving, parsing, overriding, deciding capability
+ * obtained from dp link. Link capability consists of encoders, DPRXs, cables,
+ * retimers, usb and all other possible backend capabilities.
+ */
+static void construct_link_service_dp_capability(struct link_service *link_srv)
+{
+       link_srv->dp_is_sink_present = dp_is_sink_present;
+       link_srv->dp_is_fec_supported = dp_is_fec_supported;
+       link_srv->dp_is_128b_132b_signal = dp_is_128b_132b_signal;
+       link_srv->dp_get_max_link_enc_cap = dp_get_max_link_enc_cap;
+       link_srv->dp_get_verified_link_cap = dp_get_verified_link_cap;
+       link_srv->dp_get_encoding_format = link_dp_get_encoding_format;
+       link_srv->dp_should_enable_fec = dp_should_enable_fec;
+       link_srv->dp_decide_link_settings = link_decide_link_settings;
+       link_srv->mst_decide_link_encoding_format =
+                       mst_decide_link_encoding_format;
+       link_srv->edp_decide_link_settings = edp_decide_link_settings;
+       link_srv->bw_kbps_from_raw_frl_link_rate_data =
+                       link_bw_kbps_from_raw_frl_link_rate_data;
+       link_srv->dp_overwrite_extended_receiver_cap =
+                       dp_overwrite_extended_receiver_cap;
+       link_srv->dp_decide_lttpr_mode = dp_decide_lttpr_mode;
+}
+
+/* link dp phy/dpia implements basic dp phy/dpia functionality such as
+ * enable/disable output and set lane/drive settings. It is responsible for
+ * maintaining and update software state representing current phy/dpia status
+ * such as current link settings.
+ */
+static void construct_link_service_dp_phy_or_dpia(struct link_service *link_srv)
+{
+       link_srv->dpia_handle_usb4_bandwidth_allocation_for_link =
+                       dpia_handle_usb4_bandwidth_allocation_for_link;
+       link_srv->dpia_handle_bw_alloc_response = dpia_handle_bw_alloc_response;
+       link_srv->dp_set_drive_settings = dp_set_drive_settings;
+       link_srv->dpcd_write_rx_power_ctrl = dpcd_write_rx_power_ctrl;
+}
+
+/* link dp irq handler implements DP HPD short pulse handling sequence according
+ * to DP specifications
+ */
+static void construct_link_service_dp_irq_handler(struct link_service *link_srv)
+{
+       link_srv->dp_parse_link_loss_status = dp_parse_link_loss_status;
+       link_srv->dp_should_allow_hpd_rx_irq = dp_should_allow_hpd_rx_irq;
+       link_srv->dp_handle_link_loss = dp_handle_link_loss;
+       link_srv->dp_read_hpd_rx_irq_data = dp_read_hpd_rx_irq_data;
+       link_srv->dp_handle_hpd_rx_irq = dp_handle_hpd_rx_irq;
+}
+
+/* link edp panel control implements retrieval and configuration of eDP panel
+ * features such as PSR and ABM and it also manages specs defined eDP panel
+ * power sequences.
+ */
+static void construct_link_service_edp_panel_control(struct link_service *link_srv)
+{
+       link_srv->edp_panel_backlight_power_on = edp_panel_backlight_power_on;
+       link_srv->edp_get_backlight_level = edp_get_backlight_level;
+       link_srv->edp_get_backlight_level_nits = edp_get_backlight_level_nits;
+       link_srv->edp_set_backlight_level = edp_set_backlight_level;
+       link_srv->edp_set_backlight_level_nits = edp_set_backlight_level_nits;
+       link_srv->edp_get_target_backlight_pwm = edp_get_target_backlight_pwm;
+       link_srv->edp_get_psr_state = edp_get_psr_state;
+       link_srv->edp_set_psr_allow_active = edp_set_psr_allow_active;
+       link_srv->edp_setup_psr = edp_setup_psr;
+       link_srv->edp_set_sink_vtotal_in_psr_active =
+                       edp_set_sink_vtotal_in_psr_active;
+       link_srv->edp_get_psr_residency = edp_get_psr_residency;
+       link_srv->edp_wait_for_t12 = edp_wait_for_t12;
+       link_srv->edp_is_ilr_optimization_required =
+                       edp_is_ilr_optimization_required;
+       link_srv->edp_backlight_enable_aux = edp_backlight_enable_aux;
+       link_srv->edp_add_delay_for_T9 = edp_add_delay_for_T9;
+       link_srv->edp_receiver_ready_T9 = edp_receiver_ready_T9;
+       link_srv->edp_receiver_ready_T7 = edp_receiver_ready_T7;
+       link_srv->edp_power_alpm_dpcd_enable = edp_power_alpm_dpcd_enable;
+}
+
+/* link dp cts implements dp compliance test automation protocols and manual
+ * testing interfaces for debugging and certification purpose.
+ */
+static void construct_link_service_dp_cts(struct link_service *link_srv)
+{
+       link_srv->dp_handle_automated_test = dp_handle_automated_test;
+       link_srv->dp_set_test_pattern = dp_set_test_pattern;
+       link_srv->dp_set_preferred_link_settings =
+                       dp_set_preferred_link_settings;
+       link_srv->dp_set_preferred_training_settings =
+                       dp_set_preferred_training_settings;
+}
+
+/* link dp trace implements tracing interfaces for tracking major dp sequences
+ * including execution status and timestamps
+ */
+static void construct_link_service_dp_trace(struct link_service *link_srv)
+{
+       link_srv->dp_trace_is_initialized = dp_trace_is_initialized;
+       link_srv->dp_trace_set_is_logged_flag = dp_trace_set_is_logged_flag;
+       link_srv->dp_trace_is_logged = dp_trace_is_logged;
+       link_srv->dp_trace_get_lt_end_timestamp = dp_trace_get_lt_end_timestamp;
+       link_srv->dp_trace_get_lt_counts = dp_trace_get_lt_counts;
+       link_srv->dp_trace_get_link_loss_count = dp_trace_get_link_loss_count;
+       link_srv->dp_trace_set_edp_power_timestamp =
+                       dp_trace_set_edp_power_timestamp;
+       link_srv->dp_trace_get_edp_poweron_timestamp =
+                       dp_trace_get_edp_poweron_timestamp;
+       link_srv->dp_trace_get_edp_poweroff_timestamp =
+                       dp_trace_get_edp_poweroff_timestamp;
+       link_srv->dp_trace_source_sequence = dp_trace_source_sequence;
+}
+
+static void construct_link_service(struct link_service *link_srv)
+{
+       /* All link service functions should fall under some sub categories.
+        * If a new function doesn't perfectly fall under an existing sub
+        * category, it must be that you are either adding a whole new aspect of
+        * responsibility to link service or something doesn't belong to link
+        * service. In that case please contact the arch owner to arrange a
+        * design review meeting.
+        */
+       construct_link_service_factory(link_srv);
+       construct_link_service_detection(link_srv);
+       construct_link_service_resource(link_srv);
+       construct_link_service_validation(link_srv);
+       construct_link_service_dpms(link_srv);
+       construct_link_service_ddc(link_srv);
+       construct_link_service_dp_capability(link_srv);
+       construct_link_service_dp_phy_or_dpia(link_srv);
+       construct_link_service_dp_irq_handler(link_srv);
+       construct_link_service_edp_panel_control(link_srv);
+       construct_link_service_dp_cts(link_srv);
+       construct_link_service_dp_trace(link_srv);
+}
+
+struct link_service *link_create_link_service(void)
+{
+       struct link_service *link_srv = kzalloc(sizeof(*link_srv), GFP_KERNEL);
+
+       if (link_srv == NULL)
+               goto fail;
+
+       construct_link_service(link_srv);
+
+       return link_srv;
+fail:
+       return NULL;
+}
+
+void link_destroy_link_service(struct link_service **link_srv)
+{
+       kfree(*link_srv);
+       *link_srv = NULL;
+}
+
+static enum transmitter translate_encoder_to_transmitter(
+               struct graphics_object_id encoder)
 {
        switch (encoder.id) {
        case ENCODER_ID_INTERNAL_UNIPHY:
@@ -646,8 +828,3 @@ void link_destroy(struct dc_link **link)
        kfree(*link);
        *link = NULL;
 }
-
-const struct link_service *link_get_link_service(void)
-{
-       return &link_srv;
-}
index 5b84614..e96220d 100644 (file)
@@ -25,5 +25,7 @@
 #ifndef __LINK_FACTORY_H__
 #define __LINK_FACTORY_H__
 #include "link.h"
+struct dc_link *link_create(const struct link_init_data *init_params);
+void link_destroy(struct dc_link **link);
 
 #endif /* __LINK_FACTORY_H__ */
index 68dfbfc..1907bda 100644 (file)
@@ -25,4 +25,8 @@
 #ifndef __LINK_RESOURCE_H__
 #define __LINK_RESOURCE_H__
 #include "link.h"
+void link_get_cur_res_map(const struct dc *dc, uint32_t *map);
+void link_restore_res_map(const struct dc *dc, uint32_t *map);
+void link_get_cur_link_res(const struct dc_link *link,
+               struct link_resource *link_res);
 #endif /* __LINK_RESOURCE_H__ */
index 62aa5f6..9a5010f 100644 (file)
@@ -255,8 +255,7 @@ uint32_t dp_link_bandwidth_kbps(
        return link_rate_per_lane_kbps * link_settings->lane_count / 10000 * total_data_bw_efficiency_x10000;
 }
 
-uint32_t link_timing_bandwidth_kbps(
-       const struct dc_crtc_timing *timing)
+uint32_t link_timing_bandwidth_kbps(const struct dc_crtc_timing *timing)
 {
        uint32_t bits_per_channel = 0;
        uint32_t kbps;
@@ -337,7 +336,7 @@ static bool dp_validate_mode_timing(
        */
 
        req_bw = dc_bandwidth_in_kbps_from_timing(timing);
-       max_bw = dc_link_bandwidth_kbps(link, link_setting);
+       max_bw = dp_link_bandwidth_kbps(link, link_setting);
 
        if (req_bw <= max_bw) {
                /* remember the biggest mode here, during
index ab6a44f..2191d3a 100644 (file)
 #ifndef __LINK_VALIDATION_H__
 #define __LINK_VALIDATION_H__
 #include "link.h"
+enum dc_status link_validate_mode_timing(
+               const struct dc_stream_state *stream,
+               struct dc_link *link,
+               const struct dc_crtc_timing *timing);
+uint32_t dp_link_bandwidth_kbps(
+       const struct dc_link *link,
+       const struct dc_link_settings *link_settings);
 #endif /* __LINK_VALIDATION_H__ */
index f002fa0..860ef15 100644 (file)
 
 #define EDID_SEGMENT_SIZE 256
 
+struct ddc_service *link_create_ddc_service(
+               struct ddc_service_init_data *ddc_init_data);
+
+void link_destroy_ddc_service(struct ddc_service **ddc);
+
 void set_ddc_transaction_type(
                struct ddc_service *ddc,
                enum ddc_transaction_type type);
 
+uint32_t link_get_aux_defer_delay(struct ddc_service *ddc);
+
+bool link_is_in_aux_transaction_mode(struct ddc_service *ddc);
+
 bool try_to_configure_aux_timeout(struct ddc_service *ddc,
                uint32_t timeout);
 
+bool link_query_ddc_data(
+               struct ddc_service *ddc,
+               uint32_t address,
+               uint8_t *write_buf,
+               uint32_t write_size,
+               uint8_t *read_buf,
+               uint32_t read_size);
+
+/* Attempt to submit an aux payload, retrying on timeouts, defers, and busy
+ * states as outlined in the DP spec.  Returns true if the request was
+ * successful.
+ *
+ * NOTE: The function requires explicit mutex on DM side in order to prevent
+ * potential race condition. DC components should call the dpcd read/write
+ * function in dm_helpers in order to access dpcd safely
+ */
+bool link_aux_transfer_with_retries_no_mutex(struct ddc_service *ddc,
+               struct aux_payload *payload);
+
 void write_scdc_data(
                struct ddc_service *ddc_service,
                uint32_t pix_clk,
index 75e1a68..e9bcb35 100644 (file)
@@ -347,7 +347,7 @@ bool dp_should_enable_fec(const struct dc_link *link)
        return !force_disable && dp_is_fec_supported(link);
 }
 
-bool link_is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx)
+bool dp_is_128b_132b_signal(struct pipe_ctx *pipe_ctx)
 {
        /* If this assert is hit then we have a link encoder dynamic management issue */
        ASSERT(pipe_ctx->stream_res.hpo_dp_stream_enc ? pipe_ctx->link_res.hpo_dp_link_enc != NULL : true);
@@ -656,7 +656,7 @@ static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_setting
         */
        while (current_link_setting.link_rate <=
                        link->verified_link_cap.link_rate) {
-               link_bw = dc_link_bandwidth_kbps(
+               link_bw = dp_link_bandwidth_kbps(
                                link,
                                &current_link_setting);
                if (req_bw <= link_bw) {
@@ -712,7 +712,7 @@ bool edp_decide_link_settings(struct dc_link *link,
         */
        while (current_link_setting.link_rate <=
                        link->verified_link_cap.link_rate) {
-               link_bw = dc_link_bandwidth_kbps(
+               link_bw = dp_link_bandwidth_kbps(
                                link,
                                &current_link_setting);
                if (req_bw <= link_bw) {
@@ -891,7 +891,7 @@ bool link_decide_link_settings(struct dc_stream_state *stream,
        struct dc_link_settings *link_setting)
 {
        struct dc_link *link = stream->link;
-       uint32_t req_bw = link_timing_bandwidth_kbps(&stream->timing);
+       uint32_t req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing);
 
        memset(link_setting, 0, sizeof(*link_setting));
 
@@ -924,7 +924,7 @@ bool link_decide_link_settings(struct dc_stream_state *stream,
 
                                tmp_link_setting.link_rate = LINK_RATE_UNKNOWN;
                                tmp_timing.flags.DSC = 0;
-                               orig_req_bw = link_timing_bandwidth_kbps(&tmp_timing);
+                               orig_req_bw = dc_bandwidth_in_kbps_from_timing(&tmp_timing);
                                edp_decide_link_settings(link, &tmp_link_setting, orig_req_bw);
                                max_link_rate = tmp_link_setting.link_rate;
                        }
index 62980ae..8f0ce97 100644 (file)
@@ -40,6 +40,9 @@ bool dp_get_max_link_enc_cap(const struct dc_link *link,
 const struct dc_link_settings *dp_get_verified_link_cap(
                const struct dc_link *link);
 
+enum dp_link_encoding link_dp_get_encoding_format(
+               const struct dc_link_settings *link_settings);
+
 enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link);
 
 /* Convert PHY repeater count read from DPCD uint8_t. */
@@ -59,12 +62,18 @@ void dpcd_write_cable_id_to_dprx(struct dc_link *link);
 
 bool dp_should_enable_fec(const struct dc_link *link);
 
+bool dp_is_128b_132b_signal(struct pipe_ctx *pipe_ctx);
+
 /* Initialize output parameter lt_settings. */
 void dp_decide_training_settings(
        struct dc_link *link,
        const struct dc_link_settings *link_setting,
        struct link_training_settings *lt_settings);
 
+bool link_decide_link_settings(
+       struct dc_stream_state *stream,
+       struct dc_link_settings *link_setting);
+
 bool edp_decide_link_settings(struct dc_link *link,
                struct dc_link_settings *link_setting, uint32_t req_bw);
 
index 207bff2..1eb0619 100644 (file)
@@ -44,6 +44,11 @@ void dp_set_hw_lane_settings(
                const struct link_training_settings *link_settings,
                uint32_t offset);
 
+void dp_set_drive_settings(
+       struct dc_link *link,
+       const struct link_resource *link_res,
+       struct link_training_settings *lt_settings);
+
 enum dc_status dp_set_fec_ready(struct dc_link *link,
                const struct link_resource *link_res, bool ready);
 
index eee1853..a902567 100644 (file)
@@ -42,6 +42,7 @@
 #include "link_dp_capability.h"
 #include "link_edp_panel_control.h"
 #include "link/link_detection.h"
+#include "link/link_validation.h"
 #include "atomfirmware.h"
 #include "link_enc_cfg.h"
 #include "resource.h"
@@ -861,8 +862,9 @@ static enum dc_status configure_lttpr_mode_non_transparent(
        uint8_t repeater_id;
        enum dc_status result = DC_ERROR_UNEXPECTED;
        uint8_t repeater_mode = DP_PHY_REPEATER_MODE_TRANSPARENT;
+       const struct dc *dc = link->dc;
 
-       enum dp_link_encoding encoding = link_dp_get_encoding_format(&lt_settings->link_settings);
+       enum dp_link_encoding encoding = dc->link_srv->dp_get_encoding_format(&lt_settings->link_settings);
 
        if (encoding == DP_8b_10b_ENCODING) {
                DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Transparent Mode\n", __func__);
@@ -1675,7 +1677,7 @@ bool perform_link_training_with_retries(
                        /* Flag if reduced link bandwidth no longer meets stream requirements or fallen back to
                         * minimum link bandwidth.
                         */
-                       req_bw = link_timing_bandwidth_kbps(&stream->timing);
+                       req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing);
                        link_bw = dp_link_bandwidth_kbps(link, &cur_link_settings);
                        is_link_bw_low = (req_bw > link_bw);
                        is_link_bw_min = ((cur_link_settings.link_rate <= LINK_RATE_LOW) &&
index 4d78ac9..93a6bbe 100644 (file)
@@ -201,7 +201,7 @@ bool edp_get_backlight_level_nits(struct dc_link *link,
        return true;
 }
 
-bool link_backlight_enable_aux(struct dc_link *link, bool enable)
+bool edp_backlight_enable_aux(struct dc_link *link, bool enable)
 {
        uint8_t backlight_enable = enable ? 1 : 0;
 
@@ -249,7 +249,7 @@ bool set_default_brightness_aux(struct dc_link *link)
        return false;
 }
 
-bool link_is_edp_ilr_optimization_required(struct dc_link *link,
+bool edp_is_ilr_optimization_required(struct dc_link *link,
                struct dc_crtc_timing *crtc_timing)
 {
        struct dc_link_settings link_setting;
@@ -282,7 +282,7 @@ bool link_is_edp_ilr_optimization_required(struct dc_link *link,
        core_link_read_dpcd(link, DP_LANE_COUNT_SET,
                                &lane_count_set.raw, sizeof(lane_count_set));
 
-       req_bw = link_timing_bandwidth_kbps(crtc_timing);
+       req_bw = dc_bandwidth_in_kbps_from_timing(crtc_timing);
 
        if (!crtc_timing->flags.DSC)
                edp_decide_link_settings(link, &link_setting, req_bw);
@@ -322,13 +322,13 @@ bool edp_wait_for_t12(struct dc_link *link)
        return false;
 }
 
-void link_edp_add_delay_for_T9(struct dc_link *link)
+void edp_add_delay_for_T9(struct dc_link *link)
 {
        if (link && link->panel_config.pps.extra_delay_backlight_off > 0)
                fsleep(link->panel_config.pps.extra_delay_backlight_off * 1000);
 }
 
-bool link_edp_receiver_ready_T9(struct dc_link *link)
+bool edp_receiver_ready_T9(struct dc_link *link)
 {
        unsigned int tries = 0;
        unsigned char sinkstatus = 0;
@@ -353,7 +353,7 @@ bool link_edp_receiver_ready_T9(struct dc_link *link)
        return result;
 }
 
-bool link_edp_receiver_ready_T7(struct dc_link *link)
+bool edp_receiver_ready_T7(struct dc_link *link)
 {
        unsigned char sinkstatus = 0;
        unsigned char edpRev = 0;
@@ -388,7 +388,7 @@ bool link_edp_receiver_ready_T7(struct dc_link *link)
        return result;
 }
 
-bool link_power_alpm_dpcd_enable(struct dc_link *link, bool enable)
+bool edp_power_alpm_dpcd_enable(struct dc_link *link, bool enable)
 {
        bool ret = false;
        union dpcd_alpm_configuration alpm_config;
@@ -623,7 +623,7 @@ bool edp_setup_psr(struct dc_link *link,
                sizeof(psr_configuration.raw));
 
        if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) {
-               link_power_alpm_dpcd_enable(link, true);
+               edp_power_alpm_dpcd_enable(link, true);
                psr_context->su_granularity_required =
                        psr_config->su_granularity_required;
                psr_context->su_y_granularity =
@@ -752,7 +752,7 @@ bool edp_setup_psr(struct dc_link *link,
 
 }
 
-void link_get_psr_residency(const struct dc_link *link, uint32_t *residency)
+void edp_get_psr_residency(const struct dc_link *link, uint32_t *residency)
 {
        struct dc  *dc = link->ctx->dc;
        struct dmub_psr *psr = dc->res_pool->psr;
@@ -767,7 +767,7 @@ void link_get_psr_residency(const struct dc_link *link, uint32_t *residency)
        else
                *residency = 0;
 }
-bool link_set_sink_vtotal_in_psr_active(const struct dc_link *link, uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su)
+bool edp_set_sink_vtotal_in_psr_active(const struct dc_link *link, uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su)
 {
        struct dc *dc = link->ctx->dc;
        struct dmub_psr *psr = dc->res_pool->psr;
index 4439598..28f5520 100644 (file)
@@ -49,5 +49,15 @@ bool edp_set_psr_allow_active(struct dc_link *link, const bool *allow_active,
 bool edp_setup_psr(struct dc_link *link,
                const struct dc_stream_state *stream, struct psr_config *psr_config,
                struct psr_context *psr_context);
+bool edp_set_sink_vtotal_in_psr_active(const struct dc_link *link,
+       uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su);
+void edp_get_psr_residency(const struct dc_link *link, uint32_t *residency);
 bool edp_wait_for_t12(struct dc_link *link);
+bool edp_is_ilr_optimization_required(struct dc_link *link,
+       struct dc_crtc_timing *crtc_timing);
+bool edp_backlight_enable_aux(struct dc_link *link, bool enable);
+void edp_add_delay_for_T9(struct dc_link *link);
+bool edp_receiver_ready_T9(struct dc_link *link);
+bool edp_receiver_ready_T7(struct dc_link *link);
+bool edp_power_alpm_dpcd_enable(struct dc_link *link, bool enable);
 #endif /* __DC_LINK_EDP_POWER_CONTROL_H__ */
index bd471b6..4fb526b 100644 (file)
@@ -45,6 +45,9 @@ bool program_hpd_filter(const struct dc_link *link);
 bool dpia_query_hpd_status(struct dc_link *link);
 bool query_hpd_status(struct dc_link *link, uint32_t *is_hpd_high);
 bool link_get_hpd_state(struct dc_link *link);
+struct gpio *link_get_hpd_gpio(struct dc_bios *dcb,
+               struct graphics_object_id link_id,
+               struct gpio_service *gpio_service);
 void link_enable_hpd(const struct dc_link *link);
 void link_disable_hpd(const struct dc_link *link);
 void link_enable_hpd_filter(struct dc_link *link, bool enable);