17e532c4bSJorge Ramirez-Ortiz /* 2ca661a00SMadhukar Pappireddy * Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. 37e532c4bSJorge Ramirez-Ortiz * 47e532c4bSJorge Ramirez-Ortiz * SPDX-License-Identifier: BSD-3-Clause 57e532c4bSJorge Ramirez-Ortiz */ 67e532c4bSJorge Ramirez-Ortiz 77e532c4bSJorge Ramirez-Ortiz #include <string.h> 809d40e0eSAntonio Nino Diaz 909d40e0eSAntonio Nino Diaz #include <libfdt.h> 1009d40e0eSAntonio Nino Diaz 1109d40e0eSAntonio Nino Diaz #include <platform_def.h> 1209d40e0eSAntonio Nino Diaz 1309d40e0eSAntonio Nino Diaz #include <arch_helpers.h> 1409d40e0eSAntonio Nino Diaz #include <bl1/bl1.h> 1509d40e0eSAntonio Nino Diaz #include <common/bl_common.h> 1609d40e0eSAntonio Nino Diaz #include <common/debug.h> 1709d40e0eSAntonio Nino Diaz #include <common/desc_image_load.h> 1809d40e0eSAntonio Nino Diaz #include <drivers/console.h> 19*13856f37SToshiyuki Ogasahara #include <drivers/io/io_driver.h> 20*13856f37SToshiyuki Ogasahara #include <drivers/io/io_storage.h> 2109d40e0eSAntonio Nino Diaz #include <lib/mmio.h> 2209d40e0eSAntonio Nino Diaz #include <lib/xlat_tables/xlat_tables_defs.h> 2309d40e0eSAntonio Nino Diaz #include <plat/common/platform.h> 247e532c4bSJorge Ramirez-Ortiz 257e532c4bSJorge Ramirez-Ortiz #include "avs_driver.h" 267e532c4bSJorge Ramirez-Ortiz #include "boot_init_dram.h" 277e532c4bSJorge Ramirez-Ortiz #include "cpg_registers.h" 287e532c4bSJorge Ramirez-Ortiz #include "board.h" 297e532c4bSJorge Ramirez-Ortiz #include "emmc_def.h" 307e532c4bSJorge Ramirez-Ortiz #include "emmc_hal.h" 317e532c4bSJorge Ramirez-Ortiz #include "emmc_std.h" 327e532c4bSJorge Ramirez-Ortiz 337e532c4bSJorge Ramirez-Ortiz #if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR 347e532c4bSJorge Ramirez-Ortiz #include "iic_dvfs.h" 357e532c4bSJorge Ramirez-Ortiz #endif 367e532c4bSJorge Ramirez-Ortiz 377e532c4bSJorge Ramirez-Ortiz #include "io_common.h" 38*13856f37SToshiyuki Ogasahara #include "io_rcar.h" 397e532c4bSJorge Ramirez-Ortiz #include "qos_init.h" 407e532c4bSJorge Ramirez-Ortiz #include "rcar_def.h" 417e532c4bSJorge Ramirez-Ortiz #include "rcar_private.h" 427e532c4bSJorge Ramirez-Ortiz #include "rcar_version.h" 437e532c4bSJorge Ramirez-Ortiz #include "rom_api.h" 447e532c4bSJorge Ramirez-Ortiz 45ca661a00SMadhukar Pappireddy #if RCAR_BL2_DCACHE == 1 46ca661a00SMadhukar Pappireddy /* 47ca661a00SMadhukar Pappireddy * Following symbols are only used during plat_arch_setup() only 48ca661a00SMadhukar Pappireddy * when RCAR_BL2_DCACHE is enabled. 49ca661a00SMadhukar Pappireddy */ 50ca661a00SMadhukar Pappireddy static const uint64_t BL2_RO_BASE = BL_CODE_BASE; 51ca661a00SMadhukar Pappireddy static const uint64_t BL2_RO_LIMIT = BL_CODE_END; 527e532c4bSJorge Ramirez-Ortiz 537e532c4bSJorge Ramirez-Ortiz #if USE_COHERENT_MEM 54ca661a00SMadhukar Pappireddy static const uint64_t BL2_COHERENT_RAM_BASE = BL_COHERENT_RAM_BASE; 55ca661a00SMadhukar Pappireddy static const uint64_t BL2_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END; 56ca661a00SMadhukar Pappireddy #endif 57ca661a00SMadhukar Pappireddy 587e532c4bSJorge Ramirez-Ortiz #endif 597e532c4bSJorge Ramirez-Ortiz 607e532c4bSJorge Ramirez-Ortiz extern void plat_rcar_gic_driver_init(void); 617e532c4bSJorge Ramirez-Ortiz extern void plat_rcar_gic_init(void); 627e532c4bSJorge Ramirez-Ortiz extern void bl2_enter_bl31(const struct entry_point_info *bl_ep_info); 637e532c4bSJorge Ramirez-Ortiz extern void bl2_system_cpg_init(void); 647e532c4bSJorge Ramirez-Ortiz extern void bl2_secure_setting(void); 657e532c4bSJorge Ramirez-Ortiz extern void bl2_cpg_init(void); 667e532c4bSJorge Ramirez-Ortiz extern void rcar_io_emmc_setup(void); 677e532c4bSJorge Ramirez-Ortiz extern void rcar_io_setup(void); 687e532c4bSJorge Ramirez-Ortiz extern void rcar_swdt_release(void); 697e532c4bSJorge Ramirez-Ortiz extern void rcar_swdt_init(void); 707e532c4bSJorge Ramirez-Ortiz extern void rcar_rpc_init(void); 717e532c4bSJorge Ramirez-Ortiz extern void rcar_pfc_init(void); 727e532c4bSJorge Ramirez-Ortiz extern void rcar_dma_init(void); 737e532c4bSJorge Ramirez-Ortiz 7447141b73SMarek Vasut static void bl2_init_generic_timer(void); 7547141b73SMarek Vasut 767e532c4bSJorge Ramirez-Ortiz /* R-Car Gen3 product check */ 777e532c4bSJorge Ramirez-Ortiz #if (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) 78df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_H3 797e532c4bSJorge Ramirez-Ortiz #define TARGET_NAME "R-Car H3" 807e532c4bSJorge Ramirez-Ortiz #elif RCAR_LSI == RCAR_M3 81df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_M3 827e532c4bSJorge Ramirez-Ortiz #define TARGET_NAME "R-Car M3" 837e532c4bSJorge Ramirez-Ortiz #elif RCAR_LSI == RCAR_M3N 84df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_M3N 857e532c4bSJorge Ramirez-Ortiz #define TARGET_NAME "R-Car M3N" 86b709fe9cSValentine Barshak #elif RCAR_LSI == RCAR_V3M 87df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_V3M 88b709fe9cSValentine Barshak #define TARGET_NAME "R-Car V3M" 897e532c4bSJorge Ramirez-Ortiz #elif RCAR_LSI == RCAR_E3 90df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_E3 917e532c4bSJorge Ramirez-Ortiz #define TARGET_NAME "R-Car E3" 92bfbf5df4SMarek Vasut #elif RCAR_LSI == RCAR_D3 93df51d8feSMarek Vasut #define TARGET_PRODUCT PRR_PRODUCT_D3 94bfbf5df4SMarek Vasut #define TARGET_NAME "R-Car D3" 950468aa39SMarek Vasut #elif RCAR_LSI == RCAR_AUTO 96b709fe9cSValentine Barshak #define TARGET_NAME "R-Car H3/M3/M3N/V3M" 977e532c4bSJorge Ramirez-Ortiz #endif 987e532c4bSJorge Ramirez-Ortiz 997e532c4bSJorge Ramirez-Ortiz #if (RCAR_LSI == RCAR_E3) 1007e532c4bSJorge Ramirez-Ortiz #define GPIO_INDT (GPIO_INDT6) 1017e532c4bSJorge Ramirez-Ortiz #define GPIO_BKUP_TRG_SHIFT ((uint32_t)1U<<13U) 1027e532c4bSJorge Ramirez-Ortiz #else 1037e532c4bSJorge Ramirez-Ortiz #define GPIO_INDT (GPIO_INDT1) 1047e532c4bSJorge Ramirez-Ortiz #define GPIO_BKUP_TRG_SHIFT ((uint32_t)1U<<8U) 1057e532c4bSJorge Ramirez-Ortiz #endif 1067e532c4bSJorge Ramirez-Ortiz 1077e532c4bSJorge Ramirez-Ortiz CASSERT((PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t) + 0x100) 1087e532c4bSJorge Ramirez-Ortiz < (RCAR_SHARED_MEM_BASE + RCAR_SHARED_MEM_SIZE), 1097e532c4bSJorge Ramirez-Ortiz assert_bl31_params_do_not_fit_in_shared_memory); 1107e532c4bSJorge Ramirez-Ortiz 1117e532c4bSJorge Ramirez-Ortiz static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); 1127e532c4bSJorge Ramirez-Ortiz 1131d85c4bdSMarek Vasut /* FDT with DRAM configuration */ 1141d85c4bdSMarek Vasut uint64_t fdt_blob[PAGE_SIZE_4KB / sizeof(uint64_t)]; 1151d85c4bdSMarek Vasut static void *fdt = (void *)fdt_blob; 1161d85c4bdSMarek Vasut 1171d85c4bdSMarek Vasut static void unsigned_num_print(unsigned long long int unum, unsigned int radix, 1181d85c4bdSMarek Vasut char *string) 1191d85c4bdSMarek Vasut { 1201d85c4bdSMarek Vasut /* Just need enough space to store 64 bit decimal integer */ 1211d85c4bdSMarek Vasut char num_buf[20]; 1221d85c4bdSMarek Vasut int i = 0; 1231d85c4bdSMarek Vasut unsigned int rem; 1241d85c4bdSMarek Vasut 1251d85c4bdSMarek Vasut do { 1261d85c4bdSMarek Vasut rem = unum % radix; 1271d85c4bdSMarek Vasut if (rem < 0xa) 1281d85c4bdSMarek Vasut num_buf[i] = '0' + rem; 1291d85c4bdSMarek Vasut else 1301d85c4bdSMarek Vasut num_buf[i] = 'a' + (rem - 0xa); 1311d85c4bdSMarek Vasut i++; 1321d85c4bdSMarek Vasut unum /= radix; 1331d85c4bdSMarek Vasut } while (unum > 0U); 1341d85c4bdSMarek Vasut 1351d85c4bdSMarek Vasut while (--i >= 0) 1361d85c4bdSMarek Vasut *string++ = num_buf[i]; 1371d85c4bdSMarek Vasut } 1381d85c4bdSMarek Vasut 1397e532c4bSJorge Ramirez-Ortiz #if (RCAR_LOSSY_ENABLE == 1) 1407e532c4bSJorge Ramirez-Ortiz typedef struct bl2_lossy_info { 1417e532c4bSJorge Ramirez-Ortiz uint32_t magic; 1427e532c4bSJorge Ramirez-Ortiz uint32_t a0; 1437e532c4bSJorge Ramirez-Ortiz uint32_t b0; 1447e532c4bSJorge Ramirez-Ortiz } bl2_lossy_info_t; 1457e532c4bSJorge Ramirez-Ortiz 146a6de3db7SMarek Vasut static void bl2_lossy_gen_fdt(uint32_t no, uint64_t start_addr, 147a6de3db7SMarek Vasut uint64_t end_addr, uint32_t format, 148a6de3db7SMarek Vasut uint32_t enable, int fcnlnode) 149a6de3db7SMarek Vasut { 150a6de3db7SMarek Vasut const uint64_t fcnlsize = cpu_to_fdt64(end_addr - start_addr); 151a6de3db7SMarek Vasut char nodename[40] = { 0 }; 152a6de3db7SMarek Vasut int ret, node; 153a6de3db7SMarek Vasut 154a6de3db7SMarek Vasut /* Ignore undefined addresses */ 155a6de3db7SMarek Vasut if (start_addr == 0 && end_addr == 0) 156a6de3db7SMarek Vasut return; 157a6de3db7SMarek Vasut 158a6de3db7SMarek Vasut snprintf(nodename, sizeof(nodename), "lossy-decompression@"); 159a6de3db7SMarek Vasut unsigned_num_print(start_addr, 16, nodename + strlen(nodename)); 160a6de3db7SMarek Vasut 161a6de3db7SMarek Vasut node = ret = fdt_add_subnode(fdt, fcnlnode, nodename); 162a6de3db7SMarek Vasut if (ret < 0) { 163a6de3db7SMarek Vasut NOTICE("BL2: Cannot create FCNL node (ret=%i)\n", ret); 164a6de3db7SMarek Vasut panic(); 165a6de3db7SMarek Vasut } 166a6de3db7SMarek Vasut 167a6de3db7SMarek Vasut ret = fdt_setprop_string(fdt, node, "compatible", 168a6de3db7SMarek Vasut "renesas,lossy-decompression"); 169a6de3db7SMarek Vasut if (ret < 0) { 170a6de3db7SMarek Vasut NOTICE("BL2: Cannot add FCNL compat string (ret=%i)\n", ret); 171a6de3db7SMarek Vasut panic(); 172a6de3db7SMarek Vasut } 173a6de3db7SMarek Vasut 174a6de3db7SMarek Vasut ret = fdt_appendprop_string(fdt, node, "compatible", 175a6de3db7SMarek Vasut "shared-dma-pool"); 176a6de3db7SMarek Vasut if (ret < 0) { 177a6de3db7SMarek Vasut NOTICE("BL2: Cannot append FCNL compat string (ret=%i)\n", ret); 178a6de3db7SMarek Vasut panic(); 179a6de3db7SMarek Vasut } 180a6de3db7SMarek Vasut 181a6de3db7SMarek Vasut ret = fdt_setprop_u64(fdt, node, "reg", start_addr); 182a6de3db7SMarek Vasut if (ret < 0) { 183a6de3db7SMarek Vasut NOTICE("BL2: Cannot add FCNL reg prop (ret=%i)\n", ret); 184a6de3db7SMarek Vasut panic(); 185a6de3db7SMarek Vasut } 186a6de3db7SMarek Vasut 187a6de3db7SMarek Vasut ret = fdt_appendprop(fdt, node, "reg", &fcnlsize, sizeof(fcnlsize)); 188a6de3db7SMarek Vasut if (ret < 0) { 189a6de3db7SMarek Vasut NOTICE("BL2: Cannot append FCNL reg size prop (ret=%i)\n", ret); 190a6de3db7SMarek Vasut panic(); 191a6de3db7SMarek Vasut } 192a6de3db7SMarek Vasut 193a6de3db7SMarek Vasut ret = fdt_setprop(fdt, node, "no-map", NULL, 0); 194a6de3db7SMarek Vasut if (ret < 0) { 195a6de3db7SMarek Vasut NOTICE("BL2: Cannot add FCNL no-map prop (ret=%i)\n", ret); 196a6de3db7SMarek Vasut panic(); 197a6de3db7SMarek Vasut } 198a6de3db7SMarek Vasut 199a6de3db7SMarek Vasut ret = fdt_setprop_u32(fdt, node, "renesas,formats", format); 200a6de3db7SMarek Vasut if (ret < 0) { 201a6de3db7SMarek Vasut NOTICE("BL2: Cannot add FCNL formats prop (ret=%i)\n", ret); 202a6de3db7SMarek Vasut panic(); 203a6de3db7SMarek Vasut } 204a6de3db7SMarek Vasut } 205a6de3db7SMarek Vasut 2067e532c4bSJorge Ramirez-Ortiz static void bl2_lossy_setting(uint32_t no, uint64_t start_addr, 2077e532c4bSJorge Ramirez-Ortiz uint64_t end_addr, uint32_t format, 208a6de3db7SMarek Vasut uint32_t enable, int fcnlnode) 2097e532c4bSJorge Ramirez-Ortiz { 2107e532c4bSJorge Ramirez-Ortiz bl2_lossy_info_t info; 2117e532c4bSJorge Ramirez-Ortiz uint32_t reg; 2127e532c4bSJorge Ramirez-Ortiz 213a6de3db7SMarek Vasut bl2_lossy_gen_fdt(no, start_addr, end_addr, format, enable, fcnlnode); 214a6de3db7SMarek Vasut 2157e532c4bSJorge Ramirez-Ortiz reg = format | (start_addr >> 20); 2167e532c4bSJorge Ramirez-Ortiz mmio_write_32(AXI_DCMPAREACRA0 + 0x8 * no, reg); 2177e532c4bSJorge Ramirez-Ortiz mmio_write_32(AXI_DCMPAREACRB0 + 0x8 * no, end_addr >> 20); 2187e532c4bSJorge Ramirez-Ortiz mmio_write_32(AXI_DCMPAREACRA0 + 0x8 * no, reg | enable); 2197e532c4bSJorge Ramirez-Ortiz 2207e532c4bSJorge Ramirez-Ortiz info.magic = 0x12345678U; 2217e532c4bSJorge Ramirez-Ortiz info.a0 = mmio_read_32(AXI_DCMPAREACRA0 + 0x8 * no); 2227e532c4bSJorge Ramirez-Ortiz info.b0 = mmio_read_32(AXI_DCMPAREACRB0 + 0x8 * no); 2237e532c4bSJorge Ramirez-Ortiz 2247e532c4bSJorge Ramirez-Ortiz mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no, info.magic); 2257e532c4bSJorge Ramirez-Ortiz mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x4, info.a0); 2267e532c4bSJorge Ramirez-Ortiz mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x8, info.b0); 2277e532c4bSJorge Ramirez-Ortiz 2287e532c4bSJorge Ramirez-Ortiz NOTICE(" Entry %d: DCMPAREACRAx:0x%x DCMPAREACRBx:0x%x\n", no, 2297e532c4bSJorge Ramirez-Ortiz mmio_read_32(AXI_DCMPAREACRA0 + 0x8 * no), 2307e532c4bSJorge Ramirez-Ortiz mmio_read_32(AXI_DCMPAREACRB0 + 0x8 * no)); 2317e532c4bSJorge Ramirez-Ortiz } 2327e532c4bSJorge Ramirez-Ortiz #endif 2337e532c4bSJorge Ramirez-Ortiz 2347e532c4bSJorge Ramirez-Ortiz void bl2_plat_flush_bl31_params(void) 2357e532c4bSJorge Ramirez-Ortiz { 2367e532c4bSJorge Ramirez-Ortiz uint32_t product_cut, product, cut; 2377e532c4bSJorge Ramirez-Ortiz uint32_t boot_dev, boot_cpu; 2387e532c4bSJorge Ramirez-Ortiz uint32_t lcs, reg, val; 2397e532c4bSJorge Ramirez-Ortiz 2407e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_MODEMR); 2417e532c4bSJorge Ramirez-Ortiz boot_dev = reg & MODEMR_BOOT_DEV_MASK; 2427e532c4bSJorge Ramirez-Ortiz 2437e532c4bSJorge Ramirez-Ortiz if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || 2447e532c4bSJorge Ramirez-Ortiz boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) 2457e532c4bSJorge Ramirez-Ortiz emmc_terminate(); 2467e532c4bSJorge Ramirez-Ortiz 2477e532c4bSJorge Ramirez-Ortiz if ((reg & MODEMR_BOOT_CPU_MASK) != MODEMR_BOOT_CPU_CR7) 2487e532c4bSJorge Ramirez-Ortiz bl2_secure_setting(); 2497e532c4bSJorge Ramirez-Ortiz 2507e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_PRR); 251df51d8feSMarek Vasut product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 252df51d8feSMarek Vasut product = reg & PRR_PRODUCT_MASK; 253df51d8feSMarek Vasut cut = reg & PRR_CUT_MASK; 2547e532c4bSJorge Ramirez-Ortiz 255df51d8feSMarek Vasut if (product == PRR_PRODUCT_M3 && PRR_PRODUCT_30 > cut) 2567e532c4bSJorge Ramirez-Ortiz goto tlb; 2577e532c4bSJorge Ramirez-Ortiz 258df51d8feSMarek Vasut if (product == PRR_PRODUCT_H3 && PRR_PRODUCT_20 > cut) 2597e532c4bSJorge Ramirez-Ortiz goto tlb; 2607e532c4bSJorge Ramirez-Ortiz 261df51d8feSMarek Vasut if (product == PRR_PRODUCT_D3) 262bfbf5df4SMarek Vasut goto tlb; 263bfbf5df4SMarek Vasut 2647e532c4bSJorge Ramirez-Ortiz /* Disable MFIS write protection */ 2657e532c4bSJorge Ramirez-Ortiz mmio_write_32(MFISWPCNTR, MFISWPCNTR_PASSWORD | 1); 2667e532c4bSJorge Ramirez-Ortiz 2677e532c4bSJorge Ramirez-Ortiz tlb: 2687e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_MODEMR); 2697e532c4bSJorge Ramirez-Ortiz boot_cpu = reg & MODEMR_BOOT_CPU_MASK; 2707e532c4bSJorge Ramirez-Ortiz if (boot_cpu != MODEMR_BOOT_CPU_CA57 && 2717e532c4bSJorge Ramirez-Ortiz boot_cpu != MODEMR_BOOT_CPU_CA53) 2727e532c4bSJorge Ramirez-Ortiz goto mmu; 2737e532c4bSJorge Ramirez-Ortiz 274df51d8feSMarek Vasut if (product_cut == PRR_PRODUCT_H3_CUT20) { 2757e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); 2767e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUVI1_IMSCTLR, IMSCTLR_DISCACHE); 2777e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); 2787e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV1_IMSCTLR, IMSCTLR_DISCACHE); 2797e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV2_IMSCTLR, IMSCTLR_DISCACHE); 2807e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV3_IMSCTLR, IMSCTLR_DISCACHE); 281df51d8feSMarek Vasut } else if (product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) || 282df51d8feSMarek Vasut product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11)) { 2837e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); 2847e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); 285df51d8feSMarek Vasut } else if ((product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) || 286df51d8feSMarek Vasut (product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_11))) { 2877e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); 28832385427SMarek Vasut mmio_write_32(IPMMUVP0_IMSCTLR, IMSCTLR_DISCACHE); 2897e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); 2907e532c4bSJorge Ramirez-Ortiz } 2917e532c4bSJorge Ramirez-Ortiz 292df51d8feSMarek Vasut if (product_cut == (PRR_PRODUCT_H3_CUT20) || 293df51d8feSMarek Vasut product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) || 294df51d8feSMarek Vasut product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11) || 295df51d8feSMarek Vasut product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) { 2967e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUHC_IMSCTLR, IMSCTLR_DISCACHE); 2977e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMURT_IMSCTLR, IMSCTLR_DISCACHE); 2987e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUMP_IMSCTLR, IMSCTLR_DISCACHE); 2997e532c4bSJorge Ramirez-Ortiz 3007e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUDS0_IMSCTLR, IMSCTLR_DISCACHE); 3017e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUDS1_IMSCTLR, IMSCTLR_DISCACHE); 3027e532c4bSJorge Ramirez-Ortiz } 3037e532c4bSJorge Ramirez-Ortiz 3047e532c4bSJorge Ramirez-Ortiz mmu: 3057e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUMM_IMSCTLR, IPMMUMM_IMSCTLR_ENABLE); 3067e532c4bSJorge Ramirez-Ortiz mmio_write_32(IPMMUMM_IMAUXCTLR, IPMMUMM_IMAUXCTLR_NMERGE40_BIT); 3077e532c4bSJorge Ramirez-Ortiz 3087e532c4bSJorge Ramirez-Ortiz val = rcar_rom_get_lcs(&lcs); 3097e532c4bSJorge Ramirez-Ortiz if (val) { 3107e532c4bSJorge Ramirez-Ortiz ERROR("BL2: Failed to get the LCS. (%d)\n", val); 3117e532c4bSJorge Ramirez-Ortiz panic(); 3127e532c4bSJorge Ramirez-Ortiz } 3137e532c4bSJorge Ramirez-Ortiz 3147e532c4bSJorge Ramirez-Ortiz if (lcs == LCS_SE) 3157e532c4bSJorge Ramirez-Ortiz mmio_clrbits_32(P_ARMREG_SEC_CTRL, P_ARMREG_SEC_CTRL_PROT); 3167e532c4bSJorge Ramirez-Ortiz 3177e532c4bSJorge Ramirez-Ortiz rcar_swdt_release(); 3187e532c4bSJorge Ramirez-Ortiz bl2_system_cpg_init(); 3197e532c4bSJorge Ramirez-Ortiz 3207e532c4bSJorge Ramirez-Ortiz #if RCAR_BL2_DCACHE == 1 3217e532c4bSJorge Ramirez-Ortiz /* Disable data cache (clean and invalidate) */ 3227e532c4bSJorge Ramirez-Ortiz disable_mmu_el3(); 3237e532c4bSJorge Ramirez-Ortiz #endif 3247e532c4bSJorge Ramirez-Ortiz } 3257e532c4bSJorge Ramirez-Ortiz 3267e532c4bSJorge Ramirez-Ortiz static uint32_t is_ddr_backup_mode(void) 3277e532c4bSJorge Ramirez-Ortiz { 3287e532c4bSJorge Ramirez-Ortiz #if RCAR_SYSTEM_SUSPEND 3297e532c4bSJorge Ramirez-Ortiz static uint32_t reason = RCAR_COLD_BOOT; 3307e532c4bSJorge Ramirez-Ortiz static uint32_t once; 3317e532c4bSJorge Ramirez-Ortiz 3327e532c4bSJorge Ramirez-Ortiz #if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR 3337e532c4bSJorge Ramirez-Ortiz uint8_t data; 3347e532c4bSJorge Ramirez-Ortiz #endif 3357e532c4bSJorge Ramirez-Ortiz if (once) 3367e532c4bSJorge Ramirez-Ortiz return reason; 3377e532c4bSJorge Ramirez-Ortiz 3387e532c4bSJorge Ramirez-Ortiz once = 1; 3397e532c4bSJorge Ramirez-Ortiz if ((mmio_read_32(GPIO_INDT) & GPIO_BKUP_TRG_SHIFT) == 0) 3407e532c4bSJorge Ramirez-Ortiz return reason; 3417e532c4bSJorge Ramirez-Ortiz 3427e532c4bSJorge Ramirez-Ortiz #if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR 3437e532c4bSJorge Ramirez-Ortiz if (rcar_iic_dvfs_receive(PMIC, REG_KEEP10, &data)) { 3447e532c4bSJorge Ramirez-Ortiz ERROR("BL2: REG Keep10 READ ERROR.\n"); 3457e532c4bSJorge Ramirez-Ortiz panic(); 3467e532c4bSJorge Ramirez-Ortiz } 3477e532c4bSJorge Ramirez-Ortiz 3487e532c4bSJorge Ramirez-Ortiz if (KEEP10_MAGIC != data) 3497e532c4bSJorge Ramirez-Ortiz reason = RCAR_WARM_BOOT; 3507e532c4bSJorge Ramirez-Ortiz #else 3517e532c4bSJorge Ramirez-Ortiz reason = RCAR_WARM_BOOT; 3527e532c4bSJorge Ramirez-Ortiz #endif 3537e532c4bSJorge Ramirez-Ortiz return reason; 3547e532c4bSJorge Ramirez-Ortiz #else 3557e532c4bSJorge Ramirez-Ortiz return RCAR_COLD_BOOT; 3567e532c4bSJorge Ramirez-Ortiz #endif 3577e532c4bSJorge Ramirez-Ortiz } 3587e532c4bSJorge Ramirez-Ortiz 3597e532c4bSJorge Ramirez-Ortiz int bl2_plat_handle_pre_image_load(unsigned int image_id) 3607e532c4bSJorge Ramirez-Ortiz { 3617e532c4bSJorge Ramirez-Ortiz u_register_t *boot_kind = (void *) BOOT_KIND_BASE; 3627e532c4bSJorge Ramirez-Ortiz bl_mem_params_node_t *bl_mem_params; 3637e532c4bSJorge Ramirez-Ortiz 3647e532c4bSJorge Ramirez-Ortiz if (image_id != BL31_IMAGE_ID) 3657e532c4bSJorge Ramirez-Ortiz return 0; 3667e532c4bSJorge Ramirez-Ortiz 3677e532c4bSJorge Ramirez-Ortiz bl_mem_params = get_bl_mem_params_node(image_id); 3687e532c4bSJorge Ramirez-Ortiz 3697e532c4bSJorge Ramirez-Ortiz if (is_ddr_backup_mode() == RCAR_COLD_BOOT) 3707e532c4bSJorge Ramirez-Ortiz goto cold_boot; 3717e532c4bSJorge Ramirez-Ortiz 3727e532c4bSJorge Ramirez-Ortiz *boot_kind = RCAR_WARM_BOOT; 3737e532c4bSJorge Ramirez-Ortiz flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind)); 3747e532c4bSJorge Ramirez-Ortiz 3757e532c4bSJorge Ramirez-Ortiz console_flush(); 3767e532c4bSJorge Ramirez-Ortiz bl2_plat_flush_bl31_params(); 3777e532c4bSJorge Ramirez-Ortiz 3787e532c4bSJorge Ramirez-Ortiz /* will not return */ 3797e532c4bSJorge Ramirez-Ortiz bl2_enter_bl31(&bl_mem_params->ep_info); 3807e532c4bSJorge Ramirez-Ortiz 3817e532c4bSJorge Ramirez-Ortiz cold_boot: 3827e532c4bSJorge Ramirez-Ortiz *boot_kind = RCAR_COLD_BOOT; 3837e532c4bSJorge Ramirez-Ortiz flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind)); 3847e532c4bSJorge Ramirez-Ortiz 3857e532c4bSJorge Ramirez-Ortiz return 0; 3867e532c4bSJorge Ramirez-Ortiz } 3877e532c4bSJorge Ramirez-Ortiz 388*13856f37SToshiyuki Ogasahara static uint64_t rcar_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest) 389*13856f37SToshiyuki Ogasahara { 390*13856f37SToshiyuki Ogasahara uint32_t cert, len; 391*13856f37SToshiyuki Ogasahara int ret; 392*13856f37SToshiyuki Ogasahara 393*13856f37SToshiyuki Ogasahara ret = rcar_get_certificate(certid, &cert); 394*13856f37SToshiyuki Ogasahara if (ret) { 395*13856f37SToshiyuki Ogasahara ERROR("%s : cert file load error", __func__); 396*13856f37SToshiyuki Ogasahara return 1; 397*13856f37SToshiyuki Ogasahara } 398*13856f37SToshiyuki Ogasahara 399*13856f37SToshiyuki Ogasahara rcar_read_certificate((uint64_t) cert, &len, dest); 400*13856f37SToshiyuki Ogasahara 401*13856f37SToshiyuki Ogasahara return 0; 402*13856f37SToshiyuki Ogasahara } 403*13856f37SToshiyuki Ogasahara 4047e532c4bSJorge Ramirez-Ortiz int bl2_plat_handle_post_image_load(unsigned int image_id) 4057e532c4bSJorge Ramirez-Ortiz { 4067e532c4bSJorge Ramirez-Ortiz static bl2_to_bl31_params_mem_t *params; 4077e532c4bSJorge Ramirez-Ortiz bl_mem_params_node_t *bl_mem_params; 408*13856f37SToshiyuki Ogasahara uintptr_t dest; 409*13856f37SToshiyuki Ogasahara int ret; 4107e532c4bSJorge Ramirez-Ortiz 4117e532c4bSJorge Ramirez-Ortiz if (!params) { 4127e532c4bSJorge Ramirez-Ortiz params = (bl2_to_bl31_params_mem_t *) PARAMS_BASE; 4137e532c4bSJorge Ramirez-Ortiz memset((void *)PARAMS_BASE, 0, sizeof(*params)); 4147e532c4bSJorge Ramirez-Ortiz } 4157e532c4bSJorge Ramirez-Ortiz 4167e532c4bSJorge Ramirez-Ortiz bl_mem_params = get_bl_mem_params_node(image_id); 4177e532c4bSJorge Ramirez-Ortiz 4187e532c4bSJorge Ramirez-Ortiz switch (image_id) { 4197e532c4bSJorge Ramirez-Ortiz case BL31_IMAGE_ID: 420*13856f37SToshiyuki Ogasahara ret = rcar_get_dest_addr_from_cert(SOC_FW_CONTENT_CERT_ID, 421*13856f37SToshiyuki Ogasahara &dest); 422*13856f37SToshiyuki Ogasahara if (!ret) 423*13856f37SToshiyuki Ogasahara bl_mem_params->image_info.image_base = dest; 4247e532c4bSJorge Ramirez-Ortiz break; 4257e532c4bSJorge Ramirez-Ortiz case BL32_IMAGE_ID: 426*13856f37SToshiyuki Ogasahara ret = rcar_get_dest_addr_from_cert(TRUSTED_OS_FW_CONTENT_CERT_ID, 427*13856f37SToshiyuki Ogasahara &dest); 428*13856f37SToshiyuki Ogasahara if (!ret) 429*13856f37SToshiyuki Ogasahara bl_mem_params->image_info.image_base = dest; 430*13856f37SToshiyuki Ogasahara 4317e532c4bSJorge Ramirez-Ortiz memcpy(¶ms->bl32_ep_info, &bl_mem_params->ep_info, 4327e532c4bSJorge Ramirez-Ortiz sizeof(entry_point_info_t)); 4337e532c4bSJorge Ramirez-Ortiz break; 4347e532c4bSJorge Ramirez-Ortiz case BL33_IMAGE_ID: 4357e532c4bSJorge Ramirez-Ortiz memcpy(¶ms->bl33_ep_info, &bl_mem_params->ep_info, 4367e532c4bSJorge Ramirez-Ortiz sizeof(entry_point_info_t)); 4377e532c4bSJorge Ramirez-Ortiz break; 4387e532c4bSJorge Ramirez-Ortiz } 4397e532c4bSJorge Ramirez-Ortiz 4407e532c4bSJorge Ramirez-Ortiz return 0; 4417e532c4bSJorge Ramirez-Ortiz } 4427e532c4bSJorge Ramirez-Ortiz 443db9a1555SMarek Vasut struct meminfo *bl2_plat_sec_mem_layout(void) 4447e532c4bSJorge Ramirez-Ortiz { 4457e532c4bSJorge Ramirez-Ortiz return &bl2_tzram_layout; 4467e532c4bSJorge Ramirez-Ortiz } 4477e532c4bSJorge Ramirez-Ortiz 448b7f6525dSJustin Chadwell static void bl2_populate_compatible_string(void *dt) 449ac49c5fbSMarek Vasut { 450ac49c5fbSMarek Vasut uint32_t board_type; 451ac49c5fbSMarek Vasut uint32_t board_rev; 452ac49c5fbSMarek Vasut uint32_t reg; 453ac49c5fbSMarek Vasut int ret; 454ac49c5fbSMarek Vasut 4556be71b09SMarek Vasut fdt_setprop_u32(dt, 0, "#address-cells", 2); 4566be71b09SMarek Vasut fdt_setprop_u32(dt, 0, "#size-cells", 2); 4576be71b09SMarek Vasut 458ac49c5fbSMarek Vasut /* Populate compatible string */ 459ac49c5fbSMarek Vasut rcar_get_board_type(&board_type, &board_rev); 460ac49c5fbSMarek Vasut switch (board_type) { 461ac49c5fbSMarek Vasut case BOARD_SALVATOR_X: 462b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 463ac49c5fbSMarek Vasut "renesas,salvator-x"); 464ac49c5fbSMarek Vasut break; 465ac49c5fbSMarek Vasut case BOARD_SALVATOR_XS: 466b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 467ac49c5fbSMarek Vasut "renesas,salvator-xs"); 468ac49c5fbSMarek Vasut break; 469ac49c5fbSMarek Vasut case BOARD_STARTER_KIT: 470b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 471ac49c5fbSMarek Vasut "renesas,m3ulcb"); 472ac49c5fbSMarek Vasut break; 473ac49c5fbSMarek Vasut case BOARD_STARTER_KIT_PRE: 474b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 475ac49c5fbSMarek Vasut "renesas,h3ulcb"); 476ac49c5fbSMarek Vasut break; 477b709fe9cSValentine Barshak case BOARD_EAGLE: 478b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 479b709fe9cSValentine Barshak "renesas,eagle"); 480b709fe9cSValentine Barshak break; 481ac49c5fbSMarek Vasut case BOARD_EBISU: 482ac49c5fbSMarek Vasut case BOARD_EBISU_4D: 483b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 484ac49c5fbSMarek Vasut "renesas,ebisu"); 485ac49c5fbSMarek Vasut break; 486bfbf5df4SMarek Vasut case BOARD_DRAAK: 487b7f6525dSJustin Chadwell ret = fdt_setprop_string(dt, 0, "compatible", 488bfbf5df4SMarek Vasut "renesas,draak"); 489bfbf5df4SMarek Vasut break; 490ac49c5fbSMarek Vasut default: 491ac49c5fbSMarek Vasut NOTICE("BL2: Cannot set compatible string, board unsupported\n"); 492ac49c5fbSMarek Vasut panic(); 493ac49c5fbSMarek Vasut } 494ac49c5fbSMarek Vasut 495ac49c5fbSMarek Vasut if (ret < 0) { 496ac49c5fbSMarek Vasut NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret); 497ac49c5fbSMarek Vasut panic(); 498ac49c5fbSMarek Vasut } 499ac49c5fbSMarek Vasut 500ac49c5fbSMarek Vasut reg = mmio_read_32(RCAR_PRR); 501df51d8feSMarek Vasut switch (reg & PRR_PRODUCT_MASK) { 502df51d8feSMarek Vasut case PRR_PRODUCT_H3: 503b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 504ac49c5fbSMarek Vasut "renesas,r8a7795"); 505ac49c5fbSMarek Vasut break; 506df51d8feSMarek Vasut case PRR_PRODUCT_M3: 507b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 508ac49c5fbSMarek Vasut "renesas,r8a7796"); 509ac49c5fbSMarek Vasut break; 510df51d8feSMarek Vasut case PRR_PRODUCT_M3N: 511b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 512ac49c5fbSMarek Vasut "renesas,r8a77965"); 513ac49c5fbSMarek Vasut break; 514df51d8feSMarek Vasut case PRR_PRODUCT_V3M: 515b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 516b709fe9cSValentine Barshak "renesas,r8a77970"); 517b709fe9cSValentine Barshak break; 518df51d8feSMarek Vasut case PRR_PRODUCT_E3: 519b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 520ac49c5fbSMarek Vasut "renesas,r8a77990"); 521ac49c5fbSMarek Vasut break; 522df51d8feSMarek Vasut case PRR_PRODUCT_D3: 523b7f6525dSJustin Chadwell ret = fdt_appendprop_string(dt, 0, "compatible", 524bfbf5df4SMarek Vasut "renesas,r8a77995"); 525bfbf5df4SMarek Vasut break; 526ac49c5fbSMarek Vasut default: 527ac49c5fbSMarek Vasut NOTICE("BL2: Cannot set compatible string, SoC unsupported\n"); 528ac49c5fbSMarek Vasut panic(); 529ac49c5fbSMarek Vasut } 530ac49c5fbSMarek Vasut 531ac49c5fbSMarek Vasut if (ret < 0) { 532ac49c5fbSMarek Vasut NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret); 533ac49c5fbSMarek Vasut panic(); 534ac49c5fbSMarek Vasut } 535ac49c5fbSMarek Vasut } 536ac49c5fbSMarek Vasut 53785185151SMarek Vasut static void bl2_advertise_dram_entries(uint64_t dram_config[8]) 53885185151SMarek Vasut { 5391d85c4bdSMarek Vasut char nodename[32] = { 0 }; 54085185151SMarek Vasut uint64_t start, size; 5411d85c4bdSMarek Vasut uint64_t fdtsize; 5421d85c4bdSMarek Vasut int ret, node, chan; 54385185151SMarek Vasut 54485185151SMarek Vasut for (chan = 0; chan < 4; chan++) { 54585185151SMarek Vasut start = dram_config[2 * chan]; 54685185151SMarek Vasut size = dram_config[2 * chan + 1]; 54785185151SMarek Vasut if (!size) 54885185151SMarek Vasut continue; 54985185151SMarek Vasut 5505b4f022bSMarek Vasut NOTICE("BL2: CH%d: %llx - %llx, %lld %siB\n", 5515b4f022bSMarek Vasut chan, start, start + size - 1, 5525b4f022bSMarek Vasut (size >> 30) ? : size >> 20, 5535b4f022bSMarek Vasut (size >> 30) ? "G" : "M"); 55485185151SMarek Vasut } 5551d85c4bdSMarek Vasut 5561d85c4bdSMarek Vasut /* 5571d85c4bdSMarek Vasut * We add the DT nodes in reverse order here. The fdt_add_subnode() 5581d85c4bdSMarek Vasut * adds the DT node before the first existing DT node, so we have 5591d85c4bdSMarek Vasut * to add them in reverse order to get nodes sorted by address in 5601d85c4bdSMarek Vasut * the resulting DT. 5611d85c4bdSMarek Vasut */ 5621d85c4bdSMarek Vasut for (chan = 3; chan >= 0; chan--) { 5631d85c4bdSMarek Vasut start = dram_config[2 * chan]; 5641d85c4bdSMarek Vasut size = dram_config[2 * chan + 1]; 5651d85c4bdSMarek Vasut if (!size) 5661d85c4bdSMarek Vasut continue; 5671d85c4bdSMarek Vasut 5681d85c4bdSMarek Vasut /* 5691d85c4bdSMarek Vasut * Channel 0 is mapped in 32bit space and the first 5701d85c4bdSMarek Vasut * 128 MiB are reserved 5711d85c4bdSMarek Vasut */ 5721d85c4bdSMarek Vasut if (chan == 0) { 5731d85c4bdSMarek Vasut start = 0x48000000; 5741d85c4bdSMarek Vasut size -= 0x8000000; 5751d85c4bdSMarek Vasut } 5761d85c4bdSMarek Vasut 5771d85c4bdSMarek Vasut fdtsize = cpu_to_fdt64(size); 5781d85c4bdSMarek Vasut 5791d85c4bdSMarek Vasut snprintf(nodename, sizeof(nodename), "memory@"); 5801d85c4bdSMarek Vasut unsigned_num_print(start, 16, nodename + strlen(nodename)); 5811d85c4bdSMarek Vasut node = ret = fdt_add_subnode(fdt, 0, nodename); 5821d85c4bdSMarek Vasut if (ret < 0) 5831d85c4bdSMarek Vasut goto err; 5841d85c4bdSMarek Vasut 5851d85c4bdSMarek Vasut ret = fdt_setprop_string(fdt, node, "device_type", "memory"); 5861d85c4bdSMarek Vasut if (ret < 0) 5871d85c4bdSMarek Vasut goto err; 5881d85c4bdSMarek Vasut 5891d85c4bdSMarek Vasut ret = fdt_setprop_u64(fdt, node, "reg", start); 5901d85c4bdSMarek Vasut if (ret < 0) 5911d85c4bdSMarek Vasut goto err; 5921d85c4bdSMarek Vasut 5931d85c4bdSMarek Vasut ret = fdt_appendprop(fdt, node, "reg", &fdtsize, 5941d85c4bdSMarek Vasut sizeof(fdtsize)); 5951d85c4bdSMarek Vasut if (ret < 0) 5961d85c4bdSMarek Vasut goto err; 5971d85c4bdSMarek Vasut } 5981d85c4bdSMarek Vasut 5991d85c4bdSMarek Vasut return; 6001d85c4bdSMarek Vasut err: 6011d85c4bdSMarek Vasut NOTICE("BL2: Cannot add memory node to FDT (ret=%i)\n", ret); 6021d85c4bdSMarek Vasut panic(); 60385185151SMarek Vasut } 60485185151SMarek Vasut 6057bf24ae3SMarek Vasut static void bl2_advertise_dram_size(uint32_t product) 606358ed930SMarek Vasut { 60785185151SMarek Vasut uint64_t dram_config[8] = { 60885185151SMarek Vasut [0] = 0x400000000ULL, 60985185151SMarek Vasut [2] = 0x500000000ULL, 61085185151SMarek Vasut [4] = 0x600000000ULL, 61185185151SMarek Vasut [6] = 0x700000000ULL, 61285185151SMarek Vasut }; 61385185151SMarek Vasut 614e1eddfeaSMarek Vasut switch (product) { 615df51d8feSMarek Vasut case PRR_PRODUCT_H3: 616358ed930SMarek Vasut #if (RCAR_DRAM_LPDDR4_MEMCONF == 0) 617358ed930SMarek Vasut /* 4GB(1GBx4) */ 61885185151SMarek Vasut dram_config[1] = 0x40000000ULL; 61985185151SMarek Vasut dram_config[3] = 0x40000000ULL; 62085185151SMarek Vasut dram_config[5] = 0x40000000ULL; 62185185151SMarek Vasut dram_config[7] = 0x40000000ULL; 622358ed930SMarek Vasut #elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && \ 623358ed930SMarek Vasut (RCAR_DRAM_CHANNEL == 5) && \ 624358ed930SMarek Vasut (RCAR_DRAM_SPLIT == 2) 625358ed930SMarek Vasut /* 4GB(2GBx2 2ch split) */ 62685185151SMarek Vasut dram_config[1] = 0x80000000ULL; 62785185151SMarek Vasut dram_config[3] = 0x80000000ULL; 628358ed930SMarek Vasut #elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && (RCAR_DRAM_CHANNEL == 15) 629358ed930SMarek Vasut /* 8GB(2GBx4: default) */ 63085185151SMarek Vasut dram_config[1] = 0x80000000ULL; 63185185151SMarek Vasut dram_config[3] = 0x80000000ULL; 63285185151SMarek Vasut dram_config[5] = 0x80000000ULL; 63385185151SMarek Vasut dram_config[7] = 0x80000000ULL; 634358ed930SMarek Vasut #endif /* RCAR_DRAM_LPDDR4_MEMCONF == 0 */ 635e1eddfeaSMarek Vasut break; 636358ed930SMarek Vasut 637df51d8feSMarek Vasut case PRR_PRODUCT_M3: 6385a21f313SMarek Vasut #if (RCAR_GEN3_ULCB == 1) 6395a21f313SMarek Vasut /* 2GB(1GBx2 2ch split) */ 6405a21f313SMarek Vasut dram_config[1] = 0x40000000ULL; 6415a21f313SMarek Vasut dram_config[5] = 0x40000000ULL; 6425a21f313SMarek Vasut #else 643e1eddfeaSMarek Vasut /* 4GB(2GBx2 2ch split) */ 64485185151SMarek Vasut dram_config[1] = 0x80000000ULL; 64585185151SMarek Vasut dram_config[5] = 0x80000000ULL; 6465a21f313SMarek Vasut #endif 647e1eddfeaSMarek Vasut break; 648e1eddfeaSMarek Vasut 649df51d8feSMarek Vasut case PRR_PRODUCT_M3N: 650e1eddfeaSMarek Vasut /* 2GB(1GBx2) */ 65185185151SMarek Vasut dram_config[1] = 0x80000000ULL; 652e1eddfeaSMarek Vasut break; 653e1eddfeaSMarek Vasut 654df51d8feSMarek Vasut case PRR_PRODUCT_V3M: 655b709fe9cSValentine Barshak /* 1GB(512MBx2) */ 656b709fe9cSValentine Barshak dram_config[1] = 0x40000000ULL; 657b709fe9cSValentine Barshak break; 658b709fe9cSValentine Barshak 659df51d8feSMarek Vasut case PRR_PRODUCT_E3: 660358ed930SMarek Vasut #if (RCAR_DRAM_DDR3L_MEMCONF == 0) 661358ed930SMarek Vasut /* 1GB(512MBx2) */ 66285185151SMarek Vasut dram_config[1] = 0x40000000ULL; 663358ed930SMarek Vasut #elif (RCAR_DRAM_DDR3L_MEMCONF == 1) 664358ed930SMarek Vasut /* 2GB(512MBx4) */ 66585185151SMarek Vasut dram_config[1] = 0x80000000ULL; 6663b507aabSMarek Vasut #elif (RCAR_DRAM_DDR3L_MEMCONF == 2) 6673b507aabSMarek Vasut /* 4GB(1GBx4) */ 66885185151SMarek Vasut dram_config[1] = 0x100000000ULL; 669358ed930SMarek Vasut #endif /* RCAR_DRAM_DDR3L_MEMCONF == 0 */ 670e1eddfeaSMarek Vasut break; 671bfbf5df4SMarek Vasut 672df51d8feSMarek Vasut case PRR_PRODUCT_D3: 673bfbf5df4SMarek Vasut /* 512MB */ 674bfbf5df4SMarek Vasut dram_config[1] = 0x20000000ULL; 675bfbf5df4SMarek Vasut break; 676358ed930SMarek Vasut } 67785185151SMarek Vasut 67885185151SMarek Vasut bl2_advertise_dram_entries(dram_config); 679358ed930SMarek Vasut } 680358ed930SMarek Vasut 6817e532c4bSJorge Ramirez-Ortiz void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, 6827e532c4bSJorge Ramirez-Ortiz u_register_t arg3, u_register_t arg4) 6837e532c4bSJorge Ramirez-Ortiz { 6847e532c4bSJorge Ramirez-Ortiz uint32_t reg, midr, lcs, boot_dev, boot_cpu, sscg, type, rev; 6857bf24ae3SMarek Vasut uint32_t product, product_cut, major, minor; 6867e532c4bSJorge Ramirez-Ortiz int32_t ret; 6877e532c4bSJorge Ramirez-Ortiz const char *str; 6887e532c4bSJorge Ramirez-Ortiz const char *unknown = "unknown"; 6897e532c4bSJorge Ramirez-Ortiz const char *cpu_ca57 = "CA57"; 6907e532c4bSJorge Ramirez-Ortiz const char *cpu_ca53 = "CA53"; 6917e532c4bSJorge Ramirez-Ortiz const char *product_m3n = "M3N"; 6927e532c4bSJorge Ramirez-Ortiz const char *product_h3 = "H3"; 6937e532c4bSJorge Ramirez-Ortiz const char *product_m3 = "M3"; 6947e532c4bSJorge Ramirez-Ortiz const char *product_e3 = "E3"; 695bfbf5df4SMarek Vasut const char *product_d3 = "D3"; 696b709fe9cSValentine Barshak const char *product_v3m = "V3M"; 6977e532c4bSJorge Ramirez-Ortiz const char *lcs_secure = "SE"; 6987e532c4bSJorge Ramirez-Ortiz const char *lcs_cm = "CM"; 6997e532c4bSJorge Ramirez-Ortiz const char *lcs_dm = "DM"; 7007e532c4bSJorge Ramirez-Ortiz const char *lcs_sd = "SD"; 7017e532c4bSJorge Ramirez-Ortiz const char *lcs_fa = "FA"; 7027e532c4bSJorge Ramirez-Ortiz const char *sscg_off = "PLL1 nonSSCG Clock select"; 7037e532c4bSJorge Ramirez-Ortiz const char *sscg_on = "PLL1 SSCG Clock select"; 7047e532c4bSJorge Ramirez-Ortiz const char *boot_hyper80 = "HyperFlash(80MHz)"; 7057e532c4bSJorge Ramirez-Ortiz const char *boot_qspi40 = "QSPI Flash(40MHz)"; 7067e532c4bSJorge Ramirez-Ortiz const char *boot_qspi80 = "QSPI Flash(80MHz)"; 7077e532c4bSJorge Ramirez-Ortiz const char *boot_emmc25x1 = "eMMC(25MHz x1)"; 7087e532c4bSJorge Ramirez-Ortiz const char *boot_emmc50x8 = "eMMC(50MHz x8)"; 709bfbf5df4SMarek Vasut #if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3) 7107e532c4bSJorge Ramirez-Ortiz const char *boot_hyper160 = "HyperFlash(150MHz)"; 7117e532c4bSJorge Ramirez-Ortiz #else 7127e532c4bSJorge Ramirez-Ortiz const char *boot_hyper160 = "HyperFlash(160MHz)"; 7137e532c4bSJorge Ramirez-Ortiz #endif 714a6de3db7SMarek Vasut #if (RCAR_LOSSY_ENABLE == 1) 715a6de3db7SMarek Vasut int fcnlnode; 716a6de3db7SMarek Vasut #endif 7177e532c4bSJorge Ramirez-Ortiz 71847141b73SMarek Vasut bl2_init_generic_timer(); 71947141b73SMarek Vasut 7207e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_MODEMR); 7217e532c4bSJorge Ramirez-Ortiz boot_dev = reg & MODEMR_BOOT_DEV_MASK; 7227e532c4bSJorge Ramirez-Ortiz boot_cpu = reg & MODEMR_BOOT_CPU_MASK; 7237e532c4bSJorge Ramirez-Ortiz 7247e532c4bSJorge Ramirez-Ortiz bl2_cpg_init(); 7257e532c4bSJorge Ramirez-Ortiz 7267e532c4bSJorge Ramirez-Ortiz if (boot_cpu == MODEMR_BOOT_CPU_CA57 || 7277e532c4bSJorge Ramirez-Ortiz boot_cpu == MODEMR_BOOT_CPU_CA53) { 7287e532c4bSJorge Ramirez-Ortiz rcar_pfc_init(); 729018358fcSMarek Vasut rcar_console_boot_init(); 7307e532c4bSJorge Ramirez-Ortiz } 7317e532c4bSJorge Ramirez-Ortiz 7327e532c4bSJorge Ramirez-Ortiz plat_rcar_gic_driver_init(); 7337e532c4bSJorge Ramirez-Ortiz plat_rcar_gic_init(); 7347e532c4bSJorge Ramirez-Ortiz rcar_swdt_init(); 7357e532c4bSJorge Ramirez-Ortiz 7367e532c4bSJorge Ramirez-Ortiz /* FIQ interrupts are taken to EL3 */ 7377e532c4bSJorge Ramirez-Ortiz write_scr_el3(read_scr_el3() | SCR_FIQ_BIT); 7387e532c4bSJorge Ramirez-Ortiz 7397e532c4bSJorge Ramirez-Ortiz write_daifclr(DAIF_FIQ_BIT); 7407e532c4bSJorge Ramirez-Ortiz 7417e532c4bSJorge Ramirez-Ortiz reg = read_midr(); 7427e532c4bSJorge Ramirez-Ortiz midr = reg & (MIDR_PN_MASK << MIDR_PN_SHIFT); 7437e532c4bSJorge Ramirez-Ortiz switch (midr) { 7447e532c4bSJorge Ramirez-Ortiz case MIDR_CA57: 7457e532c4bSJorge Ramirez-Ortiz str = cpu_ca57; 7467e532c4bSJorge Ramirez-Ortiz break; 7477e532c4bSJorge Ramirez-Ortiz case MIDR_CA53: 7487e532c4bSJorge Ramirez-Ortiz str = cpu_ca53; 7497e532c4bSJorge Ramirez-Ortiz break; 7507e532c4bSJorge Ramirez-Ortiz default: 7517e532c4bSJorge Ramirez-Ortiz str = unknown; 7527e532c4bSJorge Ramirez-Ortiz break; 7537e532c4bSJorge Ramirez-Ortiz } 7547e532c4bSJorge Ramirez-Ortiz 7557e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: R-Car Gen3 Initial Program Loader(%s) Rev.%s\n", str, 7567e532c4bSJorge Ramirez-Ortiz version_of_renesas); 7577e532c4bSJorge Ramirez-Ortiz 7587e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_PRR); 759df51d8feSMarek Vasut product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 760df51d8feSMarek Vasut product = reg & PRR_PRODUCT_MASK; 7617e532c4bSJorge Ramirez-Ortiz 7627e532c4bSJorge Ramirez-Ortiz switch (product) { 763df51d8feSMarek Vasut case PRR_PRODUCT_H3: 7647e532c4bSJorge Ramirez-Ortiz str = product_h3; 7657e532c4bSJorge Ramirez-Ortiz break; 766df51d8feSMarek Vasut case PRR_PRODUCT_M3: 7677e532c4bSJorge Ramirez-Ortiz str = product_m3; 7687e532c4bSJorge Ramirez-Ortiz break; 769df51d8feSMarek Vasut case PRR_PRODUCT_M3N: 7707e532c4bSJorge Ramirez-Ortiz str = product_m3n; 7717e532c4bSJorge Ramirez-Ortiz break; 772df51d8feSMarek Vasut case PRR_PRODUCT_V3M: 773b709fe9cSValentine Barshak str = product_v3m; 774b709fe9cSValentine Barshak break; 775df51d8feSMarek Vasut case PRR_PRODUCT_E3: 7767e532c4bSJorge Ramirez-Ortiz str = product_e3; 7777e532c4bSJorge Ramirez-Ortiz break; 778df51d8feSMarek Vasut case PRR_PRODUCT_D3: 779bfbf5df4SMarek Vasut str = product_d3; 780bfbf5df4SMarek Vasut break; 7817e532c4bSJorge Ramirez-Ortiz default: 7827e532c4bSJorge Ramirez-Ortiz str = unknown; 7837e532c4bSJorge Ramirez-Ortiz break; 7847e532c4bSJorge Ramirez-Ortiz } 7857e532c4bSJorge Ramirez-Ortiz 786df51d8feSMarek Vasut if ((PRR_PRODUCT_M3 == product) && 787df51d8feSMarek Vasut (PRR_PRODUCT_20 == (reg & RCAR_MAJOR_MASK))) { 788df51d8feSMarek Vasut if (RCAR_M3_CUT_VER11 == (reg & PRR_CUT_MASK)) { 789845d8fbbSMarek Vasut /* M3 Ver.1.1 or Ver.1.2 */ 790845d8fbbSMarek Vasut NOTICE("BL2: PRR is R-Car %s Ver.1.1 / Ver.1.2\n", 791845d8fbbSMarek Vasut str); 792845d8fbbSMarek Vasut } else { 793845d8fbbSMarek Vasut NOTICE("BL2: PRR is R-Car %s Ver.1.%d\n", 794845d8fbbSMarek Vasut str, 795845d8fbbSMarek Vasut (reg & RCAR_MINOR_MASK) + RCAR_M3_MINOR_OFFSET); 796845d8fbbSMarek Vasut } 7977e532c4bSJorge Ramirez-Ortiz } else { 7987e532c4bSJorge Ramirez-Ortiz major = (reg & RCAR_MAJOR_MASK) >> RCAR_MAJOR_SHIFT; 7997e532c4bSJorge Ramirez-Ortiz major = major + RCAR_MAJOR_OFFSET; 8007e532c4bSJorge Ramirez-Ortiz minor = reg & RCAR_MINOR_MASK; 8017e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: PRR is R-Car %s Ver.%d.%d\n", str, major, minor); 8027e532c4bSJorge Ramirez-Ortiz } 8037e532c4bSJorge Ramirez-Ortiz 804df51d8feSMarek Vasut if (product == PRR_PRODUCT_E3) { 8057e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_MODEMR); 8067e532c4bSJorge Ramirez-Ortiz sscg = reg & RCAR_SSCG_MASK; 8077e532c4bSJorge Ramirez-Ortiz str = sscg == RCAR_SSCG_ENABLE ? sscg_on : sscg_off; 8087e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: %s\n", str); 8097e532c4bSJorge Ramirez-Ortiz } 8107e532c4bSJorge Ramirez-Ortiz 8117e532c4bSJorge Ramirez-Ortiz rcar_get_board_type(&type, &rev); 8127e532c4bSJorge Ramirez-Ortiz 8137e532c4bSJorge Ramirez-Ortiz switch (type) { 8147e532c4bSJorge Ramirez-Ortiz case BOARD_SALVATOR_X: 8157e532c4bSJorge Ramirez-Ortiz case BOARD_KRIEK: 8167e532c4bSJorge Ramirez-Ortiz case BOARD_STARTER_KIT: 8177e532c4bSJorge Ramirez-Ortiz case BOARD_SALVATOR_XS: 8187e532c4bSJorge Ramirez-Ortiz case BOARD_EBISU: 8197e532c4bSJorge Ramirez-Ortiz case BOARD_STARTER_KIT_PRE: 8207e532c4bSJorge Ramirez-Ortiz case BOARD_EBISU_4D: 821bfbf5df4SMarek Vasut case BOARD_DRAAK: 822b709fe9cSValentine Barshak case BOARD_EAGLE: 8237e532c4bSJorge Ramirez-Ortiz break; 8247e532c4bSJorge Ramirez-Ortiz default: 8257e532c4bSJorge Ramirez-Ortiz type = BOARD_UNKNOWN; 8267e532c4bSJorge Ramirez-Ortiz break; 8277e532c4bSJorge Ramirez-Ortiz } 8287e532c4bSJorge Ramirez-Ortiz 8297e532c4bSJorge Ramirez-Ortiz if (type == BOARD_UNKNOWN || rev == BOARD_REV_UNKNOWN) 8307e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Board is %s Rev.---\n", GET_BOARD_NAME(type)); 8317e532c4bSJorge Ramirez-Ortiz else { 8327e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Board is %s Rev.%d.%d\n", 8337e532c4bSJorge Ramirez-Ortiz GET_BOARD_NAME(type), 8347e532c4bSJorge Ramirez-Ortiz GET_BOARD_MAJOR(rev), GET_BOARD_MINOR(rev)); 8357e532c4bSJorge Ramirez-Ortiz } 8367e532c4bSJorge Ramirez-Ortiz 8377e532c4bSJorge Ramirez-Ortiz #if RCAR_LSI != RCAR_AUTO 8387e532c4bSJorge Ramirez-Ortiz if (product != TARGET_PRODUCT) { 8397e532c4bSJorge Ramirez-Ortiz ERROR("BL2: IPL was been built for the %s.\n", TARGET_NAME); 8407e532c4bSJorge Ramirez-Ortiz ERROR("BL2: Please write the correct IPL to flash memory.\n"); 8417e532c4bSJorge Ramirez-Ortiz panic(); 8427e532c4bSJorge Ramirez-Ortiz } 8437e532c4bSJorge Ramirez-Ortiz #endif 8447e532c4bSJorge Ramirez-Ortiz rcar_avs_init(); 8457e532c4bSJorge Ramirez-Ortiz rcar_avs_setting(); 8467e532c4bSJorge Ramirez-Ortiz 8477e532c4bSJorge Ramirez-Ortiz switch (boot_dev) { 8487e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_HYPERFLASH160: 8497e532c4bSJorge Ramirez-Ortiz str = boot_hyper160; 8507e532c4bSJorge Ramirez-Ortiz break; 8517e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_HYPERFLASH80: 8527e532c4bSJorge Ramirez-Ortiz str = boot_hyper80; 8537e532c4bSJorge Ramirez-Ortiz break; 8547e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_QSPI_FLASH40: 8557e532c4bSJorge Ramirez-Ortiz str = boot_qspi40; 8567e532c4bSJorge Ramirez-Ortiz break; 8577e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_QSPI_FLASH80: 8587e532c4bSJorge Ramirez-Ortiz str = boot_qspi80; 8597e532c4bSJorge Ramirez-Ortiz break; 8607e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_EMMC_25X1: 861bfbf5df4SMarek Vasut #if RCAR_LSI == RCAR_D3 862bfbf5df4SMarek Vasut ERROR("BL2: Failed to Initialize. eMMC is not supported.\n"); 863bfbf5df4SMarek Vasut panic(); 864bfbf5df4SMarek Vasut #endif 8657e532c4bSJorge Ramirez-Ortiz str = boot_emmc25x1; 8667e532c4bSJorge Ramirez-Ortiz break; 8677e532c4bSJorge Ramirez-Ortiz case MODEMR_BOOT_DEV_EMMC_50X8: 868bfbf5df4SMarek Vasut #if RCAR_LSI == RCAR_D3 869bfbf5df4SMarek Vasut ERROR("BL2: Failed to Initialize. eMMC is not supported.\n"); 870bfbf5df4SMarek Vasut panic(); 871bfbf5df4SMarek Vasut #endif 8727e532c4bSJorge Ramirez-Ortiz str = boot_emmc50x8; 8737e532c4bSJorge Ramirez-Ortiz break; 8747e532c4bSJorge Ramirez-Ortiz default: 8757e532c4bSJorge Ramirez-Ortiz str = unknown; 8767e532c4bSJorge Ramirez-Ortiz break; 8777e532c4bSJorge Ramirez-Ortiz } 8787e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Boot device is %s\n", str); 8797e532c4bSJorge Ramirez-Ortiz 8807e532c4bSJorge Ramirez-Ortiz rcar_avs_setting(); 8817e532c4bSJorge Ramirez-Ortiz reg = rcar_rom_get_lcs(&lcs); 8827e532c4bSJorge Ramirez-Ortiz if (reg) { 8837e532c4bSJorge Ramirez-Ortiz str = unknown; 8847e532c4bSJorge Ramirez-Ortiz goto lcm_state; 8857e532c4bSJorge Ramirez-Ortiz } 8867e532c4bSJorge Ramirez-Ortiz 8877e532c4bSJorge Ramirez-Ortiz switch (lcs) { 8887e532c4bSJorge Ramirez-Ortiz case LCS_CM: 8897e532c4bSJorge Ramirez-Ortiz str = lcs_cm; 8907e532c4bSJorge Ramirez-Ortiz break; 8917e532c4bSJorge Ramirez-Ortiz case LCS_DM: 8927e532c4bSJorge Ramirez-Ortiz str = lcs_dm; 8937e532c4bSJorge Ramirez-Ortiz break; 8947e532c4bSJorge Ramirez-Ortiz case LCS_SD: 8957e532c4bSJorge Ramirez-Ortiz str = lcs_sd; 8967e532c4bSJorge Ramirez-Ortiz break; 8977e532c4bSJorge Ramirez-Ortiz case LCS_SE: 8987e532c4bSJorge Ramirez-Ortiz str = lcs_secure; 8997e532c4bSJorge Ramirez-Ortiz break; 9007e532c4bSJorge Ramirez-Ortiz case LCS_FA: 9017e532c4bSJorge Ramirez-Ortiz str = lcs_fa; 9027e532c4bSJorge Ramirez-Ortiz break; 9037e532c4bSJorge Ramirez-Ortiz default: 9047e532c4bSJorge Ramirez-Ortiz str = unknown; 9057e532c4bSJorge Ramirez-Ortiz break; 9067e532c4bSJorge Ramirez-Ortiz } 9077e532c4bSJorge Ramirez-Ortiz 9087e532c4bSJorge Ramirez-Ortiz lcm_state: 9097e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: LCM state is %s\n", str); 9107e532c4bSJorge Ramirez-Ortiz 9117e532c4bSJorge Ramirez-Ortiz rcar_avs_end(); 9127e532c4bSJorge Ramirez-Ortiz is_ddr_backup_mode(); 9137e532c4bSJorge Ramirez-Ortiz 9147e532c4bSJorge Ramirez-Ortiz bl2_tzram_layout.total_base = BL31_BASE; 9157e532c4bSJorge Ramirez-Ortiz bl2_tzram_layout.total_size = BL31_LIMIT - BL31_BASE; 9167e532c4bSJorge Ramirez-Ortiz 9177e532c4bSJorge Ramirez-Ortiz if (boot_cpu == MODEMR_BOOT_CPU_CA57 || 9187e532c4bSJorge Ramirez-Ortiz boot_cpu == MODEMR_BOOT_CPU_CA53) { 9197e532c4bSJorge Ramirez-Ortiz ret = rcar_dram_init(); 9207e532c4bSJorge Ramirez-Ortiz if (ret) { 9217e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Failed to DRAM initialize (%d).\n", ret); 9227e532c4bSJorge Ramirez-Ortiz panic(); 9237e532c4bSJorge Ramirez-Ortiz } 9247e532c4bSJorge Ramirez-Ortiz rcar_qos_init(); 9257e532c4bSJorge Ramirez-Ortiz } 9267e532c4bSJorge Ramirez-Ortiz 9271d85c4bdSMarek Vasut /* Set up FDT */ 9281d85c4bdSMarek Vasut ret = fdt_create_empty_tree(fdt, sizeof(fdt_blob)); 9291d85c4bdSMarek Vasut if (ret) { 9301d85c4bdSMarek Vasut NOTICE("BL2: Cannot allocate FDT for U-Boot (ret=%i)\n", ret); 9311d85c4bdSMarek Vasut panic(); 9321d85c4bdSMarek Vasut } 9331d85c4bdSMarek Vasut 934ac49c5fbSMarek Vasut /* Add platform compatible string */ 935ac49c5fbSMarek Vasut bl2_populate_compatible_string(fdt); 936ac49c5fbSMarek Vasut 93710b7a4aeSMarek Vasut /* Print DRAM layout */ 93810b7a4aeSMarek Vasut bl2_advertise_dram_size(product); 93910b7a4aeSMarek Vasut 9407e532c4bSJorge Ramirez-Ortiz if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || 9417e532c4bSJorge Ramirez-Ortiz boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) { 9427e532c4bSJorge Ramirez-Ortiz if (rcar_emmc_init() != EMMC_SUCCESS) { 9437e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Failed to eMMC driver initialize.\n"); 9447e532c4bSJorge Ramirez-Ortiz panic(); 9457e532c4bSJorge Ramirez-Ortiz } 9467e532c4bSJorge Ramirez-Ortiz rcar_emmc_memcard_power(EMMC_POWER_ON); 9477e532c4bSJorge Ramirez-Ortiz if (rcar_emmc_mount() != EMMC_SUCCESS) { 9487e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Failed to eMMC mount operation.\n"); 9497e532c4bSJorge Ramirez-Ortiz panic(); 9507e532c4bSJorge Ramirez-Ortiz } 9517e532c4bSJorge Ramirez-Ortiz } else { 9527e532c4bSJorge Ramirez-Ortiz rcar_rpc_init(); 9537e532c4bSJorge Ramirez-Ortiz rcar_dma_init(); 9547e532c4bSJorge Ramirez-Ortiz } 9557e532c4bSJorge Ramirez-Ortiz 9567e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RST_WDTRSTCR); 9577e532c4bSJorge Ramirez-Ortiz reg &= ~WDTRSTCR_RWDT_RSTMSK; 9587e532c4bSJorge Ramirez-Ortiz reg |= WDTRSTCR_PASSWORD; 9597e532c4bSJorge Ramirez-Ortiz mmio_write_32(RST_WDTRSTCR, reg); 9607e532c4bSJorge Ramirez-Ortiz 9617e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_CPGWPR, CPGWPR_PASSWORD); 9627e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_CPGWPCR, CPGWPCR_PASSWORD); 9637e532c4bSJorge Ramirez-Ortiz 9647e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(RCAR_PRR); 9657e532c4bSJorge Ramirez-Ortiz if ((reg & RCAR_CPU_MASK_CA57) == RCAR_CPU_HAVE_CA57) 9667e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_CA57DBGRCR, 9677e532c4bSJorge Ramirez-Ortiz DBGCPUPREN | mmio_read_32(CPG_CA57DBGRCR)); 9687e532c4bSJorge Ramirez-Ortiz 9697e532c4bSJorge Ramirez-Ortiz if ((reg & RCAR_CPU_MASK_CA53) == RCAR_CPU_HAVE_CA53) 9707e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_CA53DBGRCR, 9717e532c4bSJorge Ramirez-Ortiz DBGCPUPREN | mmio_read_32(CPG_CA53DBGRCR)); 9727e532c4bSJorge Ramirez-Ortiz 973df51d8feSMarek Vasut if (product_cut == PRR_PRODUCT_H3_CUT10) { 9747e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(CPG_PLL2CR); 9757e532c4bSJorge Ramirez-Ortiz reg &= ~((uint32_t) 1 << 5); 9767e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_PLL2CR, reg); 9777e532c4bSJorge Ramirez-Ortiz 9787e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(CPG_PLL4CR); 9797e532c4bSJorge Ramirez-Ortiz reg &= ~((uint32_t) 1 << 5); 9807e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_PLL4CR, reg); 9817e532c4bSJorge Ramirez-Ortiz 9827e532c4bSJorge Ramirez-Ortiz reg = mmio_read_32(CPG_PLL0CR); 9837e532c4bSJorge Ramirez-Ortiz reg &= ~((uint32_t) 1 << 12); 9847e532c4bSJorge Ramirez-Ortiz mmio_write_32(CPG_PLL0CR, reg); 9857e532c4bSJorge Ramirez-Ortiz } 9867e532c4bSJorge Ramirez-Ortiz #if (RCAR_LOSSY_ENABLE == 1) 9877e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: Lossy Decomp areas\n"); 988a6de3db7SMarek Vasut 989a6de3db7SMarek Vasut fcnlnode = fdt_add_subnode(fdt, 0, "reserved-memory"); 990a6de3db7SMarek Vasut if (fcnlnode < 0) { 991a6de3db7SMarek Vasut NOTICE("BL2: Cannot create reserved mem node (ret=%i)\n", 992a6de3db7SMarek Vasut fcnlnode); 993a6de3db7SMarek Vasut panic(); 994a6de3db7SMarek Vasut } 995a6de3db7SMarek Vasut 9967e532c4bSJorge Ramirez-Ortiz bl2_lossy_setting(0, LOSSY_ST_ADDR0, LOSSY_END_ADDR0, 997a6de3db7SMarek Vasut LOSSY_FMT0, LOSSY_ENA_DIS0, fcnlnode); 9987e532c4bSJorge Ramirez-Ortiz bl2_lossy_setting(1, LOSSY_ST_ADDR1, LOSSY_END_ADDR1, 999a6de3db7SMarek Vasut LOSSY_FMT1, LOSSY_ENA_DIS1, fcnlnode); 10007e532c4bSJorge Ramirez-Ortiz bl2_lossy_setting(2, LOSSY_ST_ADDR2, LOSSY_END_ADDR2, 1001a6de3db7SMarek Vasut LOSSY_FMT2, LOSSY_ENA_DIS2, fcnlnode); 10027e532c4bSJorge Ramirez-Ortiz #endif 10037e532c4bSJorge Ramirez-Ortiz 10041d85c4bdSMarek Vasut fdt_pack(fdt); 10051d85c4bdSMarek Vasut NOTICE("BL2: FDT at %p\n", fdt); 10061d85c4bdSMarek Vasut 10077e532c4bSJorge Ramirez-Ortiz if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || 10087e532c4bSJorge Ramirez-Ortiz boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) 10097e532c4bSJorge Ramirez-Ortiz rcar_io_emmc_setup(); 10107e532c4bSJorge Ramirez-Ortiz else 10117e532c4bSJorge Ramirez-Ortiz rcar_io_setup(); 10127e532c4bSJorge Ramirez-Ortiz } 10137e532c4bSJorge Ramirez-Ortiz 10147e532c4bSJorge Ramirez-Ortiz void bl2_el3_plat_arch_setup(void) 10157e532c4bSJorge Ramirez-Ortiz { 10167e532c4bSJorge Ramirez-Ortiz #if RCAR_BL2_DCACHE == 1 10177e532c4bSJorge Ramirez-Ortiz NOTICE("BL2: D-Cache enable\n"); 10187e532c4bSJorge Ramirez-Ortiz rcar_configure_mmu_el3(BL2_BASE, 1019bc5fabd8SMarek Vasut BL2_END - BL2_BASE, 10207e532c4bSJorge Ramirez-Ortiz BL2_RO_BASE, BL2_RO_LIMIT 10217e532c4bSJorge Ramirez-Ortiz #if USE_COHERENT_MEM 10227e532c4bSJorge Ramirez-Ortiz , BL2_COHERENT_RAM_BASE, BL2_COHERENT_RAM_LIMIT 10237e532c4bSJorge Ramirez-Ortiz #endif 10247e532c4bSJorge Ramirez-Ortiz ); 10257e532c4bSJorge Ramirez-Ortiz #endif 10267e532c4bSJorge Ramirez-Ortiz } 10277e532c4bSJorge Ramirez-Ortiz 10287e532c4bSJorge Ramirez-Ortiz void bl2_platform_setup(void) 10297e532c4bSJorge Ramirez-Ortiz { 10307e532c4bSJorge Ramirez-Ortiz 10317e532c4bSJorge Ramirez-Ortiz } 103247141b73SMarek Vasut 103347141b73SMarek Vasut static void bl2_init_generic_timer(void) 103447141b73SMarek Vasut { 1035b709fe9cSValentine Barshak /* FIXME: V3M 16.666 MHz ? */ 1036bfbf5df4SMarek Vasut #if RCAR_LSI == RCAR_D3 1037bfbf5df4SMarek Vasut uint32_t reg_cntfid = EXTAL_DRAAK; 1038bfbf5df4SMarek Vasut #elif RCAR_LSI == RCAR_E3 103947141b73SMarek Vasut uint32_t reg_cntfid = EXTAL_EBISU; 104047141b73SMarek Vasut #else /* RCAR_LSI == RCAR_E3 */ 104147141b73SMarek Vasut uint32_t reg; 104247141b73SMarek Vasut uint32_t reg_cntfid; 104347141b73SMarek Vasut uint32_t modemr; 104447141b73SMarek Vasut uint32_t modemr_pll; 104547141b73SMarek Vasut uint32_t board_type; 104647141b73SMarek Vasut uint32_t board_rev; 104747141b73SMarek Vasut uint32_t pll_table[] = { 104847141b73SMarek Vasut EXTAL_MD14_MD13_TYPE_0, /* MD14/MD13 : 0b00 */ 104947141b73SMarek Vasut EXTAL_MD14_MD13_TYPE_1, /* MD14/MD13 : 0b01 */ 105047141b73SMarek Vasut EXTAL_MD14_MD13_TYPE_2, /* MD14/MD13 : 0b10 */ 105147141b73SMarek Vasut EXTAL_MD14_MD13_TYPE_3 /* MD14/MD13 : 0b11 */ 105247141b73SMarek Vasut }; 105347141b73SMarek Vasut 105447141b73SMarek Vasut modemr = mmio_read_32(RCAR_MODEMR); 105547141b73SMarek Vasut modemr_pll = (modemr & MODEMR_BOOT_PLL_MASK); 105647141b73SMarek Vasut 105747141b73SMarek Vasut /* Set frequency data in CNTFID0 */ 105847141b73SMarek Vasut reg_cntfid = pll_table[modemr_pll >> MODEMR_BOOT_PLL_SHIFT]; 1059df51d8feSMarek Vasut reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 106047141b73SMarek Vasut switch (modemr_pll) { 106147141b73SMarek Vasut case MD14_MD13_TYPE_0: 106247141b73SMarek Vasut rcar_get_board_type(&board_type, &board_rev); 106347141b73SMarek Vasut if (BOARD_SALVATOR_XS == board_type) { 106447141b73SMarek Vasut reg_cntfid = EXTAL_SALVATOR_XS; 106547141b73SMarek Vasut } 106647141b73SMarek Vasut break; 106747141b73SMarek Vasut case MD14_MD13_TYPE_3: 1068df51d8feSMarek Vasut if (PRR_PRODUCT_H3_CUT10 == reg) { 106947141b73SMarek Vasut reg_cntfid = reg_cntfid >> 1U; 107047141b73SMarek Vasut } 107147141b73SMarek Vasut break; 107247141b73SMarek Vasut default: 107347141b73SMarek Vasut /* none */ 107447141b73SMarek Vasut break; 107547141b73SMarek Vasut } 107647141b73SMarek Vasut #endif /* RCAR_LSI == RCAR_E3 */ 107747141b73SMarek Vasut /* Update memory mapped and register based freqency */ 107847141b73SMarek Vasut write_cntfrq_el0((u_register_t )reg_cntfid); 107947141b73SMarek Vasut mmio_write_32(ARM_SYS_CNTCTL_BASE + (uintptr_t)CNTFID_OFF, reg_cntfid); 108047141b73SMarek Vasut /* Enable counter */ 108147141b73SMarek Vasut mmio_setbits_32(RCAR_CNTC_BASE + (uintptr_t)CNTCR_OFF, 108247141b73SMarek Vasut (uint32_t)CNTCR_EN); 108347141b73SMarek Vasut } 1084