1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2020-2021, Renesas Electronics Corporation. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <inttypes.h> 8*91f16700Schasinglulu #include <stdint.h> 9*91f16700Schasinglulu #include <string.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <arch_helpers.h> 12*91f16700Schasinglulu #include <bl1/bl1.h> 13*91f16700Schasinglulu #include <common/bl_common.h> 14*91f16700Schasinglulu #include <common/debug.h> 15*91f16700Schasinglulu #include <common/desc_image_load.h> 16*91f16700Schasinglulu #include <drivers/console.h> 17*91f16700Schasinglulu #include <drivers/io/io_driver.h> 18*91f16700Schasinglulu #include <drivers/io/io_storage.h> 19*91f16700Schasinglulu #include <libfdt.h> 20*91f16700Schasinglulu #include <lib/mmio.h> 21*91f16700Schasinglulu #include <lib/xlat_tables/xlat_tables_defs.h> 22*91f16700Schasinglulu #include <platform_def.h> 23*91f16700Schasinglulu #include <plat/common/platform.h> 24*91f16700Schasinglulu 25*91f16700Schasinglulu #include "avs_driver.h" 26*91f16700Schasinglulu #include "board.h" 27*91f16700Schasinglulu #include "boot_init_dram.h" 28*91f16700Schasinglulu #include "cpg_registers.h" 29*91f16700Schasinglulu #include "emmc_def.h" 30*91f16700Schasinglulu #include "emmc_hal.h" 31*91f16700Schasinglulu #include "emmc_std.h" 32*91f16700Schasinglulu #include "io_common.h" 33*91f16700Schasinglulu #include "io_rcar.h" 34*91f16700Schasinglulu #include "qos_init.h" 35*91f16700Schasinglulu #include "rcar_def.h" 36*91f16700Schasinglulu #include "rcar_private.h" 37*91f16700Schasinglulu #include "rcar_version.h" 38*91f16700Schasinglulu #include "rom_api.h" 39*91f16700Schasinglulu 40*91f16700Schasinglulu #define MAX_DRAM_CHANNELS 4 41*91f16700Schasinglulu /* 42*91f16700Schasinglulu * DDR ch0 has a shadow area mapped in 32bit address space. 43*91f16700Schasinglulu * Physical address 0x4_0000_0000 - 0x4_7fff_ffff in 64bit space 44*91f16700Schasinglulu * is mapped to 0x4000_0000 - 0xbfff_ffff in 32bit space. 45*91f16700Schasinglulu */ 46*91f16700Schasinglulu #define MAX_DRAM_SIZE_CH0_32BIT_ADDR_SPACE 0x80000000ULL 47*91f16700Schasinglulu 48*91f16700Schasinglulu #if RCAR_BL2_DCACHE == 1 49*91f16700Schasinglulu /* 50*91f16700Schasinglulu * Following symbols are only used during plat_arch_setup() only 51*91f16700Schasinglulu * when RCAR_BL2_DCACHE is enabled. 52*91f16700Schasinglulu */ 53*91f16700Schasinglulu static const uint64_t BL2_RO_BASE = BL_CODE_BASE; 54*91f16700Schasinglulu static const uint64_t BL2_RO_LIMIT = BL_CODE_END; 55*91f16700Schasinglulu 56*91f16700Schasinglulu #if USE_COHERENT_MEM 57*91f16700Schasinglulu static const uint64_t BL2_COHERENT_RAM_BASE = BL_COHERENT_RAM_BASE; 58*91f16700Schasinglulu static const uint64_t BL2_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END; 59*91f16700Schasinglulu #endif /* USE_COHERENT_MEM */ 60*91f16700Schasinglulu 61*91f16700Schasinglulu #endif /* RCAR_BL2_DCACHE */ 62*91f16700Schasinglulu 63*91f16700Schasinglulu extern void plat_rcar_gic_driver_init(void); 64*91f16700Schasinglulu extern void plat_rcar_gic_init(void); 65*91f16700Schasinglulu extern void bl2_enter_bl31(const struct entry_point_info *bl_ep_info); 66*91f16700Schasinglulu extern void bl2_system_cpg_init(void); 67*91f16700Schasinglulu extern void bl2_secure_setting(void); 68*91f16700Schasinglulu extern void bl2_cpg_init(void); 69*91f16700Schasinglulu extern void rcar_io_emmc_setup(void); 70*91f16700Schasinglulu extern void rcar_io_setup(void); 71*91f16700Schasinglulu extern void rcar_swdt_release(void); 72*91f16700Schasinglulu extern void rcar_swdt_init(void); 73*91f16700Schasinglulu extern void rcar_rpc_init(void); 74*91f16700Schasinglulu extern void rcar_dma_init(void); 75*91f16700Schasinglulu extern void rzg_pfc_init(void); 76*91f16700Schasinglulu 77*91f16700Schasinglulu static void bl2_init_generic_timer(void); 78*91f16700Schasinglulu 79*91f16700Schasinglulu /* RZ/G2 product check */ 80*91f16700Schasinglulu #if RCAR_LSI == RZ_G2M 81*91f16700Schasinglulu #define TARGET_PRODUCT PRR_PRODUCT_M3 82*91f16700Schasinglulu #define TARGET_NAME "RZ/G2M" 83*91f16700Schasinglulu #elif RCAR_LSI == RZ_G2H 84*91f16700Schasinglulu #define TARGET_PRODUCT PRR_PRODUCT_H3 85*91f16700Schasinglulu #define TARGET_NAME "RZ/G2H" 86*91f16700Schasinglulu #elif RCAR_LSI == RZ_G2N 87*91f16700Schasinglulu #define TARGET_PRODUCT PRR_PRODUCT_M3N 88*91f16700Schasinglulu #define TARGET_NAME "RZ/G2N" 89*91f16700Schasinglulu #elif RCAR_LSI == RZ_G2E 90*91f16700Schasinglulu #define TARGET_PRODUCT PRR_PRODUCT_E3 91*91f16700Schasinglulu #define TARGET_NAME "RZ/G2E" 92*91f16700Schasinglulu #elif RCAR_LSI == RCAR_AUTO 93*91f16700Schasinglulu #define TARGET_NAME "RZ/G2M" 94*91f16700Schasinglulu #endif /* RCAR_LSI == RZ_G2M */ 95*91f16700Schasinglulu 96*91f16700Schasinglulu #if (RCAR_LSI == RZ_G2E) 97*91f16700Schasinglulu #define GPIO_INDT (GPIO_INDT6) 98*91f16700Schasinglulu #define GPIO_BKUP_TRG_SHIFT ((uint32_t)1U << 13U) 99*91f16700Schasinglulu #else 100*91f16700Schasinglulu #define GPIO_INDT (GPIO_INDT1) 101*91f16700Schasinglulu #define GPIO_BKUP_TRG_SHIFT (1U << 8U) 102*91f16700Schasinglulu #endif /* RCAR_LSI == RZ_G2E */ 103*91f16700Schasinglulu 104*91f16700Schasinglulu CASSERT((PARAMS_BASE + sizeof(bl2_to_bl31_params_mem_t) + 0x100) 105*91f16700Schasinglulu < (RCAR_SHARED_MEM_BASE + RCAR_SHARED_MEM_SIZE), 106*91f16700Schasinglulu assert_bl31_params_do_not_fit_in_shared_memory); 107*91f16700Schasinglulu 108*91f16700Schasinglulu static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); 109*91f16700Schasinglulu 110*91f16700Schasinglulu /* FDT with DRAM configuration */ 111*91f16700Schasinglulu uint64_t fdt_blob[PAGE_SIZE_4KB / sizeof(uint64_t)]; 112*91f16700Schasinglulu static void *fdt = (void *)fdt_blob; 113*91f16700Schasinglulu 114*91f16700Schasinglulu static void unsigned_num_print(uint64_t unum, unsigned int radix, char *string) 115*91f16700Schasinglulu { 116*91f16700Schasinglulu /* Just need enough space to store 64 bit decimal integer */ 117*91f16700Schasinglulu char num_buf[20]; 118*91f16700Schasinglulu int i = 0; 119*91f16700Schasinglulu unsigned int rem; 120*91f16700Schasinglulu 121*91f16700Schasinglulu do { 122*91f16700Schasinglulu rem = unum % radix; 123*91f16700Schasinglulu if (rem < 0xaU) { 124*91f16700Schasinglulu num_buf[i] = '0' + rem; 125*91f16700Schasinglulu } else { 126*91f16700Schasinglulu num_buf[i] = 'a' + (rem - 0xaU); 127*91f16700Schasinglulu } 128*91f16700Schasinglulu i++; 129*91f16700Schasinglulu unum /= radix; 130*91f16700Schasinglulu } while (unum > 0U); 131*91f16700Schasinglulu 132*91f16700Schasinglulu while (--i >= 0) { 133*91f16700Schasinglulu *string++ = num_buf[i]; 134*91f16700Schasinglulu } 135*91f16700Schasinglulu *string = 0; 136*91f16700Schasinglulu } 137*91f16700Schasinglulu 138*91f16700Schasinglulu #if RCAR_LOSSY_ENABLE == 1 139*91f16700Schasinglulu typedef struct bl2_lossy_info { 140*91f16700Schasinglulu uint32_t magic; 141*91f16700Schasinglulu uint32_t a0; 142*91f16700Schasinglulu uint32_t b0; 143*91f16700Schasinglulu } bl2_lossy_info_t; 144*91f16700Schasinglulu 145*91f16700Schasinglulu static void bl2_lossy_gen_fdt(uint32_t no, uint64_t start_addr, 146*91f16700Schasinglulu uint64_t end_addr, uint32_t format, 147*91f16700Schasinglulu uint32_t enable, int fcnlnode) 148*91f16700Schasinglulu { 149*91f16700Schasinglulu const uint64_t fcnlsize = cpu_to_fdt64(end_addr - start_addr); 150*91f16700Schasinglulu char nodename[40] = { 0 }; 151*91f16700Schasinglulu int ret, node; 152*91f16700Schasinglulu 153*91f16700Schasinglulu /* Ignore undefined addresses */ 154*91f16700Schasinglulu if (start_addr == 0UL && end_addr == 0UL) { 155*91f16700Schasinglulu return; 156*91f16700Schasinglulu } 157*91f16700Schasinglulu 158*91f16700Schasinglulu snprintf(nodename, sizeof(nodename), "lossy-decompression@"); 159*91f16700Schasinglulu unsigned_num_print(start_addr, 16, nodename + strlen(nodename)); 160*91f16700Schasinglulu 161*91f16700Schasinglulu node = ret = fdt_add_subnode(fdt, fcnlnode, nodename); 162*91f16700Schasinglulu if (ret < 0) { 163*91f16700Schasinglulu NOTICE("BL2: Cannot create FCNL node (ret=%i)\n", ret); 164*91f16700Schasinglulu panic(); 165*91f16700Schasinglulu } 166*91f16700Schasinglulu 167*91f16700Schasinglulu ret = fdt_setprop_string(fdt, node, "compatible", 168*91f16700Schasinglulu "renesas,lossy-decompression"); 169*91f16700Schasinglulu if (ret < 0) { 170*91f16700Schasinglulu NOTICE("BL2: Cannot add FCNL compat string %s (ret=%i)\n", 171*91f16700Schasinglulu "renesas,lossy-decompression", ret); 172*91f16700Schasinglulu panic(); 173*91f16700Schasinglulu } 174*91f16700Schasinglulu 175*91f16700Schasinglulu ret = fdt_appendprop_string(fdt, node, "compatible", 176*91f16700Schasinglulu "shared-dma-pool"); 177*91f16700Schasinglulu if (ret < 0) { 178*91f16700Schasinglulu NOTICE("BL2: Cannot append FCNL compat string %s (ret=%i)\n", 179*91f16700Schasinglulu "shared-dma-pool", ret); 180*91f16700Schasinglulu panic(); 181*91f16700Schasinglulu } 182*91f16700Schasinglulu 183*91f16700Schasinglulu ret = fdt_setprop_u64(fdt, node, "reg", start_addr); 184*91f16700Schasinglulu if (ret < 0) { 185*91f16700Schasinglulu NOTICE("BL2: Cannot add FCNL reg prop (ret=%i)\n", ret); 186*91f16700Schasinglulu panic(); 187*91f16700Schasinglulu } 188*91f16700Schasinglulu 189*91f16700Schasinglulu ret = fdt_appendprop(fdt, node, "reg", &fcnlsize, sizeof(fcnlsize)); 190*91f16700Schasinglulu if (ret < 0) { 191*91f16700Schasinglulu NOTICE("BL2: Cannot append FCNL reg size prop (ret=%i)\n", ret); 192*91f16700Schasinglulu panic(); 193*91f16700Schasinglulu } 194*91f16700Schasinglulu 195*91f16700Schasinglulu ret = fdt_setprop(fdt, node, "no-map", NULL, 0); 196*91f16700Schasinglulu if (ret < 0) { 197*91f16700Schasinglulu NOTICE("BL2: Cannot add FCNL no-map prop (ret=%i)\n", ret); 198*91f16700Schasinglulu panic(); 199*91f16700Schasinglulu } 200*91f16700Schasinglulu 201*91f16700Schasinglulu ret = fdt_setprop_u32(fdt, node, "renesas,formats", format); 202*91f16700Schasinglulu if (ret < 0) { 203*91f16700Schasinglulu NOTICE("BL2: Cannot add FCNL formats prop (ret=%i)\n", ret); 204*91f16700Schasinglulu panic(); 205*91f16700Schasinglulu } 206*91f16700Schasinglulu } 207*91f16700Schasinglulu 208*91f16700Schasinglulu static void bl2_lossy_setting(uint32_t no, uint64_t start_addr, 209*91f16700Schasinglulu uint64_t end_addr, uint32_t format, 210*91f16700Schasinglulu uint32_t enable, int fcnlnode) 211*91f16700Schasinglulu { 212*91f16700Schasinglulu bl2_lossy_info_t info; 213*91f16700Schasinglulu uint32_t reg; 214*91f16700Schasinglulu 215*91f16700Schasinglulu bl2_lossy_gen_fdt(no, start_addr, end_addr, format, enable, fcnlnode); 216*91f16700Schasinglulu 217*91f16700Schasinglulu reg = format | (start_addr >> 20); 218*91f16700Schasinglulu mmio_write_32(AXI_DCMPAREACRA0 + 0x8U * no, reg); 219*91f16700Schasinglulu mmio_write_32(AXI_DCMPAREACRB0 + 0x8U * no, end_addr >> 20); 220*91f16700Schasinglulu mmio_write_32(AXI_DCMPAREACRA0 + 0x8U * no, reg | enable); 221*91f16700Schasinglulu 222*91f16700Schasinglulu info.magic = 0x12345678U; 223*91f16700Schasinglulu info.a0 = mmio_read_32(AXI_DCMPAREACRA0 + 0x8U * no); 224*91f16700Schasinglulu info.b0 = mmio_read_32(AXI_DCMPAREACRB0 + 0x8U * no); 225*91f16700Schasinglulu 226*91f16700Schasinglulu mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no, info.magic); 227*91f16700Schasinglulu mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x4U, info.a0); 228*91f16700Schasinglulu mmio_write_32(LOSSY_PARAMS_BASE + sizeof(info) * no + 0x8U, info.b0); 229*91f16700Schasinglulu 230*91f16700Schasinglulu NOTICE(" Entry %d: DCMPAREACRAx:0x%x DCMPAREACRBx:0x%x\n", no, 231*91f16700Schasinglulu mmio_read_32(AXI_DCMPAREACRA0 + 0x8U * no), 232*91f16700Schasinglulu mmio_read_32(AXI_DCMPAREACRB0 + 0x8U * no)); 233*91f16700Schasinglulu } 234*91f16700Schasinglulu #endif /* RCAR_LOSSY_ENABLE == 1 */ 235*91f16700Schasinglulu 236*91f16700Schasinglulu void bl2_plat_flush_bl31_params(void) 237*91f16700Schasinglulu { 238*91f16700Schasinglulu uint32_t product_cut, product, cut; 239*91f16700Schasinglulu uint32_t boot_dev, boot_cpu; 240*91f16700Schasinglulu uint32_t reg; 241*91f16700Schasinglulu 242*91f16700Schasinglulu reg = mmio_read_32(RCAR_MODEMR); 243*91f16700Schasinglulu boot_dev = reg & MODEMR_BOOT_DEV_MASK; 244*91f16700Schasinglulu 245*91f16700Schasinglulu if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || 246*91f16700Schasinglulu boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) { 247*91f16700Schasinglulu emmc_terminate(); 248*91f16700Schasinglulu } 249*91f16700Schasinglulu 250*91f16700Schasinglulu if ((reg & MODEMR_BOOT_CPU_MASK) != MODEMR_BOOT_CPU_CR7) { 251*91f16700Schasinglulu bl2_secure_setting(); 252*91f16700Schasinglulu } 253*91f16700Schasinglulu 254*91f16700Schasinglulu reg = mmio_read_32(RCAR_PRR); 255*91f16700Schasinglulu product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 256*91f16700Schasinglulu product = reg & PRR_PRODUCT_MASK; 257*91f16700Schasinglulu cut = reg & PRR_CUT_MASK; 258*91f16700Schasinglulu 259*91f16700Schasinglulu if (!((product == PRR_PRODUCT_M3 && cut < PRR_PRODUCT_30) || 260*91f16700Schasinglulu (product == PRR_PRODUCT_H3 && cut < PRR_PRODUCT_20))) { 261*91f16700Schasinglulu /* Disable MFIS write protection */ 262*91f16700Schasinglulu mmio_write_32(MFISWPCNTR, MFISWPCNTR_PASSWORD | 1U); 263*91f16700Schasinglulu } 264*91f16700Schasinglulu 265*91f16700Schasinglulu reg = mmio_read_32(RCAR_MODEMR); 266*91f16700Schasinglulu boot_cpu = reg & MODEMR_BOOT_CPU_MASK; 267*91f16700Schasinglulu if (boot_cpu == MODEMR_BOOT_CPU_CA57 || 268*91f16700Schasinglulu boot_cpu == MODEMR_BOOT_CPU_CA53) { 269*91f16700Schasinglulu if (product_cut == PRR_PRODUCT_H3_CUT20) { 270*91f16700Schasinglulu mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); 271*91f16700Schasinglulu mmio_write_32(IPMMUVI1_IMSCTLR, IMSCTLR_DISCACHE); 272*91f16700Schasinglulu mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); 273*91f16700Schasinglulu mmio_write_32(IPMMUPV1_IMSCTLR, IMSCTLR_DISCACHE); 274*91f16700Schasinglulu mmio_write_32(IPMMUPV2_IMSCTLR, IMSCTLR_DISCACHE); 275*91f16700Schasinglulu mmio_write_32(IPMMUPV3_IMSCTLR, IMSCTLR_DISCACHE); 276*91f16700Schasinglulu } else if (product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) || 277*91f16700Schasinglulu product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11)) { 278*91f16700Schasinglulu mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); 279*91f16700Schasinglulu mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); 280*91f16700Schasinglulu } else if ((product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) || 281*91f16700Schasinglulu (product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_11))) { 282*91f16700Schasinglulu mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); 283*91f16700Schasinglulu mmio_write_32(IPMMUVP0_IMSCTLR, IMSCTLR_DISCACHE); 284*91f16700Schasinglulu mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); 285*91f16700Schasinglulu } 286*91f16700Schasinglulu 287*91f16700Schasinglulu if (product_cut == (PRR_PRODUCT_H3_CUT20) || 288*91f16700Schasinglulu product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) || 289*91f16700Schasinglulu product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11) || 290*91f16700Schasinglulu product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) { 291*91f16700Schasinglulu mmio_write_32(IPMMUHC_IMSCTLR, IMSCTLR_DISCACHE); 292*91f16700Schasinglulu mmio_write_32(IPMMURT_IMSCTLR, IMSCTLR_DISCACHE); 293*91f16700Schasinglulu mmio_write_32(IPMMUMP_IMSCTLR, IMSCTLR_DISCACHE); 294*91f16700Schasinglulu 295*91f16700Schasinglulu mmio_write_32(IPMMUDS0_IMSCTLR, IMSCTLR_DISCACHE); 296*91f16700Schasinglulu mmio_write_32(IPMMUDS1_IMSCTLR, IMSCTLR_DISCACHE); 297*91f16700Schasinglulu } 298*91f16700Schasinglulu } 299*91f16700Schasinglulu 300*91f16700Schasinglulu mmio_write_32(IPMMUMM_IMSCTLR, IPMMUMM_IMSCTLR_ENABLE); 301*91f16700Schasinglulu mmio_write_32(IPMMUMM_IMAUXCTLR, IPMMUMM_IMAUXCTLR_NMERGE40_BIT); 302*91f16700Schasinglulu 303*91f16700Schasinglulu rcar_swdt_release(); 304*91f16700Schasinglulu bl2_system_cpg_init(); 305*91f16700Schasinglulu 306*91f16700Schasinglulu #if RCAR_BL2_DCACHE == 1 307*91f16700Schasinglulu /* Disable data cache (clean and invalidate) */ 308*91f16700Schasinglulu disable_mmu_el3(); 309*91f16700Schasinglulu #endif /* RCAR_BL2_DCACHE == 1 */ 310*91f16700Schasinglulu } 311*91f16700Schasinglulu 312*91f16700Schasinglulu static uint32_t is_ddr_backup_mode(void) 313*91f16700Schasinglulu { 314*91f16700Schasinglulu #if RCAR_SYSTEM_SUSPEND 315*91f16700Schasinglulu static uint32_t reason = RCAR_COLD_BOOT; 316*91f16700Schasinglulu static uint32_t once; 317*91f16700Schasinglulu 318*91f16700Schasinglulu if (once != 0U) { 319*91f16700Schasinglulu return reason; 320*91f16700Schasinglulu } 321*91f16700Schasinglulu 322*91f16700Schasinglulu once = 1; 323*91f16700Schasinglulu if ((mmio_read_32(GPIO_INDT) & GPIO_BKUP_TRG_SHIFT) == 0U) { 324*91f16700Schasinglulu return reason; 325*91f16700Schasinglulu } 326*91f16700Schasinglulu 327*91f16700Schasinglulu reason = RCAR_WARM_BOOT; 328*91f16700Schasinglulu return reason; 329*91f16700Schasinglulu #else /* RCAR_SYSTEM_SUSPEND */ 330*91f16700Schasinglulu return RCAR_COLD_BOOT; 331*91f16700Schasinglulu #endif /* RCAR_SYSTEM_SUSPEND */ 332*91f16700Schasinglulu } 333*91f16700Schasinglulu 334*91f16700Schasinglulu int bl2_plat_handle_pre_image_load(unsigned int image_id) 335*91f16700Schasinglulu { 336*91f16700Schasinglulu u_register_t *boot_kind = (void *)BOOT_KIND_BASE; 337*91f16700Schasinglulu bl_mem_params_node_t *bl_mem_params; 338*91f16700Schasinglulu 339*91f16700Schasinglulu if (image_id != BL31_IMAGE_ID) { 340*91f16700Schasinglulu return 0; 341*91f16700Schasinglulu } 342*91f16700Schasinglulu 343*91f16700Schasinglulu bl_mem_params = get_bl_mem_params_node(image_id); 344*91f16700Schasinglulu 345*91f16700Schasinglulu if (is_ddr_backup_mode() != RCAR_COLD_BOOT) { 346*91f16700Schasinglulu *boot_kind = RCAR_WARM_BOOT; 347*91f16700Schasinglulu flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind)); 348*91f16700Schasinglulu 349*91f16700Schasinglulu console_flush(); 350*91f16700Schasinglulu bl2_plat_flush_bl31_params(); 351*91f16700Schasinglulu 352*91f16700Schasinglulu /* will not return */ 353*91f16700Schasinglulu bl2_enter_bl31(&bl_mem_params->ep_info); 354*91f16700Schasinglulu } 355*91f16700Schasinglulu 356*91f16700Schasinglulu *boot_kind = RCAR_COLD_BOOT; 357*91f16700Schasinglulu flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind)); 358*91f16700Schasinglulu 359*91f16700Schasinglulu return 0; 360*91f16700Schasinglulu } 361*91f16700Schasinglulu 362*91f16700Schasinglulu static uint64_t rzg_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest) 363*91f16700Schasinglulu { 364*91f16700Schasinglulu uint32_t cert, len; 365*91f16700Schasinglulu int err; 366*91f16700Schasinglulu 367*91f16700Schasinglulu err = rcar_get_certificate(certid, &cert); 368*91f16700Schasinglulu if (err != 0) { 369*91f16700Schasinglulu ERROR("%s : cert file load error", __func__); 370*91f16700Schasinglulu return 1U; 371*91f16700Schasinglulu } 372*91f16700Schasinglulu 373*91f16700Schasinglulu rcar_read_certificate((uint64_t)cert, &len, dest); 374*91f16700Schasinglulu 375*91f16700Schasinglulu return 0U; 376*91f16700Schasinglulu } 377*91f16700Schasinglulu 378*91f16700Schasinglulu int bl2_plat_handle_post_image_load(unsigned int image_id) 379*91f16700Schasinglulu { 380*91f16700Schasinglulu static bl2_to_bl31_params_mem_t *params; 381*91f16700Schasinglulu bl_mem_params_node_t *bl_mem_params; 382*91f16700Schasinglulu uintptr_t dest; 383*91f16700Schasinglulu uint64_t ret; 384*91f16700Schasinglulu 385*91f16700Schasinglulu if (params == NULL) { 386*91f16700Schasinglulu params = (bl2_to_bl31_params_mem_t *)PARAMS_BASE; 387*91f16700Schasinglulu memset((void *)PARAMS_BASE, 0, sizeof(*params)); 388*91f16700Schasinglulu } 389*91f16700Schasinglulu 390*91f16700Schasinglulu bl_mem_params = get_bl_mem_params_node(image_id); 391*91f16700Schasinglulu 392*91f16700Schasinglulu switch (image_id) { 393*91f16700Schasinglulu case BL31_IMAGE_ID: 394*91f16700Schasinglulu ret = rzg_get_dest_addr_from_cert(SOC_FW_CONTENT_CERT_ID, 395*91f16700Schasinglulu &dest); 396*91f16700Schasinglulu if (ret == 0U) { 397*91f16700Schasinglulu bl_mem_params->image_info.image_base = dest; 398*91f16700Schasinglulu } 399*91f16700Schasinglulu break; 400*91f16700Schasinglulu case BL32_IMAGE_ID: 401*91f16700Schasinglulu ret = rzg_get_dest_addr_from_cert(TRUSTED_OS_FW_CONTENT_CERT_ID, 402*91f16700Schasinglulu &dest); 403*91f16700Schasinglulu if (ret == 0U) { 404*91f16700Schasinglulu bl_mem_params->image_info.image_base = dest; 405*91f16700Schasinglulu } 406*91f16700Schasinglulu 407*91f16700Schasinglulu memcpy(¶ms->bl32_ep_info, &bl_mem_params->ep_info, 408*91f16700Schasinglulu sizeof(entry_point_info_t)); 409*91f16700Schasinglulu break; 410*91f16700Schasinglulu case BL33_IMAGE_ID: 411*91f16700Schasinglulu memcpy(¶ms->bl33_ep_info, &bl_mem_params->ep_info, 412*91f16700Schasinglulu sizeof(entry_point_info_t)); 413*91f16700Schasinglulu break; 414*91f16700Schasinglulu default: 415*91f16700Schasinglulu break; 416*91f16700Schasinglulu } 417*91f16700Schasinglulu 418*91f16700Schasinglulu return 0; 419*91f16700Schasinglulu } 420*91f16700Schasinglulu 421*91f16700Schasinglulu struct meminfo *bl2_plat_sec_mem_layout(void) 422*91f16700Schasinglulu { 423*91f16700Schasinglulu return &bl2_tzram_layout; 424*91f16700Schasinglulu } 425*91f16700Schasinglulu 426*91f16700Schasinglulu static void bl2_populate_compatible_string(void *dt) 427*91f16700Schasinglulu { 428*91f16700Schasinglulu uint32_t board_type; 429*91f16700Schasinglulu uint32_t board_rev; 430*91f16700Schasinglulu uint32_t reg; 431*91f16700Schasinglulu int ret; 432*91f16700Schasinglulu 433*91f16700Schasinglulu fdt_setprop_u32(dt, 0, "#address-cells", 2); 434*91f16700Schasinglulu fdt_setprop_u32(dt, 0, "#size-cells", 2); 435*91f16700Schasinglulu 436*91f16700Schasinglulu /* Populate compatible string */ 437*91f16700Schasinglulu rzg_get_board_type(&board_type, &board_rev); 438*91f16700Schasinglulu switch (board_type) { 439*91f16700Schasinglulu case BOARD_HIHOPE_RZ_G2M: 440*91f16700Schasinglulu ret = fdt_setprop_string(dt, 0, "compatible", 441*91f16700Schasinglulu "hoperun,hihope-rzg2m"); 442*91f16700Schasinglulu break; 443*91f16700Schasinglulu case BOARD_HIHOPE_RZ_G2H: 444*91f16700Schasinglulu ret = fdt_setprop_string(dt, 0, "compatible", 445*91f16700Schasinglulu "hoperun,hihope-rzg2h"); 446*91f16700Schasinglulu break; 447*91f16700Schasinglulu case BOARD_HIHOPE_RZ_G2N: 448*91f16700Schasinglulu ret = fdt_setprop_string(dt, 0, "compatible", 449*91f16700Schasinglulu "hoperun,hihope-rzg2n"); 450*91f16700Schasinglulu break; 451*91f16700Schasinglulu case BOARD_EK874_RZ_G2E: 452*91f16700Schasinglulu ret = fdt_setprop_string(dt, 0, "compatible", 453*91f16700Schasinglulu "si-linux,cat874"); 454*91f16700Schasinglulu break; 455*91f16700Schasinglulu default: 456*91f16700Schasinglulu NOTICE("BL2: Cannot set compatible string, board unsupported\n"); 457*91f16700Schasinglulu panic(); 458*91f16700Schasinglulu break; 459*91f16700Schasinglulu } 460*91f16700Schasinglulu 461*91f16700Schasinglulu if (ret < 0) { 462*91f16700Schasinglulu NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret); 463*91f16700Schasinglulu panic(); 464*91f16700Schasinglulu } 465*91f16700Schasinglulu 466*91f16700Schasinglulu reg = mmio_read_32(RCAR_PRR); 467*91f16700Schasinglulu switch (reg & PRR_PRODUCT_MASK) { 468*91f16700Schasinglulu case PRR_PRODUCT_M3: 469*91f16700Schasinglulu ret = fdt_appendprop_string(dt, 0, "compatible", 470*91f16700Schasinglulu "renesas,r8a774a1"); 471*91f16700Schasinglulu break; 472*91f16700Schasinglulu case PRR_PRODUCT_H3: 473*91f16700Schasinglulu ret = fdt_appendprop_string(dt, 0, "compatible", 474*91f16700Schasinglulu "renesas,r8a774e1"); 475*91f16700Schasinglulu break; 476*91f16700Schasinglulu case PRR_PRODUCT_M3N: 477*91f16700Schasinglulu ret = fdt_appendprop_string(dt, 0, "compatible", 478*91f16700Schasinglulu "renesas,r8a774b1"); 479*91f16700Schasinglulu break; 480*91f16700Schasinglulu case PRR_PRODUCT_E3: 481*91f16700Schasinglulu ret = fdt_appendprop_string(dt, 0, "compatible", 482*91f16700Schasinglulu "renesas,r8a774c0"); 483*91f16700Schasinglulu break; 484*91f16700Schasinglulu default: 485*91f16700Schasinglulu NOTICE("BL2: Cannot set compatible string, SoC unsupported\n"); 486*91f16700Schasinglulu panic(); 487*91f16700Schasinglulu break; 488*91f16700Schasinglulu } 489*91f16700Schasinglulu 490*91f16700Schasinglulu if (ret < 0) { 491*91f16700Schasinglulu NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret); 492*91f16700Schasinglulu panic(); 493*91f16700Schasinglulu } 494*91f16700Schasinglulu } 495*91f16700Schasinglulu 496*91f16700Schasinglulu static int bl2_add_memory_node(uint64_t start, uint64_t size) 497*91f16700Schasinglulu { 498*91f16700Schasinglulu char nodename[32] = { 0 }; 499*91f16700Schasinglulu uint64_t fdtsize; 500*91f16700Schasinglulu int ret, node; 501*91f16700Schasinglulu 502*91f16700Schasinglulu fdtsize = cpu_to_fdt64(size); 503*91f16700Schasinglulu 504*91f16700Schasinglulu snprintf(nodename, sizeof(nodename), "memory@"); 505*91f16700Schasinglulu unsigned_num_print(start, 16, nodename + strlen(nodename)); 506*91f16700Schasinglulu node = ret = fdt_add_subnode(fdt, 0, nodename); 507*91f16700Schasinglulu if (ret < 0) { 508*91f16700Schasinglulu return ret; 509*91f16700Schasinglulu } 510*91f16700Schasinglulu 511*91f16700Schasinglulu ret = fdt_setprop_string(fdt, node, "device_type", "memory"); 512*91f16700Schasinglulu if (ret < 0) { 513*91f16700Schasinglulu return ret; 514*91f16700Schasinglulu } 515*91f16700Schasinglulu 516*91f16700Schasinglulu ret = fdt_setprop_u64(fdt, node, "reg", start); 517*91f16700Schasinglulu if (ret < 0) { 518*91f16700Schasinglulu return ret; 519*91f16700Schasinglulu } 520*91f16700Schasinglulu 521*91f16700Schasinglulu return fdt_appendprop(fdt, node, "reg", &fdtsize, sizeof(fdtsize)); 522*91f16700Schasinglulu } 523*91f16700Schasinglulu 524*91f16700Schasinglulu static void bl2_advertise_dram_entries(uint64_t dram_config[8]) 525*91f16700Schasinglulu { 526*91f16700Schasinglulu uint64_t start, size; 527*91f16700Schasinglulu int ret, chan; 528*91f16700Schasinglulu 529*91f16700Schasinglulu for (chan = 0; chan < MAX_DRAM_CHANNELS; chan++) { 530*91f16700Schasinglulu start = dram_config[2 * chan]; 531*91f16700Schasinglulu size = dram_config[2 * chan + 1]; 532*91f16700Schasinglulu if (size == 0U) { 533*91f16700Schasinglulu continue; 534*91f16700Schasinglulu } 535*91f16700Schasinglulu 536*91f16700Schasinglulu NOTICE("BL2: CH%d: %" PRIx64 " - %" PRIx64 ", %" PRId64 " %siB\n", 537*91f16700Schasinglulu chan, start, start + size - 1U, 538*91f16700Schasinglulu (size >> 30) ? : size >> 20, 539*91f16700Schasinglulu (size >> 30) ? "G" : "M"); 540*91f16700Schasinglulu } 541*91f16700Schasinglulu 542*91f16700Schasinglulu /* 543*91f16700Schasinglulu * We add the DT nodes in reverse order here. The fdt_add_subnode() 544*91f16700Schasinglulu * adds the DT node before the first existing DT node, so we have 545*91f16700Schasinglulu * to add them in reverse order to get nodes sorted by address in 546*91f16700Schasinglulu * the resulting DT. 547*91f16700Schasinglulu */ 548*91f16700Schasinglulu for (chan = MAX_DRAM_CHANNELS - 1; chan >= 0; chan--) { 549*91f16700Schasinglulu start = dram_config[2 * chan]; 550*91f16700Schasinglulu size = dram_config[2 * chan + 1]; 551*91f16700Schasinglulu if (size == 0U) { 552*91f16700Schasinglulu continue; 553*91f16700Schasinglulu } 554*91f16700Schasinglulu 555*91f16700Schasinglulu /* 556*91f16700Schasinglulu * Channel 0 is mapped in 32bit space and the first 557*91f16700Schasinglulu * 128 MiB are reserved 558*91f16700Schasinglulu */ 559*91f16700Schasinglulu if (chan == 0) { 560*91f16700Schasinglulu /* 561*91f16700Schasinglulu * Maximum DDR size in Channel 0 for 32 bit space is 2GB, Add DT node 562*91f16700Schasinglulu * for remaining region in 64 bit address space 563*91f16700Schasinglulu */ 564*91f16700Schasinglulu if (size > MAX_DRAM_SIZE_CH0_32BIT_ADDR_SPACE) { 565*91f16700Schasinglulu start = dram_config[chan] + MAX_DRAM_SIZE_CH0_32BIT_ADDR_SPACE; 566*91f16700Schasinglulu size -= MAX_DRAM_SIZE_CH0_32BIT_ADDR_SPACE; 567*91f16700Schasinglulu ret = bl2_add_memory_node(start, size); 568*91f16700Schasinglulu if (ret < 0) { 569*91f16700Schasinglulu goto err; 570*91f16700Schasinglulu } 571*91f16700Schasinglulu } 572*91f16700Schasinglulu start = 0x48000000U; 573*91f16700Schasinglulu size -= 0x8000000U; 574*91f16700Schasinglulu } 575*91f16700Schasinglulu 576*91f16700Schasinglulu ret = bl2_add_memory_node(start, size); 577*91f16700Schasinglulu if (ret < 0) { 578*91f16700Schasinglulu goto err; 579*91f16700Schasinglulu } 580*91f16700Schasinglulu } 581*91f16700Schasinglulu 582*91f16700Schasinglulu return; 583*91f16700Schasinglulu err: 584*91f16700Schasinglulu NOTICE("BL2: Cannot add memory node to FDT (ret=%i)\n", ret); 585*91f16700Schasinglulu panic(); 586*91f16700Schasinglulu } 587*91f16700Schasinglulu 588*91f16700Schasinglulu static void bl2_advertise_dram_size(uint32_t product) 589*91f16700Schasinglulu { 590*91f16700Schasinglulu uint64_t dram_config[8] = { 591*91f16700Schasinglulu [0] = 0x400000000ULL, 592*91f16700Schasinglulu [2] = 0x500000000ULL, 593*91f16700Schasinglulu [4] = 0x600000000ULL, 594*91f16700Schasinglulu [6] = 0x700000000ULL, 595*91f16700Schasinglulu }; 596*91f16700Schasinglulu 597*91f16700Schasinglulu switch (product) { 598*91f16700Schasinglulu case PRR_PRODUCT_M3: 599*91f16700Schasinglulu /* 4GB(2GBx2 2ch split) */ 600*91f16700Schasinglulu dram_config[1] = 0x80000000ULL; 601*91f16700Schasinglulu dram_config[5] = 0x80000000ULL; 602*91f16700Schasinglulu break; 603*91f16700Schasinglulu case PRR_PRODUCT_H3: 604*91f16700Schasinglulu #if (RCAR_DRAM_LPDDR4_MEMCONF == 0) 605*91f16700Schasinglulu /* 4GB(1GBx4) */ 606*91f16700Schasinglulu dram_config[1] = 0x40000000ULL; 607*91f16700Schasinglulu dram_config[3] = 0x40000000ULL; 608*91f16700Schasinglulu dram_config[5] = 0x40000000ULL; 609*91f16700Schasinglulu dram_config[7] = 0x40000000ULL; 610*91f16700Schasinglulu #elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && (RCAR_DRAM_CHANNEL == 5) && \ 611*91f16700Schasinglulu (RCAR_DRAM_SPLIT == 2) 612*91f16700Schasinglulu /* 4GB(2GBx2 2ch split) */ 613*91f16700Schasinglulu dram_config[1] = 0x80000000ULL; 614*91f16700Schasinglulu dram_config[3] = 0x80000000ULL; 615*91f16700Schasinglulu #elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && (RCAR_DRAM_CHANNEL == 15) 616*91f16700Schasinglulu /* 8GB(2GBx4: default) */ 617*91f16700Schasinglulu dram_config[1] = 0x80000000ULL; 618*91f16700Schasinglulu dram_config[3] = 0x80000000ULL; 619*91f16700Schasinglulu dram_config[5] = 0x80000000ULL; 620*91f16700Schasinglulu dram_config[7] = 0x80000000ULL; 621*91f16700Schasinglulu #endif /* RCAR_DRAM_LPDDR4_MEMCONF == 0 */ 622*91f16700Schasinglulu break; 623*91f16700Schasinglulu case PRR_PRODUCT_M3N: 624*91f16700Schasinglulu /* 4GB(4GBx1) */ 625*91f16700Schasinglulu dram_config[1] = 0x100000000ULL; 626*91f16700Schasinglulu break; 627*91f16700Schasinglulu case PRR_PRODUCT_E3: 628*91f16700Schasinglulu #if (RCAR_DRAM_DDR3L_MEMCONF == 0) 629*91f16700Schasinglulu /* 1GB(512MBx2) */ 630*91f16700Schasinglulu dram_config[1] = 0x40000000ULL; 631*91f16700Schasinglulu #elif (RCAR_DRAM_DDR3L_MEMCONF == 1) 632*91f16700Schasinglulu /* 2GB(512MBx4) */ 633*91f16700Schasinglulu dram_config[1] = 0x80000000ULL; 634*91f16700Schasinglulu #elif (RCAR_DRAM_DDR3L_MEMCONF == 2) 635*91f16700Schasinglulu /* 4GB(1GBx4) */ 636*91f16700Schasinglulu dram_config[1] = 0x100000000ULL; 637*91f16700Schasinglulu #endif /* RCAR_DRAM_DDR3L_MEMCONF == 0 */ 638*91f16700Schasinglulu break; 639*91f16700Schasinglulu default: 640*91f16700Schasinglulu NOTICE("BL2: Detected invalid DRAM entries\n"); 641*91f16700Schasinglulu break; 642*91f16700Schasinglulu } 643*91f16700Schasinglulu 644*91f16700Schasinglulu bl2_advertise_dram_entries(dram_config); 645*91f16700Schasinglulu } 646*91f16700Schasinglulu 647*91f16700Schasinglulu void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, 648*91f16700Schasinglulu u_register_t arg3, u_register_t arg4) 649*91f16700Schasinglulu { 650*91f16700Schasinglulu uint32_t reg, midr, boot_dev, boot_cpu, type, rev; 651*91f16700Schasinglulu uint32_t product, product_cut, major, minor; 652*91f16700Schasinglulu int32_t ret; 653*91f16700Schasinglulu const char *str; 654*91f16700Schasinglulu const char *unknown = "unknown"; 655*91f16700Schasinglulu const char *cpu_ca57 = "CA57"; 656*91f16700Schasinglulu const char *cpu_ca53 = "CA53"; 657*91f16700Schasinglulu const char *product_g2e = "G2E"; 658*91f16700Schasinglulu const char *product_g2h = "G2H"; 659*91f16700Schasinglulu const char *product_g2m = "G2M"; 660*91f16700Schasinglulu const char *product_g2n = "G2N"; 661*91f16700Schasinglulu const char *boot_hyper80 = "HyperFlash(80MHz)"; 662*91f16700Schasinglulu const char *boot_qspi40 = "QSPI Flash(40MHz)"; 663*91f16700Schasinglulu const char *boot_qspi80 = "QSPI Flash(80MHz)"; 664*91f16700Schasinglulu const char *boot_emmc25x1 = "eMMC(25MHz x1)"; 665*91f16700Schasinglulu const char *boot_emmc50x8 = "eMMC(50MHz x8)"; 666*91f16700Schasinglulu #if (RCAR_LSI == RZ_G2E) 667*91f16700Schasinglulu uint32_t sscg; 668*91f16700Schasinglulu const char *sscg_on = "PLL1 SSCG Clock select"; 669*91f16700Schasinglulu const char *sscg_off = "PLL1 nonSSCG Clock select"; 670*91f16700Schasinglulu const char *boot_hyper160 = "HyperFlash(150MHz)"; 671*91f16700Schasinglulu #else 672*91f16700Schasinglulu const char *boot_hyper160 = "HyperFlash(160MHz)"; 673*91f16700Schasinglulu #endif /* RCAR_LSI == RZ_G2E */ 674*91f16700Schasinglulu #if RZG_LCS_STATE_DETECTION_ENABLE 675*91f16700Schasinglulu uint32_t lcs; 676*91f16700Schasinglulu const char *lcs_secure = "SE"; 677*91f16700Schasinglulu const char *lcs_cm = "CM"; 678*91f16700Schasinglulu const char *lcs_dm = "DM"; 679*91f16700Schasinglulu const char *lcs_sd = "SD"; 680*91f16700Schasinglulu const char *lcs_fa = "FA"; 681*91f16700Schasinglulu #endif /* RZG_LCS_STATE_DETECTION_ENABLE */ 682*91f16700Schasinglulu 683*91f16700Schasinglulu #if (RCAR_LOSSY_ENABLE == 1) 684*91f16700Schasinglulu int fcnlnode; 685*91f16700Schasinglulu #endif /* (RCAR_LOSSY_ENABLE == 1) */ 686*91f16700Schasinglulu 687*91f16700Schasinglulu bl2_init_generic_timer(); 688*91f16700Schasinglulu 689*91f16700Schasinglulu reg = mmio_read_32(RCAR_MODEMR); 690*91f16700Schasinglulu boot_dev = reg & MODEMR_BOOT_DEV_MASK; 691*91f16700Schasinglulu boot_cpu = reg & MODEMR_BOOT_CPU_MASK; 692*91f16700Schasinglulu 693*91f16700Schasinglulu bl2_cpg_init(); 694*91f16700Schasinglulu 695*91f16700Schasinglulu if (boot_cpu == MODEMR_BOOT_CPU_CA57 || 696*91f16700Schasinglulu boot_cpu == MODEMR_BOOT_CPU_CA53) { 697*91f16700Schasinglulu rzg_pfc_init(); 698*91f16700Schasinglulu rcar_console_boot_init(); 699*91f16700Schasinglulu } 700*91f16700Schasinglulu 701*91f16700Schasinglulu plat_rcar_gic_driver_init(); 702*91f16700Schasinglulu plat_rcar_gic_init(); 703*91f16700Schasinglulu rcar_swdt_init(); 704*91f16700Schasinglulu 705*91f16700Schasinglulu /* FIQ interrupts are taken to EL3 */ 706*91f16700Schasinglulu write_scr_el3(read_scr_el3() | SCR_FIQ_BIT); 707*91f16700Schasinglulu 708*91f16700Schasinglulu write_daifclr(DAIF_FIQ_BIT); 709*91f16700Schasinglulu 710*91f16700Schasinglulu reg = read_midr(); 711*91f16700Schasinglulu midr = reg & (MIDR_PN_MASK << MIDR_PN_SHIFT); 712*91f16700Schasinglulu switch (midr) { 713*91f16700Schasinglulu case MIDR_CA57: 714*91f16700Schasinglulu str = cpu_ca57; 715*91f16700Schasinglulu break; 716*91f16700Schasinglulu case MIDR_CA53: 717*91f16700Schasinglulu str = cpu_ca53; 718*91f16700Schasinglulu break; 719*91f16700Schasinglulu default: 720*91f16700Schasinglulu str = unknown; 721*91f16700Schasinglulu break; 722*91f16700Schasinglulu } 723*91f16700Schasinglulu 724*91f16700Schasinglulu NOTICE("BL2: RZ/G2 Initial Program Loader(%s) Rev.%s\n", str, 725*91f16700Schasinglulu version_of_renesas); 726*91f16700Schasinglulu 727*91f16700Schasinglulu reg = mmio_read_32(RCAR_PRR); 728*91f16700Schasinglulu product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 729*91f16700Schasinglulu product = reg & PRR_PRODUCT_MASK; 730*91f16700Schasinglulu 731*91f16700Schasinglulu switch (product) { 732*91f16700Schasinglulu case PRR_PRODUCT_M3: 733*91f16700Schasinglulu str = product_g2m; 734*91f16700Schasinglulu break; 735*91f16700Schasinglulu case PRR_PRODUCT_H3: 736*91f16700Schasinglulu str = product_g2h; 737*91f16700Schasinglulu break; 738*91f16700Schasinglulu case PRR_PRODUCT_M3N: 739*91f16700Schasinglulu str = product_g2n; 740*91f16700Schasinglulu break; 741*91f16700Schasinglulu case PRR_PRODUCT_E3: 742*91f16700Schasinglulu str = product_g2e; 743*91f16700Schasinglulu break; 744*91f16700Schasinglulu default: 745*91f16700Schasinglulu str = unknown; 746*91f16700Schasinglulu break; 747*91f16700Schasinglulu } 748*91f16700Schasinglulu 749*91f16700Schasinglulu if ((product == PRR_PRODUCT_M3) && 750*91f16700Schasinglulu ((reg & RCAR_MAJOR_MASK) == PRR_PRODUCT_20)) { 751*91f16700Schasinglulu if ((reg & PRR_CUT_MASK) == RCAR_M3_CUT_VER11) { 752*91f16700Schasinglulu /* M3 Ver.1.1 or Ver.1.2 */ 753*91f16700Schasinglulu NOTICE("BL2: PRR is RZ/%s Ver.1.1 / Ver.1.2\n", str); 754*91f16700Schasinglulu } else { 755*91f16700Schasinglulu NOTICE("BL2: PRR is RZ/%s Ver.1.%d\n", str, 756*91f16700Schasinglulu (reg & RCAR_MINOR_MASK) + RCAR_M3_MINOR_OFFSET); 757*91f16700Schasinglulu } 758*91f16700Schasinglulu } else { 759*91f16700Schasinglulu major = (reg & RCAR_MAJOR_MASK) >> RCAR_MAJOR_SHIFT; 760*91f16700Schasinglulu major = major + RCAR_MAJOR_OFFSET; 761*91f16700Schasinglulu minor = reg & RCAR_MINOR_MASK; 762*91f16700Schasinglulu NOTICE("BL2: PRR is RZ/%s Ver.%d.%d\n", str, major, minor); 763*91f16700Schasinglulu } 764*91f16700Schasinglulu 765*91f16700Schasinglulu #if (RCAR_LSI == RZ_G2E) 766*91f16700Schasinglulu if (product == PRR_PRODUCT_E3) { 767*91f16700Schasinglulu reg = mmio_read_32(RCAR_MODEMR); 768*91f16700Schasinglulu sscg = reg & RCAR_SSCG_MASK; 769*91f16700Schasinglulu str = sscg == RCAR_SSCG_ENABLE ? sscg_on : sscg_off; 770*91f16700Schasinglulu NOTICE("BL2: %s\n", str); 771*91f16700Schasinglulu } 772*91f16700Schasinglulu #endif /* RCAR_LSI == RZ_G2E */ 773*91f16700Schasinglulu 774*91f16700Schasinglulu rzg_get_board_type(&type, &rev); 775*91f16700Schasinglulu 776*91f16700Schasinglulu switch (type) { 777*91f16700Schasinglulu case BOARD_HIHOPE_RZ_G2M: 778*91f16700Schasinglulu case BOARD_HIHOPE_RZ_G2H: 779*91f16700Schasinglulu case BOARD_HIHOPE_RZ_G2N: 780*91f16700Schasinglulu case BOARD_EK874_RZ_G2E: 781*91f16700Schasinglulu break; 782*91f16700Schasinglulu default: 783*91f16700Schasinglulu type = BOARD_UNKNOWN; 784*91f16700Schasinglulu break; 785*91f16700Schasinglulu } 786*91f16700Schasinglulu 787*91f16700Schasinglulu if (type == BOARD_UNKNOWN || rev == BOARD_REV_UNKNOWN) { 788*91f16700Schasinglulu NOTICE("BL2: Board is %s Rev.---\n", GET_BOARD_NAME(type)); 789*91f16700Schasinglulu } else { 790*91f16700Schasinglulu NOTICE("BL2: Board is %s Rev.%d.%d\n", 791*91f16700Schasinglulu GET_BOARD_NAME(type), 792*91f16700Schasinglulu GET_BOARD_MAJOR(rev), GET_BOARD_MINOR(rev)); 793*91f16700Schasinglulu } 794*91f16700Schasinglulu 795*91f16700Schasinglulu #if RCAR_LSI != RCAR_AUTO 796*91f16700Schasinglulu if (product != TARGET_PRODUCT) { 797*91f16700Schasinglulu ERROR("BL2: IPL was been built for the %s.\n", TARGET_NAME); 798*91f16700Schasinglulu ERROR("BL2: Please write the correct IPL to flash memory.\n"); 799*91f16700Schasinglulu panic(); 800*91f16700Schasinglulu } 801*91f16700Schasinglulu #endif /* RCAR_LSI != RCAR_AUTO */ 802*91f16700Schasinglulu rcar_avs_init(); 803*91f16700Schasinglulu rcar_avs_setting(); 804*91f16700Schasinglulu 805*91f16700Schasinglulu switch (boot_dev) { 806*91f16700Schasinglulu case MODEMR_BOOT_DEV_HYPERFLASH160: 807*91f16700Schasinglulu str = boot_hyper160; 808*91f16700Schasinglulu break; 809*91f16700Schasinglulu case MODEMR_BOOT_DEV_HYPERFLASH80: 810*91f16700Schasinglulu str = boot_hyper80; 811*91f16700Schasinglulu break; 812*91f16700Schasinglulu case MODEMR_BOOT_DEV_QSPI_FLASH40: 813*91f16700Schasinglulu str = boot_qspi40; 814*91f16700Schasinglulu break; 815*91f16700Schasinglulu case MODEMR_BOOT_DEV_QSPI_FLASH80: 816*91f16700Schasinglulu str = boot_qspi80; 817*91f16700Schasinglulu break; 818*91f16700Schasinglulu case MODEMR_BOOT_DEV_EMMC_25X1: 819*91f16700Schasinglulu str = boot_emmc25x1; 820*91f16700Schasinglulu break; 821*91f16700Schasinglulu case MODEMR_BOOT_DEV_EMMC_50X8: 822*91f16700Schasinglulu str = boot_emmc50x8; 823*91f16700Schasinglulu break; 824*91f16700Schasinglulu default: 825*91f16700Schasinglulu str = unknown; 826*91f16700Schasinglulu break; 827*91f16700Schasinglulu } 828*91f16700Schasinglulu NOTICE("BL2: Boot device is %s\n", str); 829*91f16700Schasinglulu 830*91f16700Schasinglulu rcar_avs_setting(); 831*91f16700Schasinglulu 832*91f16700Schasinglulu #if RZG_LCS_STATE_DETECTION_ENABLE 833*91f16700Schasinglulu reg = rcar_rom_get_lcs(&lcs); 834*91f16700Schasinglulu if (reg != 0U) { 835*91f16700Schasinglulu str = unknown; 836*91f16700Schasinglulu goto lcm_state; 837*91f16700Schasinglulu } 838*91f16700Schasinglulu 839*91f16700Schasinglulu switch (lcs) { 840*91f16700Schasinglulu case LCS_CM: 841*91f16700Schasinglulu str = lcs_cm; 842*91f16700Schasinglulu break; 843*91f16700Schasinglulu case LCS_DM: 844*91f16700Schasinglulu str = lcs_dm; 845*91f16700Schasinglulu break; 846*91f16700Schasinglulu case LCS_SD: 847*91f16700Schasinglulu str = lcs_sd; 848*91f16700Schasinglulu break; 849*91f16700Schasinglulu case LCS_SE: 850*91f16700Schasinglulu str = lcs_secure; 851*91f16700Schasinglulu break; 852*91f16700Schasinglulu case LCS_FA: 853*91f16700Schasinglulu str = lcs_fa; 854*91f16700Schasinglulu break; 855*91f16700Schasinglulu default: 856*91f16700Schasinglulu str = unknown; 857*91f16700Schasinglulu break; 858*91f16700Schasinglulu } 859*91f16700Schasinglulu 860*91f16700Schasinglulu lcm_state: 861*91f16700Schasinglulu NOTICE("BL2: LCM state is %s\n", str); 862*91f16700Schasinglulu #endif /* RZG_LCS_STATE_DETECTION_ENABLE */ 863*91f16700Schasinglulu 864*91f16700Schasinglulu rcar_avs_end(); 865*91f16700Schasinglulu is_ddr_backup_mode(); 866*91f16700Schasinglulu 867*91f16700Schasinglulu bl2_tzram_layout.total_base = BL31_BASE; 868*91f16700Schasinglulu bl2_tzram_layout.total_size = BL31_LIMIT - BL31_BASE; 869*91f16700Schasinglulu 870*91f16700Schasinglulu if (boot_cpu == MODEMR_BOOT_CPU_CA57 || 871*91f16700Schasinglulu boot_cpu == MODEMR_BOOT_CPU_CA53) { 872*91f16700Schasinglulu ret = rcar_dram_init(); 873*91f16700Schasinglulu if (ret != 0) { 874*91f16700Schasinglulu NOTICE("BL2: Failed to DRAM initialize (%d).\n", ret); 875*91f16700Schasinglulu panic(); 876*91f16700Schasinglulu } 877*91f16700Schasinglulu rzg_qos_init(); 878*91f16700Schasinglulu } 879*91f16700Schasinglulu 880*91f16700Schasinglulu /* Set up FDT */ 881*91f16700Schasinglulu ret = fdt_create_empty_tree(fdt, sizeof(fdt_blob)); 882*91f16700Schasinglulu if (ret != 0) { 883*91f16700Schasinglulu NOTICE("BL2: Cannot allocate FDT for U-Boot (ret=%i)\n", ret); 884*91f16700Schasinglulu panic(); 885*91f16700Schasinglulu } 886*91f16700Schasinglulu 887*91f16700Schasinglulu /* Add platform compatible string */ 888*91f16700Schasinglulu bl2_populate_compatible_string(fdt); 889*91f16700Schasinglulu 890*91f16700Schasinglulu /* Print DRAM layout */ 891*91f16700Schasinglulu bl2_advertise_dram_size(product); 892*91f16700Schasinglulu 893*91f16700Schasinglulu if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || 894*91f16700Schasinglulu boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) { 895*91f16700Schasinglulu if (rcar_emmc_init() != EMMC_SUCCESS) { 896*91f16700Schasinglulu NOTICE("BL2: Failed to eMMC driver initialize.\n"); 897*91f16700Schasinglulu panic(); 898*91f16700Schasinglulu } 899*91f16700Schasinglulu rcar_emmc_memcard_power(EMMC_POWER_ON); 900*91f16700Schasinglulu if (rcar_emmc_mount() != EMMC_SUCCESS) { 901*91f16700Schasinglulu NOTICE("BL2: Failed to eMMC mount operation.\n"); 902*91f16700Schasinglulu panic(); 903*91f16700Schasinglulu } 904*91f16700Schasinglulu } else { 905*91f16700Schasinglulu rcar_rpc_init(); 906*91f16700Schasinglulu rcar_dma_init(); 907*91f16700Schasinglulu } 908*91f16700Schasinglulu 909*91f16700Schasinglulu reg = mmio_read_32(RST_WDTRSTCR); 910*91f16700Schasinglulu reg &= ~WDTRSTCR_RWDT_RSTMSK; 911*91f16700Schasinglulu reg |= WDTRSTCR_PASSWORD; 912*91f16700Schasinglulu mmio_write_32(RST_WDTRSTCR, reg); 913*91f16700Schasinglulu 914*91f16700Schasinglulu mmio_write_32(CPG_CPGWPR, CPGWPR_PASSWORD); 915*91f16700Schasinglulu mmio_write_32(CPG_CPGWPCR, CPGWPCR_PASSWORD); 916*91f16700Schasinglulu 917*91f16700Schasinglulu reg = mmio_read_32(RCAR_PRR); 918*91f16700Schasinglulu if ((reg & RCAR_CPU_MASK_CA57) == RCAR_CPU_HAVE_CA57) { 919*91f16700Schasinglulu mmio_write_32(CPG_CA57DBGRCR, 920*91f16700Schasinglulu DBGCPUPREN | mmio_read_32(CPG_CA57DBGRCR)); 921*91f16700Schasinglulu } 922*91f16700Schasinglulu 923*91f16700Schasinglulu if ((reg & RCAR_CPU_MASK_CA53) == RCAR_CPU_HAVE_CA53) { 924*91f16700Schasinglulu mmio_write_32(CPG_CA53DBGRCR, 925*91f16700Schasinglulu DBGCPUPREN | mmio_read_32(CPG_CA53DBGRCR)); 926*91f16700Schasinglulu } 927*91f16700Schasinglulu 928*91f16700Schasinglulu if (product_cut == PRR_PRODUCT_H3_CUT10) { 929*91f16700Schasinglulu reg = mmio_read_32(CPG_PLL2CR); 930*91f16700Schasinglulu reg &= ~((uint32_t)1 << 5); 931*91f16700Schasinglulu mmio_write_32(CPG_PLL2CR, reg); 932*91f16700Schasinglulu 933*91f16700Schasinglulu reg = mmio_read_32(CPG_PLL4CR); 934*91f16700Schasinglulu reg &= ~((uint32_t)1 << 5); 935*91f16700Schasinglulu mmio_write_32(CPG_PLL4CR, reg); 936*91f16700Schasinglulu 937*91f16700Schasinglulu reg = mmio_read_32(CPG_PLL0CR); 938*91f16700Schasinglulu reg &= ~((uint32_t)1 << 12); 939*91f16700Schasinglulu mmio_write_32(CPG_PLL0CR, reg); 940*91f16700Schasinglulu } 941*91f16700Schasinglulu #if (RCAR_LOSSY_ENABLE == 1) 942*91f16700Schasinglulu NOTICE("BL2: Lossy Decomp areas\n"); 943*91f16700Schasinglulu 944*91f16700Schasinglulu fcnlnode = fdt_add_subnode(fdt, 0, "reserved-memory"); 945*91f16700Schasinglulu if (fcnlnode < 0) { 946*91f16700Schasinglulu NOTICE("BL2: Cannot create reserved mem node (ret=%i)\n", 947*91f16700Schasinglulu fcnlnode); 948*91f16700Schasinglulu panic(); 949*91f16700Schasinglulu } 950*91f16700Schasinglulu 951*91f16700Schasinglulu bl2_lossy_setting(0, LOSSY_ST_ADDR0, LOSSY_END_ADDR0, 952*91f16700Schasinglulu LOSSY_FMT0, LOSSY_ENA_DIS0, fcnlnode); 953*91f16700Schasinglulu bl2_lossy_setting(1, LOSSY_ST_ADDR1, LOSSY_END_ADDR1, 954*91f16700Schasinglulu LOSSY_FMT1, LOSSY_ENA_DIS1, fcnlnode); 955*91f16700Schasinglulu bl2_lossy_setting(2, LOSSY_ST_ADDR2, LOSSY_END_ADDR2, 956*91f16700Schasinglulu LOSSY_FMT2, LOSSY_ENA_DIS2, fcnlnode); 957*91f16700Schasinglulu #endif /* RCAR_LOSSY_ENABLE */ 958*91f16700Schasinglulu 959*91f16700Schasinglulu fdt_pack(fdt); 960*91f16700Schasinglulu NOTICE("BL2: FDT at %p\n", fdt); 961*91f16700Schasinglulu 962*91f16700Schasinglulu if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 || 963*91f16700Schasinglulu boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) { 964*91f16700Schasinglulu rcar_io_emmc_setup(); 965*91f16700Schasinglulu } else { 966*91f16700Schasinglulu rcar_io_setup(); 967*91f16700Schasinglulu } 968*91f16700Schasinglulu } 969*91f16700Schasinglulu 970*91f16700Schasinglulu void bl2_el3_plat_arch_setup(void) 971*91f16700Schasinglulu { 972*91f16700Schasinglulu #if RCAR_BL2_DCACHE == 1 973*91f16700Schasinglulu NOTICE("BL2: D-Cache enable\n"); 974*91f16700Schasinglulu rcar_configure_mmu_el3(BL2_BASE, 975*91f16700Schasinglulu BL2_END - BL2_BASE, 976*91f16700Schasinglulu BL2_RO_BASE, BL2_RO_LIMIT 977*91f16700Schasinglulu #if USE_COHERENT_MEM 978*91f16700Schasinglulu , BL2_COHERENT_RAM_BASE, BL2_COHERENT_RAM_LIMIT 979*91f16700Schasinglulu #endif /* USE_COHERENT_MEM */ 980*91f16700Schasinglulu ); 981*91f16700Schasinglulu #endif /* RCAR_BL2_DCACHE == 1 */ 982*91f16700Schasinglulu } 983*91f16700Schasinglulu 984*91f16700Schasinglulu void bl2_platform_setup(void) 985*91f16700Schasinglulu { 986*91f16700Schasinglulu /* 987*91f16700Schasinglulu * Place holder for performing any platform initialization specific 988*91f16700Schasinglulu * to BL2. 989*91f16700Schasinglulu */ 990*91f16700Schasinglulu } 991*91f16700Schasinglulu 992*91f16700Schasinglulu static void bl2_init_generic_timer(void) 993*91f16700Schasinglulu { 994*91f16700Schasinglulu #if RCAR_LSI == RZ_G2E 995*91f16700Schasinglulu uint32_t reg_cntfid = EXTAL_EBISU; 996*91f16700Schasinglulu #else 997*91f16700Schasinglulu uint32_t reg_cntfid; 998*91f16700Schasinglulu uint32_t modemr; 999*91f16700Schasinglulu uint32_t modemr_pll; 1000*91f16700Schasinglulu uint32_t pll_table[] = { 1001*91f16700Schasinglulu EXTAL_MD14_MD13_TYPE_0, /* MD14/MD13 : 0b00 */ 1002*91f16700Schasinglulu EXTAL_MD14_MD13_TYPE_1, /* MD14/MD13 : 0b01 */ 1003*91f16700Schasinglulu EXTAL_MD14_MD13_TYPE_2, /* MD14/MD13 : 0b10 */ 1004*91f16700Schasinglulu EXTAL_MD14_MD13_TYPE_3 /* MD14/MD13 : 0b11 */ 1005*91f16700Schasinglulu }; 1006*91f16700Schasinglulu 1007*91f16700Schasinglulu modemr = mmio_read_32(RCAR_MODEMR); 1008*91f16700Schasinglulu modemr_pll = (modemr & MODEMR_BOOT_PLL_MASK); 1009*91f16700Schasinglulu 1010*91f16700Schasinglulu /* Set frequency data in CNTFID0 */ 1011*91f16700Schasinglulu reg_cntfid = pll_table[modemr_pll >> MODEMR_BOOT_PLL_SHIFT]; 1012*91f16700Schasinglulu #endif /* RCAR_LSI == RZ_G2E */ 1013*91f16700Schasinglulu 1014*91f16700Schasinglulu /* Update memory mapped and register based frequency */ 1015*91f16700Schasinglulu write_cntfrq_el0((u_register_t)reg_cntfid); 1016*91f16700Schasinglulu mmio_write_32(ARM_SYS_CNTCTL_BASE + (uintptr_t)CNTFID_OFF, reg_cntfid); 1017*91f16700Schasinglulu /* Enable counter */ 1018*91f16700Schasinglulu mmio_setbits_32(RCAR_CNTC_BASE + (uintptr_t)CNTCR_OFF, 1019*91f16700Schasinglulu (uint32_t)CNTCR_EN); 1020*91f16700Schasinglulu } 1021