From: Daniel Miess <daniel.miess@xxxxxxx> [Why & How] Enable root clock optimization for PHYSYMCLK and only disable it when it's actively being used Reviewed-by: Charlene Liu <charlene.liu@xxxxxxx> Acked-by: Wayne Lin <wayne.lin@xxxxxxx> Signed-off-by: Daniel Miess <daniel.miess@xxxxxxx> --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c | 45 ------------------- .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 32 +++++++++++++ .../amd/display/dc/hwss/dcn35/dcn35_hwseq.h | 2 + .../amd/display/dc/hwss/dcn35/dcn35_init.c | 1 + .../amd/display/dc/hwss/dcn351/dcn351_init.c | 1 + .../display/dc/hwss/hw_sequencer_private.h | 4 ++ 7 files changed, 41 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 3048d5a0e87d..dd8940c2a4bf 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -724,6 +724,7 @@ enum pg_hw_pipe_resources { PG_OPTC, PG_DPSTREAM, PG_HDMISTREAM, + PG_PHYSYMCLK, PG_HW_PIPE_RESOURCES_NUM_ELEMENT }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c index 4b282b7e0996..795320a25fd2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c @@ -461,32 +461,22 @@ static void dccg35_set_physymclk_root_clock_gating( case 0: REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYA_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); break; case 1: REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYB_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); break; case 2: REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYC_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); break; case 3: REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYD_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); break; case 4: REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYE_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); break; default: BREAK_TO_DEBUGGER(); @@ -509,16 +499,10 @@ static void dccg35_set_physymclk( REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL, PHYASYMCLK_EN, 1, PHYASYMCLK_SRC_SEL, clk_src); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYA_REFCLK_ROOT_GATE_DISABLE, 0); } else { REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL, PHYASYMCLK_EN, 0, PHYASYMCLK_SRC_SEL, 0); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYA_REFCLK_ROOT_GATE_DISABLE, 1); } break; case 1: @@ -526,16 +510,10 @@ static void dccg35_set_physymclk( REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL, PHYBSYMCLK_EN, 1, PHYBSYMCLK_SRC_SEL, clk_src); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYB_REFCLK_ROOT_GATE_DISABLE, 0); } else { REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL, PHYBSYMCLK_EN, 0, PHYBSYMCLK_SRC_SEL, 0); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYB_REFCLK_ROOT_GATE_DISABLE, 1); } break; case 2: @@ -543,16 +521,10 @@ static void dccg35_set_physymclk( REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL, PHYCSYMCLK_EN, 1, PHYCSYMCLK_SRC_SEL, clk_src); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYC_REFCLK_ROOT_GATE_DISABLE, 0); } else { REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL, PHYCSYMCLK_EN, 0, PHYCSYMCLK_SRC_SEL, 0); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYC_REFCLK_ROOT_GATE_DISABLE, 1); } break; case 3: @@ -560,16 +532,10 @@ static void dccg35_set_physymclk( REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL, PHYDSYMCLK_EN, 1, PHYDSYMCLK_SRC_SEL, clk_src); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYD_REFCLK_ROOT_GATE_DISABLE, 0); } else { REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL, PHYDSYMCLK_EN, 0, PHYDSYMCLK_SRC_SEL, 0); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYD_REFCLK_ROOT_GATE_DISABLE, 1); } break; case 4: @@ -577,16 +543,10 @@ static void dccg35_set_physymclk( REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL, PHYESYMCLK_EN, 1, PHYESYMCLK_SRC_SEL, clk_src); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYE_REFCLK_ROOT_GATE_DISABLE, 0); } else { REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL, PHYESYMCLK_EN, 0, PHYESYMCLK_SRC_SEL, 0); -// if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) -// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4, -// PHYE_REFCLK_ROOT_GATE_DISABLE, 1); } break; default: @@ -724,11 +684,6 @@ void dccg35_init(struct dccg *dccg) dccg35_set_dpstreamclk_root_clock_gating(dccg, otg_inst, false); } - if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk) - for (otg_inst = 0; otg_inst < 5; otg_inst++) - dccg35_set_physymclk_root_clock_gating(dccg, otg_inst, - false); - if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) for (otg_inst = 0; otg_inst < 4; otg_inst++) dccg35_set_dppclk_root_clock_gating(dccg, otg_inst, 0); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c index b94a85380d73..dea7e63a49d9 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c @@ -506,6 +506,17 @@ void dcn35_dpstream_root_clock_control(struct dce_hwseq *hws, unsigned int dp_hp } } +void dcn35_physymclk_root_clock_control(struct dce_hwseq *hws, unsigned int phy_inst, bool clock_on) +{ + if (!hws->ctx->dc->debug.root_clock_optimization.bits.physymclk) + return; + + if (hws->ctx->dc->res_pool->dccg->funcs->set_physymclk_root_clock_gating) { + hws->ctx->dc->res_pool->dccg->funcs->set_physymclk_root_clock_gating( + hws->ctx->dc->res_pool->dccg, phy_inst, clock_on); + } +} + void dcn35_dsc_pg_control( struct dce_hwseq *hws, unsigned int dsc_inst, @@ -1020,6 +1031,13 @@ void dcn35_calc_blocks_to_gate(struct dc *dc, struct dc_state *context, if (pipe_ctx->stream_res.hpo_dp_stream_enc) update_state->pg_pipe_res_update[PG_DPSTREAM][pipe_ctx->stream_res.hpo_dp_stream_enc->inst] = false; } + + for (i = 0; i < dc->link_count; i++) { + update_state->pg_pipe_res_update[PG_PHYSYMCLK][i] = true; + if (dc->links[i]->type != dc_connection_none) + update_state->pg_pipe_res_update[PG_PHYSYMCLK][dc->links[i]->link_enc_hw_inst] = false; + } + /*domain24 controls all the otg, mpc, opp, as long as one otg is still up, avoid enabling OTG PG*/ for (i = 0; i < dc->res_pool->timing_generator_count; i++) { struct timing_generator *tg = dc->res_pool->timing_generators[i]; @@ -1117,6 +1135,10 @@ void dcn35_calc_blocks_to_ungate(struct dc *dc, struct dc_state *context, } } + for (i = 0; i < dc->link_count; i++) + if (dc->links[i]->type != dc_connection_none) + update_state->pg_pipe_res_update[PG_PHYSYMCLK][dc->links[i]->link_enc_hw_inst] = true; + for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++) { if (context->res_ctx.is_hpo_dp_stream_enc_acquired[i] && dc->res_pool->hpo_dp_stream_enc[i]) { @@ -1267,6 +1289,11 @@ void dcn35_root_clock_control(struct dc *dc, dc->hwseq->funcs.dpstream_root_clock_control(dc->hwseq, i, power_on); } + for (i = 0; i < dc->res_pool->dig_link_enc_count; i++) + if (update_state->pg_pipe_res_update[PG_PHYSYMCLK][i]) + if (dc->hwseq->funcs.physymclk_root_clock_control) + dc->hwseq->funcs.physymclk_root_clock_control(dc->hwseq, i, power_on); + } for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) { if (update_state->pg_pipe_res_update[PG_DSC][i]) { @@ -1292,6 +1319,11 @@ void dcn35_root_clock_control(struct dc *dc, dc->hwseq->funcs.dpstream_root_clock_control(dc->hwseq, i, power_on); } + for (i = 0; i < dc->res_pool->dig_link_enc_count; i++) + if (update_state->pg_pipe_res_update[PG_PHYSYMCLK][i]) + if (dc->hwseq->funcs.physymclk_root_clock_control) + dc->hwseq->funcs.physymclk_root_clock_control(dc->hwseq, i, power_on); + } } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h index a731c8880d60..bc05beba5f2c 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h @@ -39,6 +39,8 @@ void dcn35_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, void dcn35_dpstream_root_clock_control(struct dce_hwseq *hws, unsigned int dp_hpo_inst, bool clock_on); +void dcn35_physymclk_root_clock_control(struct dce_hwseq *hws, unsigned int phy_inst, bool clock_on); + void dcn35_enable_power_gating_plane(struct dce_hwseq *hws, bool enable); void dcn35_set_dmu_fgcg(struct dce_hwseq *hws, bool enable); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c index 0e87f3503265..7f2cbfac9099 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c @@ -149,6 +149,7 @@ static const struct hwseq_private_funcs dcn35_private_funcs = { .enable_power_gating_plane = dcn35_enable_power_gating_plane, .dpp_root_clock_control = dcn35_dpp_root_clock_control, .dpstream_root_clock_control = dcn35_dpstream_root_clock_control, + .physymclk_root_clock_control = dcn35_physymclk_root_clock_control, .program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree, .update_odm = dcn35_update_odm, .set_hdr_multiplier = dcn10_set_hdr_multiplier, diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c index ff772665d1ae..91484b71b7da 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c @@ -148,6 +148,7 @@ static const struct hwseq_private_funcs dcn351_private_funcs = { .enable_power_gating_plane = dcn35_enable_power_gating_plane, .dpp_root_clock_control = dcn35_dpp_root_clock_control, .dpstream_root_clock_control = dcn35_dpstream_root_clock_control, + .physymclk_root_clock_control = dcn35_physymclk_root_clock_control, .program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree, .update_odm = dcn35_update_odm, .set_hdr_multiplier = dcn10_set_hdr_multiplier, diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h index 939832372baf..7553d6816d36 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h @@ -124,6 +124,10 @@ struct hwseq_private_funcs { struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on); + void (*physymclk_root_clock_control)( + struct dce_hwseq *hws, + unsigned int phy_inst, + bool clock_on); void (*dpp_pg_control)(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on); -- 2.37.3