From f450b4de968348f83b5b2436f5c6f1e8a52bdd5b Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 23 May 2018 18:18:50 -0400 Subject: [PATCH 4766/5725] drm/amd/display: move dcn1 dispclk programming to dccg No functional change. Signed-off-by: Dmytro Laktyushkin Reviewed-by: Nikola Cornij Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c | 95 ++++++++++++++++-- drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h | 2 +- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 106 --------------------- .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 2 +- 4 files changed, 90 insertions(+), 115 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index 6b6570e..55f533cf 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -552,7 +552,85 @@ static void dce12_update_clocks(struct dccg *dccg, } } -static void dcn_update_clocks(struct dccg *dccg, +static int dcn1_determine_dppclk_threshold(struct dccg *dccg, struct dc_clocks *new_clocks) +{ + bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; + bool dispclk_increase = new_clocks->dispclk_khz > dccg->clks.dispclk_khz; + int disp_clk_threshold = new_clocks->max_supported_dppclk_khz; + bool cur_dpp_div = dccg->clks.dispclk_khz > dccg->clks.dppclk_khz; + + /* increase clock, looking for div is 0 for current, request div is 1*/ + if (dispclk_increase) { + /* already divided by 2, no need to reach target clk with 2 steps*/ + if (cur_dpp_div) + return new_clocks->dispclk_khz; + + /* request disp clk is lower than maximum supported dpp clk, + * no need to reach target clk with two steps. + */ + if (new_clocks->dispclk_khz <= disp_clk_threshold) + return new_clocks->dispclk_khz; + + /* target dpp clk not request divided by 2, still within threshold */ + if (!request_dpp_div) + return new_clocks->dispclk_khz; + + } else { + /* decrease clock, looking for current dppclk divided by 2, + * request dppclk not divided by 2. + */ + + /* current dpp clk not divided by 2, no need to ramp*/ + if (!cur_dpp_div) + return new_clocks->dispclk_khz; + + /* current disp clk is lower than current maximum dpp clk, + * no need to ramp + */ + if (dccg->clks.dispclk_khz <= disp_clk_threshold) + return new_clocks->dispclk_khz; + + /* request dpp clk need to be divided by 2 */ + if (request_dpp_div) + return new_clocks->dispclk_khz; + } + + return disp_clk_threshold; +} + +static void dcn1_ramp_up_dispclk_with_dpp(struct dccg *dccg, struct dc_clocks *new_clocks) +{ + struct dc *dc = dccg->ctx->dc; + int dispclk_to_dpp_threshold = dcn1_determine_dppclk_threshold(dccg, new_clocks); + bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; + int i; + + /* set disp clk to dpp clk threshold */ + dccg->funcs->set_dispclk(dccg, dispclk_to_dpp_threshold); + + /* update request dpp clk division option */ + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; + + if (!pipe_ctx->plane_state) + continue; + + pipe_ctx->plane_res.dpp->funcs->dpp_dppclk_control( + pipe_ctx->plane_res.dpp, + request_dpp_div, + true); + } + + /* If target clk not same as dppclk threshold, set to target clock */ + if (dispclk_to_dpp_threshold != new_clocks->dispclk_khz) + dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); + + dccg->clks.dispclk_khz = new_clocks->dispclk_khz; + dccg->clks.dppclk_khz = new_clocks->dppclk_khz; + dccg->clks.max_supported_dppclk_khz = new_clocks->max_supported_dppclk_khz; +} + +static void dcn1_update_clocks(struct dccg *dccg, struct dc_clocks *new_clocks, bool safe_to_lower) { @@ -572,6 +650,9 @@ static void dcn_update_clocks(struct dccg *dccg, send_request_to_increase = true; #ifdef CONFIG_DRM_AMD_DC_DCN1_0 + /* make sure dcf clk is before dpp clk to + * make sure we have enough voltage to run dpp clk + */ if (send_request_to_increase ) { /*use dcfclk to request voltage*/ @@ -584,8 +665,8 @@ static void dcn_update_clocks(struct dccg *dccg, if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK; clock_voltage_req.clocks_in_khz = new_clocks->dispclk_khz; - /* TODO: ramp up - dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); - dccg->clks.dispclk_khz = new_clocks->dispclk_khz;*/ + dcn1_ramp_up_dispclk_with_dpp(dccg, new_clocks); + dccg->clks.dispclk_khz = new_clocks->dispclk_khz; dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); send_request_to_lower = true; @@ -666,10 +747,10 @@ static void dce_update_clocks(struct dccg *dccg, } } -static const struct display_clock_funcs dcn_funcs = { +static const struct display_clock_funcs dcn1_funcs = { .get_dp_ref_clk_frequency = dce_clocks_get_dp_ref_freq_wrkaround, .set_dispclk = dce112_set_clock, - .update_clocks = dcn_update_clocks + .update_clocks = dcn1_update_clocks }; static const struct display_clock_funcs dce120_funcs = { @@ -838,7 +919,7 @@ struct dccg *dce120_dccg_create(struct dc_context *ctx) return &clk_dce->base; } -struct dccg *dcn_dccg_create(struct dc_context *ctx) +struct dccg *dcn1_dccg_create(struct dc_context *ctx) { struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); @@ -851,7 +932,7 @@ struct dccg *dcn_dccg_create(struct dc_context *ctx) dce_dccg_construct( clk_dce, ctx, NULL, NULL, NULL); - clk_dce->base.funcs = &dcn_funcs; + clk_dce->base.funcs = &dcn1_funcs; return &clk_dce->base; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h index c695b9c..7907c3c4 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h @@ -128,7 +128,7 @@ struct dccg *dce112_dccg_create( struct dccg *dce120_dccg_create(struct dc_context *ctx); -struct dccg *dcn_dccg_create(struct dc_context *ctx); +struct dccg *dcn1_dccg_create(struct dc_context *ctx); void dce_dccg_destroy(struct dccg **dccg); 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 2c15854..5d47b28 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 @@ -2375,101 +2375,6 @@ static void dcn10_apply_ctx_for_surface( */ } -static int determine_dppclk_threshold(struct dc *dc, struct dc_state *context) -{ - bool request_dpp_div = context->bw.dcn.clk.dispclk_khz > - context->bw.dcn.clk.dppclk_khz; - bool dispclk_increase = context->bw.dcn.clk.dispclk_khz > - dc->res_pool->dccg->clks.dispclk_khz; - int disp_clk_threshold = context->bw.dcn.clk.max_supported_dppclk_khz; - bool cur_dpp_div = dc->res_pool->dccg->clks.dispclk_khz > - dc->res_pool->dccg->clks.dppclk_khz; - - /* increase clock, looking for div is 0 for current, request div is 1*/ - if (dispclk_increase) { - /* already divided by 2, no need to reach target clk with 2 steps*/ - if (cur_dpp_div) - return context->bw.dcn.clk.dispclk_khz; - - /* request disp clk is lower than maximum supported dpp clk, - * no need to reach target clk with two steps. - */ - if (context->bw.dcn.clk.dispclk_khz <= disp_clk_threshold) - return context->bw.dcn.clk.dispclk_khz; - - /* target dpp clk not request divided by 2, still within threshold */ - if (!request_dpp_div) - return context->bw.dcn.clk.dispclk_khz; - - } else { - /* decrease clock, looking for current dppclk divided by 2, - * request dppclk not divided by 2. - */ - - /* current dpp clk not divided by 2, no need to ramp*/ - if (!cur_dpp_div) - return context->bw.dcn.clk.dispclk_khz; - - /* current disp clk is lower than current maximum dpp clk, - * no need to ramp - */ - if (dc->res_pool->dccg->clks.dispclk_khz <= disp_clk_threshold) - return context->bw.dcn.clk.dispclk_khz; - - /* request dpp clk need to be divided by 2 */ - if (request_dpp_div) - return context->bw.dcn.clk.dispclk_khz; - } - - return disp_clk_threshold; -} - -static void ramp_up_dispclk_with_dpp(struct dc *dc, struct dc_state *context) -{ - int i; - bool request_dpp_div = context->bw.dcn.clk.dispclk_khz > - context->bw.dcn.clk.dppclk_khz; - - int dispclk_to_dpp_threshold = determine_dppclk_threshold(dc, context); - - /* set disp clk to dpp clk threshold */ - dc->res_pool->dccg->funcs->set_dispclk( - dc->res_pool->dccg, - dispclk_to_dpp_threshold); - - /* update request dpp clk division option */ - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; - - if (!pipe_ctx->plane_state) - continue; - - pipe_ctx->plane_res.dpp->funcs->dpp_dppclk_control( - pipe_ctx->plane_res.dpp, - request_dpp_div, - true); - } - - /* If target clk not same as dppclk threshold, set to target clock */ - if (dispclk_to_dpp_threshold != context->bw.dcn.clk.dispclk_khz) { - dc->res_pool->dccg->funcs->set_dispclk( - dc->res_pool->dccg, - context->bw.dcn.clk.dispclk_khz); - } - - dc->res_pool->dccg->clks.dispclk_khz = - context->bw.dcn.clk.dispclk_khz; - dc->res_pool->dccg->clks.dppclk_khz = - context->bw.dcn.clk.dppclk_khz; - dc->res_pool->dccg->clks.max_supported_dppclk_khz = - context->bw.dcn.clk.max_supported_dppclk_khz; -} - -static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_clk) -{ - return ((safe_to_lower && calc_clk < cur_clk) || calc_clk > cur_clk); -} - static void dcn10_set_bandwidth( struct dc *dc, struct dc_state *context, @@ -2490,17 +2395,6 @@ static void dcn10_set_bandwidth( &context->bw.dcn.clk, decrease_allowed); - /* make sure dcf clk is before dpp clk to - * make sure we have enough voltage to run dpp clk - */ - if (should_set_clock( - decrease_allowed, - context->bw.dcn.clk.dispclk_khz, - dc->res_pool->dccg->clks.dispclk_khz)) { - - ramp_up_dispclk_with_dpp(dc, context); - } - dcn10_pplib_apply_display_requirements(dc, context); if (dc->debug.sanity_checks) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 6255e95..d885988 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1074,7 +1074,7 @@ static bool construct( } } - pool->base.dccg = dcn_dccg_create(ctx); + pool->base.dccg = dcn1_dccg_create(ctx); if (pool->base.dccg == NULL) { dm_error("DC: failed to create display clock!\n"); BREAK_TO_DEBUGGER(); -- 2.7.4