drm/amd/display: Add enable/disable FIFO callbacks to stream setup
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Wed, 6 Jul 2022 20:26:40 +0000 (16:26 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 25 Jul 2022 21:14:50 +0000 (17:14 -0400)
[Why]
We don't write out attributes after disabling and re-enabling the link
on some monitors, causing some, but not all, HDMI displays to fail to
lightup on DCN314.

[How]
Firmware used to do this after DIG link setup.

Since firmware is no longer doing this to support USB4 and dynamic link
remapping we'll need to add this to driver in the equivalent paths.

New optional callbacks were created in the stream encoder interface and
implementations were added for DCN314.

Reviewed-by: Michael Strauss <Michael.Strauss@amd.com>
Acked-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@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/dcn314/dcn314_dio_stream_encoder.c
drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
drivers/gpu/drm/amd/display/dc/link/link_hwss_dio.c

index 2dbfa1c..b384f30 100644 (file)
        enc1->base.ctx
 
 
+static void enc314_enable_fifo(struct stream_encoder *enc)
+{
+       struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+
+       /* TODO: Confirm if we need to wait for DIG_SYMCLK_FE_ON */
+       REG_WAIT(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, 1, 10, 5000);
+       REG_UPDATE_2(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1, DIG_FIFO_READ_START_LEVEL, 0x7);
+       REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 1, 10, 5000);
+       REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 0);
+       REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 0, 10, 5000);
+       REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 1);
+}
+
+static void enc314_disable_fifo(struct stream_encoder *enc)
+{
+       struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+
+       REG_UPDATE_2(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 0,
+                    DIG_FIFO_READ_START_LEVEL, 0);
+}
 
 static void enc314_dp_set_odm_combine(
        struct stream_encoder *enc,
@@ -92,7 +112,7 @@ void enc314_stream_encoder_dvi_set_stream_attribute(
 
                //DIG_SOURCE_SELECT is already set in dig_connect_to_otg
 
-               /* DIG_START is removed from the register spec */
+               enc314_enable_fifo(enc);
        }
 
        ASSERT(crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB);
@@ -132,7 +152,7 @@ static void enc314_stream_encoder_hdmi_set_stream_attribute(
 
                //DIG_SOURCE_SELECT is already set in dig_connect_to_otg
 
-               /* DIG_START is removed from the register spec */
+               enc314_enable_fifo(enc);
        }
 
        /* Configure pixel encoding */
@@ -302,16 +322,8 @@ static void enc314_stream_encoder_dp_unblank(
 
        REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0);
 
-       /*
-        * DIG Resync FIFO now needs to be explicitly enabled.
-        * TODO: Confirm if we need to wait for DIG_SYMCLK_FE_ON
-        */
-       REG_WAIT(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, 1, 10, 5000);
-       REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1);
-       REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 1, 10, 5000);
-       REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 0);
-       REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 0, 10, 5000);
-       REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 1);
+       /* DIG Resync FIFO now needs to be explicitly enabled. */
+       enc314_enable_fifo(enc);
 
        /* wait 100us for DIG/DP logic to prime
         * (i.e. a few video lines)
@@ -420,6 +432,8 @@ static const struct stream_encoder_funcs dcn314_str_enc_funcs = {
        .set_dynamic_metadata = enc2_set_dynamic_metadata,
        .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute,
 
+       .enable_fifo = enc314_enable_fifo,
+       .disable_fifo = enc314_disable_fifo,
        .set_input_mode = enc314_set_dig_input_mode,
 };
 
index 456dbe9..42afa19 100644 (file)
@@ -252,6 +252,8 @@ struct stream_encoder_funcs {
 
        void (*set_input_mode)(
                struct stream_encoder *enc, unsigned int pix_per_container);
+       void (*enable_fifo)(struct stream_encoder *enc);
+       void (*disable_fifo)(struct stream_encoder *enc);
 };
 
 struct hpo_dp_stream_encoder_state {
index 776e822..5e92019 100644 (file)
@@ -40,17 +40,24 @@ void set_dio_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
 void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
 {
        struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
+       struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
 
        link_enc->funcs->connect_dig_be_to_fe(link_enc,
                        pipe_ctx->stream_res.stream_enc->id, true);
        if (dc_is_dp_signal(pipe_ctx->stream->signal))
                dp_source_sequence_trace(pipe_ctx->stream->link,
                                DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
+       if (stream_enc->funcs->enable_fifo)
+               stream_enc->funcs->enable_fifo(stream_enc);
 }
 
 void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
 {
        struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
+       struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
+
+       if (stream_enc && stream_enc->funcs->disable_fifo)
+               stream_enc->funcs->disable_fifo(stream_enc);
 
        link_enc->funcs->connect_dig_be_to_fe(
                        link_enc,