xref: /OK3568_Linux_fs/u-boot/arch/arm/mach-at91/spl_at91.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2014 DENX Software Engineering
3*4882a593Smuzhiyun  *     Heiko Schocher <hs@denx.de>
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Based on:
6*4882a593Smuzhiyun  * Copyright (C) 2013 Atmel Corporation
7*4882a593Smuzhiyun  *		      Bo Shen <voice.shen@atmel.com>
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <common.h>
13*4882a593Smuzhiyun #include <asm/io.h>
14*4882a593Smuzhiyun #include <asm/arch/at91_common.h>
15*4882a593Smuzhiyun #include <asm/arch/at91sam9_matrix.h>
16*4882a593Smuzhiyun #include <asm/arch/at91_pit.h>
17*4882a593Smuzhiyun #include <asm/arch/at91_rstc.h>
18*4882a593Smuzhiyun #include <asm/arch/at91_wdt.h>
19*4882a593Smuzhiyun #include <asm/arch/clk.h>
20*4882a593Smuzhiyun #include <spl.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
23*4882a593Smuzhiyun 
enable_ext_reset(void)24*4882a593Smuzhiyun static void enable_ext_reset(void)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun 	struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC;
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 	writel(AT91_RSTC_KEY | AT91_RSTC_MR_URSTEN, &rstc->mr);
29*4882a593Smuzhiyun }
30*4882a593Smuzhiyun 
lowlevel_clock_init(void)31*4882a593Smuzhiyun void lowlevel_clock_init(void)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun 	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun 	if (!(readl(&pmc->sr) & AT91_PMC_MOSCS)) {
36*4882a593Smuzhiyun 		/* Enable Main Oscillator */
37*4882a593Smuzhiyun 		writel(AT91_PMC_MOSCS | (0x40 << 8), &pmc->mor);
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun 		/* Wait until Main Oscillator is stable */
40*4882a593Smuzhiyun 		while (!(readl(&pmc->sr) & AT91_PMC_MOSCS))
41*4882a593Smuzhiyun 			;
42*4882a593Smuzhiyun 	}
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	/* After stabilization, switch to Main Oscillator */
45*4882a593Smuzhiyun 	if ((readl(&pmc->mckr) & AT91_PMC_CSS) == AT91_PMC_CSS_SLOW) {
46*4882a593Smuzhiyun 		unsigned long tmp;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 		tmp = readl(&pmc->mckr);
49*4882a593Smuzhiyun 		tmp &= ~AT91_PMC_CSS;
50*4882a593Smuzhiyun 		tmp |= AT91_PMC_CSS_MAIN;
51*4882a593Smuzhiyun 		writel(tmp, &pmc->mckr);
52*4882a593Smuzhiyun 		while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
53*4882a593Smuzhiyun 			;
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 		tmp &= ~AT91_PMC_PRES;
56*4882a593Smuzhiyun 		tmp |= AT91_PMC_PRES_1;
57*4882a593Smuzhiyun 		writel(tmp, &pmc->mckr);
58*4882a593Smuzhiyun 		while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
59*4882a593Smuzhiyun 			;
60*4882a593Smuzhiyun 	}
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	return;
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun 
matrix_init(void)65*4882a593Smuzhiyun void __weak matrix_init(void)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun 
at91_spl_board_init(void)69*4882a593Smuzhiyun void __weak at91_spl_board_init(void)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun 
spl_board_init(void)73*4882a593Smuzhiyun void __weak spl_board_init(void)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
board_init_f(ulong dummy)77*4882a593Smuzhiyun void board_init_f(ulong dummy)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun 	lowlevel_clock_init();
80*4882a593Smuzhiyun 	at91_disable_wdt();
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	/*
83*4882a593Smuzhiyun 	 * At this stage the main oscillator is supposed to be enabled
84*4882a593Smuzhiyun 	 * PCK = MCK = MOSC
85*4882a593Smuzhiyun 	 */
86*4882a593Smuzhiyun 	at91_pllicpr_init(0x00);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	/* Configure PLLA = MOSC * (PLL_MULA + 1) / PLL_DIVA */
89*4882a593Smuzhiyun 	at91_plla_init(CONFIG_SYS_AT91_PLLA);
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	/* PCK = PLLA = 2 * MCK */
92*4882a593Smuzhiyun 	at91_mck_init(CONFIG_SYS_MCKR);
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	/* Switch MCK on PLLA output */
95*4882a593Smuzhiyun 	at91_mck_init(CONFIG_SYS_MCKR_CSS);
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun #if defined(CONFIG_SYS_AT91_PLLB)
98*4882a593Smuzhiyun 	/* Configure PLLB */
99*4882a593Smuzhiyun 	at91_pllb_init(CONFIG_SYS_AT91_PLLB);
100*4882a593Smuzhiyun #endif
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	/* Enable External Reset */
103*4882a593Smuzhiyun 	enable_ext_reset();
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	/* Initialize matrix */
106*4882a593Smuzhiyun 	matrix_init();
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	gd->arch.mck_rate_hz = CONFIG_SYS_MASTER_CLOCK;
109*4882a593Smuzhiyun 	/*
110*4882a593Smuzhiyun 	 * init timer long enough for using in spl.
111*4882a593Smuzhiyun 	 */
112*4882a593Smuzhiyun 	timer_init();
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	/* enable clocks for all PIOs */
115*4882a593Smuzhiyun #if defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAM9N12)
116*4882a593Smuzhiyun 	at91_periph_clk_enable(ATMEL_ID_PIOAB);
117*4882a593Smuzhiyun 	at91_periph_clk_enable(ATMEL_ID_PIOCD);
118*4882a593Smuzhiyun #else
119*4882a593Smuzhiyun 	at91_periph_clk_enable(ATMEL_ID_PIOA);
120*4882a593Smuzhiyun 	at91_periph_clk_enable(ATMEL_ID_PIOB);
121*4882a593Smuzhiyun 	at91_periph_clk_enable(ATMEL_ID_PIOC);
122*4882a593Smuzhiyun #endif
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun #if defined(CONFIG_SPL_SERIAL_SUPPORT)
125*4882a593Smuzhiyun 	/* init console */
126*4882a593Smuzhiyun 	at91_seriald_hw_init();
127*4882a593Smuzhiyun 	preloader_console_init();
128*4882a593Smuzhiyun #endif
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	mem_init();
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	at91_spl_board_init();
133*4882a593Smuzhiyun }
134