2015-06-08 23:59:18

by Eric Anholt

[permalink] [raw]
Subject: [PATCH v3 1/7] dt/bindings: Add binding for the Raspberry Pi clock provider

The hardware clocks are not controllable by the ARM, so we have to
make requests to the firmware to do so from the VPU side. This will
let us replace fixed clocks in our DT with actual clock control (and
correct frequency information).

v2: Include the dt-bindings header in this commit instead of the next
one. Make the clock indices match the firmware clock IDs. Rename
the binding's compat string. Move the firmware phandle to be
under a vendor-specific namespace.

Signed-off-by: Eric Anholt <[email protected]>
---
.../clock/raspberrypi,bcm2835-firmware-clocks.txt | 25 ++++++++++++++++++++++
include/dt-bindings/clk/raspberrypi.h | 23 ++++++++++++++++++++
2 files changed, 48 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
create mode 100644 include/dt-bindings/clk/raspberrypi.h

diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
new file mode 100644
index 0000000..0972602
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
@@ -0,0 +1,25 @@
+Raspberry Pi firmware clock provider.
+
+The Raspberry Pi architecture doesn't provide direct access to the
+CLOCKMAN peripheral from the ARM side, so Linux has to make requests
+to the VPU firmware to program them.
+
+This binding uses the common clock binding:
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible: Should be "raspberrypi,bcm2835-firmware-clocks"
+
+- #clock-cells: Shall have value <1>. The permitted clock-specifier
+ values can be found in
+ include/dt-bindings/clk/raspberrypi.h.
+
+- raspberrypi,firmware: Phandle to the firmware driver node.
+
+Example:
+
+firmware_clocks: firmware-clocks {
+ compatible = "raspberrypi,bcm2835-firmware-clocks";
+ #clock-cells = <1>;
+ raspberrypi,firmware = <&firmware>;
+};
diff --git a/include/dt-bindings/clk/raspberrypi.h b/include/dt-bindings/clk/raspberrypi.h
new file mode 100644
index 0000000..ceec90f
--- /dev/null
+++ b/include/dt-bindings/clk/raspberrypi.h
@@ -0,0 +1,23 @@
+#/*
+ * Copyright © 2015 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _DT_BINDINGS_CLK_RASPBERRYPI_H
+#define _DT_BINDINGS_CLK_RASPBERRYPI_H
+
+#define RPI_CLOCK_EMMC 1
+#define RPI_CLOCK_UART0 2
+#define RPI_CLOCK_ARM 3
+#define RPI_CLOCK_CORE 4
+#define RPI_CLOCK_V3D 5
+#define RPI_CLOCK_H264 6
+#define RPI_CLOCK_ISP 7
+#define RPI_CLOCK_SDRAM 8
+#define RPI_CLOCK_PIXEL 9
+#define RPI_CLOCK_PWM 10
+
+#endif
--
2.1.4


2015-06-08 23:59:39

by Eric Anholt

[permalink] [raw]
Subject: [PATCH v3 2/7] ARM: bcm2835: Add a Raspberry Pi-specific clock driver.

Unfortunately, the clock manager's registers are not accessible by the
ARM, so we have to request that the firmware modify our clocks for us.

This driver only registers the clocks at the point they are requested
by a client driver. This is partially to support returning
-EPROBE_DEFER when the firmware driver isn't supported yet, but it
also avoids issues with disabling "unused" clocks due to them not yet
being connected to their consumers in the DT.

v2: Declare the mutex static (from review by Baruch Siach), merge
description and copyright comments.

v3: Update for new rpi firmware API. Update the compatible string.
Make the firmware handle be under a vendor-namespaced property.
Make the DT indices match the firmware clock IDs. Move the driver
under the firmware driver's Kconfig, since it requires it. Move a
container_of() from 2 callers into the callee.

