17e532c4bSJorge Ramirez-Ortiz /* 24f7e0fa3STakuya Sakata * Copyright (c) 2018-2023, Renesas Electronics Corporation. All rights reserved. 37e532c4bSJorge Ramirez-Ortiz * 47e532c4bSJorge Ramirez-Ortiz * SPDX-License-Identifier: BSD-3-Clause 57e532c4bSJorge Ramirez-Ortiz */ 67e532c4bSJorge Ramirez-Ortiz 74ce3e99aSScott Branden #include <inttypes.h> 84ce3e99aSScott Branden #include <stdint.h> 97e532c4bSJorge Ramirez-Ortiz #include <string.h> 1009d40e0eSAntonio Nino Diaz 1109d40e0eSAntonio Nino Diaz #include <libfdt.h> 1209d40e0eSAntonio Nino Diaz 1309d40e0eSAntonio Nino Diaz #include <platform_def.h> 1409d40e0eSAntonio Nino Diaz 1509d40e0eSAntonio Nino Diaz #include <arch_helpers.h> 1609d40e0eSAntonio Nino Diaz #include <bl1/bl1.h> 1709d40e0eSAntonio Nino Diaz #include <common/bl_common.h> 1809d40e0eSAntonio Nino Diaz #include <common/debug.h> 1909d40e0eSAntonio Nino Diaz #include <common/desc_image_load.h> 20ddf2ca03SMarek Vasut #include <common/image_decompress.h> 2109d40e0eSAntonio Nino Diaz #include <drivers/console.h> 2213856f37SToshiyuki Ogasahara #include <drivers/io/io_driver.h> 2313856f37SToshiyuki Ogasahara #include <drivers/io/io_storage.h> 2409d40e0eSAntonio Nino Diaz #include <lib/mmio.h> 2509d40e0eSAntonio Nino Diaz #include <lib/xlat_tables/xlat_tables_defs.h> 2609d40e0eSAntonio Nino Diaz #include <plat/common/platform.h> 27ddf2ca03SMarek Vasut #if RCAR_GEN3_BL33_GZIP == 1 28ddf2ca03SMarek Vasut #include <tf_gunzip.h> 29ddf2ca03SMarek Vasut #endif 307e532c4bSJorge Ramirez-Ortiz 317e532c4bSJorge Ramirez-Ortiz #include "avs_driver.h" 327e532c4bSJorge Ramirez-Ortiz #include "boot_init_dram.h" 337e532c4bSJorge Ramirez-Ortiz #include "cpg_registers.h" 347e532c4bSJorge Ramirez-Ortiz #include "board.h" 357e532c4bSJorge Ramirez-Ortiz #include "emmc_def.h" 367e532c4bSJorge Ramirez-Ortiz #include "emmc_hal.h" 377e532c4bSJorge Ramirez-Ortiz #include "emmc_std.h" 387e532c4bSJorge Ramirez-Ortiz 397e532c4bSJorge Ramirez-Ortiz #if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR 407e532c4bSJorge Ramirez-Ortiz #include "iic_dvfs.h" 417e532c4bSJorge Ramirez-Ortiz #endif 427e532c4bSJorge Ramirez-Ortiz 437e532c4bSJorge Ramirez-Ortiz #include "io_common.h" 4413856f37SToshiyuki Ogasahara #include "io_rcar.h" 457e532c4bSJorge Ramirez-Ortiz #include "qos_init.h" 467e532c4bSJorge Ramirez-Ortiz #include "rcar_def.h" 477e532c4bSJorge Ramirez-Ortiz #include "rcar_private.h" 487e532c4bSJorge Ramirez-Ortiz #include "rcar_version.h" 497e532c4bSJorge Ramirez-Ortiz #include "rom_api.h" 507e532c4bSJorge Ramirez-Ortiz 51ca661a00SMadhukar Pappireddy /* 525e8c2d8eSToshiyuki Ogasahara * Following symbols are only used during plat_arch_setup() 53ca661a00SMadhukar Pappireddy */ 54ca661a00SMadhukar Pappireddy static const uint64_t BL2_RO_BASE = BL_CODE_BASE; 55ca661a00SMadhukar Pappireddy static const uint64_t BL2_RO_LIMIT = BL_CODE_END; 567e532c4bSJorge Ramirez-Ortiz 577e532c4bSJorge Ramirez-Ortiz #if USE_COHERENT_MEM 58ca661a00SMadhukar Pappireddy static const uint64_t BL2_COHERENT_RAM_BASE = BL_COHERENT_RAM_BASE; 59ca661a00SMadhukar Pappireddy static const uint64_t BL2_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END; 60ca661a00SMadhukar Pappireddy #endif 61ca661a00SMadhukar Pappireddy 627e532c4bSJorge Ramirez-Ortiz extern void plat_rcar_gic_driver_init(void); 637e532c4bSJorge Ramirez-Ortiz extern void plat_rcar_gic_init(void); 647e532c4bSJorge Ramirez-Ortiz extern void bl2_enter_bl31(const struct entry_point_info *bl_ep_info); 657e532c4bSJorge Ramirez-Ortiz extern void bl2_system_cpg_init(void); 667e532c4bSJorge Ramirez-Ortiz extern void bl2_secure_setting(void); 67e9afde1aSToshiyuki Ogasahara extern void bl2_ram_security_setting_finish(void); 687e532c4bSJorge Ramirez-Ortiz extern void bl2_cpg_init(void); 697e532c4bSJorge Ramirez-Ortiz extern void rcar_io_emmc_setup(void); 707e532c4bSJorge Ramirez-Ortiz extern void rcar_io_setup(void); 717e532c4bSJorge Ramirez-Ortiz extern void rcar_swdt_release(void); 727e532c4bSJorge Ramirez-Ortiz extern void rcar_swdt_init(void); 737e532c4bSJorge Ramirez-Ortiz extern void rcar_rpc_init(void); 747e532c4bSJorge Ramirez-Ortiz extern void rcar_pfc_init(void); 757e532c4bSJorge Ramirez-Ortiz extern void rcar_dma_init(void); 767e532c4bSJorge Ramirez-Ortiz 7747141b73SMarek Vasut static void bl2_init_generic_timer(void); 7847141b73SMarek Vasut 797e532c4bSJorge Ramirez-Ortiz /* R-Car Gen3 product check */ 807e532c4bSJorge Ramirez-Ortiz #if (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) 81df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_H3 827e532c4bSJorge Ramirez-Ortiz #define TARGET_NAME "R-Car H3" 837e532c4bSJorge Ramirez-Ortiz #elif RCAR_LSI == RCAR_M3 84df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_M3 857e532c4bSJorge Ramirez-Ortiz #define TARGET_NAME "R-Car M3" 867e532c4bSJorge Ramirez-Ortiz #elif RCAR_LSI == RCAR_M3N 87df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_M3N 887e532c4bSJorge Ramirez-Ortiz #define TARGET_NAME "R-Car M3N" 89b709fe9cSValentine Barshak #elif RCAR_LSI == RCAR_V3M 90df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_V3M 91b709fe9cSValentine Barshak #define TARGET_NAME "R-Car V3M" 927e532c4bSJorge Ramirez-Ortiz #elif RCAR_LSI == RCAR_E3 93df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_E3 947e532c4bSJorge Ramirez-Ortiz #define TARGET_NAME "R-Car E3" 95bfbf5df4SMarek Vasut #elif RCAR_LSI == RCAR_D3 96df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_D3 97bfbf5df4SMarek Vasut #define TARGET_NAME "R-Car D3" 980468aa39SMarek Vasut #elif RCAR_LSI == RCAR_AUTO 99b709fe9cSValentine Barshak #define TARGET_NAME "R-Car H3/M3/M3N/V3M" 1007e532c4bSJorge Ramirez-Ortiz #endif 1017e532c4bSJorge Ramirez-Ortiz 1027e532c4bSJorge Ramirez-Ortiz #if (RCAR_LSI == RCAR_E3) 1037e532c4bSJorge Ramirez-Ortiz #define GPIO_INDT (GPIO_INDT6) 1047e532c4bSJorge Ramirez-Ortiz #define GPIO_BKUP_TRG_SHIFT ((uint32_t)1U<<13U) 1057e532c4bSJorge Ramirez-Ortiz #else 1067e532c4bSJorge Ramirez-Ortiz #define GPIO_INDT (GPIO_INDT1) 1077e532c4bSJorge Ramirez-Ortiz #define GPIO_BKUP_TRG_SHIFT ((uint32_t)1U<<8U) 1087e532c4bSJorge Ramirez-Ortiz #endif 1097e532c4bSJorge Ramirez-Ortiz 1107e532c4bSJorge Ramirez-Ortiz CASSERT((PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t) + 0x100) 1117e532c4bSJorge Ramirez-Ortiz < (RCAR_SHARED_MEM_BASE + RCAR_SHARED_MEM_SIZE), 1127e532c4bSJorge Ramirez-Ortiz assert_bl31_params_do_not_fit_in_shared_memory); 1137e532c4bSJorge Ramirez-Ortiz 1147e532c4bSJorge Ramirez-Ortiz static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); 1157e532c4bSJorge Ramirez-Ortiz 1161d85c4bdSMarek Vasut /* FDT with DRAM configuration */ 1171d85c4bdSMarek Vasut uint64_t fdt_blob[PAGE_SIZE_4KB / sizeof(uint64_t)]; 1181d85c4bdSMarek Vasut static void *fdt = (void *)fdt_blob; 1191d85c4bdSMarek Vasut 1201d85c4bdSMarek Vasut static void unsigned_num_print(unsigned long long int unum, unsigned int radix, 1211d85c4bdSMarek Vasut char *string) 1221d85c4bdSMarek Vasut { 1231d85c4bdSMarek Vasut /* Just need enough space to store 64 bit decimal integer */ 1241d85c4bdSMarek Vasut char num_buf[20]; 1251d85c4bdSMarek Vasut int i = 0; 1261d85c4bdSMarek Vasut unsigned int rem; 1271d85c4bdSMarek Vasut 1281d85c4bdSMarek Vasut do { 1291d85c4bdSMarek Vasut rem = unum % radix; 1301d85c4bdSMarek Vasut if (rem < 0xa) 1311d85c4bdSMarek Vasut num_buf[i] = '0' + rem; 1321d85c4bdSMarek Vasut else 1331d85c4bdSMarek Vasut num_buf[i] = 'a' + (rem - 0xa); 1341d85c4bdSMarek Vasut i++; 1351d85c4bdSMarek Vasut unum /= radix; 1361d85c4bdSMarek Vasut } while (unum > 0U); 1371d85c4bdSMarek Vasut 1381d85c4bdSMarek Vasut while (--i >= 0) 1391d85c4bdSMarek Vasut *string++ = num_buf[i]; 140dcd08687SMarek Vasut *string = 0; 1411d85c4bdSMarek Vasut } 1421d85c4bdSMarek Vasut 1437e532c4bSJorge Ramirez-Ortiz #if (RCAR_LOSSY_ENABLE == 1) 1447e532c4bSJorge Ramirez-Ortiz typedef struct bl2_lossy_info { 1457e532c4bSJorge Ramirez-Ortiz uint32_t magic; 1467e532c4bSJorge Ramirez-Ortiz uint32_t a0; 1477e532c4bSJorge Ramirez-Ortiz uint32_t b0; 1487e532c4bSJorge Ramirez-Ortiz } bl2_lossy_info_t; 1497e532c4bSJorge Ramirez-Ortiz 150a6de3db7SMarek Vasut static void bl2_lossy_gen_fdt(uint32_t no, uint64_t start_addr, 151a6de3db7SMarek Vasut uint64_t end_addr, uint32_t format, 152a6de3db7SMarek Vasut uint32_t enable, int fcnlnode) 153a6de3db7SMarek Vasut { 154a6de3db7SMarek Vasut const uint64_t fcnlsize = cpu_to_fdt64(end_addr - start_addr); 155a6de3db7SMarek Vasut char nodename[40] = { 0 }; 156a6de3db7SMarek Vasut int ret, node; 157a6de3db7SMarek Vasut 158a6de3db7SMarek Vasut /* Ignore undefined addresses */ 159a6de3db7SMarek Vasut if (start_addr == 0 && end_addr == 0) 160a6de3db7SMarek Vasut return; 161a6de3db7SMarek Vasut 162a6de3db7SMarek Vasut snprintf(nodename, sizeof(nodename), "lossy-decompression@"); 163a6de3db7SMarek Vasut unsigned_num_print(start_addr, 16, nodename + strlen(nodename)); 164a6de3db7SMarek Vasut 165a6de3db7SMarek Vasut node = ret = fdt_add_subnode(fdt, fcnlnode, nodename); 166a6de3db7SMarek Vasut if (ret < 0) { 167a6de3db7SMarek Vasut NOTICE("BL2: Cannot create FCNL node (ret=%i)\n", ret); 168a6de3db7SMarek Vasut panic(); 169a6de3db7SMarek Vasut } 170a6de3db7SMarek Vasut 171a6de3db7SMarek Vasut ret = fdt_setprop_string(fdt, node, "compatible", 172a6de3db7SMarek Vasut "renesas,lossy-decompression"); 173a6de3db7SMarek Vasut if (ret < 0) { 174a6de3db7SMarek Vasut NOTICE("BL2: Cannot add FCNL compat string (ret=%i)\n", ret); 175a6de3db7SMarek Vasut panic(); 176a6de3db7SMarek Vasut } 177a6de3db7SMarek Vasut 178a6de3db7SMarek Vasut ret = fdt_appendprop_string(fdt, node, "compatible", 179a6de3db7SMarek Vasut "shared-dma-pool"); 180a6de3db7SMarek Vasut if (ret < 0) { 181a6de3db7SMarek Vasut NOTICE("BL2: Cannot append FCNL compat string (ret=%i)\n", ret); 182a6de3db7SMarek Vasut panic(); 183a6de3db7SMarek Vasut } 184a6de3db7SMarek Vasut 185a6de3db7SMarek Vasut ret = fdt_setprop_u64(fdt, node, "reg", start_addr); 186a6de3db7SMarek Vasut if (ret < 0) { 187a6de3db7SMarek Vasut NOTICE("BL2: Cannot add FCNL reg prop (ret=%i)\n", ret); 188a6de3db7SMarek Vasut panic(); 189a6de3db7SMarek Vasut } 190a6de3db7SMarek Vasut 191a6de3db7SMarek Vasut ret = fdt_appendprop(fdt, node, "reg", &fcnlsize, sizeof(fcnlsize)); 192a6de3db7SMarek Vasut if (ret < 0) { 193a6de3db7SMarek Vasut NOTICE("BL2: Cannot append FCNL reg size prop (ret=%i)\n", ret); 194a6de3db7SMarek Vasut panic(); 195a6de3db7SMarek Vasut } 196a6de3db7SMarek Vasut 197a6de3db7SMarek Vasut ret = fdt_setprop(fdt, node, "no-map", NULL, 0); 198a6de3db7SMarek Vasut if (ret < 0) { 199a6de3db7SMarek Vasut NOTICE("BL2: Cannot add FCNL no-map prop (ret=%i)\n", ret); 200a6de3db7SMarek Vasut panic(); 201a6de3db7SMarek Vasut } 202a6de3db7SMarek Vasut 203a6de3db7SMarek Vasut ret = fdt_setprop_u32(fdt, node, "renesas,formats", format); 204a6de3db7SMarek Vasut if (ret < 0) { 205a6de3db7SMarek Vasut NOTICE("BL2: Cannot add FCNL formats prop (ret=%i)\n", ret); 206a6de3db7SMarek Vasut panic(); 207a6de3db7SMarek Vasut } 208a6de3db7SMarek Vasut } 209a6de3db7SMarek Vasut 2107e532c4bSJorge Ramirez-Ortiz static void bl2_lossy_setting(uint32_t no, uint64_t start_addr, 2117e532c4bSJorge Ramirez-Ortiz uint64_t end_addr, uint32_t format, 212a6de3db7SMarek Vasut uint32_t enable, int fcnlnode) 2137e532c4bSJorge Ramirez-Ortiz { 2147e532c4bSJorge Ramirez-Ortiz bl2_lossy_info_t info; 2157e532c4bSJorge Ramirez-Ortiz uint32_t reg; 2167e532c4bSJorge Ramirez-Ortiz 217a6de3db7SMarek Vasut bl2_lossy_gen_fdt(no, start_addr, end_addr, format, enable, fcnlnode); 218a6de3db7SMarek Vasut 2197e532c4bSJorge Ramirez-Ortiz reg = format | (start_addr >> 20); 2207e532c4bSJorge Ramirez-Ortiz mmio_write_32(AXI_DCMPAREACRA0 + 0x8 * no, reg); 2217e532c4bSJorge Ramirez-Ortiz mmio_write_32(AXI_DCMPAREACRB0 + 0x8 * no, end_addr >> 20); 2227e532c4bSJorge Ramirez-Ortiz mmio_write_32(AXI_DCMPAREACRA0 + 0x8 * no, reg | enable); 2237e532c4bSJorge Ramirez-Ortiz 2247e532c4bSJorge Ramirez-Ortiz info.magic = 0x12345678U; 2257e532c4bSJorge Ramirez-Ortiz info.a0 = mmio_read_32(AXI_DCMPAREACRA0 + 0x8 * no); 2267e532c4bSJorge Ramirez-Ortiz info.b0 = mmio_read_32(AXI_DCMPAREACRB0 + 0x8 * no); 2277e532c4bSJorge Ramirez-Ortiz 2287e532c4bSJorge Ramirez-Ortiz mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no, info.magic); 2297e532c4bSJorge Ramirez-Ortiz mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x4, info.a0); 2307e532c4bSJorge Ramirez-Ortiz mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x8, info.b0); 2317e532c4bSJorge Ramirez-Ortiz 2327e532c4bSJorge Ramirez-Ortiz NOTICE(" Entry %d: DCMPAREACRAx:0x%x DCMPAREACRBx:0x%x\n", no, 2337e532c4bSJorge Ramirez-Ortiz mmio_read_32(AXI_DCMPAREACRA0 + 0x8 * no), 2347e532c4bSJorge Ramirez-Ortiz mmio_read_32(AXI_DCMPAREACRB0 + 0x8 * no)); 2357e532c4bSJorge Ramirez-Ortiz } 236f945498fSDetlev Casanova 237f945498fSDetlev Casanova static int bl2_create_reserved_memory(void) 238f945498fSDetlev Casanova { 239f945498fSDetlev Casanova int ret; 240f945498fSDetlev Casanova 241f945498fSDetlev Casanova int fcnlnode = fdt_add_subnode(fdt, 0, "reserved-memory"); 242f945498fSDetlev Casanova if (fcnlnode < 0) { 243f945498fSDetlev Casanova NOTICE("BL2: Cannot create reserved mem node (ret=%i)\n", 244f945498fSDetlev Casanova fcnlnode); 245f945498fSDetlev Casanova panic(); 246f945498fSDetlev Casanova } 247f945498fSDetlev Casanova 248f945498fSDetlev Casanova ret = fdt_setprop(fdt, fcnlnode, "ranges", NULL, 0); 249f945498fSDetlev Casanova if (ret < 0) { 250f945498fSDetlev Casanova NOTICE("BL2: Cannot add FCNL ranges prop (ret=%i)\n", ret); 251f945498fSDetlev Casanova panic(); 252f945498fSDetlev Casanova } 253f945498fSDetlev Casanova 254f945498fSDetlev Casanova ret = fdt_setprop_u32(fdt, fcnlnode, "#address-cells", 2); 255f945498fSDetlev Casanova if (ret < 0) { 256f945498fSDetlev Casanova NOTICE("BL2: Cannot add FCNL #address-cells prop (ret=%i)\n", ret); 257f945498fSDetlev Casanova panic(); 258f945498fSDetlev Casanova } 259f945498fSDetlev Casanova 260f945498fSDetlev Casanova ret = fdt_setprop_u32(fdt, fcnlnode, "#size-cells", 2); 261f945498fSDetlev Casanova if (ret < 0) { 262f945498fSDetlev Casanova NOTICE("BL2: Cannot add FCNL #size-cells prop (ret=%i)\n", ret); 263f945498fSDetlev Casanova panic(); 264f945498fSDetlev Casanova } 265f945498fSDetlev Casanova 266f945498fSDetlev Casanova return fcnlnode; 267f945498fSDetlev Casanova } 268f945498fSDetlev Casanova 269f945498fSDetlev Casanova static void bl2_create_fcnl_reserved_memory(void) 270f945498fSDetlev Casanova { 271f945498fSDetlev Casanova int fcnlnode; 272f945498fSDetlev Casanova 273f945498fSDetlev Casanova NOTICE("BL2: Lossy Decomp areas\n"); 274f945498fSDetlev Casanova 275f945498fSDetlev Casanova fcnlnode = bl2_create_reserved_memory(); 276f945498fSDetlev Casanova 277f945498fSDetlev Casanova bl2_lossy_setting(0, LOSSY_ST_ADDR0, LOSSY_END_ADDR0, 278f945498fSDetlev Casanova LOSSY_FMT0, LOSSY_ENA_DIS0, fcnlnode); 279f945498fSDetlev Casanova bl2_lossy_setting(1, LOSSY_ST_ADDR1, LOSSY_END_ADDR1, 280f945498fSDetlev Casanova LOSSY_FMT1, LOSSY_ENA_DIS1, fcnlnode); 281f945498fSDetlev Casanova bl2_lossy_setting(2, LOSSY_ST_ADDR2, LOSSY_END_ADDR2, 282f945498fSDetlev Casanova LOSSY_FMT2, LOSSY_ENA_DIS2, fcnlnode); 283f945498fSDetlev Casanova } 284f945498fSDetlev Casanova #else 285f945498fSDetlev Casanova static void bl2_create_fcnl_reserved_memory(void) {} 2867e532c4bSJorge Ramirez-Ortiz #endif 2877e532c4bSJorge Ramirez-Ortiz 2887e532c4bSJorge Ramirez-Ortiz void bl2_plat_flush_bl31_params(void) 2897e532c4bSJorge Ramirez-Ortiz { 2907e532c4bSJorge Ramirez-Ortiz uint32_t product_cut, product, cut; 2917e532c4bSJorge Ramirez-Ortiz uint32_t boot_dev, boot_cpu; 2927e532c4bSJorge Ramirez-Ortiz uint32_t lcs, reg, val; 2937e532c4bSJorge Ramirez-Ortiz 2947e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_MODEMR); 2957e532c4bSJorge Ramirez-Ortiz boot_dev = reg & MODEMR_BOOT_DEV_MASK; 2967e532c4bSJorge Ramirez-Ortiz 2977e532c4bSJorge Ramirez-Ortiz if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || 2987e532c4bSJorge Ramirez-Ortiz boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) 2997e532c4bSJorge Ramirez-Ortiz emmc_terminate(); 3007e532c4bSJorge Ramirez-Ortiz 3017e532c4bSJorge Ramirez-Ortiz if ((reg & MODEMR_BOOT_CPU_MASK) != MODEMR_BOOT_CPU_CR7) 3027e532c4bSJorge Ramirez-Ortiz bl2_secure_setting(); 3037e532c4bSJorge Ramirez-Ortiz 3047e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_PRR); 305df51d8feSMarek Vasut product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 306df51d8feSMarek Vasut product = reg & PRR_PRODUCT_MASK; 307df51d8feSMarek Vasut cut = reg & PRR_CUT_MASK; 3087e532c4bSJorge Ramirez-Ortiz 309df51d8feSMarek Vasut if (product == PRR_PRODUCT_M3 && PRR_PRODUCT_30 > cut) 3107e532c4bSJorge Ramirez-Ortiz goto tlb; 3117e532c4bSJorge Ramirez-Ortiz 312df51d8feSMarek Vasut if (product == PRR_PRODUCT_H3 && PRR_PRODUCT_20 > cut) 3137e532c4bSJorge Ramirez-Ortiz goto tlb; 3147e532c4bSJorge Ramirez-Ortiz 3157e532c4bSJorge Ramirez-Ortiz /* Disable MFIS write protection */ 3167e532c4bSJorge Ramirez-Ortiz mmio_write_32(MFISWPCNTR, MFISWPCNTR_PASSWORD | 1); 3177e532c4bSJorge Ramirez-Ortiz 3187e532c4bSJorge Ramirez-Ortiz tlb: 3197e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_MODEMR); 3207e532c4bSJorge Ramirez-Ortiz boot_cpu = reg & MODEMR_BOOT_CPU_MASK; 3217e532c4bSJorge Ramirez-Ortiz if (boot_cpu != MODEMR_BOOT_CPU_CA57 && 3227e532c4bSJorge Ramirez-Ortiz boot_cpu != MODEMR_BOOT_CPU_CA53) 3237e532c4bSJorge Ramirez-Ortiz goto mmu; 3247e532c4bSJorge Ramirez-Ortiz 325df51d8feSMarek Vasut if (product_cut == PRR_PRODUCT_H3_CUT20) { 3267e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); 3277e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUVI1_IMSCTLR, IMSCTLR_DISCACHE); 3287e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); 3297e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV1_IMSCTLR, IMSCTLR_DISCACHE); 3307e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV2_IMSCTLR, IMSCTLR_DISCACHE); 3317e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV3_IMSCTLR, IMSCTLR_DISCACHE); 332df51d8feSMarek Vasut } else if (product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) || 333df51d8feSMarek Vasut product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11)) { 3347e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); 3357e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); 336df51d8feSMarek Vasut } else if ((product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) || 337df51d8feSMarek Vasut (product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_11))) { 3387e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); 33932385427SMarek Vasut mmio_write_32(IPMMUVP0_IMSCTLR, IMSCTLR_DISCACHE); 3407e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); 3417e532c4bSJorge Ramirez-Ortiz } 3427e532c4bSJorge Ramirez-Ortiz 343df51d8feSMarek Vasut if (product_cut == (PRR_PRODUCT_H3_CUT20) || 344df51d8feSMarek Vasut product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) || 345df51d8feSMarek Vasut product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11) || 346df51d8feSMarek Vasut product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) { 3477e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUHC_IMSCTLR, IMSCTLR_DISCACHE); 3487e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMURT_IMSCTLR, IMSCTLR_DISCACHE); 3497e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUMP_IMSCTLR, IMSCTLR_DISCACHE); 3507e532c4bSJorge Ramirez-Ortiz 3517e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUDS0_IMSCTLR, IMSCTLR_DISCACHE); 3527e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUDS1_IMSCTLR, IMSCTLR_DISCACHE); 3537e532c4bSJorge Ramirez-Ortiz } 3547e532c4bSJorge Ramirez-Ortiz 3557e532c4bSJorge Ramirez-Ortiz mmu: 3567e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUMM_IMSCTLR, IPMMUMM_IMSCTLR_ENABLE); 3577e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUMM_IMAUXCTLR, IPMMUMM_IMAUXCTLR_NMERGE40_BIT); 3587e532c4bSJorge Ramirez-Ortiz 3597e532c4bSJorge Ramirez-Ortiz val = rcar_rom_get_lcs(&lcs); 3607e532c4bSJorge Ramirez-Ortiz if (val) { 3617e532c4bSJorge Ramirez-Ortiz ERROR("BL2: Failed to get the LCS. (%d)\n", val); 3627e532c4bSJorge Ramirez-Ortiz panic(); 3637e532c4bSJorge Ramirez-Ortiz } 3647e532c4bSJorge Ramirez-Ortiz 3657e532c4bSJorge Ramirez-Ortiz if (lcs == LCS_SE) 3667e532c4bSJorge Ramirez-Ortiz mmio_clrbits_32(P_ARMREG_SEC_CTRL, P_ARMREG_SEC_CTRL_PROT); 3677e532c4bSJorge Ramirez-Ortiz 3687e532c4bSJorge Ramirez-Ortiz rcar_swdt_release(); 3697e532c4bSJorge Ramirez-Ortiz bl2_system_cpg_init(); 3707e532c4bSJorge Ramirez-Ortiz 3717e532c4bSJorge Ramirez-Ortiz /* Disable data cache (clean and invalidate) */ 3727e532c4bSJorge Ramirez-Ortiz disable_mmu_el3(); 3737e06b067SToshiyuki Ogasahara #if RCAR_BL2_DCACHE == 1 3747e06b067SToshiyuki Ogasahara dcsw_op_all(DCCISW); 3757e06b067SToshiyuki Ogasahara #endif 3767e06b067SToshiyuki Ogasahara tlbialle3(); 3777e06b067SToshiyuki Ogasahara disable_mmu_icache_el3(); 3787e06b067SToshiyuki Ogasahara plat_invalidate_icache(); 3797e06b067SToshiyuki Ogasahara dsbsy(); 3807e06b067SToshiyuki Ogasahara isb(); 3817e532c4bSJorge Ramirez-Ortiz } 3827e532c4bSJorge Ramirez-Ortiz 3837e532c4bSJorge Ramirez-Ortiz static uint32_t is_ddr_backup_mode(void) 3847e532c4bSJorge Ramirez-Ortiz { 3857e532c4bSJorge Ramirez-Ortiz #if RCAR_SYSTEM_SUSPEND 3867e532c4bSJorge Ramirez-Ortiz static uint32_t reason = RCAR_COLD_BOOT; 3877e532c4bSJorge Ramirez-Ortiz static uint32_t once; 3887e532c4bSJorge Ramirez-Ortiz 3897e532c4bSJorge Ramirez-Ortiz #if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR 3907e532c4bSJorge Ramirez-Ortiz uint8_t data; 3917e532c4bSJorge Ramirez-Ortiz #endif 3927e532c4bSJorge Ramirez-Ortiz if (once) 3937e532c4bSJorge Ramirez-Ortiz return reason; 3947e532c4bSJorge Ramirez-Ortiz 3957e532c4bSJorge Ramirez-Ortiz once = 1; 3967e532c4bSJorge Ramirez-Ortiz if ((mmio_read_32(GPIO_INDT) & GPIO_BKUP_TRG_SHIFT) == 0) 3977e532c4bSJorge Ramirez-Ortiz return reason; 3987e532c4bSJorge Ramirez-Ortiz 3997e532c4bSJorge Ramirez-Ortiz #if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR 4007e532c4bSJorge Ramirez-Ortiz if (rcar_iic_dvfs_receive(PMIC, REG_KEEP10, &data)) { 4017e532c4bSJorge Ramirez-Ortiz ERROR("BL2: REG Keep10 READ ERROR.\n"); 4027e532c4bSJorge Ramirez-Ortiz panic(); 4037e532c4bSJorge Ramirez-Ortiz } 4047e532c4bSJorge Ramirez-Ortiz 4057e532c4bSJorge Ramirez-Ortiz if (KEEP10_MAGIC != data) 4067e532c4bSJorge Ramirez-Ortiz reason = RCAR_WARM_BOOT; 4077e532c4bSJorge Ramirez-Ortiz #else 4087e532c4bSJorge Ramirez-Ortiz reason = RCAR_WARM_BOOT; 4097e532c4bSJorge Ramirez-Ortiz #endif 4107e532c4bSJorge Ramirez-Ortiz return reason; 4117e532c4bSJorge Ramirez-Ortiz #else 4127e532c4bSJorge Ramirez-Ortiz return RCAR_COLD_BOOT; 4137e532c4bSJorge Ramirez-Ortiz #endif 4147e532c4bSJorge Ramirez-Ortiz } 4157e532c4bSJorge Ramirez-Ortiz 416ddf2ca03SMarek Vasut #if RCAR_GEN3_BL33_GZIP == 1 417ddf2ca03SMarek Vasut void bl2_plat_preload_setup(void) 418ddf2ca03SMarek Vasut { 419ddf2ca03SMarek Vasut image_decompress_init(BL33_COMP_BASE, BL33_COMP_SIZE, gunzip); 420ddf2ca03SMarek Vasut } 421ddf2ca03SMarek Vasut #endif 422ddf2ca03SMarek Vasut 4234f7e0fa3STakuya Sakata static uint64_t check_secure_load_area(uintptr_t base, uint32_t size, 4244f7e0fa3STakuya Sakata uintptr_t dest, uint32_t len) 4257e532c4bSJorge Ramirez-Ortiz { 4264f7e0fa3STakuya Sakata uintptr_t free_end, requested_end; 4277e532c4bSJorge Ramirez-Ortiz 4284f7e0fa3STakuya Sakata /* 4294f7e0fa3STakuya Sakata * Handle corner cases first. 4304f7e0fa3STakuya Sakata * 4314f7e0fa3STakuya Sakata * The order of the 2 tests is important, because if there's no space 4324f7e0fa3STakuya Sakata * left (i.e. free_size == 0) but we don't ask for any memory 4334f7e0fa3STakuya Sakata * (i.e. size == 0) then we should report that the memory is free. 4344f7e0fa3STakuya Sakata */ 4354f7e0fa3STakuya Sakata if (len == 0U) { 4364f7e0fa3STakuya Sakata WARN("BL2: load data size is zero\n"); 4374f7e0fa3STakuya Sakata return 0; /* A zero-byte region is always free */ 438ddf2ca03SMarek Vasut } 4394f7e0fa3STakuya Sakata if (size == 0U) { 4404f7e0fa3STakuya Sakata goto err; 4417e532c4bSJorge Ramirez-Ortiz } 4427e532c4bSJorge Ramirez-Ortiz 4434f7e0fa3STakuya Sakata /* 4444f7e0fa3STakuya Sakata * Check that the end addresses don't overflow. 4454f7e0fa3STakuya Sakata * If they do, consider that this memory region is not free, as this 4464f7e0fa3STakuya Sakata * is an invalid scenario. 4474f7e0fa3STakuya Sakata */ 4484f7e0fa3STakuya Sakata if (check_uptr_overflow(base, size - 1U)) { 4494f7e0fa3STakuya Sakata goto err; 4504f7e0fa3STakuya Sakata } 4514f7e0fa3STakuya Sakata free_end = base + (size - 1U); 4524f7e0fa3STakuya Sakata 4534f7e0fa3STakuya Sakata if (check_uptr_overflow(dest, len - 1U)) { 4544f7e0fa3STakuya Sakata goto err; 4554f7e0fa3STakuya Sakata } 4564f7e0fa3STakuya Sakata requested_end = dest + (len - 1U); 4574f7e0fa3STakuya Sakata 4584f7e0fa3STakuya Sakata /* 4594f7e0fa3STakuya Sakata * Finally, check that the requested memory region lies within the free 4604f7e0fa3STakuya Sakata * region. 4614f7e0fa3STakuya Sakata */ 4624f7e0fa3STakuya Sakata if ((dest < base) || (requested_end > free_end)) { 4634f7e0fa3STakuya Sakata goto err; 4644f7e0fa3STakuya Sakata } 4654f7e0fa3STakuya Sakata 4664f7e0fa3STakuya Sakata return 0; 4674f7e0fa3STakuya Sakata 4684f7e0fa3STakuya Sakata err: 4694f7e0fa3STakuya Sakata ERROR("BL2: load data is outside the loadable area.\n"); 4704f7e0fa3STakuya Sakata ERROR("BL2: dst=0x%lx, len=%d(0x%x)\n", dest, len, len); 4714f7e0fa3STakuya Sakata return 1; 4724f7e0fa3STakuya Sakata } 4734f7e0fa3STakuya Sakata 4744f7e0fa3STakuya Sakata static uint64_t rcar_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest, 4754f7e0fa3STakuya Sakata uint32_t *len) 47613856f37SToshiyuki Ogasahara { 4774f7e0fa3STakuya Sakata uint32_t cert; 47813856f37SToshiyuki Ogasahara int ret; 47913856f37SToshiyuki Ogasahara 48013856f37SToshiyuki Ogasahara ret = rcar_get_certificate(certid, &cert); 48113856f37SToshiyuki Ogasahara if (ret) { 48213856f37SToshiyuki Ogasahara ERROR("%s : cert file load error", __func__); 48313856f37SToshiyuki Ogasahara return 1; 48413856f37SToshiyuki Ogasahara } 48513856f37SToshiyuki Ogasahara 4864f7e0fa3STakuya Sakata rcar_read_certificate((uint64_t) cert, len, dest); 4874f7e0fa3STakuya Sakata 4884f7e0fa3STakuya Sakata return 0; 4894f7e0fa3STakuya Sakata } 4904f7e0fa3STakuya Sakata 4914f7e0fa3STakuya Sakata int bl2_plat_handle_pre_image_load(unsigned int image_id) 4924f7e0fa3STakuya Sakata { 4934f7e0fa3STakuya Sakata u_register_t *boot_kind = (void *) BOOT_KIND_BASE; 4944f7e0fa3STakuya Sakata bl_mem_params_node_t *bl_mem_params; 4954f7e0fa3STakuya Sakata uintptr_t dev_handle; 4964f7e0fa3STakuya Sakata uintptr_t image_spec; 4974f7e0fa3STakuya Sakata uintptr_t dest; 4984f7e0fa3STakuya Sakata uint32_t len; 4994f7e0fa3STakuya Sakata uint64_t ui64_ret; 5004f7e0fa3STakuya Sakata int iret; 5014f7e0fa3STakuya Sakata 5024f7e0fa3STakuya Sakata bl_mem_params = get_bl_mem_params_node(image_id); 5034f7e0fa3STakuya Sakata if (bl_mem_params == NULL) { 5044f7e0fa3STakuya Sakata ERROR("BL2: Failed to get loading parameter.\n"); 5054f7e0fa3STakuya Sakata return 1; 5064f7e0fa3STakuya Sakata } 5074f7e0fa3STakuya Sakata 5084f7e0fa3STakuya Sakata switch (image_id) { 5094f7e0fa3STakuya Sakata case BL31_IMAGE_ID: 5104f7e0fa3STakuya Sakata if (is_ddr_backup_mode() == RCAR_COLD_BOOT) { 5114f7e0fa3STakuya Sakata iret = plat_get_image_source(image_id, &dev_handle, 5124f7e0fa3STakuya Sakata &image_spec); 5134f7e0fa3STakuya Sakata if (iret != 0) { 5144f7e0fa3STakuya Sakata return 1; 5154f7e0fa3STakuya Sakata } 5164f7e0fa3STakuya Sakata 5174f7e0fa3STakuya Sakata ui64_ret = rcar_get_dest_addr_from_cert( 5184f7e0fa3STakuya Sakata SOC_FW_CONTENT_CERT_ID, &dest, &len); 5194f7e0fa3STakuya Sakata if (ui64_ret != 0U) { 5204f7e0fa3STakuya Sakata return 1; 5214f7e0fa3STakuya Sakata } 5224f7e0fa3STakuya Sakata 5234f7e0fa3STakuya Sakata ui64_ret = check_secure_load_area( 5244f7e0fa3STakuya Sakata BL31_BASE, BL31_LIMIT - BL31_BASE, 5254f7e0fa3STakuya Sakata dest, len); 5264f7e0fa3STakuya Sakata if (ui64_ret != 0U) { 5274f7e0fa3STakuya Sakata return 1; 5284f7e0fa3STakuya Sakata } 5294f7e0fa3STakuya Sakata 5304f7e0fa3STakuya Sakata *boot_kind = RCAR_COLD_BOOT; 5314f7e0fa3STakuya Sakata flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind)); 5324f7e0fa3STakuya Sakata 5334f7e0fa3STakuya Sakata bl_mem_params->image_info.image_base = dest; 5344f7e0fa3STakuya Sakata bl_mem_params->image_info.image_size = len; 5354f7e0fa3STakuya Sakata } else { 5364f7e0fa3STakuya Sakata *boot_kind = RCAR_WARM_BOOT; 5374f7e0fa3STakuya Sakata flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind)); 5384f7e0fa3STakuya Sakata 5394f7e0fa3STakuya Sakata console_flush(); 5404f7e0fa3STakuya Sakata bl2_plat_flush_bl31_params(); 5414f7e0fa3STakuya Sakata 5424f7e0fa3STakuya Sakata /* will not return */ 5434f7e0fa3STakuya Sakata bl2_enter_bl31(&bl_mem_params->ep_info); 5444f7e0fa3STakuya Sakata } 5454f7e0fa3STakuya Sakata 5464f7e0fa3STakuya Sakata return 0; 5474f7e0fa3STakuya Sakata #ifndef SPD_NONE 5484f7e0fa3STakuya Sakata case BL32_IMAGE_ID: 5494f7e0fa3STakuya Sakata ui64_ret = rcar_get_dest_addr_from_cert( 5504f7e0fa3STakuya Sakata TRUSTED_OS_FW_CONTENT_CERT_ID, &dest, &len); 5514f7e0fa3STakuya Sakata if (ui64_ret != 0U) { 5524f7e0fa3STakuya Sakata return 1; 5534f7e0fa3STakuya Sakata } 5544f7e0fa3STakuya Sakata 5554f7e0fa3STakuya Sakata ui64_ret = check_secure_load_area( 5564f7e0fa3STakuya Sakata BL32_BASE, BL32_LIMIT - BL32_BASE, dest, len); 5574f7e0fa3STakuya Sakata if (ui64_ret != 0U) { 5584f7e0fa3STakuya Sakata return 1; 5594f7e0fa3STakuya Sakata } 5604f7e0fa3STakuya Sakata 5614f7e0fa3STakuya Sakata bl_mem_params->image_info.image_base = dest; 5624f7e0fa3STakuya Sakata bl_mem_params->image_info.image_size = len; 5634f7e0fa3STakuya Sakata 5644f7e0fa3STakuya Sakata return 0; 5654f7e0fa3STakuya Sakata #endif 5664f7e0fa3STakuya Sakata case BL33_IMAGE_ID: 5674f7e0fa3STakuya Sakata /* case of image_id == BL33_IMAGE_ID */ 5684f7e0fa3STakuya Sakata ui64_ret = rcar_get_dest_addr_from_cert( 5694f7e0fa3STakuya Sakata NON_TRUSTED_FW_CONTENT_CERT_ID, 5704f7e0fa3STakuya Sakata &dest, &len); 5714f7e0fa3STakuya Sakata 5724f7e0fa3STakuya Sakata if (ui64_ret != 0U) { 5734f7e0fa3STakuya Sakata return 1; 5744f7e0fa3STakuya Sakata } 5754f7e0fa3STakuya Sakata 576*e6b05fcbSHieu Nguyen bl_mem_params->image_info.image_base = dest; 577*e6b05fcbSHieu Nguyen bl_mem_params->image_info.image_size = len; 578*e6b05fcbSHieu Nguyen 5794f7e0fa3STakuya Sakata #if RCAR_GEN3_BL33_GZIP == 1 5804f7e0fa3STakuya Sakata image_decompress_prepare(&bl_mem_params->image_info); 5814f7e0fa3STakuya Sakata #endif 5824f7e0fa3STakuya Sakata 5834f7e0fa3STakuya Sakata return 0; 5844f7e0fa3STakuya Sakata default: 5854f7e0fa3STakuya Sakata return 1; 5864f7e0fa3STakuya Sakata } 58713856f37SToshiyuki Ogasahara 58813856f37SToshiyuki Ogasahara return 0; 58913856f37SToshiyuki Ogasahara } 59013856f37SToshiyuki Ogasahara 5917e532c4bSJorge Ramirez-Ortiz int bl2_plat_handle_post_image_load(unsigned int image_id) 5927e532c4bSJorge Ramirez-Ortiz { 5937e532c4bSJorge Ramirez-Ortiz static bl2_to_bl31_params_mem_t *params; 5947e532c4bSJorge Ramirez-Ortiz bl_mem_params_node_t *bl_mem_params; 5957e532c4bSJorge Ramirez-Ortiz 5967e532c4bSJorge Ramirez-Ortiz if (!params) { 5977e532c4bSJorge Ramirez-Ortiz params = (bl2_to_bl31_params_mem_t *) PARAMS_BASE; 5987e532c4bSJorge Ramirez-Ortiz memset((void *)PARAMS_BASE, 0, sizeof(*params)); 5997e532c4bSJorge Ramirez-Ortiz } 6007e532c4bSJorge Ramirez-Ortiz 6017e532c4bSJorge Ramirez-Ortiz bl_mem_params = get_bl_mem_params_node(image_id); 6024f7e0fa3STakuya Sakata if (!bl_mem_params) { 6034f7e0fa3STakuya Sakata ERROR("BL2: Failed to get loading parameter.\n"); 6044f7e0fa3STakuya Sakata return 1; 6054f7e0fa3STakuya Sakata } 6067e532c4bSJorge Ramirez-Ortiz 6077e532c4bSJorge Ramirez-Ortiz switch (image_id) { 6087e532c4bSJorge Ramirez-Ortiz case BL31_IMAGE_ID: 6094f7e0fa3STakuya Sakata bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base; 6104f7e0fa3STakuya Sakata return 0; 6117e532c4bSJorge Ramirez-Ortiz case BL32_IMAGE_ID: 6124f7e0fa3STakuya Sakata bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base; 6137e532c4bSJorge Ramirez-Ortiz memcpy(¶ms->bl32_ep_info, &bl_mem_params->ep_info, 6147e532c4bSJorge Ramirez-Ortiz sizeof(entry_point_info_t)); 6154f7e0fa3STakuya Sakata return 0; 6167e532c4bSJorge Ramirez-Ortiz case BL33_IMAGE_ID: 617ddf2ca03SMarek Vasut #if RCAR_GEN3_BL33_GZIP == 1 6184f7e0fa3STakuya Sakata int ret; 619ddf2ca03SMarek Vasut if ((mmio_read_32(BL33_COMP_BASE) & 0xffff) == 0x8b1f) { 620ddf2ca03SMarek Vasut /* decompress gzip-compressed image */ 621ddf2ca03SMarek Vasut ret = image_decompress(&bl_mem_params->image_info); 622ddf2ca03SMarek Vasut if (ret != 0) { 623ddf2ca03SMarek Vasut return ret; 624ddf2ca03SMarek Vasut } 625ddf2ca03SMarek Vasut } else { 626ddf2ca03SMarek Vasut /* plain image, copy it in place */ 627ddf2ca03SMarek Vasut memcpy((void *)BL33_BASE, (void *)BL33_COMP_BASE, 628ddf2ca03SMarek Vasut bl_mem_params->image_info.image_size); 629ddf2ca03SMarek Vasut } 630ddf2ca03SMarek Vasut #endif 631*e6b05fcbSHieu Nguyen bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base; 6327e532c4bSJorge Ramirez-Ortiz memcpy(¶ms->bl33_ep_info, &bl_mem_params->ep_info, 6337e532c4bSJorge Ramirez-Ortiz sizeof(entry_point_info_t)); 6344f7e0fa3STakuya Sakata return 0; 6354f7e0fa3STakuya Sakata default: 6364f7e0fa3STakuya Sakata return 1; 6377e532c4bSJorge Ramirez-Ortiz } 6387e532c4bSJorge Ramirez-Ortiz 6397e532c4bSJorge Ramirez-Ortiz return 0; 6407e532c4bSJorge Ramirez-Ortiz } 6417e532c4bSJorge Ramirez-Ortiz 642db9a1555SMarek Vasut struct meminfo *bl2_plat_sec_mem_layout(void) 6437e532c4bSJorge Ramirez-Ortiz { 6447e532c4bSJorge Ramirez-Ortiz return &bl2_tzram_layout; 6457e532c4bSJorge Ramirez-Ortiz } 6467e532c4bSJorge Ramirez-Ortiz 647b7f6525dSJustin Chadwell static void bl2_populate_compatible_string(void *dt) 648ac49c5fbSMarek Vasut { 649ac49c5fbSMarek Vasut uint32_t board_type; 650ac49c5fbSMarek Vasut uint32_t board_rev; 651ac49c5fbSMarek Vasut uint32_t reg; 652ac49c5fbSMarek Vasut int ret; 653ac49c5fbSMarek Vasut 6546be71b09SMarek Vasut fdt_setprop_u32(dt, 0, "#address-cells", 2); 6556be71b09SMarek Vasut fdt_setprop_u32(dt, 0, "#size-cells", 2); 6566be71b09SMarek Vasut 657ac49c5fbSMarek Vasut /* Populate compatible string */ 658ac49c5fbSMarek Vasut rcar_get_board_type(&board_type, &board_rev); 659ac49c5fbSMarek Vasut switch (board_type) { 660ac49c5fbSMarek Vasut case BOARD_SALVATOR_X: 661b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 662ac49c5fbSMarek Vasut "renesas,salvator-x"); 663ac49c5fbSMarek Vasut break; 664ac49c5fbSMarek Vasut case BOARD_SALVATOR_XS: 665b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 666ac49c5fbSMarek Vasut "renesas,salvator-xs"); 667ac49c5fbSMarek Vasut break; 668ac49c5fbSMarek Vasut case BOARD_STARTER_KIT: 669b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 670ac49c5fbSMarek Vasut "renesas,m3ulcb"); 671ac49c5fbSMarek Vasut break; 672ac49c5fbSMarek Vasut case BOARD_STARTER_KIT_PRE: 673b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 674ac49c5fbSMarek Vasut "renesas,h3ulcb"); 675ac49c5fbSMarek Vasut break; 676b709fe9cSValentine Barshak case BOARD_EAGLE: 677b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 678b709fe9cSValentine Barshak "renesas,eagle"); 679b709fe9cSValentine Barshak break; 680ac49c5fbSMarek Vasut case BOARD_EBISU: 681ac49c5fbSMarek Vasut case BOARD_EBISU_4D: 682b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 683ac49c5fbSMarek Vasut "renesas,ebisu"); 684ac49c5fbSMarek Vasut break; 685bfbf5df4SMarek Vasut case BOARD_DRAAK: 686b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 687bfbf5df4SMarek Vasut "renesas,draak"); 688bfbf5df4SMarek Vasut break; 689ac49c5fbSMarek Vasut default: 690ac49c5fbSMarek Vasut NOTICE("BL2: Cannot set compatible string, board unsupported\n"); 691ac49c5fbSMarek Vasut panic(); 692ac49c5fbSMarek Vasut } 693ac49c5fbSMarek Vasut 694ac49c5fbSMarek Vasut if (ret < 0) { 695ac49c5fbSMarek Vasut NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret); 696ac49c5fbSMarek Vasut panic(); 697ac49c5fbSMarek Vasut } 698ac49c5fbSMarek Vasut 699ac49c5fbSMarek Vasut reg = mmio_read_32(RCAR_PRR); 700df51d8feSMarek Vasut switch (reg & PRR_PRODUCT_MASK) { 701df51d8feSMarek Vasut case PRR_PRODUCT_H3: 702b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 703ac49c5fbSMarek Vasut "renesas,r8a7795"); 704ac49c5fbSMarek Vasut break; 705df51d8feSMarek Vasut case PRR_PRODUCT_M3: 706b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 707ac49c5fbSMarek Vasut "renesas,r8a7796"); 708ac49c5fbSMarek Vasut break; 709df51d8feSMarek Vasut case PRR_PRODUCT_M3N: 710b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 711ac49c5fbSMarek Vasut "renesas,r8a77965"); 712ac49c5fbSMarek Vasut break; 713df51d8feSMarek Vasut case PRR_PRODUCT_V3M: 714b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 715b709fe9cSValentine Barshak "renesas,r8a77970"); 716b709fe9cSValentine Barshak break; 717df51d8feSMarek Vasut case PRR_PRODUCT_E3: 718b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 719ac49c5fbSMarek Vasut "renesas,r8a77990"); 720ac49c5fbSMarek Vasut break; 721df51d8feSMarek Vasut case PRR_PRODUCT_D3: 722b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 723bfbf5df4SMarek Vasut "renesas,r8a77995"); 724bfbf5df4SMarek Vasut break; 725ac49c5fbSMarek Vasut default: 726ac49c5fbSMarek Vasut NOTICE("BL2: Cannot set compatible string, SoC unsupported\n"); 727ac49c5fbSMarek Vasut panic(); 728ac49c5fbSMarek Vasut } 729ac49c5fbSMarek Vasut 730ac49c5fbSMarek Vasut if (ret < 0) { 731ac49c5fbSMarek Vasut NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret); 732ac49c5fbSMarek Vasut panic(); 733ac49c5fbSMarek Vasut } 734ac49c5fbSMarek Vasut } 735ac49c5fbSMarek Vasut 73612c75c88SMarek Vasut static void bl2_add_rpc_node(void) 73712c75c88SMarek Vasut { 73812c75c88SMarek Vasut #if (RCAR_RPC_HYPERFLASH_LOCKED == 0) 73912c75c88SMarek Vasut int ret, node; 74012c75c88SMarek Vasut 74112c75c88SMarek Vasut node = ret = fdt_add_subnode(fdt, 0, "soc"); 74212c75c88SMarek Vasut if (ret < 0) { 74312c75c88SMarek Vasut goto err; 74412c75c88SMarek Vasut } 74512c75c88SMarek Vasut 74608ae2471SGeert Uytterhoeven node = ret = fdt_add_subnode(fdt, node, "spi@ee200000"); 74712c75c88SMarek Vasut if (ret < 0) { 74812c75c88SMarek Vasut goto err; 74912c75c88SMarek Vasut } 75012c75c88SMarek Vasut 75112c75c88SMarek Vasut ret = fdt_setprop_string(fdt, node, "status", "okay"); 75212c75c88SMarek Vasut if (ret < 0) { 75312c75c88SMarek Vasut goto err; 75412c75c88SMarek Vasut } 75512c75c88SMarek Vasut 75612c75c88SMarek Vasut return; 75712c75c88SMarek Vasut err: 75812c75c88SMarek Vasut NOTICE("BL2: Cannot add RPC node to FDT (ret=%i)\n", ret); 75912c75c88SMarek Vasut panic(); 76012c75c88SMarek Vasut #endif 76112c75c88SMarek Vasut } 76212c75c88SMarek Vasut 763b9e34d14SMarek Vasut static void bl2_add_kaslr_seed(void) 764b9e34d14SMarek Vasut { 765b9e34d14SMarek Vasut uint32_t cnt, isr, prr; 766b9e34d14SMarek Vasut uint64_t seed; 767b9e34d14SMarek Vasut int ret, node; 768b9e34d14SMarek Vasut 769b9e34d14SMarek Vasut /* SCEG is only available on H3/M3-W/M3-N */ 770b9e34d14SMarek Vasut prr = mmio_read_32(RCAR_PRR); 771b9e34d14SMarek Vasut switch (prr & PRR_PRODUCT_MASK) { 772b9e34d14SMarek Vasut case PRR_PRODUCT_H3: 773b9e34d14SMarek Vasut case PRR_PRODUCT_M3: 774b9e34d14SMarek Vasut case PRR_PRODUCT_M3N: 775b9e34d14SMarek Vasut break; 776b9e34d14SMarek Vasut default: 777b9e34d14SMarek Vasut return; 778b9e34d14SMarek Vasut } 779b9e34d14SMarek Vasut 780b9e34d14SMarek Vasut mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SW_RESET_REG_ADDR, 781b9e34d14SMarek Vasut CC63_TRNG_SW_RESET_REG_SET); 782b9e34d14SMarek Vasut 783b9e34d14SMarek Vasut do { 784b9e34d14SMarek Vasut mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_CLK_ENABLE_REG_ADDR, 785b9e34d14SMarek Vasut CC63_TRNG_CLK_ENABLE_REG_SET); 786b9e34d14SMarek Vasut mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SAMPLE_CNT1_REG_ADDR, 787b9e34d14SMarek Vasut CC63_TRNG_SAMPLE_CNT1_REG_SAMPLE_COUNT); 788b9e34d14SMarek Vasut cnt = mmio_read_32(RCAR_CC63_BASE + CC63_TRNG_SAMPLE_CNT1_REG_ADDR); 789b9e34d14SMarek Vasut } while (cnt != CC63_TRNG_SAMPLE_CNT1_REG_SAMPLE_COUNT); 790b9e34d14SMarek Vasut 791b9e34d14SMarek Vasut mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_CONFIG_REG_ADDR, 792b9e34d14SMarek Vasut CC63_TRNG_CONFIG_REG_ROSC_MAX_LENGTH); 793b9e34d14SMarek Vasut mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_DEBUG_CONTROL_REG_ADDR, 794b9e34d14SMarek Vasut CC63_TRNG_DEBUG_CONTROL_REG_80090B); 795b9e34d14SMarek Vasut mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SOURCE_ENABLE_REG_ADDR, 796b9e34d14SMarek Vasut CC63_TRNG_SOURCE_ENABLE_REG_SET); 797b9e34d14SMarek Vasut 798b9e34d14SMarek Vasut do { 799b9e34d14SMarek Vasut isr = mmio_read_32(RCAR_CC63_BASE + CC63_TRNG_ISR_REG_ADDR); 800b9e34d14SMarek Vasut if ((isr & CC63_TRNG_ISR_REG_AUTOCORR_ERR) != 0U) { 801b9e34d14SMarek Vasut panic(); 802b9e34d14SMarek Vasut } 803b9e34d14SMarek Vasut } while ((isr & CC63_TRNG_ISR_REG_EHR_VALID) == 0U); 804b9e34d14SMarek Vasut 805b9e34d14SMarek Vasut mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_ICR_REG_ADDR, UINT32_MAX); 806b9e34d14SMarek Vasut seed = mmio_read_64(RCAR_CC63_BASE + CC63_TRNG_EHR_DATA_ADDR_0_REG_ADDR); 807b9e34d14SMarek Vasut mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SOURCE_ENABLE_REG_ADDR, 808b9e34d14SMarek Vasut CC63_TRNG_SOURCE_ENABLE_REG_CLR); 809b9e34d14SMarek Vasut 810b9e34d14SMarek Vasut node = ret = fdt_add_subnode(fdt, 0, "chosen"); 811b9e34d14SMarek Vasut if (ret < 0) { 812b9e34d14SMarek Vasut goto err; 813b9e34d14SMarek Vasut } 814b9e34d14SMarek Vasut 815b9e34d14SMarek Vasut ret = fdt_setprop_u64(fdt, node, "kaslr-seed", seed); 816b9e34d14SMarek Vasut if (ret < 0) { 817b9e34d14SMarek Vasut goto err; 818b9e34d14SMarek Vasut } 819b9e34d14SMarek Vasut 820b9e34d14SMarek Vasut return; 821b9e34d14SMarek Vasut err: 822b9e34d14SMarek Vasut NOTICE("BL2: Cannot add KASLR seed to FDT (ret=%i)\n", ret); 823b9e34d14SMarek Vasut panic(); 824b9e34d14SMarek Vasut } 825b9e34d14SMarek Vasut 826e624e98dSMarek Vasut static void bl2_add_dram_entry(uint64_t start, uint64_t size) 82785185151SMarek Vasut { 8281d85c4bdSMarek Vasut char nodename[32] = { 0 }; 8291d85c4bdSMarek Vasut uint64_t fdtsize; 830e624e98dSMarek Vasut int ret, node; 831e624e98dSMarek Vasut 832e624e98dSMarek Vasut fdtsize = cpu_to_fdt64(size); 833e624e98dSMarek Vasut 834e624e98dSMarek Vasut snprintf(nodename, sizeof(nodename), "memory@"); 835e624e98dSMarek Vasut unsigned_num_print(start, 16, nodename + strlen(nodename)); 836e624e98dSMarek Vasut node = ret = fdt_add_subnode(fdt, 0, nodename); 837e624e98dSMarek Vasut if (ret < 0) { 838e624e98dSMarek Vasut goto err; 839e624e98dSMarek Vasut } 840e624e98dSMarek Vasut 841e624e98dSMarek Vasut ret = fdt_setprop_string(fdt, node, "device_type", "memory"); 842e624e98dSMarek Vasut if (ret < 0) { 843e624e98dSMarek Vasut goto err; 844e624e98dSMarek Vasut } 845e624e98dSMarek Vasut 846e624e98dSMarek Vasut ret = fdt_setprop_u64(fdt, node, "reg", start); 847e624e98dSMarek Vasut if (ret < 0) { 848e624e98dSMarek Vasut goto err; 849e624e98dSMarek Vasut } 850e624e98dSMarek Vasut 851e624e98dSMarek Vasut ret = fdt_appendprop(fdt, node, "reg", &fdtsize, 852e624e98dSMarek Vasut sizeof(fdtsize)); 853e624e98dSMarek Vasut if (ret < 0) { 854e624e98dSMarek Vasut goto err; 855e624e98dSMarek Vasut } 856e624e98dSMarek Vasut 857e624e98dSMarek Vasut return; 858e624e98dSMarek Vasut err: 8594ce3e99aSScott Branden NOTICE("BL2: Cannot add memory node [%" PRIx64 " - %" PRIx64 "] to FDT (ret=%i)\n", 860e624e98dSMarek Vasut start, start + size - 1, ret); 861e624e98dSMarek Vasut panic(); 862e624e98dSMarek Vasut } 863e624e98dSMarek Vasut 864e624e98dSMarek Vasut static void bl2_advertise_dram_entries(uint64_t dram_config[8]) 865e624e98dSMarek Vasut { 86621924f24SMarek Vasut uint64_t start, size, size32; 867e624e98dSMarek Vasut int chan; 86885185151SMarek Vasut 86985185151SMarek Vasut for (chan = 0; chan < 4; chan++) { 87085185151SMarek Vasut start = dram_config[2 * chan]; 87185185151SMarek Vasut size = dram_config[2 * chan + 1]; 87285185151SMarek Vasut if (!size) 87385185151SMarek Vasut continue; 87485185151SMarek Vasut 8754ce3e99aSScott Branden NOTICE("BL2: CH%d: %" PRIx64 " - %" PRIx64 ", %" PRId64 " %siB\n", 8765b4f022bSMarek Vasut chan, start, start + size - 1, 8775b4f022bSMarek Vasut (size >> 30) ? : size >> 20, 8785b4f022bSMarek Vasut (size >> 30) ? "G" : "M"); 87985185151SMarek Vasut } 8801d85c4bdSMarek Vasut 8811d85c4bdSMarek Vasut /* 8821d85c4bdSMarek Vasut * We add the DT nodes in reverse order here. The fdt_add_subnode() 8831d85c4bdSMarek Vasut * adds the DT node before the first existing DT node, so we have 8841d85c4bdSMarek Vasut * to add them in reverse order to get nodes sorted by address in 8851d85c4bdSMarek Vasut * the resulting DT. 8861d85c4bdSMarek Vasut */ 8871d85c4bdSMarek Vasut for (chan = 3; chan >= 0; chan--) { 8881d85c4bdSMarek Vasut start = dram_config[2 * chan]; 8891d85c4bdSMarek Vasut size = dram_config[2 * chan + 1]; 8901d85c4bdSMarek Vasut if (!size) 8911d85c4bdSMarek Vasut continue; 8921d85c4bdSMarek Vasut 8931d85c4bdSMarek Vasut /* 8941d85c4bdSMarek Vasut * Channel 0 is mapped in 32bit space and the first 89521924f24SMarek Vasut * 128 MiB are reserved and the maximum size is 2GiB. 8961d85c4bdSMarek Vasut */ 8971d85c4bdSMarek Vasut if (chan == 0) { 89821924f24SMarek Vasut /* Limit the 32bit entry to 2 GiB - 128 MiB */ 89921924f24SMarek Vasut size32 = size - 0x8000000U; 90021924f24SMarek Vasut if (size32 >= 0x78000000U) { 90121924f24SMarek Vasut size32 = 0x78000000U; 90221924f24SMarek Vasut } 90321924f24SMarek Vasut 90421924f24SMarek Vasut /* Emit 32bit entry, up to 2 GiB - 128 MiB long. */ 90521924f24SMarek Vasut bl2_add_dram_entry(0x48000000, size32); 90621924f24SMarek Vasut 90721924f24SMarek Vasut /* 90821924f24SMarek Vasut * If channel 0 is less than 2 GiB long, the 90921924f24SMarek Vasut * entire memory fits into the 32bit space entry, 91021924f24SMarek Vasut * so move on to the next channel. 91121924f24SMarek Vasut */ 91221924f24SMarek Vasut if (size <= 0x80000000U) { 91321924f24SMarek Vasut continue; 91421924f24SMarek Vasut } 91521924f24SMarek Vasut 91621924f24SMarek Vasut /* 91721924f24SMarek Vasut * If channel 0 is more than 2 GiB long, emit 91821924f24SMarek Vasut * another entry which covers the rest of the 91921924f24SMarek Vasut * memory in channel 0, in the 64bit space. 92021924f24SMarek Vasut * 92121924f24SMarek Vasut * Start of this new entry is at 2 GiB offset 92221924f24SMarek Vasut * from the beginning of the 64bit channel 0 92321924f24SMarek Vasut * address, size is 2 GiB shorter than total 92421924f24SMarek Vasut * size of the channel. 92521924f24SMarek Vasut */ 92621924f24SMarek Vasut start += 0x80000000U; 92721924f24SMarek Vasut size -= 0x80000000U; 9281d85c4bdSMarek Vasut } 9291d85c4bdSMarek Vasut 930e624e98dSMarek Vasut bl2_add_dram_entry(start, size); 9311d85c4bdSMarek Vasut } 93285185151SMarek Vasut } 93385185151SMarek Vasut 9347bf24ae3SMarek Vasut static void bl2_advertise_dram_size(uint32_t product) 935358ed930SMarek Vasut { 93685185151SMarek Vasut uint64_t dram_config[8] = { 93785185151SMarek Vasut [0] = 0x400000000ULL, 93885185151SMarek Vasut [2] = 0x500000000ULL, 93985185151SMarek Vasut [4] = 0x600000000ULL, 94085185151SMarek Vasut [6] = 0x700000000ULL, 94185185151SMarek Vasut }; 94242ffd279SToshiyuki Ogasahara uint32_t cut = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK; 94385185151SMarek Vasut 944e1eddfeaSMarek Vasut switch (product) { 945df51d8feSMarek Vasut case PRR_PRODUCT_H3: 946358ed930SMarek Vasut #if (RCAR_DRAM_LPDDR4_MEMCONF == 0) 947358ed930SMarek Vasut /* 4GB(1GBx4) */ 94885185151SMarek Vasut dram_config[1] = 0x40000000ULL; 94985185151SMarek Vasut dram_config[3] = 0x40000000ULL; 95085185151SMarek Vasut dram_config[5] = 0x40000000ULL; 95185185151SMarek Vasut dram_config[7] = 0x40000000ULL; 952358ed930SMarek Vasut #elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && \ 953358ed930SMarek Vasut (RCAR_DRAM_CHANNEL == 5) && \ 954358ed930SMarek Vasut (RCAR_DRAM_SPLIT == 2) 955358ed930SMarek Vasut /* 4GB(2GBx2 2ch split) */ 95685185151SMarek Vasut dram_config[1] = 0x80000000ULL; 95785185151SMarek Vasut dram_config[3] = 0x80000000ULL; 958358ed930SMarek Vasut #elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && (RCAR_DRAM_CHANNEL == 15) 959358ed930SMarek Vasut /* 8GB(2GBx4: default) */ 96085185151SMarek Vasut dram_config[1] = 0x80000000ULL; 96185185151SMarek Vasut dram_config[3] = 0x80000000ULL; 96285185151SMarek Vasut dram_config[5] = 0x80000000ULL; 96385185151SMarek Vasut dram_config[7] = 0x80000000ULL; 964358ed930SMarek Vasut #endif /* RCAR_DRAM_LPDDR4_MEMCONF == 0 */ 965e1eddfeaSMarek Vasut break; 966358ed930SMarek Vasut 967df51d8feSMarek Vasut case PRR_PRODUCT_M3: 96842ffd279SToshiyuki Ogasahara if (cut < PRR_PRODUCT_30) { 9695a21f313SMarek Vasut #if (RCAR_GEN3_ULCB == 1) 9705a21f313SMarek Vasut /* 2GB(1GBx2 2ch split) */ 9715a21f313SMarek Vasut dram_config[1] = 0x40000000ULL; 9725a21f313SMarek Vasut dram_config[5] = 0x40000000ULL; 9735a21f313SMarek Vasut #else 974e1eddfeaSMarek Vasut /* 4GB(2GBx2 2ch split) */ 97585185151SMarek Vasut dram_config[1] = 0x80000000ULL; 97685185151SMarek Vasut dram_config[5] = 0x80000000ULL; 9775a21f313SMarek Vasut #endif 97842ffd279SToshiyuki Ogasahara } else { 97942ffd279SToshiyuki Ogasahara /* 8GB(2GBx4 2ch split) */ 98042ffd279SToshiyuki Ogasahara dram_config[1] = 0x100000000ULL; 98142ffd279SToshiyuki Ogasahara dram_config[5] = 0x100000000ULL; 98242ffd279SToshiyuki Ogasahara } 983e1eddfeaSMarek Vasut break; 984e1eddfeaSMarek Vasut 985df51d8feSMarek Vasut case PRR_PRODUCT_M3N: 986f95d5512SToshiyuki Ogasahara #if (RCAR_DRAM_LPDDR4_MEMCONF == 2) 987f95d5512SToshiyuki Ogasahara /* 4GB(4GBx1) */ 988f95d5512SToshiyuki Ogasahara dram_config[1] = 0x100000000ULL; 989f95d5512SToshiyuki Ogasahara #elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) 990e1eddfeaSMarek Vasut /* 2GB(1GBx2) */ 99185185151SMarek Vasut dram_config[1] = 0x80000000ULL; 992f95d5512SToshiyuki Ogasahara #endif 993e1eddfeaSMarek Vasut break; 994e1eddfeaSMarek Vasut 995df51d8feSMarek Vasut case PRR_PRODUCT_V3M: 996b709fe9cSValentine Barshak /* 1GB(512MBx2) */ 997b709fe9cSValentine Barshak dram_config[1] = 0x40000000ULL; 998b709fe9cSValentine Barshak break; 999b709fe9cSValentine Barshak 1000df51d8feSMarek Vasut case PRR_PRODUCT_E3: 1001358ed930SMarek Vasut #if (RCAR_DRAM_DDR3L_MEMCONF == 0) 1002358ed930SMarek Vasut /* 1GB(512MBx2) */ 100385185151SMarek Vasut dram_config[1] = 0x40000000ULL; 1004358ed930SMarek Vasut #elif (RCAR_DRAM_DDR3L_MEMCONF == 1) 1005358ed930SMarek Vasut /* 2GB(512MBx4) */ 100685185151SMarek Vasut dram_config[1] = 0x80000000ULL; 10073b507aabSMarek Vasut #elif (RCAR_DRAM_DDR3L_MEMCONF == 2) 10083b507aabSMarek Vasut /* 4GB(1GBx4) */ 100985185151SMarek Vasut dram_config[1] = 0x100000000ULL; 1010358ed930SMarek Vasut #endif /* RCAR_DRAM_DDR3L_MEMCONF == 0 */ 1011e1eddfeaSMarek Vasut break; 1012bfbf5df4SMarek Vasut 1013df51d8feSMarek Vasut case PRR_PRODUCT_D3: 1014bfbf5df4SMarek Vasut /* 512MB */ 1015bfbf5df4SMarek Vasut dram_config[1] = 0x20000000ULL; 1016bfbf5df4SMarek Vasut break; 1017358ed930SMarek Vasut } 101885185151SMarek Vasut 101985185151SMarek Vasut bl2_advertise_dram_entries(dram_config); 1020358ed930SMarek Vasut } 1021358ed930SMarek Vasut 10227e532c4bSJorge Ramirez-Ortiz void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, 10237e532c4bSJorge Ramirez-Ortiz u_register_t arg3, u_register_t arg4) 10247e532c4bSJorge Ramirez-Ortiz { 10257e532c4bSJorge Ramirez-Ortiz uint32_t reg, midr, lcs, boot_dev, boot_cpu, sscg, type, rev; 10267bf24ae3SMarek Vasut uint32_t product, product_cut, major, minor; 10277e532c4bSJorge Ramirez-Ortiz int32_t ret; 10287e532c4bSJorge Ramirez-Ortiz const char *str; 10297e532c4bSJorge Ramirez-Ortiz const char *unknown = "unknown"; 10307e532c4bSJorge Ramirez-Ortiz const char *cpu_ca57 = "CA57"; 10317e532c4bSJorge Ramirez-Ortiz const char *cpu_ca53 = "CA53"; 10327e532c4bSJorge Ramirez-Ortiz const char *product_m3n = "M3N"; 10337e532c4bSJorge Ramirez-Ortiz const char *product_h3 = "H3"; 10347e532c4bSJorge Ramirez-Ortiz const char *product_m3 = "M3"; 10357e532c4bSJorge Ramirez-Ortiz const char *product_e3 = "E3"; 1036bfbf5df4SMarek Vasut const char *product_d3 = "D3"; 1037b709fe9cSValentine Barshak const char *product_v3m = "V3M"; 10387e532c4bSJorge Ramirez-Ortiz const char *lcs_secure = "SE"; 10397e532c4bSJorge Ramirez-Ortiz const char *lcs_cm = "CM"; 10407e532c4bSJorge Ramirez-Ortiz const char *lcs_dm = "DM"; 10417e532c4bSJorge Ramirez-Ortiz const char *lcs_sd = "SD"; 10427e532c4bSJorge Ramirez-Ortiz const char *lcs_fa = "FA"; 10437e532c4bSJorge Ramirez-Ortiz const char *sscg_off = "PLL1 nonSSCG Clock select"; 10447e532c4bSJorge Ramirez-Ortiz const char *sscg_on = "PLL1 SSCG Clock select"; 10457e532c4bSJorge Ramirez-Ortiz const char *boot_hyper80 = "HyperFlash(80MHz)"; 10467e532c4bSJorge Ramirez-Ortiz const char *boot_qspi40 = "QSPI Flash(40MHz)"; 10477e532c4bSJorge Ramirez-Ortiz const char *boot_qspi80 = "QSPI Flash(80MHz)"; 10487e532c4bSJorge Ramirez-Ortiz const char *boot_emmc25x1 = "eMMC(25MHz x1)"; 10497e532c4bSJorge Ramirez-Ortiz const char *boot_emmc50x8 = "eMMC(50MHz x8)"; 1050bfbf5df4SMarek Vasut #if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) 10517e532c4bSJorge Ramirez-Ortiz const char *boot_hyper160 = "HyperFlash(150MHz)"; 10527e532c4bSJorge Ramirez-Ortiz #else 10537e532c4bSJorge Ramirez-Ortiz const char *boot_hyper160 = "HyperFlash(160MHz)"; 10547e532c4bSJorge Ramirez-Ortiz #endif 10557e532c4bSJorge Ramirez-Ortiz 105647141b73SMarek Vasut bl2_init_generic_timer(); 105747141b73SMarek Vasut 10587e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_MODEMR); 10597e532c4bSJorge Ramirez-Ortiz boot_dev = reg & MODEMR_BOOT_DEV_MASK; 10607e532c4bSJorge Ramirez-Ortiz boot_cpu = reg & MODEMR_BOOT_CPU_MASK; 10617e532c4bSJorge Ramirez-Ortiz 10627e532c4bSJorge Ramirez-Ortiz bl2_cpg_init(); 10637e532c4bSJorge Ramirez-Ortiz 10647e532c4bSJorge Ramirez-Ortiz if (boot_cpu == MODEMR_BOOT_CPU_CA57 || 10657e532c4bSJorge Ramirez-Ortiz boot_cpu == MODEMR_BOOT_CPU_CA53) { 10667e532c4bSJorge Ramirez-Ortiz rcar_pfc_init(); 1067018358fcSMarek Vasut rcar_console_boot_init(); 10687e532c4bSJorge Ramirez-Ortiz } 10697e532c4bSJorge Ramirez-Ortiz 10707e532c4bSJorge Ramirez-Ortiz plat_rcar_gic_driver_init(); 10717e532c4bSJorge Ramirez-Ortiz plat_rcar_gic_init(); 10727e532c4bSJorge Ramirez-Ortiz rcar_swdt_init(); 10737e532c4bSJorge Ramirez-Ortiz 10747e532c4bSJorge Ramirez-Ortiz /* FIQ interrupts are taken to EL3 */ 10757e532c4bSJorge Ramirez-Ortiz write_scr_el3(read_scr_el3() | SCR_FIQ_BIT); 10767e532c4bSJorge Ramirez-Ortiz 10777e532c4bSJorge Ramirez-Ortiz write_daifclr(DAIF_FIQ_BIT); 10787e532c4bSJorge Ramirez-Ortiz 10797e532c4bSJorge Ramirez-Ortiz reg = read_midr(); 10807e532c4bSJorge Ramirez-Ortiz midr = reg & (MIDR_PN_MASK << MIDR_PN_SHIFT); 10817e532c4bSJorge Ramirez-Ortiz switch (midr) { 10827e532c4bSJorge Ramirez-Ortiz case MIDR_CA57: 10837e532c4bSJorge Ramirez-Ortiz str = cpu_ca57; 10847e532c4bSJorge Ramirez-Ortiz break; 10857e532c4bSJorge Ramirez-Ortiz case MIDR_CA53: 10867e532c4bSJorge Ramirez-Ortiz str = cpu_ca53; 10877e532c4bSJorge Ramirez-Ortiz break; 10887e532c4bSJorge Ramirez-Ortiz default: 10897e532c4bSJorge Ramirez-Ortiz str = unknown; 10907e532c4bSJorge Ramirez-Ortiz break; 10917e532c4bSJorge Ramirez-Ortiz } 10927e532c4bSJorge Ramirez-Ortiz 10937e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: R-Car Gen3 Initial Program Loader(%s) Rev.%s\n", str, 10947e532c4bSJorge Ramirez-Ortiz version_of_renesas); 10957e532c4bSJorge Ramirez-Ortiz 10967e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_PRR); 1097df51d8feSMarek Vasut product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 1098df51d8feSMarek Vasut product = reg & PRR_PRODUCT_MASK; 10997e532c4bSJorge Ramirez-Ortiz 11007e532c4bSJorge Ramirez-Ortiz switch (product) { 1101df51d8feSMarek Vasut case PRR_PRODUCT_H3: 11027e532c4bSJorge Ramirez-Ortiz str = product_h3; 11037e532c4bSJorge Ramirez-Ortiz break; 1104df51d8feSMarek Vasut case PRR_PRODUCT_M3: 11057e532c4bSJorge Ramirez-Ortiz str = product_m3; 11067e532c4bSJorge Ramirez-Ortiz break; 1107df51d8feSMarek Vasut case PRR_PRODUCT_M3N: 11087e532c4bSJorge Ramirez-Ortiz str = product_m3n; 11097e532c4bSJorge Ramirez-Ortiz break; 1110df51d8feSMarek Vasut case PRR_PRODUCT_V3M: 1111b709fe9cSValentine Barshak str = product_v3m; 1112b709fe9cSValentine Barshak break; 1113df51d8feSMarek Vasut case PRR_PRODUCT_E3: 11147e532c4bSJorge Ramirez-Ortiz str = product_e3; 11157e532c4bSJorge Ramirez-Ortiz break; 1116df51d8feSMarek Vasut case PRR_PRODUCT_D3: 1117bfbf5df4SMarek Vasut str = product_d3; 1118bfbf5df4SMarek Vasut break; 11197e532c4bSJorge Ramirez-Ortiz default: 11207e532c4bSJorge Ramirez-Ortiz str = unknown; 11217e532c4bSJorge Ramirez-Ortiz break; 11227e532c4bSJorge Ramirez-Ortiz } 11237e532c4bSJorge Ramirez-Ortiz 1124df51d8feSMarek Vasut if ((PRR_PRODUCT_M3 == product) && 1125df51d8feSMarek Vasut (PRR_PRODUCT_20 == (reg & RCAR_MAJOR_MASK))) { 1126df51d8feSMarek Vasut if (RCAR_M3_CUT_VER11 == (reg & PRR_CUT_MASK)) { 1127845d8fbbSMarek Vasut /* M3 Ver.1.1 or Ver.1.2 */ 1128845d8fbbSMarek Vasut NOTICE("BL2: PRR is R-Car %s Ver.1.1 / Ver.1.2\n", 1129845d8fbbSMarek Vasut str); 1130845d8fbbSMarek Vasut } else { 1131845d8fbbSMarek Vasut NOTICE("BL2: PRR is R-Car %s Ver.1.%d\n", 1132845d8fbbSMarek Vasut str, 1133845d8fbbSMarek Vasut (reg & RCAR_MINOR_MASK) + RCAR_M3_MINOR_OFFSET); 1134845d8fbbSMarek Vasut } 1135c3d192b8SToshiyuki Ogasahara } else if (product == PRR_PRODUCT_D3) { 1136c3d192b8SToshiyuki Ogasahara if (RCAR_D3_CUT_VER10 == (reg & PRR_CUT_MASK)) { 1137c3d192b8SToshiyuki Ogasahara NOTICE("BL2: PRR is R-Car %s Ver.1.0\n", str); 1138c3d192b8SToshiyuki Ogasahara } else if (RCAR_D3_CUT_VER11 == (reg & PRR_CUT_MASK)) { 1139c3d192b8SToshiyuki Ogasahara NOTICE("BL2: PRR is R-Car %s Ver.1.1\n", str); 1140c3d192b8SToshiyuki Ogasahara } else { 1141c3d192b8SToshiyuki Ogasahara NOTICE("BL2: PRR is R-Car %s Ver.X.X\n", str); 1142c3d192b8SToshiyuki Ogasahara } 11437e532c4bSJorge Ramirez-Ortiz } else { 11447e532c4bSJorge Ramirez-Ortiz major = (reg & RCAR_MAJOR_MASK) >> RCAR_MAJOR_SHIFT; 11457e532c4bSJorge Ramirez-Ortiz major = major + RCAR_MAJOR_OFFSET; 11467e532c4bSJorge Ramirez-Ortiz minor = reg & RCAR_MINOR_MASK; 11477e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: PRR is R-Car %s Ver.%d.%d\n", str, major, minor); 11487e532c4bSJorge Ramirez-Ortiz } 11497e532c4bSJorge Ramirez-Ortiz 115014f0a081SToshiyuki Ogasahara if (PRR_PRODUCT_E3 == product || PRR_PRODUCT_D3 == product) { 11517e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_MODEMR); 11527e532c4bSJorge Ramirez-Ortiz sscg = reg & RCAR_SSCG_MASK; 11537e532c4bSJorge Ramirez-Ortiz str = sscg == RCAR_SSCG_ENABLE ? sscg_on : sscg_off; 11547e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: %s\n", str); 11557e532c4bSJorge Ramirez-Ortiz } 11567e532c4bSJorge Ramirez-Ortiz 11577e532c4bSJorge Ramirez-Ortiz rcar_get_board_type(&type, &rev); 11587e532c4bSJorge Ramirez-Ortiz 11597e532c4bSJorge Ramirez-Ortiz switch (type) { 11607e532c4bSJorge Ramirez-Ortiz case BOARD_SALVATOR_X: 11617e532c4bSJorge Ramirez-Ortiz case BOARD_KRIEK: 11627e532c4bSJorge Ramirez-Ortiz case BOARD_STARTER_KIT: 11637e532c4bSJorge Ramirez-Ortiz case BOARD_SALVATOR_XS: 11647e532c4bSJorge Ramirez-Ortiz case BOARD_EBISU: 11657e532c4bSJorge Ramirez-Ortiz case BOARD_STARTER_KIT_PRE: 11667e532c4bSJorge Ramirez-Ortiz case BOARD_EBISU_4D: 1167bfbf5df4SMarek Vasut case BOARD_DRAAK: 1168b709fe9cSValentine Barshak case BOARD_EAGLE: 11697e532c4bSJorge Ramirez-Ortiz break; 11707e532c4bSJorge Ramirez-Ortiz default: 11717e532c4bSJorge Ramirez-Ortiz type = BOARD_UNKNOWN; 11727e532c4bSJorge Ramirez-Ortiz break; 11737e532c4bSJorge Ramirez-Ortiz } 11747e532c4bSJorge Ramirez-Ortiz 11757e532c4bSJorge Ramirez-Ortiz if (type == BOARD_UNKNOWN || rev == BOARD_REV_UNKNOWN) 11767e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Board is %s Rev.---\n", GET_BOARD_NAME(type)); 11777e532c4bSJorge Ramirez-Ortiz else { 11787e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Board is %s Rev.%d.%d\n", 11797e532c4bSJorge Ramirez-Ortiz GET_BOARD_NAME(type), 11807e532c4bSJorge Ramirez-Ortiz GET_BOARD_MAJOR(rev), GET_BOARD_MINOR(rev)); 11817e532c4bSJorge Ramirez-Ortiz } 11827e532c4bSJorge Ramirez-Ortiz 11837e532c4bSJorge Ramirez-Ortiz #if RCAR_LSI != RCAR_AUTO 11847e532c4bSJorge Ramirez-Ortiz if (product != TARGET_PRODUCT) { 11857e532c4bSJorge Ramirez-Ortiz ERROR("BL2: IPL was been built for the %s.\n", TARGET_NAME); 11867e532c4bSJorge Ramirez-Ortiz ERROR("BL2: Please write the correct IPL to flash memory.\n"); 11877e532c4bSJorge Ramirez-Ortiz panic(); 11887e532c4bSJorge Ramirez-Ortiz } 11897e532c4bSJorge Ramirez-Ortiz #endif 11907e532c4bSJorge Ramirez-Ortiz rcar_avs_init(); 11917e532c4bSJorge Ramirez-Ortiz rcar_avs_setting(); 11927e532c4bSJorge Ramirez-Ortiz 11937e532c4bSJorge Ramirez-Ortiz switch (boot_dev) { 11947e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_HYPERFLASH160: 11957e532c4bSJorge Ramirez-Ortiz str = boot_hyper160; 11967e532c4bSJorge Ramirez-Ortiz break; 11977e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_HYPERFLASH80: 11987e532c4bSJorge Ramirez-Ortiz str = boot_hyper80; 11997e532c4bSJorge Ramirez-Ortiz break; 12007e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_QSPI_FLASH40: 12017e532c4bSJorge Ramirez-Ortiz str = boot_qspi40; 12027e532c4bSJorge Ramirez-Ortiz break; 12037e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_QSPI_FLASH80: 12047e532c4bSJorge Ramirez-Ortiz str = boot_qspi80; 12057e532c4bSJorge Ramirez-Ortiz break; 12067e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_EMMC_25X1: 1207bfbf5df4SMarek Vasut #if RCAR_LSI == RCAR_D3 1208bfbf5df4SMarek Vasut ERROR("BL2: Failed to Initialize. eMMC is not supported.\n"); 1209bfbf5df4SMarek Vasut panic(); 1210bfbf5df4SMarek Vasut #endif 12117e532c4bSJorge Ramirez-Ortiz str = boot_emmc25x1; 12127e532c4bSJorge Ramirez-Ortiz break; 12137e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_EMMC_50X8: 12147e532c4bSJorge Ramirez-Ortiz str = boot_emmc50x8; 12157e532c4bSJorge Ramirez-Ortiz break; 12167e532c4bSJorge Ramirez-Ortiz default: 12177e532c4bSJorge Ramirez-Ortiz str = unknown; 12187e532c4bSJorge Ramirez-Ortiz break; 12197e532c4bSJorge Ramirez-Ortiz } 12207e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Boot device is %s\n", str); 12217e532c4bSJorge Ramirez-Ortiz 12227e532c4bSJorge Ramirez-Ortiz rcar_avs_setting(); 12237e532c4bSJorge Ramirez-Ortiz reg = rcar_rom_get_lcs(&lcs); 12247e532c4bSJorge Ramirez-Ortiz if (reg) { 12257e532c4bSJorge Ramirez-Ortiz str = unknown; 12267e532c4bSJorge Ramirez-Ortiz goto lcm_state; 12277e532c4bSJorge Ramirez-Ortiz } 12287e532c4bSJorge Ramirez-Ortiz 12297e532c4bSJorge Ramirez-Ortiz switch (lcs) { 12307e532c4bSJorge Ramirez-Ortiz case LCS_CM: 12317e532c4bSJorge Ramirez-Ortiz str = lcs_cm; 12327e532c4bSJorge Ramirez-Ortiz break; 12337e532c4bSJorge Ramirez-Ortiz case LCS_DM: 12347e532c4bSJorge Ramirez-Ortiz str = lcs_dm; 12357e532c4bSJorge Ramirez-Ortiz break; 12367e532c4bSJorge Ramirez-Ortiz case LCS_SD: 12377e532c4bSJorge Ramirez-Ortiz str = lcs_sd; 12387e532c4bSJorge Ramirez-Ortiz break; 12397e532c4bSJorge Ramirez-Ortiz case LCS_SE: 12407e532c4bSJorge Ramirez-Ortiz str = lcs_secure; 12417e532c4bSJorge Ramirez-Ortiz break; 12427e532c4bSJorge Ramirez-Ortiz case LCS_FA: 12437e532c4bSJorge Ramirez-Ortiz str = lcs_fa; 12447e532c4bSJorge Ramirez-Ortiz break; 12457e532c4bSJorge Ramirez-Ortiz default: 12467e532c4bSJorge Ramirez-Ortiz str = unknown; 12477e532c4bSJorge Ramirez-Ortiz break; 12487e532c4bSJorge Ramirez-Ortiz } 12497e532c4bSJorge Ramirez-Ortiz 12507e532c4bSJorge Ramirez-Ortiz lcm_state: 12517e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: LCM state is %s\n", str); 12527e532c4bSJorge Ramirez-Ortiz 12537e532c4bSJorge Ramirez-Ortiz rcar_avs_end(); 12547e532c4bSJorge Ramirez-Ortiz is_ddr_backup_mode(); 12557e532c4bSJorge Ramirez-Ortiz 12567e532c4bSJorge Ramirez-Ortiz bl2_tzram_layout.total_base = BL31_BASE; 12577e532c4bSJorge Ramirez-Ortiz bl2_tzram_layout.total_size = BL31_LIMIT - BL31_BASE; 12587e532c4bSJorge Ramirez-Ortiz 12597e532c4bSJorge Ramirez-Ortiz if (boot_cpu == MODEMR_BOOT_CPU_CA57 || 12607e532c4bSJorge Ramirez-Ortiz boot_cpu == MODEMR_BOOT_CPU_CA53) { 12617e532c4bSJorge Ramirez-Ortiz ret = rcar_dram_init(); 12627e532c4bSJorge Ramirez-Ortiz if (ret) { 12637e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Failed to DRAM initialize (%d).\n", ret); 12647e532c4bSJorge Ramirez-Ortiz panic(); 12657e532c4bSJorge Ramirez-Ortiz } 12667e532c4bSJorge Ramirez-Ortiz rcar_qos_init(); 12677e532c4bSJorge Ramirez-Ortiz } 12687e532c4bSJorge Ramirez-Ortiz 12691d85c4bdSMarek Vasut /* Set up FDT */ 12701d85c4bdSMarek Vasut ret = fdt_create_empty_tree(fdt, sizeof(fdt_blob)); 12711d85c4bdSMarek Vasut if (ret) { 12721d85c4bdSMarek Vasut NOTICE("BL2: Cannot allocate FDT for U-Boot (ret=%i)\n", ret); 12731d85c4bdSMarek Vasut panic(); 12741d85c4bdSMarek Vasut } 12751d85c4bdSMarek Vasut 1276ac49c5fbSMarek Vasut /* Add platform compatible string */ 1277ac49c5fbSMarek Vasut bl2_populate_compatible_string(fdt); 1278ac49c5fbSMarek Vasut 127912c75c88SMarek Vasut /* Enable RPC if unlocked */ 128012c75c88SMarek Vasut bl2_add_rpc_node(); 128112c75c88SMarek Vasut 128210b7a4aeSMarek Vasut /* Print DRAM layout */ 128310b7a4aeSMarek Vasut bl2_advertise_dram_size(product); 128410b7a4aeSMarek Vasut 1285b9e34d14SMarek Vasut /* Add KASLR seed */ 1286b9e34d14SMarek Vasut bl2_add_kaslr_seed(); 1287b9e34d14SMarek Vasut 12887e532c4bSJorge Ramirez-Ortiz if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || 12897e532c4bSJorge Ramirez-Ortiz boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) { 12907e532c4bSJorge Ramirez-Ortiz if (rcar_emmc_init() != EMMC_SUCCESS) { 12917e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Failed to eMMC driver initialize.\n"); 12927e532c4bSJorge Ramirez-Ortiz panic(); 12937e532c4bSJorge Ramirez-Ortiz } 12947e532c4bSJorge Ramirez-Ortiz rcar_emmc_memcard_power(EMMC_POWER_ON); 12957e532c4bSJorge Ramirez-Ortiz if (rcar_emmc_mount() != EMMC_SUCCESS) { 12967e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Failed to eMMC mount operation.\n"); 12977e532c4bSJorge Ramirez-Ortiz panic(); 12987e532c4bSJorge Ramirez-Ortiz } 12997e532c4bSJorge Ramirez-Ortiz } else { 13007e532c4bSJorge Ramirez-Ortiz rcar_rpc_init(); 13017e532c4bSJorge Ramirez-Ortiz rcar_dma_init(); 13027e532c4bSJorge Ramirez-Ortiz } 13037e532c4bSJorge Ramirez-Ortiz 13047e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RST_WDTRSTCR); 13057e532c4bSJorge Ramirez-Ortiz reg &= ~WDTRSTCR_RWDT_RSTMSK; 13067e532c4bSJorge Ramirez-Ortiz reg |= WDTRSTCR_PASSWORD; 13077e532c4bSJorge Ramirez-Ortiz mmio_write_32(RST_WDTRSTCR, reg); 13087e532c4bSJorge Ramirez-Ortiz 13097e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_CPGWPR, CPGWPR_PASSWORD); 13107e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_CPGWPCR, CPGWPCR_PASSWORD); 13117e532c4bSJorge Ramirez-Ortiz 13127e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_PRR); 13137e532c4bSJorge Ramirez-Ortiz if ((reg & RCAR_CPU_MASK_CA57) == RCAR_CPU_HAVE_CA57) 13147e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_CA57DBGRCR, 13157e532c4bSJorge Ramirez-Ortiz DBGCPUPREN | mmio_read_32(CPG_CA57DBGRCR)); 13167e532c4bSJorge Ramirez-Ortiz 13177e532c4bSJorge Ramirez-Ortiz if ((reg & RCAR_CPU_MASK_CA53) == RCAR_CPU_HAVE_CA53) 13187e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_CA53DBGRCR, 13197e532c4bSJorge Ramirez-Ortiz DBGCPUPREN | mmio_read_32(CPG_CA53DBGRCR)); 13207e532c4bSJorge Ramirez-Ortiz 1321df51d8feSMarek Vasut if (product_cut == PRR_PRODUCT_H3_CUT10) { 13227e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(CPG_PLL2CR); 13237e532c4bSJorge Ramirez-Ortiz reg &= ~((uint32_t) 1 << 5); 13247e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_PLL2CR, reg); 13257e532c4bSJorge Ramirez-Ortiz 13267e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(CPG_PLL4CR); 13277e532c4bSJorge Ramirez-Ortiz reg &= ~((uint32_t) 1 << 5); 13287e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_PLL4CR, reg); 13297e532c4bSJorge Ramirez-Ortiz 13307e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(CPG_PLL0CR); 13317e532c4bSJorge Ramirez-Ortiz reg &= ~((uint32_t) 1 << 12); 13327e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_PLL0CR, reg); 13337e532c4bSJorge Ramirez-Ortiz } 1334a6de3db7SMarek Vasut 1335f945498fSDetlev Casanova bl2_create_fcnl_reserved_memory(); 13367e532c4bSJorge Ramirez-Ortiz 13371d85c4bdSMarek Vasut fdt_pack(fdt); 13381d85c4bdSMarek Vasut NOTICE("BL2: FDT at %p\n", fdt); 13391d85c4bdSMarek Vasut 13407e532c4bSJorge Ramirez-Ortiz if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || 13417e532c4bSJorge Ramirez-Ortiz boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) 13427e532c4bSJorge Ramirez-Ortiz rcar_io_emmc_setup(); 13437e532c4bSJorge Ramirez-Ortiz else 13447e532c4bSJorge Ramirez-Ortiz rcar_io_setup(); 13457e532c4bSJorge Ramirez-Ortiz } 13467e532c4bSJorge Ramirez-Ortiz 13477e532c4bSJorge Ramirez-Ortiz void bl2_el3_plat_arch_setup(void) 13487e532c4bSJorge Ramirez-Ortiz { 13497e532c4bSJorge Ramirez-Ortiz rcar_configure_mmu_el3(BL2_BASE, 1350bc5fabd8SMarek Vasut BL2_END - BL2_BASE, 13517e532c4bSJorge Ramirez-Ortiz BL2_RO_BASE, BL2_RO_LIMIT 13527e532c4bSJorge Ramirez-Ortiz #if USE_COHERENT_MEM 13537e532c4bSJorge Ramirez-Ortiz , BL2_COHERENT_RAM_BASE, BL2_COHERENT_RAM_LIMIT 13547e532c4bSJorge Ramirez-Ortiz #endif 13557e532c4bSJorge Ramirez-Ortiz ); 13567e532c4bSJorge Ramirez-Ortiz } 13577e532c4bSJorge Ramirez-Ortiz 1358e9afde1aSToshiyuki Ogasahara void bl2_el3_plat_prepare_exit(void) 1359e9afde1aSToshiyuki Ogasahara { 1360e9afde1aSToshiyuki Ogasahara bl2_ram_security_setting_finish(); 1361e9afde1aSToshiyuki Ogasahara } 1362e9afde1aSToshiyuki Ogasahara 13637e532c4bSJorge Ramirez-Ortiz void bl2_platform_setup(void) 13647e532c4bSJorge Ramirez-Ortiz { 13657e532c4bSJorge Ramirez-Ortiz 13667e532c4bSJorge Ramirez-Ortiz } 136747141b73SMarek Vasut 136847141b73SMarek Vasut static void bl2_init_generic_timer(void) 136947141b73SMarek Vasut { 1370b709fe9cSValentine Barshak /* FIXME: V3M 16.666 MHz ? */ 1371bfbf5df4SMarek Vasut #if RCAR_LSI == RCAR_D3 1372bfbf5df4SMarek Vasut uint32_t reg_cntfid = EXTAL_DRAAK; 1373bfbf5df4SMarek Vasut #elif RCAR_LSI == RCAR_E3 137447141b73SMarek Vasut uint32_t reg_cntfid = EXTAL_EBISU; 137547141b73SMarek Vasut #else /* RCAR_LSI == RCAR_E3 */ 137647141b73SMarek Vasut uint32_t reg; 137747141b73SMarek Vasut uint32_t reg_cntfid; 137847141b73SMarek Vasut uint32_t modemr; 137947141b73SMarek Vasut uint32_t modemr_pll; 138047141b73SMarek Vasut uint32_t board_type; 138147141b73SMarek Vasut uint32_t board_rev; 138247141b73SMarek Vasut uint32_t pll_table[] = { 138347141b73SMarek Vasut EXTAL_MD14_MD13_TYPE_0, /* MD14/MD13 : 0b00 */ 138447141b73SMarek Vasut EXTAL_MD14_MD13_TYPE_1, /* MD14/MD13 : 0b01 */ 138547141b73SMarek Vasut EXTAL_MD14_MD13_TYPE_2, /* MD14/MD13 : 0b10 */ 138647141b73SMarek Vasut EXTAL_MD14_MD13_TYPE_3 /* MD14/MD13 : 0b11 */ 138747141b73SMarek Vasut }; 138847141b73SMarek Vasut 138947141b73SMarek Vasut modemr = mmio_read_32(RCAR_MODEMR); 139047141b73SMarek Vasut modemr_pll = (modemr & MODEMR_BOOT_PLL_MASK); 139147141b73SMarek Vasut 139247141b73SMarek Vasut /* Set frequency data in CNTFID0 */ 139347141b73SMarek Vasut reg_cntfid = pll_table[modemr_pll >> MODEMR_BOOT_PLL_SHIFT]; 1394df51d8feSMarek Vasut reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 139547141b73SMarek Vasut switch (modemr_pll) { 139647141b73SMarek Vasut case MD14_MD13_TYPE_0: 139747141b73SMarek Vasut rcar_get_board_type(&board_type, &board_rev); 139847141b73SMarek Vasut if (BOARD_SALVATOR_XS == board_type) { 139947141b73SMarek Vasut reg_cntfid = EXTAL_SALVATOR_XS; 140047141b73SMarek Vasut } 140147141b73SMarek Vasut break; 140247141b73SMarek Vasut case MD14_MD13_TYPE_3: 1403df51d8feSMarek Vasut if (PRR_PRODUCT_H3_CUT10 == reg) { 140447141b73SMarek Vasut reg_cntfid = reg_cntfid >> 1U; 140547141b73SMarek Vasut } 140647141b73SMarek Vasut break; 140747141b73SMarek Vasut default: 140847141b73SMarek Vasut /* none */ 140947141b73SMarek Vasut break; 141047141b73SMarek Vasut } 141147141b73SMarek Vasut #endif /* RCAR_LSI == RCAR_E3 */ 14121b491eeaSElyes Haouas /* Update memory mapped and register based frequency */ 141347141b73SMarek Vasut write_cntfrq_el0((u_register_t )reg_cntfid); 141447141b73SMarek Vasut mmio_write_32(ARM_SYS_CNTCTL_BASE + (uintptr_t)CNTFID_OFF, reg_cntfid); 141547141b73SMarek Vasut /* Enable counter */ 141647141b73SMarek Vasut mmio_setbits_32(RCAR_CNTC_BASE + (uintptr_t)CNTCR_OFF, 141747141b73SMarek Vasut (uint32_t)CNTCR_EN); 141847141b73SMarek Vasut } 1419