blob: 674a47061e73f235ff488eb3ef67f2624bc5df9b [file] [log] [blame]
Bo Shenc5e88852013-11-15 11:12:38 +08001/*
2 * Copyright (C) 2013 Atmel Corporation
3 * Bo Shen <voice.shen@atmel.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <common.h>
9#include <asm/io.h>
10#include <asm/arch/at91_common.h>
11#include <asm/arch/at91_pmc.h>
12#include <asm/arch/at91_wdt.h>
13#include <asm/arch/clk.h>
14#include <spl.h>
15
16static void at91_disable_wdt(void)
17{
18 struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT;
19
20 writel(AT91_WDT_MR_WDDIS, &wdt->mr);
21}
22
Bo Shen12bbc0b2014-03-19 14:48:44 +080023static void switch_to_main_crystal_osc(void)
24{
25 struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
26 u32 tmp;
27
28 tmp = readl(&pmc->mor);
29 tmp &= ~AT91_PMC_MOR_OSCOUNT(0xff);
30 tmp &= ~AT91_PMC_MOR_KEY(0xff);
31 tmp |= AT91_PMC_MOR_MOSCEN;
32 tmp |= AT91_PMC_MOR_OSCOUNT(8);
33 tmp |= AT91_PMC_MOR_KEY(0x37);
34 writel(tmp, &pmc->mor);
35 while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCS))
36 ;
37
38 tmp = readl(&pmc->mor);
39 tmp &= ~AT91_PMC_MOR_OSCBYPASS;
40 tmp &= ~AT91_PMC_MOR_KEY(0xff);
41 tmp |= AT91_PMC_MOR_KEY(0x37);
42 writel(tmp, &pmc->mor);
43
44 tmp = readl(&pmc->mor);
45 tmp |= AT91_PMC_MOR_MOSCSEL;
46 tmp &= ~AT91_PMC_MOR_KEY(0xff);
47 tmp |= AT91_PMC_MOR_KEY(0x37);
48 writel(tmp, &pmc->mor);
49
50 while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCSELS))
51 ;
52
53 tmp = readl(&pmc->mor);
54 tmp &= ~AT91_PMC_MOR_MOSCRCEN;
55 tmp &= ~AT91_PMC_MOR_KEY(0xff);
56 tmp |= AT91_PMC_MOR_KEY(0x37);
57 writel(tmp, &pmc->mor);
58}
59
Bo Shenc5e88852013-11-15 11:12:38 +080060void at91_plla_init(u32 pllar)
61{
62 struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
63
64 writel(pllar, &pmc->pllar);
65 while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY)))
66 ;
67}
68
69void at91_mck_init(u32 mckr)
70{
71 struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
72 u32 tmp;
73
74 tmp = readl(&pmc->mckr);
75 tmp &= ~(AT91_PMC_MCKR_PRES_MASK |
76 AT91_PMC_MCKR_MDIV_MASK |
77 AT91_PMC_MCKR_PLLADIV_2);
78 tmp |= mckr & (AT91_PMC_MCKR_PRES_MASK |
79 AT91_PMC_MCKR_MDIV_MASK |
80 AT91_PMC_MCKR_PLLADIV_2);
81 writel(tmp, &pmc->mckr);
82
83 while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
84 ;
85}
86
87
88u32 spl_boot_device(void)
89{
90#ifdef CONFIG_SYS_USE_MMC
91 return BOOT_DEVICE_MMC1;
Bo Shen27019e42014-03-03 14:47:17 +080092#elif CONFIG_SYS_USE_NANDFLASH
93 return BOOT_DEVICE_NAND;
Bo Shen8a45b0b2014-03-03 14:47:15 +080094#elif CONFIG_SYS_USE_SERIALFLASH
95 return BOOT_DEVICE_SPI;
Bo Shenc5e88852013-11-15 11:12:38 +080096#endif
97 return BOOT_DEVICE_NONE;
98}
99
100u32 spl_boot_mode(void)
101{
102 switch (spl_boot_device()) {
103#ifdef CONFIG_SYS_USE_MMC
104 case BOOT_DEVICE_MMC1:
Guillaume GARDET205b4f32014-10-15 17:53:11 +0200105 return MMCSD_MODE_FS;
Bo Shenc5e88852013-11-15 11:12:38 +0800106 break;
107#endif
108 case BOOT_DEVICE_NONE:
109 default:
110 hang();
111 }
112}
113
114void s_init(void)
115{
Bo Shen12bbc0b2014-03-19 14:48:44 +0800116 switch_to_main_crystal_osc();
117
Bo Shenc5e88852013-11-15 11:12:38 +0800118 /* disable watchdog */
119 at91_disable_wdt();
120
121 /* PMC configuration */
122 at91_pmc_init();
123
124 at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK);
125
126 timer_init();
127
128 board_early_init_f();
129
130 preloader_console_init();
131
132 mem_init();
133}