From 90bd324fb23dd2f4e8d53a54e12bcd99073e91db Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Wed, 26 Mar 2025 15:46:03 +0000
Subject: [PATCH] overlay: Rework/fix the Pi 5 MIDI UART overlays

The old Pi 5 MIDI UART overlays replaced the reference to the UART's
source clock with a fixed clock (essentially an integer dressed up like
a clock). This is fragile, in that the fixed clock must be updated if
the source clock's (fixed) frequency is ever changed, but it also relies
on the source clock having been enabled, which is likely not to be the
case unless another RP1 UART is being actively used.

Switching to a fixed-factor-clock solves both of those problems.

See: https://forums.raspberrypi.com/viewtopic.php?t=385906

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
 .../dts/overlays/midi-uart0-pi5-overlay.dts   | 20 ++++++++++---------
 .../dts/overlays/midi-uart1-pi5-overlay.dts   | 20 ++++++++++---------
 .../dts/overlays/midi-uart2-pi5-overlay.dts   | 20 ++++++++++---------
 .../dts/overlays/midi-uart3-pi5-overlay.dts   | 20 ++++++++++---------
 .../dts/overlays/midi-uart4-pi5-overlay.dts   | 20 ++++++++++---------
 5 files changed, 55 insertions(+), 45 deletions(-)

