From bd107d20ee00dc05a4405dfe0270c7b6e9c3afa4 Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Thu, 17 Aug 2017 09:33:34 -1000 Subject: [PATCH 1/5] sdio.h:Fix typos --- include/nuttx/sdio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nuttx/sdio.h b/include/nuttx/sdio.h index 41752a264c..eb7498285a 100644 --- a/include/nuttx/sdio.h +++ b/include/nuttx/sdio.h @@ -671,7 +671,7 @@ * SDIO_WAITEVENT: Wait for the event of interest (which might * already have occurred) * - * This sequency should eliminate race conditions between the command/trasnfer + * This sequence should eliminate race conditions between the command/transfer * setup and the subsequent events. * * The enabled events persist until either (1) SDIO_WAITENABLE is called From 38cbf1f6602497068629c1becace5f71d03704df Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Thu, 17 Aug 2017 09:35:50 -1000 Subject: [PATCH 2/5] stm32f7:DMA correct comments and document stm32_dmacapable Updated comment to proper refernce manual for STM32F7 not STM32F4. Added stm32_dmacapable input paramaters documentation. --- arch/arm/src/stm32f7/stm32_dma.c | 10 +++++++++- arch/arm/src/stm32f7/stm32_dma.h | 7 +++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/arm/src/stm32f7/stm32_dma.c b/arch/arm/src/stm32f7/stm32_dma.c index efd5e005ec..ef55df9ec5 100644 --- a/arch/arm/src/stm32f7/stm32_dma.c +++ b/arch/arm/src/stm32f7/stm32_dma.c @@ -860,6 +860,13 @@ size_t stm32_dmaresidual(DMA_HANDLE handle) * of the processor. Note that this only applies to memory addresses, it * will return false for any peripheral address. * + * Input Parameters: + * + * maddr - starting memory address + * count - number of unit8 or uint16 or uint32 items as defined by MSIZE of + * ccr. + * ccr - DMA stream configuration register + * * Returned value: * True, if transfer is possible. * @@ -877,7 +884,8 @@ bool stm32_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr) * Transfers to/from memory performed by the DMA controller are * required to be aligned to their size. * - * See ST RM0090 rev4, section 9.3.11 + * See ST RM0410 DocID028270 Rev 2, section 8.3.11 Single and burst + * transfers * * Compute mend inline to avoid a possible non-constant integer * multiply. diff --git a/arch/arm/src/stm32f7/stm32_dma.h b/arch/arm/src/stm32f7/stm32_dma.h index 3604d45d0c..e0494d5381 100644 --- a/arch/arm/src/stm32f7/stm32_dma.h +++ b/arch/arm/src/stm32f7/stm32_dma.h @@ -241,6 +241,13 @@ size_t stm32_dmaresidual(DMA_HANDLE handle); * only applies to memory addresses, it will return false for any peripheral * address. * + * Input Parameters: + * + * maddr - starting memory address + * count - number of unit8 or uint16 or uint32 items as defined by MSIZE of + * ccr. + * ccr - DMA stream configuration register + * * Returned value: * True, if transfer is possible. * From dffab2f4dd6d8686838dd8e5d5a02e6dd147f260 Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Thu, 17 Aug 2017 09:39:14 -1000 Subject: [PATCH 3/5] stm32f7:DMA add dcache alignment check in stm32_dmacapable In the case dcache write-buffed mode is used (not write-through) buffer alignment is required for DMA transfers because a) arch_invalidate_dcache could lose buffered writes data and b) arch_flush_dcache could corrupt adjacent memory if the maddr and the mend+1, the next next address are not on ARMV7M_DCACHE_LINESIZE boundaries. --- arch/arm/src/stm32f7/stm32_dma.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm/src/stm32f7/stm32_dma.c b/arch/arm/src/stm32f7/stm32_dma.c index ef55df9ec5..92e8cb2437 100644 --- a/arch/arm/src/stm32f7/stm32_dma.c +++ b/arch/arm/src/stm32f7/stm32_dma.c @@ -919,6 +919,23 @@ bool stm32_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr) return false; } +# if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH) + /* buffer alignment is required for DMA transfers with dcache in buffered + * mode (not write-through) because a) arch_invalidate_dcache could lose + * buffered writes and b) arch_flush_dcache could corrupt adjacent memory if + * the maddr and the mend+1, the next next address are not on + * ARMV7M_DCACHE_LINESIZE boundaries. + */ + + if ((maddr & (ARMV7M_DCACHE_LINESIZE-1)) != 0 || + ((mend + 1) & (ARMV7M_DCACHE_LINESIZE-1)) != 0) + { + dmainfo("stm32_dmacapable: dcache unaligned maddr:0x%08x mend:0x%08x\n", + maddr, mend); + return false; + } +# endif + /* Verify that burst transfers do not cross a 1KiB boundary. */ if ((maddr / 1024) != (mend / 1024)) From 1e7ddfea8e5fbf06516a9d14b81d87f236f76c16 Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Thu, 17 Aug 2017 09:48:46 -1000 Subject: [PATCH 4/5] stm32f7:SDMMC remove widebus limitation on DMA There is no documantation for the STM32F7 that limits DMA on 1 bit vrs 4 bit mode. --- arch/arm/src/stm32f7/stm32_sdmmc.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index 6be8f5f496..ac955044bf 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -2802,13 +2802,6 @@ static int stm32_dmapreflight(FAR struct sdio_dev_s *dev, DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); - /* Wide bus operation is required for DMA */ - - if (!priv->widebus) - { - return -EINVAL; - } - /* DMA must be possible to the buffer */ if (!stm32_dmacapable((uintptr_t)buffer, (buflen + 3) >> 2, From ef42c251402d27b23e56402db387b96b5b4e8697 Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Thu, 17 Aug 2017 09:51:37 -1000 Subject: [PATCH 5/5] stm32f7:SDMMC add dcache alignment check in dma{recv|send}setup In the where CONFIG_SDIO_PREFLIGHT is not used and dcache write-buffed mode is used (not write-through) buffer alignment is required for DMA transfers because a) arch_invalidate_dcache could lose buffered writes data and b) arch_flush_dcache could corrupt adjacent memory if the buffer and the bufflen, are not on ARMV7M_DCACHE_LINESIZE boundaries. --- arch/arm/src/stm32f7/stm32_sdmmc.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index ac955044bf..49a70d63fa 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -2843,16 +2843,21 @@ static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); #ifdef CONFIG_SDIO_PREFLIGHT DEBUGASSERT(stm32_dmapreflight(dev, buffer, buflen) == 0); -#endif - -#ifdef CONFIG_ARMV7M_DCACHE - /* buffer alignment is required for DMA transfers with dcache */ +#else +# if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH) + /* buffer alignment is required for DMA transfers with dcache in buffered + * mode (not write-through) because the arch_invalidate_dcache could lose + * buffered buffered writes if the buffer alignment and sizes are not on + * ARMV7M_DCACHE_LINESIZE boundaries. + */ if (((uintptr_t)buffer & (ARMV7M_DCACHE_LINESIZE-1)) != 0 || (buflen & (ARMV7M_DCACHE_LINESIZE-1)) != 0) { return -EFAULT; } +# endif + #endif /* Reset the DPSM configuration */ @@ -2928,16 +2933,20 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); #ifdef CONFIG_SDIO_PREFLIGHT DEBUGASSERT(stm32_dmapreflight(dev, buffer, buflen) == 0); -#endif - -#ifdef CONFIG_ARMV7M_DCACHE - /* buffer alignment is required for DMA transfers with dcache */ +#else +# if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH) + /* buffer alignment is required for DMA transfers with dcache in buffered + * mode (not write-through) because the arch_flush_dcache would corrupt adjacent + * memory if the buffer alignment and sizes are not on ARMV7M_DCACHE_LINESIZE + * boundaries. + */ if (((uintptr_t)buffer & (ARMV7M_DCACHE_LINESIZE-1)) != 0 || (buflen & (ARMV7M_DCACHE_LINESIZE-1)) != 0) { return -EFAULT; } +# endif #endif /* Reset the DPSM configuration */