]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/at91-common/spl.c
ARM: atmel: switch to main crystal osc for SPL boot
[karo-tx-uboot.git] / arch / arm / cpu / at91-common / spl.c
1 /*
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
16 static 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
23 static 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
60 void 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
69 void 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
88 u32 spl_boot_device(void)
89 {
90 #ifdef CONFIG_SYS_USE_MMC
91         return BOOT_DEVICE_MMC1;
92 #elif CONFIG_SYS_USE_NANDFLASH
93         return BOOT_DEVICE_NAND;
94 #elif CONFIG_SYS_USE_SERIALFLASH
95         return BOOT_DEVICE_SPI;
96 #endif
97         return BOOT_DEVICE_NONE;
98 }
99
100 u32 spl_boot_mode(void)
101 {
102         switch (spl_boot_device()) {
103 #ifdef CONFIG_SYS_USE_MMC
104         case BOOT_DEVICE_MMC1:
105                 return MMCSD_MODE_FAT;
106                 break;
107 #endif
108         case BOOT_DEVICE_NONE:
109         default:
110                 hang();
111         }
112 }
113
114 void s_init(void)
115 {
116         switch_to_main_crystal_osc();
117
118         /* 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 }