Signed-off-by: Eric Anholt <[email protected]>
---
drivers/clk/Makefile | 1 +
drivers/clk/clk-raspberrypi.c | 242 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 243 insertions(+)
create mode 100644 drivers/clk/clk-raspberrypi.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 3d00c25..0525c6b 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o
obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o
obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
+obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += clk-raspberrypi.o
obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o
obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
diff --git a/drivers/clk/clk-raspberrypi.c b/drivers/clk/clk-raspberrypi.c
new file mode 100644
index 0000000..e1071d1
--- /dev/null
+++ b/drivers/clk/clk-raspberrypi.c
@@ -0,0 +1,242 @@
+/*
+ * Implements a clock provider for the clocks controlled by the
+ * firmware on Raspberry Pi.
+ *
+ * These clocks are controlled by the CLOCKMAN peripheral in the
+ * hardware, but the ARM doesn't have access to the registers for
+ * them. As a result, we have to call into the firmware to get it to
+ * enable, disable, and set their frequencies.
+ *
+ * We don't have an interface for getting the set of frequencies
+ * available from the hardware. We can request a min/max, but other
+ * than that we have to request a frequency and take what it gives us.
+ *
+ * Copyright © 2015 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <dt-bindings/clk/raspberrypi.h>
+#include <linux/clk-provider.h>
+#include <soc/bcm2835/raspberrypi-firmware.h>
+
+struct rpi_firmware_clock {
+ /* Clock definitions in our static struct. */
+ const char *name;
+
+ /* The rest are filled in at init time. */
+ struct clk_hw hw;
+ struct device *dev;
+ struct rpi_firmware *firmware;
+};
+
+static struct rpi_firmware_clock rpi_clocks[] = {
+ [RPI_CLOCK_EMMC] = { "emmc" },
+ [RPI_CLOCK_UART0] = { "uart0" },
+ [RPI_CLOCK_ARM] = { "arm" },
+ [RPI_CLOCK_CORE] = { "core" },
+ [RPI_CLOCK_V3D] = { "v3d" },
+ [RPI_CLOCK_H264] = { "h264" },
+ [RPI_CLOCK_ISP] = { "isp" },
+ [RPI_CLOCK_SDRAM] = { "sdram" },
+ [RPI_CLOCK_PIXEL] = { "pixel" },
+ [RPI_CLOCK_PWM] = { "pwm" },
+};
+
+static int rpi_clock_id(struct rpi_firmware_clock *rpi_clk)
+{
+ return rpi_clk - rpi_clocks;
+}
+
+static int rpi_clk_is_on(struct clk_hw *hw)
+{
+ struct rpi_firmware_clock *rpi_clk =
+ container_of(hw, struct rpi_firmware_clock, hw);
+ u32 packet[2];
+ int ret;
+
+ packet[0] = rpi_clock_id(rpi_clk);
+ packet[1] = 0;
+ ret = rpi_firmware_property(rpi_clk->firmware,
+ RPI_FIRMWARE_GET_CLOCK_STATE,
+ &packet, sizeof(packet));
+ if (ret) {
+ dev_err(rpi_clk->dev, "Failed to get clock state\n");
+ return 0;
+ }
+
+ return packet[1] != 0;
+}
+
+static int rpi_clk_set_state(struct clk_hw *hw, bool on)
+{
+ struct rpi_firmware_clock *rpi_clk =
+ container_of(hw, struct rpi_firmware_clock, hw);
+ u32 packet[2];
+ int ret;
+
+ packet[0] = rpi_clock_id(rpi_clk);
+ packet[1] = on;
+ ret = rpi_firmware_property(rpi_clk->firmware,
+ RPI_FIRMWARE_SET_CLOCK_STATE,
+ &packet, sizeof(packet));
+ if (ret || (packet[1] & (1 << 1))) {
+ dev_err(rpi_clk->dev, "Failed to set clock state\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rpi_clk_on(struct clk_hw *hw)
+{
+ return rpi_clk_set_state(hw, true);
+}
+
+static void rpi_clk_off(struct clk_hw *hw)
+{
+ rpi_clk_set_state(hw, false);
+}
+
+static unsigned long rpi_clk_get_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct rpi_firmware_clock *rpi_clk =
+ container_of(hw, struct rpi_firmware_clock, hw);
+ u32 packet[2];
+ int ret;
+
+ packet[0] = rpi_clock_id(rpi_clk);
+ packet[1] = 0;
+ ret = rpi_firmware_property(rpi_clk->firmware,
+ RPI_FIRMWARE_GET_CLOCK_RATE,
+ &packet, sizeof(packet));
+ if (ret) {
+ dev_err(rpi_clk->dev, "Failed to get clock rate\n");
+ return 0;
+ }
+
+ return packet[1];
+}
+
+static int rpi_clk_set_rate(struct clk_hw *hw,
+ unsigned long rate, unsigned long parent_rate)
+{
+ struct rpi_firmware_clock *rpi_clk =
+ container_of(hw, struct rpi_firmware_clock, hw);
+ u32 packet[2];
+ int ret;
+
+ packet[0] = rpi_clock_id(rpi_clk);
+ packet[1] = rate;
+ ret = rpi_firmware_property(rpi_clk->firmware,
+ RPI_FIRMWARE_SET_CLOCK_RATE,
+ &packet, sizeof(packet));
+ if (ret) {
+ dev_err(rpi_clk->dev, "Failed to set clock rate\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static long rpi_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ /*
+ * The firmware will end up rounding our rate to something,
+ * but we don't have an interface for it. Just return the
+ * requested value, and it'll get updated after the clock gets
+ * set.
+ */
+ return rate;
+}
+
+static struct clk_ops rpi_clk_ops = {
+ .is_prepared = rpi_clk_is_on,
+ .prepare = rpi_clk_on,
+ .unprepare = rpi_clk_off,
+ .recalc_rate = rpi_clk_get_rate,
+ .set_rate = rpi_clk_set_rate,
+ .round_rate = rpi_clk_round_rate,
+};
+
+static DEFINE_MUTEX(delayed_clock_init);
+static struct clk *rpi_firmware_delayed_get_clk(struct of_phandle_args *clkspec,
+ void *_data)
+{
+ struct device_node *of_node = _data;
+ struct platform_device *pdev = of_find_device_by_node(of_node);
+ struct device *dev = &pdev->dev;
+ struct device_node *firmware_node;
+ struct rpi_firmware *firmware;
+ struct clk_init_data init;
+ struct rpi_firmware_clock *rpi_clk;
+ struct clk *ret_clk;
+
+ if (clkspec->args_count != 1) {
+ dev_err(dev, "clock phandle should have 1 argument\n");
+ return ERR_PTR(-ENODEV);
+ }
+
+ if (clkspec->args[0] >= ARRAY_SIZE(rpi_clocks)) {
+ dev_err(dev, "clock phandle index %d out of range\n",
+ clkspec->args[0]);
+ return ERR_PTR(-ENODEV);
+ }
+
+ rpi_clk = &rpi_clocks[clkspec->args[0]];
+ if (!rpi_clk->name) {
+ dev_err(dev, "clock phandle index %d invalid\n",
+ clkspec->args[0]);
+ return ERR_PTR(-ENODEV);
+ }
+
+ firmware_node = of_parse_phandle(of_node, "raspberrypi,firmware", 0);
+ if (!firmware_node) {
+ dev_err(dev, "%s: Missing firmware node\n", rpi_clk->name);
+ return ERR_PTR(-ENODEV);
+ }
+ firmware = rpi_firmware_get(firmware_node);
+ if (!firmware)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ mutex_lock(&delayed_clock_init);
+ if (rpi_clk->hw.clk) {
+ mutex_unlock(&delayed_clock_init);
+ return rpi_clk->hw.clk;
+ }
+ memset(&init, 0, sizeof(init));
+ init.ops = &rpi_clk_ops;
+
+ rpi_clk->firmware = firmware;
+ rpi_clk->dev = dev;
+ rpi_clk->hw.init = &init;
+ init.name = rpi_clk->name;
+ init.flags = CLK_IS_ROOT;
+
+ ret_clk = clk_register(dev, &rpi_clk->hw);
+ mutex_unlock(&delayed_clock_init);
+ if (!IS_ERR(ret_clk))
+ dev_info(dev, "registered %s clock\n", rpi_clk->name);
+ else {
+ dev_err(dev, "%s clock failed to init: %ld\n", rpi_clk->name,
+ PTR_ERR(ret_clk));
+ }
+ return ret_clk;
+}
+
+void __init rpi_firmware_init_clock_provider(struct device_node *node)
+{
+ /* We delay construction of our struct clks until get time,
+ * because we need to be able to return -EPROBE_DEFER if the
+ * firmware driver isn't up yet. clk core doesn't support
+ * re-probing on -EPROBE_DEFER, but callers of clk_get can.
+ */
+ of_clk_add_provider(node, rpi_firmware_delayed_get_clk, node);
+}
+
+CLK_OF_DECLARE(rpi_firmware_clocks, "raspberrypi,bcm2835-firmware-clocks",
+ rpi_firmware_init_clock_provider);
--
2.1.4

2015-06-08 23:59:09

by Eric Anholt

[permalink] [raw]
Subject: [PATCH v3 3/7] ARM: bcm2835: Add DT for the firmware clocks driver.

v2: Rename our compat string to mention bcm2835, and make our firmware
phandle be under a vendor-namespaced property.

Signed-off-by: Eric Anholt <[email protected]>
---
arch/arm/boot/dts/bcm2835-rpi.dtsi | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index ab5474e..7cc47fb 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -20,6 +20,12 @@
compatible = "raspberrypi,bcm2835-firmware";
mboxes = <&mailbox>;
};
+
+ firmware_clocks: firmware-clocks {
+ compatible = "raspberrypi,bcm2835-firmware-clocks";
+ #clock-cells = <1>;
+ raspberrypi,firmware = <&firmware>;
+ };
};
};

--
2.1.4

2015-06-08 23:59:35

by Eric Anholt

[permalink] [raw]
Subject: [PATCH v3 4/7] ARM: bcm2835: Drop never-used clock-frequency property of uart0.

This appears to have been copy-and-paste from another serial driver's
DT. The driver has never used this value -- instead, the pl011 driver
is getting the fixed 20201000.uart clock from clk-bcm2835.c.

Signed-off-by: Eric Anholt <[email protected]>
---
arch/arm/boot/dts/bcm2835.dtsi | 1 -
1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 301c73f..32f5830 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -96,7 +96,6 @@
compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
reg = <0x7e201000 0x1000>;
interrupts = <2 25>;
- clock-frequency = <3000000>;
arm,primecell-periphid = <0x00241011>;
};

