From: Dominik Kaszewski <[email protected]> [Why] stream->sink is optional and can be null, so should always be checked before dereference. Additionally, most of its usage in DPMS sequences is for stream->sink->link, which can be replaced with stream->link, as the two should always be the same.
[How] * Replace stream->sink->link in DPMS on/off * Add assert to USB4 BW allocation where sink is required * Avoid inconsistencies in resource access, e.g. don't repeat stream->link after it was already saved to a local variable * Pull out effective VPG calculation to helper getter * Formatting fixes Reviewed-by: Nicholas Kazlauskas <[email protected]> Signed-off-by: Dominik Kaszewski <[email protected]> Signed-off-by: George Zhang <[email protected]> --- .../gpu/drm/amd/display/dc/link/link_dpms.c | 178 +++++++++--------- 1 file changed, 90 insertions(+), 88 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 42e7f0e9b3ce..479a8fbfdc5d 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -2296,6 +2296,8 @@ static enum dc_status enable_link( static bool allocate_usb4_bandwidth_for_stream(struct dc_stream_state *stream, int stream_bw) { + ASSERT(stream->sink); + struct dc_link *link = stream->sink->link; int req_bw = stream_bw; @@ -2342,6 +2344,8 @@ static bool allocate_usb4_bandwidth_for_stream(struct dc_stream_state *stream, i static bool allocate_usb4_bandwidth(struct dc_stream_state *stream) { + ASSERT(stream->sink); + bool ret; int bw = dc_bandwidth_in_kbps_from_timing(&stream->timing, @@ -2361,38 +2365,43 @@ static bool deallocate_usb4_bandwidth(struct dc_stream_state *stream) return ret; } +static struct vpg *get_vpg(struct pipe_ctx *pipe_ctx) +{ + if (dc_is_hdmi_frl_signal(pipe_ctx->stream->signal)) + return pipe_ctx->stream_res.hpo_frl_stream_enc->vpg; + else if (dp_is_128b_132b_signal(pipe_ctx)) + return pipe_ctx->stream_res.hpo_dp_stream_enc->vpg; + else + return pipe_ctx->stream_res.stream_enc->vpg; +} + void link_set_dpms_off(struct pipe_ctx *pipe_ctx) { - struct dc *dc = pipe_ctx->stream->ctx->dc; + DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); struct dc_stream_state *stream = pipe_ctx->stream; - struct dc_link *link = stream->sink->link; - struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg; + struct dc *dc = stream->ctx->dc; + struct dc_link *link = stream->link; + struct vpg *vpg = get_vpg(pipe_ctx); enum dp_panel_mode panel_mode_dp = dp_get_panel_mode(link); - DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); - ASSERT(is_master_pipe_for_link(link, pipe_ctx)); - if (dp_is_128b_132b_signal(pipe_ctx)) - vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg; - if (dc_is_hdmi_frl_signal(pipe_ctx->stream->signal)) - vpg = pipe_ctx->stream_res.hpo_frl_stream_enc->vpg; - if (dc_is_virtual_signal(pipe_ctx->stream->signal)) + if (dc_is_virtual_signal(stream->signal)) return; - if (pipe_ctx->stream->sink) { - if (pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL && - pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_NONE) { + if (stream->sink) { + if (stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL && + stream->sink->sink_signal != SIGNAL_TYPE_NONE) { DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x link=%d sink_count=%d\n", __func__, - pipe_ctx->stream->sink->edid_caps.display_name, - pipe_ctx->stream->signal, link->link_index, link->sink_count); + stream->sink->edid_caps.display_name, + stream->signal, link->link_index, link->sink_count); } } link_wait_for_unlocked(link); - if (!pipe_ctx->stream->sink->edid_caps.panel_patch.skip_avmute) { - if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) + if (stream->sink && !stream->sink->edid_caps.panel_patch.skip_avmute) { + if (dc_is_hdmi_signal(stream->signal)) set_avmute(pipe_ctx, true); } @@ -2402,15 +2411,15 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx) dc->hwss.blank_stream(pipe_ctx); if (pipe_ctx->link_config.dp_tunnel_settings.should_use_dp_bw_allocation) - deallocate_usb4_bandwidth(pipe_ctx->stream); + deallocate_usb4_bandwidth(stream); - if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) + if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) deallocate_mst_payload(pipe_ctx); - else if (dc_is_dp_sst_signal(pipe_ctx->stream->signal) && + else if (dc_is_dp_sst_signal(stream->signal) && dp_is_128b_132b_signal(pipe_ctx)) update_sst_payload(pipe_ctx, false); - if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) { + if (dc_is_hdmi_signal(stream->signal)) { struct ext_hdmi_settings settings = {0}; enum engine_id eng_id = pipe_ctx->stream_res.stream_enc->id; @@ -2433,7 +2442,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx) } } - if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT && + if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT && !dp_is_128b_132b_signal(pipe_ctx)) { /* In DP1.x SST mode, our encoder will go to TPS1 @@ -2443,18 +2452,18 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx) * state machine. * In DP2 or MST mode, our encoder will stay video active */ - disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal); + disable_link(link, &pipe_ctx->link_res, stream->signal); dc->hwss.disable_stream(pipe_ctx); } else { dc->hwss.disable_stream(pipe_ctx); - disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal); + disable_link(link, &pipe_ctx->link_res, stream->signal); } edp_set_panel_assr(link, pipe_ctx, &panel_mode_dp, false); - if (pipe_ctx->stream->timing.flags.DSC) { - if (dc_is_dp_signal(pipe_ctx->stream->signal)) + if (stream->timing.flags.DSC) { + if (dc_is_dp_signal(stream->signal)) link_set_dsc_enable(pipe_ctx, false); - else if (dc_is_hdmi_frl_signal(pipe_ctx->stream->signal)) + else if (dc_is_hdmi_frl_signal(stream->signal)) link_set_dsc_on_stream(pipe_ctx, false); } if (dp_is_128b_132b_signal(pipe_ctx)) { @@ -2468,7 +2477,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx) /* for psp not exist case */ if (link->connector_signal == SIGNAL_TYPE_EDP && dc->debug.psp_disabled_wa) { /* reset internal save state to default since eDP is off */ - enum dp_panel_mode panel_mode = dp_get_panel_mode(pipe_ctx->stream->link); + enum dp_panel_mode panel_mode = dp_get_panel_mode(link); /* since current psp not loaded, we need to reset it to default */ link->panel_mode = panel_mode; } @@ -2478,62 +2487,57 @@ void link_set_dpms_on( struct dc_state *state, struct pipe_ctx *pipe_ctx) { - struct dc *dc = pipe_ctx->stream->ctx->dc; + DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); struct dc_stream_state *stream = pipe_ctx->stream; - struct dc_link *link = stream->sink->link; + struct dc *dc = stream->ctx->dc; + struct dc_link *link = stream->link; enum dc_status status; struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc; enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO; - struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg; + struct vpg *vpg = get_vpg(pipe_ctx); const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res); bool apply_edp_fast_boot_optimization = - pipe_ctx->stream->apply_edp_fast_boot_optimization; - - DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); + stream->apply_edp_fast_boot_optimization; ASSERT(is_master_pipe_for_link(link, pipe_ctx)); - if (dp_is_128b_132b_signal(pipe_ctx)) - vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg; - if (dc_is_hdmi_frl_signal(pipe_ctx->stream->signal)) - vpg = pipe_ctx->stream_res.hpo_frl_stream_enc->vpg; - if (dc_is_virtual_signal(pipe_ctx->stream->signal)) + if (dc_is_virtual_signal(stream->signal)) return; - if (pipe_ctx->stream->sink) { - if (pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL && - pipe_ctx->stream->sink->sink_signal != SIGNAL_TYPE_NONE) { + if (stream->sink) { + if (stream->sink->sink_signal != SIGNAL_TYPE_VIRTUAL && + stream->sink->sink_signal != SIGNAL_TYPE_NONE) { DC_LOG_DC("%s pipe_ctx dispname=%s signal=%x link=%d sink_count=%d\n", __func__, - pipe_ctx->stream->sink->edid_caps.display_name, - pipe_ctx->stream->signal, + stream->sink->edid_caps.display_name, + stream->signal, link->link_index, link->sink_count); } } - link_wait_for_unlocked(stream->link); + link_wait_for_unlocked(link); if (!dc->config.unify_link_enc_assignment) link_enc = link_enc_cfg_get_link_enc(link); ASSERT(link_enc); - if (!dc_is_virtual_signal(pipe_ctx->stream->signal) - && !dc_is_hdmi_frl_signal(pipe_ctx->stream->signal) + if (!dc_is_virtual_signal(stream->signal) + && !dc_is_hdmi_frl_signal(stream->signal) && !dp_is_128b_132b_signal(pipe_ctx)) { if (link_enc) link_enc->funcs->setup( link_enc, - pipe_ctx->stream->signal); + stream->signal); } - pipe_ctx->stream->link->link_state_valid = true; + link->link_state_valid = true; - if (dc_is_hdmi_frl_signal(pipe_ctx->stream->signal)) - hdmi_frl_decide_link_settings(stream, &stream->link->frl_link_settings, &pipe_ctx->dsc_padding_params); + if (dc_is_hdmi_frl_signal(stream->signal)) + hdmi_frl_decide_link_settings(stream, &link->frl_link_settings, &pipe_ctx->dsc_padding_params); if (pipe_ctx->stream_res.tg->funcs->set_out_mux) { if (dp_is_128b_132b_signal(pipe_ctx)) otg_out_dest = OUT_MUX_HPO_DP; - else if (dc_is_hdmi_frl_signal(pipe_ctx->stream->signal)) + else if (dc_is_hdmi_frl_signal(stream->signal)) otg_out_dest = OUT_MUX_HPO_FRL; else otg_out_dest = OUT_MUX_DIO; @@ -2542,7 +2546,7 @@ void link_set_dpms_on( link_hwss->setup_stream_attribute(pipe_ctx); - pipe_ctx->stream->apply_edp_fast_boot_optimization = false; + stream->apply_edp_fast_boot_optimization = false; // Enable VPG before building infoframe if (vpg && vpg->funcs->vpg_poweron) @@ -2551,15 +2555,15 @@ void link_set_dpms_on( resource_build_info_frame(pipe_ctx); dc->hwss.update_info_frame(pipe_ctx); - if (dc_is_dp_signal(pipe_ctx->stream->signal)) + if (dc_is_dp_signal(stream->signal)) 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) { - pipe_ctx->stream->dpms_off = false; + if (stream->apply_seamless_boot_optimization) { + stream->dpms_off = false; /* Still enable stream features & audio on seamless boot for DP external displays */ - if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT) { + if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT) { enable_stream_features(pipe_ctx); dc->hwss.enable_audio_stream(pipe_ctx); } @@ -2569,11 +2573,11 @@ void link_set_dpms_on( } /* eDP lit up by bios already, no need to enable again. */ - if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP && + if (stream->signal == SIGNAL_TYPE_EDP && apply_edp_fast_boot_optimization && - !pipe_ctx->stream->timing.flags.DSC && + !stream->timing.flags.DSC && !pipe_ctx->next_odm_pipe) { - pipe_ctx->stream->dpms_off = false; + stream->dpms_off = false; update_psp_stream_config(pipe_ctx, false); if (link->is_dds) { @@ -2586,7 +2590,7 @@ void link_set_dpms_on( return; } - if (pipe_ctx->stream->dpms_off) + if (stream->dpms_off) return; /* For Dp tunneling link, a pending HPD means that we have a race condition between processing @@ -2604,9 +2608,9 @@ void link_set_dpms_on( * will be automatically set at a later time when the video is enabled * (DP_VID_STREAM_EN = 1). */ - if (pipe_ctx->stream->timing.flags.DSC) { - if (dc_is_dp_signal(pipe_ctx->stream->signal) || - dc_is_virtual_signal(pipe_ctx->stream->signal)) + if (stream->timing.flags.DSC) { + if (dc_is_dp_signal(stream->signal) || + dc_is_virtual_signal(stream->signal)) link_set_dsc_enable(pipe_ctx, true); } @@ -2617,7 +2621,7 @@ void link_set_dpms_on( if (status != DC_OK) { DC_LOG_WARNING("enabling link %u failed: %d\n", - pipe_ctx->stream->link->link_index, + link->link_index, status); /* Abort stream enable *unless* the failure was due to @@ -2627,19 +2631,18 @@ void link_set_dpms_on( */ if ((status != DC_FAIL_DP_LINK_TRAINING && status != DC_FAIL_HDMI_FRL_LINK_TRAINING) || - pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { - if (false == stream->link->link_status.link_active) - disable_link(stream->link, &pipe_ctx->link_res, - pipe_ctx->stream->signal); + stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { + if (false == link->link_status.link_active) + disable_link(link, &pipe_ctx->link_res, + stream->signal); BREAK_TO_DEBUGGER(); return; } } - if (pipe_ctx->stream->timing.flags.DSC && - dc_is_hdmi_frl_signal(pipe_ctx->stream->signal)) - //TODO: bring HDMI FRL in line with DP - link_set_dsc_on_stream(pipe_ctx, true); + if (stream->timing.flags.DSC && dc_is_hdmi_frl_signal(stream->signal)) + //TODO: bring HDMI FRL in line with DP + link_set_dsc_on_stream(pipe_ctx, true); /* turn off otg test pattern if enable */ if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) @@ -2651,37 +2654,37 @@ void link_set_dpms_on( * as a workaround for the incorrect value being applied * from transmitter control. */ - if (!(dc_is_virtual_signal(pipe_ctx->stream->signal) || - dc_is_hdmi_frl_signal(pipe_ctx->stream->signal) || + if (!(dc_is_virtual_signal(stream->signal) || + dc_is_hdmi_frl_signal(stream->signal) || dp_is_128b_132b_signal(pipe_ctx))) { if (link_enc) link_enc->funcs->setup( link_enc, - pipe_ctx->stream->signal); + stream->signal); } dc->hwss.enable_stream(pipe_ctx); /* Set DPS PPS SDP (AKA "info frames") */ - if (pipe_ctx->stream->timing.flags.DSC) { - if (dc_is_dp_signal(pipe_ctx->stream->signal) || - dc_is_virtual_signal(pipe_ctx->stream->signal)) { + if (stream->timing.flags.DSC) { + if (dc_is_dp_signal(stream->signal) || + dc_is_virtual_signal(stream->signal)) { dp_set_dsc_on_rx(pipe_ctx, true); link_set_dsc_pps_packet(pipe_ctx, true, true); } } - if (dc_is_dp_signal(pipe_ctx->stream->signal)) + if (dc_is_dp_signal(stream->signal)) dp_set_hblank_reduction_on_rx(pipe_ctx); if (pipe_ctx->link_config.dp_tunnel_settings.should_use_dp_bw_allocation) - allocate_usb4_bandwidth(pipe_ctx->stream); + allocate_usb4_bandwidth(stream); - if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) + if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) allocate_mst_payload(pipe_ctx); - else if (dc_is_dp_sst_signal(pipe_ctx->stream->signal) && + else if (dc_is_dp_sst_signal(stream->signal) && dp_is_128b_132b_signal(pipe_ctx)) update_sst_payload(pipe_ctx, true); @@ -2690,23 +2693,22 @@ void link_set_dpms_on( * training and stream unblank resolves the corruption issue. * This is workaround. */ - if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP && + if (stream->signal == SIGNAL_TYPE_EDP && link->is_display_mux_present) msleep(20); dc->hwss.unblank_stream(pipe_ctx, - &pipe_ctx->stream->link->cur_link_settings); + &link->cur_link_settings); if (stream->sink_patches.delay_ignore_msa > 0) msleep(stream->sink_patches.delay_ignore_msa); - if (dc_is_dp_signal(pipe_ctx->stream->signal)) + if (dc_is_dp_signal(stream->signal)) enable_stream_features(pipe_ctx); update_psp_stream_config(pipe_ctx, false); dc->hwss.enable_audio_stream(pipe_ctx); - if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) { + if (dc_is_hdmi_signal(stream->signal)) set_avmute(pipe_ctx, false); - } } -- 2.55.0
