]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
drm/amd/display: Wait for all pending cleared before full update
authorAlvin Lee <Alvin.Lee2@amd.com>
Thu, 8 Aug 2024 14:19:54 +0000 (10:19 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 27 Aug 2024 21:52:01 +0000 (17:52 -0400)
[Description]
Before every full update we must wait for all pending updates to be
cleared - this is particularly important for minimal transitions
because if we don't wait for pending cleared, it will be as if
there was no minimal transition at all. In OTG we must read 3 different
status registers for pending cleared, one specifically for OTG updates,
one specifically for OPTC updates, and the last for surface related
updates

Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Alvin Lee <Alvin.Lee2@amd.com>
Signed-off-by: Zaeem Mohamed <zaeem.mohamed@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
24 files changed:
drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.h
drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c
drivers/gpu/drm/amd/display/dc/hwss/dcn301/dcn301_init.c
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
drivers/gpu/drm/amd/display/dc/optc/dcn20/dcn20_optc.h
drivers/gpu/drm/amd/display/dc/optc/dcn30/dcn30_optc.c
drivers/gpu/drm/amd/display/dc/optc/dcn30/dcn30_optc.h
drivers/gpu/drm/amd/display/dc/optc/dcn301/dcn301_optc.c
drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h
drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.h
drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c
drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h
drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h
drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.c
drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.h
drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h

index 7ee2be8f82c467ffb3b25e39ee4c7c8daa730cde..2cb9253c9bdecbf5a0c9a638d066227dfe45e59e 100644 (file)
@@ -1071,8 +1071,13 @@ void hwss_wait_for_outstanding_hw_updates(struct dc *dc, struct dc_state *dc_con
                if (!pipe_ctx->stream)
                        continue;
 
-               if (pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear)
-                       pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear(pipe_ctx->stream_res.tg);
+               /* For full update we must wait for all double buffer updates, not just DRR updates. This
+                * is particularly important for minimal transitions. Only check for OTG_MASTER pipes,
+                * as non-OTG Master pipes share the same OTG as
+                */
+               if (resource_is_pipe_type(pipe_ctx, OTG_MASTER) && dc->hwss.wait_for_all_pending_updates) {
+                       dc->hwss.wait_for_all_pending_updates(pipe_ctx);
+               }
 
                hubp = pipe_ctx->plane_res.hubp;
                if (!hubp)
index a80c08582932076333a5ff087f2096e646f612a4..b383ed8cb4d49517baf2e3ae44d3a0772d635751 100644 (file)
@@ -2255,9 +2255,9 @@ void dcn20_post_unlock_program_front_end(
                        struct timing_generator *tg = pipe->stream_res.tg;
 
 
-                       if (tg->funcs->get_double_buffer_pending) {
+                       if (tg->funcs->get_optc_double_buffer_pending) {
                                for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_US / polling_interval_us
-                               && tg->funcs->get_double_buffer_pending(tg); j++)
+                               && tg->funcs->get_optc_double_buffer_pending(tg); j++)
                                        udelay(polling_interval_us);
                        }
                }
index 42c52284a868090d3ee2f912d9ab5db3f525a6ac..d5458dae6d305b9b48139a868ab1c618db188118 100644 (file)
@@ -1185,3 +1185,30 @@ void dcn30_prepare_bandwidth(struct dc *dc,
        if (!dc->clk_mgr->clks.fw_based_mclk_switching)
                dc_dmub_srv_p_state_delegate(dc, false, context);
 }
+
+void dcn30_wait_for_all_pending_updates(const struct pipe_ctx *pipe_ctx)
+{
+       struct timing_generator *tg = pipe_ctx->stream_res.tg;
+       bool pending_updates = false;
+       unsigned int i;
+
+       if (tg && tg->funcs->is_tg_enabled(tg)) {
+               // Poll for 100ms maximum
+               for (i = 0; i < 100000; i++) {
+                       pending_updates = false;
+                       if (tg->funcs->get_optc_double_buffer_pending)
+                               pending_updates |= tg->funcs->get_optc_double_buffer_pending(tg);
+
+                       if (tg->funcs->get_otg_double_buffer_pending)
+                               pending_updates |= tg->funcs->get_otg_double_buffer_pending(tg);
+
+                       if (tg->funcs->get_pipe_update_pending)
+                               pending_updates |= tg->funcs->get_pipe_update_pending(tg);
+
+                       if (!pending_updates)
+                               break;
+
+                       udelay(1);
+               }
+       }
+}
index 6a153e7ce910efb6384858348c66d9412dabab83..4b90b781c4f2d9fe3483c6d321da68acefbc288f 100644 (file)
@@ -96,4 +96,6 @@ void dcn30_set_hubp_blank(const struct dc *dc,
 void dcn30_prepare_bandwidth(struct dc *dc,
        struct dc_state *context);
 
+void dcn30_wait_for_all_pending_updates(const struct pipe_ctx *pipe_ctx);
+
 #endif /* __DC_HWSS_DCN30_H__ */
index 2a8dc40d28477b5b4c53b077912c6a7f50c2da17..0e8d32e3dbae1db1c9313fb4acd622b0903cc6b2 100644 (file)
@@ -108,7 +108,8 @@ static const struct hw_sequencer_funcs dcn30_funcs = {
        .set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
        .get_dcc_en_bits = dcn10_get_dcc_en_bits,
        .update_visual_confirm_color = dcn10_update_visual_confirm_color,
-       .is_abm_supported = dcn21_is_abm_supported
+       .is_abm_supported = dcn21_is_abm_supported,
+       .wait_for_all_pending_updates = dcn30_wait_for_all_pending_updates,
 };
 
 static const struct hwseq_private_funcs dcn30_private_funcs = {
index 93e49d87a67ce0ce5842b7a0a0fc90da23f982a0..780ce4c064aa5826dcebeab95143127565408722 100644 (file)
@@ -107,6 +107,7 @@ static const struct hw_sequencer_funcs dcn301_funcs = {
        .optimize_pwr_state = dcn21_optimize_pwr_state,
        .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
        .update_visual_confirm_color = dcn10_update_visual_confirm_color,
+       .wait_for_all_pending_updates = dcn30_wait_for_all_pending_updates,
 };
 
 static const struct hwseq_private_funcs dcn301_private_funcs = {
index 3422b564ae9847e2e2f76de691af22471b47879a..8e0946fd5b7feb61fb0be98733e1e9aca2a20b61 100644 (file)
@@ -121,6 +121,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = {
        .is_pipe_topology_transition_seamless = dcn32_is_pipe_topology_transition_seamless,
        .calculate_pix_rate_divider = dcn32_calculate_pix_rate_divider,
        .program_outstanding_updates = dcn32_program_outstanding_updates,
+       .wait_for_all_pending_updates = dcn30_wait_for_all_pending_updates,
 };
 
 static const struct hwseq_private_funcs dcn32_private_funcs = {
index a2ca07235c83d9d58f647900b5d2c94e563a77df..73a632b5ff89328d7f922114f85a4a610c5e42d4 100644 (file)
@@ -100,6 +100,7 @@ static const struct hw_sequencer_funcs dcn401_funcs = {
        .fams2_update_config = dcn401_fams2_update_config,
        .fams2_global_control_lock_fast = dcn401_fams2_global_control_lock_fast,
        .program_outstanding_updates = dcn401_program_outstanding_updates,
+       .wait_for_all_pending_updates = dcn30_wait_for_all_pending_updates,
 };
 
 static const struct hwseq_private_funcs dcn401_private_funcs = {
index ac920562562336c579ff552aa04ab2b2be4de8d9..b8c47e4c51c153c73968e822662fb6536dca1679 100644 (file)
@@ -462,6 +462,7 @@ struct hw_sequencer_funcs {
        void (*program_outstanding_updates)(struct dc *dc,
                        struct dc_state *context);
        void (*setup_hpo_hw_control)(const struct dce_hwseq *hws, bool enable);
+       void (*wait_for_all_pending_updates)(const struct pipe_ctx *pipe_ctx);
 };
 
 void color_space_to_black_color(
index 3d4c8bd42b4920dff974d2b4bf85b319bdbbc03c..4e08e80eafe8e57520076d6db12b5cce06a14c8e 100644 (file)
@@ -342,7 +342,9 @@ struct timing_generator_funcs {
        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);
-       bool (*get_double_buffer_pending)(struct timing_generator *tg);
+       bool (*get_optc_double_buffer_pending)(struct timing_generator *tg);
+       bool (*get_otg_double_buffer_pending)(struct timing_generator *tg);
+       bool (*get_pipe_update_pending)(struct timing_generator *tg);
 };
 
 #endif
index b7a57f98553d78171113664cb1ad39278014d629..40757f20d73f41f3aea9e0864a588465516b694d 100644 (file)
@@ -202,6 +202,7 @@ struct dcn_optc_registers {
        uint32_t OPTC_CLOCK_CONTROL;
        uint32_t OPTC_WIDTH_CONTROL2;
        uint32_t OTG_PSTATE_REGISTER;
+       uint32_t OTG_PIPE_UPDATE_STATUS;
 };
 
 #define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\
@@ -566,6 +567,12 @@ struct dcn_optc_registers {
        type OTG_H_TIMING_DIV_MODE_DB_UPDATE_PENDING;\
        type OPTC_DOUBLE_BUFFER_PENDING;\
 
+#define TG_REG_FIELD_LIST_DCN2_0(type) \
+       type OTG_FLIP_PENDING;\
+       type OTG_DC_REG_UPDATE_PENDING;\
+       type OTG_CURSOR_UPDATE_PENDING;\
+       type OTG_VUPDATE_KEEPOUT_STATUS;\
+
 #define TG_REG_FIELD_LIST_DCN3_2(type) \
        type OTG_H_TIMING_DIV_MODE_MANUAL;
 
@@ -600,6 +607,7 @@ struct dcn_optc_registers {
 
 struct dcn_optc_shift {
        TG_REG_FIELD_LIST(uint8_t)
+       TG_REG_FIELD_LIST_DCN2_0(uint8_t)
        TG_REG_FIELD_LIST_DCN3_2(uint8_t)
        TG_REG_FIELD_LIST_DCN3_5(uint8_t)
        TG_REG_FIELD_LIST_DCN401(uint8_t)
@@ -607,6 +615,7 @@ struct dcn_optc_shift {
 
 struct dcn_optc_mask {
        TG_REG_FIELD_LIST(uint32_t)
+       TG_REG_FIELD_LIST_DCN2_0(uint32_t)
        TG_REG_FIELD_LIST_DCN3_2(uint32_t)
        TG_REG_FIELD_LIST_DCN3_5(uint32_t)
        TG_REG_FIELD_LIST_DCN401(uint32_t)
index 364034b190281bad90c706bfac71cc11bb2bb8b3..928e110b95fb5c292f6fc809582b18ea70fe7719 100644 (file)
@@ -43,7 +43,8 @@
        SRI(OPTC_MEMORY_CONFIG, ODM, inst),\
        SR(DWB_SOURCE_SELECT),\
        SRI(OTG_MANUAL_FLOW_CONTROL, OTG, inst), \
-       SRI(OTG_DRR_CONTROL, OTG, inst)
+       SRI(OTG_DRR_CONTROL, OTG, inst),\
+       SRI(OTG_PIPE_UPDATE_STATUS, OTG, inst)
 
 #define TG_COMMON_MASK_SH_LIST_DCN2_0(mask_sh)\
        TG_COMMON_MASK_SH_LIST_DCN(mask_sh),\
        SF(OTG0_OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, mask_sh),\
        SF(OTG0_OTG_GLOBAL_CONTROL2, DIG_UPDATE_LOCATION, mask_sh),\
        SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_RANGE_TIMING_DBUF_UPDATE_MODE, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_FLIP_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_DC_REG_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_CURSOR_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh),\
        SF(OTG0_OTG_GSL_WINDOW_X, OTG_GSL_WINDOW_START_X, mask_sh),\
        SF(OTG0_OTG_GSL_WINDOW_X, OTG_GSL_WINDOW_END_X, mask_sh), \
        SF(OTG0_OTG_GSL_WINDOW_Y, OTG_GSL_WINDOW_START_Y, mask_sh),\
index abcd03d7866843b9eaae5de71eb0bea6f2428975..4c95c095861229de8c4d227abbed488b755af510 100644 (file)
@@ -271,6 +271,48 @@ void optc3_set_odm_combine(struct timing_generator *optc, int *opp_id, int opp_c
        optc1->opp_count = opp_cnt;
 }
 
+/* OTG status register that indicates OPTC update is pending */
+bool optc3_get_optc_double_buffer_pending(struct timing_generator *optc)
+{
+       struct optc *optc1 = DCN10TG_FROM_TG(optc);
+       uint32_t update_pending = 0;
+
+       REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
+                       OPTC_DOUBLE_BUFFER_PENDING,
+                       &update_pending);
+
+       return (update_pending == 1);
+}
+
+/* OTG status register that indicates OTG update is pending */
+bool optc3_get_otg_update_pending(struct timing_generator *optc)
+{
+       struct optc *optc1 = DCN10TG_FROM_TG(optc);
+       uint32_t update_pending = 0;
+
+       REG_GET(OTG_DOUBLE_BUFFER_CONTROL,
+                       OTG_UPDATE_PENDING,
+                       &update_pending);
+
+       return (update_pending == 1);
+}
+
+/* OTG status register that indicates surface update is pending */
+bool optc3_get_pipe_update_pending(struct timing_generator *optc)
+{
+       struct optc *optc1 = DCN10TG_FROM_TG(optc);
+       uint32_t flip_pending = 0;
+       uint32_t dc_update_pending = 0;
+
+       REG_GET_2(OTG_PIPE_UPDATE_STATUS,
+                       OTG_FLIP_PENDING,
+                       &flip_pending,
+                       OTG_DC_REG_UPDATE_PENDING,
+                       &dc_update_pending);
+
+       return (flip_pending == 1 || dc_update_pending == 1);
+}
+
 /**
  * optc3_set_timing_double_buffer() - DRR double buffering control
  *
@@ -375,6 +417,9 @@ static struct timing_generator_funcs dcn30_tg_funcs = {
                .get_hw_timing = optc1_get_hw_timing,
                .wait_drr_doublebuffer_pending_clear = optc3_wait_drr_doublebuffer_pending_clear,
                .is_two_pixels_per_container = optc1_is_two_pixels_per_container,
+               .get_optc_double_buffer_pending = optc3_get_optc_double_buffer_pending,
+               .get_otg_double_buffer_pending = optc3_get_otg_update_pending,
+               .get_pipe_update_pending = optc3_get_pipe_update_pending,
 };
 
 void dcn30_timing_generator_init(struct optc *optc1)
index bda974d432ea6af56f27a6e4d71742137a7a5080..e2303f9eaf13b699c8a6d2c83e37ef05994136a6 100644 (file)
        SRI(OPTC_BYTES_PER_PIXEL, ODM, inst),\
        SRI(OPTC_WIDTH_CONTROL, ODM, inst),\
        SRI(OPTC_MEMORY_CONFIG, ODM, inst),\
-       SR(DWB_SOURCE_SELECT)
+       SR(DWB_SOURCE_SELECT),\
+       SRI(OTG_PIPE_UPDATE_STATUS, OTG, inst)
 
 #define DCN30_VTOTAL_REGS_SF(mask_sh)
 
        SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_GATE_DIS, mask_sh),\
        SF(ODM0_OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_OCCURRED_STATUS, mask_sh),\
        SF(ODM0_OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, mask_sh),\
+       SF(ODM0_OPTC_INPUT_GLOBAL_CONTROL, OPTC_DOUBLE_BUFFER_PENDING, mask_sh),\
        SF(VTG0_CONTROL, VTG0_ENABLE, mask_sh),\
        SF(VTG0_CONTROL, VTG0_FP2, mask_sh),\
        SF(VTG0_CONTROL, VTG0_VCOUNT_INIT, mask_sh),\
        SF(OTG0_OTG_DRR_V_TOTAL_CHANGE, OTG_DRR_V_TOTAL_CHANGE_LIMIT, mask_sh),\
        SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE, mask_sh),\
        SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_PENDING, mask_sh),\
-       SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_MODE, mask_sh)
+       SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_MODE, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_FLIP_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_DC_REG_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_CURSOR_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh),\
 
 void dcn30_timing_generator_init(struct optc *optc1);
 
@@ -356,4 +362,7 @@ void optc3_set_odm_combine(struct timing_generator *optc, int *opp_id, int opp_c
 void optc3_wait_drr_doublebuffer_pending_clear(struct timing_generator *optc);
 void optc3_tg_init(struct timing_generator *optc);
 void optc3_set_vtotal_min_max(struct timing_generator *optc, int vtotal_min, int vtotal_max);
+bool optc3_get_optc_double_buffer_pending(struct timing_generator *optc);
+bool optc3_get_otg_update_pending(struct timing_generator *optc);
+bool optc3_get_pipe_update_pending(struct timing_generator *optc);
 #endif /* __DC_OPTC_DCN30_H__ */
index 1a22ae89fb5555462b5245baf6b9a61ea74040a6..d7a45ef2d01b383b767a22ee55d7f651d0821741 100644 (file)
@@ -169,6 +169,9 @@ static struct timing_generator_funcs dcn30_tg_funcs = {
                .get_hw_timing = optc1_get_hw_timing,
                .wait_drr_doublebuffer_pending_clear = optc3_wait_drr_doublebuffer_pending_clear,
                .is_two_pixels_per_container = optc1_is_two_pixels_per_container,
+               .get_optc_double_buffer_pending = optc3_get_optc_double_buffer_pending,
+               .get_otg_double_buffer_pending = optc3_get_otg_update_pending,
+               .get_pipe_update_pending = optc3_get_pipe_update_pending,
 };
 
 void dcn301_timing_generator_init(struct optc *optc1)
index 30b81a448ce2d16ce566e2f16fb1f6c716c66f5e..fbbe86d00c2e3e0183fd05b27629201af764fc7d 100644 (file)
@@ -99,7 +99,8 @@
        SRI(OPTC_MEMORY_CONFIG, ODM, inst),\
        SRI(OTG_CRC_CNTL2, OTG, inst),\
        SR(DWB_SOURCE_SELECT),\
-       SRI(OTG_DRR_CONTROL, OTG, inst)
+       SRI(OTG_DRR_CONTROL, OTG, inst),\
+       SRI(OTG_PIPE_UPDATE_STATUS, OTG, inst)
 
 #define OPTC_COMMON_MASK_SH_LIST_DCN3_1(mask_sh)\
        SF(OTG0_OTG_VSTARTUP_PARAM, VSTARTUP_START, mask_sh),\
        SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DATA_STREAM_COMBINE_MODE, mask_sh),\
        SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DATA_STREAM_SPLIT_MODE, mask_sh),\
        SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DATA_FORMAT, mask_sh),\
-       SF(OTG0_OTG_DRR_CONTROL, OTG_V_TOTAL_LAST_USED_BY_DRR, mask_sh)
+       SF(OTG0_OTG_DRR_CONTROL, OTG_V_TOTAL_LAST_USED_BY_DRR, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_FLIP_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_DC_REG_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_CURSOR_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh),\
 
 void dcn31_timing_generator_init(struct optc *optc1);
 
index 99c098e76116fc8cd59373a79b0a30a2906b4591..0ff72b97b465c593f742a8eea1c506f556b16b7c 100644 (file)
@@ -98,7 +98,8 @@
        SRI(OPTC_BYTES_PER_PIXEL, ODM, inst),\
        SRI(OPTC_WIDTH_CONTROL, ODM, inst),\
        SRI(OPTC_MEMORY_CONFIG, ODM, inst),\
-       SRI(OTG_DRR_CONTROL, OTG, inst)
+       SRI(OTG_DRR_CONTROL, OTG, inst),\
+       SRI(OTG_PIPE_UPDATE_STATUS, OTG, inst)
 
 #define OPTC_COMMON_MASK_SH_LIST_DCN3_14(mask_sh)\
        SF(OTG0_OTG_VSTARTUP_PARAM, VSTARTUP_START, mask_sh),\
        SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE, mask_sh),\
        SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE_MANUAL, mask_sh),\
        SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_MODE, mask_sh),\
-       SF(OTG0_OTG_DRR_CONTROL, OTG_V_TOTAL_LAST_USED_BY_DRR, mask_sh)
+       SF(OTG0_OTG_DRR_CONTROL, OTG_V_TOTAL_LAST_USED_BY_DRR, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_FLIP_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_DC_REG_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_CURSOR_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh),\
 
 void dcn314_timing_generator_init(struct optc *optc1);
 
index 00094f0e8470659bcead7361ccc12af0c27f2c33..c217f653b3c815544d4078484f32b269fbd4e4ef 100644 (file)
@@ -297,18 +297,6 @@ static void optc32_set_drr(
        optc32_setup_manual_trigger(optc);
 }
 
-bool optc32_get_double_buffer_pending(struct timing_generator *optc)
-{
-       struct optc *optc1 = DCN10TG_FROM_TG(optc);
-       uint32_t update_pending = 0;
-
-       REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
-                       OPTC_DOUBLE_BUFFER_PENDING,
-                       &update_pending);
-
-       return (update_pending == 1);
-}
-
 static struct timing_generator_funcs dcn32_tg_funcs = {
                .validate_timing = optc1_validate_timing,
                .program_timing = optc1_program_timing,
@@ -373,7 +361,9 @@ static struct timing_generator_funcs dcn32_tg_funcs = {
                .setup_manual_trigger = optc2_setup_manual_trigger,
                .get_hw_timing = optc1_get_hw_timing,
                .is_two_pixels_per_container = optc1_is_two_pixels_per_container,
-               .get_double_buffer_pending = optc32_get_double_buffer_pending,
+               .get_optc_double_buffer_pending = optc3_get_optc_double_buffer_pending,
+               .get_otg_double_buffer_pending = optc3_get_otg_update_pending,
+               .get_pipe_update_pending = optc3_get_pipe_update_pending,
 };
 
 void dcn32_timing_generator_init(struct optc *optc1)
index 665d7c52f67cd34d4cc3d247491b1a03320d243e..0b0964a9da7487ae17178a794ada09af78890b01 100644 (file)
        SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE, mask_sh),\
        SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE_MANUAL, mask_sh),\
        SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_MODE, mask_sh),\
