1 /*
2 * Copyright (c) 2019 STMicroelectronics
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #ifndef ZEPHYR_INCLUDE_DRIVERS_HSEM_STM32_HSEM_H_
7 #define ZEPHYR_INCLUDE_DRIVERS_HSEM_STM32_HSEM_H_
8
9 #include <soc.h>
10 #include <stm32_ll_hsem.h>
11 #include <zephyr/kernel.h>
12
13 #if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE)
14 /** HW semaphore Complement ID list defined in hw_conf.h from STM32WB
15 * and used also for H7 dualcore targets
16 */
17 /**
18 * Index of the semaphore used by CPU2 to prevent the CPU1 to either write or
19 * erase data in flash. The CPU1 shall not either write or erase in flash when
20 * this semaphore is taken by the CPU2. When the CPU1 needs to either write or
21 * erase in flash, it shall first get the semaphore and release it just
22 * after writing a raw (64bits data) or erasing one sector.
23 * On v1.4.0 and older CPU2 wireless firmware, this semaphore is unused and
24 * CPU2 is using PES bit. By default, CPU2 is using the PES bit to protect its
25 * timing. The CPU1 may request the CPU2 to use the semaphore instead of the
26 * PES bit by sending the system command SHCI_C2_SetFlashActivityControl()
27 */
28 #define CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID 7U
29
30 /**
31 * Index of the semaphore used by CPU1 to prevent the CPU2 to either write or
32 * erase data in flash. In order to protect its timing, the CPU1 may get this
33 * semaphore to prevent the CPU2 to either write or erase in flash
34 * (as this will stall both CPUs)
35 * The PES bit shall not be used as this may stall the CPU2 in some cases.
36 */
37 #define CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID 6U
38
39 /**
40 * Index of the semaphore used to manage the CLK48 clock configuration
41 * When the USB is required, this semaphore shall be taken before configuring
42 * the CLK48 for USB and should be released after the application switch OFF
43 * the clock when the USB is not used anymore. When using the RNG, it is good
44 * enough to use CFG_HW_RNG_SEMID to control CLK48.
45 * More details in AN5289
46 */
47 #define CFG_HW_CLK48_CONFIG_SEMID 5U
48 #define CFG_HW_RCC_CRRCR_CCIPR_SEMID CFG_HW_CLK48_CONFIG_SEMID
49
50 /* Index of the semaphore used to manage the entry Stop Mode procedure */
51 #define CFG_HW_ENTRY_STOP_MODE_SEMID 4U
52 #define CFG_HW_ENTRY_STOP_MODE_MASK_SEMID (1U << CFG_HW_ENTRY_STOP_MODE_SEMID)
53
54 /* Index of the semaphore used to access the RCC */
55 #define CFG_HW_RCC_SEMID 3U
56
57 /* Index of the semaphore used to access the FLASH */
58 #define CFG_HW_FLASH_SEMID 2U
59
60 /* Index of the semaphore used to access the PKA */
61 #define CFG_HW_PKA_SEMID 1U
62
63 /* Index of the semaphore used to access the RNG */
64 #define CFG_HW_RNG_SEMID 0U
65
66 /** Index of the semaphore used to access GPIO */
67 #define CFG_HW_GPIO_SEMID 8U
68
69 /** Index of the semaphore used to access the EXTI */
70 #define CFG_HW_EXTI_SEMID 9U
71
72 /** Index of the semaphore for CPU1 mailbox */
73 #define CFG_HW_IPM_CPU1_SEMID 10U
74
75 /** Index of the semaphore for CPU2 mailbox */
76 #define CFG_HW_IPM_CPU2_SEMID 11U
77
78 #elif defined(CONFIG_SOC_SERIES_STM32MP1X)
79 /** HW semaphore from STM32MP1
80 * EXTI and GPIO are inherited from STM32MP1 Linux.
81 * Other SEMID are not used by linux and must not be used here,
82 * but reserved for MPU.
83 */
84 /** Index of the semaphore used to access GPIO */
85 #define CFG_HW_GPIO_SEMID 0U
86
87 /** Index of the semaphore used to access the EXTI */
88 #define CFG_HW_EXTI_SEMID 1U
89
90 #else
91 /** Fake semaphore ID definition for compilation purpose only */
92 #define CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID 0U
93 #define CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID 0U
94 #define CFG_HW_CLK48_CONFIG_SEMID 0U
95 #define CFG_HW_RCC_CRRCR_CCIPR_SEMID 0U
96 #define CFG_HW_ENTRY_STOP_MODE_SEMID 0U
97 #define CFG_HW_RCC_SEMID 0U
98 #define CFG_HW_FLASH_SEMID 0U
99 #define CFG_HW_PKA_SEMID 0U
100 #define CFG_HW_RNG_SEMID 0U
101 #define CFG_HW_GPIO_SEMID 0U
102 #define CFG_HW_EXTI_SEMID 0U
103 #define CFG_HW_IPM_CPU1_SEMID 0U
104 #define CFG_HW_IPM_CPU2_SEMID 0U
105
106 #endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE */
107
108 /** Hardware Semaphore wait forever value */
109 #define HSEM_LOCK_WAIT_FOREVER 0xFFFFFFFFU
110 /** Hardware Semaphore default retry value */
111 #define HSEM_LOCK_DEFAULT_RETRY 0x100000U
112
113 /**
114 * @brief Lock Hardware Semaphore
115 */
z_stm32_hsem_lock(uint32_t hsem,uint32_t retry)116 static inline void z_stm32_hsem_lock(uint32_t hsem, uint32_t retry)
117 {
118 #if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) \
119 || defined(CONFIG_SOC_SERIES_STM32MP1X)
120
121 while (LL_HSEM_1StepLock(HSEM, hsem)) {
122 if (retry != HSEM_LOCK_WAIT_FOREVER) {
123 retry--;
124 if (retry == 0) {
125 k_panic();
126 }
127 }
128 }
129 #endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE || ... */
130 }
131
132 /**
133 * @brief Try to lock Hardware Semaphore
134 */
z_stm32_hsem_try_lock(uint32_t hsem)135 static inline int z_stm32_hsem_try_lock(uint32_t hsem)
136 {
137 #if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) \
138 || defined(CONFIG_SOC_SERIES_STM32MP1X)
139
140 if (LL_HSEM_1StepLock(HSEM, hsem)) {
141 return -EAGAIN;
142 }
143 #endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE || ... */
144
145 return 0;
146 }
147
148 /**
149 * @brief Release Hardware Semaphore
150 */
z_stm32_hsem_unlock(uint32_t hsem)151 static inline void z_stm32_hsem_unlock(uint32_t hsem)
152 {
153 #if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) \
154 || defined(CONFIG_SOC_SERIES_STM32MP1X)
155 LL_HSEM_ReleaseLock(HSEM, hsem, 0);
156 #endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE || ... */
157 }
158
159 /**
160 * @brief Indicates whether Hardware Semaphore is owned by this core
161 */
z_stm32_hsem_is_owned(uint32_t hsem)162 static inline bool z_stm32_hsem_is_owned(uint32_t hsem)
163 {
164 bool owned = false;
165
166 #if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) \
167 || defined(CONFIG_SOC_SERIES_STM32MP1X)
168
169 owned = LL_HSEM_GetCoreId(HSEM, hsem) == LL_HSEM_COREID;
170 #endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE || ... */
171
172 return owned;
173 }
174
175 #endif /* ZEPHYR_INCLUDE_DRIVERS_HSEM_STM32_HSEM_H_ */
176