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

Reply via email to