drm/amd/display: Trigger DIO FIFO resync on commit streams
authorSaaem Rizvi <syedsaaem.rizvi@amd.com>
Tue, 9 May 2023 18:41:59 +0000 (14:41 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 9 Jun 2023 14:42:58 +0000 (10:42 -0400)
[WHY]
Currently, there is an intermittent issue where a screen can either go
blank or be corrupted.

[HOW]
To resolve the issue we trigger the ramping logic for DIO FIFO so that
it goes back up to the correct speed.

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Acked-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Saaem Rizvi <syedsaaem.rizvi@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.h
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c
drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h

index 8d2460d..1a0be40 100644 (file)
@@ -2291,6 +2291,9 @@ enum dc_status dce110_apply_ctx_to_hw(
 
                if (DC_OK != status)
                        return status;
+
+               if (hws->funcs.resync_fifo_dccg_dio)
+                       hws->funcs.resync_fifo_dccg_dio(hws, dc, context);
        }
 
        if (dc->fbc_compressor)
index 7bdc146..c8602bc 100644 (file)
 #define DCCG314_REG_FIELD_LIST(type) \
        type DSCCLK3_DTO_PHASE;\
        type DSCCLK3_DTO_MODULO;\
-       type DSCCLK3_DTO_ENABLE;
+       type DSCCLK3_DTO_ENABLE;\
+       type DENTIST_DISPCLK_RDIVIDER;\
+       type DENTIST_DISPCLK_WDIVIDER;
 
 #define DCCG32_REG_FIELD_LIST(type) \
        type DPSTREAMCLK0_EN;\
index de7bfba..e0e7d32 100644 (file)
 #define DC_LOGGER \
        dccg->ctx->logger
 
+static void dccg314_trigger_dio_fifo_resync(
+       struct dccg *dccg)
+{
+       struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+       uint32_t dispclk_rdivider_value = 0;
+
+       REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, &dispclk_rdivider_value);
+       REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value);
+}
+
 static void dccg314_get_pixel_rate_div(
                struct dccg *dccg,
                uint32_t otg_inst,
@@ -357,6 +367,7 @@ static const struct dccg_funcs dccg314_funcs = {
        .disable_dsc = dccg31_disable_dscclk,
        .enable_dsc = dccg31_enable_dscclk,
        .set_pixel_rate_div = dccg314_set_pixel_rate_div,
+       .trigger_dio_fifo_resync = dccg314_trigger_dio_fifo_resync,
        .set_valid_pixel_rate = dccg314_set_valid_pixel_rate,
 };
 
index 90687a9..8e07d31 100644 (file)
        DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYBSYMCLK_GATE_DISABLE, mask_sh),\
        DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYCSYMCLK_GATE_DISABLE, mask_sh),\
        DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYDSYMCLK_GATE_DISABLE, mask_sh),\
-       DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYESYMCLK_GATE_DISABLE, mask_sh)
+       DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYESYMCLK_GATE_DISABLE, mask_sh),\
+       DCCG_SF(HDMISTREAMCLK0_DTO_PARAM, HDMISTREAMCLK0_DTO_MODULO, mask_sh),\
+       DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, mask_sh),\
+       DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh)
 
 struct dccg *dccg314_create(
        struct dc_context *ctx,
index f7a3e0d..70fac2e 100644 (file)
@@ -390,6 +390,33 @@ void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx)
                                pix_per_cycle);
 }
 
+void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context)
+{
+       uint8_t i;
+       struct pipe_ctx *pipe = NULL;
+       bool otg_disabled[MAX_PIPES] = {false};
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+               if (pipe->top_pipe || pipe->prev_odm_pipe)
+                       continue;
+
+               if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) {
+                       pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
+                       reset_sync_context_for_pipe(dc, context, i);
+                       otg_disabled[i] = true;
+               }
+       }
+
+       hws->ctx->dc->res_pool->dccg->funcs->trigger_dio_fifo_resync(hws->ctx->dc->res_pool->dccg);
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               if (otg_disabled[i])
+                       pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
+       }
+}
+
 void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on)
 {
        if (!hws->ctx->dc->debug.root_clock_optimization.bits.dpp)
index 6d0b625..559d710 100644 (file)
@@ -41,6 +41,8 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
 
 void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx);
 
+void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context);
+
 void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
 
 void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on);
index 7a28c7b..90be62c 100644 (file)
@@ -152,6 +152,7 @@ static const struct hwseq_private_funcs dcn314_private_funcs = {
        .setup_hpo_hw_control = dcn31_setup_hpo_hw_control,
        .calculate_dccg_k1_k2_values = dcn314_calculate_dccg_k1_k2_values,
        .set_pixels_per_cycle = dcn314_set_pixels_per_cycle,
+       .resync_fifo_dccg_dio = dcn314_resync_fifo_dccg_dio,
 };
 
 void dcn314_hw_sequencer_construct(struct dc *dc)
index ad6acd1..0b700b3 100644 (file)
@@ -159,6 +159,9 @@ struct dccg_funcs {
                        int otg_inst,
                        int pixclk_khz);
 
+       void (*trigger_dio_fifo_resync)(
+                       struct dccg *dccg);
+
        void (*dpp_root_clock_control)(
                        struct dccg *dccg,
                        unsigned int dpp_inst,
index 4513544..4ca4192 100644 (file)
@@ -160,6 +160,8 @@ struct hwseq_private_funcs {
                        unsigned int *k1_div,
                        unsigned int *k2_div);
        void (*set_pixels_per_cycle)(struct pipe_ctx *pipe_ctx);
+       void (*resync_fifo_dccg_dio)(struct dce_hwseq *hws, struct dc *dc,
+                       struct dc_state *context);
        bool (*is_dp_dig_pixel_rate_div_policy)(struct pipe_ctx *pipe_ctx);
 #endif
 };