Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Trigger DIO FIFO resync on commit streams

[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>

authored by

Saaem Rizvi and committed by
Alex Deucher
3e8d74cb 91b38ca1

+56 -2
+3
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
··· 2291 2291 2292 2292 if (DC_OK != status) 2293 2293 return status; 2294 + 2295 + if (hws->funcs.resync_fifo_dccg_dio) 2296 + hws->funcs.resync_fifo_dccg_dio(hws, dc, context); 2294 2297 } 2295 2298 2296 2299 if (dc->fbc_compressor)
+3 -1
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h
··· 208 208 #define DCCG314_REG_FIELD_LIST(type) \ 209 209 type DSCCLK3_DTO_PHASE;\ 210 210 type DSCCLK3_DTO_MODULO;\ 211 - type DSCCLK3_DTO_ENABLE; 211 + type DSCCLK3_DTO_ENABLE;\ 212 + type DENTIST_DISPCLK_RDIVIDER;\ 213 + type DENTIST_DISPCLK_WDIVIDER; 212 214 213 215 #define DCCG32_REG_FIELD_LIST(type) \ 214 216 type DPSTREAMCLK0_EN;\
+11
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
··· 45 45 #define DC_LOGGER \ 46 46 dccg->ctx->logger 47 47 48 + static void dccg314_trigger_dio_fifo_resync( 49 + struct dccg *dccg) 50 + { 51 + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); 52 + uint32_t dispclk_rdivider_value = 0; 53 + 54 + REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, &dispclk_rdivider_value); 55 + REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value); 56 + } 57 + 48 58 static void dccg314_get_pixel_rate_div( 49 59 struct dccg *dccg, 50 60 uint32_t otg_inst, ··· 367 357 .disable_dsc = dccg31_disable_dscclk, 368 358 .enable_dsc = dccg31_enable_dscclk, 369 359 .set_pixel_rate_div = dccg314_set_pixel_rate_div, 360 + .trigger_dio_fifo_resync = dccg314_trigger_dio_fifo_resync, 370 361 .set_valid_pixel_rate = dccg314_set_valid_pixel_rate, 371 362 }; 372 363
+4 -1
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.h
··· 192 192 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYBSYMCLK_GATE_DISABLE, mask_sh),\ 193 193 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYCSYMCLK_GATE_DISABLE, mask_sh),\ 194 194 DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYDSYMCLK_GATE_DISABLE, mask_sh),\ 195 - DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYESYMCLK_GATE_DISABLE, mask_sh) 195 + DCCG_SF(DCCG_GATE_DISABLE_CNTL2, PHYESYMCLK_GATE_DISABLE, mask_sh),\ 196 + DCCG_SF(HDMISTREAMCLK0_DTO_PARAM, HDMISTREAMCLK0_DTO_MODULO, mask_sh),\ 197 + DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, mask_sh),\ 198 + DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh) 196 199 197 200 struct dccg *dccg314_create( 198 201 struct dc_context *ctx,
+27
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
··· 390 390 pix_per_cycle); 391 391 } 392 392 393 + void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context) 394 + { 395 + uint8_t i; 396 + struct pipe_ctx *pipe = NULL; 397 + bool otg_disabled[MAX_PIPES] = {false}; 398 + 399 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 400 + pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 401 + 402 + if (pipe->top_pipe || pipe->prev_odm_pipe) 403 + continue; 404 + 405 + if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) { 406 + pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg); 407 + reset_sync_context_for_pipe(dc, context, i); 408 + otg_disabled[i] = true; 409 + } 410 + } 411 + 412 + hws->ctx->dc->res_pool->dccg->funcs->trigger_dio_fifo_resync(hws->ctx->dc->res_pool->dccg); 413 + 414 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 415 + if (otg_disabled[i]) 416 + pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg); 417 + } 418 + } 419 + 393 420 void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on) 394 421 { 395 422 if (!hws->ctx->dc->debug.root_clock_optimization.bits.dpp)
+2
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h
··· 41 41 42 42 void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx); 43 43 44 + void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context); 45 + 44 46 void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on); 45 47 46 48 void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on);
+1
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c
··· 152 152 .setup_hpo_hw_control = dcn31_setup_hpo_hw_control, 153 153 .calculate_dccg_k1_k2_values = dcn314_calculate_dccg_k1_k2_values, 154 154 .set_pixels_per_cycle = dcn314_set_pixels_per_cycle, 155 + .resync_fifo_dccg_dio = dcn314_resync_fifo_dccg_dio, 155 156 }; 156 157 157 158 void dcn314_hw_sequencer_construct(struct dc *dc)
+3
drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
··· 159 159 int otg_inst, 160 160 int pixclk_khz); 161 161 162 + void (*trigger_dio_fifo_resync)( 163 + struct dccg *dccg); 164 + 162 165 void (*dpp_root_clock_control)( 163 166 struct dccg *dccg, 164 167 unsigned int dpp_inst,
+2
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h
··· 160 160 unsigned int *k1_div, 161 161 unsigned int *k2_div); 162 162 void (*set_pixels_per_cycle)(struct pipe_ctx *pipe_ctx); 163 + void (*resync_fifo_dccg_dio)(struct dce_hwseq *hws, struct dc *dc, 164 + struct dc_state *context); 163 165 bool (*is_dp_dig_pixel_rate_div_policy)(struct pipe_ctx *pipe_ctx); 164 166 #endif 165 167 };