xref: /rk3399_rockchip-uboot/arch/arm/cpu/armv8/fsl-layerscape/cpu.c (revision 85cdf38e69bbf3b2bb67c8218c8e4cbf28f8759b)
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