-       SF(OTG0_OTG_DRR_CONTROL, OTG_V_TOTAL_LAST_USED_BY_DRR, mask_sh)
+       SF(OTG0_OTG_DRR_CONTROL, OTG_V_TOTAL_LAST_USED_BY_DRR, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_FLIP_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_DC_REG_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_CURSOR_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh)
 
 void dcn32_timing_generator_init(struct optc *optc1);
 void optc32_set_h_timing_div_manual_mode(struct timing_generator *optc, bool manual_mode);
@@ -185,6 +189,5 @@ void optc32_get_odm_combine_segments(struct timing_generator *tg, int *odm_combi
 void optc32_set_odm_bypass(struct timing_generator *optc,
                const struct dc_crtc_timing *dc_crtc_timing);
 void optc32_wait_odm_doublebuffer_pending_clear(struct timing_generator *tg);
-bool optc32_get_double_buffer_pending(struct timing_generator *optc);
 
 #endif /* __DC_OPTC_DCN32_H__ */
index d077e2392379cab1163e3a0492137c9575eac125..be749ab41dce795b56fa30ba95b2d851844eb176 100644 (file)
        SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL_READBACK, OTG_CRC1_WINDOWB_Y_END_READBACK, mask_sh),\
        SF(OPTC_CLOCK_CONTROL, OPTC_FGCG_REP_DIS, mask_sh),\
        SF(OTG0_OTG_V_COUNT_STOP_CONTROL, OTG_V_COUNT_STOP, mask_sh),\
