drm/amd/display: rework recent update PHY state commit
authorWenjing Liu <wenjing.liu@amd.com>
Wed, 31 Aug 2022 18:56:46 +0000 (14:56 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 19 Sep 2022 19:10:24 +0000 (15:10 -0400)
[why]
Original change 594b237b9a07 ("drm/amd/display: Add
interface to track PHY state") was implemented by assuming stream's
dpms off is equivalent to PHY power off.
This assumption doesn't hold in following situations:
1. MST multiple stream scenario, where multiple streams are sharing the
same PHY output. Toggle dpms off for one of the stream doesn't power
off the PHY due to the presence of other streams.
2. enable stream failure scenario, where enable stream fails due to
failure of link training. This will cause DPMS off is set to false, while
the actual PHY power state is off in certain cases.
Due to the problematic assumption, the logic will skip disabling
other streams for MST multiple stream scenario, therefore PHY is
not actually powered off.

[how]
1. Rework this refactor by moving PHY state update down to hardware
level, where we update PHY state in place when hardware sequencer
is actually changing the power state of the PHY hardware.
2. Reimplement symclk on TX off workaround in place when we are actually
calling transmitter control to power off PHY in dcn32. Note the workaround is
added due to the lack of proper software interface to set TX while keeping
symclk on. We plan to address this interface problem so we can set TX off
only without affecting symclk in future dcn versions.

Fixes: 594b237b9a07 ("drm/amd/display: Add interface to track PHY state")
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Wayne Lin <wayne.lin@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>
28 files changed:
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dc_link.h
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c
drivers/gpu/drm/amd/display/dc/dcn201/dcn201_init.c
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.c
drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.h
drivers/gpu/drm/amd/display/dc/link/link_hwss_dpia.c
drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c
drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.c

index bc7325831c9184f649407eb8e310c66907fa595d..19eb960d75d8872e39b9dbeac5566dd81fd74f98 100644 (file)
@@ -1184,11 +1184,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) {
-                                               if (dc->hwss.update_phy_state)
-                                                       dc->hwss.update_phy_state(dc->current_state,
-                                                                       pipe, TX_OFF_SYMCLK_OFF);
-                                               else
-                                                       core_link_disable_stream(pipe);
+                                               core_link_disable_stream(pipe);
                                                pipe->stream->dpms_off = false;
                                        }
                                }
@@ -3061,11 +3057,7 @@ static void commit_planes_do_stream_update(struct dc *dc,
 
                        if (stream_update->dpms_off) {
                                if (*stream_update->dpms_off) {
-                                       if (dc->hwss.update_phy_state)
-                                               dc->hwss.update_phy_state(dc->current_state,
-                                                               pipe_ctx, TX_OFF_SYMCLK_ON);
-                                       else
-                                               core_link_disable_stream(pipe_ctx);
+                                       core_link_disable_stream(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);
@@ -3075,12 +3067,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);
-
-                                       if (dc->hwss.update_phy_state)
-                                               dc->hwss.update_phy_state(dc->current_state,
-                                                               pipe_ctx, TX_ON_SYMCLK_ON);
-                                       else
-                                               core_link_enable_stream(dc->current_state, pipe_ctx);
+                                       core_link_enable_stream(dc->current_state, pipe_ctx);
                                }
                        }
 
index 4bb78e356ebd240ce67faeb878614e2497752139..15ee23a0a944274e18c4e681bf2ae6d731b11eea 100644 (file)
@@ -2644,9 +2644,8 @@ static void disable_link(struct dc_link *link, const struct link_resource *link_
                                dp_set_fec_ready(link, link_res, false);
                        }
                }
-       } else {
-               if (signal != SIGNAL_TYPE_VIRTUAL)
-                       link->link_enc->funcs->disable_output(link->link_enc, signal);
+       } else if (signal != SIGNAL_TYPE_VIRTUAL) {
+               link->dc->hwss.disable_link_output(link, link_res, signal);
        }
 
        if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
@@ -2668,6 +2667,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
        bool is_over_340mhz = false;
        bool is_vga_mode = (stream->timing.h_addressable == 640)
                        && (stream->timing.v_addressable == 480);
+       struct dc *dc = pipe_ctx->stream->ctx->dc;
 
        if (stream->phy_pix_clk == 0)
                stream->phy_pix_clk = stream->timing.pix_clk_100hz / 10;
@@ -2707,11 +2707,12 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
        if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422)
                display_color_depth = COLOR_DEPTH_888;
 
-       link->link_enc->funcs->enable_tmds_output(
-                       link->link_enc,
+       dc->hwss.enable_tmds_link_output(
+                       link,
+                       &pipe_ctx->link_res,
+                       pipe_ctx->stream->signal,
                        pipe_ctx->clock_source->id,
                        display_color_depth,
-                       pipe_ctx->stream->signal,
                        stream->phy_pix_clk);
 
        if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
@@ -2722,15 +2723,16 @@ static void enable_link_lvds(struct pipe_ctx *pipe_ctx)
 {
        struct dc_stream_state *stream = pipe_ctx->stream;
        struct dc_link *link = stream->link;
+       struct dc *dc = stream->ctx->dc;
 
        if (stream->phy_pix_clk == 0)
                stream->phy_pix_clk = stream->timing.pix_clk_100hz / 10;
 
        memset(&stream->link->cur_link_settings, 0,
                        sizeof(struct dc_link_settings));
-
-       link->link_enc->funcs->enable_lvds_output(
-                       link->link_enc,
+       dc->hwss.enable_lvds_link_output(
+                       link,
+                       &pipe_ctx->link_res,
                        pipe_ctx->clock_source->id,
                        stream->phy_pix_clk);
 
index 2aa91cd461f99ce06bb041d0ac957ba023154c6f..2ffa146d35fb53e824a0de88a2e8c95bdf2725d6 100644 (file)
@@ -4518,25 +4518,15 @@ void dc_link_dp_handle_link_loss(struct dc_link *link)
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
-                               pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
-                       if (link->dc->hwss.update_phy_state)
-                               link->dc->hwss.update_phy_state(link->dc->current_state,
-                                               pipe_ctx, TX_OFF_SYMCLK_OFF);
-                       else
-                               core_link_disable_stream(pipe_ctx);
-               }
+                               pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe)
+                       core_link_disable_stream(pipe_ctx);
        }
 
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
-                               pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
-                       if (link->dc->hwss.update_phy_state)
-                               link->dc->hwss.update_phy_state(link->dc->current_state,
-                                               pipe_ctx, TX_ON_SYMCLK_ON);
-                       else
-                               core_link_enable_stream(link->dc->current_state, pipe_ctx);
-               }
+                               pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe)
+                       core_link_enable_stream(link->dc->current_state, pipe_ctx);
        }
 }
 
