blob: 597ff8c036736f206b61389b7945a61bfe7721d9 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Heiko Schocher5abc00d2014-10-31 08:31:04 +01002/*
3 * Copyright (C) 2013 Atmel Corporation
4 * Bo Shen <voice.shen@atmel.com>
Heiko Schocher5abc00d2014-10-31 08:31:04 +01005 */
6
7#include <common.h>
8#include <asm/io.h>
9#include <asm/arch/at91_common.h>
10#include <asm/arch/at91_pit.h>
11#include <asm/arch/at91_pmc.h>
12#include <asm/arch/at91_rstc.h>
13#include <asm/arch/at91_wdt.h>
14#include <asm/arch/clk.h>
15#include <spl.h>
16
Heiko Schocher5abc00d2014-10-31 08:31:04 +010017static void switch_to_main_crystal_osc(void)
18{
19 struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
20 u32 tmp;
21
22 tmp = readl(&pmc->mor);
23 tmp &= ~AT91_PMC_MOR_OSCOUNT(0xff);
24 tmp &= ~AT91_PMC_MOR_KEY(0xff);
25 tmp |= AT91_PMC_MOR_MOSCEN;
26 tmp |= AT91_PMC_MOR_OSCOUNT(8);
27 tmp |= AT91_PMC_MOR_KEY(0x37);
28 writel(tmp, &pmc->mor);
29 while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCS))
30 ;
31
Wenyou Yang3ceb5112017-09-13 14:58:48 +080032#if defined(CONFIG_SAMA5D2)
33 /* Enable a measurement of the external oscillator */
34 tmp = readl(&pmc->mcfr);
35 tmp |= AT91_PMC_MCFR_CCSS_XTAL_OSC;
36 tmp |= AT91_PMC_MCFR_RCMEAS;
37 writel(tmp, &pmc->mcfr);
38
39 while (!(readl(&pmc->mcfr) & AT91_PMC_MCFR_MAINRDY))
40 ;
41
42 if (!(readl(&pmc->mcfr) & AT91_PMC_MCFR_MAINF_MASK))
43 hang();
44#endif
45
Heiko Schocher5abc00d2014-10-31 08:31:04 +010046 tmp = readl(&pmc->mor);
47 tmp &= ~AT91_PMC_MOR_OSCBYPASS;
48 tmp &= ~AT91_PMC_MOR_KEY(0xff);
49 tmp |= AT91_PMC_MOR_KEY(0x37);
50 writel(tmp, &pmc->mor);
51
52 tmp = readl(&pmc->mor);
53 tmp |= AT91_PMC_MOR_MOSCSEL;
54 tmp &= ~AT91_PMC_MOR_KEY(0xff);
55 tmp |= AT91_PMC_MOR_KEY(0x37);
56 writel(tmp, &pmc->mor);
57
58 while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCSELS))
59 ;
60
Wenyou Yang3ceb5112017-09-13 14:58:48 +080061#if !defined(CONFIG_SAMA5D2)
Heiko Schocher5abc00d2014-10-31 08:31:04 +010062 /* Wait until MAINRDY field is set to make sure main clock is stable */
63 while (!(readl(&pmc->mcfr) & AT91_PMC_MAINRDY))
64 ;
Wenyou Yang3ceb5112017-09-13 14:58:48 +080065#endif
Heiko Schocher5abc00d2014-10-31 08:31:04 +010066
Wenyou Yang3ceb5112017-09-13 14:58:48 +080067#if !defined(CONFIG_SAMA5D4) && !defined(CONFIG_SAMA5D2)
Heiko Schocher5abc00d2014-10-31 08:31:04 +010068 tmp = readl(&pmc->mor);
69 tmp &= ~AT91_PMC_MOR_MOSCRCEN;
70 tmp &= ~AT91_PMC_MOR_KEY(0xff);
71 tmp |= AT91_PMC_MOR_KEY(0x37);
72 writel(tmp, &pmc->mor);
Bo Shen0246b7c2014-12-15 13:24:32 +080073#endif
Heiko Schocher5abc00d2014-10-31 08:31:04 +010074}
75
Bo Shen433be902014-12-15 13:24:30 +080076__weak void matrix_init(void)
77{
78 /* This only be used for sama5d4 soc now */
79}
80
Bo Shen4514b5f2014-12-15 13:24:31 +080081__weak void redirect_int_from_saic_to_aic(void)
82{
83 /* This only be used for sama5d4 soc now */
84}
85
Tom Rinie755d542015-02-10 19:07:22 -050086/* empty stub to satisfy current lowlevel_init, can be removed any time */
Heiko Schocher5abc00d2014-10-31 08:31:04 +010087void s_init(void)
88{
Tom Rinie755d542015-02-10 19:07:22 -050089}
90
91void board_init_f(ulong dummy)
92{
Wenyou Yang730a7b42017-03-24 11:34:04 +080093 int ret;
94
Heiko Schocher5abc00d2014-10-31 08:31:04 +010095 switch_to_main_crystal_osc();
96
Samuel Mescofff7cf2912016-02-16 09:45:06 +010097#ifdef CONFIG_SAMA5D2
98 configure_2nd_sram_as_l2_cache();
99#endif
100
Tom Rinif58e9462018-05-10 07:15:52 -0400101#if !defined(CONFIG_AT91SAM9_WATCHDOG)
Heiko Schocher5abc00d2014-10-31 08:31:04 +0100102 /* disable watchdog */
103 at91_disable_wdt();
Tom Rinif58e9462018-05-10 07:15:52 -0400104#endif
Heiko Schocher5abc00d2014-10-31 08:31:04 +0100105
106 /* PMC configuration */
107 at91_pmc_init();
108
109 at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK);
110
Bo Shen433be902014-12-15 13:24:30 +0800111 matrix_init();
112
Bo Shen4514b5f2014-12-15 13:24:31 +0800113 redirect_int_from_saic_to_aic();
114
Heiko Schocher5abc00d2014-10-31 08:31:04 +0100115 timer_init();
116
117 board_early_init_f();
118
Wenyou Yang5bede732017-03-24 11:34:05 +0800119 mem_init();
120
Wenyou Yang730a7b42017-03-24 11:34:04 +0800121 ret = spl_init();
122 if (ret) {
123 debug("spl_init() failed: %d\n", ret);
124 hang();
125 }
126
Heiko Schocher5abc00d2014-10-31 08:31:04 +0100127 preloader_console_init();
128
Heiko Schocher5abc00d2014-10-31 08:31:04 +0100129}