diff mbox series

[u-boot,2/3] ARM: renesas: Propagate RPC-IF enablement to subsequent software

Message ID 9e42cfdcb14eef5c75bbb8dd3e761b66257d492e.1648544792.git.geert+renesas@glider.be (mailing list archive)
State Handled Elsewhere
Delegated to: Geert Uytterhoeven
Headers show
Series renesas: Fix RPC-IF enablement | expand

Commit Message

Geert Uytterhoeven March 29, 2022, 12:19 p.m. UTC
As the Renesas Reduced Pin Count Interface may be locked by TF-A, it is
disabled by default[1].  When unlocked, TF-A passes a DT fragment to
enable it, which is applied to the U-Boot DT[2].

Unlike the memory layout, the RPC-IF enablement is not propagated to
subsequent software.  Hence e.g. Linux cannot know if the RPC-IF is
locked or not, and will lock-up when trying to access the RPC-IF when
locked.

Fix this by checking if the RPC-IF is enabled in the TF-A DT fragment, and
setting the status of the RPC-IF device node in the target DT, if
present, to "okay".  Do this only when a "flash" subnode is found, to
avoid errors in subsequent software when the RPC-IF is not intended to
be used.

Note that this requires the status of the RPC-IF node to be set to
"disabled" in the target DT, just like in the U-Boot DT.

[1] commit 3d5f45c95c9db73d ("ARM: dts: rmobile: Disable RPC HF by
    default")
[2] commit 361377dbdbc9f0f5 ("ARM: rmobile: Merge prior-stage firmware
    DT fragment into U-Boot DT on Gen3")

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 board/renesas/rcar-common/common.c | 46 ++++++++++++++++++++++++++++--
 1 file changed, 44 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/board/renesas/rcar-common/common.c b/board/renesas/rcar-common/common.c
index 0352d341e757bed9..daa1beb14f807800 100644
--- a/board/renesas/rcar-common/common.c
+++ b/board/renesas/rcar-common/common.c
@@ -9,6 +9,7 @@ 
 
 #include <common.h>
 #include <dm.h>
+#include <fdt_support.h>
 #include <init.h>
 #include <asm/global_data.h>
 #include <dm/uclass-internal.h>
@@ -19,9 +20,11 @@ 
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* If the firmware passed a device tree use it for U-Boot DRAM setup. */
+/* If the firmware passed a device tree use it for e.g. U-Boot DRAM setup. */
 extern u64 rcar_atf_boot_args[];
 
+#define FDT_RPC_PATH	"/soc/spi@ee200000"
+
 int fdtdec_board_setup(const void *fdt_blob)
 {
 	void *atf_fdt_blob = (void *)(rcar_atf_boot_args[1]);
@@ -81,7 +84,7 @@  static int is_mem_overlap(void *blob, int first_mem_node, int curr_mem_node)
 	return 0;
 }
 
-int ft_board_setup(void *blob, struct bd_info *bd)
+static void scrub_duplicate_memory(void *blob)
 {
 	/*
 	 * Scrub duplicate /memory@* node entries here. Some R-Car DTs might
@@ -119,6 +122,45 @@  int ft_board_setup(void *blob, struct bd_info *bd)
 		first_mem_node = 0;
 		mem = 0;
 	}
+}
+
+static void update_rpc_status(void *blob)
+{
+	void *atf_fdt_blob = (void *)(rcar_atf_boot_args[1]);
+	int offset, enabled;
+
+	/*
+	 * Check if the DT fragment received from TF-A had its RPC-IF device node
+	 * enabled.
+	 */
+	if (fdt_magic(atf_fdt_blob) != FDT_MAGIC)
+		return;
+
+	offset = fdt_path_offset(atf_fdt_blob, FDT_RPC_PATH);
+	if (offset < 0)
+		return;
+
+	enabled = fdtdec_get_is_enabled(atf_fdt_blob, offset);
+	if (!enabled)
+		return;
+
+	/*
+	 * Find the RPC-IF device node, and enable it if it has a flash subnode.
+	 */
+	offset = fdt_path_offset(blob, FDT_RPC_PATH);
+	if (offset < 0)
+		return;
+
+	if (fdt_subnode_offset(blob, offset, "flash") < 0)
+		return;
+
+	fdt_status_okay(blob, offset);
+}
+
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+	scrub_duplicate_memory(blob);
+	update_rpc_status(blob);
 
 	return 0;
 }