@@ -7077,60 +7067,9 @@ void dp_enable_link_phy(
        enum clock_source_id clock_source,
        const struct dc_link_settings *link_settings)
 {
-       struct dc  *dc = link->ctx->dc;
-       struct dmcu *dmcu = dc->res_pool->dmcu;
-       struct pipe_ctx *pipes =
-                       link->dc->current_state->res_ctx.pipe_ctx;
-       struct clock_source *dp_cs =
-                       link->dc->res_pool->dp_clock_source;
-       const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
-       unsigned int i;
-
-       if (link->connector_signal == SIGNAL_TYPE_EDP) {
-               if (!link->dc->config.edp_no_power_sequencing)
-                       link->dc->hwss.edp_power_control(link, true);
-               link->dc->hwss.edp_wait_for_hpd_ready(link, true);
-       }
-
-       /* If the current pixel clock source is not DTO(happens after
-        * switching from HDMI passive dongle to DP on the same connector),
-        * switch the pixel clock source to DTO.
-        */
-       for (i = 0; i < MAX_PIPES; i++) {
-               if (pipes[i].stream != NULL &&
-                       pipes[i].stream->link == link) {
-                       if (pipes[i].clock_source != NULL &&
-                                       pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
-                               pipes[i].clock_source = dp_cs;
-                               pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz =
-                                               pipes[i].stream->timing.pix_clk_100hz;
-                               pipes[i].clock_source->funcs->program_pix_clk(
-                                                       pipes[i].clock_source,
-                                                       &pipes[i].stream_res.pix_clk_params,
-                                                       dp_get_link_encoding_format(link_settings),
-                                                       &pipes[i].pll_settings);
-                       }
-               }
-       }
-
+       link->dc->hwss.enable_dp_link_output(link, link_res, signal,
+                       clock_source, link_settings);
        link->cur_link_settings = *link_settings;
-
-       if (dp_get_link_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);
-       }
-
-       if (dmcu != NULL && dmcu->funcs->lock_phy)
-               dmcu->funcs->lock_phy(dmcu);
-
-       if (link_hwss->ext.enable_dp_link_output)
-               link_hwss->ext.enable_dp_link_output(link, link_res, signal,
-                               clock_source, link_settings);
-
-       if (dmcu != NULL && dmcu->funcs->unlock_phy)
-               dmcu->funcs->unlock_phy(dmcu);
-
-       dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
        dp_receiver_power_ctrl(link, true);
 }
 
