c3110e3
From fbdb31e061b67941342fc5afa714488f75174632 Mon Sep 17 00:00:00 2001
e8f4892
From: Peter Robinson <pbrobinson@gmail.com>
e8f4892
Date: Thu, 31 May 2018 19:08:12 +0100
c3110e3
Subject: [PATCH 1/3] bcm2835: cpufreq: add CPU frequency control driver
e8f4892
e8f4892
Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
e8f4892
---
e8f4892
 arch/arm/boot/dts/bcm2835-rpi.dtsi |   7 ++
e8f4892
 arch/arm/boot/dts/bcm2837.dtsi     |  33 +++++++
e8f4892
 drivers/clk/bcm/Kconfig            |   8 ++
e8f4892
 drivers/clk/bcm/Makefile           |   1 +
e8f4892
 drivers/clk/bcm/clk-raspberrypi.c  | 138 +++++++++++++++++++++++++++++
e8f4892
 5 files changed, 187 insertions(+)
e8f4892
 create mode 100644 drivers/clk/bcm/clk-raspberrypi.c
e8f4892
e8f4892
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
c3110e3
index 29f970f864dc..6d0f43957af4 100644
e8f4892
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
e8f4892
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
e8f4892
@@ -35,6 +35,13 @@
c3110e3
 			reg = <0x7e00b840 0x3c>;
e8f4892
 			interrupts = <0 2>;
e8f4892
 		};
e8f4892
+
e8f4892
+		arm_clk: arm_clk {
e8f4892
+			compatible = "raspberrypi,bcm2835-cpu";
e8f4892
+			clocks = <&clocks BCM2835_CLOCK_VPU>;
e8f4892
+			#clock-cells = <0>;
e8f4892
+			clock-output-names = "arm";
e8f4892
+		};
e8f4892
 	};
e8f4892
 };
e8f4892
 
e8f4892
diff --git a/arch/arm/boot/dts/bcm2837.dtsi b/arch/arm/boot/dts/bcm2837.dtsi
c3110e3
index beb6c502dadc..9cfc553a3633 100644
e8f4892
--- a/arch/arm/boot/dts/bcm2837.dtsi
e8f4892
+++ b/arch/arm/boot/dts/bcm2837.dtsi
c3110e3
@@ -44,6 +44,9 @@
e8f4892
 			reg = <0>;
e8f4892
 			enable-method = "spin-table";
e8f4892
 			cpu-release-addr = <0x0 0x000000d8>;
e8f4892
+			clocks = <&arm_clk>;
e8f4892
+			clock-names = "cpu";
e8f4892
+			operating-points-v2 = <&cpu0_opp_table>;
e8f4892
 		};
e8f4892
 
e8f4892
 		cpu1: cpu@1 {
c3110e3
@@ -52,6 +55,9 @@
e8f4892
 			reg = <1>;
e8f4892
 			enable-method = "spin-table";
e8f4892
 			cpu-release-addr = <0x0 0x000000e0>;
e8f4892
+			clocks = <&arm_clk>;
e8f4892
+			clock-names = "cpu";
e8f4892
+			operating-points-v2 = <&cpu0_opp_table>;
e8f4892
 		};
e8f4892
 
e8f4892
 		cpu2: cpu@2 {
c3110e3
@@ -60,6 +66,9 @@
e8f4892
 			reg = <2>;
e8f4892
 			enable-method = "spin-table";
e8f4892
 			cpu-release-addr = <0x0 0x000000e8>;
e8f4892
+			clocks = <&arm_clk>;
e8f4892
+			clock-names = "cpu";
e8f4892
+			operating-points-v2 = <&cpu0_opp_table>;
e8f4892
 		};
e8f4892
 
