/* * Copyright (c) 2019 STMicroelectronics * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_DRIVERS_HSEM_STM32_HSEM_H_ #define ZEPHYR_INCLUDE_DRIVERS_HSEM_STM32_HSEM_H_ #include #include #include #if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) /** HW semaphore Complement ID list defined in hw_conf.h from STM32WB * and used also for H7 dualcore targets */ /** * Index of the semaphore used by CPU2 to prevent the CPU1 to either write or * erase data in flash. The CPU1 shall not either write or erase in flash when * this semaphore is taken by the CPU2. When the CPU1 needs to either write or * erase in flash, it shall first get the semaphore and release it just * after writing a raw (64bits data) or erasing one sector. * On v1.4.0 and older CPU2 wireless firmware, this semaphore is unused and * CPU2 is using PES bit. By default, CPU2 is using the PES bit to protect its * timing. The CPU1 may request the CPU2 to use the semaphore instead of the * PES bit by sending the system command SHCI_C2_SetFlashActivityControl() */ #define CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID 7U /** * Index of the semaphore used by CPU1 to prevent the CPU2 to either write or * erase data in flash. In order to protect its timing, the CPU1 may get this * semaphore to prevent the CPU2 to either write or erase in flash * (as this will stall both CPUs) * The PES bit shall not be used as this may stall the CPU2 in some cases. */ #define CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID 6U /** * Index of the semaphore used to manage the CLK48 clock configuration * When the USB is required, this semaphore shall be taken before configuring * the CLK48 for USB and should be released after the application switch OFF * the clock when the USB is not used anymore. When using the RNG, it is good * enough to use CFG_HW_RNG_SEMID to control CLK48. * More details in AN5289 */ #define CFG_HW_CLK48_CONFIG_SEMID 5U #define CFG_HW_RCC_CRRCR_CCIPR_SEMID CFG_HW_CLK48_CONFIG_SEMID /* Index of the semaphore used to manage the entry Stop Mode procedure */ #define CFG_HW_ENTRY_STOP_MODE_SEMID 4U #define CFG_HW_ENTRY_STOP_MODE_MASK_SEMID (1U << CFG_HW_ENTRY_STOP_MODE_SEMID) /* Index of the semaphore used to access the RCC */ #define CFG_HW_RCC_SEMID 3U /* Index of the semaphore used to access the FLASH */ #define CFG_HW_FLASH_SEMID 2U /* Index of the semaphore used to access the PKA */ #define CFG_HW_PKA_SEMID 1U /* Index of the semaphore used to access the RNG */ #define CFG_HW_RNG_SEMID 0U /** Index of the semaphore used to access GPIO */ #define CFG_HW_GPIO_SEMID 8U /** Index of the semaphore used to access the EXTI */ #define CFG_HW_EXTI_SEMID 9U /** Index of the semaphore for CPU1 mailbox */ #define CFG_HW_IPM_CPU1_SEMID 10U /** Index of the semaphore for CPU2 mailbox */ #define CFG_HW_IPM_CPU2_SEMID 11U #elif defined(CONFIG_SOC_SERIES_STM32MP1X) /** HW semaphore from STM32MP1 * EXTI and GPIO are inherited from STM32MP1 Linux. * Other SEMID are not used by linux and must not be used here, * but reserved for MPU. */ /** Index of the semaphore used to access GPIO */ #define CFG_HW_GPIO_SEMID 0U /** Index of the semaphore used to access the EXTI */ #define CFG_HW_EXTI_SEMID 1U #else /** Fake semaphore ID definition for compilation purpose only */ #define CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID 0U #define CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID 0U #define CFG_HW_CLK48_CONFIG_SEMID 0U #define CFG_HW_RCC_CRRCR_CCIPR_SEMID 0U #define CFG_HW_ENTRY_STOP_MODE_SEMID 0U #define CFG_HW_RCC_SEMID 0U #define CFG_HW_FLASH_SEMID 0U #define CFG_HW_PKA_SEMID 0U #define CFG_HW_RNG_SEMID 0U #define CFG_HW_GPIO_SEMID 0U #define CFG_HW_EXTI_SEMID 0U #define CFG_HW_IPM_CPU1_SEMID 0U #define CFG_HW_IPM_CPU2_SEMID 0U #endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE */ /** Hardware Semaphore wait forever value */ #define HSEM_LOCK_WAIT_FOREVER 0xFFFFFFFFU /** Hardware Semaphore default retry value */ #define HSEM_LOCK_DEFAULT_RETRY 0x100000U /** * @brief Lock Hardware Semaphore */ static inline void z_stm32_hsem_lock(uint32_t hsem, uint32_t retry) { #if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) \ || defined(CONFIG_SOC_SERIES_STM32MP1X) while (LL_HSEM_1StepLock(HSEM, hsem)) { if (retry != HSEM_LOCK_WAIT_FOREVER) { retry--; if (retry == 0) { k_panic(); } } } #endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE || ... */ } /** * @brief Try to lock Hardware Semaphore */ static inline int z_stm32_hsem_try_lock(uint32_t hsem) { #if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) \ || defined(CONFIG_SOC_SERIES_STM32MP1X) if (LL_HSEM_1StepLock(HSEM, hsem)) { return -EAGAIN; } #endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE || ... */ return 0; } /** * @brief Release Hardware Semaphore */ static inline void z_stm32_hsem_unlock(uint32_t hsem) { #if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) \ || defined(CONFIG_SOC_SERIES_STM32MP1X) LL_HSEM_ReleaseLock(HSEM, hsem, 0); #endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE || ... */ } /** * @brief Indicates whether Hardware Semaphore is owned by this core */ static inline bool z_stm32_hsem_is_owned(uint32_t hsem) { bool owned = false; #if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) \ || defined(CONFIG_SOC_SERIES_STM32MP1X) owned = LL_HSEM_GetCoreId(HSEM, hsem) == LL_HSEM_COREID; #endif /* CONFIG_SOC_SERIES_STM32WBX || CONFIG_STM32H7_DUAL_CORE || ... */ return owned; } #endif /* ZEPHYR_INCLUDE_DRIVERS_HSEM_STM32_HSEM_H_ */