--
2.1.4

2015-06-08 23:59:23

by Eric Anholt

[permalink] [raw]
Subject: [PATCH v3 5/7] ARM: bcm2835: Drop the fixed sys_pclk.

Nothing uses it, and I can't find any evidence that anything ever has.

Signed-off-by: Eric Anholt <[email protected]>
---
drivers/clk/clk-bcm2835.c | 5 -----
1 file changed, 5 deletions(-)

diff --git a/drivers/clk/clk-bcm2835.c b/drivers/clk/clk-bcm2835.c
index 6b950ca..dd295e4 100644
--- a/drivers/clk/clk-bcm2835.c
+++ b/drivers/clk/clk-bcm2835.c
@@ -32,11 +32,6 @@ void __init bcm2835_init_clocks(void)
struct clk *clk;
int ret;

- clk = clk_register_fixed_rate(NULL, "sys_pclk", NULL, CLK_IS_ROOT,
- 250000000);
- if (IS_ERR(clk))
- pr_err("sys_pclk not registered\n");
-
clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT,
126000000);
if (IS_ERR(clk))
--
2.1.4

2015-06-08 23:59:49

by Eric Anholt

[permalink] [raw]
Subject: [PATCH v3 6/7] ARM: bcm2835: Use the RPi firmware clocks for uart.