e8f4892
 		cpu3: cpu@3 {
c3110e3
@@ -68,6 +77,30 @@
e8f4892
 			reg = <3>;
e8f4892
 			enable-method = "spin-table";
e8f4892
 			cpu-release-addr = <0x0 0x000000f0>;
e8f4892
+			clocks = <&arm_clk>;
e8f4892
+			clock-names = "cpu";
e8f4892
+			operating-points-v2 = <&cpu0_opp_table>;
e8f4892
+		};
e8f4892
+	};
e8f4892
+
e8f4892
+	cpu0_opp_table: opp_table0 {
e8f4892
+		compatible = "operating-points-v2";
e8f4892
+		opp-shared;
e8f4892
+
e8f4892
+		opp@600000000 {
e8f4892
+			opp-hz = /bits/ 64 <600000000>;
e8f4892
+			clock-latency-ns = <355000>;
e8f4892
+			opp-suspend;
e8f4892
+		};
e8f4892
+
e8f4892
+		opp@900000000 {
e8f4892
+			opp-hz = /bits/ 64 <900000000>;
e8f4892
+			clock-latency-ns = <355000>;
e8f4892
+		};
e8f4892
+
e8f4892
+		opp@1200000000 {
e8f4892
+			opp-hz = /bits/ 64 <1200000000>;
e8f4892
+			clock-latency-ns = <355000>;
e8f4892
 		};
e8f4892
 	};
e8f4892
 };
e8f4892
diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig
e8f4892
index 4c4bd85f707c..e40bd19da22b 100644
e8f4892
--- a/drivers/clk/bcm/Kconfig
e8f4892
+++ b/drivers/clk/bcm/Kconfig
e8f4892
@@ -63,3 +63,11 @@ config CLK_BCM_SR
e8f4892
 	default ARCH_BCM_IPROC
e8f4892
 	help
e8f4892
 	  Enable common clock framework support for the Broadcom Stingray SoC
e8f4892
+
e8f4892
+config CLK_RASPBERRYPI_CPU
e8f4892
+	bool "Raspberry Pi CPU clock driver"
e8f4892
+	depends on ARCH_BCM2835 || (COMPILE_TEST && OF)
e8f4892
+	depends on RASPBERRYPI_FIRMWARE=y
e8f4892
+	help
e8f4892
+	  This enables support for the RPi CPU clock which can be adjusted
e8f4892
+	  via the RPi firmware.
e8f4892
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile
e8f4892
index 002661d39128..a028b0a90b6e 100644
e8f4892
--- a/drivers/clk/bcm/Makefile
e8f4892
+++ b/drivers/clk/bcm/Makefile
e8f4892
@@ -8,6 +8,7 @@ obj-$(CONFIG_COMMON_CLK_IPROC)	+= clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-a
e8f4892
 obj-$(CONFIG_ARCH_BCM2835)	+= clk-bcm2835.o
e8f4892
 obj-$(CONFIG_ARCH_BCM2835)	+= clk-bcm2835-aux.o
e8f4892
 obj-$(CONFIG_ARCH_BCM_53573)	+= clk-bcm53573-ilp.o
e8f4892
+obj-$(CONFIG_CLK_RASPBERRYPI_CPU)	+= clk-raspberrypi.o
e8f4892
 obj-$(CONFIG_CLK_BCM_CYGNUS)	+= clk-cygnus.o
e8f4892
 obj-$(CONFIG_CLK_BCM_HR2)	+= clk-hr2.o
e8f4892
 obj-$(CONFIG_CLK_BCM_NSP)	+= clk-nsp.o
