summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/arch/arm/src/sama5/sam_memories.c32
-rw-r--r--nuttx/arch/arm/src/sama5/sam_nand.c122
-rw-r--r--nuttx/configs/sama5d3x-ek/README.txt30
3 files changed, 156 insertions, 28 deletions
diff --git a/nuttx/arch/arm/src/sama5/sam_memories.c b/nuttx/arch/arm/src/sama5/sam_memories.c
index 833ef0991..6e1b38f7a 100644
--- a/nuttx/arch/arm/src/sama5/sam_memories.c
+++ b/nuttx/arch/arm/src/sama5/sam_memories.c
@@ -211,7 +211,8 @@ static inline uintptr_t sdram_physramaddr(uintptr_t virtramaddr)
*
* Description:
* Given the virtual address of an NFC SRAM memory location, return the
- * physical address of that location
+ * physical address of that location. If NFC SRAM is not being used by
+ * the NAND logic, then it may be used a general purpose SRAM.
*
****************************************************************************/
@@ -465,10 +466,12 @@ static inline uintptr_t sdram_virtramaddr(uintptr_t physramaddr)
*
* Description:
* Given the physical address of an NFC SRAM memory location, return the
- * virtual address of that location
+ * virtual address of that location. If NFC SRAM is not being used by
+ * the NAND logic, then it may be used a general purpose SRAM.
*
****************************************************************************/
+#ifndef CONFIG_SAMA5_HAVE_NAND
static inline uintptr_t nfcsram_virtramaddr(uintptr_t physramaddr)
{
#if SAM_NFCSRAM_PSECTION != SAM_NFCSRAM_VSECTION
@@ -489,6 +492,7 @@ static inline uintptr_t nfcsram_virtramaddr(uintptr_t physramaddr)
#endif
}
+#endif
/****************************************************************************
* Name: udphsram_virtramaddr
@@ -691,6 +695,18 @@ uintptr_t sam_physregaddr(uintptr_t virtregaddr)
return sysc_physregaddr(virtregaddr);
}
+ /* Check for NFCS SRAM. If NFC SRAM is being used by the NAND logic,
+ * then it will be treated as peripheral space.
+ */
+
+#ifdef CONFIG_SAMA5_HAVE_NAND
+ if (virtregaddr >= SAM_NFCSRAM_VSECTION &&
+ virtregaddr < (SAM_NFCSRAM_VSECTION + SAM_NFCSRAM_SIZE))
+ {
+ return nfcsram_physramaddr(virtregaddr);
+ }
+#endif
+
/* We will not get here unless we are called with an invalid register
* address
*/
@@ -731,13 +747,17 @@ uintptr_t sam_physramaddr(uintptr_t virtramaddr)
}
#endif
- /* Check for NFCS SRAM. */
+ /* Check for NFCS SRAM. If NFC SRAM is not being used by the NAND logic,
+ * then it may be used a general purpose SRAM.
+ */
+#ifndef CONFIG_SAMA5_HAVE_NAND
if (virtramaddr >= SAM_NFCSRAM_VSECTION &&
virtramaddr < (SAM_NFCSRAM_VSECTION + SAM_NFCSRAM_SIZE))
{
return nfcsram_physramaddr(virtramaddr);
}
+#endif
/* Check for UDPH SRAM. */
@@ -835,13 +855,17 @@ uintptr_t sam_virtramaddr(uintptr_t physramaddr)
}
#endif
- /* Check for NFCS SRAM. */
+ /* Check for NFCS SRAM. If NFC SRAM is not being used by the NAND logic,
+ * then it may be used a general purpose SRAM.
+ */
+#ifndef CONFIG_SAMA5_HAVE_NAND
if (physramaddr >= SAM_NFCSRAM_PSECTION &&
physramaddr < (SAM_NFCSRAM_PSECTION + SAM_NFCSRAM_SIZE))
{
return nfcsram_virtramaddr(physramaddr);
}
+#endif
/* Check for UDPH SRAM. */
diff --git a/nuttx/arch/arm/src/sama5/sam_nand.c b/nuttx/arch/arm/src/sama5/sam_nand.c
index f39418026..dc7492712 100644
--- a/nuttx/arch/arm/src/sama5/sam_nand.c
+++ b/nuttx/arch/arm/src/sama5/sam_nand.c
@@ -107,7 +107,7 @@
/* DMA Configuration */
-#define DMA_FLAGS8 \
+#define NFCSRAM_DMA_FLAGS8 \
DMACH_FLAG_FIFOCFG_LARGEST | \
(((0x3f) << DMACH_FLAG_PERIPHPID_SHIFT) | DMACH_FLAG_PERIPHAHB_AHB_IF0 | \
DMACH_FLAG_PERIPHWIDTH_8BITS | DMACH_FLAG_PERIPHINCREMENT | \
@@ -116,7 +116,15 @@
DMACH_FLAG_MEMWIDTH_8BITS | DMACH_FLAG_MEMINCREMENT | \
DMACH_FLAG_MEMCHUNKSIZE_1)
-#define DMA_FLAGS16 \
+#define NAND_DMA_FLAGS8 \
+ DMACH_FLAG_FIFOCFG_LARGEST | \
+ (((0x3f) << DMACH_FLAG_PERIPHPID_SHIFT) | DMACH_FLAG_PERIPHAHB_AHB_IF0 | \
+ DMACH_FLAG_PERIPHWIDTH_8BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 | \
+ ((0x3f) << DMACH_FLAG_MEMPID_SHIFT) | DMACH_FLAG_MEMAHB_AHB_IF0 | \
+ DMACH_FLAG_MEMWIDTH_8BITS | DMACH_FLAG_MEMINCREMENT | \
+ DMACH_FLAG_MEMCHUNKSIZE_1)
+
+#define NFCSRAM_DMA_FLAGS16 \
DMACH_FLAG_FIFOCFG_LARGEST | \
(((0x3f) << DMACH_FLAG_PERIPHPID_SHIFT) | DMACH_FLAG_PERIPHAHB_AHB_IF0 | \
DMACH_FLAG_PERIPHWIDTH_16BITS | DMACH_FLAG_PERIPHINCREMENT | \
@@ -125,6 +133,14 @@
DMACH_FLAG_MEMWIDTH_16BITS | DMACH_FLAG_MEMINCREMENT | \
DMACH_FLAG_MEMCHUNKSIZE_1)
+#define NAND_DMA_FLAGS16 \
+ DMACH_FLAG_FIFOCFG_LARGEST | \
+ (((0x3f) << DMACH_FLAG_PERIPHPID_SHIFT) | DMACH_FLAG_PERIPHAHB_AHB_IF0 | \
+ DMACH_FLAG_PERIPHWIDTH_16BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 | \
+ ((0x3f) << DMACH_FLAG_MEMPID_SHIFT) | DMACH_FLAG_MEMAHB_AHB_IF0 | \
+ DMACH_FLAG_MEMWIDTH_16BITS | DMACH_FLAG_MEMINCREMENT | \
+ DMACH_FLAG_MEMCHUNKSIZE_1)
+
/****************************************************************************
* Private Types
****************************************************************************/
@@ -170,9 +186,11 @@ static int hsmc_interrupt(int irq, void *context);
static int nand_wait_dma(struct sam_nandcs_s *priv);
static void nand_dmacallback(DMA_HANDLE handle, void *arg, int result);
static int nand_dma_read(struct sam_nandcs_s *priv,
- uintptr_t vsrc, uintptr_t vdest, size_t nbytes);
+ uintptr_t vsrc, uintptr_t vdest, size_t nbytes,
+ uint32_t dmaflags);
static int nand_dma_write(struct sam_nandcs_s *priv,
- uintptr_t vsrc, uintptr_t vdest, size_t nbytes)
+ uintptr_t vsrc, uintptr_t vdest, size_t nbytes,
+ uint32_t dmaflags)
#endif
/* Raw Data Transfer Helpers */
@@ -972,10 +990,11 @@ static void nand_dmacallback(DMA_HANDLE handle, void *arg, int result)
* Transfer data to NAND from the provided buffer via DMA.
*
* Input Parameters:
- * priv - Lower-half, private NAND FLASH device state
- * vsrc - NAND data destination address.
- * vdest - Buffer where data read from NAND will be returned.
- * nbytes - The number of bytes to transfer
+ * priv - Lower-half, private NAND FLASH device state
+ * vsrc - NAND data destination address.
+ * vdest - Buffer where data read from NAND will be returned.
+ * nbytes - The number of bytes to transfer
+ * dmaflags - Describes the DMA configuration
*
* Returned Value
* OK on success; a negated errno value on failure.
@@ -984,7 +1003,8 @@ static void nand_dmacallback(DMA_HANDLE handle, void *arg, int result)
#ifdef CONFIG_SAMA5_NAND_DMA
static int nand_dma_read(struct sam_nandcs_s *priv,
- uintptr_t vsrc, uintptr_t vdest, size_t nbytes)
+ uintptr_t vsrc, uintptr_t vdest, size_t nbytes,
+ uint32_t dmaflags)
{
uint32_t psrc;
uint32_t pdest;
@@ -1007,6 +1027,10 @@ static int nand_dma_read(struct sam_nandcs_s *priv,
psrc = sam_physregaddr(vsrc); /* Source is NAND */
pdest = sam_physramaddr(vdest); /* Destination is normal memory */
+ /* Configure the DMA: 8- vs 16-bit, NFC SRAM or NAND */
+
+ sam_dmaconfig(priv->dma, dmaflags);
+
/* Setup the Memory-to-Memory DMA. The semantics of the DMA module are
* awkward here. We will treat the NAND (src) as the peripheral source
* and memory as the destination. Internally, the DMA module will realize
@@ -1046,10 +1070,11 @@ static int nand_dma_read(struct sam_nandcs_s *priv,
* Transfer data to NAND from the provided buffer via DMA.
*
* Input Parameters:
- * priv - Lower-half, private NAND FLASH device state
- * vsrc - Buffer that provides the data for the write
- * vdest - NAND data destination address
- * nbytes - The number of bytes to transfer
+ * priv - Lower-half, private NAND FLASH device state
+ * vsrc - Buffer that provides the data for the write
+ * vdest - NAND data destination address
+ * nbytes - The number of bytes to transfer
+ * dmaflags - Describes the DMA configuration
*
* Returned Value
* OK on success; a negated errno value on failure.
@@ -1058,7 +1083,8 @@ static int nand_dma_read(struct sam_nandcs_s *priv,
#ifdef CONFIG_SAMA5_NAND_DMA
static int nand_dma_write(struct sam_nandcs_s *priv,
- uintptr_t vsrc, uintptr_t vdest, size_t nbytes)
+ uintptr_t vsrc, uintptr_t vdest, size_t nbytes,
+ uint32_t dmaflags)
{
uint32_t psrc;
uint32_t pdest;
@@ -1077,6 +1103,10 @@ static int nand_dma_write(struct sam_nandcs_s *priv,
psrc = sam_physramaddr(vsrc); /* Source is normal memory */
pdest = sam_physregaddr(vdest); /* Destination is NAND (or NAND host SRAM) */
+ /* Configure the DMA: 8- vs 16-bit, NFC SRAM or NAND */
+
+ sam_dmaconfig(priv->dma, dmaflags);
+
/* Setup the Memory-to-Memory DMA. The semantics of the DMA module are
* awkward here. We will treat the NAND (dest) as the peripheral destination
* and memory as the source. Internally, the DMA module will realize taht
@@ -1216,17 +1246,40 @@ static int nand_read(struct sam_nandcs_s *priv, bool nfcsram,
uint8_t *buffer, size_t buflen)
{
uintptr_t src;
+#ifdef CONFIG_SAMA5_NAND_DMA
+ uint32_t dmaflags;
+#endif
int buswidth;
- /* Pick the data destination: The NFC SRAM or the NAND data address */
+ /* Get the buswidth */
+
+ buswidth = nandmodel_getbuswidth(&priv->raw.model);
+
+ /* Pick the data source: The NFC SRAM or the NAND data address */
if (nfcsram)
{
+ /* Source is NFC SRAM */
+
src = NFCSRAM_BASE;
+
+#ifdef CONFIG_SAMA5_NAND_DMA
+ /* Select NFC SRAM DMA */
+
+ dmaflags = (buswidth == 16 ? NFCSRAM_DMA_FLAGS16 : NFCSRAM_DMA_FLAGS8);
+#endif
}
else
{
+ /* Source is NFC NAND */
+
src = priv->raw.dataaddr;
+
+#ifdef CONFIG_SAMA5_NAND_DMA
+ /* Select NAND DMA */
+
+ dmaflags = (buswidth == 16 ? NAND_DMA_FLAGS16 : NAND_DMA_FLAGS8);
+#endif
}
#ifdef CONFIG_SAMA5_NAND_DMA
@@ -1238,7 +1291,7 @@ static int nand_read(struct sam_nandcs_s *priv, bool nfcsram,
{
/* Transfer using DMA */
- return nand_dma_read(priv, src, (uintptr_t)buffer, buflen);
+ return nand_dma_read(priv, src, (uintptr_t)buffer, buflen, dmaflags);
}
else
#endif
@@ -1253,7 +1306,6 @@ static int nand_read(struct sam_nandcs_s *priv, bool nfcsram,
{
/* Check the data bus width of the NAND FLASH */
- buswidth = nandmodel_getbuswidth(&priv->raw.model);
if (buswidth == 16)
{
return nand_smc_read16(src, buffer, buflen);
@@ -1493,17 +1545,40 @@ static int nand_write(struct sam_nandcs_s *priv, bool nfcsram,
uint8_t *buffer, size_t buflen, off_t offset)
{
uintptr_t dest;
+#ifdef CONFIG_SAMA5_NAND_DMA
+ uint32_t dmaflags;
+#endif
int buswidth;
- /* Pick the data source: The NFC SRAM or the NAND data address */
+ /* Get the buswidth */
+
+ buswidth = nandmodel_getbuswidth(&priv->raw.model);
+
+ /* Pick the data destination: The NFC SRAM or the NAND data address */
if (nfcsram)
{
+ /* Destination is NFC SRAM */
+
dest = NFCSRAM_BASE;
+
+#ifdef CONFIG_SAMA5_NAND_DMA
+ /* Select NFC SRAM DMA */
+
+ dmaflags = (buswidth == 16 ? NFCSRAM_DMA_FLAGS16 : NFCSRAM_DMA_FLAGS8);
+#endif
}
else
{
+ /* Destination is NFC NAND */
+
dest = priv->raw.dataaddr;
+
+#ifdef CONFIG_SAMA5_NAND_DMA
+ /* Select NAND DMA */
+
+ dmaflags = (buswidth == 16 ? NAND_DMA_FLAGS16 : NAND_DMA_FLAGS8);
+#endif
}
/* Apply the offset to the source address */
@@ -1519,7 +1594,7 @@ static int nand_write(struct sam_nandcs_s *priv, bool nfcsram,
{
/* Transfer using DMA */
- return nand_dma_write(priv, (uintptr_t)buffer, dest, buflen);
+ return nand_dma_write(priv, (uintptr_t)buffer, dest, buflen, dmaflags);
}
else
#endif
@@ -1534,7 +1609,6 @@ static int nand_write(struct sam_nandcs_s *priv, bool nfcsram,
{
/* Check the data bus width of the NAND FLASH */
- buswidth = nandmodel_getbuswidth(&priv->raw.model);
if (buswidth == 16)
{
return nand_smc_write16(buffer, dest, buflen);
@@ -2611,16 +2685,18 @@ struct mtd_dev_s *sam_nand_initialize(int cs)
return NULL;
}
- /* Allocate a DMA channel for NAND transfers */
+ /* Allocate a DMA channel for NAND transfers. The channels will be
+ * configured as needed on-the-fly
+ */
#ifdef CONFIG_SAMA5_NAND_DMA
if (nandmodel_getbuswidth(&priv->raw.model) == 16)
{
- priv->dma = sam_dmachannel(NAND_DMAC, DMA_FLAGS16);
+ priv->dma = sam_dmachannel(NAND_DMAC, 0);
}
else
{
- priv->dma = sam_dmachannel(NAND_DMAC, DMA_FLAGS8);
+ priv->dma = sam_dmachannel(NAND_DMAC, 0);
}
if (!priv->dma)
diff --git a/nuttx/configs/sama5d3x-ek/README.txt b/nuttx/configs/sama5d3x-ek/README.txt
index 8c5516cb1..62d55d067 100644
--- a/nuttx/configs/sama5d3x-ek/README.txt
+++ b/nuttx/configs/sama5d3x-ek/README.txt
@@ -76,6 +76,8 @@ Contents
- Serial FLASH
- HSMCI Card Slots
- USB Ports
+ - SDRAM Support
+ - NAND Support
- AT24 Serial EEPROM
- CAN Usage
- SAMA5 ADC Support
@@ -640,6 +642,28 @@ USB Ports
---- ----------- -------------------------------------------------------
PD28 OVCUR_USB Combined overrcurrent indication from port A and B
+SDRAM Support
+=============
+ In these configurations, .data and .bss are retained in ISRAM. SDRAM can
+ be initialized and included in the heap. Relevant configuration settings:
+
+ System Type->ATSAMA5 Peripheral Support
+ CONFIG_SAMA5_MPDDRC=y : Enable the DDR controller
+
+ System Type->External Memory Configuration
+ CONFIG_SAMA5_DDRCS=y : Tell the system that DRAM is at the DDR CS
+ CONFIG_SAMA5_DDRCS_SIZE=268435456 : 2Gb DRAM -> 256GB
+ CONFIG_SAMA5_DDRCS_LPDDR2=y : Its DDR2
+ CONFIG_SAMA5_MT47H128M16RT=y : This is the type of DDR2
+
+ System Type->Heap Configuration
+ CONFIG_SAMA5_DDRCS_HEAP=y : Add the SDRAM to the heap
+ CONFIG_SAMA5_DDRCS_HEAP_OFFSET=0
+ CONFIG_SAMA5_DDRCS_HEAP_SIZE=268435456
+
+ Memory Management
+ CONFIG_MM_REGIONS=2 : Two heap memory regions: ISRAM and SDRAM
+
NAND Support
============
NAND Support can be added to the the NSH configuration by modifying the
@@ -670,7 +694,11 @@ NAND Support
File Systems:
CONFIG_FS_NXFFS=y : Enable the NXFFS file system
- Defaults for all other NXFFS settings should be okay
+ Defaults for all other NXFFS settings should be okay.
+
+ NOTE: NXFFS will require some significant buffering because of
+ the large size of the NAND flash blocks. You will also need
+ to enable SDRAM as described above.
Board Selection
CONFIG_SAMA5_NAND_AUTOMOUNT=y : Enable FS support on NAND