@@ -7205,29 +7144,8 @@ void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_
                enum signal_type signal)
 {
        struct dc  *dc = link->ctx->dc;
-       struct dmcu *dmcu = dc->res_pool->dmcu;
-       const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
-
-       if (!link->wa_flags.dp_keep_receiver_powered)
-               dp_receiver_power_ctrl(link, false);
-
-       if (signal == SIGNAL_TYPE_EDP) {
-               if (link->dc->hwss.edp_backlight_control)
-                       link->dc->hwss.edp_backlight_control(link, false);
-               if (link_hwss->ext.disable_dp_link_output)
-                       link_hwss->ext.disable_dp_link_output(link, link_res, signal);
-               link->dc->hwss.edp_power_control(link, false);
-       } else {
-               if (dmcu != NULL && dmcu->funcs->lock_phy)
-                       dmcu->funcs->lock_phy(dmcu);
-               if (link_hwss->ext.disable_dp_link_output)
-                       link_hwss->ext.disable_dp_link_output(link, link_res, signal);
-               if (dmcu != NULL && dmcu->funcs->unlock_phy)
-                       dmcu->funcs->unlock_phy(dmcu);
-       }
-
-       dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
 
+       dc->hwss.disable_link_output(link, link_res, signal);
        /* Clear current link setting.*/
        memset(&link->cur_link_settings, 0,
                        sizeof(link->cur_link_settings));
index 3f64b30926927b8d45917bd1c428dd090f90163f..4d9819d9ffb6162c97f583dc7e661a135863bf4d 100644 (file)
@@ -244,7 +244,7 @@ struct dc_link {
        struct gpio *hpd_gpio;
        enum dc_link_fec_state fec_state;
        struct dc_panel_config panel_config;
-       enum phy_state phy_state;
+       struct phy_state phy_state;
 };
 
 const struct dc_link_status *dc_link_get_status(const struct dc_link *dc_link);
index 801206aed63a145dcb89bc52a6bcfddb96b63b0e..8ffb13847ae092218e61905242caba9b6cdcf697 100644 (file)
@@ -1441,6 +1441,14 @@ static enum dc_status dce110_enable_stream_timing(
                        return DC_ERROR_UNEXPECTED;
                }
 
+               if (dc_is_hdmi_tmds_signal(stream->signal)) {
+                       stream->link->phy_state.symclk_ref_cnts.otg = 1;
+                       if (stream->link->phy_state.symclk_state == SYMCLK_OFF_TX_OFF)
+                               stream->link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
+                       else
+                               stream->link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+               }
+
                pipe_ctx->stream_res.tg->funcs->program_timing(
                                pipe_ctx->stream_res.tg,
                                &stream->timing,
@@ -1577,12 +1585,8 @@ static enum dc_status apply_single_controller_ctx_to_hw(
        if (dc_is_dp_signal(pipe_ctx->stream->signal))
                dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG);
 
-       if (!stream->dpms_off) {
-               if (dc->hwss.update_phy_state)
-                       dc->hwss.update_phy_state(context, pipe_ctx, TX_ON_SYMCLK_ON);
-               else
-                       core_link_enable_stream(context, pipe_ctx);
-       }
+       if (!stream->dpms_off)
+               core_link_enable_stream(context, pipe_ctx);
 
        /* DCN3.1 FPGA Workaround
         * Need to enable HPO DP Stream Encoder before setting OTG master enable.
@@ -2118,6 +2122,7 @@ static void dce110_reset_hw_ctx_wrap(
                                BREAK_TO_DEBUGGER();
                        }
                        pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg);
+                       pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg = 0;
                        pipe_ctx_old->plane_res.mi->funcs->free_mem_input(
                                        pipe_ctx_old->plane_res.mi, dc->current_state->stream_count);
 
@@ -2996,6 +3001,122 @@ void dce110_set_pipe(struct pipe_ctx *pipe_ctx)
                abm->funcs->set_pipe(abm, otg_inst, panel_cntl->inst);
 }
 
+void dce110_enable_lvds_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum clock_source_id clock_source,
+               uint32_t pixel_clock)
+{
+       link->link_enc->funcs->enable_lvds_output(
+                       link->link_enc,
+                       clock_source,
+                       pixel_clock);
+       link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+}
+
+void dce110_enable_tmds_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal,
+               enum clock_source_id clock_source,
+               enum dc_color_depth color_depth,
+               uint32_t pixel_clock)
+{
+       link->link_enc->funcs->enable_tmds_output(
+                       link->link_enc,
+                       clock_source,
+                       color_depth,
+                       signal,
+                       pixel_clock);
+       link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+}
+
+void dce110_enable_dp_link_output(
+               struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal,
+               enum clock_source_id clock_source,
+               const struct dc_link_settings *link_settings)
+{
+       struct dc  *dc = link->ctx->dc;
+       struct dmcu *dmcu = dc->res_pool->dmcu;
+       struct pipe_ctx *pipes =
+                       link->dc->current_state->res_ctx.pipe_ctx;
+       struct clock_source *dp_cs =
+                       link->dc->res_pool->dp_clock_source;
+       const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
+       unsigned int i;
+
+
+       if (link->connector_signal == SIGNAL_TYPE_EDP) {
+               if (!link->dc->config.edp_no_power_sequencing)
+                       link->dc->hwss.edp_power_control(link, true);
+               link->dc->hwss.edp_wait_for_hpd_ready(link, true);
+       }
+
+       /* If the current pixel clock source is not DTO(happens after
+        * switching from HDMI passive dongle to DP on the same connector),
+        * switch the pixel clock source to DTO.
+        */
+
+       for (i = 0; i < MAX_PIPES; i++) {
+               if (pipes[i].stream != NULL &&
+                               pipes[i].stream->link == link) {
+                       if (pipes[i].clock_source != NULL &&
+                                       pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
+                               pipes[i].clock_source = dp_cs;
+                               pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz =
+                                               pipes[i].stream->timing.pix_clk_100hz;
+                               pipes[i].clock_source->funcs->program_pix_clk(
+                                               pipes[i].clock_source,
+                                               &pipes[i].stream_res.pix_clk_params,
+                                               dp_get_link_encoding_format(link_settings),
+                                               &pipes[i].pll_settings);
+                       }
+               }
+       }
+
+       if (dp_get_link_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);
+       }
+
+       if (dmcu != NULL && dmcu->funcs->lock_phy)
+               dmcu->funcs->lock_phy(dmcu);
+
+       if (link_hwss->ext.enable_dp_link_output)
+               link_hwss->ext.enable_dp_link_output(link, link_res, signal,
+                               clock_source, link_settings);
+
+       link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+
+       if (dmcu != NULL && dmcu->funcs->unlock_phy)
+               dmcu->funcs->unlock_phy(dmcu);
+
+}
+
+void dce110_disable_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal)
+{
+       struct dc *dc = link->ctx->dc;
+       const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
+       struct dmcu *dmcu = dc->res_pool->dmcu;
+
+       if (signal == SIGNAL_TYPE_EDP &&
+                       link->dc->hwss.edp_backlight_control)
+               link->dc->hwss.edp_backlight_control(link, false);
+       else if (dc_is_dp_signal(signal) && dmcu != NULL && dmcu->funcs->lock_phy)
+               dmcu->funcs->lock_phy(dmcu);
+
+       link_hwss->disable_link_output(link, link_res, signal);
+       link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+
+       if (signal == SIGNAL_TYPE_EDP &&
+                       link->dc->hwss.edp_backlight_control)
+               link->dc->hwss.edp_power_control(link, false);
+       else if (dc_is_dp_signal(signal) && dmcu != NULL && dmcu->funcs->lock_phy)
+               dmcu->funcs->unlock_phy(dmcu);
+}
+
 static const struct hw_sequencer_funcs dce110_funcs = {
        .program_gamut_remap = program_gamut_remap,
        .program_output_csc = program_output_csc,
@@ -3035,6 +3156,10 @@ static const struct hw_sequencer_funcs dce110_funcs = {
        .set_backlight_level = dce110_set_backlight_level,
        .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
        .set_pipe = dce110_set_pipe,
+       .enable_lvds_link_output = dce110_enable_lvds_link_output,
+       .enable_tmds_link_output = dce110_enable_tmds_link_output,
+       .enable_dp_link_output = dce110_enable_dp_link_output,
+       .disable_link_output = dce110_disable_link_output,
 };
 
 static const struct hwseq_private_funcs dce110_private_funcs = {
index b6f3843d3d05c7e505a3f6d128a6aad5f751f529..758f4b3b0087f58baee53d8865c9115779203d56 100644 (file)
@@ -90,6 +90,24 @@ bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
                uint32_t frame_ramp);
 void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx);
 void dce110_set_pipe(struct pipe_ctx *pipe_ctx);