This gets us a correct apb_pclk, which previously was accidentally
using the "20201000.uart" clock from clk-bcm2835.c, due to the
fallback clk_get_sys() path.

Signed-off-by: Eric Anholt <[email protected]>
---
arch/arm/boot/dts/bcm2835-rpi.dtsi | 7 +++++++
arch/arm/boot/dts/bcm2835.dtsi | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 7cc47fb..9549eb8 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -1,3 +1,4 @@
+#include <dt-bindings/clk/raspberrypi.h>
#include "bcm2835.dtsi"

/ {
@@ -62,3 +63,9 @@
status = "okay";
bus-width = <4>;
};
+
+&uart0 {
+ clocks = <&firmware_clocks RPI_CLOCK_UART0>,
+ <&firmware_clocks RPI_CLOCK_CORE>;
+ clock-names = "uartclk", "apb_pclk";
+};
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 32f5830..5be2862 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -92,7 +92,7 @@
#interrupt-cells = <2>;
};

- uart@7e201000 {
+ uart0: uart@7e201000 {
compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
reg = <0x7e201000 0x1000>;
interrupts = <2 25>;
--
2.1.4

2015-06-09 00:00:37

by Eric Anholt

[permalink] [raw]
Subject: [PATCH v3 7/7] ARM: bcm2835: Tie SPI clock to the core clock rate.

We were previously using a fixed clock declared in the 2835 DT, but
it's actually the core clock, and it might not be the same if you had
adjusted it using the firmware's config.txt.

Signed-off-by: Eric Anholt <[email protected]>
---
arch/arm/boot/dts/bcm2835-rpi.dtsi | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 9549eb8..0a32123 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -69,3 +69,7 @@
<&firmware_clocks RPI_CLOCK_CORE>;
clock-names = "uartclk", "apb_pclk";
};
+
+&spi {
+ clocks = <&firmware_clocks RPI_CLOCK_CORE>;
+};
--
2.1.4

2015-06-09 00:03:16

by Eric Anholt

[permalink] [raw]
Subject: Re: [PATCH v3 1/7] dt/bindings: Add binding for the Raspberry Pi clock provider

Eric Anholt <[email protected]> writes:

> The hardware clocks are not controllable by the ARM, so we have to
> make requests to the firmware to do so from the VPU side. This will
> let us replace fixed clocks in our DT with actual clock control (and
> correct frequency information).
>
> v2: Include the dt-bindings header in this commit instead of the next
> one. Make the clock indices match the firmware clock IDs. Rename
> the binding's compat string. Move the firmware phandle to be
> under a vendor-specific namespace.

Having failed to move the versioning bits below --- again, I'm adding
scripting to hopefully catch myself if I'm about to do it again.


Attachments:
signature.asc (818.00 B)

2015-06-09 01:56:17

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH v3 2/7] ARM: bcm2835: Add a Raspberry Pi-specific clock driver.

