1 // SPDX-License-Identifier: GPL-2.0
3 * board/renesas/rcar-common/common.c
5 * Copyright (C) 2013 Renesas Electronics Corporation
6 * Copyright (C) 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
7 * Copyright (C) 2015 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
12 #include <fdt_support.h>
15 #include <asm/global_data.h>
17 #include <dm/uclass-internal.h>
18 #include <asm/arch/rmobile.h>
19 #include <linux/libfdt.h>
23 DECLARE_GLOBAL_DATA_PTR
;
25 /* If the firmware passed a device tree use it for e.g. U-Boot DRAM setup. */
26 extern u64 rcar_atf_boot_args
[];
28 #define FDT_RPC_PATH "/soc/spi@ee200000"
30 static void apply_atf_overlay(void *fdt_blob
)
32 void *atf_fdt_blob
= (void *)(rcar_atf_boot_args
[1]);
34 if (fdt_magic(atf_fdt_blob
) == FDT_MAGIC
)
35 fdt_overlay_apply_node(fdt_blob
, 0, atf_fdt_blob
, 0);
38 int fdtdec_board_setup(const void *fdt_blob
)
40 apply_atf_overlay((void *)fdt_blob
);
47 return fdtdec_setup_mem_size_base();
50 int dram_init_banksize(void)
52 fdtdec_setup_memory_banksize();
57 int __weak
board_init(void)
62 #if defined(CONFIG_RCAR_GEN3)
63 #define RST_BASE 0xE6160000
64 #define RST_CA57RESCNT (RST_BASE + 0x40)
65 #define RST_CA53RESCNT (RST_BASE + 0x44)
66 #define RST_RSTOUTCR (RST_BASE + 0x58)
67 #define RST_CA57_CODE 0xA5A5000F
68 #define RST_CA53_CODE 0x5A5A000F
70 void __weak
reset_cpu(void)
72 unsigned long midr
, cputype
;
74 asm volatile("mrs %0, midr_el1" : "=r" (midr
));
75 cputype
= (midr
>> 4) & 0xfff;
78 writel(RST_CA53_CODE
, RST_CA53RESCNT
);
79 else if (cputype
== 0xd07)
80 writel(RST_CA57_CODE
, RST_CA57RESCNT
);
84 #elif defined(CONFIG_RCAR_GEN4)
85 #define RST_BASE 0xE6160000 /* Domain0 */
86 #define RST_SRESCR0 (RST_BASE + 0x18)
87 #define RST_SPRES 0x5AA58000
89 void __weak
reset_cpu(void)
91 writel(RST_SPRES
, RST_SRESCR0
);
94 #error Neither CONFIG_RCAR_GEN3 nor CONFIG_RCAR_GEN4 are set
97 #if defined(CONFIG_OF_BOARD_SETUP)
98 static int is_mem_overlap(void *blob
, int first_mem_node
, int curr_mem_node
)
100 struct fdt_resource first_mem_res
, curr_mem_res
;
101 int curr_mem_reg
, first_mem_reg
= 0;
105 ret
= fdt_get_resource(blob
, first_mem_node
, "reg",
106 first_mem_reg
++, &first_mem_res
);
107 if (ret
) /* No more entries, no overlap found */
112 ret
= fdt_get_resource(blob
, curr_mem_node
, "reg",
113 curr_mem_reg
++, &curr_mem_res
);
114 if (ret
) /* No more entries, check next tuple */
117 if (curr_mem_res
.end
< first_mem_res
.start
)
120 if (curr_mem_res
.start
>= first_mem_res
.end
)
123 log_debug("Overlap found: 0x%llx..0x%llx / 0x%llx..0x%llx\n",
124 first_mem_res
.start
, first_mem_res
.end
,
125 curr_mem_res
.start
, curr_mem_res
.end
);
134 static void scrub_duplicate_memory(void *blob
)
137 * Scrub duplicate /memory@* node entries here. Some R-Car DTs might
138 * contain multiple /memory@* nodes, however fdt_fixup_memory_banks()
139 * either generates single /memory node or updates the first /memory
140 * node. Any remaining memory nodes are thus potential duplicates.
142 * However, it is not possible to delete all the memory nodes right
143 * away, since some of those might not be DRAM memory nodes, but some
144 * sort of other memory. Thus, delete only the memory nodes which are
145 * in the R-Car3 DBSC ranges.
147 int mem
= 0, first_mem_node
= 0;
150 mem
= fdt_node_offset_by_prop_value(blob
, mem
,
151 "device_type", "memory", 7);
154 if (!fdtdec_get_is_enabled(blob
, mem
))
157 /* First memory node, patched by U-Boot */
158 if (!first_mem_node
) {
159 first_mem_node
= mem
;
163 /* Check the remaining nodes and delete duplicates */
164 if (!is_mem_overlap(blob
, first_mem_node
, mem
))
167 /* Delete duplicate node, start again */
168 fdt_del_node(blob
, mem
);
174 static void update_rpc_status(void *blob
)
176 void *atf_fdt_blob
= (void *)(rcar_atf_boot_args
[1]);
180 * Check if the DT fragment received from TF-A had its RPC-IF device node
183 if (fdt_magic(atf_fdt_blob
) != FDT_MAGIC
)
186 offset
= fdt_path_offset(atf_fdt_blob
, FDT_RPC_PATH
);
190 enabled
= fdtdec_get_is_enabled(atf_fdt_blob
, offset
);
195 * Find the RPC-IF device node, and enable it if it has a flash subnode.
197 offset
= fdt_path_offset(blob
, FDT_RPC_PATH
);
201 if (fdt_subnode_offset(blob
, offset
, "flash") < 0)
204 fdt_status_okay(blob
, offset
);
207 int ft_board_setup(void *blob
, struct bd_info
*bd
)
209 apply_atf_overlay(blob
);
210 scrub_duplicate_memory(blob
);
211 update_rpc_status(blob
);