From baa1fd7f32f23118f067b5af79b53998a617ef17 Mon Sep 17 00:00:00 2001 From: Eric Yang Date: Wed, 8 May 2019 19:06:30 -0400 Subject: [PATCH] drm/amd/display: Refactor clk_mgr functions [Why] Some HW specific implementations can be pulled out into clk_mgr.c. [How] * Pull get_active_display_cnt out to clk_mgr. * Pull out shared logic in set_dispclk and set_dprefclk Signed-off-by: Eric Yang Reviewed-by: Tony Cheng Acked-by: Leo Li Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 25 ++++++++ .../display/dc/clk_mgr/dcn10/rv1_clk_mgr.c | 25 +------- .../dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c | 58 ++++++++++--------- .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h | 5 ++ .../amd/display/dc/inc/hw/clk_mgr_internal.h | 4 ++ 5 files changed, 65 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c index ce24614aedcb..08b27c775cd4 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c @@ -35,6 +35,31 @@ #include "dcn10/rv1_clk_mgr.h" #include "dcn10/rv2_clk_mgr.h" + +int clk_mgr_helper_get_active_display_cnt( + struct dc *dc, + struct dc_state *context) +{ + int i, display_count; + + display_count = 0; + for (i = 0; i < context->stream_count; i++) { + const struct dc_stream_state *stream = context->streams[i]; + + /* + * Only notify active stream or virtual stream. + * Need to notify virtual stream to work around + * headless case. HPD does not fire when system is in + * S0i2. + */ + if (!stream->dpms_off || stream->signal == SIGNAL_TYPE_VIRTUAL) + display_count++; + } + + return display_count; +} + + struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg) { struct hw_asic_id asic_id = ctx->asic_id; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c index a3f953c8839d..31db9b55e11a 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c @@ -114,29 +114,6 @@ static void ramp_up_dispclk_with_dpp(struct clk_mgr_internal *clk_mgr, struct dc clk_mgr->base.clks.max_supported_dppclk_khz = new_clocks->max_supported_dppclk_khz; } -static int get_active_display_cnt( - struct dc *dc, - struct dc_state *context) -{ - int i, display_count; - - display_count = 0; - for (i = 0; i < context->stream_count; i++) { - const struct dc_stream_state *stream = context->streams[i]; - - /* - * Only notify active stream or virtual stream. - * Need to notify virtual stream to work around - * headless case. HPD does not fire when system is in - * S0i2. - */ - if (!stream->dpms_off || stream->signal == SIGNAL_TYPE_VIRTUAL) - display_count++; - } - - return display_count; -} - static void rv1_update_clocks(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool safe_to_lower) @@ -156,7 +133,7 @@ static void rv1_update_clocks(struct clk_mgr *clk_mgr_base, pp_smu = &clk_mgr->pp_smu->rv_funcs; - display_count = get_active_display_cnt(dc, context); + display_count = clk_mgr_helper_get_active_display_cnt(dc, context); if (display_count == 0) enter_display_off = true; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c index 196087072063..1897e91c8ccb 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c @@ -68,57 +68,59 @@ static const struct IP_BASE MP1_BASE = { { { { 0x00016000, 0, 0, 0, 0 } }, #define VBIOSSMC_MSG_SetDispclkFreq 0x4 #define VBIOSSMC_MSG_SetDprefclkFreq 0x5 -int rv1_vbios_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz) +int rv1_vbios_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr, unsigned int msg_id, unsigned int param) { - - int actual_dispclk_set_khz = -1; - struct dc *core_dc = clk_mgr->base.ctx->dc; - struct dmcu *dmcu = core_dc->res_pool->dmcu; - /* First clear response register */ - //dm_write_reg(ctx, mmMP1_SMN_C2PMSG_91, 0); REG_WRITE(MP1_SMN_C2PMSG_91, 0); /* Set the parameter register for the SMU message, unit is Mhz */ - //dm_write_reg(ctx, mmMP1_SMN_C2PMSG_83, requested_dispclk_khz / 1000); - REG_WRITE(MP1_SMN_C2PMSG_83, requested_dispclk_khz / 1000); + REG_WRITE(MP1_SMN_C2PMSG_83, param); /* Trigger the message transaction by writing the message ID */ - //dm_write_reg(ctx, mmMP1_SMN_C2PMSG_67, VBIOSSMC_MSG_SetDispclkFreq); - REG_WRITE(MP1_SMN_C2PMSG_67, VBIOSSMC_MSG_SetDispclkFreq); + REG_WRITE(MP1_SMN_C2PMSG_67, msg_id); REG_WAIT(MP1_SMN_C2PMSG_91, CONTENT, 1, 10, 200000); /* Actual dispclk set is returned in the parameter register */ - actual_dispclk_set_khz = REG_READ(MP1_SMN_C2PMSG_83) * 1000; + return REG_READ(MP1_SMN_C2PMSG_83); +} + +int rv1_vbios_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz) +{ + int actual_dispclk_set_mhz = -1; + struct dc *core_dc = clk_mgr->base.ctx->dc; + struct dmcu *dmcu = core_dc->res_pool->dmcu; + + /* Unit of SMU msg parameter is Mhz */ + actual_dispclk_set_mhz = rv1_vbios_smu_send_msg_with_param( + clk_mgr, + VBIOSSMC_MSG_SetDispclkFreq, + requested_dispclk_khz / 1000); + + /* Actual dispclk set is returned in the parameter register */ + actual_dispclk_set_mhz = REG_READ(MP1_SMN_C2PMSG_83) * 1000; if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) { if (dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) { - if (clk_mgr->dfs_bypass_disp_clk != actual_dispclk_set_khz) + if (clk_mgr->dfs_bypass_disp_clk != actual_dispclk_set_mhz) dmcu->funcs->set_psr_wait_loop(dmcu, - actual_dispclk_set_khz / 1000 / 7); + actual_dispclk_set_mhz / 7); } } - return actual_dispclk_set_khz; + return actual_dispclk_set_mhz * 1000; } int rv1_vbios_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr) { - int actual_dprefclk_set_khz = -1; + int actual_dprefclk_set_mhz = -1; - REG_WRITE(MP1_SMN_C2PMSG_91, 0); + actual_dprefclk_set_mhz = rv1_vbios_smu_send_msg_with_param( + clk_mgr, + VBIOSSMC_MSG_SetDprefclkFreq, + clk_mgr->base.dprefclk_khz / 1000); - /* Set the parameter register for the SMU message */ - REG_WRITE(MP1_SMN_C2PMSG_83, clk_mgr->base.dprefclk_khz / 1000); + /* TODO: add code for programing DP DTO, currently this is down by command table */ - /* Trigger the message transaction by writing the message ID */ - REG_WRITE(MP1_SMN_C2PMSG_67, VBIOSSMC_MSG_SetDprefclkFreq); - - /* Wait for SMU response */ - REG_WAIT(MP1_SMN_C2PMSG_91, CONTENT, 1, 10, 200000); - - actual_dprefclk_set_khz = REG_READ(MP1_SMN_C2PMSG_83) * 1000; - - return actual_dprefclk_set_khz; + return actual_dprefclk_set_mhz * 1000; } diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h index 0a2346a009ad..721e13135e76 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h @@ -30,6 +30,10 @@ /* Public interfaces */ +struct clk_states { + uint32_t dprefclk_khz; +}; + struct clk_mgr_funcs { /* * This function should set new clocks based on the input "safe_to_lower". @@ -46,6 +50,7 @@ struct clk_mgr_funcs { void (*init_clocks)(struct clk_mgr *clk_mgr); + void (*enable_pme_wa) (struct clk_mgr *clk_mgr); }; void dce121_clock_patch_xgmi_ss_info(struct clk_mgr *clk_mgr_base); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h index 53f6286b2fd6..6e189b1283aa 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h @@ -202,6 +202,10 @@ static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_cl return ((safe_to_lower && calc_clk < cur_clk) || calc_clk > cur_clk); } +int clk_mgr_helper_get_active_display_cnt( + struct dc *dc, + struct dc_state *context); + #endif //__DAL_CLK_MGR_INTERNAL_H__