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@xxxxxxxxx> --- board/renesas/rcar-common/common.c | 46 ++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) 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; } -- 2.25.1