--- a/arch/arm/boot/dts/overlays/midi-uart0-pi5-overlay.dts
+++ b/arch/arm/boot/dts/overlays/midi-uart0-pi5-overlay.dts
@@ -5,23 +5,24 @@
 
 /*
  * Fake a higher clock rate to get a larger divisor, and thereby a lower
- * baudrate. The real clock is 50MHz, which we scale so that requesting
- * 38.4kHz results in an actual 31.25kHz.
- *
- *   50000000*38400/31250 = 61440000
+ * baudrate. Create an intermediary clock that reports the real clock frequency
+ * multiplied by 38400/31250. This will result in the UART's clock divisor being
+ * greater by a factor of 38400/31250, such that requesting 38.4kHz results in
+ * an actual 31.25kHz.
  */
 
 /{
 	compatible = "brcm,bcm2712";
 
 	fragment@0 {
-		target-path = "/";
+		target-path = "/clocks";
 		__overlay__ {
-			midi_clk: midi_clk0 {
-				compatible = "fixed-clock";
+			midi_clk: midiclock_0 {
+				compatible = "fixed-factor-clock";
 				#clock-cells = <0>;
-				clock-output-names = "uart0_pclk";
-				clock-frequency = <61440000>;
+				clocks = <&rp1_clocks RP1_CLK_UART>;
+				clock-mult = <38400>;
+				clock-div  = <31250>;
 			};
 		};
 	};
@@ -29,6 +30,7 @@
 	fragment@1 {
 		target = <&uart0>;
 		__overlay__ {
+			status = "okay";
 			clocks = <&midi_clk &rp1_clocks RP1_PLL_SYS_PRI_PH>;
 		};
 	};
--- a/arch/arm/boot/dts/overlays/midi-uart1-pi5-overlay.dts
+++ b/arch/arm/boot/dts/overlays/midi-uart1-pi5-overlay.dts
@@ -5,23 +5,24 @@
 
 /*
  * Fake a higher clock rate to get a larger divisor, and thereby a lower
- * baudrate. The real clock is 50MHz, which we scale so that requesting
- * 38.4kHz results in an actual 31.25kHz.
- *
- *   50000000*38400/31250 = 61440000
+ * baudrate. Create an intermediary clock that reports the real clock frequency
+ * multiplied by 38400/31250. This will result in the UART's clock divisor being
+ * greater by a factor of 38400/31250, such that requesting 38.4kHz results in
+ * an actual 31.25kHz.
  */
 
 /{
 	compatible = "brcm,bcm2712";
 
 	fragment@0 {
-		target-path = "/";
+		target-path = "/clocks";
 		__overlay__ {
-			midi_clk: midi_clk1 {
-				compatible = "fixed-clock";
+			midi_clk: midiclock_1 {
+				compatible = "fixed-factor-clock";
 				#clock-cells = <0>;
-				clock-output-names = "uart1_pclk";
-				clock-frequency = <61440000>;
+				clocks = <&rp1_clocks RP1_CLK_UART>;
+				clock-mult = <38400>;
+				clock-div  = <31250>;
 			};
 		};
 	};
@@ -29,6 +30,7 @@
 	fragment@1 {
 		target = <&uart1>;
 		__overlay__ {
+			status = "okay";
 			clocks = <&midi_clk &rp1_clocks RP1_PLL_SYS_PRI_PH>;
 		};
 	};
--- a/arch/arm/boot/dts/overlays/midi-uart2-pi5-overlay.dts
+++ b/arch/arm/boot/dts/overlays/midi-uart2-pi5-overlay.dts
@@ -5,23 +5,24 @@
 
 /*
  * Fake a higher clock rate to get a larger divisor, and thereby a lower
- * baudrate. The real clock is 50MHz, which we scale so that requesting
- * 38.4kHz results in an actual 31.25kHz.
- *
- *   50000000*38400/31250 = 61440000
+ * baudrate. Create an intermediary clock that reports the real clock frequency
+ * multiplied by 38400/31250. This will result in the UART's clock divisor being
+ * greater by a factor of 38400/31250, such that requesting 38.4kHz results in
+ * an actual 31.25kHz.
  */
 
 /{
 	compatible = "brcm,bcm2712";
 
 	fragment@0 {
-		target-path = "/";
+		target-path = "/clocks";
 		__overlay__ {
-			midi_clk: midi_clk2 {
-				compatible = "fixed-clock";
+			midi_clk: midiclock_2 {
+				compatible = "fixed-factor-clock";
 				#clock-cells = <0>;
-				clock-output-names = "uart2_pclk";
-				clock-frequency = <61440000>;
+				clocks = <&rp1_clocks RP1_CLK_UART>;
+				clock-mult = <38400>;
+				clock-div  = <31250>;
 			};
 		};
 	};
@@ -29,6 +30,7 @@
 	fragment@1 {
 		target = <&uart2>;
 		__overlay__ {
+			status = "okay";
 			clocks = <&midi_clk &rp1_clocks RP1_PLL_SYS_PRI_PH>;
 		};
 	};
--- a/arch/arm/boot/dts/overlays/midi-uart3-pi5-overlay.dts
+++ b/arch/arm/boot/dts/overlays/midi-uart3-pi5-overlay.dts
@@ -5,23 +5,24 @@
 
 /*
  * Fake a higher clock rate to get a larger divisor, and thereby a lower
- * baudrate. The real clock is 50MHz, which we scale so that requesting
- * 38.4kHz results in an actual 31.25kHz.
- *
- *   50000000*38400/31250 = 61440000
+ * baudrate. Create an intermediary clock that reports the real clock frequency
+ * multiplied by 38400/31250. This will result in the UART's clock divisor being
+ * greater by a factor of 38400/31250, such that requesting 38.4kHz results in
+ * an actual 31.25kHz.
  */
 
 /{
 	compatible = "brcm,bcm2712";
 
 	fragment@0 {
-		target-path = "/";
+		target-path = "/clocks";
 		__overlay__ {
-			midi_clk: midi_clk3 {
-				compatible = "fixed-clock";
+			midi_clk: midiclock_3 {
+				compatible = "fixed-factor-clock";
 				#clock-cells = <0>;
-				clock-output-names = "uart3_pclk";
-				clock-frequency = <61440000>;
+				clocks = <&rp1_clocks RP1_CLK_UART>;
+				clock-mult = <38400>;
+				clock-div  = <31250>;
 			};
 		};
 	};
@@ -29,6 +30,7 @@
 	fragment@1 {
 		target = <&uart3>;
 		__overlay__ {
+			status = "okay";
 			clocks = <&midi_clk &rp1_clocks RP1_PLL_SYS_PRI_PH>;
 		};
 	};
--- a/arch/arm/boot/dts/overlays/midi-uart4-pi5-overlay.dts
+++ b/arch/arm/boot/dts/overlays/midi-uart4-pi5-overlay.dts
@@ -5,23 +5,24 @@
 
 /*
  * Fake a higher clock rate to get a larger divisor, and thereby a lower
- * baudrate. The real clock is 50MHz, which we scale so that requesting
- * 38.4kHz results in an actual 31.25kHz.
- *
- *   50000000*38400/31250 = 61440000
+ * baudrate. Create an intermediary clock that reports the real clock frequency
+ * multiplied by 38400/31250. This will result in the UART's clock divisor being
+ * greater by a factor of 38400/31250, such that requesting 38.4kHz results in
+ * an actual 31.25kHz.
  */
 
 /{
 	compatible = "brcm,bcm2712";
 
 	fragment@0 {
-		target-path = "/";
+		target-path = "/clocks";
 		__overlay__ {
-			midi_clk: midi_clk4 {
-				compatible = "fixed-clock";
+			midi_clk: midiclock_4 {
+				compatible = "fixed-factor-clock";
 				#clock-cells = <0>;
-				clock-output-names = "uart4_pclk";
-				clock-frequency = <61440000>;
+				clocks = <&rp1_clocks RP1_CLK_UART>;
+				clock-mult = <38400>;
+				clock-div  = <31250>;
 			};
 		};
 	};
@@ -29,6 +30,7 @@
 	fragment@1 {
 		target = <&uart4>;
 		__overlay__ {
+			status = "okay";
 			clocks = <&midi_clk &rp1_clocks RP1_PLL_SYS_PRI_PH>;
 		};
 	};
