17e532c4bSJorge Ramirez-Ortiz /* 242ffd279SToshiyuki Ogasahara * Copyright (c) 2018-2021, 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 #if RCAR_BL2_DCACHE == 1 52ca661a00SMadhukar Pappireddy /* 53ca661a00SMadhukar Pappireddy * Following symbols are only used during plat_arch_setup() only 54ca661a00SMadhukar Pappireddy * when RCAR_BL2_DCACHE is enabled. 55ca661a00SMadhukar Pappireddy */ 56ca661a00SMadhukar Pappireddy static const uint64_t BL2_RO_BASE = BL_CODE_BASE; 57ca661a00SMadhukar Pappireddy static const uint64_t BL2_RO_LIMIT = BL_CODE_END; 587e532c4bSJorge Ramirez-Ortiz 597e532c4bSJorge Ramirez-Ortiz #if USE_COHERENT_MEM 60ca661a00SMadhukar Pappireddy static const uint64_t BL2_COHERENT_RAM_BASE = BL_COHERENT_RAM_BASE; 61ca661a00SMadhukar Pappireddy static const uint64_t BL2_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END; 62ca661a00SMadhukar Pappireddy #endif 63ca661a00SMadhukar Pappireddy 647e532c4bSJorge Ramirez-Ortiz #endif 657e532c4bSJorge Ramirez-Ortiz 667e532c4bSJorge Ramirez-Ortiz extern void plat_rcar_gic_driver_init(void); 677e532c4bSJorge Ramirez-Ortiz extern void plat_rcar_gic_init(void); 687e532c4bSJorge Ramirez-Ortiz extern void bl2_enter_bl31(const struct entry_point_info *bl_ep_info); 697e532c4bSJorge Ramirez-Ortiz extern void bl2_system_cpg_init(void); 707e532c4bSJorge Ramirez-Ortiz extern void bl2_secure_setting(void); 717e532c4bSJorge Ramirez-Ortiz extern void bl2_cpg_init(void); 727e532c4bSJorge Ramirez-Ortiz extern void rcar_io_emmc_setup(void); 737e532c4bSJorge Ramirez-Ortiz extern void rcar_io_setup(void); 747e532c4bSJorge Ramirez-Ortiz extern void rcar_swdt_release(void); 757e532c4bSJorge Ramirez-Ortiz extern void rcar_swdt_init(void); 767e532c4bSJorge Ramirez-Ortiz extern void rcar_rpc_init(void); 777e532c4bSJorge Ramirez-Ortiz extern void rcar_pfc_init(void); 787e532c4bSJorge Ramirez-Ortiz extern void rcar_dma_init(void); 797e532c4bSJorge Ramirez-Ortiz 8047141b73SMarek Vasut static void bl2_init_generic_timer(void); 8147141b73SMarek Vasut 827e532c4bSJorge Ramirez-Ortiz /* R-Car Gen3 product check */ 837e532c4bSJorge Ramirez-Ortiz #if (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) 84df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_H3 857e532c4bSJorge Ramirez-Ortiz #define TARGET_NAME "R-Car H3" 867e532c4bSJorge Ramirez-Ortiz #elif RCAR_LSI == RCAR_M3 87df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_M3 887e532c4bSJorge Ramirez-Ortiz #define TARGET_NAME "R-Car M3" 897e532c4bSJorge Ramirez-Ortiz #elif RCAR_LSI == RCAR_M3N 90df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_M3N 917e532c4bSJorge Ramirez-Ortiz #define TARGET_NAME "R-Car M3N" 92b709fe9cSValentine Barshak #elif RCAR_LSI == RCAR_V3M 93df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_V3M 94b709fe9cSValentine Barshak #define TARGET_NAME "R-Car V3M" 957e532c4bSJorge Ramirez-Ortiz #elif RCAR_LSI == RCAR_E3 96df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_E3 977e532c4bSJorge Ramirez-Ortiz #define TARGET_NAME "R-Car E3" 98bfbf5df4SMarek Vasut #elif RCAR_LSI == RCAR_D3 99df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_D3 100bfbf5df4SMarek Vasut #define TARGET_NAME "R-Car D3" 1010468aa39SMarek Vasut #elif RCAR_LSI == RCAR_AUTO 102b709fe9cSValentine Barshak #define TARGET_NAME "R-Car H3/M3/M3N/V3M" 1037e532c4bSJorge Ramirez-Ortiz #endif 1047e532c4bSJorge Ramirez-Ortiz 1057e532c4bSJorge Ramirez-Ortiz #if (RCAR_LSI == RCAR_E3) 1067e532c4bSJorge Ramirez-Ortiz #define GPIO_INDT (GPIO_INDT6) 1077e532c4bSJorge Ramirez-Ortiz #define GPIO_BKUP_TRG_SHIFT ((uint32_t)1U<<13U) 1087e532c4bSJorge Ramirez-Ortiz #else 1097e532c4bSJorge Ramirez-Ortiz #define GPIO_INDT (GPIO_INDT1) 1107e532c4bSJorge Ramirez-Ortiz #define GPIO_BKUP_TRG_SHIFT ((uint32_t)1U<<8U) 1117e532c4bSJorge Ramirez-Ortiz #endif 1127e532c4bSJorge Ramirez-Ortiz 1137e532c4bSJorge Ramirez-Ortiz CASSERT((PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t) + 0x100) 1147e532c4bSJorge Ramirez-Ortiz < (RCAR_SHARED_MEM_BASE + RCAR_SHARED_MEM_SIZE), 1157e532c4bSJorge Ramirez-Ortiz assert_bl31_params_do_not_fit_in_shared_memory); 1167e532c4bSJorge Ramirez-Ortiz 1177e532c4bSJorge Ramirez-Ortiz static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); 1187e532c4bSJorge Ramirez-Ortiz 1191d85c4bdSMarek Vasut /* FDT with DRAM configuration */ 1201d85c4bdSMarek Vasut uint64_t fdt_blob[PAGE_SIZE_4KB / sizeof(uint64_t)]; 1211d85c4bdSMarek Vasut static void *fdt = (void *)fdt_blob; 1221d85c4bdSMarek Vasut 1231d85c4bdSMarek Vasut static void unsigned_num_print(unsigned long long int unum, unsigned int radix, 1241d85c4bdSMarek Vasut char *string) 1251d85c4bdSMarek Vasut { 1261d85c4bdSMarek Vasut /* Just need enough space to store 64 bit decimal integer */ 1271d85c4bdSMarek Vasut char num_buf[20]; 1281d85c4bdSMarek Vasut int i = 0; 1291d85c4bdSMarek Vasut unsigned int rem; 1301d85c4bdSMarek Vasut 1311d85c4bdSMarek Vasut do { 1321d85c4bdSMarek Vasut rem = unum % radix; 1331d85c4bdSMarek Vasut if (rem < 0xa) 1341d85c4bdSMarek Vasut num_buf[i] = '0' + rem; 1351d85c4bdSMarek Vasut else 1361d85c4bdSMarek Vasut num_buf[i] = 'a' + (rem - 0xa); 1371d85c4bdSMarek Vasut i++; 1381d85c4bdSMarek Vasut unum /= radix; 1391d85c4bdSMarek Vasut } while (unum > 0U); 1401d85c4bdSMarek Vasut 1411d85c4bdSMarek Vasut while (--i >= 0) 1421d85c4bdSMarek Vasut *string++ = num_buf[i]; 143dcd08687SMarek Vasut *string = 0; 1441d85c4bdSMarek Vasut } 1451d85c4bdSMarek Vasut 1467e532c4bSJorge Ramirez-Ortiz #if (RCAR_LOSSY_ENABLE == 1) 1477e532c4bSJorge Ramirez-Ortiz typedef struct bl2_lossy_info { 1487e532c4bSJorge Ramirez-Ortiz uint32_t magic; 1497e532c4bSJorge Ramirez-Ortiz uint32_t a0; 1507e532c4bSJorge Ramirez-Ortiz uint32_t b0; 1517e532c4bSJorge Ramirez-Ortiz } bl2_lossy_info_t; 1527e532c4bSJorge Ramirez-Ortiz 153a6de3db7SMarek Vasut static void bl2_lossy_gen_fdt(uint32_t no, uint64_t start_addr, 154a6de3db7SMarek Vasut uint64_t end_addr, uint32_t format, 155a6de3db7SMarek Vasut uint32_t enable, int fcnlnode) 156a6de3db7SMarek Vasut { 157a6de3db7SMarek Vasut const uint64_t fcnlsize = cpu_to_fdt64(end_addr - start_addr); 158a6de3db7SMarek Vasut char nodename[40] = { 0 }; 159a6de3db7SMarek Vasut int ret, node; 160a6de3db7SMarek Vasut 161a6de3db7SMarek Vasut /* Ignore undefined addresses */ 162a6de3db7SMarek Vasut if (start_addr == 0 && end_addr == 0) 163a6de3db7SMarek Vasut return; 164a6de3db7SMarek Vasut 165a6de3db7SMarek Vasut snprintf(nodename, sizeof(nodename), "lossy-decompression@"); 166a6de3db7SMarek Vasut unsigned_num_print(start_addr, 16, nodename + strlen(nodename)); 167a6de3db7SMarek Vasut 168a6de3db7SMarek Vasut node = ret = fdt_add_subnode(fdt, fcnlnode, nodename); 169a6de3db7SMarek Vasut if (ret < 0) { 170a6de3db7SMarek Vasut NOTICE("BL2: Cannot create FCNL node (ret=%i)\n", ret); 171a6de3db7SMarek Vasut panic(); 172a6de3db7SMarek Vasut } 173a6de3db7SMarek Vasut 174a6de3db7SMarek Vasut ret = fdt_setprop_string(fdt, node, "compatible", 175a6de3db7SMarek Vasut "renesas,lossy-decompression"); 176a6de3db7SMarek Vasut if (ret < 0) { 177a6de3db7SMarek Vasut NOTICE("BL2: Cannot add FCNL compat string (ret=%i)\n", ret); 178a6de3db7SMarek Vasut panic(); 179a6de3db7SMarek Vasut } 180a6de3db7SMarek Vasut 181a6de3db7SMarek Vasut ret = fdt_appendprop_string(fdt, node, "compatible", 182a6de3db7SMarek Vasut "shared-dma-pool"); 183a6de3db7SMarek Vasut if (ret < 0) { 184a6de3db7SMarek Vasut NOTICE("BL2: Cannot append FCNL compat string (ret=%i)\n", ret); 185a6de3db7SMarek Vasut panic(); 186a6de3db7SMarek Vasut } 187a6de3db7SMarek Vasut 188a6de3db7SMarek Vasut ret = fdt_setprop_u64(fdt, node, "reg", start_addr); 189a6de3db7SMarek Vasut if (ret < 0) { 190a6de3db7SMarek Vasut NOTICE("BL2: Cannot add FCNL reg prop (ret=%i)\n", ret); 191a6de3db7SMarek Vasut panic(); 192a6de3db7SMarek Vasut } 193a6de3db7SMarek Vasut 194a6de3db7SMarek Vasut ret = fdt_appendprop(fdt, node, "reg", &fcnlsize, sizeof(fcnlsize)); 195a6de3db7SMarek Vasut if (ret < 0) { 196a6de3db7SMarek Vasut NOTICE("BL2: Cannot append FCNL reg size prop (ret=%i)\n", ret); 197a6de3db7SMarek Vasut panic(); 198a6de3db7SMarek Vasut } 199a6de3db7SMarek Vasut 200a6de3db7SMarek Vasut ret = fdt_setprop(fdt, node, "no-map", NULL, 0); 201a6de3db7SMarek Vasut if (ret < 0) { 202a6de3db7SMarek Vasut NOTICE("BL2: Cannot add FCNL no-map prop (ret=%i)\n", ret); 203a6de3db7SMarek Vasut panic(); 204a6de3db7SMarek Vasut } 205a6de3db7SMarek Vasut 206a6de3db7SMarek Vasut ret = fdt_setprop_u32(fdt, node, "renesas,formats", format); 207a6de3db7SMarek Vasut if (ret < 0) { 208a6de3db7SMarek Vasut NOTICE("BL2: Cannot add FCNL formats prop (ret=%i)\n", ret); 209a6de3db7SMarek Vasut panic(); 210a6de3db7SMarek Vasut } 211a6de3db7SMarek Vasut } 212a6de3db7SMarek Vasut 2137e532c4bSJorge Ramirez-Ortiz static void bl2_lossy_setting(uint32_t no, uint64_t start_addr, 2147e532c4bSJorge Ramirez-Ortiz uint64_t end_addr, uint32_t format, 215a6de3db7SMarek Vasut uint32_t enable, int fcnlnode) 2167e532c4bSJorge Ramirez-Ortiz { 2177e532c4bSJorge Ramirez-Ortiz bl2_lossy_info_t info; 2187e532c4bSJorge Ramirez-Ortiz uint32_t reg; 2197e532c4bSJorge Ramirez-Ortiz 220a6de3db7SMarek Vasut bl2_lossy_gen_fdt(no, start_addr, end_addr, format, enable, fcnlnode); 221a6de3db7SMarek Vasut 2227e532c4bSJorge Ramirez-Ortiz reg = format | (start_addr >> 20); 2237e532c4bSJorge Ramirez-Ortiz mmio_write_32(AXI_DCMPAREACRA0 + 0x8 * no, reg); 2247e532c4bSJorge Ramirez-Ortiz mmio_write_32(AXI_DCMPAREACRB0 + 0x8 * no, end_addr >> 20); 2257e532c4bSJorge Ramirez-Ortiz mmio_write_32(AXI_DCMPAREACRA0 + 0x8 * no, reg | enable); 2267e532c4bSJorge Ramirez-Ortiz 2277e532c4bSJorge Ramirez-Ortiz info.magic = 0x12345678U; 2287e532c4bSJorge Ramirez-Ortiz info.a0 = mmio_read_32(AXI_DCMPAREACRA0 + 0x8 * no); 2297e532c4bSJorge Ramirez-Ortiz info.b0 = mmio_read_32(AXI_DCMPAREACRB0 + 0x8 * no); 2307e532c4bSJorge Ramirez-Ortiz 2317e532c4bSJorge Ramirez-Ortiz mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no, info.magic); 2327e532c4bSJorge Ramirez-Ortiz mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x4, info.a0); 2337e532c4bSJorge Ramirez-Ortiz mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x8, info.b0); 2347e532c4bSJorge Ramirez-Ortiz 2357e532c4bSJorge Ramirez-Ortiz NOTICE(" Entry %d: DCMPAREACRAx:0x%x DCMPAREACRBx:0x%x\n", no, 2367e532c4bSJorge Ramirez-Ortiz mmio_read_32(AXI_DCMPAREACRA0 + 0x8 * no), 2377e532c4bSJorge Ramirez-Ortiz mmio_read_32(AXI_DCMPAREACRB0 + 0x8 * no)); 2387e532c4bSJorge Ramirez-Ortiz } 239*f945498fSDetlev Casanova 240*f945498fSDetlev Casanova static int bl2_create_reserved_memory(void) 241*f945498fSDetlev Casanova { 242*f945498fSDetlev Casanova int ret; 243*f945498fSDetlev Casanova 244*f945498fSDetlev Casanova int fcnlnode = fdt_add_subnode(fdt, 0, "reserved-memory"); 245*f945498fSDetlev Casanova if (fcnlnode < 0) { 246*f945498fSDetlev Casanova NOTICE("BL2: Cannot create reserved mem node (ret=%i)\n", 247*f945498fSDetlev Casanova fcnlnode); 248*f945498fSDetlev Casanova panic(); 249*f945498fSDetlev Casanova } 250*f945498fSDetlev Casanova 251*f945498fSDetlev Casanova ret = fdt_setprop(fdt, fcnlnode, "ranges", NULL, 0); 252*f945498fSDetlev Casanova if (ret < 0) { 253*f945498fSDetlev Casanova NOTICE("BL2: Cannot add FCNL ranges prop (ret=%i)\n", ret); 254*f945498fSDetlev Casanova panic(); 255*f945498fSDetlev Casanova } 256*f945498fSDetlev Casanova 257*f945498fSDetlev Casanova ret = fdt_setprop_u32(fdt, fcnlnode, "#address-cells", 2); 258*f945498fSDetlev Casanova if (ret < 0) { 259*f945498fSDetlev Casanova NOTICE("BL2: Cannot add FCNL #address-cells prop (ret=%i)\n", ret); 260*f945498fSDetlev Casanova panic(); 261*f945498fSDetlev Casanova } 262*f945498fSDetlev Casanova 263*f945498fSDetlev Casanova ret = fdt_setprop_u32(fdt, fcnlnode, "#size-cells", 2); 264*f945498fSDetlev Casanova if (ret < 0) { 265*f945498fSDetlev Casanova NOTICE("BL2: Cannot add FCNL #size-cells prop (ret=%i)\n", ret); 266*f945498fSDetlev Casanova panic(); 267*f945498fSDetlev Casanova } 268*f945498fSDetlev Casanova 269*f945498fSDetlev Casanova return fcnlnode; 270*f945498fSDetlev Casanova } 271*f945498fSDetlev Casanova 272*f945498fSDetlev Casanova static void bl2_create_fcnl_reserved_memory(void) 273*f945498fSDetlev Casanova { 274*f945498fSDetlev Casanova int fcnlnode; 275*f945498fSDetlev Casanova 276*f945498fSDetlev Casanova NOTICE("BL2: Lossy Decomp areas\n"); 277*f945498fSDetlev Casanova 278*f945498fSDetlev Casanova fcnlnode = bl2_create_reserved_memory(); 279*f945498fSDetlev Casanova 280*f945498fSDetlev Casanova bl2_lossy_setting(0, LOSSY_ST_ADDR0, LOSSY_END_ADDR0, 281*f945498fSDetlev Casanova LOSSY_FMT0, LOSSY_ENA_DIS0, fcnlnode); 282*f945498fSDetlev Casanova bl2_lossy_setting(1, LOSSY_ST_ADDR1, LOSSY_END_ADDR1, 283*f945498fSDetlev Casanova LOSSY_FMT1, LOSSY_ENA_DIS1, fcnlnode); 284*f945498fSDetlev Casanova bl2_lossy_setting(2, LOSSY_ST_ADDR2, LOSSY_END_ADDR2, 285*f945498fSDetlev Casanova LOSSY_FMT2, LOSSY_ENA_DIS2, fcnlnode); 286*f945498fSDetlev Casanova } 287*f945498fSDetlev Casanova #else 288*f945498fSDetlev Casanova static void bl2_create_fcnl_reserved_memory(void) {} 2897e532c4bSJorge Ramirez-Ortiz #endif 2907e532c4bSJorge Ramirez-Ortiz 2917e532c4bSJorge Ramirez-Ortiz void bl2_plat_flush_bl31_params(void) 2927e532c4bSJorge Ramirez-Ortiz { 2937e532c4bSJorge Ramirez-Ortiz uint32_t product_cut, product, cut; 2947e532c4bSJorge Ramirez-Ortiz uint32_t boot_dev, boot_cpu; 2957e532c4bSJorge Ramirez-Ortiz uint32_t lcs, reg, val; 2967e532c4bSJorge Ramirez-Ortiz 2977e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_MODEMR); 2987e532c4bSJorge Ramirez-Ortiz boot_dev = reg & MODEMR_BOOT_DEV_MASK; 2997e532c4bSJorge Ramirez-Ortiz 3007e532c4bSJorge Ramirez-Ortiz if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || 3017e532c4bSJorge Ramirez-Ortiz boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) 3027e532c4bSJorge Ramirez-Ortiz emmc_terminate(); 3037e532c4bSJorge Ramirez-Ortiz 3047e532c4bSJorge Ramirez-Ortiz if ((reg & MODEMR_BOOT_CPU_MASK) != MODEMR_BOOT_CPU_CR7) 3057e532c4bSJorge Ramirez-Ortiz bl2_secure_setting(); 3067e532c4bSJorge Ramirez-Ortiz 3077e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_PRR); 308df51d8feSMarek Vasut product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 309df51d8feSMarek Vasut product = reg & PRR_PRODUCT_MASK; 310df51d8feSMarek Vasut cut = reg & PRR_CUT_MASK; 3117e532c4bSJorge Ramirez-Ortiz 312df51d8feSMarek Vasut if (product == PRR_PRODUCT_M3 && PRR_PRODUCT_30 > cut) 3137e532c4bSJorge Ramirez-Ortiz goto tlb; 3147e532c4bSJorge Ramirez-Ortiz 315df51d8feSMarek Vasut if (product == PRR_PRODUCT_H3 && PRR_PRODUCT_20 > cut) 3167e532c4bSJorge Ramirez-Ortiz goto tlb; 3177e532c4bSJorge Ramirez-Ortiz 3187e532c4bSJorge Ramirez-Ortiz /* Disable MFIS write protection */ 3197e532c4bSJorge Ramirez-Ortiz mmio_write_32(MFISWPCNTR, MFISWPCNTR_PASSWORD | 1); 3207e532c4bSJorge Ramirez-Ortiz 3217e532c4bSJorge Ramirez-Ortiz tlb: 3227e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_MODEMR); 3237e532c4bSJorge Ramirez-Ortiz boot_cpu = reg & MODEMR_BOOT_CPU_MASK; 3247e532c4bSJorge Ramirez-Ortiz if (boot_cpu != MODEMR_BOOT_CPU_CA57 && 3257e532c4bSJorge Ramirez-Ortiz boot_cpu != MODEMR_BOOT_CPU_CA53) 3267e532c4bSJorge Ramirez-Ortiz goto mmu; 3277e532c4bSJorge Ramirez-Ortiz 328df51d8feSMarek Vasut if (product_cut == PRR_PRODUCT_H3_CUT20) { 3297e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); 3307e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUVI1_IMSCTLR, IMSCTLR_DISCACHE); 3317e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); 3327e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV1_IMSCTLR, IMSCTLR_DISCACHE); 3337e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV2_IMSCTLR, IMSCTLR_DISCACHE); 3347e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV3_IMSCTLR, IMSCTLR_DISCACHE); 335df51d8feSMarek Vasut } else if (product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) || 336df51d8feSMarek Vasut product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11)) { 3377e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); 3387e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); 339df51d8feSMarek Vasut } else if ((product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) || 340df51d8feSMarek Vasut (product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_11))) { 3417e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); 34232385427SMarek Vasut mmio_write_32(IPMMUVP0_IMSCTLR, IMSCTLR_DISCACHE); 3437e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); 3447e532c4bSJorge Ramirez-Ortiz } 3457e532c4bSJorge Ramirez-Ortiz 346df51d8feSMarek Vasut if (product_cut == (PRR_PRODUCT_H3_CUT20) || 347df51d8feSMarek Vasut product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) || 348df51d8feSMarek Vasut product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11) || 349df51d8feSMarek Vasut product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) { 3507e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUHC_IMSCTLR, IMSCTLR_DISCACHE); 3517e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMURT_IMSCTLR, IMSCTLR_DISCACHE); 3527e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUMP_IMSCTLR, IMSCTLR_DISCACHE); 3537e532c4bSJorge Ramirez-Ortiz 3547e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUDS0_IMSCTLR, IMSCTLR_DISCACHE); 3557e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUDS1_IMSCTLR, IMSCTLR_DISCACHE); 3567e532c4bSJorge Ramirez-Ortiz } 3577e532c4bSJorge Ramirez-Ortiz 3587e532c4bSJorge Ramirez-Ortiz mmu: 3597e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUMM_IMSCTLR, IPMMUMM_IMSCTLR_ENABLE); 3607e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUMM_IMAUXCTLR, IPMMUMM_IMAUXCTLR_NMERGE40_BIT); 3617e532c4bSJorge Ramirez-Ortiz 3627e532c4bSJorge Ramirez-Ortiz val = rcar_rom_get_lcs(&lcs); 3637e532c4bSJorge Ramirez-Ortiz if (val) { 3647e532c4bSJorge Ramirez-Ortiz ERROR("BL2: Failed to get the LCS. (%d)\n", val); 3657e532c4bSJorge Ramirez-Ortiz panic(); 3667e532c4bSJorge Ramirez-Ortiz } 3677e532c4bSJorge Ramirez-Ortiz 3687e532c4bSJorge Ramirez-Ortiz if (lcs == LCS_SE) 3697e532c4bSJorge Ramirez-Ortiz mmio_clrbits_32(P_ARMREG_SEC_CTRL, P_ARMREG_SEC_CTRL_PROT); 3707e532c4bSJorge Ramirez-Ortiz 3717e532c4bSJorge Ramirez-Ortiz rcar_swdt_release(); 3727e532c4bSJorge Ramirez-Ortiz bl2_system_cpg_init(); 3737e532c4bSJorge Ramirez-Ortiz 3747e532c4bSJorge Ramirez-Ortiz #if RCAR_BL2_DCACHE == 1 3757e532c4bSJorge Ramirez-Ortiz /* Disable data cache (clean and invalidate) */ 3767e532c4bSJorge Ramirez-Ortiz disable_mmu_el3(); 3777e532c4bSJorge Ramirez-Ortiz #endif 3787e532c4bSJorge Ramirez-Ortiz } 3797e532c4bSJorge Ramirez-Ortiz 3807e532c4bSJorge Ramirez-Ortiz static uint32_t is_ddr_backup_mode(void) 3817e532c4bSJorge Ramirez-Ortiz { 3827e532c4bSJorge Ramirez-Ortiz #if RCAR_SYSTEM_SUSPEND 3837e532c4bSJorge Ramirez-Ortiz static uint32_t reason = RCAR_COLD_BOOT; 3847e532c4bSJorge Ramirez-Ortiz static uint32_t once; 3857e532c4bSJorge Ramirez-Ortiz 3867e532c4bSJorge Ramirez-Ortiz #if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR 3877e532c4bSJorge Ramirez-Ortiz uint8_t data; 3887e532c4bSJorge Ramirez-Ortiz #endif 3897e532c4bSJorge Ramirez-Ortiz if (once) 3907e532c4bSJorge Ramirez-Ortiz return reason; 3917e532c4bSJorge Ramirez-Ortiz 3927e532c4bSJorge Ramirez-Ortiz once = 1; 3937e532c4bSJorge Ramirez-Ortiz if ((mmio_read_32(GPIO_INDT) & GPIO_BKUP_TRG_SHIFT) == 0) 3947e532c4bSJorge Ramirez-Ortiz return reason; 3957e532c4bSJorge Ramirez-Ortiz 3967e532c4bSJorge Ramirez-Ortiz #if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR 3977e532c4bSJorge Ramirez-Ortiz if (rcar_iic_dvfs_receive(PMIC, REG_KEEP10, &data)) { 3987e532c4bSJorge Ramirez-Ortiz ERROR("BL2: REG Keep10 READ ERROR.\n"); 3997e532c4bSJorge Ramirez-Ortiz panic(); 4007e532c4bSJorge Ramirez-Ortiz } 4017e532c4bSJorge Ramirez-Ortiz 4027e532c4bSJorge Ramirez-Ortiz if (KEEP10_MAGIC != data) 4037e532c4bSJorge Ramirez-Ortiz reason = RCAR_WARM_BOOT; 4047e532c4bSJorge Ramirez-Ortiz #else 4057e532c4bSJorge Ramirez-Ortiz reason = RCAR_WARM_BOOT; 4067e532c4bSJorge Ramirez-Ortiz #endif 4077e532c4bSJorge Ramirez-Ortiz return reason; 4087e532c4bSJorge Ramirez-Ortiz #else 4097e532c4bSJorge Ramirez-Ortiz return RCAR_COLD_BOOT; 4107e532c4bSJorge Ramirez-Ortiz #endif 4117e532c4bSJorge Ramirez-Ortiz } 4127e532c4bSJorge Ramirez-Ortiz 413ddf2ca03SMarek Vasut #if RCAR_GEN3_BL33_GZIP == 1 414ddf2ca03SMarek Vasut void bl2_plat_preload_setup(void) 415ddf2ca03SMarek Vasut { 416ddf2ca03SMarek Vasut image_decompress_init(BL33_COMP_BASE, BL33_COMP_SIZE, gunzip); 417ddf2ca03SMarek Vasut } 418ddf2ca03SMarek Vasut #endif 419ddf2ca03SMarek Vasut 4207e532c4bSJorge Ramirez-Ortiz int bl2_plat_handle_pre_image_load(unsigned int image_id) 4217e532c4bSJorge Ramirez-Ortiz { 4227e532c4bSJorge Ramirez-Ortiz u_register_t *boot_kind = (void *) BOOT_KIND_BASE; 4237e532c4bSJorge Ramirez-Ortiz bl_mem_params_node_t *bl_mem_params; 4247e532c4bSJorge Ramirez-Ortiz 425ddf2ca03SMarek Vasut bl_mem_params = get_bl_mem_params_node(image_id); 426ddf2ca03SMarek Vasut 427ddf2ca03SMarek Vasut #if RCAR_GEN3_BL33_GZIP == 1 428ddf2ca03SMarek Vasut if (image_id == BL33_IMAGE_ID) { 429ddf2ca03SMarek Vasut image_decompress_prepare(&bl_mem_params->image_info); 430ddf2ca03SMarek Vasut } 431ddf2ca03SMarek Vasut #endif 432ddf2ca03SMarek Vasut 4337e532c4bSJorge Ramirez-Ortiz if (image_id != BL31_IMAGE_ID) 4347e532c4bSJorge Ramirez-Ortiz return 0; 4357e532c4bSJorge Ramirez-Ortiz 4367e532c4bSJorge Ramirez-Ortiz if (is_ddr_backup_mode() == RCAR_COLD_BOOT) 4377e532c4bSJorge Ramirez-Ortiz goto cold_boot; 4387e532c4bSJorge Ramirez-Ortiz 4397e532c4bSJorge Ramirez-Ortiz *boot_kind = RCAR_WARM_BOOT; 4407e532c4bSJorge Ramirez-Ortiz flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind)); 4417e532c4bSJorge Ramirez-Ortiz 4427e532c4bSJorge Ramirez-Ortiz console_flush(); 4437e532c4bSJorge Ramirez-Ortiz bl2_plat_flush_bl31_params(); 4447e532c4bSJorge Ramirez-Ortiz 4457e532c4bSJorge Ramirez-Ortiz /* will not return */ 4467e532c4bSJorge Ramirez-Ortiz bl2_enter_bl31(&bl_mem_params->ep_info); 4477e532c4bSJorge Ramirez-Ortiz 4487e532c4bSJorge Ramirez-Ortiz cold_boot: 4497e532c4bSJorge Ramirez-Ortiz *boot_kind = RCAR_COLD_BOOT; 4507e532c4bSJorge Ramirez-Ortiz flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind)); 4517e532c4bSJorge Ramirez-Ortiz 4527e532c4bSJorge Ramirez-Ortiz return 0; 4537e532c4bSJorge Ramirez-Ortiz } 4547e532c4bSJorge Ramirez-Ortiz 45513856f37SToshiyuki Ogasahara static uint64_t rcar_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest) 45613856f37SToshiyuki Ogasahara { 45713856f37SToshiyuki Ogasahara uint32_t cert, len; 45813856f37SToshiyuki Ogasahara int ret; 45913856f37SToshiyuki Ogasahara 46013856f37SToshiyuki Ogasahara ret = rcar_get_certificate(certid, &cert); 46113856f37SToshiyuki Ogasahara if (ret) { 46213856f37SToshiyuki Ogasahara ERROR("%s : cert file load error", __func__); 46313856f37SToshiyuki Ogasahara return 1; 46413856f37SToshiyuki Ogasahara } 46513856f37SToshiyuki Ogasahara 46613856f37SToshiyuki Ogasahara rcar_read_certificate((uint64_t) cert, &len, dest); 46713856f37SToshiyuki Ogasahara 46813856f37SToshiyuki Ogasahara return 0; 46913856f37SToshiyuki Ogasahara } 47013856f37SToshiyuki Ogasahara 4717e532c4bSJorge Ramirez-Ortiz int bl2_plat_handle_post_image_load(unsigned int image_id) 4727e532c4bSJorge Ramirez-Ortiz { 4737e532c4bSJorge Ramirez-Ortiz static bl2_to_bl31_params_mem_t *params; 4747e532c4bSJorge Ramirez-Ortiz bl_mem_params_node_t *bl_mem_params; 47513856f37SToshiyuki Ogasahara uintptr_t dest; 47613856f37SToshiyuki Ogasahara int ret; 4777e532c4bSJorge Ramirez-Ortiz 4787e532c4bSJorge Ramirez-Ortiz if (!params) { 4797e532c4bSJorge Ramirez-Ortiz params = (bl2_to_bl31_params_mem_t *) PARAMS_BASE; 4807e532c4bSJorge Ramirez-Ortiz memset((void *)PARAMS_BASE, 0, sizeof(*params)); 4817e532c4bSJorge Ramirez-Ortiz } 4827e532c4bSJorge Ramirez-Ortiz 4837e532c4bSJorge Ramirez-Ortiz bl_mem_params = get_bl_mem_params_node(image_id); 4847e532c4bSJorge Ramirez-Ortiz 4857e532c4bSJorge Ramirez-Ortiz switch (image_id) { 4867e532c4bSJorge Ramirez-Ortiz case BL31_IMAGE_ID: 48713856f37SToshiyuki Ogasahara ret = rcar_get_dest_addr_from_cert(SOC_FW_CONTENT_CERT_ID, 48813856f37SToshiyuki Ogasahara &dest); 48913856f37SToshiyuki Ogasahara if (!ret) 49013856f37SToshiyuki Ogasahara bl_mem_params->image_info.image_base = dest; 4917e532c4bSJorge Ramirez-Ortiz break; 4927e532c4bSJorge Ramirez-Ortiz case BL32_IMAGE_ID: 49313856f37SToshiyuki Ogasahara ret = rcar_get_dest_addr_from_cert(TRUSTED_OS_FW_CONTENT_CERT_ID, 49413856f37SToshiyuki Ogasahara &dest); 49513856f37SToshiyuki Ogasahara if (!ret) 49613856f37SToshiyuki Ogasahara bl_mem_params->image_info.image_base = dest; 49713856f37SToshiyuki Ogasahara 4987e532c4bSJorge Ramirez-Ortiz memcpy(¶ms->bl32_ep_info, &bl_mem_params->ep_info, 4997e532c4bSJorge Ramirez-Ortiz sizeof(entry_point_info_t)); 5007e532c4bSJorge Ramirez-Ortiz break; 5017e532c4bSJorge Ramirez-Ortiz case BL33_IMAGE_ID: 502ddf2ca03SMarek Vasut #if RCAR_GEN3_BL33_GZIP == 1 503ddf2ca03SMarek Vasut if ((mmio_read_32(BL33_COMP_BASE) & 0xffff) == 0x8b1f) { 504ddf2ca03SMarek Vasut /* decompress gzip-compressed image */ 505ddf2ca03SMarek Vasut ret = image_decompress(&bl_mem_params->image_info); 506ddf2ca03SMarek Vasut if (ret != 0) { 507ddf2ca03SMarek Vasut return ret; 508ddf2ca03SMarek Vasut } 509ddf2ca03SMarek Vasut } else { 510ddf2ca03SMarek Vasut /* plain image, copy it in place */ 511ddf2ca03SMarek Vasut memcpy((void *)BL33_BASE, (void *)BL33_COMP_BASE, 512ddf2ca03SMarek Vasut bl_mem_params->image_info.image_size); 513ddf2ca03SMarek Vasut } 514ddf2ca03SMarek Vasut #endif 5157e532c4bSJorge Ramirez-Ortiz memcpy(¶ms->bl33_ep_info, &bl_mem_params->ep_info, 5167e532c4bSJorge Ramirez-Ortiz sizeof(entry_point_info_t)); 5177e532c4bSJorge Ramirez-Ortiz break; 5187e532c4bSJorge Ramirez-Ortiz } 5197e532c4bSJorge Ramirez-Ortiz 5207e532c4bSJorge Ramirez-Ortiz return 0; 5217e532c4bSJorge Ramirez-Ortiz } 5227e532c4bSJorge Ramirez-Ortiz 523db9a1555SMarek Vasut struct meminfo *bl2_plat_sec_mem_layout(void) 5247e532c4bSJorge Ramirez-Ortiz { 5257e532c4bSJorge Ramirez-Ortiz return &bl2_tzram_layout; 5267e532c4bSJorge Ramirez-Ortiz } 5277e532c4bSJorge Ramirez-Ortiz 528b7f6525dSJustin Chadwell static void bl2_populate_compatible_string(void *dt) 529ac49c5fbSMarek Vasut { 530ac49c5fbSMarek Vasut uint32_t board_type; 531ac49c5fbSMarek Vasut uint32_t board_rev; 532ac49c5fbSMarek Vasut uint32_t reg; 533ac49c5fbSMarek Vasut int ret; 534ac49c5fbSMarek Vasut 5356be71b09SMarek Vasut fdt_setprop_u32(dt, 0, "#address-cells", 2); 5366be71b09SMarek Vasut fdt_setprop_u32(dt, 0, "#size-cells", 2); 5376be71b09SMarek Vasut 538ac49c5fbSMarek Vasut /* Populate compatible string */ 539ac49c5fbSMarek Vasut rcar_get_board_type(&board_type, &board_rev); 540ac49c5fbSMarek Vasut switch (board_type) { 541ac49c5fbSMarek Vasut case BOARD_SALVATOR_X: 542b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 543ac49c5fbSMarek Vasut "renesas,salvator-x"); 544ac49c5fbSMarek Vasut break; 545ac49c5fbSMarek Vasut case BOARD_SALVATOR_XS: 546b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 547ac49c5fbSMarek Vasut "renesas,salvator-xs"); 548ac49c5fbSMarek Vasut break; 549ac49c5fbSMarek Vasut case BOARD_STARTER_KIT: 550b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 551ac49c5fbSMarek Vasut "renesas,m3ulcb"); 552ac49c5fbSMarek Vasut break; 553ac49c5fbSMarek Vasut case BOARD_STARTER_KIT_PRE: 554b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 555ac49c5fbSMarek Vasut "renesas,h3ulcb"); 556ac49c5fbSMarek Vasut break; 557b709fe9cSValentine Barshak case BOARD_EAGLE: 558b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 559b709fe9cSValentine Barshak "renesas,eagle"); 560b709fe9cSValentine Barshak break; 561ac49c5fbSMarek Vasut case BOARD_EBISU: 562ac49c5fbSMarek Vasut case BOARD_EBISU_4D: 563b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 564ac49c5fbSMarek Vasut "renesas,ebisu"); 565ac49c5fbSMarek Vasut break; 566bfbf5df4SMarek Vasut case BOARD_DRAAK: 567b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 568bfbf5df4SMarek Vasut "renesas,draak"); 569bfbf5df4SMarek Vasut break; 570ac49c5fbSMarek Vasut default: 571ac49c5fbSMarek Vasut NOTICE("BL2: Cannot set compatible string, board unsupported\n"); 572ac49c5fbSMarek Vasut panic(); 573ac49c5fbSMarek Vasut } 574ac49c5fbSMarek Vasut 575ac49c5fbSMarek Vasut if (ret < 0) { 576ac49c5fbSMarek Vasut NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret); 577ac49c5fbSMarek Vasut panic(); 578ac49c5fbSMarek Vasut } 579ac49c5fbSMarek Vasut 580ac49c5fbSMarek Vasut reg = mmio_read_32(RCAR_PRR); 581df51d8feSMarek Vasut switch (reg & PRR_PRODUCT_MASK) { 582df51d8feSMarek Vasut case PRR_PRODUCT_H3: 583b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 584ac49c5fbSMarek Vasut "renesas,r8a7795"); 585ac49c5fbSMarek Vasut break; 586df51d8feSMarek Vasut case PRR_PRODUCT_M3: 587b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 588ac49c5fbSMarek Vasut "renesas,r8a7796"); 589ac49c5fbSMarek Vasut break; 590df51d8feSMarek Vasut case PRR_PRODUCT_M3N: 591b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 592ac49c5fbSMarek Vasut "renesas,r8a77965"); 593ac49c5fbSMarek Vasut break; 594df51d8feSMarek Vasut case PRR_PRODUCT_V3M: 595b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 596b709fe9cSValentine Barshak "renesas,r8a77970"); 597b709fe9cSValentine Barshak break; 598df51d8feSMarek Vasut case PRR_PRODUCT_E3: 599b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 600ac49c5fbSMarek Vasut "renesas,r8a77990"); 601ac49c5fbSMarek Vasut break; 602df51d8feSMarek Vasut case PRR_PRODUCT_D3: 603b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 604bfbf5df4SMarek Vasut "renesas,r8a77995"); 605bfbf5df4SMarek Vasut break; 606ac49c5fbSMarek Vasut default: 607ac49c5fbSMarek Vasut NOTICE("BL2: Cannot set compatible string, SoC unsupported\n"); 608ac49c5fbSMarek Vasut panic(); 609ac49c5fbSMarek Vasut } 610ac49c5fbSMarek Vasut 611ac49c5fbSMarek Vasut if (ret < 0) { 612ac49c5fbSMarek Vasut NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret); 613ac49c5fbSMarek Vasut panic(); 614ac49c5fbSMarek Vasut } 615ac49c5fbSMarek Vasut } 616ac49c5fbSMarek Vasut 61712c75c88SMarek Vasut static void bl2_add_rpc_node(void) 61812c75c88SMarek Vasut { 61912c75c88SMarek Vasut #if (RCAR_RPC_HYPERFLASH_LOCKED == 0) 62012c75c88SMarek Vasut int ret, node; 62112c75c88SMarek Vasut 62212c75c88SMarek Vasut node = ret = fdt_add_subnode(fdt, 0, "soc"); 62312c75c88SMarek Vasut if (ret < 0) { 62412c75c88SMarek Vasut goto err; 62512c75c88SMarek Vasut } 62612c75c88SMarek Vasut 62708ae2471SGeert Uytterhoeven node = ret = fdt_add_subnode(fdt, node, "spi@ee200000"); 62812c75c88SMarek Vasut if (ret < 0) { 62912c75c88SMarek Vasut goto err; 63012c75c88SMarek Vasut } 63112c75c88SMarek Vasut 63212c75c88SMarek Vasut ret = fdt_setprop_string(fdt, node, "status", "okay"); 63312c75c88SMarek Vasut if (ret < 0) { 63412c75c88SMarek Vasut goto err; 63512c75c88SMarek Vasut } 63612c75c88SMarek Vasut 63712c75c88SMarek Vasut return; 63812c75c88SMarek Vasut err: 63912c75c88SMarek Vasut NOTICE("BL2: Cannot add RPC node to FDT (ret=%i)\n", ret); 64012c75c88SMarek Vasut panic(); 64112c75c88SMarek Vasut #endif 64212c75c88SMarek Vasut } 64312c75c88SMarek Vasut 644e624e98dSMarek Vasut static void bl2_add_dram_entry(uint64_t start, uint64_t size) 64585185151SMarek Vasut { 6461d85c4bdSMarek Vasut char nodename[32] = { 0 }; 6471d85c4bdSMarek Vasut uint64_t fdtsize; 648e624e98dSMarek Vasut int ret, node; 649e624e98dSMarek Vasut 650e624e98dSMarek Vasut fdtsize = cpu_to_fdt64(size); 651e624e98dSMarek Vasut 652e624e98dSMarek Vasut snprintf(nodename, sizeof(nodename), "memory@"); 653e624e98dSMarek Vasut unsigned_num_print(start, 16, nodename + strlen(nodename)); 654e624e98dSMarek Vasut node = ret = fdt_add_subnode(fdt, 0, nodename); 655e624e98dSMarek Vasut if (ret < 0) { 656e624e98dSMarek Vasut goto err; 657e624e98dSMarek Vasut } 658e624e98dSMarek Vasut 659e624e98dSMarek Vasut ret = fdt_setprop_string(fdt, node, "device_type", "memory"); 660e624e98dSMarek Vasut if (ret < 0) { 661e624e98dSMarek Vasut goto err; 662e624e98dSMarek Vasut } 663e624e98dSMarek Vasut 664e624e98dSMarek Vasut ret = fdt_setprop_u64(fdt, node, "reg", start); 665e624e98dSMarek Vasut if (ret < 0) { 666e624e98dSMarek Vasut goto err; 667e624e98dSMarek Vasut } 668e624e98dSMarek Vasut 669e624e98dSMarek Vasut ret = fdt_appendprop(fdt, node, "reg", &fdtsize, 670e624e98dSMarek Vasut sizeof(fdtsize)); 671e624e98dSMarek Vasut if (ret < 0) { 672e624e98dSMarek Vasut goto err; 673e624e98dSMarek Vasut } 674e624e98dSMarek Vasut 675e624e98dSMarek Vasut return; 676e624e98dSMarek Vasut err: 6774ce3e99aSScott Branden NOTICE("BL2: Cannot add memory node [%" PRIx64 " - %" PRIx64 "] to FDT (ret=%i)\n", 678e624e98dSMarek Vasut start, start + size - 1, ret); 679e624e98dSMarek Vasut panic(); 680e624e98dSMarek Vasut } 681e624e98dSMarek Vasut 682e624e98dSMarek Vasut static void bl2_advertise_dram_entries(uint64_t dram_config[8]) 683e624e98dSMarek Vasut { 68421924f24SMarek Vasut uint64_t start, size, size32; 685e624e98dSMarek Vasut int chan; 68685185151SMarek Vasut 68785185151SMarek Vasut for (chan = 0; chan < 4; chan++) { 68885185151SMarek Vasut start = dram_config[2 * chan]; 68985185151SMarek Vasut size = dram_config[2 * chan + 1]; 69085185151SMarek Vasut if (!size) 69185185151SMarek Vasut continue; 69285185151SMarek Vasut 6934ce3e99aSScott Branden NOTICE("BL2: CH%d: %" PRIx64 " - %" PRIx64 ", %" PRId64 " %siB\n", 6945b4f022bSMarek Vasut chan, start, start + size - 1, 6955b4f022bSMarek Vasut (size >> 30) ? : size >> 20, 6965b4f022bSMarek Vasut (size >> 30) ? "G" : "M"); 69785185151SMarek Vasut } 6981d85c4bdSMarek Vasut 6991d85c4bdSMarek Vasut /* 7001d85c4bdSMarek Vasut * We add the DT nodes in reverse order here. The fdt_add_subnode() 7011d85c4bdSMarek Vasut * adds the DT node before the first existing DT node, so we have 7021d85c4bdSMarek Vasut * to add them in reverse order to get nodes sorted by address in 7031d85c4bdSMarek Vasut * the resulting DT. 7041d85c4bdSMarek Vasut */ 7051d85c4bdSMarek Vasut for (chan = 3; chan >= 0; chan--) { 7061d85c4bdSMarek Vasut start = dram_config[2 * chan]; 7071d85c4bdSMarek Vasut size = dram_config[2 * chan + 1]; 7081d85c4bdSMarek Vasut if (!size) 7091d85c4bdSMarek Vasut continue; 7101d85c4bdSMarek Vasut 7111d85c4bdSMarek Vasut /* 7121d85c4bdSMarek Vasut * Channel 0 is mapped in 32bit space and the first 71321924f24SMarek Vasut * 128 MiB are reserved and the maximum size is 2GiB. 7141d85c4bdSMarek Vasut */ 7151d85c4bdSMarek Vasut if (chan == 0) { 71621924f24SMarek Vasut /* Limit the 32bit entry to 2 GiB - 128 MiB */ 71721924f24SMarek Vasut size32 = size - 0x8000000U; 71821924f24SMarek Vasut if (size32 >= 0x78000000U) { 71921924f24SMarek Vasut size32 = 0x78000000U; 72021924f24SMarek Vasut } 72121924f24SMarek Vasut 72221924f24SMarek Vasut /* Emit 32bit entry, up to 2 GiB - 128 MiB long. */ 72321924f24SMarek Vasut bl2_add_dram_entry(0x48000000, size32); 72421924f24SMarek Vasut 72521924f24SMarek Vasut /* 72621924f24SMarek Vasut * If channel 0 is less than 2 GiB long, the 72721924f24SMarek Vasut * entire memory fits into the 32bit space entry, 72821924f24SMarek Vasut * so move on to the next channel. 72921924f24SMarek Vasut */ 73021924f24SMarek Vasut if (size <= 0x80000000U) { 73121924f24SMarek Vasut continue; 73221924f24SMarek Vasut } 73321924f24SMarek Vasut 73421924f24SMarek Vasut /* 73521924f24SMarek Vasut * If channel 0 is more than 2 GiB long, emit 73621924f24SMarek Vasut * another entry which covers the rest of the 73721924f24SMarek Vasut * memory in channel 0, in the 64bit space. 73821924f24SMarek Vasut * 73921924f24SMarek Vasut * Start of this new entry is at 2 GiB offset 74021924f24SMarek Vasut * from the beginning of the 64bit channel 0 74121924f24SMarek Vasut * address, size is 2 GiB shorter than total 74221924f24SMarek Vasut * size of the channel. 74321924f24SMarek Vasut */ 74421924f24SMarek Vasut start += 0x80000000U; 74521924f24SMarek Vasut size -= 0x80000000U; 7461d85c4bdSMarek Vasut } 7471d85c4bdSMarek Vasut 748e624e98dSMarek Vasut bl2_add_dram_entry(start, size); 7491d85c4bdSMarek Vasut } 75085185151SMarek Vasut } 75185185151SMarek Vasut 7527bf24ae3SMarek Vasut static void bl2_advertise_dram_size(uint32_t product) 753358ed930SMarek Vasut { 75485185151SMarek Vasut uint64_t dram_config[8] = { 75585185151SMarek Vasut [0] = 0x400000000ULL, 75685185151SMarek Vasut [2] = 0x500000000ULL, 75785185151SMarek Vasut [4] = 0x600000000ULL, 75885185151SMarek Vasut [6] = 0x700000000ULL, 75985185151SMarek Vasut }; 76042ffd279SToshiyuki Ogasahara uint32_t cut = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK; 76185185151SMarek Vasut 762e1eddfeaSMarek Vasut switch (product) { 763df51d8feSMarek Vasut case PRR_PRODUCT_H3: 764358ed930SMarek Vasut #if (RCAR_DRAM_LPDDR4_MEMCONF == 0) 765358ed930SMarek Vasut /* 4GB(1GBx4) */ 76685185151SMarek Vasut dram_config[1] = 0x40000000ULL; 76785185151SMarek Vasut dram_config[3] = 0x40000000ULL; 76885185151SMarek Vasut dram_config[5] = 0x40000000ULL; 76985185151SMarek Vasut dram_config[7] = 0x40000000ULL; 770358ed930SMarek Vasut #elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && \ 771358ed930SMarek Vasut (RCAR_DRAM_CHANNEL == 5) && \ 772358ed930SMarek Vasut (RCAR_DRAM_SPLIT == 2) 773358ed930SMarek Vasut /* 4GB(2GBx2 2ch split) */ 77485185151SMarek Vasut dram_config[1] = 0x80000000ULL; 77585185151SMarek Vasut dram_config[3] = 0x80000000ULL; 776358ed930SMarek Vasut #elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && (RCAR_DRAM_CHANNEL == 15) 777358ed930SMarek Vasut /* 8GB(2GBx4: default) */ 77885185151SMarek Vasut dram_config[1] = 0x80000000ULL; 77985185151SMarek Vasut dram_config[3] = 0x80000000ULL; 78085185151SMarek Vasut dram_config[5] = 0x80000000ULL; 78185185151SMarek Vasut dram_config[7] = 0x80000000ULL; 782358ed930SMarek Vasut #endif /* RCAR_DRAM_LPDDR4_MEMCONF == 0 */ 783e1eddfeaSMarek Vasut break; 784358ed930SMarek Vasut 785df51d8feSMarek Vasut case PRR_PRODUCT_M3: 78642ffd279SToshiyuki Ogasahara if (cut < PRR_PRODUCT_30) { 7875a21f313SMarek Vasut #if (RCAR_GEN3_ULCB == 1) 7885a21f313SMarek Vasut /* 2GB(1GBx2 2ch split) */ 7895a21f313SMarek Vasut dram_config[1] = 0x40000000ULL; 7905a21f313SMarek Vasut dram_config[5] = 0x40000000ULL; 7915a21f313SMarek Vasut #else 792e1eddfeaSMarek Vasut /* 4GB(2GBx2 2ch split) */ 79385185151SMarek Vasut dram_config[1] = 0x80000000ULL; 79485185151SMarek Vasut dram_config[5] = 0x80000000ULL; 7955a21f313SMarek Vasut #endif 79642ffd279SToshiyuki Ogasahara } else { 79742ffd279SToshiyuki Ogasahara /* 8GB(2GBx4 2ch split) */ 79842ffd279SToshiyuki Ogasahara dram_config[1] = 0x100000000ULL; 79942ffd279SToshiyuki Ogasahara dram_config[5] = 0x100000000ULL; 80042ffd279SToshiyuki Ogasahara } 801e1eddfeaSMarek Vasut break; 802e1eddfeaSMarek Vasut 803df51d8feSMarek Vasut case PRR_PRODUCT_M3N: 804f95d5512SToshiyuki Ogasahara #if (RCAR_DRAM_LPDDR4_MEMCONF == 2) 805f95d5512SToshiyuki Ogasahara /* 4GB(4GBx1) */ 806f95d5512SToshiyuki Ogasahara dram_config[1] = 0x100000000ULL; 807f95d5512SToshiyuki Ogasahara #elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) 808e1eddfeaSMarek Vasut /* 2GB(1GBx2) */ 80985185151SMarek Vasut dram_config[1] = 0x80000000ULL; 810f95d5512SToshiyuki Ogasahara #endif 811e1eddfeaSMarek Vasut break; 812e1eddfeaSMarek Vasut 813df51d8feSMarek Vasut case PRR_PRODUCT_V3M: 814b709fe9cSValentine Barshak /* 1GB(512MBx2) */ 815b709fe9cSValentine Barshak dram_config[1] = 0x40000000ULL; 816b709fe9cSValentine Barshak break; 817b709fe9cSValentine Barshak 818df51d8feSMarek Vasut case PRR_PRODUCT_E3: 819358ed930SMarek Vasut #if (RCAR_DRAM_DDR3L_MEMCONF == 0) 820358ed930SMarek Vasut /* 1GB(512MBx2) */ 82185185151SMarek Vasut dram_config[1] = 0x40000000ULL; 822358ed930SMarek Vasut #elif (RCAR_DRAM_DDR3L_MEMCONF == 1) 823358ed930SMarek Vasut /* 2GB(512MBx4) */ 82485185151SMarek Vasut dram_config[1] = 0x80000000ULL; 8253b507aabSMarek Vasut #elif (RCAR_DRAM_DDR3L_MEMCONF == 2) 8263b507aabSMarek Vasut /* 4GB(1GBx4) */ 82785185151SMarek Vasut dram_config[1] = 0x100000000ULL; 828358ed930SMarek Vasut #endif /* RCAR_DRAM_DDR3L_MEMCONF == 0 */ 829e1eddfeaSMarek Vasut break; 830bfbf5df4SMarek Vasut 831df51d8feSMarek Vasut case PRR_PRODUCT_D3: 832bfbf5df4SMarek Vasut /* 512MB */ 833bfbf5df4SMarek Vasut dram_config[1] = 0x20000000ULL; 834bfbf5df4SMarek Vasut break; 835358ed930SMarek Vasut } 83685185151SMarek Vasut 83785185151SMarek Vasut bl2_advertise_dram_entries(dram_config); 838358ed930SMarek Vasut } 839358ed930SMarek Vasut 8407e532c4bSJorge Ramirez-Ortiz void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, 8417e532c4bSJorge Ramirez-Ortiz u_register_t arg3, u_register_t arg4) 8427e532c4bSJorge Ramirez-Ortiz { 8437e532c4bSJorge Ramirez-Ortiz uint32_t reg, midr, lcs, boot_dev, boot_cpu, sscg, type, rev; 8447bf24ae3SMarek Vasut uint32_t product, product_cut, major, minor; 8457e532c4bSJorge Ramirez-Ortiz int32_t ret; 8467e532c4bSJorge Ramirez-Ortiz const char *str; 8477e532c4bSJorge Ramirez-Ortiz const char *unknown = "unknown"; 8487e532c4bSJorge Ramirez-Ortiz const char *cpu_ca57 = "CA57"; 8497e532c4bSJorge Ramirez-Ortiz const char *cpu_ca53 = "CA53"; 8507e532c4bSJorge Ramirez-Ortiz const char *product_m3n = "M3N"; 8517e532c4bSJorge Ramirez-Ortiz const char *product_h3 = "H3"; 8527e532c4bSJorge Ramirez-Ortiz const char *product_m3 = "M3"; 8537e532c4bSJorge Ramirez-Ortiz const char *product_e3 = "E3"; 854bfbf5df4SMarek Vasut const char *product_d3 = "D3"; 855b709fe9cSValentine Barshak const char *product_v3m = "V3M"; 8567e532c4bSJorge Ramirez-Ortiz const char *lcs_secure = "SE"; 8577e532c4bSJorge Ramirez-Ortiz const char *lcs_cm = "CM"; 8587e532c4bSJorge Ramirez-Ortiz const char *lcs_dm = "DM"; 8597e532c4bSJorge Ramirez-Ortiz const char *lcs_sd = "SD"; 8607e532c4bSJorge Ramirez-Ortiz const char *lcs_fa = "FA"; 8617e532c4bSJorge Ramirez-Ortiz const char *sscg_off = "PLL1 nonSSCG Clock select"; 8627e532c4bSJorge Ramirez-Ortiz const char *sscg_on = "PLL1 SSCG Clock select"; 8637e532c4bSJorge Ramirez-Ortiz const char *boot_hyper80 = "HyperFlash(80MHz)"; 8647e532c4bSJorge Ramirez-Ortiz const char *boot_qspi40 = "QSPI Flash(40MHz)"; 8657e532c4bSJorge Ramirez-Ortiz const char *boot_qspi80 = "QSPI Flash(80MHz)"; 8667e532c4bSJorge Ramirez-Ortiz const char *boot_emmc25x1 = "eMMC(25MHz x1)"; 8677e532c4bSJorge Ramirez-Ortiz const char *boot_emmc50x8 = "eMMC(50MHz x8)"; 868bfbf5df4SMarek Vasut #if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) 8697e532c4bSJorge Ramirez-Ortiz const char *boot_hyper160 = "HyperFlash(150MHz)"; 8707e532c4bSJorge Ramirez-Ortiz #else 8717e532c4bSJorge Ramirez-Ortiz const char *boot_hyper160 = "HyperFlash(160MHz)"; 8727e532c4bSJorge Ramirez-Ortiz #endif 8737e532c4bSJorge Ramirez-Ortiz 87447141b73SMarek Vasut bl2_init_generic_timer(); 87547141b73SMarek Vasut 8767e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_MODEMR); 8777e532c4bSJorge Ramirez-Ortiz boot_dev = reg & MODEMR_BOOT_DEV_MASK; 8787e532c4bSJorge Ramirez-Ortiz boot_cpu = reg & MODEMR_BOOT_CPU_MASK; 8797e532c4bSJorge Ramirez-Ortiz 8807e532c4bSJorge Ramirez-Ortiz bl2_cpg_init(); 8817e532c4bSJorge Ramirez-Ortiz 8827e532c4bSJorge Ramirez-Ortiz if (boot_cpu == MODEMR_BOOT_CPU_CA57 || 8837e532c4bSJorge Ramirez-Ortiz boot_cpu == MODEMR_BOOT_CPU_CA53) { 8847e532c4bSJorge Ramirez-Ortiz rcar_pfc_init(); 885018358fcSMarek Vasut rcar_console_boot_init(); 8867e532c4bSJorge Ramirez-Ortiz } 8877e532c4bSJorge Ramirez-Ortiz 8887e532c4bSJorge Ramirez-Ortiz plat_rcar_gic_driver_init(); 8897e532c4bSJorge Ramirez-Ortiz plat_rcar_gic_init(); 8907e532c4bSJorge Ramirez-Ortiz rcar_swdt_init(); 8917e532c4bSJorge Ramirez-Ortiz 8927e532c4bSJorge Ramirez-Ortiz /* FIQ interrupts are taken to EL3 */ 8937e532c4bSJorge Ramirez-Ortiz write_scr_el3(read_scr_el3() | SCR_FIQ_BIT); 8947e532c4bSJorge Ramirez-Ortiz 8957e532c4bSJorge Ramirez-Ortiz write_daifclr(DAIF_FIQ_BIT); 8967e532c4bSJorge Ramirez-Ortiz 8977e532c4bSJorge Ramirez-Ortiz reg = read_midr(); 8987e532c4bSJorge Ramirez-Ortiz midr = reg & (MIDR_PN_MASK << MIDR_PN_SHIFT); 8997e532c4bSJorge Ramirez-Ortiz switch (midr) { 9007e532c4bSJorge Ramirez-Ortiz case MIDR_CA57: 9017e532c4bSJorge Ramirez-Ortiz str = cpu_ca57; 9027e532c4bSJorge Ramirez-Ortiz break; 9037e532c4bSJorge Ramirez-Ortiz case MIDR_CA53: 9047e532c4bSJorge Ramirez-Ortiz str = cpu_ca53; 9057e532c4bSJorge Ramirez-Ortiz break; 9067e532c4bSJorge Ramirez-Ortiz default: 9077e532c4bSJorge Ramirez-Ortiz str = unknown; 9087e532c4bSJorge Ramirez-Ortiz break; 9097e532c4bSJorge Ramirez-Ortiz } 9107e532c4bSJorge Ramirez-Ortiz 9117e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: R-Car Gen3 Initial Program Loader(%s) Rev.%s\n", str, 9127e532c4bSJorge Ramirez-Ortiz version_of_renesas); 9137e532c4bSJorge Ramirez-Ortiz 9147e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_PRR); 915df51d8feSMarek Vasut product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 916df51d8feSMarek Vasut product = reg & PRR_PRODUCT_MASK; 9177e532c4bSJorge Ramirez-Ortiz 9187e532c4bSJorge Ramirez-Ortiz switch (product) { 919df51d8feSMarek Vasut case PRR_PRODUCT_H3: 9207e532c4bSJorge Ramirez-Ortiz str = product_h3; 9217e532c4bSJorge Ramirez-Ortiz break; 922df51d8feSMarek Vasut case PRR_PRODUCT_M3: 9237e532c4bSJorge Ramirez-Ortiz str = product_m3; 9247e532c4bSJorge Ramirez-Ortiz break; 925df51d8feSMarek Vasut case PRR_PRODUCT_M3N: 9267e532c4bSJorge Ramirez-Ortiz str = product_m3n; 9277e532c4bSJorge Ramirez-Ortiz break; 928df51d8feSMarek Vasut case PRR_PRODUCT_V3M: 929b709fe9cSValentine Barshak str = product_v3m; 930b709fe9cSValentine Barshak break; 931df51d8feSMarek Vasut case PRR_PRODUCT_E3: 9327e532c4bSJorge Ramirez-Ortiz str = product_e3; 9337e532c4bSJorge Ramirez-Ortiz break; 934df51d8feSMarek Vasut case PRR_PRODUCT_D3: 935bfbf5df4SMarek Vasut str = product_d3; 936bfbf5df4SMarek Vasut break; 9377e532c4bSJorge Ramirez-Ortiz default: 9387e532c4bSJorge Ramirez-Ortiz str = unknown; 9397e532c4bSJorge Ramirez-Ortiz break; 9407e532c4bSJorge Ramirez-Ortiz } 9417e532c4bSJorge Ramirez-Ortiz 942df51d8feSMarek Vasut if ((PRR_PRODUCT_M3 == product) && 943df51d8feSMarek Vasut (PRR_PRODUCT_20 == (reg & RCAR_MAJOR_MASK))) { 944df51d8feSMarek Vasut if (RCAR_M3_CUT_VER11 == (reg & PRR_CUT_MASK)) { 945845d8fbbSMarek Vasut /* M3 Ver.1.1 or Ver.1.2 */ 946845d8fbbSMarek Vasut NOTICE("BL2: PRR is R-Car %s Ver.1.1 / Ver.1.2\n", 947845d8fbbSMarek Vasut str); 948845d8fbbSMarek Vasut } else { 949845d8fbbSMarek Vasut NOTICE("BL2: PRR is R-Car %s Ver.1.%d\n", 950845d8fbbSMarek Vasut str, 951845d8fbbSMarek Vasut (reg & RCAR_MINOR_MASK) + RCAR_M3_MINOR_OFFSET); 952845d8fbbSMarek Vasut } 953c3d192b8SToshiyuki Ogasahara } else if (product == PRR_PRODUCT_D3) { 954c3d192b8SToshiyuki Ogasahara if (RCAR_D3_CUT_VER10 == (reg & PRR_CUT_MASK)) { 955c3d192b8SToshiyuki Ogasahara NOTICE("BL2: PRR is R-Car %s Ver.1.0\n", str); 956c3d192b8SToshiyuki Ogasahara } else if (RCAR_D3_CUT_VER11 == (reg & PRR_CUT_MASK)) { 957c3d192b8SToshiyuki Ogasahara NOTICE("BL2: PRR is R-Car %s Ver.1.1\n", str); 958c3d192b8SToshiyuki Ogasahara } else { 959c3d192b8SToshiyuki Ogasahara NOTICE("BL2: PRR is R-Car %s Ver.X.X\n", str); 960c3d192b8SToshiyuki Ogasahara } 9617e532c4bSJorge Ramirez-Ortiz } else { 9627e532c4bSJorge Ramirez-Ortiz major = (reg & RCAR_MAJOR_MASK) >> RCAR_MAJOR_SHIFT; 9637e532c4bSJorge Ramirez-Ortiz major = major + RCAR_MAJOR_OFFSET; 9647e532c4bSJorge Ramirez-Ortiz minor = reg & RCAR_MINOR_MASK; 9657e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: PRR is R-Car %s Ver.%d.%d\n", str, major, minor); 9667e532c4bSJorge Ramirez-Ortiz } 9677e532c4bSJorge Ramirez-Ortiz 96814f0a081SToshiyuki Ogasahara if (PRR_PRODUCT_E3 == product || PRR_PRODUCT_D3 == product) { 9697e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_MODEMR); 9707e532c4bSJorge Ramirez-Ortiz sscg = reg & RCAR_SSCG_MASK; 9717e532c4bSJorge Ramirez-Ortiz str = sscg == RCAR_SSCG_ENABLE ? sscg_on : sscg_off; 9727e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: %s\n", str); 9737e532c4bSJorge Ramirez-Ortiz } 9747e532c4bSJorge Ramirez-Ortiz 9757e532c4bSJorge Ramirez-Ortiz rcar_get_board_type(&type, &rev); 9767e532c4bSJorge Ramirez-Ortiz 9777e532c4bSJorge Ramirez-Ortiz switch (type) { 9787e532c4bSJorge Ramirez-Ortiz case BOARD_SALVATOR_X: 9797e532c4bSJorge Ramirez-Ortiz case BOARD_KRIEK: 9807e532c4bSJorge Ramirez-Ortiz case BOARD_STARTER_KIT: 9817e532c4bSJorge Ramirez-Ortiz case BOARD_SALVATOR_XS: 9827e532c4bSJorge Ramirez-Ortiz case BOARD_EBISU: 9837e532c4bSJorge Ramirez-Ortiz case BOARD_STARTER_KIT_PRE: 9847e532c4bSJorge Ramirez-Ortiz case BOARD_EBISU_4D: 985bfbf5df4SMarek Vasut case BOARD_DRAAK: 986b709fe9cSValentine Barshak case BOARD_EAGLE: 9877e532c4bSJorge Ramirez-Ortiz break; 9887e532c4bSJorge Ramirez-Ortiz default: 9897e532c4bSJorge Ramirez-Ortiz type = BOARD_UNKNOWN; 9907e532c4bSJorge Ramirez-Ortiz break; 9917e532c4bSJorge Ramirez-Ortiz } 9927e532c4bSJorge Ramirez-Ortiz 9937e532c4bSJorge Ramirez-Ortiz if (type == BOARD_UNKNOWN || rev == BOARD_REV_UNKNOWN) 9947e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Board is %s Rev.---\n", GET_BOARD_NAME(type)); 9957e532c4bSJorge Ramirez-Ortiz else { 9967e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Board is %s Rev.%d.%d\n", 9977e532c4bSJorge Ramirez-Ortiz GET_BOARD_NAME(type), 9987e532c4bSJorge Ramirez-Ortiz GET_BOARD_MAJOR(rev), GET_BOARD_MINOR(rev)); 9997e532c4bSJorge Ramirez-Ortiz } 10007e532c4bSJorge Ramirez-Ortiz 10017e532c4bSJorge Ramirez-Ortiz #if RCAR_LSI != RCAR_AUTO 10027e532c4bSJorge Ramirez-Ortiz if (product != TARGET_PRODUCT) { 10037e532c4bSJorge Ramirez-Ortiz ERROR("BL2: IPL was been built for the %s.\n", TARGET_NAME); 10047e532c4bSJorge Ramirez-Ortiz ERROR("BL2: Please write the correct IPL to flash memory.\n"); 10057e532c4bSJorge Ramirez-Ortiz panic(); 10067e532c4bSJorge Ramirez-Ortiz } 10077e532c4bSJorge Ramirez-Ortiz #endif 10087e532c4bSJorge Ramirez-Ortiz rcar_avs_init(); 10097e532c4bSJorge Ramirez-Ortiz rcar_avs_setting(); 10107e532c4bSJorge Ramirez-Ortiz 10117e532c4bSJorge Ramirez-Ortiz switch (boot_dev) { 10127e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_HYPERFLASH160: 10137e532c4bSJorge Ramirez-Ortiz str = boot_hyper160; 10147e532c4bSJorge Ramirez-Ortiz break; 10157e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_HYPERFLASH80: 10167e532c4bSJorge Ramirez-Ortiz str = boot_hyper80; 10177e532c4bSJorge Ramirez-Ortiz break; 10187e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_QSPI_FLASH40: 10197e532c4bSJorge Ramirez-Ortiz str = boot_qspi40; 10207e532c4bSJorge Ramirez-Ortiz break; 10217e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_QSPI_FLASH80: 10227e532c4bSJorge Ramirez-Ortiz str = boot_qspi80; 10237e532c4bSJorge Ramirez-Ortiz break; 10247e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_EMMC_25X1: 1025bfbf5df4SMarek Vasut #if RCAR_LSI == RCAR_D3 1026bfbf5df4SMarek Vasut ERROR("BL2: Failed to Initialize. eMMC is not supported.\n"); 1027bfbf5df4SMarek Vasut panic(); 1028bfbf5df4SMarek Vasut #endif 10297e532c4bSJorge Ramirez-Ortiz str = boot_emmc25x1; 10307e532c4bSJorge Ramirez-Ortiz break; 10317e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_EMMC_50X8: 10327e532c4bSJorge Ramirez-Ortiz str = boot_emmc50x8; 10337e532c4bSJorge Ramirez-Ortiz break; 10347e532c4bSJorge Ramirez-Ortiz default: 10357e532c4bSJorge Ramirez-Ortiz str = unknown; 10367e532c4bSJorge Ramirez-Ortiz break; 10377e532c4bSJorge Ramirez-Ortiz } 10387e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Boot device is %s\n", str); 10397e532c4bSJorge Ramirez-Ortiz 10407e532c4bSJorge Ramirez-Ortiz rcar_avs_setting(); 10417e532c4bSJorge Ramirez-Ortiz reg = rcar_rom_get_lcs(&lcs); 10427e532c4bSJorge Ramirez-Ortiz if (reg) { 10437e532c4bSJorge Ramirez-Ortiz str = unknown; 10447e532c4bSJorge Ramirez-Ortiz goto lcm_state; 10457e532c4bSJorge Ramirez-Ortiz } 10467e532c4bSJorge Ramirez-Ortiz 10477e532c4bSJorge Ramirez-Ortiz switch (lcs) { 10487e532c4bSJorge Ramirez-Ortiz case LCS_CM: 10497e532c4bSJorge Ramirez-Ortiz str = lcs_cm; 10507e532c4bSJorge Ramirez-Ortiz break; 10517e532c4bSJorge Ramirez-Ortiz case LCS_DM: 10527e532c4bSJorge Ramirez-Ortiz str = lcs_dm; 10537e532c4bSJorge Ramirez-Ortiz break; 10547e532c4bSJorge Ramirez-Ortiz case LCS_SD: 10557e532c4bSJorge Ramirez-Ortiz str = lcs_sd; 10567e532c4bSJorge Ramirez-Ortiz break; 10577e532c4bSJorge Ramirez-Ortiz case LCS_SE: 10587e532c4bSJorge Ramirez-Ortiz str = lcs_secure; 10597e532c4bSJorge Ramirez-Ortiz break; 10607e532c4bSJorge Ramirez-Ortiz case LCS_FA: 10617e532c4bSJorge Ramirez-Ortiz str = lcs_fa; 10627e532c4bSJorge Ramirez-Ortiz break; 10637e532c4bSJorge Ramirez-Ortiz default: 10647e532c4bSJorge Ramirez-Ortiz str = unknown; 10657e532c4bSJorge Ramirez-Ortiz break; 10667e532c4bSJorge Ramirez-Ortiz } 10677e532c4bSJorge Ramirez-Ortiz 10687e532c4bSJorge Ramirez-Ortiz lcm_state: 10697e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: LCM state is %s\n", str); 10707e532c4bSJorge Ramirez-Ortiz 10717e532c4bSJorge Ramirez-Ortiz rcar_avs_end(); 10727e532c4bSJorge Ramirez-Ortiz is_ddr_backup_mode(); 10737e532c4bSJorge Ramirez-Ortiz 10747e532c4bSJorge Ramirez-Ortiz bl2_tzram_layout.total_base = BL31_BASE; 10757e532c4bSJorge Ramirez-Ortiz bl2_tzram_layout.total_size = BL31_LIMIT - BL31_BASE; 10767e532c4bSJorge Ramirez-Ortiz 10777e532c4bSJorge Ramirez-Ortiz if (boot_cpu == MODEMR_BOOT_CPU_CA57 || 10787e532c4bSJorge Ramirez-Ortiz boot_cpu == MODEMR_BOOT_CPU_CA53) { 10797e532c4bSJorge Ramirez-Ortiz ret = rcar_dram_init(); 10807e532c4bSJorge Ramirez-Ortiz if (ret) { 10817e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Failed to DRAM initialize (%d).\n", ret); 10827e532c4bSJorge Ramirez-Ortiz panic(); 10837e532c4bSJorge Ramirez-Ortiz } 10847e532c4bSJorge Ramirez-Ortiz rcar_qos_init(); 10857e532c4bSJorge Ramirez-Ortiz } 10867e532c4bSJorge Ramirez-Ortiz 10871d85c4bdSMarek Vasut /* Set up FDT */ 10881d85c4bdSMarek Vasut ret = fdt_create_empty_tree(fdt, sizeof(fdt_blob)); 10891d85c4bdSMarek Vasut if (ret) { 10901d85c4bdSMarek Vasut NOTICE("BL2: Cannot allocate FDT for U-Boot (ret=%i)\n", ret); 10911d85c4bdSMarek Vasut panic(); 10921d85c4bdSMarek Vasut } 10931d85c4bdSMarek Vasut 1094ac49c5fbSMarek Vasut /* Add platform compatible string */ 1095ac49c5fbSMarek Vasut bl2_populate_compatible_string(fdt); 1096ac49c5fbSMarek Vasut 109712c75c88SMarek Vasut /* Enable RPC if unlocked */ 109812c75c88SMarek Vasut bl2_add_rpc_node(); 109912c75c88SMarek Vasut 110010b7a4aeSMarek Vasut /* Print DRAM layout */ 110110b7a4aeSMarek Vasut bl2_advertise_dram_size(product); 110210b7a4aeSMarek Vasut 11037e532c4bSJorge Ramirez-Ortiz if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || 11047e532c4bSJorge Ramirez-Ortiz boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) { 11057e532c4bSJorge Ramirez-Ortiz if (rcar_emmc_init() != EMMC_SUCCESS) { 11067e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Failed to eMMC driver initialize.\n"); 11077e532c4bSJorge Ramirez-Ortiz panic(); 11087e532c4bSJorge Ramirez-Ortiz } 11097e532c4bSJorge Ramirez-Ortiz rcar_emmc_memcard_power(EMMC_POWER_ON); 11107e532c4bSJorge Ramirez-Ortiz if (rcar_emmc_mount() != EMMC_SUCCESS) { 11117e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Failed to eMMC mount operation.\n"); 11127e532c4bSJorge Ramirez-Ortiz panic(); 11137e532c4bSJorge Ramirez-Ortiz } 11147e532c4bSJorge Ramirez-Ortiz } else { 11157e532c4bSJorge Ramirez-Ortiz rcar_rpc_init(); 11167e532c4bSJorge Ramirez-Ortiz rcar_dma_init(); 11177e532c4bSJorge Ramirez-Ortiz } 11187e532c4bSJorge Ramirez-Ortiz 11197e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RST_WDTRSTCR); 11207e532c4bSJorge Ramirez-Ortiz reg &= ~WDTRSTCR_RWDT_RSTMSK; 11217e532c4bSJorge Ramirez-Ortiz reg |= WDTRSTCR_PASSWORD; 11227e532c4bSJorge Ramirez-Ortiz mmio_write_32(RST_WDTRSTCR, reg); 11237e532c4bSJorge Ramirez-Ortiz 11247e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_CPGWPR, CPGWPR_PASSWORD); 11257e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_CPGWPCR, CPGWPCR_PASSWORD); 11267e532c4bSJorge Ramirez-Ortiz 11277e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_PRR); 11287e532c4bSJorge Ramirez-Ortiz if ((reg & RCAR_CPU_MASK_CA57) == RCAR_CPU_HAVE_CA57) 11297e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_CA57DBGRCR, 11307e532c4bSJorge Ramirez-Ortiz DBGCPUPREN | mmio_read_32(CPG_CA57DBGRCR)); 11317e532c4bSJorge Ramirez-Ortiz 11327e532c4bSJorge Ramirez-Ortiz if ((reg & RCAR_CPU_MASK_CA53) == RCAR_CPU_HAVE_CA53) 11337e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_CA53DBGRCR, 11347e532c4bSJorge Ramirez-Ortiz DBGCPUPREN | mmio_read_32(CPG_CA53DBGRCR)); 11357e532c4bSJorge Ramirez-Ortiz 1136df51d8feSMarek Vasut if (product_cut == PRR_PRODUCT_H3_CUT10) { 11377e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(CPG_PLL2CR); 11387e532c4bSJorge Ramirez-Ortiz reg &= ~((uint32_t) 1 << 5); 11397e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_PLL2CR, reg); 11407e532c4bSJorge Ramirez-Ortiz 11417e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(CPG_PLL4CR); 11427e532c4bSJorge Ramirez-Ortiz reg &= ~((uint32_t) 1 << 5); 11437e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_PLL4CR, reg); 11447e532c4bSJorge Ramirez-Ortiz 11457e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(CPG_PLL0CR); 11467e532c4bSJorge Ramirez-Ortiz reg &= ~((uint32_t) 1 << 12); 11477e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_PLL0CR, reg); 11487e532c4bSJorge Ramirez-Ortiz } 1149a6de3db7SMarek Vasut 1150*f945498fSDetlev Casanova bl2_create_fcnl_reserved_memory(); 11517e532c4bSJorge Ramirez-Ortiz 11521d85c4bdSMarek Vasut fdt_pack(fdt); 11531d85c4bdSMarek Vasut NOTICE("BL2: FDT at %p\n", fdt); 11541d85c4bdSMarek Vasut 11557e532c4bSJorge Ramirez-Ortiz if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || 11567e532c4bSJorge Ramirez-Ortiz boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) 11577e532c4bSJorge Ramirez-Ortiz rcar_io_emmc_setup(); 11587e532c4bSJorge Ramirez-Ortiz else 11597e532c4bSJorge Ramirez-Ortiz rcar_io_setup(); 11607e532c4bSJorge Ramirez-Ortiz } 11617e532c4bSJorge Ramirez-Ortiz 11627e532c4bSJorge Ramirez-Ortiz void bl2_el3_plat_arch_setup(void) 11637e532c4bSJorge Ramirez-Ortiz { 11647e532c4bSJorge Ramirez-Ortiz #if RCAR_BL2_DCACHE == 1 11657e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: D-Cache enable\n"); 11667e532c4bSJorge Ramirez-Ortiz rcar_configure_mmu_el3(BL2_BASE, 1167bc5fabd8SMarek Vasut BL2_END - BL2_BASE, 11687e532c4bSJorge Ramirez-Ortiz BL2_RO_BASE, BL2_RO_LIMIT 11697e532c4bSJorge Ramirez-Ortiz #if USE_COHERENT_MEM 11707e532c4bSJorge Ramirez-Ortiz , BL2_COHERENT_RAM_BASE, BL2_COHERENT_RAM_LIMIT 11717e532c4bSJorge Ramirez-Ortiz #endif 11727e532c4bSJorge Ramirez-Ortiz ); 11737e532c4bSJorge Ramirez-Ortiz #endif 11747e532c4bSJorge Ramirez-Ortiz } 11757e532c4bSJorge Ramirez-Ortiz 11767e532c4bSJorge Ramirez-Ortiz void bl2_platform_setup(void) 11777e532c4bSJorge Ramirez-Ortiz { 11787e532c4bSJorge Ramirez-Ortiz 11797e532c4bSJorge Ramirez-Ortiz } 118047141b73SMarek Vasut 118147141b73SMarek Vasut static void bl2_init_generic_timer(void) 118247141b73SMarek Vasut { 1183b709fe9cSValentine Barshak /* FIXME: V3M 16.666 MHz ? */ 1184bfbf5df4SMarek Vasut #if RCAR_LSI == RCAR_D3 1185bfbf5df4SMarek Vasut uint32_t reg_cntfid = EXTAL_DRAAK; 1186bfbf5df4SMarek Vasut #elif RCAR_LSI == RCAR_E3 118747141b73SMarek Vasut uint32_t reg_cntfid = EXTAL_EBISU; 118847141b73SMarek Vasut #else /* RCAR_LSI == RCAR_E3 */ 118947141b73SMarek Vasut uint32_t reg; 119047141b73SMarek Vasut uint32_t reg_cntfid; 119147141b73SMarek Vasut uint32_t modemr; 119247141b73SMarek Vasut uint32_t modemr_pll; 119347141b73SMarek Vasut uint32_t board_type; 119447141b73SMarek Vasut uint32_t board_rev; 119547141b73SMarek Vasut uint32_t pll_table[] = { 119647141b73SMarek Vasut EXTAL_MD14_MD13_TYPE_0, /* MD14/MD13 : 0b00 */ 119747141b73SMarek Vasut EXTAL_MD14_MD13_TYPE_1, /* MD14/MD13 : 0b01 */ 119847141b73SMarek Vasut EXTAL_MD14_MD13_TYPE_2, /* MD14/MD13 : 0b10 */ 119947141b73SMarek Vasut EXTAL_MD14_MD13_TYPE_3 /* MD14/MD13 : 0b11 */ 120047141b73SMarek Vasut }; 120147141b73SMarek Vasut 120247141b73SMarek Vasut modemr = mmio_read_32(RCAR_MODEMR); 120347141b73SMarek Vasut modemr_pll = (modemr & MODEMR_BOOT_PLL_MASK); 120447141b73SMarek Vasut 120547141b73SMarek Vasut /* Set frequency data in CNTFID0 */ 120647141b73SMarek Vasut reg_cntfid = pll_table[modemr_pll >> MODEMR_BOOT_PLL_SHIFT]; 1207df51d8feSMarek Vasut reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 120847141b73SMarek Vasut switch (modemr_pll) { 120947141b73SMarek Vasut case MD14_MD13_TYPE_0: 121047141b73SMarek Vasut rcar_get_board_type(&board_type, &board_rev); 121147141b73SMarek Vasut if (BOARD_SALVATOR_XS == board_type) { 121247141b73SMarek Vasut reg_cntfid = EXTAL_SALVATOR_XS; 121347141b73SMarek Vasut } 121447141b73SMarek Vasut break; 121547141b73SMarek Vasut case MD14_MD13_TYPE_3: 1216df51d8feSMarek Vasut if (PRR_PRODUCT_H3_CUT10 == reg) { 121747141b73SMarek Vasut reg_cntfid = reg_cntfid >> 1U; 121847141b73SMarek Vasut } 121947141b73SMarek Vasut break; 122047141b73SMarek Vasut default: 122147141b73SMarek Vasut /* none */ 122247141b73SMarek Vasut break; 122347141b73SMarek Vasut } 122447141b73SMarek Vasut #endif /* RCAR_LSI == RCAR_E3 */ 122547141b73SMarek Vasut /* Update memory mapped and register based freqency */ 122647141b73SMarek Vasut write_cntfrq_el0((u_register_t )reg_cntfid); 122747141b73SMarek Vasut mmio_write_32(ARM_SYS_CNTCTL_BASE + (uintptr_t)CNTFID_OFF, reg_cntfid); 122847141b73SMarek Vasut /* Enable counter */ 122947141b73SMarek Vasut mmio_setbits_32(RCAR_CNTC_BASE + (uintptr_t)CNTCR_OFF, 123047141b73SMarek Vasut (uint32_t)CNTCR_EN); 123147141b73SMarek Vasut } 1232