diff options
-rw-r--r-- | drivers/clk/qcom/common.c | 44 | ||||
-rw-r--r-- | drivers/clk/qcom/common.h | 9 |
2 files changed, 53 insertions, 0 deletions
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 9cbf1c5296da..b3838d885db2 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -14,6 +14,8 @@ #include <linux/of.h> #include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" #include "clk-rcg.h" #include "clk-regmap.h" #include "reset.h" @@ -285,6 +287,40 @@ static int qcom_cc_icc_register(struct device *dev, desc->num_icc_hws, icd); } +static int qcom_cc_clk_pll_configure(const struct qcom_cc_driver_data *data, + struct regmap *regmap) +{ + const struct clk_init_data *init; + struct clk_alpha_pll *pll; + int i; + + for (i = 0; i < data->num_alpha_plls; i++) { + pll = data->alpha_plls[i]; + init = pll->clkr.hw.init; + + if (!pll->config || !pll->regs) { + pr_err("%s: missing pll config or regs\n", init->name); + return -EINVAL; + } + + qcom_clk_alpha_pll_configure(pll, regmap); + } + + return 0; +} + +static void qcom_cc_clk_regs_configure(struct device *dev, const struct qcom_cc_driver_data *data, + struct regmap *regmap) +{ + int i; + + for (i = 0; i < data->num_clk_cbcrs; i++) + qcom_branch_set_clk_en(regmap, data->clk_cbcrs[i]); + + if (data->clk_regs_configure) + data->clk_regs_configure(dev, regmap); +} + int qcom_cc_really_probe(struct device *dev, const struct qcom_cc_desc *desc, struct regmap *regmap) { @@ -315,6 +351,14 @@ int qcom_cc_really_probe(struct device *dev, return ret; } + if (desc->driver_data) { + ret = qcom_cc_clk_pll_configure(desc->driver_data, regmap); + if (ret) + goto put_rpm; + + qcom_cc_clk_regs_configure(dev, desc->driver_data, regmap); + } + reset = &cc->reset; reset->rcdev.of_node = dev->of_node; reset->rcdev.ops = &qcom_reset_ops; diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h index 9c10bc8c197c..0f4b2d40c65c 100644 --- a/drivers/clk/qcom/common.h +++ b/drivers/clk/qcom/common.h @@ -25,6 +25,14 @@ struct qcom_icc_hws_data { int clk_id; }; +struct qcom_cc_driver_data { + struct clk_alpha_pll **alpha_plls; + size_t num_alpha_plls; + u32 *clk_cbcrs; + size_t num_clk_cbcrs; + void (*clk_regs_configure)(struct device *dev, struct regmap *regmap); +}; + struct qcom_cc_desc { const struct regmap_config *config; struct clk_regmap **clks; @@ -39,6 +47,7 @@ struct qcom_cc_desc { size_t num_icc_hws; unsigned int icc_first_node_id; bool use_rpm; + struct qcom_cc_driver_data *driver_data; }; /** |