1 From 8737ec830ee32162858af7c1504169b05b313ab1 Mon Sep 17 00:00:00 2001
2 From: Varadarajan Narayanan <quic_varada@quicinc.com>
3 Date: Tue, 30 Apr 2024 12:12:12 +0530
4 Subject: [PATCH] clk: qcom: common: Add interconnect clocks support
6 Unlike MSM platforms that manage NoC related clocks and scaling
7 from RPM, IPQ SoCs dont involve RPM in managing NoC related
8 clocks and there is no NoC scaling.
10 However, there is a requirement to enable some NoC interface
11 clocks for accessing the peripheral controllers present on
12 these NoCs. Though exposing these as normal clocks would work,
13 having a minimalistic interconnect driver to handle these clocks
14 would make it consistent with other Qualcomm platforms resulting
15 in common code paths. This is similar to msm8996-cbf's usage of
18 Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
19 Link: https://lore.kernel.org/r/20240430064214.2030013-5-quic_varada@quicinc.com
20 Signed-off-by: Bjorn Andersson <andersson@kernel.org>
22 drivers/clk/qcom/common.c | 35 ++++++++++++++++++++++++++++++++++-
23 drivers/clk/qcom/common.h | 9 +++++++++
24 2 files changed, 43 insertions(+), 1 deletion(-)
26 diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
27 index c92e10c60322..ea3788ba46f7 100644
28 --- a/drivers/clk/qcom/common.c
29 +++ b/drivers/clk/qcom/common.c
31 #include <linux/regmap.h>
32 #include <linux/platform_device.h>
33 #include <linux/clk-provider.h>
34 +#include <linux/interconnect-clk.h>
35 #include <linux/reset-controller.h>
38 @@ -252,6 +253,38 @@ static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec,
39 return cc->rclks[idx] ? &cc->rclks[idx]->hw : NULL;
42 +static int qcom_cc_icc_register(struct device *dev,
43 + const struct qcom_cc_desc *desc)
45 + struct icc_clk_data *icd;
49 + if (!IS_ENABLED(CONFIG_INTERCONNECT_CLK))
55 + icd = devm_kcalloc(dev, desc->num_icc_hws, sizeof(*icd), GFP_KERNEL);
59 + for (i = 0; i < desc->num_icc_hws; i++) {
60 + icd[i].master_id = desc->icc_hws[i].master_id;
61 + icd[i].slave_id = desc->icc_hws[i].slave_id;
62 + hws = &desc->clks[desc->icc_hws[i].clk_id]->hw;
63 + icd[i].clk = devm_clk_hw_get_clk(dev, hws, "icc");
65 + return dev_err_probe(dev, -ENOENT,
66 + "(%d) clock entry is null\n", i);
67 + icd[i].name = clk_hw_get_name(hws);
70 + return devm_icc_clk_register(dev, desc->icc_first_node_id,
71 + desc->num_icc_hws, icd);
74 int qcom_cc_really_probe(struct device *dev,
75 const struct qcom_cc_desc *desc, struct regmap *regmap)
77 @@ -320,7 +353,7 @@ int qcom_cc_really_probe(struct device *dev,
82 + return qcom_cc_icc_register(dev, desc);
84 EXPORT_SYMBOL_GPL(qcom_cc_really_probe);
86 diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h
87 index d048bdeeba10..7e57f8fe8ea6 100644
88 --- a/drivers/clk/qcom/common.h
89 +++ b/drivers/clk/qcom/common.h
90 @@ -19,6 +19,12 @@ struct clk_hw;
91 #define PLL_VOTE_FSM_ENA BIT(20)
92 #define PLL_VOTE_FSM_RESET BIT(21)
94 +struct qcom_icc_hws_data {
100 struct qcom_cc_desc {
101 const struct regmap_config *config;
102 struct clk_regmap **clks;
103 @@ -29,6 +35,9 @@ struct qcom_cc_desc {
105 struct clk_hw **clk_hws;
107 + struct qcom_icc_hws_data *icc_hws;
108 + size_t num_icc_hws;
109 + unsigned int icc_first_node_id;