-       SF(OTG0_OTG_V_COUNT_STOP_CONTROL2, OTG_V_COUNT_STOP_TIMER, mask_sh)
+       SF(OTG0_OTG_V_COUNT_STOP_CONTROL2, OTG_V_COUNT_STOP_TIMER, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_FLIP_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_DC_REG_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_CURSOR_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh)
 
 void dcn35_timing_generator_init(struct optc *optc1);
 
index a5d6a7dca554c345ae27807208fc0081e6e55d56..db670fc172644c429ec7e9d3bc15fbc6619463b7 100644 (file)
@@ -493,7 +493,9 @@ static struct timing_generator_funcs dcn401_tg_funcs = {
                .setup_manual_trigger = optc2_setup_manual_trigger,
                .get_hw_timing = optc1_get_hw_timing,
                .is_two_pixels_per_container = optc1_is_two_pixels_per_container,
-               .get_double_buffer_pending = optc32_get_double_buffer_pending,
+               .get_optc_double_buffer_pending = optc3_get_optc_double_buffer_pending,
+               .get_otg_double_buffer_pending = optc3_get_otg_update_pending,
+               .get_pipe_update_pending = optc3_get_pipe_update_pending,
 };
 
 void dcn401_timing_generator_init(struct optc *optc1)
index bb13a645802d0eb6081f57a268426bf13ce8c3d6..1be89571986fff82f1a6d51dd3707b42f8c747dc 100644 (file)
        SF(OTG0_OTG_PSTATE_REGISTER, OTG_PSTATE_KEEPOUT_START, mask_sh),\
        SF(OTG0_OTG_PSTATE_REGISTER, OTG_PSTATE_EXTEND, mask_sh),\
        SF(OTG0_OTG_PSTATE_REGISTER, OTG_UNBLANK, mask_sh),\
