19f3183d2SMingkai Hu /* 29f3183d2SMingkai Hu * Copyright 2014-2015 Freescale Semiconductor, Inc. 39f3183d2SMingkai Hu * 49f3183d2SMingkai Hu * SPDX-License-Identifier: GPL-2.0+ 59f3183d2SMingkai Hu */ 69f3183d2SMingkai Hu 79f3183d2SMingkai Hu #include <common.h> 89f3183d2SMingkai Hu #include <asm/io.h> 99f3183d2SMingkai Hu #include <asm/errno.h> 109f3183d2SMingkai Hu #include <asm/system.h> 119f3183d2SMingkai Hu #include <asm/armv8/mmu.h> 129f3183d2SMingkai Hu #include <asm/io.h> 139f3183d2SMingkai Hu #include <asm/arch/fsl_serdes.h> 149f3183d2SMingkai Hu #include <asm/arch/soc.h> 159f3183d2SMingkai Hu #include <asm/arch/cpu.h> 169f3183d2SMingkai Hu #include <asm/arch/speed.h> 179f3183d2SMingkai Hu #ifdef CONFIG_MP 189f3183d2SMingkai Hu #include <asm/arch/mp.h> 199f3183d2SMingkai Hu #endif 209f3183d2SMingkai Hu #include <fm_eth.h> 219f3183d2SMingkai Hu #include <fsl_debug_server.h> 229f3183d2SMingkai Hu #include <fsl-mc/fsl_mc.h> 239f3183d2SMingkai Hu #ifdef CONFIG_FSL_ESDHC 249f3183d2SMingkai Hu #include <fsl_esdhc.h> 259f3183d2SMingkai Hu #endif 269f3183d2SMingkai Hu 279f3183d2SMingkai Hu DECLARE_GLOBAL_DATA_PTR; 289f3183d2SMingkai Hu 295ad5823dSYork Sun struct mm_region *mem_map = early_map; 307985cdf7SAlexander Graf 319f3183d2SMingkai Hu void cpu_name(char *name) 329f3183d2SMingkai Hu { 339f3183d2SMingkai Hu struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 349f3183d2SMingkai Hu unsigned int i, svr, ver; 359f3183d2SMingkai Hu 369f3183d2SMingkai Hu svr = gur_in32(&gur->svr); 379f3183d2SMingkai Hu ver = SVR_SOC_VER(svr); 389f3183d2SMingkai Hu 399f3183d2SMingkai Hu for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++) 409f3183d2SMingkai Hu if ((cpu_type_list[i].soc_ver & SVR_WO_E) == ver) { 419f3183d2SMingkai Hu strcpy(name, cpu_type_list[i].name); 429f3183d2SMingkai Hu 439f3183d2SMingkai Hu if (IS_E_PROCESSOR(svr)) 449f3183d2SMingkai Hu strcat(name, "E"); 459f3183d2SMingkai Hu break; 469f3183d2SMingkai Hu } 479f3183d2SMingkai Hu 489f3183d2SMingkai Hu if (i == ARRAY_SIZE(cpu_type_list)) 499f3183d2SMingkai Hu strcpy(name, "unknown"); 509f3183d2SMingkai Hu } 519f3183d2SMingkai Hu 529f3183d2SMingkai Hu #ifndef CONFIG_SYS_DCACHE_OFF 539f3183d2SMingkai Hu /* 549f3183d2SMingkai Hu * To start MMU before DDR is available, we create MMU table in SRAM. 559f3183d2SMingkai Hu * The base address of SRAM is CONFIG_SYS_FSL_OCRAM_BASE. We use three 569f3183d2SMingkai Hu * levels of translation tables here to cover 40-bit address space. 579f3183d2SMingkai Hu * We use 4KB granule size, with 40 bits physical address, T0SZ=24 585ad5823dSYork Sun * Address above EARLY_PGTABLE_SIZE (0x5000) is free for other purpose. 595ad5823dSYork Sun * Note, the debug print in cache_v8.c is not usable for debugging 605ad5823dSYork Sun * these early MMU tables because UART is not yet available. 619f3183d2SMingkai Hu */ 629f3183d2SMingkai Hu static inline void early_mmu_setup(void) 639f3183d2SMingkai Hu { 645ad5823dSYork Sun unsigned int el = current_el(); 659f3183d2SMingkai Hu 665ad5823dSYork Sun /* global data is already setup, no allocation yet */ 675ad5823dSYork Sun gd->arch.tlb_addr = CONFIG_SYS_FSL_OCRAM_BASE; 685ad5823dSYork Sun gd->arch.tlb_fillptr = gd->arch.tlb_addr; 695ad5823dSYork Sun gd->arch.tlb_size = EARLY_PGTABLE_SIZE; 709f3183d2SMingkai Hu 715ad5823dSYork Sun /* Create early page tables */ 725ad5823dSYork Sun setup_pgtables(); 739f3183d2SMingkai Hu 745ad5823dSYork Sun /* point TTBR to the new table */ 755ad5823dSYork Sun set_ttbr_tcr_mair(el, gd->arch.tlb_addr, 765ad5823dSYork Sun get_tcr(el, NULL, NULL) & 775ad5823dSYork Sun ~(TCR_ORGN_MASK | TCR_IRGN_MASK), 789f3183d2SMingkai Hu MEMORY_ATTRIBUTES); 795ad5823dSYork Sun 809f3183d2SMingkai Hu set_sctlr(get_sctlr() | CR_M); 819f3183d2SMingkai Hu } 829f3183d2SMingkai Hu 839f3183d2SMingkai Hu /* 849f3183d2SMingkai Hu * The final tables look similar to early tables, but different in detail. 859f3183d2SMingkai Hu * These tables are in DRAM. Sub tables are added to enable cache for 869f3183d2SMingkai Hu * QBMan and OCRAM. 879f3183d2SMingkai Hu * 88e61a7534SYork Sun * Put the MMU table in secure memory if gd->arch.secure_ram is valid. 89e61a7534SYork Sun * OCRAM will be not used for this purpose so gd->arch.secure_ram can't be 0. 909f3183d2SMingkai Hu */ 919f3183d2SMingkai Hu static inline void final_mmu_setup(void) 929f3183d2SMingkai Hu { 935ad5823dSYork Sun u64 tlb_addr_save = gd->arch.tlb_addr; 94c107c0c0SYork Sun unsigned int el = current_el(); 955ad5823dSYork Sun #ifdef CONFIG_SYS_MEM_RESERVE_SECURE 965ad5823dSYork Sun int index; 979f3183d2SMingkai Hu #endif 985ad5823dSYork Sun 995ad5823dSYork Sun mem_map = final_map; 100c107c0c0SYork Sun 101c107c0c0SYork Sun #ifdef CONFIG_SYS_MEM_RESERVE_SECURE 1025ad5823dSYork Sun if (gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED) { 103c107c0c0SYork Sun if (el == 3) { 104c107c0c0SYork Sun /* 1055ad5823dSYork Sun * Only use gd->arch.secure_ram if the address is 1065ad5823dSYork Sun * recalculated. Align to 4KB for MMU table. 107c107c0c0SYork Sun */ 1085ad5823dSYork Sun /* put page tables in secure ram */ 1095ad5823dSYork Sun index = ARRAY_SIZE(final_map) - 2; 1105ad5823dSYork Sun gd->arch.tlb_addr = gd->arch.secure_ram & ~0xfff; 1115ad5823dSYork Sun final_map[index].virt = gd->arch.secure_ram & ~0x3; 1125ad5823dSYork Sun final_map[index].phys = final_map[index].virt; 1135ad5823dSYork Sun final_map[index].size = CONFIG_SYS_MEM_RESERVE_SECURE; 1145ad5823dSYork Sun final_map[index].attrs = PTE_BLOCK_OUTER_SHARE; 115e61a7534SYork Sun gd->arch.secure_ram |= MEM_RESERVE_SECURE_SECURED; 1165ad5823dSYork Sun tlb_addr_save = gd->arch.tlb_addr; 117c107c0c0SYork Sun } else { 1185ad5823dSYork Sun /* Use allocated (board_f.c) memory for TLB */ 1195ad5823dSYork Sun tlb_addr_save = gd->arch.tlb_allocated; 1205ad5823dSYork Sun gd->arch.tlb_addr = tlb_addr_save; 121c107c0c0SYork Sun } 122c107c0c0SYork Sun } 123c107c0c0SYork Sun #endif 1249f3183d2SMingkai Hu 1255ad5823dSYork Sun /* Reset the fill ptr */ 1265ad5823dSYork Sun gd->arch.tlb_fillptr = tlb_addr_save; 1275ad5823dSYork Sun 1285ad5823dSYork Sun /* Create normal system page tables */ 1295ad5823dSYork Sun setup_pgtables(); 1305ad5823dSYork Sun 1315ad5823dSYork Sun /* Create emergency page tables */ 1325ad5823dSYork Sun gd->arch.tlb_addr = gd->arch.tlb_fillptr; 1335ad5823dSYork Sun gd->arch.tlb_emerg = gd->arch.tlb_addr; 1345ad5823dSYork Sun setup_pgtables(); 1355ad5823dSYork Sun gd->arch.tlb_addr = tlb_addr_save; 1365ad5823dSYork Sun 1379f3183d2SMingkai Hu /* flush new MMU table */ 1385ad5823dSYork Sun flush_dcache_range(gd->arch.tlb_addr, 1395ad5823dSYork Sun gd->arch.tlb_addr + gd->arch.tlb_size); 1409f3183d2SMingkai Hu 1419f3183d2SMingkai Hu /* point TTBR to the new table */ 1425ad5823dSYork Sun set_ttbr_tcr_mair(el, gd->arch.tlb_addr, get_tcr(el, NULL, NULL), 1439f3183d2SMingkai Hu MEMORY_ATTRIBUTES); 1449f3183d2SMingkai Hu /* 1459f3183d2SMingkai Hu * MMU is already enabled, just need to invalidate TLB to load the 1469f3183d2SMingkai Hu * new table. The new table is compatible with the current table, if 1479f3183d2SMingkai Hu * MMU somehow walks through the new table before invalidation TLB, 1489f3183d2SMingkai Hu * it still works. So we don't need to turn off MMU here. 1499f3183d2SMingkai Hu */ 1509f3183d2SMingkai Hu } 1519f3183d2SMingkai Hu 152c05016abSAlexander Graf u64 get_page_table_size(void) 153c05016abSAlexander Graf { 154c05016abSAlexander Graf return 0x10000; 155c05016abSAlexander Graf } 156c05016abSAlexander Graf 1579f3183d2SMingkai Hu int arch_cpu_init(void) 1589f3183d2SMingkai Hu { 1599f3183d2SMingkai Hu icache_enable(); 1609f3183d2SMingkai Hu __asm_invalidate_dcache_all(); 1619f3183d2SMingkai Hu __asm_invalidate_tlb_all(); 1629f3183d2SMingkai Hu early_mmu_setup(); 1639f3183d2SMingkai Hu set_sctlr(get_sctlr() | CR_C); 1649f3183d2SMingkai Hu return 0; 1659f3183d2SMingkai Hu } 1669f3183d2SMingkai Hu 167*85cdf38eSHou Zhiqiang void mmu_setup(void) 168*85cdf38eSHou Zhiqiang { 169*85cdf38eSHou Zhiqiang final_mmu_setup(); 170*85cdf38eSHou Zhiqiang } 171*85cdf38eSHou Zhiqiang 1729f3183d2SMingkai Hu /* 173*85cdf38eSHou Zhiqiang * This function is called from common/board_r.c. 174*85cdf38eSHou Zhiqiang * It recreates MMU table in main memory. 1759f3183d2SMingkai Hu */ 1769f3183d2SMingkai Hu void enable_caches(void) 1779f3183d2SMingkai Hu { 178*85cdf38eSHou Zhiqiang mmu_setup(); 1799f3183d2SMingkai Hu __asm_invalidate_tlb_all(); 180*85cdf38eSHou Zhiqiang icache_enable(); 181*85cdf38eSHou Zhiqiang dcache_enable(); 1829f3183d2SMingkai Hu } 1839f3183d2SMingkai Hu #endif 1849f3183d2SMingkai Hu 1859f3183d2SMingkai Hu static inline u32 initiator_type(u32 cluster, int init_id) 1869f3183d2SMingkai Hu { 1879f3183d2SMingkai Hu struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 1889f3183d2SMingkai Hu u32 idx = (cluster >> (init_id * 8)) & TP_CLUSTER_INIT_MASK; 1899f3183d2SMingkai Hu u32 type = 0; 1909f3183d2SMingkai Hu 1919f3183d2SMingkai Hu type = gur_in32(&gur->tp_ityp[idx]); 1929f3183d2SMingkai Hu if (type & TP_ITYP_AV) 1939f3183d2SMingkai Hu return type; 1949f3183d2SMingkai Hu 1959f3183d2SMingkai Hu return 0; 1969f3183d2SMingkai Hu } 1979f3183d2SMingkai Hu 1989f3183d2SMingkai Hu u32 cpu_mask(void) 1999f3183d2SMingkai Hu { 2009f3183d2SMingkai Hu struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 2019f3183d2SMingkai Hu int i = 0, count = 0; 2029f3183d2SMingkai Hu u32 cluster, type, mask = 0; 2039f3183d2SMingkai Hu 2049f3183d2SMingkai Hu do { 2059f3183d2SMingkai Hu int j; 2069f3183d2SMingkai Hu 2079f3183d2SMingkai Hu cluster = gur_in32(&gur->tp_cluster[i].lower); 2089f3183d2SMingkai Hu for (j = 0; j < TP_INIT_PER_CLUSTER; j++) { 2099f3183d2SMingkai Hu type = initiator_type(cluster, j); 2109f3183d2SMingkai Hu if (type) { 2119f3183d2SMingkai Hu if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_ARM) 2129f3183d2SMingkai Hu mask |= 1 << count; 2139f3183d2SMingkai Hu count++; 2149f3183d2SMingkai Hu } 2159f3183d2SMingkai Hu } 2169f3183d2SMingkai Hu i++; 2179f3183d2SMingkai Hu } while ((cluster & TP_CLUSTER_EOC) == 0x0); 2189f3183d2SMingkai Hu 2199f3183d2SMingkai Hu return mask; 2209f3183d2SMingkai Hu } 2219f3183d2SMingkai Hu 2229f3183d2SMingkai Hu /* 2239f3183d2SMingkai Hu * Return the number of cores on this SOC. 2249f3183d2SMingkai Hu */ 2259f3183d2SMingkai Hu int cpu_numcores(void) 2269f3183d2SMingkai Hu { 2279f3183d2SMingkai Hu return hweight32(cpu_mask()); 2289f3183d2SMingkai Hu } 2299f3183d2SMingkai Hu 2309f3183d2SMingkai Hu int fsl_qoriq_core_to_cluster(unsigned int core) 2319f3183d2SMingkai Hu { 2329f3183d2SMingkai Hu struct ccsr_gur __iomem *gur = 2339f3183d2SMingkai Hu (void __iomem *)(CONFIG_SYS_FSL_GUTS_ADDR); 2349f3183d2SMingkai Hu int i = 0, count = 0; 2359f3183d2SMingkai Hu u32 cluster; 2369f3183d2SMingkai Hu 2379f3183d2SMingkai Hu do { 2389f3183d2SMingkai Hu int j; 2399f3183d2SMingkai Hu 2409f3183d2SMingkai Hu cluster = gur_in32(&gur->tp_cluster[i].lower); 2419f3183d2SMingkai Hu for (j = 0; j < TP_INIT_PER_CLUSTER; j++) { 2429f3183d2SMingkai Hu if (initiator_type(cluster, j)) { 2439f3183d2SMingkai Hu if (count == core) 2449f3183d2SMingkai Hu return i; 2459f3183d2SMingkai Hu count++; 2469f3183d2SMingkai Hu } 2479f3183d2SMingkai Hu } 2489f3183d2SMingkai Hu i++; 2499f3183d2SMingkai Hu } while ((cluster & TP_CLUSTER_EOC) == 0x0); 2509f3183d2SMingkai Hu 2519f3183d2SMingkai Hu return -1; /* cannot identify the cluster */ 2529f3183d2SMingkai Hu } 2539f3183d2SMingkai Hu 2549f3183d2SMingkai Hu u32 fsl_qoriq_core_to_type(unsigned int core) 2559f3183d2SMingkai Hu { 2569f3183d2SMingkai Hu struct ccsr_gur __iomem *gur = 2579f3183d2SMingkai Hu (void __iomem *)(CONFIG_SYS_FSL_GUTS_ADDR); 2589f3183d2SMingkai Hu int i = 0, count = 0; 2599f3183d2SMingkai Hu u32 cluster, type; 2609f3183d2SMingkai Hu 2619f3183d2SMingkai Hu do { 2629f3183d2SMingkai Hu int j; 2639f3183d2SMingkai Hu 2649f3183d2SMingkai Hu cluster = gur_in32(&gur->tp_cluster[i].lower); 2659f3183d2SMingkai Hu for (j = 0; j < TP_INIT_PER_CLUSTER; j++) { 2669f3183d2SMingkai Hu type = initiator_type(cluster, j); 2679f3183d2SMingkai Hu if (type) { 2689f3183d2SMingkai Hu if (count == core) 2699f3183d2SMingkai Hu return type; 2709f3183d2SMingkai Hu count++; 2719f3183d2SMingkai Hu } 2729f3183d2SMingkai Hu } 2739f3183d2SMingkai Hu i++; 2749f3183d2SMingkai Hu } while ((cluster & TP_CLUSTER_EOC) == 0x0); 2759f3183d2SMingkai Hu 2769f3183d2SMingkai Hu return -1; /* cannot identify the cluster */ 2779f3183d2SMingkai Hu } 2789f3183d2SMingkai Hu 2796fb522dcSSriram Dash uint get_svr(void) 2806fb522dcSSriram Dash { 2816fb522dcSSriram Dash struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 2826fb522dcSSriram Dash 2836fb522dcSSriram Dash return gur_in32(&gur->svr); 2846fb522dcSSriram Dash } 2856fb522dcSSriram Dash 2869f3183d2SMingkai Hu #ifdef CONFIG_DISPLAY_CPUINFO 2879f3183d2SMingkai Hu int print_cpuinfo(void) 2889f3183d2SMingkai Hu { 2899f3183d2SMingkai Hu struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 2909f3183d2SMingkai Hu struct sys_info sysinfo; 2919f3183d2SMingkai Hu char buf[32]; 2929f3183d2SMingkai Hu unsigned int i, core; 2933c1d218aSYork Sun u32 type, rcw, svr = gur_in32(&gur->svr); 2949f3183d2SMingkai Hu 2959f3183d2SMingkai Hu puts("SoC: "); 2969f3183d2SMingkai Hu 2979f3183d2SMingkai Hu cpu_name(buf); 2983c1d218aSYork Sun printf(" %s (0x%x)\n", buf, svr); 2999f3183d2SMingkai Hu memset((u8 *)buf, 0x00, ARRAY_SIZE(buf)); 3009f3183d2SMingkai Hu get_sys_info(&sysinfo); 3019f3183d2SMingkai Hu puts("Clock Configuration:"); 3029f3183d2SMingkai Hu for_each_cpu(i, core, cpu_numcores(), cpu_mask()) { 3039f3183d2SMingkai Hu if (!(i % 3)) 3049f3183d2SMingkai Hu puts("\n "); 3059f3183d2SMingkai Hu type = TP_ITYP_VER(fsl_qoriq_core_to_type(core)); 3069f3183d2SMingkai Hu printf("CPU%d(%s):%-4s MHz ", core, 3079f3183d2SMingkai Hu type == TY_ITYP_VER_A7 ? "A7 " : 3089f3183d2SMingkai Hu (type == TY_ITYP_VER_A53 ? "A53" : 3099f3183d2SMingkai Hu (type == TY_ITYP_VER_A57 ? "A57" : " ")), 3109f3183d2SMingkai Hu strmhz(buf, sysinfo.freq_processor[core])); 3119f3183d2SMingkai Hu } 3129f3183d2SMingkai Hu printf("\n Bus: %-4s MHz ", 3139f3183d2SMingkai Hu strmhz(buf, sysinfo.freq_systembus)); 3149f3183d2SMingkai Hu printf("DDR: %-4s MT/s", strmhz(buf, sysinfo.freq_ddrbus)); 315e8297341SShaohui Xie #ifdef CONFIG_SYS_DPAA_FMAN 316e8297341SShaohui Xie printf(" FMAN: %-4s MHz", strmhz(buf, sysinfo.freq_fman[0])); 317e8297341SShaohui Xie #endif 31844937214SPrabhakar Kushwaha #ifdef CONFIG_SYS_FSL_HAS_DP_DDR 3193c1d218aSYork Sun if (soc_has_dp_ddr()) { 3203c1d218aSYork Sun printf(" DP-DDR: %-4s MT/s", 3213c1d218aSYork Sun strmhz(buf, sysinfo.freq_ddrbus2)); 3223c1d218aSYork Sun } 3239f3183d2SMingkai Hu #endif 3249f3183d2SMingkai Hu puts("\n"); 3259f3183d2SMingkai Hu 3269f3183d2SMingkai Hu /* 3279f3183d2SMingkai Hu * Display the RCW, so that no one gets confused as to what RCW 3289f3183d2SMingkai Hu * we're actually using for this boot. 3299f3183d2SMingkai Hu */ 3309f3183d2SMingkai Hu puts("Reset Configuration Word (RCW):"); 3319f3183d2SMingkai Hu for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) { 3329f3183d2SMingkai Hu rcw = gur_in32(&gur->rcwsr[i]); 3339f3183d2SMingkai Hu if ((i % 4) == 0) 3349f3183d2SMingkai Hu printf("\n %08x:", i * 4); 3359f3183d2SMingkai Hu printf(" %08x", rcw); 3369f3183d2SMingkai Hu } 3379f3183d2SMingkai Hu puts("\n"); 3389f3183d2SMingkai Hu 3399f3183d2SMingkai Hu return 0; 3409f3183d2SMingkai Hu } 3419f3183d2SMingkai Hu #endif 3429f3183d2SMingkai Hu 3439f3183d2SMingkai Hu #ifdef CONFIG_FSL_ESDHC 3449f3183d2SMingkai Hu int cpu_mmc_init(bd_t *bis) 3459f3183d2SMingkai Hu { 3469f3183d2SMingkai Hu return fsl_esdhc_mmc_init(bis); 3479f3183d2SMingkai Hu } 3489f3183d2SMingkai Hu #endif 3499f3183d2SMingkai Hu 3509f3183d2SMingkai Hu int cpu_eth_init(bd_t *bis) 3519f3183d2SMingkai Hu { 3529f3183d2SMingkai Hu int error = 0; 3539f3183d2SMingkai Hu 3549f3183d2SMingkai Hu #ifdef CONFIG_FSL_MC_ENET 3559f3183d2SMingkai Hu error = fsl_mc_ldpaa_init(bis); 3569f3183d2SMingkai Hu #endif 357e8297341SShaohui Xie #ifdef CONFIG_FMAN_ENET 358e8297341SShaohui Xie fm_standard_init(bis); 359e8297341SShaohui Xie #endif 3609f3183d2SMingkai Hu return error; 3619f3183d2SMingkai Hu } 3629f3183d2SMingkai Hu 3639f3183d2SMingkai Hu int arch_early_init_r(void) 3649f3183d2SMingkai Hu { 3659f3183d2SMingkai Hu #ifdef CONFIG_MP 3669f3183d2SMingkai Hu int rv = 1; 367b4017364SPrabhakar Kushwaha #endif 3689f3183d2SMingkai Hu 369b4017364SPrabhakar Kushwaha #ifdef CONFIG_SYS_FSL_ERRATUM_A009635 370b4017364SPrabhakar Kushwaha erratum_a009635(); 371b4017364SPrabhakar Kushwaha #endif 372b4017364SPrabhakar Kushwaha 373b4017364SPrabhakar Kushwaha #ifdef CONFIG_MP 3749f3183d2SMingkai Hu rv = fsl_layerscape_wake_seconday_cores(); 3759f3183d2SMingkai Hu if (rv) 3769f3183d2SMingkai Hu printf("Did not wake secondary cores\n"); 3779f3183d2SMingkai Hu #endif 3789f3183d2SMingkai Hu 3799f3183d2SMingkai Hu #ifdef CONFIG_SYS_HAS_SERDES 3809f3183d2SMingkai Hu fsl_serdes_init(); 3819f3183d2SMingkai Hu #endif 382e8297341SShaohui Xie #ifdef CONFIG_FMAN_ENET 383e8297341SShaohui Xie fman_enet_init(); 384e8297341SShaohui Xie #endif 3859f3183d2SMingkai Hu return 0; 3869f3183d2SMingkai Hu } 3879f3183d2SMingkai Hu 3889f3183d2SMingkai Hu int timer_init(void) 3899f3183d2SMingkai Hu { 3909f3183d2SMingkai Hu u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR; 3919f3183d2SMingkai Hu #ifdef CONFIG_FSL_LSCH3 3929f3183d2SMingkai Hu u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR; 3939f3183d2SMingkai Hu #endif 394a758177fSYunhui Cui #ifdef CONFIG_LS2080A 395a758177fSYunhui Cui u32 __iomem *pctbenr = (u32 *)FSL_PMU_PCTBENR_OFFSET; 396a758177fSYunhui Cui #endif 3979f3183d2SMingkai Hu #ifdef COUNTER_FREQUENCY_REAL 3989f3183d2SMingkai Hu unsigned long cntfrq = COUNTER_FREQUENCY_REAL; 3999f3183d2SMingkai Hu 4009f3183d2SMingkai Hu /* Update with accurate clock frequency */ 4019f3183d2SMingkai Hu asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory"); 4029f3183d2SMingkai Hu #endif 4039f3183d2SMingkai Hu 4049f3183d2SMingkai Hu #ifdef CONFIG_FSL_LSCH3 4059f3183d2SMingkai Hu /* Enable timebase for all clusters. 4069f3183d2SMingkai Hu * It is safe to do so even some clusters are not enabled. 4079f3183d2SMingkai Hu */ 4089f3183d2SMingkai Hu out_le32(cltbenr, 0xf); 4099f3183d2SMingkai Hu #endif 4109f3183d2SMingkai Hu 411a758177fSYunhui Cui #ifdef CONFIG_LS2080A 412a758177fSYunhui Cui /* 413a758177fSYunhui Cui * In certain Layerscape SoCs, the clock for each core's 414a758177fSYunhui Cui * has an enable bit in the PMU Physical Core Time Base Enable 415a758177fSYunhui Cui * Register (PCTBENR), which allows the watchdog to operate. 416a758177fSYunhui Cui */ 417a758177fSYunhui Cui setbits_le32(pctbenr, 0xff); 418a758177fSYunhui Cui #endif 419a758177fSYunhui Cui 4209f3183d2SMingkai Hu /* Enable clock for timer 4219f3183d2SMingkai Hu * This is a global setting. 4229f3183d2SMingkai Hu */ 4239f3183d2SMingkai Hu out_le32(cntcr, 0x1); 4249f3183d2SMingkai Hu 4259f3183d2SMingkai Hu return 0; 4269f3183d2SMingkai Hu } 4279f3183d2SMingkai Hu 4289f3183d2SMingkai Hu void reset_cpu(ulong addr) 4299f3183d2SMingkai Hu { 4309f3183d2SMingkai Hu u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR; 4319f3183d2SMingkai Hu u32 val; 4329f3183d2SMingkai Hu 4339f3183d2SMingkai Hu /* Raise RESET_REQ_B */ 4349f3183d2SMingkai Hu val = scfg_in32(rstcr); 4359f3183d2SMingkai Hu val |= 0x02; 4369f3183d2SMingkai Hu scfg_out32(rstcr, val); 4379f3183d2SMingkai Hu } 438c0492141SYork Sun 439c0492141SYork Sun phys_size_t board_reserve_ram_top(phys_size_t ram_size) 440c0492141SYork Sun { 441c0492141SYork Sun phys_size_t ram_top = ram_size; 442c0492141SYork Sun 443c0492141SYork Sun #ifdef CONFIG_SYS_MEM_TOP_HIDE 444c0492141SYork Sun #error CONFIG_SYS_MEM_TOP_HIDE not to be used together with this function 445c0492141SYork Sun #endif 446c0492141SYork Sun /* Carve the Debug Server private DRAM block from the end of DRAM */ 447c0492141SYork Sun #ifdef CONFIG_FSL_DEBUG_SERVER 448c0492141SYork Sun ram_top -= debug_server_get_dram_block_size(); 449c0492141SYork Sun #endif 450c0492141SYork Sun 451c0492141SYork Sun /* Carve the MC private DRAM block from the end of DRAM */ 452c0492141SYork Sun #ifdef CONFIG_FSL_MC_ENET 453c0492141SYork Sun ram_top -= mc_get_dram_block_size(); 454c0492141SYork Sun ram_top &= ~(CONFIG_SYS_MC_RSV_MEM_ALIGN - 1); 455c0492141SYork Sun #endif 456c0492141SYork Sun 457c0492141SYork Sun return ram_top; 458c0492141SYork Sun } 459