1 /*
2  * Copyright (c) 2021 Andrés Manelli <am@toroid.io>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /** @file
8  * @brief System module to support early STM32 MCU configuration
9  */
10 
11 #include <zephyr/device.h>
12 #include <zephyr/init.h>
13 #include <soc.h>
14 #include <zephyr/arch/cpu.h>
15 #include <stm32_ll_system.h>
16 #include <stm32_ll_bus.h>
17 #include <stm32_ll_pwr.h>
18 
19 /**
20  * @brief Perform SoC configuration at boot.
21  *
22  * This should be run early during the boot process but after basic hardware
23  * initialization is done.
24  *
25  * @return 0
26  */
st_stm32_common_config(void)27 static int st_stm32_common_config(void)
28 {
29 #ifdef CONFIG_LOG_BACKEND_SWO
30 	/* Enable SWO trace asynchronous mode */
31 #if defined(CONFIG_SOC_SERIES_STM32H5X) || defined(CONFIG_SOC_SERIES_STM32H7RSX) ||                \
32 	defined(CONFIG_SOC_SERIES_STM32L5X) || defined(CONFIG_SOC_SERIES_STM32U5X) ||              \
33 	defined(CONFIG_SOC_SERIES_STM32WBX)
34 	LL_DBGMCU_EnableTraceClock();
35 #endif
36 #if !defined(CONFIG_SOC_SERIES_STM32WBX) && defined(DBGMCU_CR_TRACE_IOEN)
37 	LL_DBGMCU_SetTracePinAssignment(LL_DBGMCU_TRACE_ASYNCH);
38 #endif
39 #endif /* CONFIG_LOG_BACKEND_SWO */
40 
41 #if defined(CONFIG_USE_SEGGER_RTT)
42 	/* On some STM32 boards, for unclear reason,
43 	 * RTT feature is working with realtime update only when
44 	 *   - one of the DMA is clocked.
45 	 * See https://github.com/zephyrproject-rtos/zephyr/issues/34324
46 	 */
47 #if defined(__HAL_RCC_DMA1_CLK_ENABLE)
48 	__HAL_RCC_DMA1_CLK_ENABLE();
49 #elif defined(__HAL_RCC_GPDMA1_CLK_ENABLE)
50 	__HAL_RCC_GPDMA1_CLK_ENABLE();
51 #endif /* __HAL_RCC_DMA1_CLK_ENABLE */
52 
53 #endif /* CONFIG_USE_SEGGER_RTT */
54 
55 	/* On some STM32 boards, for unclear reason,
56 	 * RTT feature is working with realtime update only when
57 	 *   - one of the DBGMCU bit STOP/STANDBY/SLEEP is set
58 	 * See https://github.com/zephyrproject-rtos/zephyr/issues/34324
59 	 */
60 
61 	/* Enable DBGMCU clock if it exists */
62 #if defined(LL_APB1_GRP1_PERIPH_DBGMCU)
63 	LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_DBGMCU);
64 #elif defined(LL_APB1_GRP2_PERIPH_DBGMCU)
65 	LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_DBGMCU);
66 #elif defined(LL_APB2_GRP1_PERIPH_DBGMCU)
67 	LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_DBGMCU);
68 #endif /* LL_APB1_GRP1_PERIPH_DBGMCU */
69 
70 #if defined(CONFIG_STM32_ENABLE_DEBUG_SLEEP_STOP)
71 
72 #if defined(CONFIG_SOC_SERIES_STM32H7X)
73 	LL_DBGMCU_EnableD1DebugInStopMode();
74 	LL_DBGMCU_EnableD1DebugInSleepMode();
75 #elif defined(CONFIG_SOC_SERIES_STM32MP1X)
76 	LL_DBGMCU_EnableDebugInStopMode();
77 #elif defined(CONFIG_SOC_SERIES_STM32WB0X)
78 	LL_PWR_EnableDEEPSTOP2();
79 #else /* all other parts */
80 	LL_DBGMCU_EnableDBGStopMode();
81 #endif
82 
83 #else
84 
85 /* keeping in mind that debugging draws a lot of power we explcitly disable when not needed */
86 #if defined(CONFIG_SOC_SERIES_STM32H7X)
87 	LL_DBGMCU_DisableD1DebugInStopMode();
88 	LL_DBGMCU_DisableD1DebugInSleepMode();
89 #elif defined(CONFIG_SOC_SERIES_STM32MP1X)
90 	LL_DBGMCU_DisableDebugInStopMode();
91 #elif defined(CONFIG_SOC_SERIES_STM32WB0X)
92 	LL_PWR_DisableDEEPSTOP2();
93 #else /* all other parts */
94 	LL_DBGMCU_DisableDBGStopMode();
95 #endif
96 
97 #endif /* CONFIG_STM32_ENABLE_DEBUG_SLEEP_STOP */
98 
99 	/* Disable DBGMCU clock if it exists */
100 #if defined(LL_APB1_GRP1_PERIPH_DBGMCU)
101 	LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_DBGMCU);
102 #elif defined(LL_APB1_GRP2_PERIPH_DBGMCU)
103 	LL_APB1_GRP2_DisableClock(LL_APB1_GRP2_PERIPH_DBGMCU);
104 #elif defined(LL_APB2_GRP1_PERIPH_DBGMCU)
105 	LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_DBGMCU);
106 #endif /* LL_APB1_GRP1_PERIPH_DBGMCU */
107 
108 	return 0;
109 }
110 
111 SYS_INIT(st_stm32_common_config, PRE_KERNEL_1, 1);
112