On 06/08/2015 05:58 PM, Eric Anholt wrote:
> Unfortunately, the clock manager's registers are not accessible by the
> ARM, so we have to request that the firmware modify our clocks for us.
>
> This driver only registers the clocks at the point they are requested
> by a client driver. This is partially to support returning
> -EPROBE_DEFER when the firmware driver isn't supported yet, but it
> also avoids issues with disabling "unused" clocks due to them not yet
> being connected to their consumers in the DT.

> diff --git a/drivers/clk/clk-raspberrypi.c b/drivers/clk/clk-raspberrypi.c

> +static int rpi_clk_set_state(struct clk_hw *hw, bool on)

> + if (ret || (packet[1] & (1 << 1))) {

A #define for the shift amount would be nice, so that this statement was
a bit more semantic.

Aside from that, the series,
Acked-by: Stephen Warren <[email protected]>

2015-06-09 09:56:45

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH v3 2/7] ARM: bcm2835: Add a Raspberry Pi-specific clock driver.

On Mon, 08 Jun 2015, Eric Anholt wrote:

> Unfortunately, the clock manager's registers are not accessible by the
> ARM, so we have to request that the firmware modify our clocks for us.
>
> This driver only registers the clocks at the point they are requested
> by a client driver. This is partially to support returning
> -EPROBE_DEFER when the firmware driver isn't supported yet, but it
> also avoids issues with disabling "unused" clocks due to them not yet
> being connected to their consumers in the DT.
>
> v2: Declare the mutex static (from review by Baruch Siach), merge
> description and copyright comments.
>
> v3: Update for new rpi firmware API. Update the compatible string.
> Make the firmware handle be under a vendor-namespaced property.
> Make the DT indices match the firmware clock IDs. Move the driver
> under the firmware driver's Kconfig, since it requires it. Move a
> container_of() from 2 callers into the callee.
>
> Signed-off-by: Eric Anholt <[email protected]>
> ---
> drivers/clk/Makefile | 1 +
> drivers/clk/clk-raspberrypi.c | 242 ++++++++++++++++++++++++++++++++++++++++++

