blob: dba6cdb90cf6bac2313565a812de2b20d654d610 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (c) 2015 Travis Geiselbrecht
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#include <err.h>
24#include <debug.h>
25#include <stdlib.h>
26#include <reg.h>
27#include <dev/uart.h>
28#include <platform.h>
29#include <platform/stm32.h>
30#include <platform/sdram.h>
31#include <kernel/novm.h>
32#include <arch/arm/cm.h>
33
34uint32_t SystemCoreClock = HSI_VALUE;
35uint32_t stm32_unique_id[3];
36
37#if defined(ENABLE_SDRAM)
38// target exports this with sdram configuration values
39extern const sdram_config_t target_sdram_config;
40#endif
41
42void SystemInit(void)
43{
44 /* FPU settings ------------------------------------------------------------*/
45#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
46 SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
47#endif
48 /* Reset the RCC clock configuration to the default reset state ------------*/
49 /* Set HSION bit */
50 RCC->CR |= (uint32_t)0x00000001;
51
52 /* Reset CFGR register */
53 RCC->CFGR = 0x00000000;
54
55 /* Reset HSEON, CSSON and PLLON bits */
56 RCC->CR &= (uint32_t)0xFEF6FFFF;
57
58 /* Reset PLLCFGR register */
59 RCC->PLLCFGR = 0x24003010;
60
61 /* Reset HSEBYP bit */
62 RCC->CR &= (uint32_t)0xFFFBFFFF;
63
64 /* Disable all interrupts */
65 RCC->CIR = 0x00000000;
66
67 __HAL_RCC_PWR_CLK_ENABLE();
68
69#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
70 SystemInit_ExtMemCtl();
71#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
72}
73
74/**
75 * @brief System Clock Configuration
76 * The system Clock is configured as follow :
77 * System Clock source = PLL (HSE or HSI)
78 * SYSCLK(Hz) = 216000000
79 * HCLK(Hz) = 216000000
80 * AHB Prescaler = 1
81 * APB1 Prescaler = 4
82 * APB2 Prescaler = 2
83 * HSE Frequency(Hz) = 25000000
84 * PLL_M = 25 or 16
85 * PLL_N = 432
86 * PLL_P = 2
87 * PLL_Q = 9
88 * VDD(V) = 3.3
89 * Main regulator output voltage = Scale1 mode
90 * Flash Latency(WS) = 7
91 * @param None
92 * @retval None
93 */
94static void SystemClock_Config(void)
95{
96 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
97 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
98 HAL_StatusTypeDef ret = HAL_OK;
99
100#if defined(USE_HSE_XTAL)
101 /* Enable HSE Oscillator and activate PLL with HSE as source.
102 * The external XTAL is a more stable clock source.
103 */
104 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
105 RCC_OscInitStruct.HSEState = RCC_HSE_ON;
106 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
107 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
108 RCC_OscInitStruct.PLL.PLLM = 25;
109 RCC_OscInitStruct.PLL.PLLN = 432;
110 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
111 RCC_OscInitStruct.PLL.PLLQ = 9;
112#else
113 /* Enable HSI Oscillator and activate PLL with HSI as source.
114 * Some boards like STm32756G-EVAL2 seem to malfuction with the
115 * HSE xtal configuration.
116 */
117 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
118 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
119 RCC_OscInitStruct.HSICalibrationValue = 16;
120 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
121 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
122 RCC_OscInitStruct.PLL.PLLM = 16;
123 RCC_OscInitStruct.PLL.PLLN = 432;
124 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
125 RCC_OscInitStruct.PLL.PLLQ = 9;
126#endif
127
128 ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
129 if (ret != HAL_OK) {
130 while (1) { ; }
131 }
132
133 /* Activate the OverDrive to reach the 216 MHz Frequency */
134 ret = HAL_PWREx_EnableOverDrive();
135 if (ret != HAL_OK) {
136 while (1) { ; }
137 }
138
139 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
140 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
141 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
142 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
143 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
144 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
145
146 ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);
147 if (ret != HAL_OK) {
148 while (1) { ; }
149 }
150}
151
152void stm32_rng_init(void)
153{
154 RNG_HandleTypeDef rng_handle = { 0 };
155
156 __HAL_RCC_RNG_CLK_ENABLE();
157
158 rng_handle.Instance = RNG;
159 HAL_StatusTypeDef status = HAL_RNG_Init(&rng_handle);
160 if (status != HAL_OK) {
161 panic("error initializing random number hardware\n");
162 }
163
164 /* seed the pseudo random number generator with this */
165#if STM32_SEED_RAND_FROM_HWRNG
166 uint32_t r;
167
168 /* discard he first result */
169 status = HAL_RNG_GenerateRandomNumber(&rng_handle, &r);
170 if (status != HAL_OK) {
171 panic("error getting random number from hardware\n");
172 }
173
174 status = HAL_RNG_GenerateRandomNumber(&rng_handle, &r);
175 if (status != HAL_OK) {
176 panic("error getting random number from hardware\n");
177 }
178
179 srand(r);
180#endif
181}
182
183/* set up the mpu to enable caching in the appropriate areas */
184static void mpu_init(void)
185{
186 MPU_Region_InitTypeDef MPU_InitStruct;
187 HAL_MPU_Disable();
188
189 uint region_num = 0;
190
191 /* mark the first bit of the address space as inaccessible, to catch null pointers */
192 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
193 MPU_InitStruct.BaseAddress = 0x0;
194 MPU_InitStruct.Size = MPU_REGION_SIZE_128KB; /* 0x00200000 */
195 MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
196 MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
197 MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
198 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
199 MPU_InitStruct.Number = region_num++;
200 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
201 MPU_InitStruct.SubRegionDisable = 0x00;
202 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
203 HAL_MPU_ConfigRegion(&MPU_InitStruct);
204
205#if defined(ENABLE_SDRAM)
206 /* configure SDRAM */
207 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
208 MPU_InitStruct.BaseAddress = SDRAM_BASE;
209
210 MPU_InitStruct.Size =
211#if SDRAM_SIZE == 0x00100000
212 MPU_REGION_SIZE_1MB;
213#elif SDRAM_SIZE == 0x00200000
214 MPU_REGION_SIZE_2MB;
215#elif SDRAM_SIZE == 0x00400000
216 MPU_REGION_SIZE_4MB;
217#elif SDRAM_SIZE == 0x00800000
218 MPU_REGION_SIZE_8MB;
219#elif SDRAM_SIZE == 0x01000000
220 MPU_REGION_SIZE_16MB
221#elif SDRAM_SIZE == 0x02000000
222 MPU_REGION_SIZE_32MB;
223#elif SDRAM_SIZE == 0x04000000
224 MPU_REGION_SIZE_64MB;
225#elif SDRAM_SIZE == 0x08000000
226 MPU_REGION_SIZE_128MB;
227#else
228#error SDRAM_SIZE not defined.
229#endif
230
231 MPU_InitStruct.AccessPermission = MPU_REGION_PRIV_RW;
232 MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
233 MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
234 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
235 MPU_InitStruct.Number = region_num++;
236 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
237 MPU_InitStruct.SubRegionDisable = 0x00;
238 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
239 HAL_MPU_ConfigRegion(&MPU_InitStruct);
240#endif
241
242 // SRAM
243#if defined(ENABLE_EXT_SRAM)
244 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
245 MPU_InitStruct.BaseAddress = EXT_SRAM_BASE;
246 MPU_InitStruct.Size = MPU_REGION_SIZE_2MB; // XXX use max size of aperture?
247 MPU_InitStruct.AccessPermission = MPU_REGION_PRIV_RW;
248 MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
249 MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
250 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
251 MPU_InitStruct.Number = region_num++;
252 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
253 MPU_InitStruct.SubRegionDisable = 0x00;
254 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
255
256 HAL_MPU_ConfigRegion(&MPU_InitStruct);
257#endif
258
259 HAL_MPU_Enable(MPU_HFNMI_PRIVDEF);
260}
261
262void platform_early_init(void)
263{
264 // Do general system init
265 SystemInit();
266 SystemClock_Config();
267
268 // Enable the flash ART controller
269 __HAL_FLASH_ART_ENABLE();
270 __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
271
272 /* read the unique id */
273 stm32_unique_id[0] = *REG32(0x1ff0f420);
274 stm32_unique_id[1] = *REG32(0x1ff0f424);
275 stm32_unique_id[2] = *REG32(0x1ff0f428);
276
277 /* seed the random number generator based on this */
278 srand(stm32_unique_id[0] ^ stm32_unique_id[1] ^ stm32_unique_id[2]);
279
280 // Start the systick timer
281 uint32_t sysclk = HAL_RCC_GetSysClockFreq();
282 arm_cm_systick_init(sysclk);
283
284 stm32_timer_early_init();
285 stm32_gpio_early_init();
286 stm32_flash_early_init();
287 stm32_rng_init();
288 stm32_usbc_early_init();
289
290 /* clear the reboot reason */
291 RCC->CSR |= (1<<24);
292
293#if defined(ENABLE_SDRAM)
294 /* initialize SDRAM */
295 stm32_sdram_init((sdram_config_t *)&target_sdram_config);
296
297 /* add a novm arena for it */
298 novm_add_arena("sdram", SDRAM_BASE, SDRAM_SIZE);
299#endif
300
301 mpu_init();
302}
303
304void platform_init(void)
305{
306 printf("clocks:\n");
307 printf("\tsysclk %u\n", HAL_RCC_GetSysClockFreq());
308 printf("\thclk %u\n", HAL_RCC_GetHCLKFreq());
309 printf("\tpclk1 %u\n", HAL_RCC_GetPCLK1Freq());
310 printf("\tpclk2 %u\n", HAL_RCC_GetPCLK2Freq());
311
312 printf("unique id: 0x%08x%08x%08x\n", stm32_unique_id[0], stm32_unique_id[1], stm32_unique_id[2]);
313
314 stm32_timer_init();
315
316 stm32_flash_init();
317
318 stm32_usbc_init();
319}
320