diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-12-04 07:41:29 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-12-04 07:41:29 -0600 |
commit | cfb48ddeb95a8e9a5f1fbd5ae0f7e08f6f6b5429 (patch) | |
tree | 49fe08006df62dc20afc4718b07680d8825f08d8 | |
parent | 35f099dcfae84f69d08ab94b5c471872833309c7 (diff) | |
download | px4-nuttx-cfb48ddeb95a8e9a5f1fbd5ae0f7e08f6f6b5429.tar.gz px4-nuttx-cfb48ddeb95a8e9a5f1fbd5ae0f7e08f6f6b5429.tar.bz2 px4-nuttx-cfb48ddeb95a8e9a5f1fbd5ae0f7e08f6f6b5429.zip |
SAMA5 NAND: Do not perform DMA on small transfers
-rw-r--r-- | nuttx/arch/arm/src/sama5/Kconfig | 22 | ||||
-rw-r--r-- | nuttx/arch/arm/src/sama5/sam_nand.c | 18 | ||||
-rw-r--r-- | nuttx/arch/arm/src/sama5/sam_nand.h | 18 |
3 files changed, 49 insertions, 9 deletions
diff --git a/nuttx/arch/arm/src/sama5/Kconfig b/nuttx/arch/arm/src/sama5/Kconfig index 12513c5c0..ea4b0b729 100644 --- a/nuttx/arch/arm/src/sama5/Kconfig +++ b/nuttx/arch/arm/src/sama5/Kconfig @@ -3348,8 +3348,26 @@ config SAMA5_NAND_DMA default y depends on SAMA5_DMAC0 ---help--- - Use DMA to perform NAND data transfers. NOTE that DMAC0 must be - selected (DMAC1 cannot access NFC SRAM). (highly recommended) + Use memory-to-memory DMA to perform NAND data transfers. NOTE that + DMAC0 must be selected (DMAC1 cannot access NFC SRAM). + +config SAMA5_NAND_DMA_THRESHOLD + int "DMA threshold" + default 784 + depends on SAMA5_NAND_DMA + ---help--- + Defines a threshold value for performing memory-to-memory DMA. + + If memory-to-memory DMAs are used, then two context switches will + occur: (1) when the NAND logic waits for the DMA to complete, and + (2) again when the DMA completes and the NAND logic is re-awakened. + Each context switch will required saving and restoring a set of + registers defining the task state. Those register include the PSR, + 16 general purpose registers, and 32 floating point registers or + about 196 bytes per task state. That is then 392*2 bytes per + context and 784 bytes for both. Plus there is processing overhead. + So certainly, there is no reason to use a memory-to-memory DMA + transfer for much smaller blocks of data. config SAMA5_NAND_READYBUSY bool "NAND Ready/Busy" diff --git a/nuttx/arch/arm/src/sama5/sam_nand.c b/nuttx/arch/arm/src/sama5/sam_nand.c index 6fecea58f..b5865be8c 100644 --- a/nuttx/arch/arm/src/sama5/sam_nand.c +++ b/nuttx/arch/arm/src/sama5/sam_nand.c @@ -1599,11 +1599,13 @@ static int nand_read(struct sam_nandcs_s *priv, bool nfcsram, } #ifdef CONFIG_SAMA5_NAND_DMA - /* Then perform the transfer via DMA or not, depending on if we have - * a DMA channel assigned. + /* Then perform the transfer via memory-to-memory DMA or not, depending + * on if we have a DMA channel assigned and if the transfer is + * sufficiently large. Small DMAs (e.g., for spare data) are not peformed + * because the DMA context switch can take more time that the DMA itself. */ - if (priv->dma) + if (priv->dma && buflen > CONFIG_SAMA5_NAND_DMA_THRESHOLD) { /* Transfer using DMA */ @@ -1909,12 +1911,14 @@ static int nand_write(struct sam_nandcs_s *priv, bool nfcsram, dest += offset; - /* Then perform the transfer via DMA or not, depending on if we have - * a DMA channel assigned. +#ifdef CONFIG_SAMA5_NAND_DMA + /* Then perform the transfer via memory-to-memory DMA or not, depending + * on if we have a DMA channel assigned and if the transfer is + * sufficiently large. Small DMAs (e.g., for spare data) are not peformed + * because the DMA context switch can take more time that the DMA itself. */ -#ifdef CONFIG_SAMA5_NAND_DMA - if (priv->dma) + if (priv->dma && buflen > CONFIG_SAMA5_NAND_DMA_THRESHOLD) { /* Transfer using DMA */ diff --git a/nuttx/arch/arm/src/sama5/sam_nand.h b/nuttx/arch/arm/src/sama5/sam_nand.h index cd282c6a9..ca1d8fd81 100644 --- a/nuttx/arch/arm/src/sama5/sam_nand.h +++ b/nuttx/arch/arm/src/sama5/sam_nand.h @@ -74,6 +74,24 @@ # endif #endif +/* If memory-to-memory DMAs are used, then two context switches will occur: + * (1) when the NAND logic waits for the DMA to complete, and (2) again when + * the DMA completes and the NAND logic is re-awakened. Each context switch + * will required saving and restoring a set of registers defining the task + * state. Those register include the PSR, 16 general purpose registers, and + * 32 floating point registers or about 196 bytes per task state. That is + * then 392*2 bytes per context and 784 bytes for both. Plus there is + * processing overhead. So certainly, there is no reason to use a memory-to- + * memory DMA transfer for much smaller blocks of data. + */ + +#ifdef CONFIG_SAMA5_NAND_DMA +# ifndef CONFIG_SAMA5_NAND_DMA_THRESHOLD +# define CONFIG_SAMA5_NAND_DMA_THRESHOLD 784 +# endif +#endif + + /* Hardware ECC types. These are extensions to the NANDECC_HWECC value * defined in include/nuttx/mtd/nand_raw.h. * |