e8f4892
diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
e8f4892
new file mode 100644
e8f4892
index 000000000000..046efc822a59
e8f4892
--- /dev/null
e8f4892
+++ b/drivers/clk/bcm/clk-raspberrypi.c
e8f4892
@@ -0,0 +1,138 @@
e8f4892
+// SPDX-License-Identifier: GPL-2.0+
e8f4892
+/*
e8f4892
+ * Raspberry Pi CPU clock driver
e8f4892
+ *
e8f4892
+ * Copyright (C) 2018 Stefan Wahren <stefan.wahren@i2se.com>
e8f4892
+ */
e8f4892
+
e8f4892
+#include <linux/clk.h>
e8f4892
+#include <linux/clk-provider.h>
e8f4892
+#include <linux/device.h>
e8f4892
+#include <linux/err.h>
e8f4892
+#include <linux/module.h>
e8f4892
+#include <linux/of_device.h>
e8f4892
+#include <linux/platform_device.h>
e8f4892
+#include <linux/slab.h>
e8f4892
+#include <soc/bcm2835/raspberrypi-firmware.h>
e8f4892
+
e8f4892
+#define VCMSG_ID_ARM_CLOCK 0x000000003	/* Clock/Voltage ID's */
e8f4892
+
e8f4892
+struct rpi_cpu_clkgen {
e8f4892
+	struct clk_hw hw;
e8f4892
+	struct rpi_firmware *fw;
e8f4892
+};
e8f4892
+
e8f4892
+/* tag part of the message */
e8f4892
+struct prop {
e8f4892
+       u32 id;			/* the ID of the clock/voltage to get or set */
e8f4892
+       u32 val;			/* the value (e.g. rate (in Hz)) to set */
e8f4892
+} __packed;
e8f4892
+
e8f4892
+static int rpi_cpu_clock_property(struct rpi_firmware *fw, u32 tag, u32 *val)
e8f4892
+{
e8f4892
+	int ret;
e8f4892
+	struct prop msg = {
e8f4892
+		.id = VCMSG_ID_ARM_CLOCK,
e8f4892
+		.val = *val,
e8f4892
+	};
e8f4892
+
e8f4892
+	ret = rpi_firmware_property(fw, tag, &msg, sizeof(msg));
e8f4892
+	if (ret)
e8f4892
+		return ret;
e8f4892
+
e8f4892
+	*val = msg.val;
e8f4892
+
e8f4892
+	return 0;
e8f4892
+}
e8f4892
+
e8f4892
+static unsigned long rpi_cpu_get_rate(struct clk_hw *hw,
e8f4892
+				      unsigned long parent_rate)
e8f4892
+{
e8f4892
+	struct rpi_cpu_clkgen *cpu = container_of(hw, struct rpi_cpu_clkgen, hw);
e8f4892
+	u32 rate = 0;
e8f4892
+
e8f4892
+	rpi_cpu_clock_property(cpu->fw, RPI_FIRMWARE_GET_CLOCK_RATE, &rate;;
e8f4892
+
e8f4892
+	return rate;
e8f4892
+}
e8f4892
+
e8f4892
+static long rpi_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
e8f4892
+				     unsigned long *parent_rate)
e8f4892
+{
e8f4892
+	return rate;
e8f4892
+}
e8f4892
+
e8f4892
+static int rpi_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
e8f4892
+			    unsigned long parent_rate)
e8f4892
+{
e8f4892
+	struct rpi_cpu_clkgen *cpu = container_of(hw, struct rpi_cpu_clkgen, hw);
e8f4892
+	u32 new_rate = rate;
e8f4892
+
e8f4892
+	return rpi_cpu_clock_property(cpu->fw, RPI_FIRMWARE_SET_CLOCK_RATE,
e8f4892
+				      &new_rate);
e8f4892
+}
e8f4892
+
e8f4892
+static const struct clk_ops rpi_cpu_ops = {
e8f4892
+	.recalc_rate = rpi_cpu_get_rate,
e8f4892
+	.round_rate = rpi_cpu_round_rate,
e8f4892
+	.set_rate = rpi_cpu_set_rate,
e8f4892
+};
e8f4892
+
e8f4892
+static int rpi_cpu_probe(struct platform_device *pdev)
e8f4892
+{
e8f4892
+	struct device *dev = &pdev->dev;
e8f4892
+	struct device_node *fw_node;
e8f4892
+	struct rpi_cpu_clkgen *cpu;
e8f4892
+	struct clk_init_data *init;
e8f4892
+	int ret;
e8f4892
+
e8f4892
+	cpu = devm_kzalloc(dev, sizeof(*cpu), GFP_KERNEL);
e8f4892
+	if (!cpu)
e8f4892
+		return -ENOMEM;
e8f4892
+
e8f4892
+	init = devm_kzalloc(dev, sizeof(*init), GFP_KERNEL);
e8f4892
+	if (!init)
e8f4892
+		return -ENOMEM;
e8f4892
+
e8f4892
+	fw_node = of_find_compatible_node(NULL, NULL,
e8f4892
+					  "raspberrypi,bcm2835-firmware");
e8f4892
+	if (!fw_node) {
e8f4892
+		dev_err(dev, "Missing firmware node\n");
e8f4892
+		return -ENOENT;
e8f4892
+	}
e8f4892
+
e8f4892
+	cpu->fw = rpi_firmware_get(fw_node);
e8f4892
+	of_node_put(fw_node);
e8f4892
+	if (!cpu->fw)
e8f4892
+		return -EPROBE_DEFER;
e8f4892
+
e8f4892
+	init->name = dev->of_node->name;
e8f4892
+	init->ops = &rpi_cpu_ops;
e8f4892
+
e8f4892
+	cpu->hw.init = init;
e8f4892
+	ret = devm_clk_hw_register(dev, &cpu->hw);
e8f4892
+	if (ret)
e8f4892
+		return ret;
e8f4892
+
e8f4892
+	return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get,
e8f4892
+				      &cpu->hw);
e8f4892
+}
e8f4892
+
e8f4892
+static const struct of_device_id rpi_cpu_of_match[] = {
e8f4892
+	{ .compatible = "raspberrypi,bcm2835-cpu", },
e8f4892
+	{},
e8f4892
+};
e8f4892
+MODULE_DEVICE_TABLE(of, rpi_cpu_of_match);
e8f4892
+
e8f4892
+static struct platform_driver rpi_cpu_driver = {
e8f4892
+	.driver = {
e8f4892
+		.name = "raspberrypi-cpu",
e8f4892
+		.of_match_table = rpi_cpu_of_match,
e8f4892
+	},
e8f4892
+	.probe		= rpi_cpu_probe,
e8f4892
+};
e8f4892
+builtin_platform_driver(rpi_cpu_driver);
e8f4892
+
e8f4892
+MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>");
e8f4892
+MODULE_DESCRIPTION("Raspberry Pi CPU clock driver");
e8f4892
+MODULE_LICENSE("GPL v2");
e8f4892
-- 
c3110e3
2.20.1
e8f4892
c3110e3
c3110e3
From 0681db63db37cf9015ef9b667c237c3974de04e6 Mon Sep 17 00:00:00 2001
c882c6b
From: Peter Robinson <pbrobinson@gmail.com>
c882c6b
Date: Mon, 4 Jun 2018 09:14:10 +0100
c3110e3
Subject: [PATCH 2/3] add 1.4 ghz OPP for the 3B+
c882c6b
c882c6b
Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
c882c6b
---
c882c6b
 arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 7 +++++++
