Commit f2303026 authored by Daniel Miess's avatar Daniel Miess Committed by Alex Deucher

drm/amd/display: Enable RCO for PHYSYMCLK in DCN35

[Why & How]
Enable root clock optimization for PHYSYMCLK and only
disable it when it's actively being used

v2:  Fix array-index-out-of-bounds in dcn35_calc_blocks_to_gate
Reviewed-by: default avatarRoman Li <roman.li@amd.com>
Reviewed-by: default avatarCharlene Liu <charlene.liu@amd.com>
Acked-by: default avatarWayne Lin <wayne.lin@amd.com>
Signed-off-by: default avatarDaniel Miess <daniel.miess@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 47745acc
...@@ -724,6 +724,7 @@ enum pg_hw_pipe_resources { ...@@ -724,6 +724,7 @@ enum pg_hw_pipe_resources {
PG_OPTC, PG_OPTC,
PG_DPSTREAM, PG_DPSTREAM,
PG_HDMISTREAM, PG_HDMISTREAM,
PG_PHYSYMCLK,
PG_HW_PIPE_RESOURCES_NUM_ELEMENT PG_HW_PIPE_RESOURCES_NUM_ELEMENT
}; };
......
...@@ -461,32 +461,22 @@ static void dccg35_set_physymclk_root_clock_gating( ...@@ -461,32 +461,22 @@ static void dccg35_set_physymclk_root_clock_gating(
case 0: case 0:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
// PHYA_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
break; break;
case 1: case 1:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
// PHYB_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
break; break;
case 2: case 2:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
// PHYC_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
break; break;
case 3: case 3:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
// PHYD_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
break; break;
case 4: case 4:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
// REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
// PHYE_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
break; break;
default: default:
BREAK_TO_DEBUGGER(); BREAK_TO_DEBUGGER();
...@@ -509,16 +499,10 @@ static void dccg35_set_physymclk( ...@@ -509,16 +499,10 @@ static void dccg35_set_physymclk(
REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL, REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
PHYASYMCLK_EN, 1, PHYASYMCLK_EN, 1,
PHYASYMCLK_SRC_SEL, clk_src); 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 { } else {
REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL, REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
PHYASYMCLK_EN, 0, PHYASYMCLK_EN, 0,
PHYASYMCLK_SRC_SEL, 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; break;
case 1: case 1:
...@@ -526,16 +510,10 @@ static void dccg35_set_physymclk( ...@@ -526,16 +510,10 @@ static void dccg35_set_physymclk(
REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL, REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
PHYBSYMCLK_EN, 1, PHYBSYMCLK_EN, 1,
PHYBSYMCLK_SRC_SEL, clk_src); 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 { } else {
REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL, REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
PHYBSYMCLK_EN, 0, PHYBSYMCLK_EN, 0,
PHYBSYMCLK_SRC_SEL, 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; break;
case 2: case 2:
...@@ -543,16 +521,10 @@ static void dccg35_set_physymclk( ...@@ -543,16 +521,10 @@ static void dccg35_set_physymclk(
REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL, REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
PHYCSYMCLK_EN, 1, PHYCSYMCLK_EN, 1,
PHYCSYMCLK_SRC_SEL, clk_src); 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 { } else {
REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL, REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
PHYCSYMCLK_EN, 0, PHYCSYMCLK_EN, 0,
PHYCSYMCLK_SRC_SEL, 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; break;
case 3: case 3:
...@@ -560,16 +532,10 @@ static void dccg35_set_physymclk( ...@@ -560,16 +532,10 @@ static void dccg35_set_physymclk(
REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL, REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
PHYDSYMCLK_EN, 1, PHYDSYMCLK_EN, 1,
PHYDSYMCLK_SRC_SEL, clk_src); 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 { } else {
REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL, REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
PHYDSYMCLK_EN, 0, PHYDSYMCLK_EN, 0,
PHYDSYMCLK_SRC_SEL, 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; break;
case 4: case 4:
...@@ -577,16 +543,10 @@ static void dccg35_set_physymclk( ...@@ -577,16 +543,10 @@ static void dccg35_set_physymclk(
REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL, REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
PHYESYMCLK_EN, 1, PHYESYMCLK_EN, 1,
PHYESYMCLK_SRC_SEL, clk_src); 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 { } else {
REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL, REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
PHYESYMCLK_EN, 0, PHYESYMCLK_EN, 0,
PHYESYMCLK_SRC_SEL, 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; break;
default: default:
...@@ -724,11 +684,6 @@ void dccg35_init(struct dccg *dccg) ...@@ -724,11 +684,6 @@ void dccg35_init(struct dccg *dccg)
dccg35_set_dpstreamclk_root_clock_gating(dccg, otg_inst, false); 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) if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
for (otg_inst = 0; otg_inst < 4; otg_inst++) for (otg_inst = 0; otg_inst < 4; otg_inst++)
dccg35_set_dppclk_root_clock_gating(dccg, otg_inst, 0); dccg35_set_dppclk_root_clock_gating(dccg, otg_inst, 0);
......
...@@ -506,6 +506,17 @@ void dcn35_dpstream_root_clock_control(struct dce_hwseq *hws, unsigned int dp_hp ...@@ -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( void dcn35_dsc_pg_control(
struct dce_hwseq *hws, struct dce_hwseq *hws,
unsigned int dsc_inst, unsigned int dsc_inst,
...@@ -1020,6 +1031,13 @@ void dcn35_calc_blocks_to_gate(struct dc *dc, struct dc_state *context, ...@@ -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) 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; 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][dc->links[i]->link_enc_hw_inst] = 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*/ /*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++) { for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
struct timing_generator *tg = dc->res_pool->timing_generators[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, ...@@ -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++) { for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++) {
if (context->res_ctx.is_hpo_dp_stream_enc_acquired[i] && if (context->res_ctx.is_hpo_dp_stream_enc_acquired[i] &&
dc->res_pool->hpo_dp_stream_enc[i]) { dc->res_pool->hpo_dp_stream_enc[i]) {
...@@ -1267,6 +1289,11 @@ void dcn35_root_clock_control(struct dc *dc, ...@@ -1267,6 +1289,11 @@ void dcn35_root_clock_control(struct dc *dc,
dc->hwseq->funcs.dpstream_root_clock_control(dc->hwseq, i, power_on); 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++) { for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) {
if (update_state->pg_pipe_res_update[PG_DSC][i]) { if (update_state->pg_pipe_res_update[PG_DSC][i]) {
...@@ -1292,6 +1319,11 @@ void dcn35_root_clock_control(struct dc *dc, ...@@ -1292,6 +1319,11 @@ void dcn35_root_clock_control(struct dc *dc,
dc->hwseq->funcs.dpstream_root_clock_control(dc->hwseq, i, power_on); 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);
} }
} }
......
...@@ -39,6 +39,8 @@ void dcn35_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, ...@@ -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_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_enable_power_gating_plane(struct dce_hwseq *hws, bool enable);
void dcn35_set_dmu_fgcg(struct dce_hwseq *hws, bool enable); void dcn35_set_dmu_fgcg(struct dce_hwseq *hws, bool enable);
......
...@@ -149,6 +149,7 @@ static const struct hwseq_private_funcs dcn35_private_funcs = { ...@@ -149,6 +149,7 @@ static const struct hwseq_private_funcs dcn35_private_funcs = {
.enable_power_gating_plane = dcn35_enable_power_gating_plane, .enable_power_gating_plane = dcn35_enable_power_gating_plane,
.dpp_root_clock_control = dcn35_dpp_root_clock_control, .dpp_root_clock_control = dcn35_dpp_root_clock_control,
.dpstream_root_clock_control = dcn35_dpstream_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, .program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree,
.update_odm = dcn35_update_odm, .update_odm = dcn35_update_odm,
.set_hdr_multiplier = dcn10_set_hdr_multiplier, .set_hdr_multiplier = dcn10_set_hdr_multiplier,
......
...@@ -148,6 +148,7 @@ static const struct hwseq_private_funcs dcn351_private_funcs = { ...@@ -148,6 +148,7 @@ static const struct hwseq_private_funcs dcn351_private_funcs = {
.enable_power_gating_plane = dcn35_enable_power_gating_plane, .enable_power_gating_plane = dcn35_enable_power_gating_plane,
.dpp_root_clock_control = dcn35_dpp_root_clock_control, .dpp_root_clock_control = dcn35_dpp_root_clock_control,
.dpstream_root_clock_control = dcn35_dpstream_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, .program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree,
.update_odm = dcn35_update_odm, .update_odm = dcn35_update_odm,
.set_hdr_multiplier = dcn10_set_hdr_multiplier, .set_hdr_multiplier = dcn10_set_hdr_multiplier,
......
...@@ -124,6 +124,10 @@ struct hwseq_private_funcs { ...@@ -124,6 +124,10 @@ struct hwseq_private_funcs {
struct dce_hwseq *hws, struct dce_hwseq *hws,
unsigned int dpp_inst, unsigned int dpp_inst,
bool clock_on); 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, void (*dpp_pg_control)(struct dce_hwseq *hws,
unsigned int dpp_inst, unsigned int dpp_inst,
bool power_on); bool power_on);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment