mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 00:22:00 +02:00
clk: qcom: common: Add support to configure clk regs in qcom_cc_really_probe
Add support to configure PLLS and clk registers in qcom_cc_really_probe(). This ensures all required power domains are enabled and kept ON by runtime PM code in qcom_cc_really_probe() before configuring the PLLS or clock registers. Add support for qcom_cc_driver_data struct to maintain the clock controllers PLLs and CBCRs data, and a pointer of it can be stored in clock descriptor structure. If any clock controller driver requires to program some additional misc register settings, it can register the clk_regs_configure() callback in the driver data. Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Signed-off-by: Jagadeesh Kona <quic_jkona@quicinc.com> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Link: https://lore.kernel.org/r/20250530-videocc-pll-multi-pd-voting-v5-6-02303b3a582d@quicinc.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
This commit is contained in:
parent
c0b6627369
commit
452ae64997
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user