From e0d6534f09afbcb5f9dc6cda95bf5742b514db30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Boutreux?= Date: Fri, 2 Aug 2019 07:53:07 +0200 Subject: [PATCH] drivers: spi: spi_ll_stm32: Add support for STM32MP1x SoC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add SPI driver support for STM32MP1x SoC. Signed-off-by: Yaƫl Boutreux Signed-off-by: Arnaud Pouliquen Signed-off-by: Alexandre Torgue --- drivers/spi/Kconfig.stm32 | 4 +- drivers/spi/spi_ll_stm32.c | 18 +++++++++ drivers/spi/spi_ll_stm32.h | 69 +++++++++++++++++++++++++++++++++ soc/arm/st_stm32/stm32mp1/soc.h | 4 ++ 4 files changed, 94 insertions(+), 1 deletion(-) diff --git a/drivers/spi/Kconfig.stm32 b/drivers/spi/Kconfig.stm32 index be8a3aa30db..1147d8b46e2 100644 --- a/drivers/spi/Kconfig.stm32 +++ b/drivers/spi/Kconfig.stm32 @@ -17,7 +17,9 @@ if SPI_STM32 config SPI_STM32_HAS_FIFO bool - depends on SOC_SERIES_STM32L4X || SOC_SERIES_STM32F0X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32F7X || SOC_SERIES_STM32WBX + depends on (SOC_SERIES_STM32L4X || SOC_SERIES_STM32F0X || \ + SOC_SERIES_STM32F3X || SOC_SERIES_STM32F7X || SOC_SERIES_STM32MP1X || \ + SOC_SERIES_STM32WBX) default y config SPI_STM32_INTERRUPT diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index 37362e90e80..fce2e17807d 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -31,6 +31,10 @@ LOG_MODULE_REGISTER(spi_ll_stm32); * error flag, because STM32F1 SoCs do not support it and STM32CUBE * for F1 family defines an unused LL_SPI_SR_FRE. */ +#ifdef CONFIG_SOC_SERIES_STM32MP1X +#define SPI_STM32_ERR_MSK (LL_SPI_SR_UDR | LL_SPI_SR_CRCE | LL_SPI_SR_MODF | \ + LL_SPI_SR_OVR | LL_SPI_SR_TIFRE) +#else #if defined(LL_SPI_SR_UDR) #define SPI_STM32_ERR_MSK (LL_SPI_SR_UDR | LL_SPI_SR_CRCERR | LL_SPI_SR_MODF | \ LL_SPI_SR_OVR | LL_SPI_SR_FRE) @@ -40,6 +44,7 @@ LOG_MODULE_REGISTER(spi_ll_stm32); #else #define SPI_STM32_ERR_MSK (LL_SPI_SR_CRCERR | LL_SPI_SR_MODF | LL_SPI_SR_OVR) #endif +#endif /* CONFIG_SOC_SERIES_STM32MP1X */ /* Value to shift out when no application data needs transmitting. */ #define SPI_STM32_TX_NOP 0x00 @@ -93,6 +98,19 @@ static void spi_stm32_shift_m(SPI_TypeDef *spi, struct spi_stm32_data *data) while (!ll_func_tx_is_empty(spi)) { /* NOP */ } + +#ifdef CONFIG_SOC_SERIES_STM32MP1X + /* With the STM32MP1, if the device is the SPI master, we need to enable + * the start of the transfer with LL_SPI_StartMasterTransfer(spi) + */ + if (LL_SPI_GetMode(spi) == LL_SPI_MODE_MASTER) { + LL_SPI_StartMasterTransfer(spi); + while (!LL_SPI_IsActiveMasterTransfer(spi)) { + /* NOP */ + } + } +#endif + if (SPI_WORD_SIZE_GET(data->ctx.config->operation) == 8) { LL_SPI_TransmitData8(spi, tx_frame); /* The update is ignored if TX is off. */ diff --git a/drivers/spi/spi_ll_stm32.h b/drivers/spi/spi_ll_stm32.h index 472431b0750..ce1618e6c9b 100644 --- a/drivers/spi/spi_ll_stm32.h +++ b/drivers/spi/spi_ll_stm32.h @@ -25,47 +25,92 @@ struct spi_stm32_data { static inline u32_t ll_func_tx_is_empty(SPI_TypeDef *spi) { +#ifdef CONFIG_SOC_SERIES_STM32MP1X + return LL_SPI_IsActiveFlag_TXP(spi); +#else return LL_SPI_IsActiveFlag_TXE(spi); +#endif } static inline u32_t ll_func_rx_is_not_empty(SPI_TypeDef *spi) { +#ifdef CONFIG_SOC_SERIES_STM32MP1X + return LL_SPI_IsActiveFlag_RXP(spi); +#else return LL_SPI_IsActiveFlag_RXNE(spi); +#endif } static inline void ll_func_enable_int_tx_empty(SPI_TypeDef *spi) { +#ifdef CONFIG_SOC_SERIES_STM32MP1X + LL_SPI_EnableIT_TXP(spi); +#else LL_SPI_EnableIT_TXE(spi); +#endif } static inline void ll_func_enable_int_rx_not_empty(SPI_TypeDef *spi) { +#ifdef CONFIG_SOC_SERIES_STM32MP1X + LL_SPI_EnableIT_RXP(spi); +#else LL_SPI_EnableIT_RXNE(spi); +#endif } static inline void ll_func_enable_int_errors(SPI_TypeDef *spi) { +#ifdef CONFIG_SOC_SERIES_STM32MP1X + LL_SPI_EnableIT_UDR(spi); + LL_SPI_EnableIT_OVR(spi); + LL_SPI_EnableIT_CRCERR(spi); + LL_SPI_EnableIT_FRE(spi); + LL_SPI_EnableIT_MODF(spi); +#else LL_SPI_EnableIT_ERR(spi); +#endif } static inline void ll_func_disable_int_tx_empty(SPI_TypeDef *spi) { +#ifdef CONFIG_SOC_SERIES_STM32MP1X + LL_SPI_DisableIT_TXP(spi); +#else LL_SPI_DisableIT_TXE(spi); +#endif } static inline void ll_func_disable_int_rx_not_empty(SPI_TypeDef *spi) { +#ifdef CONFIG_SOC_SERIES_STM32MP1X + LL_SPI_DisableIT_RXP(spi); +#else LL_SPI_DisableIT_RXNE(spi); +#endif } static inline void ll_func_disable_int_errors(SPI_TypeDef *spi) { +#ifdef CONFIG_SOC_SERIES_STM32MP1X + LL_SPI_DisableIT_UDR(spi); + LL_SPI_DisableIT_OVR(spi); + LL_SPI_DisableIT_CRCERR(spi); + LL_SPI_DisableIT_FRE(spi); + LL_SPI_DisableIT_MODF(spi); +#else LL_SPI_DisableIT_ERR(spi); +#endif } static inline u32_t ll_func_spi_is_busy(SPI_TypeDef *spi) { +#ifdef CONFIG_SOC_SERIES_STM32MP1X + return (!LL_SPI_IsActiveFlag_MODF(spi) && + !LL_SPI_IsActiveFlag_TXC(spi)); +#else return LL_SPI_IsActiveFlag_BSY(spi); +#endif } /* Header is compiled first, this switch avoid the compiler to lookup for @@ -74,13 +119,37 @@ static inline u32_t ll_func_spi_is_busy(SPI_TypeDef *spi) #ifdef CONFIG_SPI_STM32_HAS_FIFO static inline void ll_func_set_fifo_threshold_8bit(SPI_TypeDef *spi) { +#ifdef CONFIG_SOC_SERIES_STM32MP1X + LL_SPI_SetFIFOThreshold(spi, LL_SPI_FIFO_TH_01DATA); +#else LL_SPI_SetRxFIFOThreshold(spi, LL_SPI_RX_FIFO_TH_QUARTER); +#endif } #endif static inline void ll_func_disable_spi(SPI_TypeDef *spi) { +#ifdef CONFIG_SOC_SERIES_STM32MP1X + if (LL_SPI_IsActiveMasterTransfer(spi)) { + LL_SPI_SuspendMasterTransfer(spi); + while (LL_SPI_IsActiveMasterTransfer(spi)) { + /* NOP */ + } + } + LL_SPI_Disable(spi); + while (LL_SPI_IsEnabled(spi)) { + /* NOP */ + } + + /* Flush RX buffer */ + while (LL_SPI_IsActiveFlag_RXP(spi)) { + (void)LL_SPI_ReceiveData8(spi); + } + LL_SPI_ClearFlag_SUSP(spi); +#else + LL_SPI_Disable(spi); +#endif } #endif /* ZEPHYR_DRIVERS_SPI_SPI_LL_STM32_H_ */ diff --git a/soc/arm/st_stm32/stm32mp1/soc.h b/soc/arm/st_stm32/stm32mp1/soc.h index 2a8b3668cd6..392e010a148 100644 --- a/soc/arm/st_stm32/stm32mp1/soc.h +++ b/soc/arm/st_stm32/stm32mp1/soc.h @@ -46,6 +46,10 @@ #include #endif +#ifdef CONFIG_SPI_STM32 +#include +#endif + #ifdef CONFIG_IPM_STM32_IPCC #include #endif