-       SF(OTG0_OTG_PSTATE_REGISTER, OTG_PSTATE_ALLOW_WIDTH_MIN, mask_sh)
+       SF(OTG0_OTG_PSTATE_REGISTER, OTG_PSTATE_ALLOW_WIDTH_MIN, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_FLIP_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_DC_REG_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_CURSOR_UPDATE_PENDING, mask_sh),\
+       SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh)
 
 void dcn401_timing_generator_init(struct optc *optc1);
 
index 7901792afb7b3a73fb5575f7ebc9e5821efd25c9..86c6e5e8c42eb870f93a1d0ac688d12c0224afb0 100644 (file)
@@ -1054,7 +1054,8 @@ unsigned int dcn32_calculate_mall_ways_from_bytes(const struct dc *dc, unsigned
       SRI_ARR(OPTC_BYTES_PER_PIXEL, ODM, inst),                                \
       SRI_ARR(OPTC_WIDTH_CONTROL, ODM, inst),                                  \
       SRI_ARR(OPTC_MEMORY_CONFIG, ODM, inst),                                  \
-      SRI_ARR(OTG_DRR_CONTROL, OTG, inst)
+      SRI_ARR(OTG_DRR_CONTROL, OTG, inst),                                     \
+         SRI_ARR(OTG_PIPE_UPDATE_STATUS, OTG, inst)
 
 /* HUBP */
 
index 514d1ce20df9ef965983faf43da184d132cf09ef..bdafa7496ceae744f959c7780aafde0169989a87 100644 (file)
@@ -536,8 +536,9 @@ void dcn401_prepare_mcache_programming(struct dc *dc, struct dc_state *context);
        SRI_ARR(OPTC_WIDTH_CONTROL, ODM, inst),                                  \
        SRI_ARR(OPTC_WIDTH_CONTROL2, ODM, inst),                                 \
        SRI_ARR(OPTC_MEMORY_CONFIG, ODM, inst),                                  \
-       SRI_ARR(OTG_DRR_CONTROL, OTG, inst),                                                                             \
-       SRI_ARR(OTG_PSTATE_REGISTER, OTG, inst)
+       SRI_ARR(OTG_DRR_CONTROL, OTG, inst),                                     \
+       SRI_ARR(OTG_PSTATE_REGISTER, OTG, inst),                                 \
+       SRI_ARR(OTG_PIPE_UPDATE_STATUS, OTG, inst)
 
 /* HUBBUB */
 #define HUBBUB_REG_LIST_DCN4_01_RI(id)                                       \