diff options
author | Jun Lei <Jun.Lei@amd.com> | 2019-07-15 10:41:47 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-08-15 10:53:43 -0500 |
commit | f7f38ffef56b0138f902efd261a6d90680fec2d3 (patch) | |
tree | 09828e5dca528aab9256bc99a6d81dfc3dca872a /drivers/gpu/drm/amd/display/dc/dcn20 | |
parent | 9adc8050bf3ca3e49c65e13259a4c310640542f1 (diff) |
drm/amd/display: fixup DPP programming sequence
[why]
DC does not correct account for the fact that DPP DTO is double buffered while DPP ref is not.
This means that when DPP ref clock is lowered when it's "safe to lower", the DPP blocks that need
an increased divider will temporarily have actual DPP clock drop below minimum while DTO
double buffering takes effect. This results in temporary underflow.
[how]
To fix this, DPP clock cannot be programmed atomically, but rather be broken up into the DTO and the
ref. Each has a separate "safe to lower" logic. When doing "prepare" the ref and dividers may only increase.
When doing "optimize", both may decrease. It is guaranteed that we won't exceed max DPP clock because
we do not use dividers larger than 1.
Signed-off-by: Jun Lei <Jun.Lei@amd.com>
Reviewed-by: Eric Yang <eric.yang2@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn20')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 2 |
3 files changed, 29 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c index 31aa6ee5cd5b..16476ed25536 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c @@ -44,12 +44,16 @@ #define DC_LOGGER \ dccg->ctx->logger -void dccg2_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk) +void dccg2_update_dpp_dto(struct dccg *dccg, + int dpp_inst, + int req_dppclk, + bool reduce_divider_only) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); if (dccg->ref_dppclk && req_dppclk) { int ref_dppclk = dccg->ref_dppclk; + int current_phase, current_modulo; ASSERT(req_dppclk <= ref_dppclk); /* need to clamp to 8 bits */ @@ -61,9 +65,28 @@ void dccg2_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk) if (req_dppclk > ref_dppclk) req_dppclk = ref_dppclk; } - REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, - DPPCLK0_DTO_PHASE, req_dppclk, - DPPCLK0_DTO_MODULO, ref_dppclk); + + REG_GET_2(DPPCLK_DTO_PARAM[dpp_inst], + DPPCLK0_DTO_PHASE, ¤t_phase, + DPPCLK0_DTO_MODULO, ¤t_modulo); + + if (reduce_divider_only) { + // requested phase/modulo greater than current + if (req_dppclk * current_modulo >= current_phase * ref_dppclk) { + REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, + DPPCLK0_DTO_PHASE, req_dppclk, + DPPCLK0_DTO_MODULO, ref_dppclk); + } else { + REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, + DPPCLK0_DTO_PHASE, current_phase, + DPPCLK0_DTO_MODULO, current_modulo); + } + } else { + REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, + DPPCLK0_DTO_PHASE, req_dppclk, + DPPCLK0_DTO_MODULO, ref_dppclk); + } + REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_ENABLE[dpp_inst], 1); } else { diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h index 2205cb0204e7..74a074a873cd 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h @@ -97,7 +97,7 @@ struct dcn_dccg { const struct dccg_mask *dccg_mask; }; -void dccg2_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk); +void dccg2_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk, bool raise_divider_only); void dccg2_get_dccg_ref_freq(struct dccg *dccg, unsigned int xtalin_freq_inKhz, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 6dc4bf92c370..a6715a47f0ba 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -2482,7 +2482,7 @@ void dcn20_calculate_dlg_params( context->bw_ctx.bw.dcn.clk.socclk_khz = context->bw_ctx.dml.vba.SOCCLK * 1000; context->bw_ctx.bw.dcn.clk.dramclk_khz = context->bw_ctx.dml.vba.DRAMSpeed * 1000 / 16; context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = context->bw_ctx.dml.vba.DCFCLKDeepSleep * 1000; - context->bw_ctx.bw.dcn.clk.fclk_khz = context->bw_ctx.dml.vba.FabricClock * 1000; + context->bw_ctx.bw.dcn.clk.fclk_khz = 0; context->bw_ctx.bw.dcn.clk.p_state_change_support = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != dm_dram_clock_change_unsupported; |