]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/amd/display: Fix garbage or black screen when resetting otg
authorZhongwei <Zhongwei.Zhang@amd.com>
Wed, 18 Sep 2024 06:43:49 +0000 (14:43 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 14 Dec 2024 19:03:44 +0000 (20:03 +0100)
[ Upstream commit ffa1e31f70d2e97c121709b44a8960f5d7becb10 ]

[Why]
For some EDP to MIPI panel, disabling OTG when link is alive like boot
case, the converter might output garbage or show no display because our
GPU is not sending required pixel data.
Alos Dig fifo underflow was found which might cause garbage, when
resetting otg for other types of EDP panels.

[How]
Skipping resetting OTG if the dig fifo is on. Make sure that the otg for
the pipe is the one that the dig fifo is selecting via the FE mask.

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Zhongwei <Zhongwei.Zhang@amd.com>
Signed-off-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/amd/display/dc/dio/dcn314/dcn314_dio_stream_encoder.c
drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c

index 5b343f745cf3333bf264d87ccdc31c91a777227c..ae81451a3a725ce1ce201c9b4f45b3bde3892971 100644 (file)
@@ -83,6 +83,15 @@ void enc314_disable_fifo(struct stream_encoder *enc)
        REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 0);
 }
 
+static bool enc314_is_fifo_enabled(struct stream_encoder *enc)
+{
+       struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+       uint32_t reset_val;
+
+       REG_GET(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, &reset_val);
+       return (reset_val != 0);
+}
+
 void enc314_dp_set_odm_combine(
        struct stream_encoder *enc,
        bool odm_combine)
@@ -468,6 +477,7 @@ static const struct stream_encoder_funcs dcn314_str_enc_funcs = {
 
        .enable_fifo = enc314_enable_fifo,
        .disable_fifo = enc314_disable_fifo,
+       .is_fifo_enabled = enc314_is_fifo_enabled,
        .set_input_mode = enc314_set_dig_input_mode,
 };
 
index a8e04a39a19e5d7e23d52c4c4ed5bfd19246cb64..efcc1a6b364c27c14b31fda81ab622f44647f60b 100644 (file)
@@ -355,6 +355,20 @@ void dcn314_calculate_pix_rate_divider(
        }
 }
 
+static bool dcn314_is_pipe_dig_fifo_on(struct pipe_ctx *pipe)
+{
+       return pipe && pipe->stream
+               // Check dig's otg instance.
+               && pipe->stream_res.stream_enc
+               && pipe->stream_res.stream_enc->funcs->dig_source_otg
+               && pipe->stream_res.tg->inst == pipe->stream_res.stream_enc->funcs->dig_source_otg(pipe->stream_res.stream_enc)
+               && pipe->stream->link && pipe->stream->link->link_enc
+               && pipe->stream->link->link_enc->funcs->is_dig_enabled
+               && pipe->stream->link->link_enc->funcs->is_dig_enabled(pipe->stream->link->link_enc)
+               && pipe->stream_res.stream_enc->funcs->is_fifo_enabled
+               && pipe->stream_res.stream_enc->funcs->is_fifo_enabled(pipe->stream_res.stream_enc);
+}
+
 void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context, unsigned int current_pipe_idx)
 {
        unsigned int i;
@@ -374,6 +388,8 @@ void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc
                if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal)) &&
                        !pipe->stream->apply_seamless_boot_optimization &&
                        !pipe->stream->apply_edp_fast_boot_optimization) {
+                       if (dcn314_is_pipe_dig_fifo_on(pipe))
+                               continue;
                        pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
                        reset_sync_context_for_pipe(dc, context, i);
                        otg_disabled[i] = true;