SAMA5: Centralize logic for conversion between physical and virtual addresses
This commit is contained in:
parent
ad6b8726c2
commit
d8b3921972
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
289
arch/arm/src/sama5/sam_memories.c
Normal file
289
arch/arm/src/sama5/sam_memories.c
Normal file
@ -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;
|
||||
}
|
||||
|
104
arch/arm/src/sama5/sam_memories.h
Normal file
104
arch/arm/src/sama5/sam_memories.h
Normal file
@ -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 */
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user