From: jsg Date: Thu, 17 Aug 2023 04:09:00 +0000 (+0000) Subject: drm/amd/display: Disable phantom OTG after enable for plane disable X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=6da81288a1da034c63076833027aa40b5959fdc4;p=openbsd drm/amd/display: Disable phantom OTG after enable for plane disable From Alvin Lee e61f0ad73668912feef345e35beeefcce5bbbd63 in linux-6.1.y/6.1.46 dc55b106ad477c67f969f3432d9070c6846fb557 in mainline linux --- diff --git a/sys/dev/pci/drm/amd/display/dc/core/amdgpu_dc.c b/sys/dev/pci/drm/amd/display/dc/core/amdgpu_dc.c index c9ed0346b88..f16a9e410d1 100644 --- a/sys/dev/pci/drm/amd/display/dc/core/amdgpu_dc.c +++ b/sys/dev/pci/drm/amd/display/dc/core/amdgpu_dc.c @@ -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); + } } } diff --git a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_optc.c b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_optc.c index fe941b103de..a974f86e718 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_optc.c +++ b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_optc.c @@ -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, diff --git a/sys/dev/pci/drm/amd/display/dc/inc/hw/timing_generator.h b/sys/dev/pci/drm/amd/display/dc/inc/hw/timing_generator.h index 06066809867..37a718fc551 100644 --- a/sys/dev/pci/drm/amd/display/dc/inc/hw/timing_generator.h +++ b/sys/dev/pci/drm/amd/display/dc/inc/hw/timing_generator.h @@ -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);