This is not an "ARM" patch.

The subject line needs to reflect the subsystem you are submitting to.

`git log --oneline -- <subsystem>`

2015-06-09 10:03:43

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH v3 1/7] dt/bindings: Add binding for the Raspberry Pi clock provider

If I were the Clock Maintainer, I would have probably missed this
patch. You _must_ intimate which subsystem you are submitting to.

> The hardware clocks are not controllable by the ARM, so we have to
> make requests to the firmware to do so from the VPU side. This will
> let us replace fixed clocks in our DT with actual clock control (and
> correct frequency information).
>
> v2: Include the dt-bindings header in this commit instead of the next
> one. Make the clock indices match the firmware clock IDs. Rename
> the binding's compat string. Move the firmware phandle to be
> under a vendor-specific namespace.
>
> Signed-off-by: Eric Anholt <[email protected]>
> ---
> .../clock/raspberrypi,bcm2835-firmware-clocks.txt | 25 ++++++++++++++++++++++
> include/dt-bindings/clk/raspberrypi.h | 23 ++++++++++++++++++++
> 2 files changed, 48 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
> create mode 100644 include/dt-bindings/clk/raspberrypi.h
>
> diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
> new file mode 100644
> index 0000000..0972602
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
> @@ -0,0 +1,25 @@
> +Raspberry Pi firmware clock provider.
> +
> +The Raspberry Pi architecture doesn't provide direct access to the
> +CLOCKMAN peripheral from the ARM side, so Linux has to make requests
> +to the VPU firmware to program them.
> +
> +This binding uses the common clock binding:
> +Documentation/devicetree/bindings/clock/clock-bindings.txt
> +
> +Required properties:
> +- compatible: Should be "raspberrypi,bcm2835-firmware-clocks"
> +
> +- #clock-cells: Shall have value <1>. The permitted clock-specifier
> + values can be found in
> + include/dt-bindings/clk/raspberrypi.h.
> +
> +- raspberrypi,firmware: Phandle to the firmware driver node.

I think 'firmware' is a candidate for a generic phandle name.

Apart from that, binding looks pretty inert:

Acked-by: Lee Jones <[email protected]>

> +Example:
> +
> +firmware_clocks: firmware-clocks {
> + compatible = "raspberrypi,bcm2835-firmware-clocks";
> + #clock-cells = <1>;
> + raspberrypi,firmware = <&firmware>;
> +};
> diff --git a/include/dt-bindings/clk/raspberrypi.h b/include/dt-bindings/clk/raspberrypi.h
> new file mode 100644
> index 0000000..ceec90f
> --- /dev/null
> +++ b/include/dt-bindings/clk/raspberrypi.h
> @@ -0,0 +1,23 @@
> +#/*
> + * Copyright ? 2015 Broadcom
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_RASPBERRYPI_H
> +#define _DT_BINDINGS_CLK_RASPBERRYPI_H
> +
> +#define RPI_CLOCK_EMMC 1
> +#define RPI_CLOCK_UART0 2
> +#define RPI_CLOCK_ARM 3
> +#define RPI_CLOCK_CORE 4
> +#define RPI_CLOCK_V3D 5
> +#define RPI_CLOCK_H264 6
> +#define RPI_CLOCK_ISP 7
> +#define RPI_CLOCK_SDRAM 8
> +#define RPI_CLOCK_PIXEL 9
> +#define RPI_CLOCK_PWM 10
> +
> +#endif

2015-07-07 20:14:00

by Eric Anholt

