drm/amd/display: convert link.h functions to function pointer style

[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>
This commit is contained in:
Wenjing Liu 2023-02-23 17:04:47 -05:00 committed by Alex Deucher
parent 98ef341862
commit 98ce7d32e2
52 changed files with 799 additions and 386 deletions

View 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 {

View 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;

View 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);
}
}

View 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)

View 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;

View 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,

View 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(

View 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.

View 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 = {

View 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);

View 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(

View 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 =

View 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;
}

View 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(

View 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;
}

View 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);

View 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;
}

View 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;
}

View 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;
}

View 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;

View 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.

View 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)) {

View 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.

View 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);
}

View 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;
}

View 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;
}

View 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:

View 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;

View 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,

View File

@ -28,13 +28,58 @@
/* 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);
/* DDC */
/*************************** 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 **************************************/
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__ */

View 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"

View 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,

View 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__ */

View 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);
}

View 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,

View 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;
}

View File

@ -26,11 +26,18 @@
#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__ */

View 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))

View File

@ -27,14 +27,27 @@
#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__ */

View 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"
@ -49,69 +52,248 @@
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,
/* link factory owns the creation/destruction of link structures. */
static void construct_link_service_factory(struct link_service *link_srv)
{
/* DDC */
.aux_transfer_raw = link_aux_transfer_raw,
link_srv->create_link = link_create;
link_srv->destroy_link = link_destroy;
}
/* 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,
/* 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;
}
/* 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,
/* 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;
}
/* 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,
/* 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;
}
/* 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,
/* 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;
}
/* 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,
};
/* 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;
}
static enum transmitter translate_encoder_to_transmitter(struct graphics_object_id encoder)
/* 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;
}

View 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__ */

View 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__ */

View 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

View File

@ -25,4 +25,11 @@
#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__ */

View File

@ -37,13 +37,41 @@
#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,

View 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;
}

View 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);

View 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);

View 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) &&

View 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;

View 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__ */

View 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);