1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
6 #include <linux/export.h>
7 #include <linux/module.h>
8 #include <linux/regmap.h>
9 #include <linux/platform_device.h>
10 #include <linux/clk-provider.h>
11 #include <linux/interconnect-clk.h>
12 #include <linux/reset-controller.h>
17 #include "clk-regmap.h"
22 struct qcom_reset_controller reset
;
23 struct clk_regmap
**rclks
;
28 struct freq_tbl
*qcom_find_freq(const struct freq_tbl
*f
, unsigned long rate
)
40 /* Default to our fastest rate */
43 EXPORT_SYMBOL_GPL(qcom_find_freq
);
45 const struct freq_multi_tbl
*qcom_find_freq_multi(const struct freq_multi_tbl
*f
,
58 /* Default to our fastest rate */
61 EXPORT_SYMBOL_GPL(qcom_find_freq_multi
);
63 const struct freq_tbl
*qcom_find_freq_floor(const struct freq_tbl
*f
,
66 const struct freq_tbl
*best
= NULL
;
68 for ( ; f
->freq
; f
++) {
77 EXPORT_SYMBOL_GPL(qcom_find_freq_floor
);
79 int qcom_find_src_index(struct clk_hw
*hw
, const struct parent_map
*map
, u8 src
)
81 int i
, num_parents
= clk_hw_get_num_parents(hw
);
83 for (i
= 0; i
< num_parents
; i
++)
84 if (src
== map
[i
].src
)
89 EXPORT_SYMBOL_GPL(qcom_find_src_index
);
91 int qcom_find_cfg_index(struct clk_hw
*hw
, const struct parent_map
*map
, u8 cfg
)
93 int i
, num_parents
= clk_hw_get_num_parents(hw
);
95 for (i
= 0; i
< num_parents
; i
++)
96 if (cfg
== map
[i
].cfg
)
101 EXPORT_SYMBOL_GPL(qcom_find_cfg_index
);
104 qcom_cc_map(struct platform_device
*pdev
, const struct qcom_cc_desc
*desc
)
107 struct device
*dev
= &pdev
->dev
;
109 base
= devm_platform_ioremap_resource(pdev
, 0);
111 return ERR_CAST(base
);
113 return devm_regmap_init_mmio(dev
, base
, desc
->config
);
115 EXPORT_SYMBOL_GPL(qcom_cc_map
);
118 qcom_pll_set_fsm_mode(struct regmap
*map
, u32 reg
, u8 bias_count
, u8 lock_count
)
123 /* De-assert reset to FSM */
124 regmap_update_bits(map
, reg
, PLL_VOTE_FSM_RESET
, 0);
126 /* Program bias count and lock count */
127 val
= bias_count
<< PLL_BIAS_COUNT_SHIFT
|
128 lock_count
<< PLL_LOCK_COUNT_SHIFT
;
129 mask
= PLL_BIAS_COUNT_MASK
<< PLL_BIAS_COUNT_SHIFT
;
130 mask
|= PLL_LOCK_COUNT_MASK
<< PLL_LOCK_COUNT_SHIFT
;
131 regmap_update_bits(map
, reg
, mask
, val
);
133 /* Enable PLL FSM voting */
134 regmap_update_bits(map
, reg
, PLL_VOTE_FSM_ENA
, PLL_VOTE_FSM_ENA
);
136 EXPORT_SYMBOL_GPL(qcom_pll_set_fsm_mode
);
138 static void qcom_cc_gdsc_unregister(void *data
)
140 gdsc_unregister(data
);
144 * Backwards compatibility with old DTs. Register a pass-through factor 1/1
145 * clock to translate 'path' clk into 'name' clk and register the 'path'
146 * clk as a fixed rate clock if it isn't present.
148 static int _qcom_cc_register_board_clk(struct device
*dev
, const char *path
,
149 const char *name
, unsigned long rate
,
152 struct device_node
*node
= NULL
;
153 struct device_node
*clocks_node
;
154 struct clk_fixed_factor
*factor
;
155 struct clk_fixed_rate
*fixed
;
156 struct clk_init_data init_data
= { };
159 clocks_node
= of_find_node_by_path("/clocks");
161 node
= of_get_child_by_name(clocks_node
, path
);
162 of_node_put(clocks_node
);
166 fixed
= devm_kzalloc(dev
, sizeof(*fixed
), GFP_KERNEL
);
170 fixed
->fixed_rate
= rate
;
171 fixed
->hw
.init
= &init_data
;
173 init_data
.name
= path
;
174 init_data
.ops
= &clk_fixed_rate_ops
;
176 ret
= devm_clk_hw_register(dev
, &fixed
->hw
);
183 factor
= devm_kzalloc(dev
, sizeof(*factor
), GFP_KERNEL
);
187 factor
->mult
= factor
->div
= 1;
188 factor
->hw
.init
= &init_data
;
190 init_data
.name
= name
;
191 init_data
.parent_names
= &path
;
192 init_data
.num_parents
= 1;
194 init_data
.ops
= &clk_fixed_factor_ops
;
196 ret
= devm_clk_hw_register(dev
, &factor
->hw
);
204 int qcom_cc_register_board_clk(struct device
*dev
, const char *path
,
205 const char *name
, unsigned long rate
)
207 bool add_factor
= true;
210 * TODO: The RPM clock driver currently does not support the xo clock.
211 * When xo is added to the RPM clock driver, we should change this
212 * function to skip registration of xo factor clocks.
215 return _qcom_cc_register_board_clk(dev
, path
, name
, rate
, add_factor
);
217 EXPORT_SYMBOL_GPL(qcom_cc_register_board_clk
);
219 int qcom_cc_register_sleep_clk(struct device
*dev
)
221 return _qcom_cc_register_board_clk(dev
, "sleep_clk", "sleep_clk_src",
224 EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk
);
226 /* Drop 'protected-clocks' from the list of clocks to register */
227 static void qcom_cc_drop_protected(struct device
*dev
, struct qcom_cc
*cc
)
229 struct device_node
*np
= dev
->of_node
;
232 of_property_for_each_u32(np
, "protected-clocks", i
) {
233 if (i
>= cc
->num_rclks
)
240 static struct clk_hw
*qcom_cc_clk_hw_get(struct of_phandle_args
*clkspec
,
243 struct qcom_cc
*cc
= data
;
244 unsigned int idx
= clkspec
->args
[0];
246 if (idx
>= cc
->num_rclks
) {
247 pr_err("%s: invalid index %u\n", __func__
, idx
);
248 return ERR_PTR(-EINVAL
);
251 return cc
->rclks
[idx
] ? &cc
->rclks
[idx
]->hw
: NULL
;
254 static int qcom_cc_icc_register(struct device
*dev
,
255 const struct qcom_cc_desc
*desc
)
257 struct icc_clk_data
*icd
;
261 if (!IS_ENABLED(CONFIG_INTERCONNECT_CLK
))
267 icd
= devm_kcalloc(dev
, desc
->num_icc_hws
, sizeof(*icd
), GFP_KERNEL
);
271 for (i
= 0; i
< desc
->num_icc_hws
; i
++) {
272 icd
[i
].master_id
= desc
->icc_hws
[i
].master_id
;
273 icd
[i
].slave_id
= desc
->icc_hws
[i
].slave_id
;
274 hws
= &desc
->clks
[desc
->icc_hws
[i
].clk_id
]->hw
;
275 icd
[i
].clk
= devm_clk_hw_get_clk(dev
, hws
, "icc");
277 return dev_err_probe(dev
, -ENOENT
,
278 "(%d) clock entry is null\n", i
);
279 icd
[i
].name
= clk_hw_get_name(hws
);
282 return devm_icc_clk_register(dev
, desc
->icc_first_node_id
,
283 desc
->num_icc_hws
, icd
);
286 int qcom_cc_really_probe(struct device
*dev
,
287 const struct qcom_cc_desc
*desc
, struct regmap
*regmap
)
290 struct qcom_reset_controller
*reset
;
292 struct gdsc_desc
*scd
;
293 size_t num_clks
= desc
->num_clks
;
294 struct clk_regmap
**rclks
= desc
->clks
;
295 size_t num_clk_hws
= desc
->num_clk_hws
;
296 struct clk_hw
**clk_hws
= desc
->clk_hws
;
298 cc
= devm_kzalloc(dev
, sizeof(*cc
), GFP_KERNEL
);
303 reset
->rcdev
.of_node
= dev
->of_node
;
304 reset
->rcdev
.ops
= &qcom_reset_ops
;
305 reset
->rcdev
.owner
= dev
->driver
->owner
;
306 reset
->rcdev
.nr_resets
= desc
->num_resets
;
307 reset
->regmap
= regmap
;
308 reset
->reset_map
= desc
->resets
;
310 ret
= devm_reset_controller_register(dev
, &reset
->rcdev
);
314 if (desc
->gdscs
&& desc
->num_gdscs
) {
315 scd
= devm_kzalloc(dev
, sizeof(*scd
), GFP_KERNEL
);
319 scd
->scs
= desc
->gdscs
;
320 scd
->num
= desc
->num_gdscs
;
321 ret
= gdsc_register(scd
, &reset
->rcdev
, regmap
);
324 ret
= devm_add_action_or_reset(dev
, qcom_cc_gdsc_unregister
,
331 cc
->num_rclks
= num_clks
;
333 qcom_cc_drop_protected(dev
, cc
);
335 for (i
= 0; i
< num_clk_hws
; i
++) {
336 ret
= devm_clk_hw_register(dev
, clk_hws
[i
]);
341 for (i
= 0; i
< num_clks
; i
++) {
345 ret
= devm_clk_register_regmap(dev
, rclks
[i
]);
350 ret
= devm_of_clk_add_hw_provider(dev
, qcom_cc_clk_hw_get
, cc
);
354 return qcom_cc_icc_register(dev
, desc
);
356 EXPORT_SYMBOL_GPL(qcom_cc_really_probe
);
358 int qcom_cc_probe(struct platform_device
*pdev
, const struct qcom_cc_desc
*desc
)
360 struct regmap
*regmap
;
362 regmap
= qcom_cc_map(pdev
, desc
);
364 return PTR_ERR(regmap
);
366 return qcom_cc_really_probe(&pdev
->dev
, desc
, regmap
);
368 EXPORT_SYMBOL_GPL(qcom_cc_probe
);
370 int qcom_cc_probe_by_index(struct platform_device
*pdev
, int index
,
371 const struct qcom_cc_desc
*desc
)
373 struct regmap
*regmap
;
376 base
= devm_platform_ioremap_resource(pdev
, index
);
380 regmap
= devm_regmap_init_mmio(&pdev
->dev
, base
, desc
->config
);
382 return PTR_ERR(regmap
);
384 return qcom_cc_really_probe(&pdev
->dev
, desc
, regmap
);
386 EXPORT_SYMBOL_GPL(qcom_cc_probe_by_index
);
388 MODULE_LICENSE("GPL v2");
389 MODULE_DESCRIPTION("QTI Common Clock module");