blob: bede82e8942ac43f224abb27fc0d6f4fddb65bef [file] [log] [blame]
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001/*
Takuya Sakatacb9efd82021-12-01 13:42:54 +09002 * Copyright (c) 2018-2023, Renesas Electronics Corporation. All rights reserved.
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Scott Brandene5dcf982020-08-25 13:49:32 -07007#include <inttypes.h>
8#include <stdint.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009#include <string.h>
10
Marek Vasut93c85fc2018-10-02 20:45:18 +020011#include <libfdt.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000012
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020013#include <platform_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000014
15#include <arch_helpers.h>
16#include <bl1/bl1.h>
17#include <common/bl_common.h>
18#include <common/debug.h>
19#include <common/desc_image_load.h>
Marek Vasutb25ee352021-02-13 19:09:29 +010020#include <common/image_decompress.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000021#include <drivers/console.h>
Toshiyuki Ogasahara04f16282019-12-13 14:43:52 +090022#include <drivers/io/io_driver.h>
23#include <drivers/io/io_storage.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000024#include <lib/mmio.h>
25#include <lib/xlat_tables/xlat_tables_defs.h>
26#include <plat/common/platform.h>
Marek Vasutb25ee352021-02-13 19:09:29 +010027#if RCAR_GEN3_BL33_GZIP == 1
28#include <tf_gunzip.h>
29#endif
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020030
31#include "avs_driver.h"
32#include "boot_init_dram.h"
33#include "cpg_registers.h"
34#include "board.h"
35#include "emmc_def.h"
36#include "emmc_hal.h"
37#include "emmc_std.h"
38
39#if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR
40#include "iic_dvfs.h"
41#endif
42
43#include "io_common.h"
Toshiyuki Ogasahara04f16282019-12-13 14:43:52 +090044#include "io_rcar.h"
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020045#include "qos_init.h"
46#include "rcar_def.h"
47#include "rcar_private.h"
48#include "rcar_version.h"
49#include "rom_api.h"
50
Madhukar Pappireddyfc9b4112019-12-23 14:49:52 -060051/*
Toshiyuki Ogasahara18fb4d82021-07-12 18:33:42 +090052 * Following symbols are only used during plat_arch_setup()
Madhukar Pappireddyfc9b4112019-12-23 14:49:52 -060053 */
54static const uint64_t BL2_RO_BASE = BL_CODE_BASE;
55static const uint64_t BL2_RO_LIMIT = BL_CODE_END;
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020056
57#if USE_COHERENT_MEM
Madhukar Pappireddyfc9b4112019-12-23 14:49:52 -060058static const uint64_t BL2_COHERENT_RAM_BASE = BL_COHERENT_RAM_BASE;
59static const uint64_t BL2_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END;
60#endif
61
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020062extern void plat_rcar_gic_driver_init(void);
63extern void plat_rcar_gic_init(void);
64extern void bl2_enter_bl31(const struct entry_point_info *bl_ep_info);
65extern void bl2_system_cpg_init(void);
66extern void bl2_secure_setting(void);
Toshiyuki Ogasahara22c44b92021-07-12 18:39:52 +090067extern void bl2_ram_security_setting_finish(void);
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020068extern void bl2_cpg_init(void);
69extern void rcar_io_emmc_setup(void);
70extern void rcar_io_setup(void);
71extern void rcar_swdt_release(void);
72extern void rcar_swdt_init(void);
73extern void rcar_rpc_init(void);
74extern void rcar_pfc_init(void);
75extern void rcar_dma_init(void);
76
Marek Vasut1eca7782018-12-28 20:12:13 +010077static void bl2_init_generic_timer(void);
78
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020079/* R-Car Gen3 product check */
80#if (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N)
Marek Vasut9cadc782019-08-06 19:13:22 +020081#define TARGET_PRODUCT PRR_PRODUCT_H3
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020082#define TARGET_NAME "R-Car H3"
83#elif RCAR_LSI == RCAR_M3
Marek Vasut9cadc782019-08-06 19:13:22 +020084#define TARGET_PRODUCT PRR_PRODUCT_M3
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020085#define TARGET_NAME "R-Car M3"
86#elif RCAR_LSI == RCAR_M3N
Marek Vasut9cadc782019-08-06 19:13:22 +020087#define TARGET_PRODUCT PRR_PRODUCT_M3N
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020088#define TARGET_NAME "R-Car M3N"
Valentine Barshakf2184142018-10-30 02:06:17 +030089#elif RCAR_LSI == RCAR_V3M
Marek Vasut9cadc782019-08-06 19:13:22 +020090#define TARGET_PRODUCT PRR_PRODUCT_V3M
Valentine Barshakf2184142018-10-30 02:06:17 +030091#define TARGET_NAME "R-Car V3M"
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020092#elif RCAR_LSI == RCAR_E3
Marek Vasut9cadc782019-08-06 19:13:22 +020093#define TARGET_PRODUCT PRR_PRODUCT_E3
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020094#define TARGET_NAME "R-Car E3"
Marek Vasut4ae342c2019-01-05 13:56:03 +010095#elif RCAR_LSI == RCAR_D3
Marek Vasut9cadc782019-08-06 19:13:22 +020096#define TARGET_PRODUCT PRR_PRODUCT_D3
Marek Vasut4ae342c2019-01-05 13:56:03 +010097#define TARGET_NAME "R-Car D3"
Marek Vasut94cc0f82018-12-28 20:11:26 +010098#elif RCAR_LSI == RCAR_AUTO
Valentine Barshakf2184142018-10-30 02:06:17 +030099#define TARGET_NAME "R-Car H3/M3/M3N/V3M"
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200100#endif
101
102#if (RCAR_LSI == RCAR_E3)
103#define GPIO_INDT (GPIO_INDT6)
104#define GPIO_BKUP_TRG_SHIFT ((uint32_t)1U<<13U)
105#else
106#define GPIO_INDT (GPIO_INDT1)
107#define GPIO_BKUP_TRG_SHIFT ((uint32_t)1U<<8U)
108#endif
109
110CASSERT((PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t) + 0x100)
111 < (RCAR_SHARED_MEM_BASE + RCAR_SHARED_MEM_SIZE),
112 assert_bl31_params_do_not_fit_in_shared_memory);
113
114static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
115
Marek Vasut93c85fc2018-10-02 20:45:18 +0200116/* FDT with DRAM configuration */
117uint64_t fdt_blob[PAGE_SIZE_4KB / sizeof(uint64_t)];
118static void *fdt = (void *)fdt_blob;
119
120static void unsigned_num_print(unsigned long long int unum, unsigned int radix,
121 char *string)
122{
123 /* Just need enough space to store 64 bit decimal integer */
124 char num_buf[20];
125 int i = 0;
126 unsigned int rem;
127
128 do {
129 rem = unum % radix;
130 if (rem < 0xa)
131 num_buf[i] = '0' + rem;
132 else
133 num_buf[i] = 'a' + (rem - 0xa);
134 i++;
135 unum /= radix;
136 } while (unum > 0U);
137
138 while (--i >= 0)
139 *string++ = num_buf[i];
Marek Vasut64299332020-04-11 19:02:29 +0200140 *string = 0;
Marek Vasut93c85fc2018-10-02 20:45:18 +0200141}
142
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200143#if (RCAR_LOSSY_ENABLE == 1)
144typedef struct bl2_lossy_info {
145 uint32_t magic;
146 uint32_t a0;
147 uint32_t b0;
148} bl2_lossy_info_t;
149
Marek Vasut4d693c22018-10-11 16:53:58 +0200150static void bl2_lossy_gen_fdt(uint32_t no, uint64_t start_addr,
151 uint64_t end_addr, uint32_t format,
152 uint32_t enable, int fcnlnode)
153{
154 const uint64_t fcnlsize = cpu_to_fdt64(end_addr - start_addr);
155 char nodename[40] = { 0 };
156 int ret, node;
157
158 /* Ignore undefined addresses */
159 if (start_addr == 0 && end_addr == 0)
160 return;
161
162 snprintf(nodename, sizeof(nodename), "lossy-decompression@");
163 unsigned_num_print(start_addr, 16, nodename + strlen(nodename));
164
165 node = ret = fdt_add_subnode(fdt, fcnlnode, nodename);
166 if (ret < 0) {
167 NOTICE("BL2: Cannot create FCNL node (ret=%i)\n", ret);
168 panic();
169 }
170
171 ret = fdt_setprop_string(fdt, node, "compatible",
172 "renesas,lossy-decompression");
173 if (ret < 0) {
174 NOTICE("BL2: Cannot add FCNL compat string (ret=%i)\n", ret);
175 panic();
176 }
177
178 ret = fdt_appendprop_string(fdt, node, "compatible",
179 "shared-dma-pool");
180 if (ret < 0) {
181 NOTICE("BL2: Cannot append FCNL compat string (ret=%i)\n", ret);
182 panic();
183 }
184
185 ret = fdt_setprop_u64(fdt, node, "reg", start_addr);
186 if (ret < 0) {
187 NOTICE("BL2: Cannot add FCNL reg prop (ret=%i)\n", ret);
188 panic();
189 }
190
191 ret = fdt_appendprop(fdt, node, "reg", &fcnlsize, sizeof(fcnlsize));
192 if (ret < 0) {
193 NOTICE("BL2: Cannot append FCNL reg size prop (ret=%i)\n", ret);
194 panic();
195 }
196
197 ret = fdt_setprop(fdt, node, "no-map", NULL, 0);
198 if (ret < 0) {
199 NOTICE("BL2: Cannot add FCNL no-map prop (ret=%i)\n", ret);
200 panic();
201 }
202
203 ret = fdt_setprop_u32(fdt, node, "renesas,formats", format);
204 if (ret < 0) {
205 NOTICE("BL2: Cannot add FCNL formats prop (ret=%i)\n", ret);
206 panic();
207 }
208}
209
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200210static void bl2_lossy_setting(uint32_t no, uint64_t start_addr,
211 uint64_t end_addr, uint32_t format,
Marek Vasut4d693c22018-10-11 16:53:58 +0200212 uint32_t enable, int fcnlnode)
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200213{
214 bl2_lossy_info_t info;
215 uint32_t reg;
216
Marek Vasut4d693c22018-10-11 16:53:58 +0200217 bl2_lossy_gen_fdt(no, start_addr, end_addr, format, enable, fcnlnode);
218
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200219 reg = format | (start_addr >> 20);
220 mmio_write_32(AXI_DCMPAREACRA0 + 0x8 * no, reg);
221 mmio_write_32(AXI_DCMPAREACRB0 + 0x8 * no, end_addr >> 20);
222 mmio_write_32(AXI_DCMPAREACRA0 + 0x8 * no, reg | enable);
223
224 info.magic = 0x12345678U;
225 info.a0 = mmio_read_32(AXI_DCMPAREACRA0 + 0x8 * no);
226 info.b0 = mmio_read_32(AXI_DCMPAREACRB0 + 0x8 * no);
227
228 mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no, info.magic);
229 mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x4, info.a0);
230 mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x8, info.b0);
231
232 NOTICE(" Entry %d: DCMPAREACRAx:0x%x DCMPAREACRBx:0x%x\n", no,
233 mmio_read_32(AXI_DCMPAREACRA0 + 0x8 * no),
234 mmio_read_32(AXI_DCMPAREACRB0 + 0x8 * no));
235}
Detlev Casanova8348acd2022-12-01 17:57:31 -0500236
237static int bl2_create_reserved_memory(void)
238{
239 int ret;
240
241 int fcnlnode = fdt_add_subnode(fdt, 0, "reserved-memory");
242 if (fcnlnode < 0) {
243 NOTICE("BL2: Cannot create reserved mem node (ret=%i)\n",
244 fcnlnode);
245 panic();
246 }
247
248 ret = fdt_setprop(fdt, fcnlnode, "ranges", NULL, 0);
249 if (ret < 0) {
250 NOTICE("BL2: Cannot add FCNL ranges prop (ret=%i)\n", ret);
251 panic();
252 }
253
254 ret = fdt_setprop_u32(fdt, fcnlnode, "#address-cells", 2);
255 if (ret < 0) {
256 NOTICE("BL2: Cannot add FCNL #address-cells prop (ret=%i)\n", ret);
257 panic();
258 }
259
260 ret = fdt_setprop_u32(fdt, fcnlnode, "#size-cells", 2);
261 if (ret < 0) {
262 NOTICE("BL2: Cannot add FCNL #size-cells prop (ret=%i)\n", ret);
263 panic();
264 }
265
266 return fcnlnode;
267}
268
269static void bl2_create_fcnl_reserved_memory(void)
270{
271 int fcnlnode;
272
273 NOTICE("BL2: Lossy Decomp areas\n");
274
275 fcnlnode = bl2_create_reserved_memory();
276
277 bl2_lossy_setting(0, LOSSY_ST_ADDR0, LOSSY_END_ADDR0,
278 LOSSY_FMT0, LOSSY_ENA_DIS0, fcnlnode);
279 bl2_lossy_setting(1, LOSSY_ST_ADDR1, LOSSY_END_ADDR1,
280 LOSSY_FMT1, LOSSY_ENA_DIS1, fcnlnode);
281 bl2_lossy_setting(2, LOSSY_ST_ADDR2, LOSSY_END_ADDR2,
282 LOSSY_FMT2, LOSSY_ENA_DIS2, fcnlnode);
283}
284#else
285static void bl2_create_fcnl_reserved_memory(void) {}
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200286#endif
287
288void bl2_plat_flush_bl31_params(void)
289{
290 uint32_t product_cut, product, cut;
291 uint32_t boot_dev, boot_cpu;
292 uint32_t lcs, reg, val;
293
294 reg = mmio_read_32(RCAR_MODEMR);
295 boot_dev = reg & MODEMR_BOOT_DEV_MASK;
296
297 if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 ||
298 boot_dev == MODEMR_BOOT_DEV_EMMC_50X8)
299 emmc_terminate();
300
301 if ((reg & MODEMR_BOOT_CPU_MASK) != MODEMR_BOOT_CPU_CR7)
302 bl2_secure_setting();
303
304 reg = mmio_read_32(RCAR_PRR);
Marek Vasut9cadc782019-08-06 19:13:22 +0200305 product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK);
306 product = reg & PRR_PRODUCT_MASK;
307 cut = reg & PRR_CUT_MASK;
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200308
Marek Vasut9cadc782019-08-06 19:13:22 +0200309 if (product == PRR_PRODUCT_M3 && PRR_PRODUCT_30 > cut)
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200310 goto tlb;
311
Marek Vasut9cadc782019-08-06 19:13:22 +0200312 if (product == PRR_PRODUCT_H3 && PRR_PRODUCT_20 > cut)
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200313 goto tlb;
314
315 /* Disable MFIS write protection */
316 mmio_write_32(MFISWPCNTR, MFISWPCNTR_PASSWORD | 1);
317
318tlb:
319 reg = mmio_read_32(RCAR_MODEMR);
320 boot_cpu = reg & MODEMR_BOOT_CPU_MASK;
321 if (boot_cpu != MODEMR_BOOT_CPU_CA57 &&
322 boot_cpu != MODEMR_BOOT_CPU_CA53)
323 goto mmu;
324
Marek Vasut9cadc782019-08-06 19:13:22 +0200325 if (product_cut == PRR_PRODUCT_H3_CUT20) {
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200326 mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE);
327 mmio_write_32(IPMMUVI1_IMSCTLR, IMSCTLR_DISCACHE);
328 mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE);
329 mmio_write_32(IPMMUPV1_IMSCTLR, IMSCTLR_DISCACHE);
330 mmio_write_32(IPMMUPV2_IMSCTLR, IMSCTLR_DISCACHE);
331 mmio_write_32(IPMMUPV3_IMSCTLR, IMSCTLR_DISCACHE);
Marek Vasut9cadc782019-08-06 19:13:22 +0200332 } else if (product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) ||
333 product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11)) {
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200334 mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE);
335 mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE);
Marek Vasut9cadc782019-08-06 19:13:22 +0200336 } else if ((product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) ||
337 (product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_11))) {
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200338 mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE);
Marek Vasute6208012018-12-31 16:48:04 +0100339 mmio_write_32(IPMMUVP0_IMSCTLR, IMSCTLR_DISCACHE);
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200340 mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE);
341 }
342
Marek Vasut9cadc782019-08-06 19:13:22 +0200343 if (product_cut == (PRR_PRODUCT_H3_CUT20) ||
344 product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) ||
345 product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11) ||
346 product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) {
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200347 mmio_write_32(IPMMUHC_IMSCTLR, IMSCTLR_DISCACHE);
348 mmio_write_32(IPMMURT_IMSCTLR, IMSCTLR_DISCACHE);
349 mmio_write_32(IPMMUMP_IMSCTLR, IMSCTLR_DISCACHE);
350
351 mmio_write_32(IPMMUDS0_IMSCTLR, IMSCTLR_DISCACHE);
352 mmio_write_32(IPMMUDS1_IMSCTLR, IMSCTLR_DISCACHE);
353 }
354
355mmu:
356 mmio_write_32(IPMMUMM_IMSCTLR, IPMMUMM_IMSCTLR_ENABLE);
357 mmio_write_32(IPMMUMM_IMAUXCTLR, IPMMUMM_IMAUXCTLR_NMERGE40_BIT);
358
359 val = rcar_rom_get_lcs(&lcs);
360 if (val) {
361 ERROR("BL2: Failed to get the LCS. (%d)\n", val);
362 panic();
363 }
364
365 if (lcs == LCS_SE)
366 mmio_clrbits_32(P_ARMREG_SEC_CTRL, P_ARMREG_SEC_CTRL_PROT);
367
368 rcar_swdt_release();
369 bl2_system_cpg_init();
370
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200371 /* Disable data cache (clean and invalidate) */
372 disable_mmu_el3();
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200373}
374
375static uint32_t is_ddr_backup_mode(void)
376{
377#if RCAR_SYSTEM_SUSPEND
378 static uint32_t reason = RCAR_COLD_BOOT;
379 static uint32_t once;
380
381#if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR
382 uint8_t data;
383#endif
384 if (once)
385 return reason;
386
387 once = 1;
388 if ((mmio_read_32(GPIO_INDT) & GPIO_BKUP_TRG_SHIFT) == 0)
389 return reason;
390
391#if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR
392 if (rcar_iic_dvfs_receive(PMIC, REG_KEEP10, &data)) {
393 ERROR("BL2: REG Keep10 READ ERROR.\n");
394 panic();
395 }
396
397 if (KEEP10_MAGIC != data)
398 reason = RCAR_WARM_BOOT;
399#else
400 reason = RCAR_WARM_BOOT;
401#endif
402 return reason;
403#else
404 return RCAR_COLD_BOOT;
405#endif
406}
407
Marek Vasutb25ee352021-02-13 19:09:29 +0100408#if RCAR_GEN3_BL33_GZIP == 1
409void bl2_plat_preload_setup(void)
410{
411 image_decompress_init(BL33_COMP_BASE, BL33_COMP_SIZE, gunzip);
412}
413#endif
414
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900415static uint64_t check_secure_load_area(uintptr_t base, uint32_t size,
416 uintptr_t dest, uint32_t len)
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200417{
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900418 uintptr_t free_end, requested_end;
Marek Vasutb25ee352021-02-13 19:09:29 +0100419
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900420 /*
421 * Handle corner cases first.
422 *
423 * The order of the 2 tests is important, because if there's no space
424 * left (i.e. free_size == 0) but we don't ask for any memory
425 * (i.e. size == 0) then we should report that the memory is free.
426 */
427 if (len == 0U) {
428 WARN("BL2: load data size is zero\n");
429 return 0; /* A zero-byte region is always free */
Marek Vasutb25ee352021-02-13 19:09:29 +0100430 }
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900431 if (size == 0U) {
432 goto err;
433 }
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200434
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900435 /*
436 * Check that the end addresses don't overflow.
437 * If they do, consider that this memory region is not free, as this
438 * is an invalid scenario.
439 */
440 if (check_uptr_overflow(base, size - 1U)) {
441 goto err;
442 }
443 free_end = base + (size - 1U);
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200444
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900445 if (check_uptr_overflow(dest, len - 1U)) {
446 goto err;
447 }
448 requested_end = dest + (len - 1U);
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200449
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900450 /*
451 * Finally, check that the requested memory region lies within the free
452 * region.
453 */
454 if ((dest < base) || (requested_end > free_end)) {
455 goto err;
456 }
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200457
458 return 0;
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900459
460err:
461 ERROR("BL2: load data is outside the loadable area.\n");
462 ERROR("BL2: dst=0x%lx, len=%d(0x%x)\n", dest, len, len);
463 return 1;
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200464}
465
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900466static uint64_t rcar_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest,
467 uint32_t *len)
Toshiyuki Ogasahara04f16282019-12-13 14:43:52 +0900468{
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900469 uint32_t cert;
Toshiyuki Ogasahara04f16282019-12-13 14:43:52 +0900470 int ret;
471
472 ret = rcar_get_certificate(certid, &cert);
473 if (ret) {
474 ERROR("%s : cert file load error", __func__);
475 return 1;
476 }
477
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900478 rcar_read_certificate((uint64_t) cert, len, dest);
Toshiyuki Ogasahara04f16282019-12-13 14:43:52 +0900479
480 return 0;
481}
482
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900483int bl2_plat_handle_pre_image_load(unsigned int image_id)
484{
485 u_register_t *boot_kind = (void *) BOOT_KIND_BASE;
486 bl_mem_params_node_t *bl_mem_params;
487 uintptr_t dev_handle;
488 uintptr_t image_spec;
489 uintptr_t dest;
490 uint32_t len;
491 uint64_t ui64_ret;
492 int iret;
493
494 bl_mem_params = get_bl_mem_params_node(image_id);
495 if (bl_mem_params == NULL) {
496 ERROR("BL2: Failed to get loading parameter.\n");
497 return 1;
498 }
499
500 switch (image_id) {
501 case BL31_IMAGE_ID:
502 if (is_ddr_backup_mode() == RCAR_COLD_BOOT) {
503 iret = plat_get_image_source(image_id, &dev_handle,
504 &image_spec);
505 if (iret != 0) {
506 return 1;
507 }
508
509 ui64_ret = rcar_get_dest_addr_from_cert(
510 SOC_FW_CONTENT_CERT_ID, &dest, &len);
511 if (ui64_ret != 0U) {
512 return 1;
513 }
514
515 ui64_ret = check_secure_load_area(
516 BL31_BASE, BL31_LIMIT - BL31_BASE,
517 dest, len);
518 if (ui64_ret != 0U) {
519 return 1;
520 }
521
522 *boot_kind = RCAR_COLD_BOOT;
523 flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind));
524
525 bl_mem_params->image_info.image_base = dest;
526 bl_mem_params->image_info.image_size = len;
527 } else {
528 *boot_kind = RCAR_WARM_BOOT;
529 flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind));
530
531 console_flush();
532 bl2_plat_flush_bl31_params();
533
534 /* will not return */
535 bl2_enter_bl31(&bl_mem_params->ep_info);
536 }
537
538 return 0;
539#ifndef SPD_NONE
540 case BL32_IMAGE_ID:
541 ui64_ret = rcar_get_dest_addr_from_cert(
542 TRUSTED_OS_FW_CONTENT_CERT_ID, &dest, &len);
543 if (ui64_ret != 0U) {
544 return 1;
545 }
546
547 ui64_ret = check_secure_load_area(
548 BL32_BASE, BL32_LIMIT - BL32_BASE, dest, len);
549 if (ui64_ret != 0U) {
550 return 1;
551 }
552
553 bl_mem_params->image_info.image_base = dest;
554 bl_mem_params->image_info.image_size = len;
555
556 return 0;
557#endif
558 case BL33_IMAGE_ID:
559 /* case of image_id == BL33_IMAGE_ID */
560 ui64_ret = rcar_get_dest_addr_from_cert(
561 NON_TRUSTED_FW_CONTENT_CERT_ID,
562 &dest, &len);
563
564 if (ui64_ret != 0U) {
565 return 1;
566 }
567
568#if RCAR_GEN3_BL33_GZIP == 1
569 image_decompress_prepare(&bl_mem_params->image_info);
570#endif
571
572 return 0;
573 default:
574 return 1;
575 }
576
577 return 0;
578}
579
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200580int bl2_plat_handle_post_image_load(unsigned int image_id)
581{
582 static bl2_to_bl31_params_mem_t *params;
583 bl_mem_params_node_t *bl_mem_params;
584
585 if (!params) {
586 params = (bl2_to_bl31_params_mem_t *) PARAMS_BASE;
587 memset((void *)PARAMS_BASE, 0, sizeof(*params));
588 }
589
590 bl_mem_params = get_bl_mem_params_node(image_id);
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900591 if (!bl_mem_params) {
592 ERROR("BL2: Failed to get loading parameter.\n");
593 return 1;
594 }
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200595
596 switch (image_id) {
597 case BL31_IMAGE_ID:
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900598 bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
599 return 0;
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200600 case BL32_IMAGE_ID:
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900601 bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200602 memcpy(&params->bl32_ep_info, &bl_mem_params->ep_info,
603 sizeof(entry_point_info_t));
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900604 return 0;
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200605 case BL33_IMAGE_ID:
Marek Vasutb25ee352021-02-13 19:09:29 +0100606#if RCAR_GEN3_BL33_GZIP == 1
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900607 int ret;
Marek Vasutb25ee352021-02-13 19:09:29 +0100608 if ((mmio_read_32(BL33_COMP_BASE) & 0xffff) == 0x8b1f) {
609 /* decompress gzip-compressed image */
610 ret = image_decompress(&bl_mem_params->image_info);
611 if (ret != 0) {
612 return ret;
613 }
614 } else {
615 /* plain image, copy it in place */
616 memcpy((void *)BL33_BASE, (void *)BL33_COMP_BASE,
617 bl_mem_params->image_info.image_size);
618 }
619#endif
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200620 memcpy(&params->bl33_ep_info, &bl_mem_params->ep_info,
621 sizeof(entry_point_info_t));
Takuya Sakatacb9efd82021-12-01 13:42:54 +0900622 return 0;
623 default:
624 return 1;
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200625 }
626
627 return 0;
628}
629
Marek Vasutc7077c62018-12-26 15:57:08 +0100630struct meminfo *bl2_plat_sec_mem_layout(void)
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200631{
632 return &bl2_tzram_layout;
633}
634
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100635static void bl2_populate_compatible_string(void *dt)
Marek Vasuta987b002018-10-11 16:15:41 +0200636{
637 uint32_t board_type;
638 uint32_t board_rev;
639 uint32_t reg;
640 int ret;
641
Marek Vasut688251a2020-01-06 03:26:43 +0100642 fdt_setprop_u32(dt, 0, "#address-cells", 2);
643 fdt_setprop_u32(dt, 0, "#size-cells", 2);
644
Marek Vasuta987b002018-10-11 16:15:41 +0200645 /* Populate compatible string */
646 rcar_get_board_type(&board_type, &board_rev);
647 switch (board_type) {
648 case BOARD_SALVATOR_X:
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100649 ret = fdt_setprop_string(dt, 0, "compatible",
Marek Vasuta987b002018-10-11 16:15:41 +0200650 "renesas,salvator-x");
651 break;
652 case BOARD_SALVATOR_XS:
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100653 ret = fdt_setprop_string(dt, 0, "compatible",
Marek Vasuta987b002018-10-11 16:15:41 +0200654 "renesas,salvator-xs");
655 break;
656 case BOARD_STARTER_KIT:
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100657 ret = fdt_setprop_string(dt, 0, "compatible",
Marek Vasuta987b002018-10-11 16:15:41 +0200658 "renesas,m3ulcb");
659 break;
660 case BOARD_STARTER_KIT_PRE:
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100661 ret = fdt_setprop_string(dt, 0, "compatible",
Marek Vasuta987b002018-10-11 16:15:41 +0200662 "renesas,h3ulcb");
663 break;
Valentine Barshakf2184142018-10-30 02:06:17 +0300664 case BOARD_EAGLE:
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100665 ret = fdt_setprop_string(dt, 0, "compatible",
Valentine Barshakf2184142018-10-30 02:06:17 +0300666 "renesas,eagle");
667 break;
Marek Vasuta987b002018-10-11 16:15:41 +0200668 case BOARD_EBISU:
669 case BOARD_EBISU_4D:
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100670 ret = fdt_setprop_string(dt, 0, "compatible",
Marek Vasuta987b002018-10-11 16:15:41 +0200671 "renesas,ebisu");
672 break;
Marek Vasut4ae342c2019-01-05 13:56:03 +0100673 case BOARD_DRAAK:
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100674 ret = fdt_setprop_string(dt, 0, "compatible",
Marek Vasut4ae342c2019-01-05 13:56:03 +0100675 "renesas,draak");
676 break;
Marek Vasuta987b002018-10-11 16:15:41 +0200677 default:
678 NOTICE("BL2: Cannot set compatible string, board unsupported\n");
679 panic();
680 }
681
682 if (ret < 0) {
683 NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret);
684 panic();
685 }
686
687 reg = mmio_read_32(RCAR_PRR);
Marek Vasut9cadc782019-08-06 19:13:22 +0200688 switch (reg & PRR_PRODUCT_MASK) {
689 case PRR_PRODUCT_H3:
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100690 ret = fdt_appendprop_string(dt, 0, "compatible",
Marek Vasuta987b002018-10-11 16:15:41 +0200691 "renesas,r8a7795");
692 break;
Marek Vasut9cadc782019-08-06 19:13:22 +0200693 case PRR_PRODUCT_M3:
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100694 ret = fdt_appendprop_string(dt, 0, "compatible",
Marek Vasuta987b002018-10-11 16:15:41 +0200695 "renesas,r8a7796");
696 break;
Marek Vasut9cadc782019-08-06 19:13:22 +0200697 case PRR_PRODUCT_M3N:
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100698 ret = fdt_appendprop_string(dt, 0, "compatible",
Marek Vasuta987b002018-10-11 16:15:41 +0200699 "renesas,r8a77965");
700 break;
Marek Vasut9cadc782019-08-06 19:13:22 +0200701 case PRR_PRODUCT_V3M:
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100702 ret = fdt_appendprop_string(dt, 0, "compatible",
Valentine Barshakf2184142018-10-30 02:06:17 +0300703 "renesas,r8a77970");
704 break;
Marek Vasut9cadc782019-08-06 19:13:22 +0200705 case PRR_PRODUCT_E3:
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100706 ret = fdt_appendprop_string(dt, 0, "compatible",
Marek Vasuta987b002018-10-11 16:15:41 +0200707 "renesas,r8a77990");
708 break;
Marek Vasut9cadc782019-08-06 19:13:22 +0200709 case PRR_PRODUCT_D3:
Justin Chadwell7d0e3ba2019-09-17 15:21:50 +0100710 ret = fdt_appendprop_string(dt, 0, "compatible",
Marek Vasut4ae342c2019-01-05 13:56:03 +0100711 "renesas,r8a77995");
712 break;
Marek Vasuta987b002018-10-11 16:15:41 +0200713 default:
714 NOTICE("BL2: Cannot set compatible string, SoC unsupported\n");
715 panic();
716 }
717
718 if (ret < 0) {
719 NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret);
720 panic();
721 }
722}
723
Marek Vasute7618e72021-07-10 17:59:05 +0200724static void bl2_add_rpc_node(void)
725{
726#if (RCAR_RPC_HYPERFLASH_LOCKED == 0)
727 int ret, node;
728
729 node = ret = fdt_add_subnode(fdt, 0, "soc");
730 if (ret < 0) {
731 goto err;
732 }
733
Geert Uytterhoeven5480bd12022-03-23 14:21:31 +0100734 node = ret = fdt_add_subnode(fdt, node, "spi@ee200000");
Marek Vasute7618e72021-07-10 17:59:05 +0200735 if (ret < 0) {
736 goto err;
737 }
738
739 ret = fdt_setprop_string(fdt, node, "status", "okay");
740 if (ret < 0) {
741 goto err;
742 }
743
744 return;
745err:
746 NOTICE("BL2: Cannot add RPC node to FDT (ret=%i)\n", ret);
747 panic();
748#endif
749}
750
Marek Vasut5ca408a2021-04-16 21:25:27 +0200751static void bl2_add_dram_entry(uint64_t start, uint64_t size)
Marek Vasut6a6881a2018-10-02 20:43:09 +0200752{
Marek Vasut93c85fc2018-10-02 20:45:18 +0200753 char nodename[32] = { 0 };
Marek Vasut93c85fc2018-10-02 20:45:18 +0200754 uint64_t fdtsize;
Marek Vasut5ca408a2021-04-16 21:25:27 +0200755 int ret, node;
756
757 fdtsize = cpu_to_fdt64(size);
758
759 snprintf(nodename, sizeof(nodename), "memory@");
760 unsigned_num_print(start, 16, nodename + strlen(nodename));
761 node = ret = fdt_add_subnode(fdt, 0, nodename);
762 if (ret < 0) {
763 goto err;
764 }
765
766 ret = fdt_setprop_string(fdt, node, "device_type", "memory");
767 if (ret < 0) {
768 goto err;
769 }
770
771 ret = fdt_setprop_u64(fdt, node, "reg", start);
772 if (ret < 0) {
773 goto err;
774 }
775
776 ret = fdt_appendprop(fdt, node, "reg", &fdtsize,
777 sizeof(fdtsize));
778 if (ret < 0) {
779 goto err;
780 }
781
782 return;
783err:
Scott Brandene5dcf982020-08-25 13:49:32 -0700784 NOTICE("BL2: Cannot add memory node [%" PRIx64 " - %" PRIx64 "] to FDT (ret=%i)\n",
Marek Vasut5ca408a2021-04-16 21:25:27 +0200785 start, start + size - 1, ret);
786 panic();
787}
788
789static void bl2_advertise_dram_entries(uint64_t dram_config[8])
790{
Marek Vasut9601d5a2021-04-16 21:39:36 +0200791 uint64_t start, size, size32;
Marek Vasut5ca408a2021-04-16 21:25:27 +0200792 int chan;
Marek Vasut6a6881a2018-10-02 20:43:09 +0200793
794 for (chan = 0; chan < 4; chan++) {
795 start = dram_config[2 * chan];
796 size = dram_config[2 * chan + 1];
797 if (!size)
798 continue;
799
Scott Brandene5dcf982020-08-25 13:49:32 -0700800 NOTICE("BL2: CH%d: %" PRIx64 " - %" PRIx64 ", %" PRId64 " %siB\n",
Marek Vasut89c17512019-03-30 04:01:41 +0100801 chan, start, start + size - 1,
802 (size >> 30) ? : size >> 20,
803 (size >> 30) ? "G" : "M");
Marek Vasut6a6881a2018-10-02 20:43:09 +0200804 }
Marek Vasut93c85fc2018-10-02 20:45:18 +0200805
806 /*
807 * We add the DT nodes in reverse order here. The fdt_add_subnode()
808 * adds the DT node before the first existing DT node, so we have
809 * to add them in reverse order to get nodes sorted by address in
810 * the resulting DT.
811 */
812 for (chan = 3; chan >= 0; chan--) {
813 start = dram_config[2 * chan];
814 size = dram_config[2 * chan + 1];
815 if (!size)
816 continue;
817
818 /*
819 * Channel 0 is mapped in 32bit space and the first
Marek Vasut9601d5a2021-04-16 21:39:36 +0200820 * 128 MiB are reserved and the maximum size is 2GiB.
Marek Vasut93c85fc2018-10-02 20:45:18 +0200821 */
822 if (chan == 0) {
Marek Vasut9601d5a2021-04-16 21:39:36 +0200823 /* Limit the 32bit entry to 2 GiB - 128 MiB */
824 size32 = size - 0x8000000U;
825 if (size32 >= 0x78000000U) {
826 size32 = 0x78000000U;
827 }
828
829 /* Emit 32bit entry, up to 2 GiB - 128 MiB long. */
830 bl2_add_dram_entry(0x48000000, size32);
831
832 /*
833 * If channel 0 is less than 2 GiB long, the
834 * entire memory fits into the 32bit space entry,
835 * so move on to the next channel.
836 */
837 if (size <= 0x80000000U) {
838 continue;
839 }
840
841 /*
842 * If channel 0 is more than 2 GiB long, emit
843 * another entry which covers the rest of the
844 * memory in channel 0, in the 64bit space.
845 *
846 * Start of this new entry is at 2 GiB offset
847 * from the beginning of the 64bit channel 0
848 * address, size is 2 GiB shorter than total
849 * size of the channel.
850 */
851 start += 0x80000000U;
852 size -= 0x80000000U;
Marek Vasut93c85fc2018-10-02 20:45:18 +0200853 }
854
Marek Vasut5ca408a2021-04-16 21:25:27 +0200855 bl2_add_dram_entry(start, size);
Marek Vasut93c85fc2018-10-02 20:45:18 +0200856 }
Marek Vasut6a6881a2018-10-02 20:43:09 +0200857}
858
Marek Vasutb0e13592018-10-02 14:53:27 +0200859static void bl2_advertise_dram_size(uint32_t product)
Marek Vasut673bc322018-10-02 13:33:32 +0200860{
Marek Vasut6a6881a2018-10-02 20:43:09 +0200861 uint64_t dram_config[8] = {
862 [0] = 0x400000000ULL,
863 [2] = 0x500000000ULL,
864 [4] = 0x600000000ULL,
865 [6] = 0x700000000ULL,
866 };
Toshiyuki Ogasahara58ff4b22021-07-12 19:05:06 +0900867 uint32_t cut = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK;
Marek Vasut6a6881a2018-10-02 20:43:09 +0200868
Marek Vasut9963f702018-10-02 15:09:04 +0200869 switch (product) {
Marek Vasut9cadc782019-08-06 19:13:22 +0200870 case PRR_PRODUCT_H3:
Marek Vasut673bc322018-10-02 13:33:32 +0200871#if (RCAR_DRAM_LPDDR4_MEMCONF == 0)
872 /* 4GB(1GBx4) */
Marek Vasut6a6881a2018-10-02 20:43:09 +0200873 dram_config[1] = 0x40000000ULL;
874 dram_config[3] = 0x40000000ULL;
875 dram_config[5] = 0x40000000ULL;
876 dram_config[7] = 0x40000000ULL;
Marek Vasut673bc322018-10-02 13:33:32 +0200877#elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && \
878 (RCAR_DRAM_CHANNEL == 5) && \
879 (RCAR_DRAM_SPLIT == 2)
880 /* 4GB(2GBx2 2ch split) */
Marek Vasut6a6881a2018-10-02 20:43:09 +0200881 dram_config[1] = 0x80000000ULL;
882 dram_config[3] = 0x80000000ULL;
Marek Vasut673bc322018-10-02 13:33:32 +0200883#elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && (RCAR_DRAM_CHANNEL == 15)
884 /* 8GB(2GBx4: default) */
Marek Vasut6a6881a2018-10-02 20:43:09 +0200885 dram_config[1] = 0x80000000ULL;
886 dram_config[3] = 0x80000000ULL;
887 dram_config[5] = 0x80000000ULL;
888 dram_config[7] = 0x80000000ULL;
Marek Vasut673bc322018-10-02 13:33:32 +0200889#endif /* RCAR_DRAM_LPDDR4_MEMCONF == 0 */
Marek Vasut9963f702018-10-02 15:09:04 +0200890 break;
Marek Vasut673bc322018-10-02 13:33:32 +0200891
Marek Vasut9cadc782019-08-06 19:13:22 +0200892 case PRR_PRODUCT_M3:
Toshiyuki Ogasahara58ff4b22021-07-12 19:05:06 +0900893 if (cut < PRR_PRODUCT_30) {
Marek Vasut0208c942019-03-09 16:10:59 +0100894#if (RCAR_GEN3_ULCB == 1)
Toshiyuki Ogasahara58ff4b22021-07-12 19:05:06 +0900895 /* 2GB(1GBx2 2ch split) */
896 dram_config[1] = 0x40000000ULL;
897 dram_config[5] = 0x40000000ULL;
Marek Vasut0208c942019-03-09 16:10:59 +0100898#else
Toshiyuki Ogasahara58ff4b22021-07-12 19:05:06 +0900899 /* 4GB(2GBx2 2ch split) */
900 dram_config[1] = 0x80000000ULL;
901 dram_config[5] = 0x80000000ULL;
Marek Vasut0208c942019-03-09 16:10:59 +0100902#endif
Toshiyuki Ogasahara58ff4b22021-07-12 19:05:06 +0900903 } else {
904 /* 8GB(2GBx4 2ch split) */
905 dram_config[1] = 0x100000000ULL;
906 dram_config[5] = 0x100000000ULL;
907 }
Marek Vasut9963f702018-10-02 15:09:04 +0200908 break;
909
Marek Vasut9cadc782019-08-06 19:13:22 +0200910 case PRR_PRODUCT_M3N:
Toshiyuki Ogasahara67e19522020-12-15 18:22:16 +0900911#if (RCAR_DRAM_LPDDR4_MEMCONF == 2)
912 /* 4GB(4GBx1) */
913 dram_config[1] = 0x100000000ULL;
914#elif (RCAR_DRAM_LPDDR4_MEMCONF == 1)
Marek Vasut9963f702018-10-02 15:09:04 +0200915 /* 2GB(1GBx2) */
Marek Vasut6a6881a2018-10-02 20:43:09 +0200916 dram_config[1] = 0x80000000ULL;
Toshiyuki Ogasahara67e19522020-12-15 18:22:16 +0900917#endif
Marek Vasut9963f702018-10-02 15:09:04 +0200918 break;
919
Marek Vasut9cadc782019-08-06 19:13:22 +0200920 case PRR_PRODUCT_V3M:
Valentine Barshakf2184142018-10-30 02:06:17 +0300921 /* 1GB(512MBx2) */
922 dram_config[1] = 0x40000000ULL;
923 break;
924
Marek Vasut9cadc782019-08-06 19:13:22 +0200925 case PRR_PRODUCT_E3:
Marek Vasut673bc322018-10-02 13:33:32 +0200926#if (RCAR_DRAM_DDR3L_MEMCONF == 0)
927 /* 1GB(512MBx2) */
Marek Vasut6a6881a2018-10-02 20:43:09 +0200928 dram_config[1] = 0x40000000ULL;
Marek Vasut673bc322018-10-02 13:33:32 +0200929#elif (RCAR_DRAM_DDR3L_MEMCONF == 1)
930 /* 2GB(512MBx4) */
Marek Vasut6a6881a2018-10-02 20:43:09 +0200931 dram_config[1] = 0x80000000ULL;
Marek Vasut8cb12ec2018-10-02 13:51:19 +0200932#elif (RCAR_DRAM_DDR3L_MEMCONF == 2)
933 /* 4GB(1GBx4) */
Marek Vasut6a6881a2018-10-02 20:43:09 +0200934 dram_config[1] = 0x100000000ULL;
Marek Vasut673bc322018-10-02 13:33:32 +0200935#endif /* RCAR_DRAM_DDR3L_MEMCONF == 0 */
Marek Vasut9963f702018-10-02 15:09:04 +0200936 break;
Marek Vasut4ae342c2019-01-05 13:56:03 +0100937
Marek Vasut9cadc782019-08-06 19:13:22 +0200938 case PRR_PRODUCT_D3:
Marek Vasut4ae342c2019-01-05 13:56:03 +0100939 /* 512MB */
940 dram_config[1] = 0x20000000ULL;
941 break;
Marek Vasut673bc322018-10-02 13:33:32 +0200942 }
Marek Vasut6a6881a2018-10-02 20:43:09 +0200943
944 bl2_advertise_dram_entries(dram_config);
Marek Vasut673bc322018-10-02 13:33:32 +0200945}
946
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200947void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2,
948 u_register_t arg3, u_register_t arg4)
949{
950 uint32_t reg, midr, lcs, boot_dev, boot_cpu, sscg, type, rev;
Marek Vasutb0e13592018-10-02 14:53:27 +0200951 uint32_t product, product_cut, major, minor;
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200952 int32_t ret;
953 const char *str;
954 const char *unknown = "unknown";
955 const char *cpu_ca57 = "CA57";
956 const char *cpu_ca53 = "CA53";
957 const char *product_m3n = "M3N";
958 const char *product_h3 = "H3";
959 const char *product_m3 = "M3";
960 const char *product_e3 = "E3";
Marek Vasut4ae342c2019-01-05 13:56:03 +0100961 const char *product_d3 = "D3";
Valentine Barshakf2184142018-10-30 02:06:17 +0300962 const char *product_v3m = "V3M";
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200963 const char *lcs_secure = "SE";
964 const char *lcs_cm = "CM";
965 const char *lcs_dm = "DM";
966 const char *lcs_sd = "SD";
967 const char *lcs_fa = "FA";
968 const char *sscg_off = "PLL1 nonSSCG Clock select";
969 const char *sscg_on = "PLL1 SSCG Clock select";
970 const char *boot_hyper80 = "HyperFlash(80MHz)";
971 const char *boot_qspi40 = "QSPI Flash(40MHz)";
972 const char *boot_qspi80 = "QSPI Flash(80MHz)";
973 const char *boot_emmc25x1 = "eMMC(25MHz x1)";
974 const char *boot_emmc50x8 = "eMMC(50MHz x8)";
Marek Vasut4ae342c2019-01-05 13:56:03 +0100975#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3)
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200976 const char *boot_hyper160 = "HyperFlash(150MHz)";
977#else
978 const char *boot_hyper160 = "HyperFlash(160MHz)";
979#endif
980
Marek Vasut1eca7782018-12-28 20:12:13 +0100981 bl2_init_generic_timer();
982
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200983 reg = mmio_read_32(RCAR_MODEMR);
984 boot_dev = reg & MODEMR_BOOT_DEV_MASK;
985 boot_cpu = reg & MODEMR_BOOT_CPU_MASK;
986
987 bl2_cpg_init();
988
989 if (boot_cpu == MODEMR_BOOT_CPU_CA57 ||
990 boot_cpu == MODEMR_BOOT_CPU_CA53) {
991 rcar_pfc_init();
Marek Vasut0aa268e2019-05-18 19:29:16 +0200992 rcar_console_boot_init();
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200993 }
994
995 plat_rcar_gic_driver_init();
996 plat_rcar_gic_init();
997 rcar_swdt_init();
998
999 /* FIQ interrupts are taken to EL3 */
1000 write_scr_el3(read_scr_el3() | SCR_FIQ_BIT);
1001
1002 write_daifclr(DAIF_FIQ_BIT);
1003
1004 reg = read_midr();
1005 midr = reg & (MIDR_PN_MASK << MIDR_PN_SHIFT);
1006 switch (midr) {
1007 case MIDR_CA57:
1008 str = cpu_ca57;
1009 break;
1010 case MIDR_CA53:
1011 str = cpu_ca53;
1012 break;
1013 default:
1014 str = unknown;
1015 break;
1016 }
1017
1018 NOTICE("BL2: R-Car Gen3 Initial Program Loader(%s) Rev.%s\n", str,
1019 version_of_renesas);
1020
1021 reg = mmio_read_32(RCAR_PRR);
Marek Vasut9cadc782019-08-06 19:13:22 +02001022 product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK);
1023 product = reg & PRR_PRODUCT_MASK;
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001024
1025 switch (product) {
Marek Vasut9cadc782019-08-06 19:13:22 +02001026 case PRR_PRODUCT_H3:
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001027 str = product_h3;
1028 break;
Marek Vasut9cadc782019-08-06 19:13:22 +02001029 case PRR_PRODUCT_M3:
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001030 str = product_m3;
1031 break;
Marek Vasut9cadc782019-08-06 19:13:22 +02001032 case PRR_PRODUCT_M3N:
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001033 str = product_m3n;
1034 break;
Marek Vasut9cadc782019-08-06 19:13:22 +02001035 case PRR_PRODUCT_V3M:
Valentine Barshakf2184142018-10-30 02:06:17 +03001036 str = product_v3m;
1037 break;
Marek Vasut9cadc782019-08-06 19:13:22 +02001038 case PRR_PRODUCT_E3:
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001039 str = product_e3;
1040 break;
Marek Vasut9cadc782019-08-06 19:13:22 +02001041 case PRR_PRODUCT_D3:
Marek Vasut4ae342c2019-01-05 13:56:03 +01001042 str = product_d3;
1043 break;
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001044 default:
1045 str = unknown;
1046 break;
1047 }
1048
Marek Vasut9cadc782019-08-06 19:13:22 +02001049 if ((PRR_PRODUCT_M3 == product) &&
1050 (PRR_PRODUCT_20 == (reg & RCAR_MAJOR_MASK))) {
1051 if (RCAR_M3_CUT_VER11 == (reg & PRR_CUT_MASK)) {
Marek Vasut3af20052019-02-25 14:57:08 +01001052 /* M3 Ver.1.1 or Ver.1.2 */
1053 NOTICE("BL2: PRR is R-Car %s Ver.1.1 / Ver.1.2\n",
1054 str);
1055 } else {
1056 NOTICE("BL2: PRR is R-Car %s Ver.1.%d\n",
1057 str,
1058 (reg & RCAR_MINOR_MASK) + RCAR_M3_MINOR_OFFSET);
1059 }
Toshiyuki Ogasaharac3c52272021-07-12 19:18:57 +09001060 } else if (product == PRR_PRODUCT_D3) {
1061 if (RCAR_D3_CUT_VER10 == (reg & PRR_CUT_MASK)) {
1062 NOTICE("BL2: PRR is R-Car %s Ver.1.0\n", str);
1063 } else if (RCAR_D3_CUT_VER11 == (reg & PRR_CUT_MASK)) {
1064 NOTICE("BL2: PRR is R-Car %s Ver.1.1\n", str);
1065 } else {
1066 NOTICE("BL2: PRR is R-Car %s Ver.X.X\n", str);
1067 }
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001068 } else {
1069 major = (reg & RCAR_MAJOR_MASK) >> RCAR_MAJOR_SHIFT;
1070 major = major + RCAR_MAJOR_OFFSET;
1071 minor = reg & RCAR_MINOR_MASK;
1072 NOTICE("BL2: PRR is R-Car %s Ver.%d.%d\n", str, major, minor);
1073 }
1074
Toshiyuki Ogasahara9be13a92021-07-12 19:19:39 +09001075 if (PRR_PRODUCT_E3 == product || PRR_PRODUCT_D3 == product) {
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001076 reg = mmio_read_32(RCAR_MODEMR);
1077 sscg = reg & RCAR_SSCG_MASK;
1078 str = sscg == RCAR_SSCG_ENABLE ? sscg_on : sscg_off;
1079 NOTICE("BL2: %s\n", str);
1080 }
1081
1082 rcar_get_board_type(&type, &rev);
1083
1084 switch (type) {
1085 case BOARD_SALVATOR_X:
1086 case BOARD_KRIEK:
1087 case BOARD_STARTER_KIT:
1088 case BOARD_SALVATOR_XS:
1089 case BOARD_EBISU:
1090 case BOARD_STARTER_KIT_PRE:
1091 case BOARD_EBISU_4D:
Marek Vasut4ae342c2019-01-05 13:56:03 +01001092 case BOARD_DRAAK:
Valentine Barshakf2184142018-10-30 02:06:17 +03001093 case BOARD_EAGLE:
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001094 break;
1095 default:
1096 type = BOARD_UNKNOWN;
1097 break;
1098 }
1099
1100 if (type == BOARD_UNKNOWN || rev == BOARD_REV_UNKNOWN)
1101 NOTICE("BL2: Board is %s Rev.---\n", GET_BOARD_NAME(type));
1102 else {
1103 NOTICE("BL2: Board is %s Rev.%d.%d\n",
1104 GET_BOARD_NAME(type),
1105 GET_BOARD_MAJOR(rev), GET_BOARD_MINOR(rev));
1106 }
1107
1108#if RCAR_LSI != RCAR_AUTO
1109 if (product != TARGET_PRODUCT) {
1110 ERROR("BL2: IPL was been built for the %s.\n", TARGET_NAME);
1111 ERROR("BL2: Please write the correct IPL to flash memory.\n");
1112 panic();
1113 }
1114#endif
1115 rcar_avs_init();
1116 rcar_avs_setting();
1117
1118 switch (boot_dev) {
1119 case MODEMR_BOOT_DEV_HYPERFLASH160:
1120 str = boot_hyper160;
1121 break;
1122 case MODEMR_BOOT_DEV_HYPERFLASH80:
1123 str = boot_hyper80;
1124 break;
1125 case MODEMR_BOOT_DEV_QSPI_FLASH40:
1126 str = boot_qspi40;
1127 break;
1128 case MODEMR_BOOT_DEV_QSPI_FLASH80:
1129 str = boot_qspi80;
1130 break;
1131 case MODEMR_BOOT_DEV_EMMC_25X1:
Marek Vasut4ae342c2019-01-05 13:56:03 +01001132#if RCAR_LSI == RCAR_D3
1133 ERROR("BL2: Failed to Initialize. eMMC is not supported.\n");
1134 panic();
1135#endif
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001136 str = boot_emmc25x1;
1137 break;
1138 case MODEMR_BOOT_DEV_EMMC_50X8:
1139 str = boot_emmc50x8;
1140 break;
1141 default:
1142 str = unknown;
1143 break;
1144 }
1145 NOTICE("BL2: Boot device is %s\n", str);
1146
1147 rcar_avs_setting();
1148 reg = rcar_rom_get_lcs(&lcs);
1149 if (reg) {
1150 str = unknown;
1151 goto lcm_state;
1152 }
1153
1154 switch (lcs) {
1155 case LCS_CM:
1156 str = lcs_cm;
1157 break;
1158 case LCS_DM:
1159 str = lcs_dm;
1160 break;
1161 case LCS_SD:
1162 str = lcs_sd;
1163 break;
1164 case LCS_SE:
1165 str = lcs_secure;
1166 break;
1167 case LCS_FA:
1168 str = lcs_fa;
1169 break;
1170 default:
1171 str = unknown;
1172 break;
1173 }
1174
1175lcm_state:
1176 NOTICE("BL2: LCM state is %s\n", str);
1177
1178 rcar_avs_end();
1179 is_ddr_backup_mode();
1180
1181 bl2_tzram_layout.total_base = BL31_BASE;
1182 bl2_tzram_layout.total_size = BL31_LIMIT - BL31_BASE;
1183
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001184 if (boot_cpu == MODEMR_BOOT_CPU_CA57 ||
1185 boot_cpu == MODEMR_BOOT_CPU_CA53) {
1186 ret = rcar_dram_init();
1187 if (ret) {
1188 NOTICE("BL2: Failed to DRAM initialize (%d).\n", ret);
1189 panic();
1190 }
1191 rcar_qos_init();
1192 }
1193
Marek Vasut93c85fc2018-10-02 20:45:18 +02001194 /* Set up FDT */
1195 ret = fdt_create_empty_tree(fdt, sizeof(fdt_blob));
1196 if (ret) {
1197 NOTICE("BL2: Cannot allocate FDT for U-Boot (ret=%i)\n", ret);
1198 panic();
1199 }
1200
Marek Vasuta987b002018-10-11 16:15:41 +02001201 /* Add platform compatible string */
1202 bl2_populate_compatible_string(fdt);
1203
Marek Vasute7618e72021-07-10 17:59:05 +02001204 /* Enable RPC if unlocked */
1205 bl2_add_rpc_node();
1206
Marek Vasut63659fd2018-10-02 15:12:15 +02001207 /* Print DRAM layout */
1208 bl2_advertise_dram_size(product);
1209
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001210 if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 ||
1211 boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) {
1212 if (rcar_emmc_init() != EMMC_SUCCESS) {
1213 NOTICE("BL2: Failed to eMMC driver initialize.\n");
1214 panic();
1215 }
1216 rcar_emmc_memcard_power(EMMC_POWER_ON);
1217 if (rcar_emmc_mount() != EMMC_SUCCESS) {
1218 NOTICE("BL2: Failed to eMMC mount operation.\n");
1219 panic();
1220 }
1221 } else {
1222 rcar_rpc_init();
1223 rcar_dma_init();
1224 }
1225
1226 reg = mmio_read_32(RST_WDTRSTCR);
1227 reg &= ~WDTRSTCR_RWDT_RSTMSK;
1228 reg |= WDTRSTCR_PASSWORD;
1229 mmio_write_32(RST_WDTRSTCR, reg);
1230
1231 mmio_write_32(CPG_CPGWPR, CPGWPR_PASSWORD);
1232 mmio_write_32(CPG_CPGWPCR, CPGWPCR_PASSWORD);
1233
1234 reg = mmio_read_32(RCAR_PRR);
1235 if ((reg & RCAR_CPU_MASK_CA57) == RCAR_CPU_HAVE_CA57)
1236 mmio_write_32(CPG_CA57DBGRCR,
1237 DBGCPUPREN | mmio_read_32(CPG_CA57DBGRCR));
1238
1239 if ((reg & RCAR_CPU_MASK_CA53) == RCAR_CPU_HAVE_CA53)
1240 mmio_write_32(CPG_CA53DBGRCR,
1241 DBGCPUPREN | mmio_read_32(CPG_CA53DBGRCR));
1242
Marek Vasut9cadc782019-08-06 19:13:22 +02001243 if (product_cut == PRR_PRODUCT_H3_CUT10) {
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001244 reg = mmio_read_32(CPG_PLL2CR);
1245 reg &= ~((uint32_t) 1 << 5);
1246 mmio_write_32(CPG_PLL2CR, reg);
1247
1248 reg = mmio_read_32(CPG_PLL4CR);
1249 reg &= ~((uint32_t) 1 << 5);
1250 mmio_write_32(CPG_PLL4CR, reg);
1251
1252 reg = mmio_read_32(CPG_PLL0CR);
1253 reg &= ~((uint32_t) 1 << 12);
1254 mmio_write_32(CPG_PLL0CR, reg);
1255 }
Marek Vasut4d693c22018-10-11 16:53:58 +02001256
Detlev Casanova8348acd2022-12-01 17:57:31 -05001257 bl2_create_fcnl_reserved_memory();
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001258
Marek Vasut93c85fc2018-10-02 20:45:18 +02001259 fdt_pack(fdt);
1260 NOTICE("BL2: FDT at %p\n", fdt);
1261
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001262 if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 ||
1263 boot_dev == MODEMR_BOOT_DEV_EMMC_50X8)
1264 rcar_io_emmc_setup();
1265 else
1266 rcar_io_setup();
1267}
1268
1269void bl2_el3_plat_arch_setup(void)
1270{
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001271 rcar_configure_mmu_el3(BL2_BASE,
Marek Vasut2e032c02018-12-26 15:57:08 +01001272 BL2_END - BL2_BASE,
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001273 BL2_RO_BASE, BL2_RO_LIMIT
1274#if USE_COHERENT_MEM
1275 , BL2_COHERENT_RAM_BASE, BL2_COHERENT_RAM_LIMIT
1276#endif
1277 );
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001278}
1279
Toshiyuki Ogasahara22c44b92021-07-12 18:39:52 +09001280void bl2_el3_plat_prepare_exit(void)
1281{
1282 bl2_ram_security_setting_finish();
1283}
1284
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001285void bl2_platform_setup(void)
1286{
1287
1288}
Marek Vasut1eca7782018-12-28 20:12:13 +01001289
1290static void bl2_init_generic_timer(void)
1291{
Valentine Barshakf2184142018-10-30 02:06:17 +03001292/* FIXME: V3M 16.666 MHz ? */
Marek Vasut4ae342c2019-01-05 13:56:03 +01001293#if RCAR_LSI == RCAR_D3
1294 uint32_t reg_cntfid = EXTAL_DRAAK;
1295#elif RCAR_LSI == RCAR_E3
Marek Vasut1eca7782018-12-28 20:12:13 +01001296 uint32_t reg_cntfid = EXTAL_EBISU;
1297#else /* RCAR_LSI == RCAR_E3 */
1298 uint32_t reg;
1299 uint32_t reg_cntfid;
1300 uint32_t modemr;
1301 uint32_t modemr_pll;
1302 uint32_t board_type;
1303 uint32_t board_rev;
1304 uint32_t pll_table[] = {
1305 EXTAL_MD14_MD13_TYPE_0, /* MD14/MD13 : 0b00 */
1306 EXTAL_MD14_MD13_TYPE_1, /* MD14/MD13 : 0b01 */
1307 EXTAL_MD14_MD13_TYPE_2, /* MD14/MD13 : 0b10 */
1308 EXTAL_MD14_MD13_TYPE_3 /* MD14/MD13 : 0b11 */
1309 };
1310
1311 modemr = mmio_read_32(RCAR_MODEMR);
1312 modemr_pll = (modemr & MODEMR_BOOT_PLL_MASK);
1313
1314 /* Set frequency data in CNTFID0 */
1315 reg_cntfid = pll_table[modemr_pll >> MODEMR_BOOT_PLL_SHIFT];
Marek Vasut9cadc782019-08-06 19:13:22 +02001316 reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK);
Marek Vasut1eca7782018-12-28 20:12:13 +01001317 switch (modemr_pll) {
1318 case MD14_MD13_TYPE_0:
1319 rcar_get_board_type(&board_type, &board_rev);
1320 if (BOARD_SALVATOR_XS == board_type) {
1321 reg_cntfid = EXTAL_SALVATOR_XS;
1322 }
1323 break;
1324 case MD14_MD13_TYPE_3:
Marek Vasut9cadc782019-08-06 19:13:22 +02001325 if (PRR_PRODUCT_H3_CUT10 == reg) {
Marek Vasut1eca7782018-12-28 20:12:13 +01001326 reg_cntfid = reg_cntfid >> 1U;
1327 }
1328 break;
1329 default:
1330 /* none */
1331 break;
1332 }
1333#endif /* RCAR_LSI == RCAR_E3 */
Elyes Haouas2be03c02023-02-13 09:14:48 +01001334 /* Update memory mapped and register based frequency */
Marek Vasut1eca7782018-12-28 20:12:13 +01001335 write_cntfrq_el0((u_register_t )reg_cntfid);
1336 mmio_write_32(ARM_SYS_CNTCTL_BASE + (uintptr_t)CNTFID_OFF, reg_cntfid);
1337 /* Enable counter */
1338 mmio_setbits_32(RCAR_CNTC_BASE + (uintptr_t)CNTCR_OFF,
1339 (uint32_t)CNTCR_EN);
1340}