From 408ca2c492a6af15c362a5b1e38641d835730cd0 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 9 Aug 2013 17:25:53 -0600 Subject: SAMA5: Centralize logic for conversion between physical and virtual addresses --- nuttx/ChangeLog | 2 + nuttx/arch/arm/src/sama5/Make.defs | 4 +- nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h | 16 +- nuttx/arch/arm/src/sama5/sam_hsmci.c | 83 ++---- nuttx/arch/arm/src/sama5/sam_memories.c | 289 +++++++++++++++++++++ nuttx/arch/arm/src/sama5/sam_memories.h | 104 ++++++++ nuttx/arch/arm/src/sama5/sam_spi.c | 53 +--- 7 files changed, 439 insertions(+), 112 deletions(-) create mode 100644 nuttx/arch/arm/src/sama5/sam_memories.c create mode 100644 nuttx/arch/arm/src/sama5/sam_memories.h (limited to 'nuttx') 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 + * + * 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 + +#include +#include +#include + +#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 + * + * 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 + +/**************************************************************************** + * 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); -- cgit v1.2.3