-
+void dce110_disable_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal);
+void dce110_enable_lvds_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum clock_source_id clock_source,
+               uint32_t pixel_clock);
+void dce110_enable_tmds_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal,
+               enum clock_source_id clock_source,
+               enum dc_color_depth color_depth,
+               uint32_t pixel_clock);
+void dce110_enable_dp_link_output(
+               struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal,
+               enum clock_source_id clock_source,
+               const struct dc_link_settings *link_settings);
 #endif /* __DC_HWSS_DCE110_H__ */
 
index f26e08032da0e1dd01140e9c9b741338f13e2bd5..287fdecc0b10a435184ce76a5c8852fe5b243a24 100644 (file)
@@ -899,6 +899,14 @@ enum dc_status dcn10_enable_stream_timing(
                return DC_ERROR_UNEXPECTED;
        }
 
+       if (dc_is_hdmi_tmds_signal(stream->signal)) {
+               stream->link->phy_state.symclk_ref_cnts.otg = 1;
+               if (stream->link->phy_state.symclk_state == SYMCLK_OFF_TX_OFF)
+                       stream->link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
+               else
+                       stream->link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+       }
+
        pipe_ctx->stream_res.tg->funcs->program_timing(
                        pipe_ctx->stream_res.tg,
                        &stream->timing,
@@ -1017,6 +1025,7 @@ static void dcn10_reset_back_end_for_pipe(
                if (pipe_ctx->stream_res.tg->funcs->set_drr)
                        pipe_ctx->stream_res.tg->funcs->set_drr(
                                        pipe_ctx->stream_res.tg, NULL);
+               pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0;
        }
 
        for (i = 0; i < dc->res_pool->pipe_count; i++)
index 10e613ec7d24f5e5c25f2dc50cc12b4bc6d15632..f2371c948822546fefac766dfb2abfea8ec0386a 100644 (file)
@@ -82,6 +82,10 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
        .set_backlight_level = dce110_set_backlight_level,
        .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
        .set_pipe = dce110_set_pipe,
+       .enable_lvds_link_output = dce110_enable_lvds_link_output,
+       .enable_tmds_link_output = dce110_enable_tmds_link_output,
+       .enable_dp_link_output = dce110_enable_dp_link_output,
+       .disable_link_output = dce110_disable_link_output,
        .get_dcc_en_bits = dcn10_get_dcc_en_bits,
        .update_visual_confirm_color = dcn10_update_visual_confirm_color,
 };
index 6f8c344e321d2eb817131f8fde9d27d290bad445..86ab3a71c67bda53ceb427c9889e35923bd3e41c 100644 (file)
@@ -706,6 +706,14 @@ enum dc_status dcn20_enable_stream_timing(
                return DC_ERROR_UNEXPECTED;
        }
 
+       if (dc_is_hdmi_tmds_signal(stream->signal)) {
+               stream->link->phy_state.symclk_ref_cnts.otg = 1;
+               if (stream->link->phy_state.symclk_state == SYMCLK_OFF_TX_OFF)
+                       stream->link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
+               else
+                       stream->link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+       }
+
        if (dc->hwseq->funcs.PLAT_58856_wa && (!dc_is_dp_signal(stream->signal)))
                dc->hwseq->funcs.PLAT_58856_wa(context, pipe_ctx);
 
