1 /*
2 * Copyright (c) 2019 Gerson Fernando Budke
3 * Copyright (c) 2017 Justin Watson
4 * Copyright (c) 2016 Intel Corporation.
5 * Copyright (c) 2013-2015 Wind River Systems, Inc.
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10 /**
11 * @file
12 * @brief Atmel SAM4E MCU series initialization code
13 *
14 * This module provides routines to initialize and support board-level hardware
15 * for the Atmel SAM4E series processor.
16 */
17
18 #include <device.h>
19 #include <init.h>
20 #include <soc.h>
21 #include <arch/cpu.h>
22 #include <arch/arm/aarch32/cortex_m/cmsis.h>
23
24 /**
25 * @brief Setup various clock on SoC at boot time.
26 *
27 * Setup the SoC clocks according to section 28.12 in datasheet.
28 *
29 * Setup Slow, Main, PLLA, Processor and Master clocks during the device boot.
30 * It is assumed that the relevant registers are at their reset value.
31 */
clock_init(void)32 static ALWAYS_INLINE void clock_init(void)
33 {
34 uint32_t reg_val;
35
36 #ifdef CONFIG_SOC_ATMEL_SAM4E_EXT_SLCK
37 /* Switch slow clock to the external 32 KHz crystal oscillator. */
38 SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_XTALSEL_CRYSTAL_SEL;
39
40 /* Wait for oscillator to be stabilized. */
41 while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL)) {
42 ;
43 }
44
45 #endif /* CONFIG_SOC_ATMEL_SAM4E_EXT_SLCK */
46
47 #ifdef CONFIG_SOC_ATMEL_SAM4E_EXT_MAINCK
48 /*
49 * Setup main external crystal oscillator.
50 */
51
52 /* Start the external crystal oscillator. */
53 PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD
54 /* Fast RC oscillator frequency is at 4 MHz. */
55 | CKGR_MOR_MOSCRCF_4_MHz
56 /*
57 * We select maximum setup time. While start up time
58 * could be shortened this optimization is not deemed
59 * critical right now.
60 */
61 | CKGR_MOR_MOSCXTST(0xFFu)
62 /* RC oscillator must stay on. */
63 | CKGR_MOR_MOSCRCEN
64 | CKGR_MOR_MOSCXTEN;
65
66 /* Wait for oscillator to be stabilized. */
67 while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)) {
68 ;
69 }
70
71 /* Select the external crystal oscillator as the main clock source. */
72 PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD
73 | CKGR_MOR_MOSCRCF_4_MHz
74 | CKGR_MOR_MOSCRCEN
75 | CKGR_MOR_MOSCXTEN
76 | CKGR_MOR_MOSCXTST(0xFFu)
77 | CKGR_MOR_MOSCSEL;
78
79 /* Wait for external oscillator to be selected. */
80 while (!(PMC->PMC_SR & PMC_SR_MOSCSELS)) {
81 ;
82 }
83
84 /* Turn off RC oscillator, not used any longer, to save power */
85 PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD
86 | CKGR_MOR_MOSCSEL
87 | CKGR_MOR_MOSCXTST(0xFFu)
88 | CKGR_MOR_MOSCXTEN;
89
90 /* Wait for the RC oscillator to be turned off. */
91 while (PMC->PMC_SR & PMC_SR_MOSCRCS) {
92 ;
93 }
94
95 #ifdef CONFIG_SOC_ATMEL_SAM4E_WAIT_MODE
96 /*
97 * Instruct CPU to enter Wait mode instead of Sleep mode to
98 * keep Processor Clock (HCLK) and thus be able to debug
99 * CPU using JTAG.
100 */
101 PMC->PMC_FSMR |= PMC_FSMR_LPM;
102 #endif
103 #else
104 /* Setup main fast RC oscillator. */
105
106 /*
107 * NOTE: MOSCRCF must be changed only if MOSCRCS is set in the PMC_SR
108 * register, should normally be the case.
109 */
110 while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)) {
111 ;
112 }
113
114 /* Set main fast RC oscillator to 12 MHz. */
115 PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD
116 | CKGR_MOR_MOSCRCF_12_MHz
117 | CKGR_MOR_MOSCRCEN;
118
119 /* Wait for RC oscillator to stabilize. */
120 while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)) {
121 ;
122 }
123 #endif /* CONFIG_SOC_ATMEL_SAM4E_EXT_MAINCK */
124
125 /*
126 * Setup PLLA
127 */
128
129 /* Switch MCK (Master Clock) to the main clock first. */
130 reg_val = PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk;
131 PMC->PMC_MCKR = reg_val | PMC_MCKR_CSS_MAIN_CLK;
132
133 /* Wait for clock selection to complete. */
134 while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {
135 ;
136 }
137
138 /* Setup PLLA. */
139 PMC->CKGR_PLLAR = CKGR_PLLAR_ONE
140 | CKGR_PLLAR_MULA(CONFIG_SOC_ATMEL_SAM4E_PLLA_MULA)
141 | CKGR_PLLAR_PLLACOUNT(0x3Fu)
142 | CKGR_PLLAR_DIVA(CONFIG_SOC_ATMEL_SAM4E_PLLA_DIVA);
143
144 /*
145 * NOTE: Both MULA and DIVA must be set to a value greater than 0 or
146 * otherwise PLL will be disabled. In this case we would get stuck in
147 * the following loop.
148 */
149
150 /* Wait for PLL lock. */
151 while (!(PMC->PMC_SR & PMC_SR_LOCKA)) {
152 ;
153 }
154
155 /*
156 * Final setup of the Master Clock
157 */
158
159 /*
160 * NOTE: PMC_MCKR must not be programmed in a single write operation.
161 * If CSS or PRES are modified we must wait for MCKRDY bit to be
162 * set again.
163 */
164
165 /* Setup prescaler - PLLA Clock / Processor Clock (HCLK). */
166 reg_val = PMC->PMC_MCKR & ~PMC_MCKR_PRES_Msk;
167 PMC->PMC_MCKR = reg_val | PMC_MCKR_PRES_CLK_1;
168
169 /* Wait for Master Clock setup to complete */
170 while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {
171 ;
172 }
173
174 /* Finally select PLL as Master Clock source. */
175 reg_val = PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk;
176 PMC->PMC_MCKR = reg_val | PMC_MCKR_CSS_PLLA_CLK;
177
178 /* Wait for Master Clock setup to complete. */
179 while (!(PMC->PMC_SR & PMC_SR_MCKRDY)) {
180 ;
181 }
182 }
183
184 /**
185 * @brief Perform basic hardware initialization at boot.
186 *
187 * This needs to be run from the very beginning.
188 * So the init priority has to be 0 (zero).
189 *
190 * @return 0
191 */
atmel_sam4e_init(const struct device * arg)192 static int atmel_sam4e_init(const struct device *arg)
193 {
194 uint32_t key;
195
196 ARG_UNUSED(arg);
197
198 key = irq_lock();
199
200 /*
201 * Set FWS (Flash Wait State) value before increasing Master Clock
202 * (MCK) frequency. Look at table 44.73 in the SAM4E datasheet.
203 * This is set to the highest number of read cycles because it won't
204 * hurt lower clock frequencies. However, a high frequency with too
205 * few read cycles could cause flash read problems. FWS 5 (6 cycles)
206 * is the safe setting for all of this SoCs usable frequencies.
207 */
208 EFC->EEFC_FMR = EEFC_FMR_FWS(5);
209
210 /* Setup system clocks. */
211 clock_init();
212
213 /*
214 * Install default handler that simply resets the CPU
215 * if configured in the kernel, NOP otherwise.
216 */
217 NMI_INIT();
218
219 irq_unlock(key);
220
221 return 0;
222 }
223
224 SYS_INIT(atmel_sam4e_init, PRE_KERNEL_1, 0);
225