Lines Matching +full:cpufreq +full:- +full:hw

1 // SPDX-License-Identifier: GPL-2.0-only
8 #include <linux/clk-provider.h>
19 struct clk_hw hw; member
24 #define to_scpi_clk(clk) container_of(clk, struct scpi_clk, hw)
28 static unsigned long scpi_clk_recalc_rate(struct clk_hw *hw, in scpi_clk_recalc_rate() argument
31 struct scpi_clk *clk = to_scpi_clk(hw); in scpi_clk_recalc_rate()
33 return clk->scpi_ops->clk_get_val(clk->id); in scpi_clk_recalc_rate()
36 static long scpi_clk_round_rate(struct clk_hw *hw, unsigned long rate, in scpi_clk_round_rate() argument
48 static int scpi_clk_set_rate(struct clk_hw *hw, unsigned long rate, in scpi_clk_set_rate() argument
51 struct scpi_clk *clk = to_scpi_clk(hw); in scpi_clk_set_rate()
53 return clk->scpi_ops->clk_set_val(clk->id, rate); in scpi_clk_set_rate()
67 const struct scpi_opp *opp = clk->info->opps; in __scpi_dvfs_round_rate()
69 for (idx = 0; idx < clk->info->count; idx++, opp++) { in __scpi_dvfs_round_rate()
70 ftmp = opp->freq; in __scpi_dvfs_round_rate()
82 static unsigned long scpi_dvfs_recalc_rate(struct clk_hw *hw, in scpi_dvfs_recalc_rate() argument
85 struct scpi_clk *clk = to_scpi_clk(hw); in scpi_dvfs_recalc_rate()
86 int idx = clk->scpi_ops->dvfs_get_idx(clk->id); in scpi_dvfs_recalc_rate()
92 opp = clk->info->opps + idx; in scpi_dvfs_recalc_rate()
93 return opp->freq; in scpi_dvfs_recalc_rate()
96 static long scpi_dvfs_round_rate(struct clk_hw *hw, unsigned long rate, in scpi_dvfs_round_rate() argument
99 struct scpi_clk *clk = to_scpi_clk(hw); in scpi_dvfs_round_rate()
106 int idx, max_opp = clk->info->count; in __scpi_find_dvfs_index()
107 const struct scpi_opp *opp = clk->info->opps; in __scpi_find_dvfs_index()
110 if (opp->freq == rate) in __scpi_find_dvfs_index()
112 return -EINVAL; in __scpi_find_dvfs_index()
115 static int scpi_dvfs_set_rate(struct clk_hw *hw, unsigned long rate, in scpi_dvfs_set_rate() argument
118 struct scpi_clk *clk = to_scpi_clk(hw); in scpi_dvfs_set_rate()
123 return clk->scpi_ops->dvfs_set_idx(clk->id, (u8)ret); in scpi_dvfs_set_rate()
133 { .compatible = "arm,scpi-dvfs-clocks", .data = &scpi_dvfs_ops, },
134 { .compatible = "arm,scpi-variable-clocks", .data = &scpi_clk_ops, },
149 init.ops = match->data; in scpi_clk_ops_init()
150 sclk->hw.init = &init; in scpi_clk_ops_init()
151 sclk->scpi_ops = get_scpi_ops(); in scpi_clk_ops_init()
154 sclk->info = sclk->scpi_ops->dvfs_get_info(sclk->id); in scpi_clk_ops_init()
155 if (IS_ERR(sclk->info)) in scpi_clk_ops_init()
156 return PTR_ERR(sclk->info); in scpi_clk_ops_init()
158 if (sclk->scpi_ops->clk_get_range(sclk->id, &min, &max) || !max) in scpi_clk_ops_init()
159 return -EINVAL; in scpi_clk_ops_init()
161 return -EINVAL; in scpi_clk_ops_init()
164 ret = devm_clk_hw_register(dev, &sclk->hw); in scpi_clk_ops_init()
166 clk_hw_set_rate_range(&sclk->hw, min, max); in scpi_clk_ops_init()
180 unsigned int idx = clkspec->args[0], count; in scpi_of_clk_src_get()
182 for (count = 0; count < clk_data->clk_num; count++) { in scpi_of_clk_src_get()
183 sclk = clk_data->clk[count]; in scpi_of_clk_src_get()
184 if (idx == sclk->id) in scpi_of_clk_src_get()
185 return &sclk->hw; in scpi_of_clk_src_get()
188 return ERR_PTR(-EINVAL); in scpi_of_clk_src_get()
197 count = of_property_count_strings(np, "clock-output-names"); in scpi_clk_add()
200 return -EINVAL; in scpi_clk_add()
205 return -ENOMEM; in scpi_clk_add()
207 clk_data->clk_num = count; in scpi_clk_add()
208 clk_data->clk = devm_kcalloc(dev, count, sizeof(*clk_data->clk), in scpi_clk_add()
210 if (!clk_data->clk) in scpi_clk_add()
211 return -ENOMEM; in scpi_clk_add()
220 return -ENOMEM; in scpi_clk_add()
222 if (of_property_read_string_index(np, "clock-output-names", in scpi_clk_add()
225 return -EINVAL; in scpi_clk_add()
228 if (of_property_read_u32_index(np, "clock-indices", in scpi_clk_add()
231 return -EINVAL; in scpi_clk_add()
234 sclk->id = val; in scpi_clk_add()
243 clk_data->clk[idx] = sclk; in scpi_clk_add()
251 struct device *dev = &pdev->dev; in scpi_clocks_remove()
252 struct device_node *child, *np = dev->of_node; in scpi_clocks_remove()
267 struct device *dev = &pdev->dev; in scpi_clocks_probe()
268 struct device_node *child, *np = dev->of_node; in scpi_clocks_probe()
272 return -ENXIO; in scpi_clocks_probe()
285 if (match->data != &scpi_dvfs_ops) in scpi_clocks_probe()
287 /* Add the virtual cpufreq device if it's DVFS clock provider */ in scpi_clocks_probe()
288 cpufreq_dev = platform_device_register_simple("scpi-cpufreq", in scpi_clocks_probe()
289 -1, NULL, 0); in scpi_clocks_probe()
291 pr_warn("unable to register cpufreq device"); in scpi_clocks_probe()
297 { .compatible = "arm,scpi-clocks", },