xref: /rk3399_rockchip-uboot/arch/arm/mach-omap2/hwinit-common.c (revision 3c9c4a2c509b194874ed729c5d683feb039ccc92)
1983e3700STom Rini /*
2983e3700STom Rini  *
3983e3700STom Rini  * Common functions for OMAP4/5 based boards
4983e3700STom Rini  *
5983e3700STom Rini  * (C) Copyright 2010
6983e3700STom Rini  * Texas Instruments, <www.ti.com>
7983e3700STom Rini  *
8983e3700STom Rini  * Author :
9983e3700STom Rini  *	Aneesh V	<aneesh@ti.com>
10983e3700STom Rini  *	Steve Sakoman	<steve@sakoman.com>
11983e3700STom Rini  *
12983e3700STom Rini  * SPDX-License-Identifier:	GPL-2.0+
13983e3700STom Rini  */
14983e3700STom Rini #include <common.h>
1501fe1199SLokesh Vutla #include <debug_uart.h>
16983e3700STom Rini #include <spl.h>
17983e3700STom Rini #include <asm/arch/sys_proto.h>
18983e3700STom Rini #include <linux/sizes.h>
19983e3700STom Rini #include <asm/emif.h>
20983e3700STom Rini #include <asm/omap_common.h>
21983e3700STom Rini #include <linux/compiler.h>
22983e3700STom Rini #include <asm/system.h>
23983e3700STom Rini 
24983e3700STom Rini DECLARE_GLOBAL_DATA_PTR;
25983e3700STom Rini 
do_set_mux(u32 base,struct pad_conf_entry const * array,int size)26983e3700STom Rini void do_set_mux(u32 base, struct pad_conf_entry const *array, int size)
27983e3700STom Rini {
28983e3700STom Rini 	int i;
29983e3700STom Rini 	struct pad_conf_entry *pad = (struct pad_conf_entry *) array;
30983e3700STom Rini 
31983e3700STom Rini 	for (i = 0; i < size; i++, pad++)
32983e3700STom Rini 		writew(pad->val, base + pad->offset);
33983e3700STom Rini }
34983e3700STom Rini 
set_mux_conf_regs(void)35983e3700STom Rini static void set_mux_conf_regs(void)
36983e3700STom Rini {
37983e3700STom Rini 	switch (omap_hw_init_context()) {
38983e3700STom Rini 	case OMAP_INIT_CONTEXT_SPL:
39983e3700STom Rini 		set_muxconf_regs();
40983e3700STom Rini 		break;
41983e3700STom Rini 	case OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL:
42983e3700STom Rini 		break;
43983e3700STom Rini 	case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR:
44983e3700STom Rini 	case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH:
45983e3700STom Rini 		set_muxconf_regs();
46983e3700STom Rini 		break;
47983e3700STom Rini 	}
48983e3700STom Rini }
49983e3700STom Rini 
cortex_rev(void)50983e3700STom Rini u32 cortex_rev(void)
51983e3700STom Rini {
52983e3700STom Rini 
53983e3700STom Rini 	unsigned int rev;
54983e3700STom Rini 
55983e3700STom Rini 	/* Read Main ID Register (MIDR) */
56983e3700STom Rini 	asm ("mrc p15, 0, %0, c0, c0, 0" : "=r" (rev));
57983e3700STom Rini 
58983e3700STom Rini 	return rev;
59983e3700STom Rini }
60983e3700STom Rini 
omap_rev_string(void)61983e3700STom Rini static void omap_rev_string(void)
62983e3700STom Rini {
63983e3700STom Rini 	u32 omap_rev = omap_revision();
64983e3700STom Rini 	u32 soc_variant	= (omap_rev & 0xF0000000) >> 28;
65983e3700STom Rini 	u32 omap_variant = (omap_rev & 0xFFFF0000) >> 16;
66983e3700STom Rini 	u32 major_rev = (omap_rev & 0x00000F00) >> 8;
67983e3700STom Rini 	u32 minor_rev = (omap_rev & 0x000000F0) >> 4;
68983e3700STom Rini 
69983e3700STom Rini 	const char *sec_s;
70983e3700STom Rini 
71983e3700STom Rini 	switch (get_device_type()) {
72983e3700STom Rini 	case TST_DEVICE:
73983e3700STom Rini 		sec_s = "TST";
74983e3700STom Rini 		break;
75983e3700STom Rini 	case EMU_DEVICE:
76983e3700STom Rini 		sec_s = "EMU";
77983e3700STom Rini 		break;
78983e3700STom Rini 	case HS_DEVICE:
79983e3700STom Rini 		sec_s = "HS";
80983e3700STom Rini 		break;
81983e3700STom Rini 	case GP_DEVICE:
82983e3700STom Rini 		sec_s = "GP";
83983e3700STom Rini 		break;
84983e3700STom Rini 	default:
85983e3700STom Rini 		sec_s = "?";
86983e3700STom Rini 	}
87983e3700STom Rini 
88983e3700STom Rini 	if (soc_variant)
89983e3700STom Rini 		printf("OMAP");
90983e3700STom Rini 	else
91983e3700STom Rini 		printf("DRA");
92983e3700STom Rini 	printf("%x-%s ES%x.%x\n", omap_variant, sec_s, major_rev, minor_rev);
93983e3700STom Rini }
94983e3700STom Rini 
95983e3700STom Rini #ifdef CONFIG_SPL_BUILD
spl_display_print(void)96983e3700STom Rini void spl_display_print(void)
97983e3700STom Rini {
98983e3700STom Rini 	omap_rev_string();
99983e3700STom Rini }
100983e3700STom Rini #endif
101983e3700STom Rini 
srcomp_enable(void)102983e3700STom Rini void __weak srcomp_enable(void)
103983e3700STom Rini {
104983e3700STom Rini }
105983e3700STom Rini 
106983e3700STom Rini /**
107983e3700STom Rini  * do_board_detect() - Detect board description
108983e3700STom Rini  *
109983e3700STom Rini  * Function to detect board description. This is expected to be
110983e3700STom Rini  * overridden in the SoC family board file where desired.
111983e3700STom Rini  */
do_board_detect(void)112983e3700STom Rini void __weak do_board_detect(void)
113983e3700STom Rini {
114983e3700STom Rini }
115983e3700STom Rini 
116983e3700STom Rini /**
117983e3700STom Rini  * vcores_init() - Assign omap_vcores based on board
118983e3700STom Rini  *
119983e3700STom Rini  * Function to pick the vcores based on board. This is expected to be
120983e3700STom Rini  * overridden in the SoC family board file where desired.
121983e3700STom Rini  */
vcores_init(void)122983e3700STom Rini void __weak vcores_init(void)
123983e3700STom Rini {
124983e3700STom Rini }
125983e3700STom Rini 
s_init(void)126983e3700STom Rini void s_init(void)
127983e3700STom Rini {
128983e3700STom Rini }
129983e3700STom Rini 
130983e3700STom Rini /**
131983e3700STom Rini  * early_system_init - Does Early system initialization.
132983e3700STom Rini  *
133983e3700STom Rini  * Does early system init of watchdog, muxing,  andclocks
134983e3700STom Rini  * Watchdog disable is done always. For the rest what gets done
135983e3700STom Rini  * depends on the boot mode in which this function is executed when
136983e3700STom Rini  *   1. SPL running from SRAM
137983e3700STom Rini  *   2. U-Boot running from FLASH
138983e3700STom Rini  *   3. U-Boot loaded to SDRAM by SPL
139983e3700STom Rini  *   4. U-Boot loaded to SDRAM by ROM code using the
140983e3700STom Rini  *	Configuration Header feature
141983e3700STom Rini  * Please have a look at the respective functions to see what gets
142983e3700STom Rini  * done in each of these cases
143983e3700STom Rini  * This function is called with SRAM stack.
144983e3700STom Rini  */
early_system_init(void)145983e3700STom Rini void early_system_init(void)
146983e3700STom Rini {
147983e3700STom Rini 	init_omap_revision();
148983e3700STom Rini 	hw_data_init();
149983e3700STom Rini 
150983e3700STom Rini #ifdef CONFIG_SPL_BUILD
151983e3700STom Rini 	if (warm_reset())
152983e3700STom Rini 		force_emif_self_refresh();
153983e3700STom Rini #endif
154983e3700STom Rini 	watchdog_init();
155983e3700STom Rini 	set_mux_conf_regs();
156983e3700STom Rini #ifdef CONFIG_SPL_BUILD
157983e3700STom Rini 	srcomp_enable();
158983e3700STom Rini 	do_io_settings();
159983e3700STom Rini #endif
160983e3700STom Rini 	setup_early_clocks();
1614bd754d8SLokesh Vutla #ifdef CONFIG_SPL_BUILD
1624bd754d8SLokesh Vutla 	/*
1634bd754d8SLokesh Vutla 	 * Save the boot parameters passed from romcode.
1644bd754d8SLokesh Vutla 	 * We cannot delay the saving further than this,
1654bd754d8SLokesh Vutla 	 * to prevent overwrites.
1664bd754d8SLokesh Vutla 	 */
1674bd754d8SLokesh Vutla 	save_omap_boot_params();
168*3c9c4a2cSLokesh Vutla 	spl_early_init();
1694bd754d8SLokesh Vutla #endif
170983e3700STom Rini 	do_board_detect();
171983e3700STom Rini 	vcores_init();
17201fe1199SLokesh Vutla #ifdef CONFIG_DEBUG_UART_OMAP
17301fe1199SLokesh Vutla 	debug_uart_init();
17401fe1199SLokesh Vutla #endif
175983e3700STom Rini 	prcm_init();
176983e3700STom Rini }
177983e3700STom Rini 
178983e3700STom Rini #ifdef CONFIG_SPL_BUILD
board_init_f(ulong dummy)179983e3700STom Rini void board_init_f(ulong dummy)
180983e3700STom Rini {
181983e3700STom Rini 	early_system_init();
182983e3700STom Rini #ifdef CONFIG_BOARD_EARLY_INIT_F
183983e3700STom Rini 	board_early_init_f();
184983e3700STom Rini #endif
185983e3700STom Rini 	/* For regular u-boot sdram_init() is called from dram_init() */
186983e3700STom Rini 	sdram_init();
18786282798SLokesh Vutla 	gd->ram_size = omap_sdram_size();
188983e3700STom Rini }
189983e3700STom Rini #endif
190983e3700STom Rini 
arch_cpu_init_dm(void)191983e3700STom Rini int arch_cpu_init_dm(void)
192983e3700STom Rini {
193983e3700STom Rini 	early_system_init();
194983e3700STom Rini 	return 0;
195983e3700STom Rini }
196983e3700STom Rini 
197983e3700STom Rini /*
198983e3700STom Rini  * Routine: wait_for_command_complete
199983e3700STom Rini  * Description: Wait for posting to finish on watchdog
200983e3700STom Rini  */
wait_for_command_complete(struct watchdog * wd_base)201983e3700STom Rini void wait_for_command_complete(struct watchdog *wd_base)
202983e3700STom Rini {
203983e3700STom Rini 	int pending = 1;
204983e3700STom Rini 	do {
205983e3700STom Rini 		pending = readl(&wd_base->wwps);
206983e3700STom Rini 	} while (pending);
207983e3700STom Rini }
208983e3700STom Rini 
209983e3700STom Rini /*
210983e3700STom Rini  * Routine: watchdog_init
211983e3700STom Rini  * Description: Shut down watch dogs
212983e3700STom Rini  */
watchdog_init(void)213983e3700STom Rini void watchdog_init(void)
214983e3700STom Rini {
215983e3700STom Rini 	struct watchdog *wd2_base = (struct watchdog *)WDT2_BASE;
216983e3700STom Rini 
217983e3700STom Rini 	writel(WD_UNLOCK1, &wd2_base->wspr);
218983e3700STom Rini 	wait_for_command_complete(wd2_base);
219983e3700STom Rini 	writel(WD_UNLOCK2, &wd2_base->wspr);
220983e3700STom Rini }
221983e3700STom Rini 
222983e3700STom Rini 
223983e3700STom Rini /*
224983e3700STom Rini  * This function finds the SDRAM size available in the system
225983e3700STom Rini  * based on DMM section configurations
226983e3700STom Rini  * This is needed because the size of memory installed may be
227983e3700STom Rini  * different on different versions of the board
228983e3700STom Rini  */
omap_sdram_size(void)229983e3700STom Rini u32 omap_sdram_size(void)
230983e3700STom Rini {
231983e3700STom Rini 	u32 section, i, valid;
232983e3700STom Rini 	u64 sdram_start = 0, sdram_end = 0, addr,
233983e3700STom Rini 	    size, total_size = 0, trap_size = 0, trap_start = 0;
234983e3700STom Rini 
235983e3700STom Rini 	for (i = 0; i < 4; i++) {
236983e3700STom Rini 		section	= __raw_readl(DMM_BASE + i*4);
237983e3700STom Rini 		valid = (section & EMIF_SDRC_ADDRSPC_MASK) >>
238983e3700STom Rini 			(EMIF_SDRC_ADDRSPC_SHIFT);
239983e3700STom Rini 		addr = section & EMIF_SYS_ADDR_MASK;
240983e3700STom Rini 
241983e3700STom Rini 		/* See if the address is valid */
242983e3700STom Rini 		if ((addr >= TI_ARMV7_DRAM_ADDR_SPACE_START) &&
243983e3700STom Rini 		    (addr < TI_ARMV7_DRAM_ADDR_SPACE_END)) {
244983e3700STom Rini 			size = ((section & EMIF_SYS_SIZE_MASK) >>
245983e3700STom Rini 				   EMIF_SYS_SIZE_SHIFT);
246983e3700STom Rini 			size = 1 << size;
247983e3700STom Rini 			size *= SZ_16M;
248983e3700STom Rini 
249983e3700STom Rini 			if (valid != DMM_SDRC_ADDR_SPC_INVALID) {
250983e3700STom Rini 				if (!sdram_start || (addr < sdram_start))
251983e3700STom Rini 					sdram_start = addr;
252983e3700STom Rini 				if (!sdram_end || ((addr + size) > sdram_end))
253983e3700STom Rini 					sdram_end = addr + size;
254983e3700STom Rini 			} else {
255983e3700STom Rini 				trap_size = size;
256983e3700STom Rini 				trap_start = addr;
257983e3700STom Rini 			}
258983e3700STom Rini 		}
259983e3700STom Rini 	}
260983e3700STom Rini 
261983e3700STom Rini 	if ((trap_start >= sdram_start) && (trap_start < sdram_end))
262983e3700STom Rini 		total_size = (sdram_end - sdram_start) - (trap_size);
263983e3700STom Rini 	else
264983e3700STom Rini 		total_size = sdram_end - sdram_start;
265983e3700STom Rini 
266983e3700STom Rini 	return total_size;
267983e3700STom Rini }
268983e3700STom Rini 
269983e3700STom Rini 
270983e3700STom Rini /*
271983e3700STom Rini  * Routine: dram_init
272983e3700STom Rini  * Description: sets uboots idea of sdram size
273983e3700STom Rini  */
dram_init(void)274983e3700STom Rini int dram_init(void)
275983e3700STom Rini {
276983e3700STom Rini 	sdram_init();
277983e3700STom Rini 	gd->ram_size = omap_sdram_size();
278983e3700STom Rini 	return 0;
279983e3700STom Rini }
280983e3700STom Rini 
281983e3700STom Rini /*
282983e3700STom Rini  * Print board information
283983e3700STom Rini  */
checkboard(void)284983e3700STom Rini int checkboard(void)
285983e3700STom Rini {
286983e3700STom Rini 	puts(sysinfo.board_string);
287983e3700STom Rini 	return 0;
288983e3700STom Rini }
289983e3700STom Rini 
290983e3700STom Rini #if defined(CONFIG_DISPLAY_CPUINFO)
291983e3700STom Rini /*
292983e3700STom Rini  * Print CPU information
293983e3700STom Rini  */
print_cpuinfo(void)294983e3700STom Rini int print_cpuinfo(void)
295983e3700STom Rini {
296983e3700STom Rini 	puts("CPU  : ");
297983e3700STom Rini 	omap_rev_string();
298983e3700STom Rini 
299983e3700STom Rini 	return 0;
300983e3700STom Rini }
301983e3700STom Rini #endif
302