]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Enable RCO for PHYSYMCLK in DCN35
authorDaniel Miess <daniel.miess@amd.com>
Wed, 24 Apr 2024 08:49:13 +0000 (16:49 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 30 Apr 2024 13:54:31 +0000 (09:54 -0400)
[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: Roman Li <roman.li@amd.com>
Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Acked-by: Wayne Lin <wayne.lin@amd.com>
Signed-off-by: Daniel Miess <daniel.miess@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c
drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer_private.h

index 3048d5a0e87d12e8bcf4f209f1a4f79bb3954996..dd8940c2a4bfa49e579dbbd64f2ca56af6e96847 100644 (file)
@@ -724,6 +724,7 @@ enum pg_hw_pipe_resources {
        PG_OPTC,
        PG_DPSTREAM,
        PG_HDMISTREAM,
+       PG_PHYSYMCLK,
        PG_HW_PIPE_RESOURCES_NUM_ELEMENT
 };
 
index 4b282b7e0996144313b67a5445a55bfc28d066e2..795320a25fd27e14ca0537ce855facc950091b38 100644 (file)
@@ -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);
index d4989d15e2f1d1dbc41bb5d2f31d55c5bffba4ff..1c71a5d4ac5d53af4fad30c30ba9c7a591d24d3b 100644 (file)
@@ -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][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*/
        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);
+
        }
 }
 
index a731c8880d60aa29c7442b2bd0e06b6afdf32c66..bc05beba5f2ce69074525be94c00c38a887b9c19 100644 (file)
@@ -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);
index 0e87f3503265b23885b385d548bc400ee2214f0c..7f2cbfac9099ca5d325bd232ed4f3c5ab37c2d74 100644 (file)
@@ -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,
index ff772665d1ae78fb7a80d357e5eb0c3835a78065..91484b71b7daa88714088d06c62f3bbe03461bb5 100644 (file)
@@ -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,
index 939832372baf1fa2914b3ec96238c9a8b619b3d7..7553d6816d36195fd3e76c7cb91271d72a893d22 100644 (file)
@@ -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);