c882c6b
 1 file changed, 7 insertions(+)
c882c6b
c882c6b
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
c3110e3
index 42bb09044cc7..3333c080696c 100644
c882c6b
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
c882c6b
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
c882c6b
@@ -106,3 +106,10 @@
c882c6b
 	pinctrl-0 = <&uart1_gpio14>;
c882c6b
 	status = "okay";
c882c6b
 };
c882c6b
+
c882c6b
+&cpu0_opp_table {
c882c6b
+	opp@1400000000 {
c882c6b
+		opp-hz = /bits/ 64 <1400000000>;
c882c6b
+		clock-latency-ns = <355000>;
c882c6b
+	};
c882c6b
+};
c882c6b
-- 
c3110e3
2.20.1
c3110e3
c882c6b
c3110e3
From 65f821f03ac635f28c8c79c5e436b398194521f2 Mon Sep 17 00:00:00 2001
49bf49c
From: Stefan Wahren <stefan.wahren@i2se.com>
49bf49c
Date: Wed, 26 Sep 2018 21:13:22 +0200
c3110e3
Subject: [PATCH 3/3] ARM: bcm2837: Use CPU0 as cooling device
49bf49c
49bf49c
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
49bf49c
---
49bf49c
 arch/arm/boot/dts/bcm2837.dtsi | 25 +++++++++++++++++++++++++
