diff options
author | Wenjing Liu <wenjing.liu@amd.com> | 2023-02-06 17:58:52 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2023-02-28 14:30:00 -0500 |
commit | 7ae1dbe6547c39410d82156c96eaa9c8cf55e87a (patch) | |
tree | aa73e9dbec9b57f292b08838482525c3c74902a2 | |
parent | 1099238b966e9b291fca40d908d6a016ce758455 (diff) | |
download | linux-7ae1dbe6547c39410d82156c96eaa9c8cf55e87a.tar.gz linux-7ae1dbe6547c39410d82156c96eaa9c8cf55e87a.tar.bz2 linux-7ae1dbe6547c39410d82156c96eaa9c8cf55e87a.zip |
drm/amd/display: merge dc_link.h into dc.h and dc_types.h
[why]
Remove the need to include dc_link.h separately. dc.h should contain
everything needed on DM side.
[How]
Merge dc_link.h into dc.h and dc_types.h so DM only needs to include
dc.h to use all link public functions.
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>
33 files changed, 978 insertions, 288 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index cfbde4fde852..824cfc4a0293 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2273,7 +2273,7 @@ static int dm_late_init(void *handle) struct dc_link *edp_links[MAX_NUM_EDP]; int edp_num; - get_edp_links(adev->dm.dc, edp_links, &edp_num); + dc_get_edp_links(adev->dm.dc, edp_links, &edp_num); for (i = 0; i < edp_num; i++) { if (!dmub_init_abm_config(adev->dm.dc->res_pool, params, i)) return -EINVAL; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 09a3efa517da..4a5dae578d97 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -724,7 +724,7 @@ static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __us for (i = 0; i < (unsigned int)(link_training_settings.link_settings.lane_count); i++) link_training_settings.hw_lane_settings[i] = link->cur_lane_setting[i]; - dc_link_set_test_pattern( + dc_link_dp_set_test_pattern( link, test_pattern, DP_TEST_PATTERN_COLOR_SPACE_RGB, diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c index 69691daf4dbb..73a45ec27f90 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c @@ -104,7 +104,7 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m int edp_num; unsigned int panel_inst; - get_edp_links(dc, edp_links, &edp_num); + dc_get_edp_links(dc, edp_links, &edp_num); if (dc->hwss.exit_optimized_pwr_state) dc->hwss.exit_optimized_pwr_state(dc, dc->current_state); @@ -129,7 +129,7 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr) int edp_num; unsigned int panel_inst; - get_edp_links(dc, edp_links, &edp_num); + dc_get_edp_links(dc, edp_links, &edp_num); if (edp_num) { for (panel_inst = 0; panel_inst < edp_num; panel_inst++) { edp_link = edp_links[panel_inst]; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 1c218c526650..d406d7b74c6c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -53,7 +53,6 @@ #include "link_encoder.h" #include "link_enc_cfg.h" -#include "dc_link.h" #include "link.h" #include "dm_helpers.h" #include "mem_input.h" @@ -1298,7 +1297,7 @@ static void detect_edp_presence(struct dc *dc) int i; int edp_num; - get_edp_links(dc, edp_links, &edp_num); + dc_get_edp_links(dc, edp_links, &edp_num); if (!edp_num) return; @@ -4317,157 +4316,6 @@ bool dc_is_dmcu_initialized(struct dc *dc) return false; } -bool dc_is_oem_i2c_device_present( - struct dc *dc, - size_t slave_address) -{ - if (dc->res_pool->oem_device) - return dce_i2c_oem_device_present( - dc->res_pool, - dc->res_pool->oem_device, - slave_address); - - return false; -} - -bool dc_submit_i2c( - struct dc *dc, - uint32_t link_index, - struct i2c_command *cmd) -{ - - struct dc_link *link = dc->links[link_index]; - struct ddc_service *ddc = link->ddc; - return dce_i2c_submit_command( - dc->res_pool, - ddc->ddc_pin, - cmd); -} - -bool dc_submit_i2c_oem( - struct dc *dc, - struct i2c_command *cmd) -{ - struct ddc_service *ddc = dc->res_pool->oem_device; - if (ddc) - return dce_i2c_submit_command( - dc->res_pool, - ddc->ddc_pin, - cmd); - - return false; -} - -static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink) -{ - if (dc_link->sink_count >= MAX_SINKS_PER_LINK) { - BREAK_TO_DEBUGGER(); - return false; - } - - dc_sink_retain(sink); - - dc_link->remote_sinks[dc_link->sink_count] = sink; - dc_link->sink_count++; - - return true; -} - -/* - * dc_link_add_remote_sink() - Create a sink and attach it to an existing link - * - * EDID length is in bytes - */ -struct dc_sink *dc_link_add_remote_sink( - struct dc_link *link, - const uint8_t *edid, - int len, - struct dc_sink_init_data *init_data) -{ - struct dc_sink *dc_sink; - enum dc_edid_status edid_status; - - if (len > DC_MAX_EDID_BUFFER_SIZE) { - dm_error("Max EDID buffer size breached!\n"); - return NULL; - } - - if (!init_data) { - BREAK_TO_DEBUGGER(); - return NULL; - } - - if (!init_data->link) { - BREAK_TO_DEBUGGER(); - return NULL; - } - - dc_sink = dc_sink_create(init_data); - - if (!dc_sink) - return NULL; - - memmove(dc_sink->dc_edid.raw_edid, edid, len); - dc_sink->dc_edid.length = len; - - if (!link_add_remote_sink_helper( - link, - dc_sink)) - goto fail_add_sink; - - edid_status = dm_helpers_parse_edid_caps( - link, - &dc_sink->dc_edid, - &dc_sink->edid_caps); - - /* - * Treat device as no EDID device if EDID - * parsing fails - */ - if (edid_status != EDID_OK && edid_status != EDID_PARTIAL_VALID) { - dc_sink->dc_edid.length = 0; - dm_error("Bad EDID, status%d!\n", edid_status); - } - - return dc_sink; - -fail_add_sink: - dc_sink_release(dc_sink); - return NULL; -} - -/* - * dc_link_remove_remote_sink() - Remove a remote sink from a dc_link - * - * Note that this just removes the struct dc_sink - it doesn't - * program hardware or alter other members of dc_link - */ -void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink) -{ - int i; - - if (!link->sink_count) { - BREAK_TO_DEBUGGER(); - return; - } - - for (i = 0; i < link->sink_count; i++) { - if (link->remote_sinks[i] == sink) { - dc_sink_release(sink); - link->remote_sinks[i] = NULL; - - /* shrink array to remove empty place */ - while (i < link->sink_count - 1) { - link->remote_sinks[i] = link->remote_sinks[i+1]; - i++; - } - link->remote_sinks[i] = NULL; - link->sink_count--; - return; - } - } -} - void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info) { info->displayClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz; @@ -4990,7 +4838,7 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bo return; } - get_edp_links(dc, edp_links, &edp_num); + dc_get_edp_links(dc, edp_links, &edp_num); /* Determine panel inst */ for (i = 0; i < edp_num; i++) { diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index a951e10416ee..862cb0f93b7d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -34,6 +34,49 @@ * in this file which calls link functions. */ #include "link.h" +#include "dce/dce_i2c.h" +struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index) +{ + return dc->links[link_index]; +} + +void dc_get_edp_links(const struct dc *dc, + struct dc_link **edp_links, + int *edp_num) +{ + int i; + + *edp_num = 0; + for (i = 0; i < dc->link_count; i++) { + // report any eDP links, even unconnected DDI's + if (!dc->links[i]) + continue; + if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) { + edp_links[*edp_num] = dc->links[i]; + if (++(*edp_num) == MAX_NUM_EDP) + return; + } + } +} + +bool dc_get_edp_link_panel_inst(const struct dc *dc, + const struct dc_link *link, + unsigned int *inst_out) +{ + struct dc_link *edp_links[MAX_NUM_EDP]; + int edp_num, i; + + *inst_out = 0; + if (link->connector_signal != SIGNAL_TYPE_EDP) + return false; + dc_get_edp_links(dc, edp_links, &edp_num); + for (i = 0; i < edp_num; i++) { + if (link == edp_links[i]) + break; + (*inst_out)++; + } + return true; +} bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) { @@ -101,3 +144,47 @@ bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx) { return link_update_dsc_config(pipe_ctx); } + +bool dc_is_oem_i2c_device_present( + struct dc *dc, + size_t slave_address) +{ + if (dc->res_pool->oem_device) + return dce_i2c_oem_device_present( + dc->res_pool, + dc->res_pool->oem_device, + slave_address); + + return false; +} + +bool dc_submit_i2c( + struct dc *dc, + uint32_t link_index, + struct i2c_command *cmd) +{ + + struct dc_link *link = dc->links[link_index]; + struct ddc_service *ddc = link->ddc; + + return dce_i2c_submit_command( + dc->res_pool, + ddc->ddc_pin, + cmd); +} + +bool dc_submit_i2c_oem( + struct dc *dc, + struct i2c_command *cmd) +{ + struct ddc_service *ddc = dc->res_pool->oem_device; + + if (ddc) + return dce_i2c_submit_command( + dc->res_pool, + ddc->ddc_pin, + cmd); + + return false; +} + diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 8a62f3e93e35..c84554933dc2 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1380,8 +1380,159 @@ 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); /* Link Interfaces */ -/* TODO: remove this after resolving external dependencies */ -#include "dc_link.h" +/* + * A link contains one or more sinks and their connected status. + * The currently active signal type (HDMI, DP-SST, DP-MST) is also reported. + */ +struct dc_link { + struct dc_sink *remote_sinks[MAX_SINKS_PER_LINK]; + unsigned int sink_count; + struct dc_sink *local_sink; + unsigned int link_index; + enum dc_connection_type type; + enum signal_type connector_signal; + enum dc_irq_source irq_source_hpd; + enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse */ + + bool is_hpd_filter_disabled; + bool dp_ss_off; + + /** + * @link_state_valid: + * + * If there is no link and local sink, this variable should be set to + * false. Otherwise, it should be set to true; usually, the function + * core_link_enable_stream sets this field to true. + */ + bool link_state_valid; + bool aux_access_disabled; + bool sync_lt_in_progress; + bool skip_stream_reenable; + bool is_internal_display; + /** @todo Rename. Flag an endpoint as having a programmable mapping to a DIG encoder. */ + bool is_dig_mapping_flexible; + bool hpd_status; /* HPD status of link without physical HPD pin. */ + bool is_hpd_pending; /* Indicates a new received hpd */ + bool is_automated; /* Indicates automated testing */ + + bool edp_sink_present; + + struct dp_trace dp_trace; + + /* caps is the same as reported_link_cap. link_traing use + * reported_link_cap. Will clean up. TODO + */ + struct dc_link_settings reported_link_cap; + struct dc_link_settings verified_link_cap; + struct dc_link_settings cur_link_settings; + struct dc_lane_settings cur_lane_setting[LANE_COUNT_DP_MAX]; + struct dc_link_settings preferred_link_setting; + /* preferred_training_settings are override values that + * come from DM. DM is responsible for the memory + * management of the override pointers. + */ + struct dc_link_training_overrides preferred_training_settings; + struct dp_audio_test_data audio_test_data; + + uint8_t ddc_hw_inst; + + uint8_t hpd_src; + + uint8_t link_enc_hw_inst; + /* DIG link encoder ID. Used as index in link encoder resource pool. + * For links with fixed mapping to DIG, this is not changed after dc_link + * object creation. + */ + enum engine_id eng_id; + + bool test_pattern_enabled; + union compliance_test_state compliance_test_state; + + void *priv; + + struct ddc_service *ddc; + + bool aux_mode; + + /* Private to DC core */ + + const struct dc *dc; + + struct dc_context *ctx; + + struct panel_cntl *panel_cntl; + struct link_encoder *link_enc; + struct graphics_object_id link_id; + /* Endpoint type distinguishes display endpoints which do not have entries + * in the BIOS connector table from those that do. Helps when tracking link + * encoder to display endpoint assignments. + */ + enum display_endpoint_type ep_type; + union ddi_channel_mapping ddi_channel_mapping; + struct connector_device_tag_info device_tag; + struct dpcd_caps dpcd_caps; + uint32_t dongle_max_pix_clk; + unsigned short chip_caps; + unsigned int dpcd_sink_count; +#if defined(CONFIG_DRM_AMD_DC_HDCP) + struct hdcp_caps hdcp_caps; +#endif + enum edp_revision edp_revision; + union dpcd_sink_ext_caps dpcd_sink_ext_caps; + + struct psr_settings psr_settings; + + /* Drive settings read from integrated info table */ + struct dc_lane_settings bios_forced_drive_settings; + + /* Vendor specific LTTPR workaround variables */ + uint8_t vendor_specific_lttpr_link_rate_wa; + bool apply_vendor_specific_lttpr_link_rate_wa; + + /* MST record stream using this link */ + struct link_flags { + bool dp_keep_receiver_powered; + bool dp_skip_DID2; + bool dp_skip_reset_segment; + bool dp_skip_fs_144hz; + bool dp_mot_reset_segment; + /* Some USB4 docks do not handle turning off MST DSC once it has been enabled. */ + bool dpia_mst_dsc_always_on; + /* Forced DPIA into TBT3 compatibility mode. */ + bool dpia_forced_tbt3_mode; + bool dongle_mode_timing_override; + } wa_flags; + struct link_mst_stream_allocation_table mst_stream_alloc_table; + + struct dc_link_status link_status; + struct dprx_states dprx_states; + + struct gpio *hpd_gpio; + enum dc_link_fec_state fec_state; + bool link_powered_externally; // Used to bypass hardware sequencing delays when panel is powered down forcibly + + struct dc_panel_config panel_config; + struct phy_state phy_state; + // BW ALLOCATON USB4 ONLY + struct dc_dpia_bw_alloc dpia_bw_alloc_config; +}; + +/* Return an enumerated dc_link. + * dc_link order is constant and determined at + * boot time. They cannot be created or destroyed. + * Use dc_get_caps() to get number of links. + */ +struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index); + +/* Return instance id of the edp link. Inst 0 is primary edp link. */ +bool dc_get_edp_link_panel_inst(const struct dc *dc, + const struct dc_link *link, + unsigned int *inst_out); + +/* Return an array of link pointers to edp links. */ +void dc_get_edp_links(const struct dc *dc, + struct dc_link **edp_links, + int *edp_num); /* The function initiates detection handshake over the given link. It first * determines if there are display connections over the link. If so it initiates @@ -1405,6 +1556,38 @@ uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane); */ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason); +struct dc_sink_init_data; + +/* When link connection type is dc_connection_mst_branch, remote sink can be + * added to the link. The interface creates a remote sink and associates it with + * current link. The sink will be retained by link until remove remote sink is + * called. + * + * @dc_link - link the remote sink will be added to. + * @edid - byte array of EDID raw data. + * @len - size of the edid in byte + * @init_data - + */ +struct dc_sink *dc_link_add_remote_sink( + struct dc_link *dc_link, + const uint8_t *edid, + int len, + struct dc_sink_init_data *init_data); + +/* Remove remote sink from a link with dc_connection_mst_branch connection type. + * @link - link the sink should be removed from + * @sink - sink to be removed. + */ +void dc_link_remove_remote_sink( + struct dc_link *link, + struct dc_sink *sink); + +/* Enable HPD interrupt handler for a given link */ +void dc_link_enable_hpd(const struct dc_link *link); + +/* Disable HPD interrupt handler for a given link */ +void dc_link_disable_hpd(const struct dc_link *link); + /* determine if there is a sink connected to the link * * @type - dc_connection_single if connected, dc_connection_none otherwise. @@ -1418,15 +1601,119 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason); bool dc_link_detect_connection_type(struct dc_link *link, enum dc_connection_type *type); +/* query current hpd pin value + * return - true HPD is asserted (HPD high), false otherwise (HPD low) + * + */ +bool dc_link_get_hpd_state(struct dc_link *dc_link); + /* Getter for cached link status from given link */ const struct dc_link_status *dc_link_get_status(const struct dc_link *link); +/* enable/disable hardware HPD filter. + * + * @link - The link the HPD pin is associated with. + * @enable = true - enable hardware HPD filter. HPD event will only queued to irq + * handler once after no HPD change has been detected within dc default HPD + * filtering interval since last HPD event. i.e if display keeps toggling hpd + * pulses within default HPD interval, no HPD event will be received until HPD + * toggles have stopped. Then HPD event will be queued to irq handler once after + * dc default HPD filtering interval since last HPD event. + * + * @enable = false - disable hardware HPD filter. HPD event will be queued + * immediately to irq handler after no HPD change has been detected within + * IRQ_HPD (aka HPD short pulse) interval (i.e 2ms). + */ +void dc_link_enable_hpd_filter(struct dc_link *link, bool enable); + +/* submit i2c read/write payloads through ddc channel + * @link_index - index to a link with ddc in i2c mode + * @cmd - i2c command structure + * return - true if success, false otherwise. + */ +bool dc_submit_i2c( + struct dc *dc, + uint32_t link_index, + struct i2c_command *cmd); + +/* submit i2c read/write payloads through oem channel + * @link_index - index to a link with ddc in i2c mode + * @cmd - i2c command structure + * return - true if success, false otherwise. + */ +bool dc_submit_i2c_oem( + struct dc *dc, + struct i2c_command *cmd); + +enum aux_return_code_type; +/* Attempt to transfer the given aux payload. This function does not perform + * retries or handle error states. The reply is returned in the payload->reply + * and the result through operation_result. Returns the number of bytes + * transferred,or -1 on a failure. + */ +int dc_link_aux_transfer_raw(struct ddc_service *ddc, + struct aux_payload *payload, + enum aux_return_code_type *operation_result); + +bool dc_is_oem_i2c_device_present( + struct dc *dc, + size_t slave_address +); + #ifdef CONFIG_DRM_AMD_DC_HDCP + /* return true if the connected receiver supports the hdcp version */ bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal); bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal); #endif +/* Notify DC about DP RX Interrupt (aka DP IRQ_HPD). + * + * TODO - When defer_handling is true the function will have a different purpose. + * It no longer does complete hpd rx irq handling. We should create a separate + * interface specifically for this case. + * + * Return: + * true - Downstream port status changed. DM should call DC to do the + * detection. + * false - no change in Downstream port status. No further action required + * from DM. + */ +bool dc_link_handle_hpd_rx_irq(struct dc_link *dc_link, + union hpd_irq_data *hpd_irq_dpcd_data, bool *out_link_loss, + bool defer_handling, bool *has_left_work); +/* handle DP specs define test automation sequence*/ +void dc_link_dp_handle_automated_test(struct dc_link *link); + +/* handle DP Link loss sequence and try to recover RX link loss with best + * effort + */ +void dc_link_dp_handle_link_loss(struct dc_link *link); + +/* Determine if hpd rx irq should be handled or ignored + * return true - hpd rx irq should be handled. + * return false - it is safe to ignore hpd rx irq event + */ +bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link); + +/* Determine if link loss is indicated with a given hpd_irq_dpcd_data. + * @link - link the hpd irq data associated with + * @hpd_irq_dpcd_data - input hpd irq data + * return - true if hpd irq data indicates a link lost + */ +bool dc_link_check_link_loss_status(struct dc_link *link, + union hpd_irq_data *hpd_irq_dpcd_data); + +/* Read hpd rx irq data from a given link + * @link - link where the hpd irq data should be read from + * @irq_data - output hpd irq data + * return - DC_OK if hpd irq data is read successfully, otherwise hpd irq data + * read has failed. + */ +enum dc_status dc_link_dp_read_hpd_rx_irq_data( + struct dc_link *link, + union hpd_irq_data *irq_data); + /* The function clears recorded DP RX states in the link. DM should call this * function when it is resuming from S3 power state to previously connected links. * @@ -1494,6 +1781,268 @@ void dc_restore_link_res_map(const struct dc *dc, uint32_t *map); * interface i.e stream_update->dsc_config */ bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx); + +/* translate a raw link rate data to bandwidth in kbps */ +uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw); + +/* determine the optimal bandwidth given link and required bw. + * @link - current detected link + * @req_bw - requested bandwidth in kbps + * @link_settings - returned most optimal link settings that can fit the + * requested bandwidth + * return - false if link can't support requested bandwidth, true if link + * settings is found. + */ +bool dc_link_decide_edp_link_settings(struct dc_link *link, + struct dc_link_settings *link_settings, + uint32_t req_bw); + +/* return the max dp link settings can be driven by the link without considering + * connected RX device and its capability + */ +bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, + struct dc_link_settings *max_link_enc_cap); + +/* determine when the link is driving MST mode, what DP link channel coding + * format will be used. The decision will remain unchanged until next HPD event. + * + * @link - a link with DP RX connection + * return - if stream is committed to this link with MST signal type, type of + * channel coding format dc will choose. + */ +enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format( + const struct dc_link *link); + +/* get max dp link settings the link can enable with all things considered. (i.e + * TX/RX/Cable capabilities and dp override policies. + * + * @link - a link with DP RX connection + * return - max dp link settings the link can enable. + * + */ +const struct dc_link_settings *dc_link_get_link_cap(const struct dc_link *link); + +/* Check if a RX (ex. DP sink, MST hub, passive or active dongle) is connected + * to a link with dp connector signal type. + * @link - a link with dp connector signal type + * return - true if connected, false otherwise + */ +bool dc_link_is_dp_sink_present(struct dc_link *link); + +/* Force DP lane settings update to main-link video signal and notify the change + * to DP RX via DPCD. This is a debug interface used for video signal integrity + * tuning purpose. The interface assumes link has already been enabled with DP + * signal. + * + * @lt_settings - a container structure with desired hw_lane_settings + */ +void dc_link_set_drive_settings(struct dc *dc, + struct link_training_settings *lt_settings, + const struct dc_link *link); + +/* Enable a test pattern in Link or PHY layer in an active link for compliance + * test or debugging purpose. The test pattern will remain until next un-plug. + * + * @link - active link with DP signal output enabled. + * @test_pattern - desired test pattern to output. + * NOTE: set to DP_TEST_PATTERN_VIDEO_MODE to disable previous test pattern. + * @test_pattern_color_space - for video test pattern choose a desired color + * space. + * @p_link_settings - For PHY pattern choose a desired link settings + * @p_custom_pattern - some test pattern will require a custom input to + * customize some pattern details. Otherwise keep it to NULL. + * @cust_pattern_size - size of the custom pattern input. + * + */ +bool dc_link_dp_set_test_pattern( + struct dc_link *link, + enum dp_test_pattern test_pattern, + enum dp_test_pattern_color_space test_pattern_color_space, + const struct link_training_settings *p_link_settings, + const unsigned char *p_custom_pattern, + unsigned int cust_pattern_size); + +/* Force DP link settings to always use a specific value until reboot to a + * specific link. If link has already been enabled, the interface will also + * switch to desired link settings immediately. This is a debug interface to + * generic dp issue trouble shooting. + */ +void dc_link_set_preferred_link_settings(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link *link); + +/* Force DP link to customize a specific link training behavior by overriding to + * standard DP specs defined protocol. This is a debug interface to trouble shoot + * display specific link training issues or apply some display specific + * workaround in link training. + * + * @link_settings - if not NULL, force preferred link set |