summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-08-09 17:25:53 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-08-09 17:25:53 -0600
commit408ca2c492a6af15c362a5b1e38641d835730cd0 (patch)
treed93a21d2bc2b4c3af918da1be51d7617bb0b2cd5
parent975903dcb001c7fc4f904732c47000e8f5b6794a (diff)
downloadnuttx-408ca2c492a6af15c362a5b1e38641d835730cd0.tar.gz
nuttx-408ca2c492a6af15c362a5b1e38641d835730cd0.tar.bz2
nuttx-408ca2c492a6af15c362a5b1e38641d835730cd0.zip
SAMA5: Centralize logic for conversion between physical and virtual addresses
-rw-r--r--nuttx/ChangeLog2
-rw-r--r--nuttx/arch/arm/src/sama5/Make.defs4
-rw-r--r--nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h16
-rw-r--r--nuttx/arch/arm/src/sama5/sam_hsmci.c83
-rw-r--r--nuttx/arch/arm/src/sama5/sam_memories.c289
-rw-r--r--nuttx/arch/arm/src/sama5/sam_memories.h104
-rw-r--r--nuttx/arch/arm/src/sama5/sam_spi.c53
7 files changed, 439 insertions, 112 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 599fedf71..fd40029e7 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -5330,4 +5330,6 @@
* arch/arm/src/sama5/sam_dmac.c: Finally after many bugfixes (the
last being caching issues), the SAMA5 DMA support has been
verified (with SPI) (2013-8-9).
+ * arch/arm/src/sama5/sam_memories.c and .h: Central logic for
+ conversions between physical and virtual addresses (2013-8-9).
diff --git a/nuttx/arch/arm/src/sama5/Make.defs b/nuttx/arch/arm/src/sama5/Make.defs
index 8cfd15861..3b9762beb 100644
--- a/nuttx/arch/arm/src/sama5/Make.defs
+++ b/nuttx/arch/arm/src/sama5/Make.defs
@@ -89,8 +89,8 @@ CHIP_ASRCS =
# SAMA5-specific C source files
-CHIP_CSRCS = sam_allocateheap.c sam_boot.c sam_clockconfig.c sam_pio.c
-CHIP_CSRCS += sam_irq.c sam_lowputc.c sam_serial.c sam_timerisr.c
+CHIP_CSRCS = sam_allocateheap.c sam_boot.c sam_clockconfig.c sam_memories.c
+CHIP_CSRCS += sam_pio.c sam_irq.c sam_lowputc.c sam_serial.c sam_timerisr.c
# Configuration dependent C and assembly language files
diff --git a/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h b/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h
index b3ba2deff..a24f9d834 100644
--- a/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h
+++ b/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h
@@ -192,7 +192,7 @@
#define SAM_DAP_SIZE (1*1024*1024) /* 0x00900000-0x009fffff: DAP */
#define SAM_NFCCR_SIZE (256*1024*1024) /* 0x70000000-0x7fffffff: NFC Command Registers */
/* 0xf0000000-0xffffffff: Internal Peripherals */
-#define SAM_PERIPHA_SIZE (15*1024) /* 0xf0000000-0xf003bfff: Internal Peripherals */
+#define SAM_PERIPHA_SIZE (240*1024) /* 0xf0000000-0xf003bfff: Internal Peripherals */
#define SAM_PERIPHB_SIZE (272*1024) /* 0xf8000000-0xf8043fff: Internal Peripherals */
#define SAM_SYSC_SIZE (1*1024*1024) /* 0xfff00000-0x0ffffedf: Internal Peripherals */
@@ -312,16 +312,16 @@
#ifdef CONFIG_ARCH_LOWVECTORS
#define SAM_PERIPH_VSECTION 0xf0000000 /* 0xf0000000-0xffffffff: Internal Peripherals */
-# define SAM_PERIPHA_VSECTION 0xf0000000 /* 0xf0000000-0xffffffff: Internal Peripherals */
-# define SAM_PERIPHB_VSECTION 0xf8000000 /* 0xf8000000-0xffffbfff: Internal Peripherals B */
-# define SAM_SYSC_VSECTION 0xfff00000 /* 0xfff00000-0xffffffff: System Controller */
+# define SAM_PERIPHA_VSECTION 0xf0000000 /* 0xf0000000-0xf7ffffff: Internal Peripherals A */
+# define SAM_PERIPHB_VSECTION 0xf8000000 /* 0xf8000000-0xffefffff: Internal Peripherals B */
+# define SAM_SYSC_VSECTION 0xfff00000 /* 0xfff00000-0xffffbfff: System Controller */
# define SAM_SYSC_VADDR 0xffffc000 /* 0xffffc000-0xffffffff: System Controller */
#else
#define SAM_PERIPH_VSECTION 0xf0000000 /* 0xf0000000-0xffffffff: Internal Peripherals */
-# define SAM_PERIPHA_VSECTION 0xf1000000 /* 0xf0000000-0xffffffff: Internal Peripherals */
-# define SAM_PERIPHB_VSECTION 0xf2000000 /* 0xf8000000-0xffffbfff: Internal Peripherals B */
-# define SAM_SYSC_VSECTION 0xf300000 /* 0xfff00000-0xffffffff: System Controller */
-# define SAM_SYSC_VADDR 0xf30fc000 /* 0xffffc000-0xffffffff: System Controller */
+# define SAM_PERIPHA_VSECTION 0xf0000000 /* 0xf0000000-0xf00fffff: Internal Peripherals A */
+# define SAM_PERIPHB_VSECTION 0xf1000000 /* 0xf1000000-0xf10fffff: Internal Peripherals B */
+# define SAM_SYSC_VSECTION 0xf2000000 /* 0xf2000000-0xf20fffff: System Controller */
+# define SAM_SYSC_VADDR 0xf20fc000 /* 0xf20fc000-0xf20fffff: System Controller */
#endif
#endif
diff --git a/nuttx/arch/arm/src/sama5/sam_hsmci.c b/nuttx/arch/arm/src/sama5/sam_hsmci.c
index 5c34b047f..ad73e1434 100644
--- a/nuttx/arch/arm/src/sama5/sam_hsmci.c
+++ b/nuttx/arch/arm/src/sama5/sam_hsmci.c
@@ -62,8 +62,9 @@
#include "sam_pio.h"
#include "sam_dmac.h"
-#include "sam_hsmci.h"
#include "sam_periphclks.h"
+#include "sam_memories.h"
+#include "sam_hsmci.h"
#include "chip/sam_dmac.h"
#include "chip/sam_pmc.h"
#include "chip/sam_hsmci.h"
@@ -420,7 +421,8 @@ static void sam_cmddump(struct sam_dev_s *priv);
/* DMA Helpers **************************************************************/
static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result);
-static uint32_t sam_physregaddr(struct sam_dev_s *priv, unsigned int offset);
+static inline uintptr_t hsmci_physregaddr(struct sam_dev_s *priv,
+ unsigned int offset);
/* Data Transfer Helpers ****************************************************/
@@ -1074,66 +1076,17 @@ static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result)
}
/****************************************************************************
- * Name: sam_physregaddr
+ * Name: hsmci_physregaddr
*
* Description:
* Return the physical address of an HSMCI register
*
****************************************************************************/
-static uint32_t sam_physregaddr(struct sam_dev_s *priv, unsigned int offset)
+static inline uintptr_t hsmci_physregaddr(struct sam_dev_s *priv,
+ unsigned int offset)
{
- /* Get the offset into the 1MB section containing the HSMCI registers */
-
- uint32_t pbase = priv->base & 0x000fffff;
-
-#ifdef CONFIG_SAMA5_HSMCI0
- /* Add in the physical base for HSMCI0
- *
- * We only have to check if this is HSMCI0 if either HSMCI1 or HSMCI2 are
- * enabled.
- */
-
-#if defined(CONFIG_SAMA5_HSMCI1) || defined(CONFIG_SAMA5_HSMCI2)
- if (priv->hsmci == 0)
-#endif
- {
- pbase |= SAM_PERIPHA_PSECTION;
- }
-#if defined(CONFIG_SAMA5_HSMCI1) || defined(CONFIG_SAMA5_HSMCI2)
- else
-#endif
-#endif
-
-#ifdef CONFIG_SAMA5_HSMCI1
- /* Add in the physical base for HSMCI1
- *
- * We only have to check if this is HSCMCi1 if HSMCI2 is enabled.
- */
-
-#ifdef CONFIG_SAMA5_HSMCI2
- if (priv->hsmci == 1)
-#endif
- {
- pbase |= SAM_PERIPHB_PSECTION;
- }
-#ifdef CONFIG_SAMA5_HSMCI2
- else
-#endif
-#endif
-
- /* Add in the physical base for HSMCI2.
- *
- * If we get here, we con't have to check.
- */
-
-#ifdef CONFIG_SAMA5_HSMCI2
- {
- pbase |= SAM_PERIPHB_PSECTION;
- }
-#endif
-
- return pbase + offset;
+ return sam_physregaddr(priv->base + offset);
}
/****************************************************************************
@@ -2505,14 +2458,18 @@ static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
size_t buflen)
{
struct sam_dev_s *priv = (struct sam_dev_s *)dev;
- uint32_t rdr;
+ uint32_t paddr;
+ uint32_t maddr;
DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
DEBUGASSERT(((uint32_t)buffer & 3) == 0);
- /* Physical address of the HSCMI RDR registr */
+ /* Physical address of the HSCMI RDR register and of the buffer location
+ * in RAM.
+ */
- rdr = sam_physregaddr(priv, SAM_HSMCI_RDR_OFFSET);
+ paddr = hsmci_physregaddr(priv, SAM_HSMCI_RDR_OFFSET);
+ maddr = sam_physramaddr((uintptr_t)buffer);
/* Setup register sampling */
@@ -2522,7 +2479,7 @@ static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
/* Configure the RX DMA */
sam_enablexfrints(priv, HSMCI_DMARECV_INTS);
- sam_dmarxsetup(priv->dma, rdr, (uint32_t)buffer, buflen);
+ sam_dmarxsetup(priv->dma, paddr, maddr, buflen);
/* Enable DMA handshaking */
@@ -2559,14 +2516,16 @@ static int sam_dmasendsetup(FAR struct sdio_dev_s *dev,
FAR const uint8_t *buffer, size_t buflen)
{
struct sam_dev_s *priv = (struct sam_dev_s *)dev;
- uint32_t tdr;
+ uint32_t paddr;
+ uint32_t maddr;
DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
DEBUGASSERT(((uint32_t)buffer & 3) == 0);
/* Physical address of the HSCMI TDR registr */
- tdr = sam_physregaddr(priv, SAM_HSMCI_TDR_OFFSET);
+ paddr = hsmci_physregaddr(priv, SAM_HSMCI_TDR_OFFSET);
+ maddr = sam_physramaddr((uintptr_t)buffer);
/* Setup register sampling */
@@ -2575,7 +2534,7 @@ static int sam_dmasendsetup(FAR struct sdio_dev_s *dev,
/* Configure the TX DMA */
- sam_dmatxsetup(priv->dma, tdr, (uint32_t)buffer, buflen);
+ sam_dmatxsetup(priv->dma, paddr, maddr, buflen);
/* Enable DMA handshaking */
diff --git a/nuttx/arch/arm/src/sama5/sam_memories.c b/nuttx/arch/arm/src/sama5/sam_memories.c
new file mode 100644
index 000000000..a8df6f93f
--- /dev/null
+++ b/nuttx/arch/arm/src/sama5/sam_memories.c
@@ -0,0 +1,289 @@
+/****************************************************************************
+ * arch/arm/src/sama5/sam_memories.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include "chip.h"
+#include "sam_memories.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: peripha_physregaddr
+ *
+ * Description:
+ * Give the virtual address of a peripheral A register, return the
+ * physical address of the register
+ *
+ ****************************************************************************/
+
+static uintptr_t peripha_physregaddr(uintptr_t vregaddr)
+{
+#if SAM_PERIPHA_PSECTION != SAM_PERIPHA_VSECTION
+
+ /* Get the offset into the 1MB section containing the register */
+
+ uintptr_t sectoffset = vregaddr & 0x000fffff;
+
+ /* Return that offset into the virtual peripheral A base address */
+
+ return SAM_PERIPHA_PSECTION | sectoffset;
+
+#else
+ /* 1-to-1 mapping */
+
+ return vregaddr;
+
+#endif
+}
+
+/****************************************************************************
+ * Name: periphb_physregaddr
+ *
+ * Description:
+ * Give the virtual address of a peripheral B register, return the
+ * physical address of the register
+ *
+ ****************************************************************************/
+
+static uintptr_t periphb_physregaddr(uintptr_t vregaddr)
+{
+#if SAM_PERIPHB_PSECTION != SAM_PERIPHB_VSECTION
+
+ /* Get the offset into the 1MB section containing the register */
+
+ uintptr_t sectoffset = vregaddr & 0x000fffff;
+
+ /* Return that offset into the virtual peripheral A base address */
+
+ return SAM_PERIPHB_PSECTION | sectoffset;
+
+#else
+ /* 1-to-1 mapping */
+
+ return vregaddr;
+
+#endif
+}
+
+/****************************************************************************
+ * Name: sysc_physregaddr
+ *
+ * Description:
+ * Give the virtual address of a system controller register, return the
+ * physical address of the register
+ *
+ ****************************************************************************/
+
+static uintptr_t sysc_physregaddr(uintptr_t vregaddr)
+{
+#if SAM_SYSC_PSECTION != SAM_SYSC_VSECTION
+
+ /* Get the offset into the 1MB section containing the register */
+
+ uintptr_t sectoffset = vregaddr & 0x000fffff;
+
+ /* Return that offset into the virtual peripheral A base address */
+
+ return SAM_SYSC_PSECTION | sectoffset;
+
+#else
+ /* 1-to-1 mapping */
+
+ return vregaddr;
+
+#endif
+}
+
+/****************************************************************************
+ * Name: isram_physregaddr
+ *
+ * Description:
+ * Give the virtual address of an internal SRAM memory location, return the
+ * physical address of that location
+ *
+ ****************************************************************************/
+
+static uintptr_t isram_physregaddr(uintptr_t vregaddr)
+{
+#if SAM_ISRAM_PSECTION != SAM_ISRAM_VSECTION
+
+ /* Get the offset into the 1MB section containing the register */
+
+ uintptr_t sectoffset = vregaddr & 0x000fffff;
+
+ /* Return that offset into the virtual peripheral A base address */
+
+ return SAM_ISRAM_PSECTION | sectoffset;
+
+#else
+ /* 1-to-1 mapping */
+
+ return vregaddr;
+
+#endif
+}
+
+/****************************************************************************
+ * Name: sdram_physregaddr
+ *
+ * Description:
+ * Give the virtual address of an external SDRAM memory location, return
+ * the physical address of that location
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SAMA5_DDRCS
+static uintptr_t sdram_physregaddr(uintptr_t vregaddr)
+{
+#if SAM_DDRCS_PSECTION != SAM_DDRCS_VSECTION
+
+ /* Get the offset into the 1MB section containing the register */
+
+ uintptr_t sectoffset = vregaddr & 0x000fffff;
+
+ /* Return that offset into the virtual peripheral A base address */
+
+ return SAM_DDRCS_PSECTION | sectoffset;
+
+#else
+ /* 1-to-1 mapping */
+
+ return vregaddr;
+
+#endif
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam_physregaddr
+ *
+ * Description:
+ * Give the virtual address of a register, return the physical address of
+ * the register
+ *
+ ****************************************************************************/
+
+uintptr_t sam_physregaddr(uintptr_t vregaddr)
+{
+ /* Check for a peripheral A register */
+
+ if (vregaddr >= SAM_PERIPHA_VSECTION &&
+ vregaddr < (SAM_PERIPHA_VSECTION + SAM_PERIPHA_SIZE))
+ {
+ return peripha_physregaddr(vregaddr);
+ }
+
+ /* Check for a peripheral A register */
+
+ else if (vregaddr >= SAM_PERIPHB_VSECTION &&
+ vregaddr < (SAM_PERIPHB_VSECTION + SAM_PERIPHB_SIZE))
+ {
+ return periphb_physregaddr(vregaddr);
+ }
+
+ /* Check for a system controller register */
+
+ else if (vregaddr >= SAM_SYSC_VSECTION &&
+ vregaddr < (SAM_SYSC_VSECTION + SAM_SYSC_SIZE))
+ {
+ return sysc_physregaddr(vregaddr);
+ }
+
+ /* We will not get here unless we are called with an invalid register
+ * address
+ */
+
+ DEBUGPANIC();
+ return vregaddr;
+}
+
+/****************************************************************************
+ * Name: sam_physramaddr
+ *
+ * Description:
+ * Give the virtual address of a RAM memory location, return the physical
+ * address of that location.
+ *
+ ****************************************************************************/
+
+uintptr_t sam_physramaddr(uintptr_t vregaddr)
+{
+ /* Check for internal SRAM. We we assume that ISRAM0 and ISRAM1 are
+ * contiguous.
+ */
+
+ if (vregaddr >= SAM_ISRAM_VSECTION &&
+ vregaddr < (SAM_ISRAM_VSECTION + SAM_ISRAM_SIZE))
+ {
+ return isram_physregaddr(vregaddr);
+ }
+
+#ifdef CONFIG_SAMA5_DDRCS
+ /* Check for external SDRAM */
+
+ else if (vregaddr >= SAM_DDRCS_VSECTION &&
+ vregaddr < (SAM_DDRCS_VSECTION + SAMA5_DDRCS_SIZE))
+ {
+ return sdram_physregaddr(vregaddr);
+ }
+#endif
+
+ /* We will not get here unless we are called with an invalid or
+ * unsupported RAM address
+ */
+
+ DEBUGPANIC();
+ return vregaddr;
+}
+
diff --git a/nuttx/arch/arm/src/sama5/sam_memories.h b/nuttx/arch/arm/src/sama5/sam_memories.h
new file mode 100644
index 000000000..e360759d2
--- /dev/null
+++ b/nuttx/arch/arm/src/sama5/sam_memories.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+ * arch/arm/src/sama5/sam_memories.h
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_SAMA5_SAM_MEMORIES_H
+#define __ARCH_ARM_SRC_SAMA5_SAM_MEMORIES_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Inline Functions
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam_physregaddr
+ *
+ * Description:
+ * Give the virtual address of a register, return the physical address of
+ * the register
+ *
+ ****************************************************************************/
+
+uintptr_t sam_physregaddr(uintptr_t vregaddr);
+
+/****************************************************************************
+ * Name: sam_physramaddr
+ *
+ * Description:
+ * Give the virtual address of a RAM memory location, return the physical
+ * address of that location.
+ *
+ ****************************************************************************/
+
+uintptr_t sam_physramaddr(uintptr_t vregaddr);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_SAMA5_SAM_MEMORIES_H */
diff --git a/nuttx/arch/arm/src/sama5/sam_spi.c b/nuttx/arch/arm/src/sama5/sam_spi.c
index fefb349dd..df32defae 100644
--- a/nuttx/arch/arm/src/sama5/sam_spi.c
+++ b/nuttx/arch/arm/src/sama5/sam_spi.c
@@ -66,8 +66,9 @@
#include "chip.h"
#include "sam_pio.h"
#include "sam_dmac.h"
-#include "sam_spi.h"
+#include "sam_memories.h"
#include "sam_periphclks.h"
+#include "sam_spi.h"
#include "chip/sam_pmc.h"
#include "chip/sam_spi.h"
#include "chip/sam_pinmap.h"
@@ -272,7 +273,7 @@ static void spi_dma_sampledone(struct sam_spics_s *spics);
static void spi_rxcallback(DMA_HANDLE handle, void *arg, int result);
static void spi_txcallback(DMA_HANDLE handle, void *arg, int result);
-static uint32_t spi_physregaddr(struct sam_spics_s *spics,
+static inline uintptr_t spi_physregaddr(struct sam_spics_s *spics,
unsigned int offset);
#endif
@@ -849,44 +850,11 @@ static void spi_txcallback(DMA_HANDLE handle, void *arg, int result)
****************************************************************************/
#ifdef CONFIG_SAMA5_SPI_DMA
-static uint32_t spi_physregaddr(struct sam_spics_s *spics,
- unsigned int offset)
+static inline uintptr_t spi_physregaddr(struct sam_spics_s *spics,
+ unsigned int offset)
{
struct sam_spidev_s *spi = spi_device(spics);
-
- /* Get the offset into the 1MB section containing the SPI registers */
-
- uint32_t pbase = spi->base & 0x000fffff;
-
-#ifdef CONFIG_SAMA5_SPI0
- /* Add in the physical base for SPI0
- *
- * We only have to check if this is SPI0 if SPI1 is enabled.
- */
-
-#if defined(CONFIG_SAMA5_SPI1)
- if (spics->spino == 0)
-#endif
- {
- pbase |= SAM_PERIPHA_PSECTION;
- }
-#if defined(CONFIG_SAMA5_SPI1)
- else
-#endif
-#endif
-
-#ifdef CONFIG_SAMA5_SPI1
- /* Add in the physical base for SPI1
- *
- * If we get here, we con't have to check anything.
- */
-
- {
- pbase |= SAM_PERIPHB_PSECTION;
- }
-#endif
-
- return pbase + offset;
+ return sam_physregaddr(spi->base + offset);
}
#endif
@@ -1425,6 +1393,7 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
uint32_t txdummy;
uint32_t rxdummy;
uint32_t paddr;
+ uint32_t maddr;
int ret;
/* If we cannot do DMA -OR- if this is a small SPI transfer, then let
@@ -1522,7 +1491,9 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
/* Configure the exchange transfers */
paddr = spi_physregaddr(spics, SAM_SPI_RDR_OFFSET);
- ret = sam_dmarxsetup(spics->rxdma, paddr, (uint32_t)rxbuffer, nwords);
+ maddr = sam_physramaddr((uintptr_t)rxbuffer);
+
+ ret = sam_dmarxsetup(spics->rxdma, paddr, maddr, nwords);
if (ret < 0)
{
dmadbg("ERROR: sam_dmarxsetup failed: %d\n", ret);
@@ -1532,7 +1503,9 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
spi_rxdma_sample(spics, DMA_AFTER_SETUP);
paddr = spi_physregaddr(spics, SAM_SPI_TDR_OFFSET);
- ret = sam_dmatxsetup(spics->txdma, paddr, (uint32_t)txbuffer, nwords);
+ maddr = sam_physramaddr((uintptr_t)txbuffer);
+
+ ret = sam_dmatxsetup(spics->txdma, paddr, maddr, nwords);
if (ret < 0)
{
dmadbg("ERROR: sam_dmatxsetup failed: %d\n", ret);