[PATCH 10/13] clk: qcom: dispcc-sm8750: Add support to control MDP clocks using CESTA

Jagadeesh Kona
2026-04-20T16:30:47Z

Add support to control the DISPCC MDSS MDP RCG and the associated display
PLL0 using display CESTA hardware on SM8750 platform. If display CRM is
enabled, the clock ops of these clocks will be updated by the common code
before registration to use CRM specific clock ops, allowing these clocks
to be controlled using display CRM (CESTA Resource Manager) hardware.

Co-developed-by: Taniya Das <taniya.das@oss.qualcomm.com>
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
Signed-off-by: Jagadeesh Kona <jagadeesh.kona@oss.qualcomm.com>
---
drivers/clk/qcom/dispcc-sm8750.c | 89 +++++++++++++++++++++++++---------------
1 file changed, 56 insertions(+), 33 deletions(-)

diff --git a/drivers/clk/qcom/dispcc-sm8750.c b/drivers/clk/qcom/dispcc-sm8750.c
index ca09da111a50e811481fd862b54d454de024d1c9..328e43b52192702dbbfd1ed65737520acdd4a649 100644
--- a/drivers/clk/qcom/dispcc-sm8750.c
+++ b/drivers/clk/qcom/dispcc-sm8750.c
@@ -71,6 +71,16 @@ enum {
P_SLEEP_CLK,
};

+static struct clk_crm disp_crm = {
+ .max_perf_ol = 10,
+ .regs = {
+ .reg_cfg_rcgr_lut_base = 0xd8,
+ .reg_l_val_lut_base = 0xdc,
+ .vcd_offset = 0x268,
+ .lut_level_offset = 0x28,
+ },
+};
+
static const struct pll_vco pongo_elu_vco[] = {
{ 38400000, 38400000, 0 },
};
@@ -89,21 +99,22 @@ static struct alpha_pll_config disp_cc_pll0_config = {
.user_ctl_hi_val = 0x00000002,
};

+static struct clk_init_data disp_cc_pll0_init = {
+ .name = "disp_cc_pll0",
+ .parent_data = &(const struct clk_parent_data) {
+ .index = DT_BI_TCXO,
+ },
+ .num_parents = 1,
+ .flags = CLK_GET_RATE_NOCACHE,
+ .ops = &clk_alpha_pll_taycan_elu_ops,
+};
+
static struct clk_alpha_pll disp_cc_pll0 = {
.offset = 0x0,
.vco_table = taycan_elu_vco,
.num_vco = ARRAY_SIZE(taycan_elu_vco),
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU],
- .clkr = {
- .hw.init = &(const struct clk_init_data) {
- .name = "disp_cc_pll0",
- .parent_data = &(const struct clk_parent_data) {
- .index = DT_BI_TCXO,
- },
- .num_parents = 1,
- .ops = &clk_alpha_pll_taycan_elu_ops,
- },
- },
+ .clkr.hw.init = &disp_cc_pll0_init,
};

static struct alpha_pll_config disp_cc_pll1_config = {
@@ -681,25 +692,25 @@ static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
{ }
};