[permalink] [raw]
Subject: Re: [PATCH v3 1/7] dt/bindings: Add binding for the Raspberry Pi clock provider

Lee Jones <[email protected]> writes:

> If I were the Clock Maintainer, I would have probably missed this
> patch. You _must_ intimate which subsystem you are submitting to.
>
>> The hardware clocks are not controllable by the ARM, so we have to
>> make requests to the firmware to do so from the VPU side. This will
>> let us replace fixed clocks in our DT with actual clock control (and
>> correct frequency information).
>>
>> v2: Include the dt-bindings header in this commit instead of the next
>> one. Make the clock indices match the firmware clock IDs. Rename
>> the binding's compat string. Move the firmware phandle to be
>> under a vendor-specific namespace.
>>
>> Signed-off-by: Eric Anholt <[email protected]>
>> ---
>> .../clock/raspberrypi,bcm2835-firmware-clocks.txt | 25 ++++++++++++++++++++++
>> include/dt-bindings/clk/raspberrypi.h | 23 ++++++++++++++++++++
>> 2 files changed, 48 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
>> create mode 100644 include/dt-bindings/clk/raspberrypi.h
>>
>> diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
>> new file mode 100644
>> index 0000000..0972602
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
>> @@ -0,0 +1,25 @@
>> +Raspberry Pi firmware clock provider.
>> +
>> +The Raspberry Pi architecture doesn't provide direct access to the
>> +CLOCKMAN peripheral from the ARM side, so Linux has to make requests
>> +to the VPU firmware to program them.
>> +
>> +This binding uses the common clock binding:
>> +Documentation/devicetree/bindings/clock/clock-bindings.txt
>> +
>> +Required properties:
>> +- compatible: Should be "raspberrypi,bcm2835-firmware-clocks"
>> +
>> +- #clock-cells: Shall have value <1>. The permitted clock-specifier
>> + values can be found in
>> + include/dt-bindings/clk/raspberrypi.h.
>> +
>> +- raspberrypi,firmware: Phandle to the firmware driver node.
>
> I think 'firmware' is a candidate for a generic phandle name.

Stephen Warren asked in the last version that I change it from
"firmware" to "raspberrypi,firmware", which made sense to me since we're
not some core infrastructure using these references. Which should it
be?


Attachments:
signature.asc (818.00 B)

2015-07-24 15:30:19

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH v3 1/7] dt/bindings: Add binding for the Raspberry Pi clock provider

On Tue, 07 Jul 2015, Eric Anholt wrote:

> Lee Jones <[email protected]> writes:
>
> > If I were the Clock Maintainer, I would have probably missed this
> > patch. You _must_ intimate which subsystem you are submitting to.
> >
> >> The hardware clocks are not controllable by the ARM, so we have to
> >> make requests to the firmware to do so from the VPU side. This will
> >> let us replace fixed clocks in our DT with actual clock control (and
> >> correct frequency information).
> >>
> >> v2: Include the dt-bindings header in this commit instead of the next
> >> one. Make the clock indices match the firmware clock IDs. Rename
> >> the binding's compat string. Move the firmware phandle to be
> >> under a vendor-specific namespace.
> >>
> >> Signed-off-by: Eric Anholt <[email protected]>
> >> ---
> >> .../clock/raspberrypi,bcm2835-firmware-clocks.txt | 25 ++++++++++++++++++++++
> >> include/dt-bindings/clk/raspberrypi.h | 23 ++++++++++++++++++++
> >> 2 files changed, 48 insertions(+)
> >> create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
> >> create mode 100644 include/dt-bindings/clk/raspberrypi.h
> >>
> >> diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
> >> new file mode 100644
> >> index 0000000..0972602
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
> >> @@ -0,0 +1,25 @@
> >> +Raspberry Pi firmware clock provider.
> >> +
> >> +The Raspberry Pi architecture doesn't provide direct access to the
> >> +CLOCKMAN peripheral from the ARM side, so Linux has to make requests
> >> +to the VPU firmware to program them.
> >> +
> >> +This binding uses the common clock binding:
> >> +Documentation/devicetree/bindings/clock/clock-bindings.txt
> >> +
> >> +Required properties:
> >> +- compatible: Should be "raspberrypi,bcm2835-firmware-clocks"
> >> +
> >> +- #clock-cells: Shall have value <1>. The permitted clock-specifier
> >> + values can be found in
> >> + include/dt-bindings/clk/raspberrypi.h.
> >> +
> >> +- raspberrypi,firmware: Phandle to the firmware driver node.
> >
> > I think 'firmware' is a candidate for a generic phandle name.
>
> Stephen Warren asked in the last version that I change it from
> "firmware" to "raspberrypi,firmware", which made sense to me since we're
> not some core infrastructure using these references. Which should it
> be?

