1 // SPDX-License-Identifier: GPL-2.0+
3 * Raspberry Pi driver for firmware controlled clocks
5 * Even though clk-bcm2835 provides an interface to the hardware registers for
6 * the system clocks we've had to factor out 'pllb' as the firmware 'owns' it.
7 * We're not allowed to change it directly as we might race with the
8 * over-temperature and under-voltage protections provided by the firmware.
10 * Copyright (C) 2019 Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
13 #include <linux/clkdev.h>
14 #include <linux/clk-provider.h>
16 #include <linux/module.h>
17 #include <linux/platform_device.h>
19 #include <soc/bcm2835/raspberrypi-firmware.h>
21 static char *rpi_firmware_clk_names
[] = {
22 [RPI_FIRMWARE_EMMC_CLK_ID
] = "emmc",
23 [RPI_FIRMWARE_UART_CLK_ID
] = "uart",
24 [RPI_FIRMWARE_ARM_CLK_ID
] = "arm",
25 [RPI_FIRMWARE_CORE_CLK_ID
] = "core",
26 [RPI_FIRMWARE_V3D_CLK_ID
] = "v3d",
27 [RPI_FIRMWARE_H264_CLK_ID
] = "h264",
28 [RPI_FIRMWARE_ISP_CLK_ID
] = "isp",
29 [RPI_FIRMWARE_SDRAM_CLK_ID
] = "sdram",
30 [RPI_FIRMWARE_PIXEL_CLK_ID
] = "pixel",
31 [RPI_FIRMWARE_PWM_CLK_ID
] = "pwm",
32 [RPI_FIRMWARE_HEVC_CLK_ID
] = "hevc",
33 [RPI_FIRMWARE_EMMC2_CLK_ID
] = "emmc2",
34 [RPI_FIRMWARE_M2MC_CLK_ID
] = "m2mc",
35 [RPI_FIRMWARE_PIXEL_BVB_CLK_ID
] = "pixel-bvb",
36 [RPI_FIRMWARE_VEC_CLK_ID
] = "vec",
39 #define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0)
40 #define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1)
42 struct raspberrypi_clk_variant
;
44 struct raspberrypi_clk
{
46 struct rpi_firmware
*firmware
;
47 struct platform_device
*cpufreq
;
50 struct raspberrypi_clk_data
{
54 struct raspberrypi_clk_variant
*variant
;
56 struct raspberrypi_clk
*rpi
;
59 struct raspberrypi_clk_variant
{
62 unsigned long min_rate
;
66 static struct raspberrypi_clk_variant
67 raspberrypi_clk_variants
[RPI_FIRMWARE_NUM_CLK_ID
] = {
68 [RPI_FIRMWARE_ARM_CLK_ID
] = {
72 [RPI_FIRMWARE_CORE_CLK_ID
] = {
76 * The clock is shared between the HVS and the CSI
77 * controllers, on the BCM2711 and will change depending
78 * on the pixels composited on the HVS and the capture
79 * resolution on Unicam.
81 * Since the rate can get quite large, and we need to
82 * coordinate between both driver instances, let's
83 * always use the minimum the drivers will let us.
87 [RPI_FIRMWARE_M2MC_CLK_ID
] = {
91 * If we boot without any cable connected to any of the
92 * HDMI connector, the firmware will skip the HSM
93 * initialization and leave it with a rate of 0,
94 * resulting in a bus lockup when we're accessing the
95 * registers even if it's enabled.
97 * Let's put a sensible default so that we don't end up
100 .min_rate
= 120000000,
103 * The clock is shared between the two HDMI controllers
104 * on the BCM2711 and will change depending on the
105 * resolution output on each. Since the rate can get
106 * quite large, and we need to coordinate between both
107 * driver instances, let's always use the minimum the
108 * drivers will let us.
112 [RPI_FIRMWARE_V3D_CLK_ID
] = {
115 [RPI_FIRMWARE_PIXEL_CLK_ID
] = {
118 [RPI_FIRMWARE_HEVC_CLK_ID
] = {
121 [RPI_FIRMWARE_PIXEL_BVB_CLK_ID
] = {
124 [RPI_FIRMWARE_VEC_CLK_ID
] = {
130 * Structure of the message passed to Raspberry Pi's firmware in order to
131 * change clock rates. The 'disable_turbo' option is only available to the ARM
132 * clock (pllb) which we enable by default as turbo mode will alter multiple
135 * Even though we're able to access the clock registers directly we're bound to
136 * use the firmware interface as the firmware ultimately takes care of
137 * mitigating overheating/undervoltage situations and we would be changing
138 * frequencies behind his back.
140 * For more information on the firmware interface check:
141 * https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
143 struct raspberrypi_firmware_prop
{
146 __le32 disable_turbo
;
149 static int raspberrypi_clock_property(struct rpi_firmware
*firmware
,
150 const struct raspberrypi_clk_data
*data
,
153 struct raspberrypi_firmware_prop msg
= {
154 .id
= cpu_to_le32(data
->id
),
155 .val
= cpu_to_le32(*val
),
156 .disable_turbo
= cpu_to_le32(1),
160 ret
= rpi_firmware_property(firmware
, tag
, &msg
, sizeof(msg
));
164 *val
= le32_to_cpu(msg
.val
);
169 static int raspberrypi_fw_is_prepared(struct clk_hw
*hw
)
171 struct raspberrypi_clk_data
*data
=
172 container_of(hw
, struct raspberrypi_clk_data
, hw
);
173 struct raspberrypi_clk
*rpi
= data
->rpi
;
177 ret
= raspberrypi_clock_property(rpi
->firmware
, data
,
178 RPI_FIRMWARE_GET_CLOCK_STATE
, &val
);
182 return !!(val
& RPI_FIRMWARE_STATE_ENABLE_BIT
);
186 static unsigned long raspberrypi_fw_get_rate(struct clk_hw
*hw
,
187 unsigned long parent_rate
)
189 struct raspberrypi_clk_data
*data
=
190 container_of(hw
, struct raspberrypi_clk_data
, hw
);
191 struct raspberrypi_clk
*rpi
= data
->rpi
;
195 ret
= raspberrypi_clock_property(rpi
->firmware
, data
,
196 RPI_FIRMWARE_GET_CLOCK_RATE
, &val
);
203 static int raspberrypi_fw_set_rate(struct clk_hw
*hw
, unsigned long rate
,
204 unsigned long parent_rate
)
206 struct raspberrypi_clk_data
*data
=
207 container_of(hw
, struct raspberrypi_clk_data
, hw
);
208 struct raspberrypi_clk
*rpi
= data
->rpi
;
212 ret
= raspberrypi_clock_property(rpi
->firmware
, data
,
213 RPI_FIRMWARE_SET_CLOCK_RATE
, &_rate
);
215 dev_err_ratelimited(rpi
->dev
, "Failed to change %s frequency: %d\n",
216 clk_hw_get_name(hw
), ret
);
221 static int raspberrypi_fw_dumb_determine_rate(struct clk_hw
*hw
,
222 struct clk_rate_request
*req
)
224 struct raspberrypi_clk_data
*data
=
225 container_of(hw
, struct raspberrypi_clk_data
, hw
);
226 struct raspberrypi_clk_variant
*variant
= data
->variant
;
229 * The firmware will do the rounding but that isn't part of
230 * the interface with the firmware, so we just do our best
234 req
->rate
= clamp(req
->rate
, req
->min_rate
, req
->max_rate
);
237 * We want to aggressively reduce the clock rate here, so let's
238 * just ignore the requested rate and return the bare minimum
239 * rate we can get away with.
241 if (variant
->minimize
&& req
->min_rate
> 0)
242 req
->rate
= req
->min_rate
;
247 static const struct clk_ops raspberrypi_firmware_clk_ops
= {
248 .is_prepared
= raspberrypi_fw_is_prepared
,
249 .recalc_rate
= raspberrypi_fw_get_rate
,
250 .determine_rate
= raspberrypi_fw_dumb_determine_rate
,
251 .set_rate
= raspberrypi_fw_set_rate
,
254 static struct clk_hw
*raspberrypi_clk_register(struct raspberrypi_clk
*rpi
,
257 struct raspberrypi_clk_variant
*variant
)
259 struct raspberrypi_clk_data
*data
;
260 struct clk_init_data init
= {};
261 u32 min_rate
, max_rate
;
264 data
= devm_kzalloc(rpi
->dev
, sizeof(*data
), GFP_KERNEL
);
266 return ERR_PTR(-ENOMEM
);
269 data
->variant
= variant
;
271 init
.name
= devm_kasprintf(rpi
->dev
, GFP_KERNEL
,
273 rpi_firmware_clk_names
[id
]);
274 init
.ops
= &raspberrypi_firmware_clk_ops
;
275 init
.flags
= CLK_GET_RATE_NOCACHE
;
277 data
->hw
.init
= &init
;
279 ret
= raspberrypi_clock_property(rpi
->firmware
, data
,
280 RPI_FIRMWARE_GET_MIN_CLOCK_RATE
,
283 dev_err(rpi
->dev
, "Failed to get clock %d min freq: %d\n",
288 ret
= raspberrypi_clock_property(rpi
->firmware
, data
,
289 RPI_FIRMWARE_GET_MAX_CLOCK_RATE
,
292 dev_err(rpi
->dev
, "Failed to get clock %d max freq: %d\n",
297 ret
= devm_clk_hw_register(rpi
->dev
, &data
->hw
);
301 clk_hw_set_rate_range(&data
->hw
, min_rate
, max_rate
);
303 if (variant
->clkdev
) {
304 ret
= devm_clk_hw_register_clkdev(rpi
->dev
, &data
->hw
,
305 NULL
, variant
->clkdev
);
307 dev_err(rpi
->dev
, "Failed to initialize clkdev\n");
312 if (variant
->min_rate
) {
315 clk_hw_set_rate_range(&data
->hw
, variant
->min_rate
, max_rate
);
317 rate
= raspberrypi_fw_get_rate(&data
->hw
, 0);
318 if (rate
< variant
->min_rate
) {
319 ret
= raspberrypi_fw_set_rate(&data
->hw
, variant
->min_rate
, 0);
328 struct rpi_firmware_get_clocks_response
{
333 static int raspberrypi_discover_clocks(struct raspberrypi_clk
*rpi
,
334 struct clk_hw_onecell_data
*data
)
336 struct rpi_firmware_get_clocks_response
*clks
;
340 * The firmware doesn't guarantee that the last element of
341 * RPI_FIRMWARE_GET_CLOCKS is zeroed. So allocate an additional
342 * zero element as sentinel.
344 clks
= devm_kcalloc(rpi
->dev
,
345 RPI_FIRMWARE_NUM_CLK_ID
+ 1, sizeof(*clks
),
350 ret
= rpi_firmware_property(rpi
->firmware
, RPI_FIRMWARE_GET_CLOCKS
,
352 sizeof(*clks
) * RPI_FIRMWARE_NUM_CLK_ID
);
357 struct raspberrypi_clk_variant
*variant
;
359 if (clks
->id
>= RPI_FIRMWARE_NUM_CLK_ID
) {
360 dev_err(rpi
->dev
, "Unknown clock id: %u (max: %u)\n",
361 clks
->id
, RPI_FIRMWARE_NUM_CLK_ID
- 1);
365 variant
= &raspberrypi_clk_variants
[clks
->id
];
366 if (variant
->export
) {
369 hw
= raspberrypi_clk_register(rpi
, clks
->parent
,
374 data
->num
= clks
->id
+ 1;
375 data
->hws
[clks
->id
] = hw
;
384 static int raspberrypi_clk_probe(struct platform_device
*pdev
)
386 struct clk_hw_onecell_data
*clk_data
;
387 struct device_node
*firmware_node
;
388 struct device
*dev
= &pdev
->dev
;
389 struct rpi_firmware
*firmware
;
390 struct raspberrypi_clk
*rpi
;
394 * We can be probed either through the an old-fashioned
395 * platform device registration or through a DT node that is a
396 * child of the firmware node. Handle both cases.
399 firmware_node
= of_get_parent(dev
->of_node
);
401 firmware_node
= of_find_compatible_node(NULL
, NULL
,
402 "raspberrypi,bcm2835-firmware");
403 if (!firmware_node
) {
404 dev_err(dev
, "Missing firmware node\n");
408 firmware
= devm_rpi_firmware_get(&pdev
->dev
, firmware_node
);
409 of_node_put(firmware_node
);
411 return -EPROBE_DEFER
;
413 rpi
= devm_kzalloc(dev
, sizeof(*rpi
), GFP_KERNEL
);
418 rpi
->firmware
= firmware
;
419 platform_set_drvdata(pdev
, rpi
);
421 clk_data
= devm_kzalloc(dev
, struct_size(clk_data
, hws
,
422 RPI_FIRMWARE_NUM_CLK_ID
),
427 ret
= raspberrypi_discover_clocks(rpi
, clk_data
);
431 ret
= devm_of_clk_add_hw_provider(dev
, of_clk_hw_onecell_get
,
436 rpi
->cpufreq
= platform_device_register_data(dev
, "raspberrypi-cpufreq",
442 static void raspberrypi_clk_remove(struct platform_device
*pdev
)
444 struct raspberrypi_clk
*rpi
= platform_get_drvdata(pdev
);
446 platform_device_unregister(rpi
->cpufreq
);
449 static const struct of_device_id raspberrypi_clk_match
[] = {
450 { .compatible
= "raspberrypi,firmware-clocks" },
453 MODULE_DEVICE_TABLE(of
, raspberrypi_clk_match
);
455 static struct platform_driver raspberrypi_clk_driver
= {
457 .name
= "raspberrypi-clk",
458 .of_match_table
= raspberrypi_clk_match
,
460 .probe
= raspberrypi_clk_probe
,
461 .remove
= raspberrypi_clk_remove
,
463 module_platform_driver(raspberrypi_clk_driver
);
465 MODULE_AUTHOR("Nicolas Saenz Julienne <nsaenzjulienne@suse.de>");
466 MODULE_DESCRIPTION("Raspberry Pi firmware clock driver");
467 MODULE_LICENSE("GPL");
468 MODULE_ALIAS("platform:raspberrypi-clk");