-static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
- .cmd_rcgr = 0x8150,
- .mnd_width = 0,
- .hid_width = 5,
- .parent_map = disp_cc_parent_map_9,
- .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
- .clkr.hw.init = &(const struct clk_init_data) {
- .name = "disp_cc_mdss_mdp_clk_src",
- .parent_data = disp_cc_parent_data_9,
- .num_parents = ARRAY_SIZE(disp_cc_parent_data_9),
- .flags = CLK_SET_RATE_PARENT,
- /*
- * TODO: Downstream does not manage the clock directly, but
- * places votes via new hardware block called "cesta".
- * It is not clear whether such approach should be taken instead
- * of manual control.
- */
- .ops = &clk_rcg2_shared_ops,
+static struct clk_init_data disp_cc_mdss_mdp_clk_src_init = {
+ .name = "disp_cc_mdss_mdp_clk_src",
+ .parent_data = disp_cc_parent_data_9,
+ .num_parents = ARRAY_SIZE(disp_cc_parent_data_9),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2_crm disp_cc_mdss_mdp_clk_src = {
+ .rcg = {
+ .cmd_rcgr = 0x8150,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = disp_cc_parent_map_9,
+ .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
+ .clkr.hw.init = &disp_cc_mdss_mdp_clk_src_init,
},
+ .crm_vcd = 1,
+ .crm = &disp_crm,
};

static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
@@ -1562,7 +1573,7 @@ static struct clk_branch disp_cc_mdss_mdp1_clk = {
.hw.init = &(const struct clk_init_data) {
.name = "disp_cc_mdss_mdp1_clk",
.parent_hws = (const struct clk_hw*[]) {
- &disp_cc_mdss_mdp_clk_src.clkr.hw,
+ &disp_cc_mdss_mdp_clk_src.rcg.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1580,7 +1591,7 @@ static struct clk_branch disp_cc_mdss_mdp_clk = {
.hw.init = &(const struct clk_init_data) {
.name = "disp_cc_mdss_mdp_clk",
.parent_hws = (const struct clk_hw*[]) {
- &disp_cc_mdss_mdp_clk_src.clkr.hw,
+ &disp_cc_mdss_mdp_clk_src.rcg.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1598,7 +1609,7 @@ static struct clk_branch disp_cc_mdss_mdp_lut1_clk = {
.hw.init = &(const struct clk_init_data) {
.name = "disp_cc_mdss_mdp_lut1_clk",
.parent_hws = (const struct clk_hw*[]) {
- &disp_cc_mdss_mdp_clk_src.clkr.hw,
+ &disp_cc_mdss_mdp_clk_src.rcg.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1616,7 +1627,7 @@ static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
.hw.init = &(const struct clk_init_data) {
.name = "disp_cc_mdss_mdp_lut_clk",
.parent_hws = (const struct clk_hw*[]) {
- &disp_cc_mdss_mdp_clk_src.clkr.hw,
+ &disp_cc_mdss_mdp_clk_src.rcg.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1844,7 +1855,7 @@ static struct clk_regmap *disp_cc_sm8750_clocks[] = {
[DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr,
[DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr,
[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
- [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
+ [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.rcg.clkr,
[DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr,
[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
[DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
@@ -1866,6 +1877,11 @@ static struct clk_regmap *disp_cc_sm8750_clocks[] = {
[DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr,
};

+static const struct crm_clk_data disp_cc_sm8750_crm_clks[] = {
+ CRM_CLK_PLL(disp_cc_pll0),
+ CRM_CLK_RCG_CRMB(disp_cc_mdss_mdp_clk_src),
+};
+
static const struct qcom_reset_map disp_cc_sm8750_resets[] = {
[DISP_CC_MDSS_CORE_BCR] = { 0x8000 },
[DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 },
@@ -1885,6 +1901,12 @@ static const struct regmap_config disp_cc_sm8750_regmap_config = {
.fast_io = true,
};

+static struct qcom_cc_driver_data disp_cc_sm8750_driver_data = {
+ .crm = &disp_crm,
+ .crm_clks = disp_cc_sm8750_crm_clks,
+ .num_crm_clks = ARRAY_SIZE(disp_cc_sm8750_crm_clks),
+};
+
static const struct qcom_cc_desc disp_cc_sm8750_desc = {
.config = &disp_cc_sm8750_regmap_config,
.clks = disp_cc_sm8750_clocks,
@@ -1893,6 +1915,7 @@ static const struct qcom_cc_desc disp_cc_sm8750_desc = {
.num_resets = ARRAY_SIZE(disp_cc_sm8750_resets),
.gdscs = disp_cc_sm8750_gdscs,
.num_gdscs = ARRAY_SIZE(disp_cc_sm8750_gdscs),
+ .driver_data = &disp_cc_sm8750_driver_data,
};

static const struct of_device_id disp_cc_sm8750_match_table[] = {

--
2.34.1