From 925f566cb7aedbcf26005035cf894ec824e8ca2f Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Thu, 27 Jun 2019 18:16:21 -0400 Subject: [PATCH] drm/amd/display: add set and get clock for testing purposes add dc_set_clock add dc_get_clock this is for testing and diagnostics to get/set DPPCLK and DISPCLK. Signed-off-by: Charlene Liu Reviewed-by: Dmytro Laktyushkin Acked-by: Leo Li Signed-off-by: Alex Deucher --- .../amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c | 23 +++++++++- .../amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h | 5 ++ drivers/gpu/drm/amd/display/dc/core/dc.c | 11 +++++ drivers/gpu/drm/amd/display/dc/dc.h | 5 ++ drivers/gpu/drm/amd/display/dc/dc_types.h | 13 ++++++ .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 53 +++++++++++++++++++++- .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 5 ++ drivers/gpu/drm/amd/display/dc/inc/core_status.h | 3 ++ drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h | 7 +++ drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | 9 ++++ 10 files changed, 132 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c index e9a7a7af11df..9a873e2b3736 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c @@ -316,11 +316,32 @@ void dcn2_enable_pme_wa(struct clk_mgr *clk_mgr_base) } } +void dcn2_get_clock(struct clk_mgr *clk_mgr, + struct dc_state *context, + enum dc_clock_type clock_type, + struct dc_clock_config *clock_cfg) +{ + + if (clock_type == DC_CLOCK_TYPE_DISPCLK) { + clock_cfg->max_clock_khz = context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz; + clock_cfg->min_clock_khz = DCN_MINIMUM_DISPCLK_Khz; + clock_cfg->current_clock_khz = clk_mgr->clks.dispclk_khz; + clock_cfg->bw_requirequired_clock_khz = context->bw_ctx.bw.dcn.clk.bw_dispclk_khz; + } + if (clock_type == DC_CLOCK_TYPE_DPPCLK) { + clock_cfg->max_clock_khz = context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz; + clock_cfg->min_clock_khz = DCN_MINIMUM_DPPCLK_Khz; + clock_cfg->current_clock_khz = clk_mgr->clks.dppclk_khz; + clock_cfg->bw_requirequired_clock_khz = context->bw_ctx.bw.dcn.clk.bw_dppclk_khz; + } +} + static struct clk_mgr_funcs dcn2_funcs = { .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, .update_clocks = dcn2_update_clocks, .init_clocks = dcn2_init_clocks, - .enable_pme_wa = dcn2_enable_pme_wa + .enable_pme_wa = dcn2_enable_pme_wa, + .get_clock = dcn2_get_clock, }; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h index 5661a5a89847..ac31a9787305 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h @@ -45,4 +45,9 @@ void dcn20_clk_mgr_construct(struct dc_context *ctx, uint32_t dentist_get_did_from_divider(int divider); +void dcn2_get_clock(struct clk_mgr *clk_mgr, + struct dc_state *context, + enum dc_clock_type clock_type, + struct dc_clock_config *clock_cfg); + #endif //__DCN20_CLK_MGR_H__ diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index a8516deb5ac3..c86c86c07fd9 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2431,3 +2431,14 @@ void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx info->fClock = (unsigned int)state->bw_ctx.bw.dcn.clk.fclk_khz; info->phyClock = (unsigned int)state->bw_ctx.bw.dcn.clk.phyclk_khz; } +enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping) +{ + if (dc->hwss.set_clock) + return dc->hwss.set_clock(dc, clock_type, clk_khz, stepping); + return DC_ERROR_UNEXPECTED; +} +void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg) +{ + if (dc->hwss.get_clock) + dc->hwss.get_clock(dc, clock_type, clock_cfg); +} diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index b314fd2869dd..a5b5afd48a7b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -252,7 +252,10 @@ enum wm_report_mode { struct dc_clocks { int dispclk_khz; int max_supported_dppclk_khz; + int max_supported_dispclk_khz; int dppclk_khz; + int bw_dppclk_khz; /*a copy of dppclk_khz*/ + int bw_dispclk_khz; int dcfclk_khz; int socclk_khz; int dcfclk_deep_sleep_khz; @@ -1041,6 +1044,8 @@ unsigned int dc_get_target_backlight_pwm(struct dc *dc); bool dc_is_dmcu_initialized(struct dc *dc); +enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping); +void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg); #if defined(CONFIG_DRM_AMD_DC_DSC_SUPPORT) /******************************************************************************* * DSC Interfaces diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index ce6d73d21cca..b273735b6a3e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -726,6 +726,19 @@ struct AsicStateEx { unsigned int phyClock; }; + +enum dc_clock_type { + DC_CLOCK_TYPE_DISPCLK = 0, + DC_CLOCK_TYPE_DPPCLK = 1, +}; + +struct dc_clock_config { + uint32_t max_clock_khz; + uint32_t min_clock_khz; + uint32_t bw_requirequired_clock_khz; + uint32_t current_clock_khz;/*current clock in use*/ +}; + #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT /* DSC DPCD capabilities */ union dsc_slice_caps1 { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 89c958f00e9a..29db9b2d4412 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -3069,6 +3069,56 @@ static void dcn10_send_immediate_sdp_message(struct pipe_ctx *pipe_ctx, sdp_message_size); } } +static enum dc_status dcn10_set_clock(struct dc *dc, + enum dc_clock_type clock_type, + uint32_t clk_khz, + uint32_t stepping) +{ + struct dc_state *context = dc->current_state; + struct dc_clock_config clock_cfg = {0}; + struct dc_clocks *current_clocks = &context->bw_ctx.bw.dcn.clk; + + if (dc->clk_mgr && dc->clk_mgr->funcs->get_clock) + dc->clk_mgr->funcs->get_clock(dc->clk_mgr, + context, clock_type, &clock_cfg); + + if (!dc->clk_mgr->funcs->get_clock) + return DC_FAIL_UNSUPPORTED_1; + + if (clk_khz > clock_cfg.max_clock_khz) + return DC_FAIL_CLK_EXCEED_MAX; + + if (clk_khz < clock_cfg.min_clock_khz) + return DC_FAIL_CLK_BELOW_MIN; + + if (clk_khz < clock_cfg.bw_requirequired_clock_khz) + return DC_FAIL_CLK_BELOW_CFG_REQUIRED; + + /*update internal request clock for update clock use*/ + if (clock_type == DC_CLOCK_TYPE_DISPCLK) + current_clocks->dispclk_khz = clk_khz; + else if (clock_type == DC_CLOCK_TYPE_DPPCLK) + current_clocks->dppclk_khz = clk_khz; + else + return DC_ERROR_UNEXPECTED; + + if (dc->clk_mgr && dc->clk_mgr->funcs->update_clocks) + dc->clk_mgr->funcs->update_clocks(dc->clk_mgr, + context, true); + return DC_OK; + +} + +static void dcn10_get_clock(struct dc *dc, + enum dc_clock_type clock_type, + struct dc_clock_config *clock_cfg) +{ + struct dc_state *context = dc->current_state; + + if (dc->clk_mgr && dc->clk_mgr->funcs->get_clock) + dc->clk_mgr->funcs->get_clock(dc->clk_mgr, context, clock_type, clock_cfg); + +} static const struct hw_sequencer_funcs dcn10_funcs = { .program_gamut_remap = program_gamut_remap, @@ -3123,7 +3173,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = { .enable_stream_gating = NULL, .setup_periodic_interrupt = dcn10_setup_periodic_interrupt, .setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt, - .did_underflow_occur = dcn10_did_underflow_occur + .set_clock = dcn10_set_clock, + .get_clock = dcn10_get_clock, }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index ae2545fb8ece..6ff779256729 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -2398,6 +2398,11 @@ void dcn20_calculate_dlg_params( context->res_ctx.pipe_ctx[i].pipe_dlg_param = pipes[pipe_idx].pipe.dest; pipe_idx++; } + /*save a original dppclock copy*/ + context->bw_ctx.bw.dcn.clk.bw_dppclk_khz = context->bw_ctx.bw.dcn.clk.dppclk_khz; + context->bw_ctx.bw.dcn.clk.bw_dispclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz; + context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dppclk_mhz*1000; + context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dispclk_mhz*1000; for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { bool cstate_en = context->bw_ctx.dml.vba.PrefetchMode[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != 2; diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_status.h b/drivers/gpu/drm/amd/display/dc/inc/core_status.h index 0a094d7c9380..fd39e2abe2ed 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_status.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_status.h @@ -48,6 +48,9 @@ enum dc_status { DC_NO_DSC_RESOURCE = 17, #endif DC_FAIL_UNSUPPORTED_1 = 18, + DC_FAIL_CLK_EXCEED_MAX = 21, + DC_FAIL_CLK_BELOW_MIN = 22, /*THIS IS MIN PER IP*/ + DC_FAIL_CLK_BELOW_CFG_REQUIRED = 23, /*THIS IS hard_min in PPLIB*/ DC_ERROR_UNEXPECTED = -1 }; 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 36ebd5bc7863..938bdc5c21a1 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 @@ -28,6 +28,9 @@ #include "dc.h" +#define DCN_MINIMUM_DISPCLK_Khz 100000 +#define DCN_MINIMUM_DPPCLK_Khz 100000 + /* Public interfaces */ struct clk_states { @@ -51,6 +54,10 @@ struct clk_mgr_funcs { void (*init_clocks)(struct clk_mgr *clk_mgr); void (*enable_pme_wa) (struct clk_mgr *clk_mgr); + void (*get_clock)(struct clk_mgr *clk_mgr, + struct dc_state *context, + enum dc_clock_type clock_type, + struct dc_clock_config *clock_cfg); }; struct clk_mgr { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 4d56d48a3179..36be08adae05 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -294,6 +294,15 @@ struct hw_sequencer_funcs { void (*disable_writeback)(struct dc *dc, unsigned int dwb_pipe_inst); #endif + enum dc_status (*set_clock)(struct dc *dc, + enum dc_clock_type clock_type, + uint32_t clk_khz, + uint32_t stepping); + + void (*get_clock)(struct dc *dc, + enum dc_clock_type clock_type, + struct dc_clock_config *clock_cfg); + }; void color_space_to_black_color( -- 2.11.0