From: Alvin Lee <[email protected]>

[Why & How]
- Dumping clock registers in SW init can get incorrect clock readback due
  to other init code (e.g., in DMU) potentially not executed yet
- Move clk_ip register access into HW init to ensure the clock read back
  gets the correct values

Reviewed-by: Nicholas Kazlauskas <[email protected]>
Signed-off-by: Alvin Lee <[email protected]>
Signed-off-by: Ray Wu <[email protected]>
---
 .../display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c  | 140 +++++++++---------
 1 file changed, 74 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
index 2b7740b82161..138afa7afc86 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
@@ -756,29 +756,6 @@ static bool dcn60_fetch_dal_init_table(struct 
clk_mgr_internal *clk_mgr)
        return true;
 }
 
-void dcn60_init_clocks(struct clk_mgr *clk_mgr_base)
-{
-       struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
-       uint32_t smu_header_ver = 0;
-
-       memset(&(clk_mgr_base->clks), 0, sizeof(struct dc_clocks));
-       clk_mgr_base->clks.p_state_change_support = true;
-       clk_mgr_base->clks.fclk_p_state_change_support = false;
-       clk_mgr->smu_present = !clk_mgr_base->force_smu_not_present /* not 
force-disabled */
-                       && dcn60_smu_get_msg_header_version(clk_mgr, 
&smu_header_ver)
-                       && smu_header_ver != 0;
-
-       clk_mgr->dpm_present = clk_mgr->smu_present
-                       && dcn60_fetch_dal_init_table(clk_mgr)
-                       && 
clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dcfclk_levels
-                       && 
clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dtbclk_levels
-                       && 
clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dispclk_levels;
-
-       if (clk_mgr->dpm_present)
-               clk_mgr_base->ctx->dc->res_pool->funcs->update_bw_bounding_box(
-                               clk_mgr_base->ctx->dc, clk_mgr_base->bw_params);
-}
-
 static inline uint32_t count_to_khz(uint32_t count, uint32_t timer_ths, 
uint32_t refclk_khz)
 {
        if (timer_ths == 0)
@@ -899,6 +876,80 @@ static void dcn60_dump_clk_registers(struct 
clk_state_registers_and_bypass *regs
        }
 }
 
