Lines Matching +full:cpufreq +full:- +full:hw
1 // SPDX-License-Identifier: GPL-2.0-only
8 #include <linux/clk-provider.h>
18 struct clk_hw hw; member
23 #define to_scpi_clk(clk) container_of(clk, struct scpi_clk, hw)
27 static unsigned long scpi_clk_recalc_rate(struct clk_hw *hw, in scpi_clk_recalc_rate() argument
30 struct scpi_clk *clk = to_scpi_clk(hw); in scpi_clk_recalc_rate()
32 return clk->scpi_ops->clk_get_val(clk->id); in scpi_clk_recalc_rate()
35 static long scpi_clk_round_rate(struct clk_hw *hw, unsigned long rate, in scpi_clk_round_rate() argument
47 static int scpi_clk_set_rate(struct clk_hw *hw, unsigned long rate, in scpi_clk_set_rate() argument
50 struct scpi_clk *clk = to_scpi_clk(hw); in scpi_clk_set_rate()
52 return clk->scpi_ops->clk_set_val(clk->id, rate); in scpi_clk_set_rate()
66 const struct scpi_opp *opp = clk->info->opps; in __scpi_dvfs_round_rate()
68 for (idx = 0; idx < clk->info->count; idx++, opp++) { in __scpi_dvfs_round_rate()
69 ftmp = opp->freq; in __scpi_dvfs_round_rate()
81 static unsigned long scpi_dvfs_recalc_rate(struct clk_hw *hw, in scpi_dvfs_recalc_rate() argument
84 struct scpi_clk *clk = to_scpi_clk(hw); in scpi_dvfs_recalc_rate()
85 int idx = clk->scpi_ops->dvfs_get_idx(clk->id); in scpi_dvfs_recalc_rate()
91 opp = clk->info->opps + idx; in scpi_dvfs_recalc_rate()
92 return opp->freq; in scpi_dvfs_recalc_rate()
95 static long scpi_dvfs_round_rate(struct clk_hw *hw, unsigned long rate, in scpi_dvfs_round_rate() argument
98 struct scpi_clk *clk = to_scpi_clk(hw); in scpi_dvfs_round_rate()
105 int idx, max_opp = clk->info->count; in __scpi_find_dvfs_index()
106 const struct scpi_opp *opp = clk->info->opps; in __scpi_find_dvfs_index()
109 if (opp->freq == rate) in __scpi_find_dvfs_index()
111 return -EINVAL; in __scpi_find_dvfs_index()
114 static int scpi_dvfs_set_rate(struct clk_hw *hw, unsigned long rate, in scpi_dvfs_set_rate() argument
117 struct scpi_clk *clk = to_scpi_clk(hw); in scpi_dvfs_set_rate()
122 return clk->scpi_ops->dvfs_set_idx(clk->id, (u8)ret); in scpi_dvfs_set_rate()
132 { .compatible = "arm,scpi-dvfs-clocks", .data = &scpi_dvfs_ops, },
133 { .compatible = "arm,scpi-variable-clocks", .data = &scpi_clk_ops, },
148 init.ops = match->data; in scpi_clk_ops_init()
149 sclk->hw.init = &init; in scpi_clk_ops_init()
150 sclk->scpi_ops = get_scpi_ops(); in scpi_clk_ops_init()
153 sclk->info = sclk->scpi_ops->dvfs_get_info(sclk->id); in scpi_clk_ops_init()
154 if (IS_ERR(sclk->info)) in scpi_clk_ops_init()
155 return PTR_ERR(sclk->info); in scpi_clk_ops_init()
157 if (sclk->scpi_ops->clk_get_range(sclk->id, &min, &max) || !max) in scpi_clk_ops_init()
158 return -EINVAL; in scpi_clk_ops_init()
160 return -EINVAL; in scpi_clk_ops_init()
163 ret = devm_clk_hw_register(dev, &sclk->hw); in scpi_clk_ops_init()
165 clk_hw_set_rate_range(&sclk->hw, min, max); in scpi_clk_ops_init()
179 unsigned int idx = clkspec->args[0], count; in scpi_of_clk_src_get()
181 for (count = 0; count < clk_data->clk_num; count++) { in scpi_of_clk_src_get()
182 sclk = clk_data->clk[count]; in scpi_of_clk_src_get()
183 if (idx == sclk->id) in scpi_of_clk_src_get()
184 return &sclk->hw; in scpi_of_clk_src_get()
187 return ERR_PTR(-EINVAL); in scpi_of_clk_src_get()
196 count = of_property_count_strings(np, "clock-output-names"); in scpi_clk_add()
199 return -EINVAL; in scpi_clk_add()
204 return -ENOMEM; in scpi_clk_add()
206 clk_data->clk_num = count; in scpi_clk_add()
207 clk_data->clk = devm_kcalloc(dev, count, sizeof(*clk_data->clk), in scpi_clk_add()
209 if (!clk_data->clk) in scpi_clk_add()
210 return -ENOMEM; in scpi_clk_add()
219 return -ENOMEM; in scpi_clk_add()
221 if (of_property_read_string_index(np, "clock-output-names", in scpi_clk_add()
224 return -EINVAL; in scpi_clk_add()
227 if (of_property_read_u32_index(np, "clock-indices", in scpi_clk_add()
230 return -EINVAL; in scpi_clk_add()
233 sclk->id = val; in scpi_clk_add()
242 clk_data->clk[idx] = sclk; in scpi_clk_add()
250 struct device *dev = &pdev->dev; in scpi_clocks_remove()
251 struct device_node *child, *np = dev->of_node; in scpi_clocks_remove()
265 struct device *dev = &pdev->dev; in scpi_clocks_probe()
266 struct device_node *child, *np = dev->of_node; in scpi_clocks_probe()
270 return -ENXIO; in scpi_clocks_probe()
283 if (match->data != &scpi_dvfs_ops) in scpi_clocks_probe()
285 /* Add the virtual cpufreq device if it's DVFS clock provider */ in scpi_clocks_probe()
286 cpufreq_dev = platform_device_register_simple("scpi-cpufreq", in scpi_clocks_probe()
287 -1, NULL, 0); in scpi_clocks_probe()
289 pr_warn("unable to register cpufreq device"); in scpi_clocks_probe()
295 { .compatible = "arm,scpi-clocks", },