From: Yihan Zhu <Yihan.Zhu@xxxxxxx> [WHY & HOW] Cursor corruption observed on USBC display with specific system setup with a reboot. Cursor memory might still in the lightsleep state due to voltage issue, we need program DISPCLK_R_GATE_DISABLE to avoid this issue only on DCN35. Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@xxxxxxx> Signed-off-by: Yihan Zhu <Yihan.Zhu@xxxxxxx> Signed-off-by: Wayne Lin <wayne.lin@xxxxxxx> --- .../drm/amd/display/dc/dpp/dcn20/dcn20_dpp.h | 1 + .../drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h | 1 + .../drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c | 22 +++++++++++++++---- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn20/dcn20_dpp.h b/drivers/gpu/drm/amd/display/dc/dpp/dcn20/dcn20_dpp.h index cd1706d301e7..f09cba8e29cc 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn20/dcn20_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn20/dcn20_dpp.h @@ -690,6 +690,7 @@ struct dcn20_dpp { int lb_memory_size; int lb_bits_per_entry; bool is_write_to_ram_a_safe; + bool dispclk_r_gate_disable; struct scaler_data scl_data; struct pwl_params pwl_data; }; diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h index b110f35ef66b..f236824126e9 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h @@ -572,6 +572,7 @@ struct dcn3_dpp { int lb_memory_size; int lb_bits_per_entry; bool is_write_to_ram_a_safe; + bool dispclk_r_gate_disable; struct scaler_data scl_data; struct pwl_params pwl_data; }; diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c index 9f885a03eec6..62b7012cda43 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c @@ -50,11 +50,21 @@ void dpp35_dppclk_control( DPPCLK_RATE_CONTROL, dppclk_div, DPP_CLOCK_ENABLE, 1); else - REG_UPDATE(DPP_CONTROL, - DPP_CLOCK_ENABLE, 1); + if (dpp->dispclk_r_gate_disable) + REG_UPDATE_2(DPP_CONTROL, + DPP_CLOCK_ENABLE, 1, + DISPCLK_R_GATE_DISABLE, 1); + else + REG_UPDATE(DPP_CONTROL, + DPP_CLOCK_ENABLE, 1); } else - REG_UPDATE(DPP_CONTROL, - DPP_CLOCK_ENABLE, 0); + if (dpp->dispclk_r_gate_disable) + REG_UPDATE_2(DPP_CONTROL, + DPP_CLOCK_ENABLE, 0, + DISPCLK_R_GATE_DISABLE, 0); + else + REG_UPDATE(DPP_CONTROL, + DPP_CLOCK_ENABLE, 0); } void dpp35_program_bias_and_scale_fcnv( @@ -126,6 +136,10 @@ bool dpp35_construct( (const struct dcn3_dpp_mask *)(tf_mask)); dpp->base.funcs = &dcn35_dpp_funcs; + + // w/a for cursor memory stuck in LS by programming DISPCLK_R_GATE_DISABLE, limit w/a to some ASIC revs + if (dpp->base.ctx->asic_id.hw_internal_rev <= 0x10) + dpp->dispclk_r_gate_disable = true; return ret; } -- 2.37.3