drm/amd/display: turn on symclk for dio virtual stream in dpms sequence
authorWenjing Liu <wenjing.liu@amd.com>
Fri, 10 May 2024 16:43:53 +0000 (12:43 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 5 Jun 2024 15:04:58 +0000 (11:04 -0400)
[why]
In order to support glitchless display clock ramping for virtual stream,
we must
turn on symclk for stream encoder. The code will power on phy and enable
symclk
for dio encoder during virtual stream dpms sequence.

Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Acked-by: Zaeem Mohamed <zaeem.mohamed@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>
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dcn401/dcn401_dio_stream_encoder.c
drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
drivers/gpu/drm/amd/display/dc/link/link_dpms.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c

index dc236264d9b33ce26bbaa69b25f16d5841f91dc2..234236c43d21ee3abb824ab434cb5743ffe800ca 100644 (file)
@@ -3648,8 +3648,10 @@ enum dc_status resource_map_pool_resources(
        /* Allocate DP HPO Stream Encoder based on signal, hw capabilities
         * and link settings
         */
-       if (dc_is_dp_signal(stream->signal)) {
-               if (!dc->link_srv->dp_decide_link_settings(stream, &pipe_ctx->link_config.dp_link_settings))
+       if (dc_is_dp_signal(stream->signal) ||
+                       dc_is_virtual_signal(stream->signal)) {
+               if (!dc->link_srv->dp_decide_link_settings(stream,
+                               &pipe_ctx->link_config.dp_link_settings))
                        return DC_FAIL_DP_LINK_BANDWIDTH;
                if (dc->link_srv->dp_get_encoding_format(
                                &pipe_ctx->link_config.dp_link_settings) == DP_128b_132b_ENCODING) {
index 2595cbef59423cd0a8f8a2fc31596da7badce4eb..1325db3a4ed051c5778c1ba7a6b5405ac45d5e7c 100644 (file)
@@ -254,6 +254,7 @@ static void enc35_stream_encoder_enable(
                        break;
                case SIGNAL_TYPE_EDP:
                case SIGNAL_TYPE_DISPLAY_PORT:
+               case SIGNAL_TYPE_VIRTUAL:
                        /* DP SST */
                        REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_MODE, 0);
                        break;
@@ -459,7 +460,7 @@ static const struct stream_encoder_funcs dcn35_str_enc_funcs = {
        .dp_set_dsc_pps_info_packet = enc3_dp_set_dsc_pps_info_packet,
        .set_dynamic_metadata = enc2_set_dynamic_metadata,
        .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute,
-       .dig_stream_enable = enc35_stream_encoder_enable,
+       .enable_stream = enc35_stream_encoder_enable,
 
        .set_input_mode = enc314_set_dig_input_mode,
        .enable_fifo = enc35_enable_fifo,
index 09028830560979805e1dec3781e6620c8ba7ee84..2ebfca4769aa9f130406073889764b81086f8ea5 100644 (file)
@@ -416,6 +416,7 @@ static void enc401_stream_encoder_enable(
                        break;
                case SIGNAL_TYPE_EDP:
                case SIGNAL_TYPE_DISPLAY_PORT:
+               case SIGNAL_TYPE_VIRTUAL:
                        /* DP SST */
                        REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_MODE, 0);
                        break;
@@ -760,7 +761,7 @@ static const struct stream_encoder_funcs dcn401_str_enc_funcs = {
        .dp_set_dsc_pps_info_packet = enc3_dp_set_dsc_pps_info_packet,
        .set_dynamic_metadata = enc401_set_dynamic_metadata,
        .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute,
-       .dig_stream_enable = enc401_stream_encoder_enable,
+       .enable_stream = enc401_stream_encoder_enable,
 
        .set_input_mode = enc401_set_dig_input_mode,
        .enable_fifo = enc32_enable_fifo,
index 60228f5de4d7626c3025ec48e90cf856111963b4..e5e11c84e9e2816cc243fa37eb7473facd613f23 100644 (file)
@@ -223,7 +223,7 @@ struct stream_encoder_funcs {
                struct stream_encoder *enc,
                int tg_inst);
 
-       void (*dig_stream_enable)(
+       void (*enable_stream)(
                struct stream_encoder *enc,
                enum signal_type signal,
                bool enable);
index afe4614e0087027952750131bd8faa74cc379b14..50459d7a0f85f0a2829b18ec6eb36487dceded8b 100644 (file)
@@ -46,6 +46,9 @@ void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
        if (dc_is_dp_signal(pipe_ctx->stream->signal))
                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_stream)
+               stream_enc->funcs->enable_stream(stream_enc,
+                               pipe_ctx->stream->signal, true);
        if (stream_enc->funcs->map_stream_to_link)
                stream_enc->funcs->map_stream_to_link(stream_enc,
                                stream_enc->stream_enc_inst, link_enc->transmitter - TRANSMITTER_UNIPHY_A);
@@ -65,7 +68,9 @@ void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
                stream_enc->funcs->disable_fifo(stream_enc);
        if (stream_enc->funcs->set_input_mode)
                stream_enc->funcs->set_input_mode(stream_enc, 0);
-
+       if (stream_enc->funcs->enable_stream)
+               stream_enc->funcs->enable_stream(stream_enc,
+                               pipe_ctx->stream->signal, false);
        link_enc->funcs->connect_dig_be_to_fe(
                        link_enc,
                        pipe_ctx->stream_res.stream_enc->id,
index 955c720fb565b6f0de39ae0890233df63c2f9cb1..a9ddbe12142f881535296ce51bf3622a0ab7ea0b 100644 (file)
@@ -1907,7 +1907,9 @@ static void disable_link(struct dc_link *link,
 {
        if (dc_is_dp_signal(signal)) {
                disable_link_dp(link, link_res, signal);
-       } else if (signal != SIGNAL_TYPE_VIRTUAL) {
+       } else if (signal == SIGNAL_TYPE_VIRTUAL) {
+               link->dc->hwss.disable_link_output(link, link_res, SIGNAL_TYPE_DISPLAY_PORT);
+       } else {
                link->dc->hwss.disable_link_output(link, link_res, signal);
        }
 
@@ -2154,6 +2156,18 @@ static enum dc_status enable_link_dp_mst(
        return enable_link_dp(state, pipe_ctx);
 }
 
+static enum dc_status enable_link_virtual(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_link *link = pipe_ctx->stream->link;
+
+       link->dc->hwss.enable_dp_link_output(link,
+                       &pipe_ctx->link_res,
+                       SIGNAL_TYPE_DISPLAY_PORT,
+                       pipe_ctx->clock_source->id,
+                       &pipe_ctx->link_config.dp_link_settings);
+       return DC_OK;
+}
+
 static enum dc_status enable_link(
                struct dc_state *state,
                struct pipe_ctx *pipe_ctx)
@@ -2193,7 +2207,7 @@ static enum dc_status enable_link(
                status = DC_OK;
                break;
        case SIGNAL_TYPE_VIRTUAL:
-               status = DC_OK;
+               status = enable_link_virtual(pipe_ctx);
                break;
        default:
                break;
@@ -2437,17 +2451,10 @@ void link_set_dpms_on(
 
        if (!dc_is_virtual_signal(pipe_ctx->stream->signal)
                        && !dp_is_128b_132b_signal(pipe_ctx)) {
-               struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
-
                if (link_enc)
                        link_enc->funcs->setup(
                                link_enc,
                                pipe_ctx->stream->signal);
-
-               if (stream_enc && stream_enc->funcs->dig_stream_enable)
-                       stream_enc->funcs->dig_stream_enable(
-                               stream_enc,
-                               pipe_ctx->stream->signal, 1);
        }
 
        pipe_ctx->stream->link->link_state_valid = true;
@@ -2547,18 +2554,12 @@ void link_set_dpms_on(
         */
        if (!(dc_is_virtual_signal(pipe_ctx->stream->signal) ||
                        dp_is_128b_132b_signal(pipe_ctx))) {
-                       struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
 
                        if (link_enc)
                                link_enc->funcs->setup(
                                        link_enc,
                                        pipe_ctx->stream->signal);
 
-                       if (stream_enc && stream_enc->funcs->dig_stream_enable)
-                               stream_enc->funcs->dig_stream_enable(
-                                       stream_enc,
-                                       pipe_ctx->stream->signal, 1);
-
                }
 
        dc->hwss.enable_stream(pipe_ctx);
index 766116ec627d1b28c24566cb68dced0be168ac53..964abccebdc64ddddd1033093ccec7a15fd05d33 100644 (file)
@@ -955,6 +955,9 @@ bool link_decide_link_settings(struct dc_stream_state *stream,
                } else {
                        edp_decide_link_settings(link, link_setting, req_bw);
                }
+       } else if (stream->signal == SIGNAL_TYPE_VIRTUAL) {
+               link_setting->lane_count = LANE_COUNT_FOUR;
+               link_setting->link_rate = LINK_RATE_HIGH3;
        } else {
                decide_dp_link_settings(link, link_setting, req_bw);
        }