49bf49c
 arch/arm/boot/dts/bcm283x.dtsi |  2 +-
49bf49c
 2 files changed, 26 insertions(+), 1 deletion(-)
49bf49c
49bf49c
diff --git a/arch/arm/boot/dts/bcm2837.dtsi b/arch/arm/boot/dts/bcm2837.dtsi
c3110e3
index 9cfc553a3633..1590d94b618e 100644
49bf49c
--- a/arch/arm/boot/dts/bcm2837.dtsi
49bf49c
+++ b/arch/arm/boot/dts/bcm2837.dtsi
49bf49c
@@ -1,4 +1,5 @@
49bf49c
 #include "bcm283x.dtsi"
49bf49c
+#include <dt-bindings/thermal/thermal.h>
49bf49c
 
49bf49c
 / {
49bf49c
 	compatible = "brcm,bcm2837";
49bf49c
@@ -47,6 +48,7 @@
49bf49c
 			clocks = <&arm_clk>;
49bf49c
 			clock-names = "cpu";
49bf49c
 			operating-points-v2 = <&cpu0_opp_table>;
49bf49c
+			#cooling-cells = <2>;
49bf49c
 		};
49bf49c
 
49bf49c
 		cpu1: cpu@1 {
49bf49c
@@ -58,6 +60,7 @@
49bf49c
 			clocks = <&arm_clk>;
49bf49c
 			clock-names = "cpu";
49bf49c
 			operating-points-v2 = <&cpu0_opp_table>;
49bf49c
+			#cooling-cells = <2>;
49bf49c
 		};
49bf49c
 
49bf49c
 		cpu2: cpu@2 {
49bf49c
@@ -69,6 +72,7 @@
49bf49c
 			clocks = <&arm_clk>;
49bf49c
 			clock-names = "cpu";
49bf49c
 			operating-points-v2 = <&cpu0_opp_table>;
49bf49c
+			#cooling-cells = <2>;
49bf49c
 		};
49bf49c
 
49bf49c
 		cpu3: cpu@3 {
49bf49c
@@ -80,6 +84,7 @@
49bf49c
 			clocks = <&arm_clk>;
49bf49c
 			clock-names = "cpu";
49bf49c
 			operating-points-v2 = <&cpu0_opp_table>;
49bf49c
+			#cooling-cells = <2>;
49bf49c
 		};
49bf49c
 	};
49bf49c
 
49bf49c
@@ -117,6 +122,26 @@
49bf49c
 
49bf49c
 &cpu_thermal {
49bf49c
 	coefficients = <(-538)	412000>;
49bf49c
+
49bf49c
+	trips {
49bf49c
+		cpu_alert0: cpu-alert0 {
49bf49c
+			temperature	= <70000>;
49bf49c
+			hysteresis	= <0>;
49bf49c
+			type		= "passive";
49bf49c
+		};
49bf49c
+	};
49bf49c
+
49bf49c
+	cooling-maps {
49bf49c
+		map0 {
49bf49c
+			trip = <&cpu_alert0>;
49bf49c
+			cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
49bf49c
+		};
49bf49c
+
49bf49c
+		map1 {
49bf49c
+			trip = <&cpu_crit>;
49bf49c
+			cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
49bf49c
+		};
49bf49c
+	};
49bf49c
 };
49bf49c
 
49bf49c
 /* enable thermal sensor with the correct compatible property set */
49bf49c
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
c3110e3
index 31b29646b14c..2def0684d198 100644
49bf49c
--- a/arch/arm/boot/dts/bcm283x.dtsi
49bf49c
+++ b/arch/arm/boot/dts/bcm283x.dtsi
49bf49c
@@ -38,7 +38,7 @@
49bf49c
 			thermal-sensors = <&thermal>;
49bf49c
 
49bf49c
 			trips {
49bf49c
-				cpu-crit {
49bf49c
+				cpu_crit: cpu-crit {
49bf49c
 					temperature	= <80000>;
49bf49c
 					hysteresis	= <0>;
49bf49c
 					type		= "critical";
49bf49c
-- 
c3110e3
2.20.1
c3110e3