+static void dcn60_dump_and_assign_boot_clocks(struct clk_mgr *clk_mgr_base)
+{
+       struct clk_log_info log_info = {0};
+
+       dcn60_dump_clk_registers(&clk_mgr_base->boot_snapshot, clk_mgr_base, 
&log_info);
+
+       if (clk_mgr_base->ctx->dc->debug.disable_dtb_ref_clk_switch &&
+                       clk_mgr_base->clks.ref_dtbclk_khz != 
clk_mgr_base->boot_snapshot.dtbclk) {
+               clk_mgr_base->clks.ref_dtbclk_khz = 
clk_mgr_base->boot_snapshot.dtbclk;
+       }
+
+       if (clk_mgr_base->boot_snapshot.dprefclk != 0)
+               clk_mgr_base->dprefclk_khz = 
clk_mgr_base->boot_snapshot.dprefclk;
+}
+
+static void dcn60_clock_read_ss_info(struct clk_mgr_internal *clk_mgr)
+{
+       struct dc_bios *bp = clk_mgr->base.ctx->dc_bios;
+       int ss_info_num = bp->funcs->get_ss_entry_number(
+                       bp, AS_SIGNAL_TYPE_GPU_PLL);
+
+       if (ss_info_num) {
+               struct spread_spectrum_info info = { { 0 } };
+               enum bp_result result = bp->funcs->get_spread_spectrum_info(
+                               bp, AS_SIGNAL_TYPE_GPU_PLL, 0, &info);
+
+               /* SSInfo.spreadSpectrumPercentage !=0 would be sign
+                * that SS is enabled
+                */
+               if (result == BP_RESULT_OK &&
+                               info.spread_spectrum_percentage != 0) {
+                       clk_mgr->ss_on_dprefclk = true;
+                       clk_mgr->dprefclk_ss_divider = 
info.spread_percentage_divider;
+
+                       if (info.type.CENTER_MODE == 0) {
+                               /* Currently for DP Reference clock we
+                                * need only SS percentage for
+                                * downspread
+                                */
+                               clk_mgr->dprefclk_ss_percentage =
+                                               info.spread_spectrum_percentage;
+                       }
+               }
+       }
+}
+
+void dcn60_init_clocks(struct clk_mgr *clk_mgr_base)
+{
+       struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+       uint32_t smu_header_ver = 0;
+
+       memset(&(clk_mgr_base->clks), 0, sizeof(struct dc_clocks));
+       clk_mgr_base->clks.p_state_change_support = true;
+       clk_mgr_base->clks.fclk_p_state_change_support = false;
+
+       dcn60_dump_and_assign_boot_clocks(clk_mgr_base);
+       dcn60_clock_read_ss_info(clk_mgr);
+
+       clk_mgr->smu_present = !clk_mgr_base->force_smu_not_present /* not 
force-disabled */
+                       && dcn60_smu_get_msg_header_version(clk_mgr, 
&smu_header_ver)
+                       && smu_header_ver != 0;
+
+       clk_mgr->dpm_present = clk_mgr->smu_present
+                       && dcn60_fetch_dal_init_table(clk_mgr)
+                       && 
clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dcfclk_levels
+                       && 
clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dtbclk_levels
+                       && 
clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_dispclk_levels;
+
+       if (clk_mgr->dpm_present)
+               clk_mgr_base->ctx->dc->res_pool->funcs->update_bw_bounding_box(
+                               clk_mgr_base->ctx->dc, clk_mgr_base->bw_params);
+}
+
+
 static void dcn60_auto_dpm_test_log(
                struct dc_clocks *new_clocks,
                struct clk_mgr_internal *clk_mgr,
@@ -1445,37 +1496,6 @@ static void dcn60_update_clocks(struct clk_mgr 
*clk_mgr_base,
 
 }
 
-static void dcn60_clock_read_ss_info(struct clk_mgr_internal *clk_mgr)
-{
-       struct dc_bios *bp = clk_mgr->base.ctx->dc_bios;
-       int ss_info_num = bp->funcs->get_ss_entry_number(
-                       bp, AS_SIGNAL_TYPE_GPU_PLL);
-
-       if (ss_info_num) {
-               struct spread_spectrum_info info = { { 0 } };
-               enum bp_result result = bp->funcs->get_spread_spectrum_info(
-                               bp, AS_SIGNAL_TYPE_GPU_PLL, 0, &info);
-
-               /* SSInfo.spreadSpectrumPercentage !=0 would be sign
-                * that SS is enabled
-                */
-               if (result == BP_RESULT_OK &&
-                               info.spread_spectrum_percentage != 0) {
-                       clk_mgr->ss_on_dprefclk = true;
-                       clk_mgr->dprefclk_ss_divider = 
info.spread_percentage_divider;
-
-                       if (info.type.CENTER_MODE == 0) {
-                               /* Currently for DP Reference clock we
-                                * need only SS percentage for
-                                * downspread
-                                */
-                               clk_mgr->dprefclk_ss_percentage =
-                                               info.spread_spectrum_percentage;
-                       }
-               }
-       }
-}
-
 /* Set min memclk to minimum, either constrained by the current mode or DPM0 */
 static void dcn60_set_hard_min_memclk(struct clk_mgr *clk_mgr_base, bool 
current_mode)
 {
@@ -1681,7 +1701,6 @@ struct clk_mgr_internal *dcn60_clk_mgr_construct(
                struct dc_context *ctx,
                struct dccg *dccg)
 {
-       struct clk_log_info log_info = {0};
        struct dcn60_clk_mgr *clk_mgr60 = kzalloc(sizeof(struct dcn60_clk_mgr), 
GFP_KERNEL);
        struct clk_mgr_internal *clk_mgr;
 
@@ -1716,17 +1735,6 @@ struct clk_mgr_internal *dcn60_clk_mgr_construct(
                if (clk_mgr->base.dentist_vco_freq_khz == 0)
                        clk_mgr->base.dentist_vco_freq_khz = 4500000;
 
-               dcn60_dump_clk_registers(&clk_mgr->base.boot_snapshot, 
&clk_mgr->base, &log_info);
-
-               if (ctx->dc->debug.disable_dtb_ref_clk_switch &&
-                               clk_mgr->base.clks.ref_dtbclk_khz != 
clk_mgr->base.boot_snapshot.dtbclk) {
-                       clk_mgr->base.clks.ref_dtbclk_khz = 
clk_mgr->base.boot_snapshot.dtbclk;
-               }
-
-               if (clk_mgr->base.boot_snapshot.dprefclk != 0)
-                       clk_mgr->base.dprefclk_khz = 
clk_mgr->base.boot_snapshot.dprefclk;
-               dcn60_clock_read_ss_info(clk_mgr);
-
        clk_mgr->dfs_bypass_enabled = false;
 
        clk_mgr->smu_present = false;
-- 
2.43.0

Reply via email to