@@ -2349,7 +2357,9 @@ static void dcn20_reset_back_end_for_pipe(
                struct dc_state *context)
 {
        int i;
-       struct dc_link *link;
+       struct dc_link *link = pipe_ctx->stream->link;
+       const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
+
        DC_LOGGER_INIT(dc->ctx->logger);
        if (pipe_ctx->stream_res.stream_enc == NULL) {
                pipe_ctx->stream = NULL;
@@ -2357,19 +2367,15 @@ static void dcn20_reset_back_end_for_pipe(
        }
 
        if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
-               link = pipe_ctx->stream->link;
                /* DPMS may already disable or */
                /* dpms_off status is incorrect due to fastboot
                 * feature. When system resume from S4 with second
                 * screen only, the dpms_off would be true but
                 * VBIOS lit up eDP, so check link status too.
                 */
-               if (!pipe_ctx->stream->dpms_off || link->link_status.link_active) {
-                       if (dc->hwss.update_phy_state)
-                               dc->hwss.update_phy_state(dc->current_state, pipe_ctx, TX_OFF_SYMCLK_OFF);
-                       else
-                               core_link_disable_stream(pipe_ctx);
-               } else if (pipe_ctx->stream_res.audio)
+               if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
+                       core_link_disable_stream(pipe_ctx);
+               else if (pipe_ctx->stream_res.audio)
                        dc->hwss.disable_audio_stream(pipe_ctx);
 
                /* free acquired resources */
@@ -2409,6 +2415,16 @@ static void dcn20_reset_back_end_for_pipe(
                if (pipe_ctx->stream_res.tg->funcs->set_drr)
                        pipe_ctx->stream_res.tg->funcs->set_drr(
                                        pipe_ctx->stream_res.tg, NULL);
+               /* TODO - convert symclk_ref_cnts for otg to a bit map to solve
+                * the case where the same symclk is shared across multiple otg
+                * instances
+                */
+               link->phy_state.symclk_ref_cnts.otg = 0;
+               if (link->phy_state.symclk_state == SYMCLK_ON_TX_OFF) {
+                       link_hwss->disable_link_output(link,
+                                       &pipe_ctx->link_res, pipe_ctx->stream->signal);
+                       link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+               }
        }
 
        for (i = 0; i < dc->res_pool->pipe_count; i++)
index 91e4885b743e837ca9464b5d0fca74e961c98ba2..7c5817c426faa78c55da31ac1eacf83c315fb737 100644 (file)
@@ -96,6 +96,10 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
 #ifndef TRIM_FSFT
        .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft,
 #endif
+       .enable_lvds_link_output = dce110_enable_lvds_link_output,
+       .enable_tmds_link_output = dce110_enable_tmds_link_output,
+       .enable_dp_link_output = dce110_enable_dp_link_output,
+       .disable_link_output = dce110_disable_link_output,
        .set_disp_pattern_generator = dcn20_set_disp_pattern_generator,
        .get_dcc_en_bits = dcn10_get_dcc_en_bits,
        .update_visual_confirm_color = dcn20_update_visual_confirm_color
index 1826dd7f3da142b74cb381f200170f1bfadaff37..9c16633e473a0ff87de4589e60a7e88adbd7aa2f 100644 (file)
@@ -86,6 +86,10 @@ static const struct hw_sequencer_funcs dcn201_funcs = {
        .set_backlight_level = dce110_set_backlight_level,
        .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
        .set_pipe = dce110_set_pipe,
+       .enable_lvds_link_output = dce110_enable_lvds_link_output,
+       .enable_tmds_link_output = dce110_enable_tmds_link_output,
+       .enable_dp_link_output = dce110_enable_dp_link_output,
+       .disable_link_output = dce110_disable_link_output,
        .set_disp_pattern_generator = dcn20_set_disp_pattern_generator,
        .update_visual_confirm_color = dcn20_update_visual_confirm_color,
 };
index b270f0b194dcb69905f587c7365fd846f5b90dcd..fe1a8e2e08ef1bf689ce33c3f99a810c68802a02 100644 (file)
@@ -99,6 +99,10 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
 #ifndef TRIM_FSFT
        .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft,
 #endif
+       .enable_lvds_link_output = dce110_enable_lvds_link_output,
+       .enable_tmds_link_output = dce110_enable_tmds_link_output,
+       .enable_dp_link_output = dce110_enable_dp_link_output,
+       .disable_link_output = dce110_disable_link_output,
        .is_abm_supported = dcn21_is_abm_supported,
        .set_disp_pattern_generator = dcn20_set_disp_pattern_generator,
        .get_dcc_en_bits = dcn10_get_dcc_en_bits,
index 4c06e6e1ba4a6f654e79c1e74d1ade4e52ce4b93..3216d10c58ba71d31bfd992e7f28e30769a5194b 100644 (file)
@@ -100,6 +100,10 @@ static const struct hw_sequencer_funcs dcn30_funcs = {
        .set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
        .hardware_release = dcn30_hardware_release,
        .set_pipe = dcn21_set_pipe,
+       .enable_lvds_link_output = dce110_enable_lvds_link_output,
+       .enable_tmds_link_output = dce110_enable_tmds_link_output,
+       .enable_dp_link_output = dce110_enable_dp_link_output,
+       .disable_link_output = dce110_disable_link_output,
        .set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
        .get_dcc_en_bits = dcn10_get_dcc_en_bits,
        .update_visual_confirm_color = dcn20_update_visual_confirm_color,
index 3d42a1a337ec1189fac5488380cf2022556c729a..6192851c59ed8950653ba4668177417eb2cf1a3d 100644 (file)
@@ -99,6 +99,10 @@ static const struct hw_sequencer_funcs dcn301_funcs = {
        .set_backlight_level = dcn21_set_backlight_level,
        .set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
        .set_pipe = dcn21_set_pipe,
+       .enable_lvds_link_output = dce110_enable_lvds_link_output,
+       .enable_tmds_link_output = dce110_enable_tmds_link_output,
+       .enable_dp_link_output = dce110_enable_dp_link_output,
+       .disable_link_output = dce110_disable_link_output,
        .set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
        .get_dcc_en_bits = dcn10_get_dcc_en_bits,
        .optimize_pwr_state = dcn21_optimize_pwr_state,
index 8d83b611507afa348d9c03a2629ea495d03c1f88..bdf101547484a1d543a33f8a7b1af8395657b439 100644 (file)
@@ -535,11 +535,11 @@ static void dcn31_reset_back_end_for_pipe(
                        pipe_ctx->stream_res.tg,
                        OPTC_DSC_DISABLED, 0, 0);
        pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
-
        pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);
        if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass)
                pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
                                pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
+       pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0;
 
        if (pipe_ctx->stream_res.tg->funcs->set_drr)
                pipe_ctx->stream_res.tg->funcs->set_drr(
@@ -553,12 +553,9 @@ static void dcn31_reset_back_end_for_pipe(
                 * screen only, the dpms_off would be true but
                 * VBIOS lit up eDP, so check link status too.
                 */
-               if (!pipe_ctx->stream->dpms_off || link->link_status.link_active) {
-                       if (dc->hwss.update_phy_state)
-                               dc->hwss.update_phy_state(dc->current_state, pipe_ctx, TX_OFF_SYMCLK_OFF);
-                       else
-                               core_link_disable_stream(pipe_ctx);
-               } else if (pipe_ctx->stream_res.audio)
+               if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)
+                       core_link_disable_stream(pipe_ctx);
+               else if (pipe_ctx->stream_res.audio)
                        dc->hwss.disable_audio_stream(pipe_ctx);
 
                /* free acquired resources */
index e708f07fe75af1b40d45c66a841a194f017fad4d..3a32810bbe382d45a01fdfc0ab80d367c8aee14c 100644 (file)
@@ -100,6 +100,10 @@ static const struct hw_sequencer_funcs dcn31_funcs = {
        .set_backlight_level = dcn21_set_backlight_level,
        .set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
        .set_pipe = dcn21_set_pipe,
+       .enable_lvds_link_output = dce110_enable_lvds_link_output,
+       .enable_tmds_link_output = dce110_enable_tmds_link_output,
+       .enable_dp_link_output = dce110_enable_dp_link_output,
+       .disable_link_output = dce110_disable_link_output,
        .z10_restore = dcn31_z10_restore,
        .z10_save_init = dcn31_z10_save_init,
        .set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
index 72a563a4c3e811252ec668c76dca32a961866c96..5b6c2d94ec71d90e28c5efa4889190bf5f9a458a 100644 (file)
@@ -102,6 +102,10 @@ static const struct hw_sequencer_funcs dcn314_funcs = {
        .set_backlight_level = dcn21_set_backlight_level,
        .set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
        .set_pipe = dcn21_set_pipe,
+       .enable_lvds_link_output = dce110_enable_lvds_link_output,
+       .enable_tmds_link_output = dce110_enable_tmds_link_output,
+       .enable_dp_link_output = dce110_enable_dp_link_output,
+       .disable_link_output = dce110_disable_link_output,
        .z10_restore = dcn31_z10_restore,
        .z10_save_init = dcn31_z10_save_init,
        .set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
index 449459ca5a72190bb3ae1373065983e20dbf4576..c6d2a05ded3dc81e18e3c6d0c6e655f8bb03d433 100644 (file)
@@ -883,6 +883,7 @@ void dcn32_init_hw(struct dc *dc)
                if (link->link_enc->funcs->is_dig_enabled &&
                        link->link_enc->funcs->is_dig_enabled(link->link_enc)) {
                        link->link_status.link_active = true;
+                       link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
                        if (link->link_enc->funcs->fec_is_active &&
                                        link->link_enc->funcs->fec_is_active(link->link_enc))
                                link->fec_state = dc_link_fec_enabled;
@@ -1275,31 +1276,69 @@ bool dcn32_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx)
        return false;
 }
 
-void dcn32_update_phy_state(struct dc_state *state, struct pipe_ctx *pipe_ctx,
-               enum phy_state target_state)
+static void apply_symclk_on_tx_off_wa(struct dc_link *link)
 {
-       enum phy_state current_state = pipe_ctx->stream->link->phy_state;
-
-       if (target_state == TX_OFF_SYMCLK_OFF) {
-               core_link_disable_stream(pipe_ctx);
-               pipe_ctx->stream->link->phy_state = TX_OFF_SYMCLK_OFF;
-       } else if (target_state == TX_ON_SYMCLK_ON) {
-               core_link_enable_stream(state, pipe_ctx);
-               pipe_ctx->stream->link->phy_state = TX_ON_SYMCLK_ON;
-       } else if (target_state == TX_OFF_SYMCLK_ON) {
-               if (current_state == TX_ON_SYMCLK_ON) {
-                       core_link_disable_stream(pipe_ctx);
-                       pipe_ctx->stream->link->phy_state = TX_OFF_SYMCLK_OFF;
+       /* There are use cases where SYMCLK is referenced by OTG. For instance
+        * for TMDS signal, OTG relies SYMCLK even if TX video output is off.
+        * However current link interface will power off PHY when disabling link
+        * output. This will turn off SYMCLK generated by PHY. The workaround is
+        * to identify such case where SYMCLK is still in use by OTG when we
+        * power off PHY. When this is detected, we will temporarily power PHY
+        * back on and move PHY's SYMCLK state to SYMCLK_ON_TX_OFF by calling
+        * program_pix_clk interface. When OTG is disabled, we will then power
+        * off PHY by calling disable link output again.
+        *
+        * In future dcn generations, we plan to rework transmitter control
+        * interface so that we could have an option to set SYMCLK ON TX OFF
+        * state in one step without this workaround
+        */
+
+       struct dc *dc = link->ctx->dc;
+       struct pipe_ctx *pipe_ctx = NULL;
+       uint8_t i;
+
+       if (link->phy_state.symclk_ref_cnts.otg > 0) {
+               for (i = 0; i < MAX_PIPES; i++) {
+                       pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+                       if (pipe_ctx->stream->link == link && pipe_ctx->top_pipe == NULL) {
+                               pipe_ctx->clock_source->funcs->program_pix_clk(
+                                               pipe_ctx->clock_source,
+                                               &pipe_ctx->stream_res.pix_clk_params,
+                                               dp_get_link_encoding_format(&pipe_ctx->link_config.dp_link_settings),
+                                               &pipe_ctx->pll_settings);
+                               link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
+                               break;
+                       }
                }
+       }
+}
 
-               pipe_ctx->clock_source->funcs->program_pix_clk(
-                       pipe_ctx->clock_source,
-                       &pipe_ctx->stream_res.pix_clk_params,
-                       dp_get_link_encoding_format(&pipe_ctx->link_config.dp_link_settings),
-                       &pipe_ctx->pll_settings);
-               pipe_ctx->stream->link->phy_state = TX_OFF_SYMCLK_ON;
-       } else
-               BREAK_TO_DEBUGGER();
+void dcn32_disable_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal)
+{
+       struct dc *dc = link->ctx->dc;
+       const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
+       struct dmcu *dmcu = dc->res_pool->dmcu;
+
+       if (signal == SIGNAL_TYPE_EDP &&
+                       link->dc->hwss.edp_backlight_control)
+               link->dc->hwss.edp_backlight_control(link, false);
+       else if (dmcu != NULL && dmcu->funcs->lock_phy)
+               dmcu->funcs->lock_phy(dmcu);
+
+       link_hwss->disable_link_output(link, link_res, signal);
+       link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
+
+       if (signal == SIGNAL_TYPE_EDP &&
+                       link->dc->hwss.edp_backlight_control)
+               link->dc->hwss.edp_power_control(link, false);
+       else if (dmcu != NULL && dmcu->funcs->lock_phy)
+               dmcu->funcs->unlock_phy(dmcu);
+
+       dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
+
+       apply_symclk_on_tx_off_wa(link);
 }
 
 /* For SubVP the main pipe can have a viewport position change
index 150d541f35b498c382c90ef445e044616d2558e2..86c018b2f132c806c768e99264e58df404627e30 100644 (file)
@@ -84,8 +84,9 @@ void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx,
 
 bool dcn32_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx);
 
-void dcn32_update_phy_state(struct dc_state *state, struct pipe_ctx *pipe_ctx,
-               enum phy_state target_state);
+void dcn32_disable_link_output(struct dc_link *link,
+               const struct link_resource *link_res,
+               enum signal_type signal);
 
 void dcn32_update_phantom_vp_position(struct dc *dc,
                struct dc_state *context,
index c554929471affe4c4e0802c54152e2d378541c18..c66dfe14909a430ac434531a7b2ed7da2a516ae6 100644 (file)
@@ -99,12 +99,15 @@ static const struct hw_sequencer_funcs dcn32_funcs = {
        .set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
        .hardware_release = dcn30_hardware_release,
        .set_pipe = dcn21_set_pipe,
+       .enable_lvds_link_output = dce110_enable_lvds_link_output,
+       .enable_tmds_link_output = dce110_enable_tmds_link_output,
+       .enable_dp_link_output = dce110_enable_dp_link_output,
+       .disable_link_output = dcn32_disable_link_output,
        .set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
        .get_dcc_en_bits = dcn10_get_dcc_en_bits,
        .commit_subvp_config = dcn32_commit_subvp_config,
        .subvp_pipe_control_lock = dcn32_subvp_pipe_control_lock,
        .update_visual_confirm_color = dcn20_update_visual_confirm_color,
-       .update_phy_state = dcn32_update_phy_state,
        .update_phantom_vp_position = dcn32_update_phantom_vp_position,
 };
 
index 437b64e8737732f11ec17d5dbe768d3aedc33328..cd2be729846b4684beab93c3e7aeca0db0cc2495 100644 (file)
@@ -268,10 +268,18 @@ enum dc_lut_mode {
        LUT_RAM_B
 };
 
-enum phy_state {
-       TX_OFF_SYMCLK_OFF,
-       TX_ON_SYMCLK_ON,
-       TX_OFF_SYMCLK_ON
+enum symclk_state {
+       SYMCLK_OFF_TX_OFF,
+       SYMCLK_ON_TX_ON,
+       SYMCLK_ON_TX_OFF,
+};
+
+struct phy_state {
+       struct {
+               uint8_t otg             : 1;
+               uint8_t reserved        : 7;
+       } symclk_ref_cnts;
+       enum symclk_state symclk_state;
 };
 
 /**
index d7a7b2790143f537e7d7774984e8d4d221db38dd..416b700a8d5a11e9c3226c695f7d09f637353421 100644 (file)
@@ -48,6 +48,7 @@ struct dc_phy_addr_space_config;
 struct dc_virtual_addr_space_config;
 struct dpp;
 struct dce_hwseq;
+struct link_resource;
 
 struct hw_sequencer_funcs {
        void (*hardware_release)(struct dc *dc);
@@ -218,6 +219,25 @@ struct hw_sequencer_funcs {
 
        void (*set_pipe)(struct pipe_ctx *pipe_ctx);
 
+       void (*enable_dp_link_output)(struct dc_link *link,
+                       const struct link_resource *link_res,
+                       enum signal_type signal,
+                       enum clock_source_id clock_source,
+                       const struct dc_link_settings *link_settings);
+       void (*enable_tmds_link_output)(struct dc_link *link,
+                       const struct link_resource *link_res,
+                       enum signal_type signal,
+                       enum clock_source_id clock_source,
+                       enum dc_color_depth color_depth,
+                       uint32_t pixel_clock);
+       void (*enable_lvds_link_output)(struct dc_link *link,
+                       const struct link_resource *link_res,
+                       enum clock_source_id clock_source,
+                       uint32_t pixel_clock);
+       void (*disable_link_output)(struct dc_link *link,
+                       const struct link_resource *link_res,
+                       enum signal_type signal);
+
        void (*get_dcc_en_bits)(struct dc *dc, int *dcc_en_bits);
 
        /* Idle Optimization Related */
@@ -245,9 +265,6 @@ struct hw_sequencer_funcs {
                        struct tg_color *color,
                        int mpcc_id);
 
-       void (*update_phy_state)(struct dc_state *state, struct pipe_ctx *pipe_ctx, enum phy_state target_state);
-
-
        void (*update_phantom_vp_position)(struct dc *dc,
                        struct dc_state *context,
                        struct pipe_ctx *phantom_pipe);
index 3482a877b6af567477d0eca3d1596daaf73bd209..89964c980b8712107415f802614fa4312a764504 100644 (file)
@@ -55,9 +55,6 @@ struct link_hwss_ext {
                        enum signal_type signal,
                        enum clock_source_id clock_source,
                        const struct dc_link_settings *link_settings);
-       void (*disable_dp_link_output)(struct dc_link *link,
-                       const struct link_resource *link_res,
-                       enum signal_type signal);
        void (*set_dp_link_test_pattern)(struct dc_link *link,
                        const struct link_resource *link_res,
                        struct encoder_set_dp_phy_pattern_param *tp_params);
@@ -79,6 +76,9 @@ struct link_hwss {
        void (*setup_stream_encoder)(struct pipe_ctx *pipe_ctx);
        void (*reset_stream_encoder)(struct pipe_ctx *pipe_ctx);
        void (*setup_stream_attribute)(struct pipe_ctx *pipe_ctx);
+       void (*disable_link_output)(struct dc_link *link,
+                       const struct link_resource *link_res,
+                       enum signal_type signal);
 };
 #endif /* __DC_LINK_HWSS_H__ */
 
index 5e92019539c823268ed049a73e378e7048dace92..4227adbc646a893a8a9b09a723dab16a1560804f 100644 (file)
@@ -130,7 +130,7 @@ void enable_dio_dp_link_output(struct dc_link *link,
        dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
 }
 
-void disable_dio_dp_link_output(struct dc_link *link,
+void disable_dio_link_output(struct dc_link *link,
                const struct link_resource *link_res,
                enum signal_type signal)
 {
@@ -174,10 +174,10 @@ static const struct link_hwss dio_link_hwss = {
        .setup_stream_encoder = setup_dio_stream_encoder,
        .reset_stream_encoder = reset_dio_stream_encoder,
        .setup_stream_attribute = setup_dio_stream_attribute,
+       .disable_link_output = disable_dio_link_output,
        .ext = {
                .set_throttled_vcp_size = set_dio_throttled_vcp_size,
                .enable_dp_link_output = enable_dio_dp_link_output,
-               .disable_dp_link_output = disable_dio_dp_link_output,
                .set_dp_link_test_pattern = set_dio_dp_link_test_pattern,
                .set_dp_lane_settings = set_dio_dp_lane_settings,
                .update_stream_allocation_table = update_dio_stream_allocation_table,
index 08f22b32df48dca5d5c024b2e288937f0498a04e..126d37f847a157c0c84bca902245c346e14dc95f 100644 (file)
@@ -40,7 +40,7 @@ void enable_dio_dp_link_output(struct dc_link *link,
                enum signal_type signal,
                enum clock_source_id clock_source,
                const struct dc_link_settings *link_settings);
-void disable_dio_dp_link_output(struct dc_link *link,
+void disable_dio_link_output(struct dc_link *link,
                const struct link_resource *link_res,
                enum signal_type signal);
 void set_dio_dp_link_test_pattern(struct dc_link *link,
index 89d4e8159138cc6de760f0a52cecd8315e0a8b17..64f7ea6a9aa3241a8f5748ca2b10b7f85c33227f 100644 (file)
@@ -56,10 +56,10 @@ static const struct link_hwss dpia_link_hwss = {
        .setup_stream_encoder = setup_dio_stream_encoder,
        .reset_stream_encoder = reset_dio_stream_encoder,
        .setup_stream_attribute = setup_dio_stream_attribute,
+       .disable_link_output = disable_dio_link_output,
        .ext = {
                .set_throttled_vcp_size = set_dio_throttled_vcp_size,
                .enable_dp_link_output = enable_dio_dp_link_output,
-               .disable_dp_link_output = disable_dio_dp_link_output,
                .set_dp_link_test_pattern = set_dio_dp_link_test_pattern,
                .set_dp_lane_settings = set_dio_dp_lane_settings,
                .update_stream_allocation_table = update_dpia_stream_allocation_table,
index 226af06278ce41498dc511e843908afc8ea19a28..7d3147175ca2166e716b4d50222e1e444d4dca7a 100644 (file)
@@ -266,11 +266,11 @@ static const struct link_hwss hpo_dp_link_hwss = {
        .setup_stream_encoder = setup_hpo_dp_stream_encoder,
        .reset_stream_encoder = reset_hpo_dp_stream_encoder,
        .setup_stream_attribute = setup_hpo_dp_stream_attribute,
+       .disable_link_output = disable_hpo_dp_link_output,
        .ext = {
                .set_throttled_vcp_size = set_hpo_dp_throttled_vcp_size,
                .set_hblank_min_symbol_width = set_hpo_dp_hblank_min_symbol_width,
                .enable_dp_link_output = enable_hpo_dp_link_output,
-               .disable_dp_link_output = disable_hpo_dp_link_output,
                .set_dp_link_test_pattern  = set_hpo_dp_link_test_pattern,
                .set_dp_lane_settings = set_hpo_dp_lane_settings,
                .update_stream_allocation_table = update_hpo_dp_stream_allocation_table,
index 501173ce270ed7db4dbc9afa0a30ea2762633d11..9522fe0b36c986681e62f790d1a5994e84977987 100644 (file)
@@ -36,10 +36,18 @@ void virtual_setup_stream_attribute(struct pipe_ctx *pipe_ctx)
 void virtual_reset_stream_encoder(struct pipe_ctx *pipe_ctx)
 {
 }
+
+void virtual_disable_link_output(struct dc_link *link,
+       const struct link_resource *link_res,
+       enum signal_type signal)
+{
+}
+
 static const struct link_hwss virtual_link_hwss = {
        .setup_stream_encoder = virtual_setup_stream_encoder,
        .reset_stream_encoder = virtual_reset_stream_encoder,
        .setup_stream_attribute = virtual_setup_stream_attribute,
+       .disable_link_output = virtual_disable_link_output,
 };
 
 const struct link_hwss *get_virtual_link_hwss(void)