drm/amd/display: Disable phantom OTG after enable for plane disable
authorjsg <jsg@openbsd.org>
Thu, 17 Aug 2023 04:09:00 +0000 (04:09 +0000)
committerjsg <jsg@openbsd.org>
Thu, 17 Aug 2023 04:09:00 +0000 (04:09 +0000)
From Alvin Lee
e61f0ad73668912feef345e35beeefcce5bbbd63 in linux-6.1.y/6.1.46
dc55b106ad477c67f969f3432d9070c6846fb557 in mainline linux

sys/dev/pci/drm/amd/display/dc/core/amdgpu_dc.c
sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_optc.c
sys/dev/pci/drm/amd/display/dc/inc/hw/timing_generator.h

index c9ed034..f16a9e4 100644 (file)
@@ -1079,6 +1079,7 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
        struct dc_state *dangling_context = dc_create_state(dc);
        struct dc_state *current_ctx;
        struct pipe_ctx *pipe;
+       struct timing_generator *tg;
 
        if (dangling_context == NULL)
                return;
@@ -1122,6 +1123,7 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
 
                if (should_disable && old_stream) {
                        pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+                       tg = pipe->stream_res.tg;
                        /* When disabling plane for a phantom pipe, we must turn on the
                         * phantom OTG so the disable programming gets the double buffer
                         * update. Otherwise the pipe will be left in a partially disabled
@@ -1129,7 +1131,8 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
                         * again for different use.
                         */
                        if (old_stream->mall_stream_config.type == SUBVP_PHANTOM) {
-                               pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
+                               if (tg->funcs->enable_crtc)
+                                       tg->funcs->enable_crtc(tg);
                        }
                        dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
                        disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
@@ -1146,6 +1149,15 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
                                dc->hwss.interdependent_update_lock(dc, dc->current_state, false);
                                dc->hwss.post_unlock_program_front_end(dc, dangling_context);
                        }
+                       /* We need to put the phantom OTG back into it's default (disabled) state or we
+                        * can get corruption when transition from one SubVP config to a different one.
+                        * The OTG is set to disable on falling edge of VUPDATE so the plane disable
+                        * will still get it's double buffer update.
+                        */
+                       if (old_stream->mall_stream_config.type == SUBVP_PHANTOM) {
+                               if (tg->funcs->disable_phantom_crtc)
+                                       tg->funcs->disable_phantom_crtc(tg);
+                       }
                }
        }
 
index fe941b1..a974f86 100644 (file)
@@ -167,6 +167,13 @@ static void optc32_phantom_crtc_post_enable(struct timing_generator *optc)
        REG_WAIT(OTG_CLOCK_CONTROL, OTG_BUSY, 0, 1, 100000);
 }
 
+static void optc32_disable_phantom_otg(struct timing_generator *optc)
+{
+       struct optc *optc1 = DCN10TG_FROM_TG(optc);
+
+       REG_UPDATE(OTG_CONTROL, OTG_MASTER_EN, 0);
+}
+
 static void optc32_set_odm_bypass(struct timing_generator *optc,
                const struct dc_crtc_timing *dc_crtc_timing)
 {
@@ -260,6 +267,7 @@ static struct timing_generator_funcs dcn32_tg_funcs = {
                .enable_crtc = optc32_enable_crtc,
                .disable_crtc = optc32_disable_crtc,
                .phantom_crtc_post_enable = optc32_phantom_crtc_post_enable,
+               .disable_phantom_crtc = optc32_disable_phantom_otg,
                /* used by enable_timing_synchronization. Not need for FPGA */
                .is_counter_moving = optc1_is_counter_moving,
                .get_position = optc1_get_position,
index 0606680..37a718f 100644 (file)
@@ -184,6 +184,7 @@ struct timing_generator_funcs {
        bool (*disable_crtc)(struct timing_generator *tg);
 #ifdef CONFIG_DRM_AMD_DC_DCN
        void (*phantom_crtc_post_enable)(struct timing_generator *tg);
+       void (*disable_phantom_crtc)(struct timing_generator *tg);
 #endif
        bool (*immediate_disable_crtc)(struct timing_generator *tg);
        bool (*is_counter_moving)(struct timing_generator *tg);