From: "Wang, Sung-huai" <[email protected]>

[Why]
dcn10_init_pipes unconditionally calls init_odm on all enabled TGs,
resetting ODM combine state even when it should be preserved.

[How]
Add is_odm_enabled callback to timing_generator_funcs and
guard init_odm to skip when ODM is already active.

Reviewed-by: Aric Cyr <[email protected]>
Signed-off-by: Danny Wang <[email protected]>
Signed-off-by: Chenyu Chen <[email protected]>
---
 .../gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c    |  4 +++-
 .../gpu/drm/amd/display/dc/inc/hw/timing_generator.h   |  1 +
 drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.c | 10 ++++++++++
 drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h |  1 +
 .../gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.c   |  1 +
 drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c |  1 +
 drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.c |  1 +
 7 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
index 270b6f2d4377..7fa329229ae0 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
@@ -1750,7 +1750,9 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state 
*context)
 
                if (tg->funcs->is_tg_enabled(tg)) {
                        if (tg->funcs->init_odm)
-                               tg->funcs->init_odm(tg);
+                               if (!tg->funcs->is_odm_enabled ||
+                                       !tg->funcs->is_odm_enabled(tg))
+                                               tg->funcs->init_odm(tg);
                }
 
                tg->funcs->tg_init(tg);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
index 2eaba65894ab..52d4d57358cd 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
@@ -512,6 +512,7 @@ struct timing_generator_funcs {
                        uint32_t vtotal_change_limit);
 
        void (*init_odm)(struct timing_generator *tg);
+       bool (*is_odm_enabled)(struct timing_generator *tg);
        void (*wait_drr_doublebuffer_pending_clear)(struct timing_generator 
*tg);
        void (*set_long_vtotal)(struct timing_generator *optc, const struct 
long_vtotal_params *params);
        void (*wait_odm_doublebuffer_pending_clear)(struct timing_generator 
*tg);
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.c 
b/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.c
index 3ace83e1b50f..ce9cd32b807a 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.c
@@ -221,6 +221,15 @@ void optc31_set_drr(
        }
 }
 
+bool optc3_is_odm_enabled(struct timing_generator *optc)
+{
+       struct optc *optc1 = DCN10TG_FROM_TG(optc);
+       uint32_t num_segments = 0;
+
+       REG_GET(OPTC_DATA_SOURCE_SELECT, OPTC_NUM_OF_INPUT_SEGMENT, 
&num_segments);
+       return num_segments > 0;
+}
+
 void optc3_init_odm(struct timing_generator *optc)
 {
        struct optc *optc1 = DCN10TG_FROM_TG(optc);
@@ -503,6 +512,7 @@ static const struct timing_generator_funcs dcn31_tg_funcs = 
{
                .setup_manual_trigger = optc2_setup_manual_trigger,
                .get_hw_timing = optc1_get_hw_timing,
                .init_odm = optc3_init_odm,
+               .is_odm_enabled = optc3_is_odm_enabled,
                .is_two_pixels_per_container = 
optc1_is_two_pixels_per_container,
                .read_otg_state = optc31_read_otg_state,
                .optc_read_reg_state = optc31_read_reg_state,
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h 
b/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h
index 119a954fe3e5..19d90c65a22b 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h
@@ -274,6 +274,7 @@ bool optc31_immediate_disable_crtc(struct timing_generator 
*optc);
 void optc31_set_drr(struct timing_generator *optc, const struct drr_params 
*params);
 
 void optc3_init_odm(struct timing_generator *optc);
+bool optc3_is_odm_enabled(struct timing_generator *optc);
 
 void optc31_read_otg_state(struct timing_generator *optc,
                struct dcn_otg_state *s);
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.c 
b/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.c
index 7250478a5092..f5faa49680ef 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.c
@@ -247,6 +247,7 @@ static const struct timing_generator_funcs dcn314_tg_funcs 
= {
                .setup_manual_trigger = optc2_setup_manual_trigger,
                .get_hw_timing = optc1_get_hw_timing,
                .init_odm = optc3_init_odm,
+               .is_odm_enabled = optc3_is_odm_enabled,
                .set_odm_bypass = optc314_set_odm_bypass,
                .set_odm_combine = optc314_set_odm_combine,
                .set_h_timing_div_manual_mode = 
optc314_set_h_timing_div_manual_mode,
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c 
b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c
index 897f857db448..406446e5eae5 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c
@@ -614,6 +614,7 @@ static const struct timing_generator_funcs dcn35_tg_funcs = 
{
                .setup_manual_trigger = optc2_setup_manual_trigger,
                .get_hw_timing = optc1_get_hw_timing,
                .init_odm = optc3_init_odm,
+               .is_odm_enabled = optc3_is_odm_enabled,
                .set_long_vtotal = optc35_set_long_vtotal,
                .is_two_pixels_per_container = 
optc1_is_two_pixels_per_container,
                .read_otg_state = optc31_read_otg_state,
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.c 
b/drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.c
index fd9c2b6b8b3c..1e4f2051d732 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.c
@@ -261,6 +261,7 @@ static struct timing_generator_funcs dcn42_tg_funcs = {
                .setup_manual_trigger = optc2_setup_manual_trigger,
                .get_hw_timing = optc1_get_hw_timing,
                .init_odm = optc3_init_odm,
+               .is_odm_enabled = optc3_is_odm_enabled,
                .set_long_vtotal = optc35_set_long_vtotal,
                .is_two_pixels_per_container = 
optc1_is_two_pixels_per_container,
                .get_optc_double_buffer_pending = 
optc3_get_optc_double_buffer_pending,
-- 
2.43.0

Reply via email to