We tend to use vendor specific bindings when others are unlikely to
make use of them. I would have thought that different vendors would
also make use of a generic 'firmware' phandle. The final decision
would probably be taken by the DT guys.

2015-07-28 02:54:00

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH v3 1/7] dt/bindings: Add binding for the Raspberry Pi clock provider

On 07/24/2015 09:30 AM, Lee Jones wrote:
> On Tue, 07 Jul 2015, Eric Anholt wrote:
>
>> Lee Jones <[email protected]> writes:
>>
>>> If I were the Clock Maintainer, I would have probably missed this
>>> patch. You _must_ intimate which subsystem you are submitting to.
>>>
>>>> The hardware clocks are not controllable by the ARM, so we have to
>>>> make requests to the firmware to do so from the VPU side. This will
>>>> let us replace fixed clocks in our DT with actual clock control (and
>>>> correct frequency information).
>>>>
>>>> v2: Include the dt-bindings header in this commit instead of the next
>>>> one. Make the clock indices match the firmware clock IDs. Rename
>>>> the binding's compat string. Move the firmware phandle to be
>>>> under a vendor-specific namespace.
>>>>
>>>> Signed-off-by: Eric Anholt <[email protected]>
>>>> ---
>>>> .../clock/raspberrypi,bcm2835-firmware-clocks.txt | 25 ++++++++++++++++++++++
>>>> include/dt-bindings/clk/raspberrypi.h | 23 ++++++++++++++++++++
>>>> 2 files changed, 48 insertions(+)
>>>> create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
>>>> create mode 100644 include/dt-bindings/clk/raspberrypi.h
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
>>>> new file mode 100644
>>>> index 0000000..0972602
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
>>>> @@ -0,0 +1,25 @@
>>>> +Raspberry Pi firmware clock provider.
>>>> +
>>>> +The Raspberry Pi architecture doesn't provide direct access to the
>>>> +CLOCKMAN peripheral from the ARM side, so Linux has to make requests
>>>> +to the VPU firmware to program them.
>>>> +
>>>> +This binding uses the common clock binding:
>>>> +Documentation/devicetree/bindings/clock/clock-bindings.txt
>>>> +
>>>> +Required properties:
>>>> +- compatible: Should be "raspberrypi,bcm2835-firmware-clocks"
>>>> +
>>>> +- #clock-cells: Shall have value <1>. The permitted clock-specifier
>>>> + values can be found in
>>>> + include/dt-bindings/clk/raspberrypi.h.
>>>> +
>>>> +- raspberrypi,firmware: Phandle to the firmware driver node.
>>>
>>> I think 'firmware' is a candidate for a generic phandle name.
>>
>> Stephen Warren asked in the last version that I change it from
>> "firmware" to "raspberrypi,firmware", which made sense to me since we're
>> not some core infrastructure using these references. Which should it
>> be?
>
> We tend to use vendor specific bindings when others are unlikely to
> make use of them. I would have thought that different vendors would
> also make use of a generic 'firmware' phandle. The final decision
> would probably be taken by the DT guys.

I wouldn't expect there to be a need for a common firmware API for
firmwares that don't implement some common standard (such as ACPI),
since the operations supported by the firmwares will be
firmware-specific, and hence not be amenable to generic clients (a
client of the raspberrypi,firmware object may "translate" it to standard
APIs such as clock, power domains, etc., while allowing other clients
access to all the custom features). As such, I expect using a generic
property name here isn't that useful.