1 From 679f68410271a32f200e48b501027f68bd114d5c Mon Sep 17 00:00:00 2001
2 From: popcornmix <popcornmix@gmail.com>
3 Date: Wed, 21 Aug 2019 14:55:56 +0100
4 Subject: [PATCH] clk-raspberrypi: Also support v3d clock
6 Signed-off-by: popcornmix <popcornmix@gmail.com>
8 drivers/clk/bcm/clk-raspberrypi.c | 497 ++++++++++++++++++++++++------
9 1 file changed, 408 insertions(+), 89 deletions(-)
11 --- a/drivers/clk/bcm/clk-raspberrypi.c
12 +++ b/drivers/clk/bcm/clk-raspberrypi.c
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
18 +#include <dt-bindings/clock/bcm2835.h>
19 #include <soc/bcm2835/raspberrypi-firmware.h>
21 #define RPI_FIRMWARE_ARM_CLK_ID 0x00000003
22 +#define RPI_FIRMWARE_V3D_CLK_ID 0x00000005
24 #define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0)
25 #define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1)
28 - * Even though the firmware interface alters 'pllb' the frequencies are
29 - * provided as per 'pllb_arm'. We need to scale before passing them trough.
31 -#define RPI_FIRMWARE_PLLB_ARM_DIV_RATE 2
33 #define A2W_PLL_FRAC_BITS 20
35 +#define SOC_BCM2835 BIT(0)
36 +#define SOC_BCM2711 BIT(1)
37 +#define SOC_ALL (SOC_BCM2835 | SOC_BCM2711)
39 struct raspberrypi_clk {
41 struct rpi_firmware *firmware;
42 struct platform_device *cpufreq;
45 +typedef int (*raspberrypi_clk_register)(struct raspberrypi_clk *rpi,
49 +/* assignment helper macros for different clock types */
50 +#define _REGISTER(f, s, ...) { .clk_register = (raspberrypi_clk_register)f, \
52 + .data = __VA_ARGS__ }
53 +#define REGISTER_PLL(s, ...) _REGISTER(&raspberrypi_register_pll, \
55 + &(struct raspberrypi_pll_data) \
57 +#define REGISTER_PLL_DIV(s, ...) _REGISTER(&raspberrypi_register_pll_divider, \
59 + &(struct raspberrypi_pll_divider_data) \
61 +#define REGISTER_CLK(s, ...) _REGISTER(&raspberrypi_register_clock, \
63 + &(struct raspberrypi_clock_data) \
67 +struct raspberrypi_pll_data {
69 + const char *const *parents;
74 +struct raspberrypi_clock_data {
76 + const char *const *parents;
82 +struct raspberrypi_pll_divider_data {
84 + const char *divider_name;
86 + const char *source_pll;
93 - unsigned long min_rate;
94 - unsigned long max_rate;
95 +struct raspberrypi_clk_desc {
96 + raspberrypi_clk_register clk_register;
97 + unsigned int supported;
101 - struct clk_hw pllb;
102 - struct clk_hw *pllb_arm;
103 - struct clk_lookup *pllb_arm_lookup;
104 +struct raspberrypi_clock {
106 + struct raspberrypi_clk *rpi;
109 + const struct raspberrypi_clock_data *data;
112 +struct raspberrypi_pll {
114 + struct raspberrypi_clk *rpi;
117 + const struct raspberrypi_pll_data *data;
120 +struct raspberrypi_pll_divider {
121 + struct clk_divider div;
122 + struct raspberrypi_clk *rpi;
125 + const struct raspberrypi_pll_divider_data *data;
129 @@ -83,56 +153,49 @@ static int raspberrypi_clock_property(st
133 -static int raspberrypi_fw_pll_is_on(struct clk_hw *hw)
134 +static int raspberrypi_fw_is_on(struct raspberrypi_clk *rpi, u32 clock_id, const char *name)
136 - struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk,
141 ret = raspberrypi_clock_property(rpi->firmware,
142 RPI_FIRMWARE_GET_CLOCK_STATE,
143 - RPI_FIRMWARE_ARM_CLK_ID, &val);
148 return !!(val & RPI_FIRMWARE_STATE_ENABLE_BIT);
152 -static unsigned long raspberrypi_fw_pll_get_rate(struct clk_hw *hw,
153 - unsigned long parent_rate)
154 +static unsigned long raspberrypi_fw_get_rate(struct raspberrypi_clk *rpi,
155 + u32 clock_id, const char *name, unsigned long parent_rate)
157 - struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk,
162 ret = raspberrypi_clock_property(rpi->firmware,
163 RPI_FIRMWARE_GET_CLOCK_RATE,
164 - RPI_FIRMWARE_ARM_CLK_ID,
170 - return val * RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
171 + dev_err_ratelimited(rpi->dev, "Failed to get %s frequency: %d",
176 -static int raspberrypi_fw_pll_set_rate(struct clk_hw *hw, unsigned long rate,
177 - unsigned long parent_rate)
178 +static int raspberrypi_fw_set_rate(struct raspberrypi_clk *rpi,
179 + u32 clock_id, const char *name, u32 rate,
180 + unsigned long parent_rate)
182 - struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk,
184 - u32 new_rate = rate / RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
187 ret = raspberrypi_clock_property(rpi->firmware,
188 RPI_FIRMWARE_SET_CLOCK_RATE,
189 - RPI_FIRMWARE_ARM_CLK_ID,
194 dev_err_ratelimited(rpi->dev, "Failed to change %s frequency: %d",
195 - clk_hw_get_name(hw), ret);
200 @@ -141,16 +204,15 @@ static int raspberrypi_fw_pll_set_rate(s
201 * Sadly there is no firmware rate rounding interface. We borrowed it from
204 -static int raspberrypi_pll_determine_rate(struct clk_hw *hw,
205 +static int raspberrypi_determine_rate(struct raspberrypi_clk *rpi,
206 + u32 clock_id, const char *name, unsigned long min_rate, unsigned long max_rate,
207 struct clk_rate_request *req)
209 - struct raspberrypi_clk *rpi = container_of(hw, struct raspberrypi_clk,
214 /* We can't use req->rate directly as it would overflow */
215 - final_rate = clamp(req->rate, rpi->min_rate, rpi->max_rate);
216 + final_rate = clamp(req->rate, min_rate, max_rate);
218 div = (u64)final_rate << A2W_PLL_FRAC_BITS;
219 do_div(div, req->best_parent_rate);
220 @@ -166,6 +228,125 @@ static int raspberrypi_pll_determine_rat
224 +static int raspberrypi_fw_clock_is_on(struct clk_hw *hw)
226 + struct raspberrypi_clock *pll = container_of(hw, struct raspberrypi_clock, hw);
227 + struct raspberrypi_clk *rpi = pll->rpi;
228 + const struct raspberrypi_clock_data *data = pll->data;
230 + return raspberrypi_fw_is_on(rpi, data->clock_id, data->name);
233 +static unsigned long raspberrypi_fw_clock_get_rate(struct clk_hw *hw,
234 + unsigned long parent_rate)
236 + struct raspberrypi_clock *pll = container_of(hw, struct raspberrypi_clock, hw);
237 + struct raspberrypi_clk *rpi = pll->rpi;
238 + const struct raspberrypi_clock_data *data = pll->data;
240 + return raspberrypi_fw_get_rate(rpi, data->clock_id, data->name, parent_rate);
243 +static int raspberrypi_fw_clock_set_rate(struct clk_hw *hw, unsigned long rate,
244 + unsigned long parent_rate)
246 + struct raspberrypi_clock *pll = container_of(hw, struct raspberrypi_clock, hw);
247 + struct raspberrypi_clk *rpi = pll->rpi;
248 + const struct raspberrypi_clock_data *data = pll->data;
250 + return raspberrypi_fw_set_rate(rpi, data->clock_id, data->name, rate, parent_rate);
253 +static int raspberrypi_clock_determine_rate(struct clk_hw *hw,
254 + struct clk_rate_request *req)
256 + struct raspberrypi_clock *pll = container_of(hw, struct raspberrypi_clock, hw);
257 + struct raspberrypi_clk *rpi = pll->rpi;
258 + const struct raspberrypi_clock_data *data = pll->data;
260 + return raspberrypi_determine_rate(rpi, data->clock_id, data->name, pll->min_rate, pll->max_rate, req);
263 +static int raspberrypi_fw_pll_is_on(struct clk_hw *hw)
265 + struct raspberrypi_pll *pll = container_of(hw, struct raspberrypi_pll, hw);
266 + struct raspberrypi_clk *rpi = pll->rpi;
267 + const struct raspberrypi_pll_data *data = pll->data;
269 + return raspberrypi_fw_is_on(rpi, data->clock_id, data->name);
272 +static unsigned long raspberrypi_fw_pll_get_rate(struct clk_hw *hw,
273 + unsigned long parent_rate)
275 + struct raspberrypi_pll *pll = container_of(hw, struct raspberrypi_pll, hw);
276 + struct raspberrypi_clk *rpi = pll->rpi;
277 + const struct raspberrypi_pll_data *data = pll->data;
279 + return raspberrypi_fw_get_rate(rpi, data->clock_id, data->name, parent_rate);
282 +static int raspberrypi_fw_pll_set_rate(struct clk_hw *hw, unsigned long rate,
283 + unsigned long parent_rate)
285 + struct raspberrypi_pll *pll = container_of(hw, struct raspberrypi_pll, hw);
286 + struct raspberrypi_clk *rpi = pll->rpi;
287 + const struct raspberrypi_pll_data *data = pll->data;
289 + return raspberrypi_fw_set_rate(rpi, data->clock_id, data->name, rate, parent_rate);
292 +static int raspberrypi_pll_determine_rate(struct clk_hw *hw,
293 + struct clk_rate_request *req)
295 + struct raspberrypi_pll *pll = container_of(hw, struct raspberrypi_pll, hw);
296 + struct raspberrypi_clk *rpi = pll->rpi;
297 + const struct raspberrypi_pll_data *data = pll->data;
299 + return raspberrypi_determine_rate(rpi, data->clock_id, data->name, pll->min_rate, pll->max_rate, req);
303 +static int raspberrypi_fw_pll_div_is_on(struct clk_hw *hw)
305 + struct raspberrypi_pll_divider *pll = container_of(hw, struct raspberrypi_pll_divider, div.hw);
306 + struct raspberrypi_clk *rpi = pll->rpi;
307 + const struct raspberrypi_pll_divider_data *data = pll->data;
309 + return raspberrypi_fw_is_on(rpi, data->clock_id, data->name);
312 +static unsigned long raspberrypi_fw_pll_div_get_rate(struct clk_hw *hw,
313 + unsigned long parent_rate)
315 + struct raspberrypi_pll_divider *pll = container_of(hw, struct raspberrypi_pll_divider, div.hw);
316 + struct raspberrypi_clk *rpi = pll->rpi;
317 + const struct raspberrypi_pll_divider_data *data = pll->data;
319 + return raspberrypi_fw_get_rate(rpi, data->clock_id, data->name, parent_rate);
322 +static int raspberrypi_fw_pll_div_set_rate(struct clk_hw *hw, unsigned long rate,
323 + unsigned long parent_rate)
325 + struct raspberrypi_pll_divider *pll = container_of(hw, struct raspberrypi_pll_divider, div.hw);
326 + struct raspberrypi_clk *rpi = pll->rpi;
327 + const struct raspberrypi_pll_divider_data *data = pll->data;
329 + return raspberrypi_fw_set_rate(rpi, data->clock_id, data->name, rate, parent_rate);
332 +static int raspberrypi_pll_div_determine_rate(struct clk_hw *hw,
333 + struct clk_rate_request *req)
335 + struct raspberrypi_pll_divider *pll = container_of(hw, struct raspberrypi_pll_divider, div.hw);
336 + struct raspberrypi_clk *rpi = pll->rpi;
337 + const struct raspberrypi_pll_divider_data *data = pll->data;
339 + return raspberrypi_determine_rate(rpi, data->clock_id, data->name, pll->min_rate, pll->max_rate, req);
343 static const struct clk_ops raspberrypi_firmware_pll_clk_ops = {
344 .is_prepared = raspberrypi_fw_pll_is_on,
345 .recalc_rate = raspberrypi_fw_pll_get_rate,
346 @@ -173,87 +354,225 @@ static const struct clk_ops raspberrypi_
347 .determine_rate = raspberrypi_pll_determine_rate,
350 -static int raspberrypi_register_pllb(struct raspberrypi_clk *rpi)
351 +static const struct clk_ops raspberrypi_firmware_pll_divider_clk_ops = {
352 + .is_prepared = raspberrypi_fw_pll_div_is_on,
353 + .recalc_rate = raspberrypi_fw_pll_div_get_rate,
354 + .set_rate = raspberrypi_fw_pll_div_set_rate,
355 + .determine_rate = raspberrypi_pll_div_determine_rate,
358 +static const struct clk_ops raspberrypi_firmware_clk_ops = {
359 + .is_prepared = raspberrypi_fw_clock_is_on,
360 + .recalc_rate = raspberrypi_fw_clock_get_rate,
361 + .set_rate = raspberrypi_fw_clock_set_rate,
362 + .determine_rate = raspberrypi_clock_determine_rate,
366 +static int raspberrypi_get_clock_range(struct raspberrypi_clk *rpi, u32 clock_id, u32 *min_rate, u32 *max_rate)
368 - u32 min_rate = 0, max_rate = 0;
371 + /* Get min & max rates set by the firmware */
372 + ret = raspberrypi_clock_property(rpi->firmware,
373 + RPI_FIRMWARE_GET_MIN_CLOCK_RATE,
377 + dev_err(rpi->dev, "Failed to get clock %d min freq: %d (%d)\n",
378 + clock_id, *min_rate, ret);
382 + ret = raspberrypi_clock_property(rpi->firmware,
383 + RPI_FIRMWARE_GET_MAX_CLOCK_RATE,
387 + dev_err(rpi->dev, "Failed to get clock %d max freq: %d (%d)\n",
388 + clock_id, *max_rate, ret);
395 +static int raspberrypi_register_pll(struct raspberrypi_clk *rpi,
396 + const struct raspberrypi_pll_data *data)
398 + struct raspberrypi_pll *pll;
399 struct clk_init_data init;
402 memset(&init, 0, sizeof(init));
404 /* All of the PLLs derive from the external oscillator. */
405 - init.parent_names = (const char *[]){ "osc" };
406 - init.num_parents = 1;
407 - init.name = "pllb";
408 + init.parent_names = data->parents;
409 + init.num_parents = data->num_parents;
410 + init.name = data->name;
411 init.ops = &raspberrypi_firmware_pll_clk_ops;
412 init.flags = CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED;
414 - /* Get min & max rates set by the firmware */
415 - ret = raspberrypi_clock_property(rpi->firmware,
416 - RPI_FIRMWARE_GET_MIN_CLOCK_RATE,
417 - RPI_FIRMWARE_ARM_CLK_ID,
419 + pll = kzalloc(sizeof(*pll), GFP_KERNEL);
424 + pll->hw.init = &init;
426 + ret = raspberrypi_get_clock_range(rpi, data->clock_id, &pll->min_rate, &pll->max_rate);
428 - dev_err(rpi->dev, "Failed to get %s min freq: %d\n",
430 + dev_err(rpi->dev, "%s: raspberrypi_get_clock_range(%s) failed: %d\n", __func__, init.name, ret);
434 - ret = raspberrypi_clock_property(rpi->firmware,
435 - RPI_FIRMWARE_GET_MAX_CLOCK_RATE,
436 - RPI_FIRMWARE_ARM_CLK_ID,
438 + ret = devm_clk_hw_register(rpi->dev, &pll->hw);
440 - dev_err(rpi->dev, "Failed to get %s max freq: %d\n",
442 + dev_err(rpi->dev, "%s: devm_clk_hw_register(%s) failed: %d\n", __func__, init.name, ret);
448 - if (!min_rate || !max_rate) {
449 - dev_err(rpi->dev, "Unexpected frequency range: min %u, max %u\n",
450 - min_rate, max_rate);
454 +raspberrypi_register_pll_divider(struct raspberrypi_clk *rpi,
455 + const struct raspberrypi_pll_divider_data *data)
457 + struct raspberrypi_pll_divider *divider;
458 + struct clk_init_data init;
461 + memset(&init, 0, sizeof(init));
463 + init.parent_names = &data->source_pll;
464 + init.num_parents = 1;
465 + init.name = data->name;
466 + init.ops = &raspberrypi_firmware_pll_divider_clk_ops;
467 + init.flags = data->flags | CLK_IGNORE_UNUSED;
469 - dev_info(rpi->dev, "CPU frequency range: min %u, max %u\n",
470 - min_rate, max_rate);
471 + divider = devm_kzalloc(rpi->dev, sizeof(*divider), GFP_KERNEL);
475 + divider->div.hw.init = &init;
476 + divider->rpi = rpi;
477 + divider->data = data;
479 + ret = raspberrypi_get_clock_range(rpi, data->clock_id, ÷r->min_rate, ÷r->max_rate);
481 + dev_err(rpi->dev, "%s: raspberrypi_get_clock_range(%s) failed: %d\n", __func__, init.name, ret);
485 - rpi->min_rate = min_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
486 - rpi->max_rate = max_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE;
487 + ret = devm_clk_hw_register(rpi->dev, ÷r->div.hw);
489 + dev_err(rpi->dev, "%s: devm_clk_hw_register(%s) failed: %d\n", __func__, init.name, ret);
493 - rpi->pllb.init = &init;
495 + * PLLH's channels have a fixed divide by 10 afterwards, which
496 + * is what our consumers are actually using.
498 + if (data->fixed_divider != 1) {
499 + struct clk_lookup *lookup;
500 + struct clk_hw *clk = clk_hw_register_fixed_factor(rpi->dev,
501 + data->divider_name,
503 + CLK_SET_RATE_PARENT,
505 + data->fixed_divider);
507 + dev_err(rpi->dev, "%s: clk_hw_register_fixed_factor(%s) failed: %ld\n", __func__, init.name, PTR_ERR(clk));
508 + return PTR_ERR(clk);
510 + if (data->lookup) {
511 + lookup = clkdev_hw_create(clk, NULL, data->lookup);
512 + if (IS_ERR(lookup)) {
513 + dev_err(rpi->dev, "%s: clk_hw_register_fixed_factor(%s) failed: %ld\n", __func__, init.name, PTR_ERR(lookup));
514 + return PTR_ERR(lookup);
519 - return devm_clk_hw_register(rpi->dev, &rpi->pllb);
523 -static int raspberrypi_register_pllb_arm(struct raspberrypi_clk *rpi)
524 +static int raspberrypi_register_clock(struct raspberrypi_clk *rpi,
525 + const struct raspberrypi_clock_data *data)
527 - rpi->pllb_arm = clk_hw_register_fixed_factor(rpi->dev,
528 - "pllb_arm", "pllb",
529 - CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
531 - if (IS_ERR(rpi->pllb_arm)) {
532 - dev_err(rpi->dev, "Failed to initialize pllb_arm\n");
533 - return PTR_ERR(rpi->pllb_arm);
535 + struct raspberrypi_clock *clock;
536 + struct clk_init_data init;
540 + memset(&init, 0, sizeof(init));
541 + init.parent_names = data->parents;
542 + init.num_parents = data->num_parents;
543 + init.name = data->name;
544 + init.flags = data->flags | CLK_IGNORE_UNUSED;
546 - rpi->pllb_arm_lookup = clkdev_hw_create(rpi->pllb_arm, NULL, "cpu0");
547 - if (!rpi->pllb_arm_lookup) {
548 - dev_err(rpi->dev, "Failed to initialize pllb_arm_lookup\n");
549 - clk_hw_unregister_fixed_factor(rpi->pllb_arm);
550 + init.ops = &raspberrypi_firmware_clk_ops;
552 + clock = devm_kzalloc(rpi->dev, sizeof(*clock), GFP_KERNEL);
558 + clock->data = data;
559 + clock->hw.init = &init;
561 + ret = raspberrypi_get_clock_range(rpi, data->clock_id, &clock->min_rate, &clock->max_rate);
563 + dev_err(rpi->dev, "%s: raspberrypi_get_clock_range(%s) failed: %d\n", __func__, init.name, ret);
566 + clk = devm_clk_register(rpi->dev, &clock->hw);
568 + dev_err(rpi->dev, "%s: devm_clk_register(%s) failed: %ld\n", __func__, init.name, PTR_ERR(clk));
569 + return PTR_ERR(clk);
571 + ret = clk_register_clkdev(clk, init.name, NULL);
573 + dev_err(rpi->dev, "%s: clk_register_clkdev(%s) failed: %d\n", __func__, init.name, ret);
581 + * the real definition of all the pll, pll_dividers and clocks
582 + * these make use of the above REGISTER_* macros
584 +static const struct raspberrypi_clk_desc clk_desc_array[] = {
585 + /* the PLL + PLL dividers */
586 + [BCM2835_CLOCK_V3D] = REGISTER_CLK(
589 + .parents = (const char *[]){ "osc" },
591 + .clock_id = RPI_FIRMWARE_V3D_CLK_ID),
592 + [BCM2835_PLLB_ARM] = REGISTER_PLL_DIV(
595 + .source_pll = "osc",
596 + .divider_name = "pllb_arm",
598 + .fixed_divider = 2,
599 + .clock_id = RPI_FIRMWARE_ARM_CLK_ID,
600 + .flags = CLK_SET_RATE_PARENT),
603 static int raspberrypi_clk_probe(struct platform_device *pdev)
605 struct device_node *firmware_node;
606 struct device *dev = &pdev->dev;
607 struct rpi_firmware *firmware;
608 struct raspberrypi_clk *rpi;
610 + const struct raspberrypi_clk_desc *desc;
611 + const size_t asize = ARRAY_SIZE(clk_desc_array);
614 firmware_node = of_find_compatible_node(NULL, NULL,
615 "raspberrypi,bcm2835-firmware");
616 @@ -275,16 +594,16 @@ static int raspberrypi_clk_probe(struct
617 rpi->firmware = firmware;
618 platform_set_drvdata(pdev, rpi);
620 - ret = raspberrypi_register_pllb(rpi);
622 - dev_err(dev, "Failed to initialize pllb, %d\n", ret);
624 + for (i = 0; i < asize; i++) {
625 + desc = &clk_desc_array[i];
626 + if (desc->clk_register && desc->data /*&&
627 + (desc->supported & pdata->soc)*/) {
628 + int ret = desc->clk_register(rpi, desc->data);
634 - ret = raspberrypi_register_pllb_arm(rpi);
638 rpi->cpufreq = platform_device_register_data(dev, "raspberrypi-cpufreq",