From 64a905203fd0da3e8a3f649593cc48c9fbab25d0 Mon Sep 17 00:00:00 2001 From: Hansen Dsouza Date: Tue, 23 Jul 2024 00:26:19 -0400 Subject: [PATCH] drm/amd/display: Add stream and char control callback [why & how] Add new stream and char control functions based on DCCG spec Reviewed-by: Muhammad Ahmed Signed-off-by: Hansen Dsouza Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../amd/display/dc/dccg/dcn35/dcn35_dccg.c | 132 ++++++++++++++++-- 1 file changed, 122 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c index bd3757de51c9..13e3d64ee2f0 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c @@ -896,7 +896,7 @@ static void dccg35_disable_symclk32_le_new( dccg35_set_symclk32_le_rcg(dccg, inst, true); } -static void dccg35_enable_dpp_new( +static void dccg35_enable_dpp_clk_new( struct dccg *dccg, int inst, enum dppclk_clock_source src) @@ -915,7 +915,7 @@ static void dccg35_enable_dpp_new( DPPCLK0_DTO_MODULO, 0xFF); } -static void dccg35_disable_dpp_new( +static void dccg35_disable_dpp_clk_new( struct dccg *dccg, int inst) { @@ -956,27 +956,25 @@ static void dccg35_enable_dtbclk_p_new(struct dccg *dccg, } static void dccg35_disable_dtbclk_p_new(struct dccg *dccg, - enum dtbclk_source src, int inst) { dccg35_set_dtbclk_p_src_new(dccg, DTBCLK_REFCLK, inst); dccg35_set_dtbclk_p_rcg(dccg, inst, true); } -static void dccg35_enable_dpstreamclk_new(struct dccg *dccg, - enum dtbclk_source src, +static void dccg35_disable_dpstreamclk_new(struct dccg *dccg, int inst) { dccg35_set_dpstreamclk_src_new(dccg, DP_STREAM_REFCLK, inst); dccg35_set_dpstreamclk_rcg(dccg, inst, true); } -static void dccg35_disable_dpstreamclk_new(struct dccg *dccg, - enum dtbclk_source src, +static void dccg35_enable_dpstreamclk_new(struct dccg *dccg, + enum dp_stream_clk_source src, int inst) { dccg35_set_dpstreamclk_rcg(dccg, inst, false); - dccg35_set_dtbclk_p_src_new(dccg, src, inst); + dccg35_set_dpstreamclk_src_new(dccg, src, inst); } static void dccg35_trigger_dio_fifo_resync(struct dccg *dccg) @@ -1935,6 +1933,114 @@ static void dccg35_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst } } +static void dccg35_set_dpstreamclk_cb( + struct dccg *dccg, + enum streamclk_source src, + int otg_inst, + int dp_hpo_inst) +{ + + enum dtbclk_source dtb_clk_src; + enum dp_stream_clk_source dp_stream_clk_src; + + ASSERT(otg_inst >= DP_STREAM_DTBCLK_P5); + + switch (src) { + case REFCLK: + dtb_clk_src = DTBCLK_REFCLK; + dp_stream_clk_src = DP_STREAM_REFCLK; + break; + case DPREFCLK: + dtb_clk_src = DTBCLK_DPREFCLK; + dp_stream_clk_src = (enum dp_stream_clk_source)otg_inst; + break; + case DTBCLK0: + dtb_clk_src = DTBCLK_DTBCLK0; + dp_stream_clk_src = (enum dp_stream_clk_source)otg_inst; + break; + default: + BREAK_TO_DEBUGGER(); + return; + } + + if (dtb_clk_src == DTBCLK_REFCLK && + dp_stream_clk_src == DP_STREAM_REFCLK) { + dccg35_disable_dtbclk_p_new(dccg, otg_inst); + dccg35_disable_dpstreamclk_new(dccg, dp_hpo_inst); + } else { + dccg35_enable_dtbclk_p_new(dccg, dtb_clk_src, otg_inst); + dccg35_enable_dpstreamclk_new(dccg, + dp_stream_clk_src, + dp_hpo_inst); + } +} + +static void dccg35_set_dpstreamclk_root_clock_gating_cb( + struct dccg *dccg, + int dp_hpo_inst, + bool power_on) +{ + /* power_on set indicates we need to ungate + * Currently called from optimize_bandwidth and prepare_bandwidth calls + * Since clock source is not passed restore to refclock on ungate + * Instance 0 is implied here since only one streamclock resource + * Redundant as gating when enabled is acheived through set_dpstreamclk + */ + if (power_on) + dccg35_enable_dpstreamclk_new(dccg, + DP_STREAM_REFCLK, + dp_hpo_inst); + else + dccg35_disable_dpstreamclk_new(dccg, dp_hpo_inst); +} + +static void dccg35_update_dpp_dto_cb(struct dccg *dccg, int dpp_inst, + int req_dppclk) +{ + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + if (dccg->ref_dppclk && req_dppclk) { + int ref_dppclk = dccg->ref_dppclk; + int modulo, phase; + + // phase / modulo = dpp pipe clk / dpp global clk + modulo = 0xff; // use FF at the end + phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk; + + if (phase > 0xff) { + ASSERT(false); + phase = 0xff; + } + + /* Enable DPP CLK DTO output */ + dccg35_enable_dpp_clk_new(dccg, dpp_inst, DPP_DCCG_DTO); + + /* Program DTO */ + REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, + DPPCLK0_DTO_PHASE, phase, + DPPCLK0_DTO_MODULO, modulo); + } else + dccg35_disable_dpp_clk_new(dccg, dpp_inst); + + dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk; +} + +static void dccg35_dpp_root_clock_control_cb( + struct dccg *dccg, + unsigned int dpp_inst, + bool power_on) +{ + /* power_on set indicates we need to ungate + * Currently called from optimize_bandwidth and prepare_bandwidth calls + * Since clock source is not passed restore to refclock on ungate + * Redundant as gating when enabled is acheived through update_dpp_dto + */ + if (power_on) + dccg35_enable_dpp_clk_new(dccg, dpp_inst, DPP_REFCLK); + else + dccg35_disable_dpp_clk_new(dccg, dpp_inst); +} + static const struct dccg_funcs dccg35_funcs = { .update_dpp_dto = dccg35_update_dpp_dto, .dpp_root_clock_control = dccg35_dpp_root_clock_control, @@ -2010,14 +2116,20 @@ struct dccg *dccg35_create( (void)&dccg35_disable_symclk32_se_new; (void)&dccg35_enable_symclk32_le_new; (void)&dccg35_disable_symclk32_le_new; - (void)&dccg35_enable_dpp_new; - (void)&dccg35_disable_dpp_new; + (void)&dccg35_enable_dpp_clk_new; + (void)&dccg35_enable_dpp_clk_new; (void)&dccg35_disable_dscclk_new; (void)&dccg35_enable_dscclk_new; (void)&dccg35_enable_dtbclk_p_new; (void)&dccg35_disable_dtbclk_p_new; (void)&dccg35_enable_dpstreamclk_new; (void)&dccg35_disable_dpstreamclk_new; + (void)&dccg35_set_dpstreamclk_cb; + (void)&dccg35_dpp_root_clock_control_cb; + (void)&dccg35_set_dpstreamclk_root_clock_gating_cb; + (void)&dccg35_update_dpp_dto_cb; + (void)&dccg35_dpp_root_clock_control_cb; + base = &dccg_dcn->base; base->ctx = ctx; base->funcs = &dccg35_funcs;