1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun * Common functions for OMAP4/5 based boards
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * (C) Copyright 2010
6*4882a593Smuzhiyun * Texas Instruments, <www.ti.com>
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Author :
9*4882a593Smuzhiyun * Aneesh V <aneesh@ti.com>
10*4882a593Smuzhiyun * Steve Sakoman <steve@sakoman.com>
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
13*4882a593Smuzhiyun */
14*4882a593Smuzhiyun #include <common.h>
15*4882a593Smuzhiyun #include <debug_uart.h>
16*4882a593Smuzhiyun #include <spl.h>
17*4882a593Smuzhiyun #include <asm/arch/sys_proto.h>
18*4882a593Smuzhiyun #include <linux/sizes.h>
19*4882a593Smuzhiyun #include <asm/emif.h>
20*4882a593Smuzhiyun #include <asm/omap_common.h>
21*4882a593Smuzhiyun #include <linux/compiler.h>
22*4882a593Smuzhiyun #include <asm/system.h>
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
25*4882a593Smuzhiyun
do_set_mux(u32 base,struct pad_conf_entry const * array,int size)26*4882a593Smuzhiyun void do_set_mux(u32 base, struct pad_conf_entry const *array, int size)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun int i;
29*4882a593Smuzhiyun struct pad_conf_entry *pad = (struct pad_conf_entry *) array;
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun for (i = 0; i < size; i++, pad++)
32*4882a593Smuzhiyun writew(pad->val, base + pad->offset);
33*4882a593Smuzhiyun }
34*4882a593Smuzhiyun
set_mux_conf_regs(void)35*4882a593Smuzhiyun static void set_mux_conf_regs(void)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun switch (omap_hw_init_context()) {
38*4882a593Smuzhiyun case OMAP_INIT_CONTEXT_SPL:
39*4882a593Smuzhiyun set_muxconf_regs();
40*4882a593Smuzhiyun break;
41*4882a593Smuzhiyun case OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL:
42*4882a593Smuzhiyun break;
43*4882a593Smuzhiyun case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR:
44*4882a593Smuzhiyun case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH:
45*4882a593Smuzhiyun set_muxconf_regs();
46*4882a593Smuzhiyun break;
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun
cortex_rev(void)50*4882a593Smuzhiyun u32 cortex_rev(void)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun unsigned int rev;
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun /* Read Main ID Register (MIDR) */
56*4882a593Smuzhiyun asm ("mrc p15, 0, %0, c0, c0, 0" : "=r" (rev));
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun return rev;
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun
omap_rev_string(void)61*4882a593Smuzhiyun static void omap_rev_string(void)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun u32 omap_rev = omap_revision();
64*4882a593Smuzhiyun u32 soc_variant = (omap_rev & 0xF0000000) >> 28;
65*4882a593Smuzhiyun u32 omap_variant = (omap_rev & 0xFFFF0000) >> 16;
66*4882a593Smuzhiyun u32 major_rev = (omap_rev & 0x00000F00) >> 8;
67*4882a593Smuzhiyun u32 minor_rev = (omap_rev & 0x000000F0) >> 4;
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun const char *sec_s;
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun switch (get_device_type()) {
72*4882a593Smuzhiyun case TST_DEVICE:
73*4882a593Smuzhiyun sec_s = "TST";
74*4882a593Smuzhiyun break;
75*4882a593Smuzhiyun case EMU_DEVICE:
76*4882a593Smuzhiyun sec_s = "EMU";
77*4882a593Smuzhiyun break;
78*4882a593Smuzhiyun case HS_DEVICE:
79*4882a593Smuzhiyun sec_s = "HS";
80*4882a593Smuzhiyun break;
81*4882a593Smuzhiyun case GP_DEVICE:
82*4882a593Smuzhiyun sec_s = "GP";
83*4882a593Smuzhiyun break;
84*4882a593Smuzhiyun default:
85*4882a593Smuzhiyun sec_s = "?";
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun if (soc_variant)
89*4882a593Smuzhiyun printf("OMAP");
90*4882a593Smuzhiyun else
91*4882a593Smuzhiyun printf("DRA");
92*4882a593Smuzhiyun printf("%x-%s ES%x.%x\n", omap_variant, sec_s, major_rev, minor_rev);
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun #ifdef CONFIG_SPL_BUILD
spl_display_print(void)96*4882a593Smuzhiyun void spl_display_print(void)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun omap_rev_string();
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun #endif
101*4882a593Smuzhiyun
srcomp_enable(void)102*4882a593Smuzhiyun void __weak srcomp_enable(void)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun /**
107*4882a593Smuzhiyun * do_board_detect() - Detect board description
108*4882a593Smuzhiyun *
109*4882a593Smuzhiyun * Function to detect board description. This is expected to be
110*4882a593Smuzhiyun * overridden in the SoC family board file where desired.
111*4882a593Smuzhiyun */
do_board_detect(void)112*4882a593Smuzhiyun void __weak do_board_detect(void)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun /**
117*4882a593Smuzhiyun * vcores_init() - Assign omap_vcores based on board
118*4882a593Smuzhiyun *
119*4882a593Smuzhiyun * Function to pick the vcores based on board. This is expected to be
120*4882a593Smuzhiyun * overridden in the SoC family board file where desired.
121*4882a593Smuzhiyun */
vcores_init(void)122*4882a593Smuzhiyun void __weak vcores_init(void)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun
s_init(void)126*4882a593Smuzhiyun void s_init(void)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun /**
131*4882a593Smuzhiyun * early_system_init - Does Early system initialization.
132*4882a593Smuzhiyun *
133*4882a593Smuzhiyun * Does early system init of watchdog, muxing, andclocks
134*4882a593Smuzhiyun * Watchdog disable is done always. For the rest what gets done
135*4882a593Smuzhiyun * depends on the boot mode in which this function is executed when
136*4882a593Smuzhiyun * 1. SPL running from SRAM
137*4882a593Smuzhiyun * 2. U-Boot running from FLASH
138*4882a593Smuzhiyun * 3. U-Boot loaded to SDRAM by SPL
139*4882a593Smuzhiyun * 4. U-Boot loaded to SDRAM by ROM code using the
140*4882a593Smuzhiyun * Configuration Header feature
141*4882a593Smuzhiyun * Please have a look at the respective functions to see what gets
142*4882a593Smuzhiyun * done in each of these cases
143*4882a593Smuzhiyun * This function is called with SRAM stack.
144*4882a593Smuzhiyun */
early_system_init(void)145*4882a593Smuzhiyun void early_system_init(void)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun init_omap_revision();
148*4882a593Smuzhiyun hw_data_init();
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun #ifdef CONFIG_SPL_BUILD
151*4882a593Smuzhiyun if (warm_reset())
152*4882a593Smuzhiyun force_emif_self_refresh();
153*4882a593Smuzhiyun #endif
154*4882a593Smuzhiyun watchdog_init();
155*4882a593Smuzhiyun set_mux_conf_regs();
156*4882a593Smuzhiyun #ifdef CONFIG_SPL_BUILD
157*4882a593Smuzhiyun srcomp_enable();
158*4882a593Smuzhiyun do_io_settings();
159*4882a593Smuzhiyun #endif
160*4882a593Smuzhiyun setup_early_clocks();
161*4882a593Smuzhiyun #ifdef CONFIG_SPL_BUILD
162*4882a593Smuzhiyun /*
163*4882a593Smuzhiyun * Save the boot parameters passed from romcode.
164*4882a593Smuzhiyun * We cannot delay the saving further than this,
165*4882a593Smuzhiyun * to prevent overwrites.
166*4882a593Smuzhiyun */
167*4882a593Smuzhiyun save_omap_boot_params();
168*4882a593Smuzhiyun spl_early_init();
169*4882a593Smuzhiyun #endif
170*4882a593Smuzhiyun do_board_detect();
171*4882a593Smuzhiyun vcores_init();
172*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_UART_OMAP
173*4882a593Smuzhiyun debug_uart_init();
174*4882a593Smuzhiyun #endif
175*4882a593Smuzhiyun prcm_init();
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun #ifdef CONFIG_SPL_BUILD
board_init_f(ulong dummy)179*4882a593Smuzhiyun void board_init_f(ulong dummy)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun early_system_init();
182*4882a593Smuzhiyun #ifdef CONFIG_BOARD_EARLY_INIT_F
183*4882a593Smuzhiyun board_early_init_f();
184*4882a593Smuzhiyun #endif
185*4882a593Smuzhiyun /* For regular u-boot sdram_init() is called from dram_init() */
186*4882a593Smuzhiyun sdram_init();
187*4882a593Smuzhiyun gd->ram_size = omap_sdram_size();
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun #endif
190*4882a593Smuzhiyun
arch_cpu_init_dm(void)191*4882a593Smuzhiyun int arch_cpu_init_dm(void)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun early_system_init();
194*4882a593Smuzhiyun return 0;
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun /*
198*4882a593Smuzhiyun * Routine: wait_for_command_complete
199*4882a593Smuzhiyun * Description: Wait for posting to finish on watchdog
200*4882a593Smuzhiyun */
wait_for_command_complete(struct watchdog * wd_base)201*4882a593Smuzhiyun void wait_for_command_complete(struct watchdog *wd_base)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun int pending = 1;
204*4882a593Smuzhiyun do {
205*4882a593Smuzhiyun pending = readl(&wd_base->wwps);
206*4882a593Smuzhiyun } while (pending);
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun /*
210*4882a593Smuzhiyun * Routine: watchdog_init
211*4882a593Smuzhiyun * Description: Shut down watch dogs
212*4882a593Smuzhiyun */
watchdog_init(void)213*4882a593Smuzhiyun void watchdog_init(void)
214*4882a593Smuzhiyun {
215*4882a593Smuzhiyun struct watchdog *wd2_base = (struct watchdog *)WDT2_BASE;
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun writel(WD_UNLOCK1, &wd2_base->wspr);
218*4882a593Smuzhiyun wait_for_command_complete(wd2_base);
219*4882a593Smuzhiyun writel(WD_UNLOCK2, &wd2_base->wspr);
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun /*
224*4882a593Smuzhiyun * This function finds the SDRAM size available in the system
225*4882a593Smuzhiyun * based on DMM section configurations
226*4882a593Smuzhiyun * This is needed because the size of memory installed may be
227*4882a593Smuzhiyun * different on different versions of the board
228*4882a593Smuzhiyun */
omap_sdram_size(void)229*4882a593Smuzhiyun u32 omap_sdram_size(void)
230*4882a593Smuzhiyun {
231*4882a593Smuzhiyun u32 section, i, valid;
232*4882a593Smuzhiyun u64 sdram_start = 0, sdram_end = 0, addr,
233*4882a593Smuzhiyun size, total_size = 0, trap_size = 0, trap_start = 0;
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun for (i = 0; i < 4; i++) {
236*4882a593Smuzhiyun section = __raw_readl(DMM_BASE + i*4);
237*4882a593Smuzhiyun valid = (section & EMIF_SDRC_ADDRSPC_MASK) >>
238*4882a593Smuzhiyun (EMIF_SDRC_ADDRSPC_SHIFT);
239*4882a593Smuzhiyun addr = section & EMIF_SYS_ADDR_MASK;
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun /* See if the address is valid */
242*4882a593Smuzhiyun if ((addr >= TI_ARMV7_DRAM_ADDR_SPACE_START) &&
243*4882a593Smuzhiyun (addr < TI_ARMV7_DRAM_ADDR_SPACE_END)) {
244*4882a593Smuzhiyun size = ((section & EMIF_SYS_SIZE_MASK) >>
245*4882a593Smuzhiyun EMIF_SYS_SIZE_SHIFT);
246*4882a593Smuzhiyun size = 1 << size;
247*4882a593Smuzhiyun size *= SZ_16M;
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun if (valid != DMM_SDRC_ADDR_SPC_INVALID) {
250*4882a593Smuzhiyun if (!sdram_start || (addr < sdram_start))
251*4882a593Smuzhiyun sdram_start = addr;
252*4882a593Smuzhiyun if (!sdram_end || ((addr + size) > sdram_end))
253*4882a593Smuzhiyun sdram_end = addr + size;
254*4882a593Smuzhiyun } else {
255*4882a593Smuzhiyun trap_size = size;
256*4882a593Smuzhiyun trap_start = addr;
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun if ((trap_start >= sdram_start) && (trap_start < sdram_end))
262*4882a593Smuzhiyun total_size = (sdram_end - sdram_start) - (trap_size);
263*4882a593Smuzhiyun else
264*4882a593Smuzhiyun total_size = sdram_end - sdram_start;
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun return total_size;
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun /*
271*4882a593Smuzhiyun * Routine: dram_init
272*4882a593Smuzhiyun * Description: sets uboots idea of sdram size
273*4882a593Smuzhiyun */
dram_init(void)274*4882a593Smuzhiyun int dram_init(void)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun sdram_init();
277*4882a593Smuzhiyun gd->ram_size = omap_sdram_size();
278*4882a593Smuzhiyun return 0;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun /*
282*4882a593Smuzhiyun * Print board information
283*4882a593Smuzhiyun */
checkboard(void)284*4882a593Smuzhiyun int checkboard(void)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun puts(sysinfo.board_string);
287*4882a593Smuzhiyun return 0;
288*4882a593Smuzhiyun }
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun #if defined(CONFIG_DISPLAY_CPUINFO)
291*4882a593Smuzhiyun /*
292*4882a593Smuzhiyun * Print CPU information
293*4882a593Smuzhiyun */
print_cpuinfo(void)294*4882a593Smuzhiyun int print_cpuinfo(void)
295*4882a593Smuzhiyun {
296*4882a593Smuzhiyun puts("CPU : ");
297*4882a593Smuzhiyun omap_rev_string();
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun return 0;
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun #endif
302