SAMA5D4: Add configuration to redirect all interrupts to the AIC

This commit is contained in:
Gregory Nutt
2014-06-26 11:51:39 -06:00
parent fd7b06c68e
commit 6a451baa51
3 changed files with 70 additions and 11 deletions
+6 -1
View File
@@ -80,7 +80,6 @@ config SAMA5_HAVE_HSMCI2
config SAMA5_HAVE_SAIC
bool
default n
select ARMV7A_DECODEFIQ
config SAMA5_HAVE_SBM
bool
@@ -276,6 +275,12 @@ config SAMA5_SMD
bool "SMD Soft Modem (SMD)"
default n
config SAMA5_SAIC
bool "Secure Advanced Interrupt Controller (SAIC)"
default n
depends on SAMA5_HAVE_SAIC
select ARMV7A_DECODEFIQ
config SAMA5_UART0
bool "UART 0"
default y
+11 -2
View File
@@ -69,6 +69,7 @@
#ifdef ATSAMA5D4
# define SAM_SFR_SN0_OFFSET 0x004c /* Serial Number 0 Register */
# define SAM_SFR_SN1_OFFSET 0x0050 /* Serial Number 1 Register */
# define SAM_SFR_AICREDIR_OFFSET 0x0054 /* AIC Redirection Register */
#endif
/* SFR Register Addresses ***********************************************************/
@@ -88,8 +89,9 @@
#define SAM_SFR_EBICFG (SAM_SFR_VBASE+SAM_SFR_EBICFG_OFFSET)
#ifdef ATSAMA5D4
# define SAM_SFR_SN0 (SAM_SFR_VBASE+SAM_SFR_SN0_OFFSET)
# define SAM_SFR_SN1 (SAM_SFR_VBASE+SAM_SFR_SN1_OFFSET)
# define SAM_SFR_SN0 (SAM_SFR_VBASE+SAM_SFR_SN0_OFFSET)
# define SAM_SFR_SN1 (SAM_SFR_VBASE+SAM_SFR_SN1_OFFSET)
# define SAM_SFR_AICREDIR (SAM_SFR_VBASE+SAM_SFR_AICREDIR_OFFSET)
#endif
/* SFR Register Bit Definitions *****************************************************/
@@ -215,6 +217,13 @@
#ifdef ATSAMA5D4
/* Serial Number 0 Register (32-bit value) */
/* Serial Number 1 Register (32-bit value) */
/* AIC Redirection Register */
# define SFR_AICREDIR_ENABLE (1 << 0) /* Bit 0: 1=All interrupts to AIC */
# define SFR_AICREDIR_DISABLE (0) /* Bit 0: 0=Secure interrupts to SAIC */
# define SFR_AICREDIR_KEY (0x5f67b102) /* Bits 1-31: Access key */
#endif
#endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SFR_H */
+53 -8
View File
@@ -61,6 +61,7 @@
#include "chip/sam_aic.h"
#include "chip/sam_matrix.h"
#include "chip/sam_aximx.h"
#include "chip/sam_sfr.h"
#include "sam_irq.h"
@@ -100,7 +101,7 @@ static const uint8_t g_srctype[SCRTYPE_NTYPES] =
* peripheral interrupts are secured or not.
*/
#if defined(CONFIG_SAMA5_HAVE_SAIC)
#if defined(CONFIG_SAMA5_SAIC)
static const uint32_t g_h64mxpids[3] =
{
H64MX_SPSELR0_PIDS, H64MX_SPSELR1_PIDS, H64MX_SPSELR2_PIDS
@@ -260,7 +261,7 @@ static uint32_t *sam_fiqhandler(int irq, uint32_t *regs)
*
****************************************************************************/
#if defined(CONFIG_SAMA5_HAVE_SAIC)
#if defined(CONFIG_SAMA5_SAIC)
static bool sam_aic_issecure(uint32_t irq)
{
uintptr_t regaddr;
@@ -294,6 +295,46 @@ static bool sam_aic_issecure(uint32_t irq)
}
#endif
/****************************************************************************
* Name: sam_aic_redirection
*
* Description:
* Redirect all interrupts to the AIC. This function is only compiled if
* (1) the architecture supports an SAIC (CONFIG_SAMA5_HAVE_SAIC), but (2)
* Use of the SAIC has not been selected (!CONFIG_SAMA5_SAIC).
*
****************************************************************************/
#if defined(CONFIG_SAMA5_HAVE_SAIC) && !defined(CONFIG_SAMA5_SAIC)
static void sam_aic_redirection(void)
{
unsigned int regval;
/* Check if interrupts are already redirected to the AIC */
regval = getreg32(SAM_SFR_AICREDIR);
if ((regval & SFR_AICREDIR_ENABLE) == 0)
{
/* Enable redirection of all interrupts to the AIC */
regval = getreg32(SAM_SFR_SN1);
regval ^= SFR_AICREDIR_KEY;
regval |= SFR_AICREDIR_ENABLE;
putreg32(regval, SAM_SFR_AICREDIR);
#if defined(CONFIG_DEBUG_IRQ)
/* Check if redirection was successfully enabled */
regval = getreg32(SAM_SFR_AICREDIR);
lldbg("Interrupts %s redirected to the AIC\n",
(regval & SFR_AICREDIR_ENABLE) != 0 ? "ARE" : "NOT");
#endif
}
}
#else
# define sam_aic_redirection()
#endif
/****************************************************************************
* Name: sam_aic_initialize
*
@@ -395,11 +436,15 @@ void up_irqinitialize(void)
}
#endif
/* Redirect all interrupts to the AIC if so configured */
sam_aic_redirection();
/* Initialize the Advanced Interrupt Controller (AIC) */
sam_aic_initialize(SAM_AIC_VBASE);
#if defined(CONFIG_SAMA5_HAVE_SAIC)
#if defined(CONFIG_SAMA5_SAIC)
/* Initialize the Secure Advanced Interrupt Controller (SAIC) */
sam_aic_initialize(SAM_SAIC_VBASE);
@@ -602,7 +647,7 @@ uint32_t *arm_decodeirq(uint32_t *regs)
return sam_decodeirq(SAM_AIC_VBASE, regs);
}
#if defined(CONFIG_SAMA5_HAVE_SAIC)
#if defined(CONFIG_SAMA5_SAIC)
/* This is the entry point from the ARM FIQ vector handler */
uint32_t *arm_decodefiq(FAR uint32_t *regs)
@@ -674,7 +719,7 @@ static void sam_disable_irq(uintptr_t base, int irq)
void up_disable_irq(int irq)
{
#if defined(CONFIG_SAMA5_HAVE_SAIC)
#if defined(CONFIG_SAMA5_SAIC)
if (sam_aic_issecure(irq))
{
sam_disable_irq(SAM_SAIC_VBASE, irq);
@@ -726,7 +771,7 @@ static void sam_enable_irq(uintptr_t base, int irq)
void up_enable_irq(int irq)
{
#if defined(CONFIG_SAMA5_HAVE_SAIC)
#if defined(CONFIG_SAMA5_SAIC)
if (sam_aic_issecure(irq))
{
sam_enable_irq(SAM_SAIC_VBASE, irq);
@@ -802,7 +847,7 @@ static int sam_prioritize_irq(uint32_t base, int irq, int priority)
int up_prioritize_irq(int irq, int priority)
{
#if defined(CONFIG_SAMA5_HAVE_SAIC)
#if defined(CONFIG_SAMA5_SAIC)
if (sam_aic_issecure(irq))
{
sam_prioritize_irq(SAM_SAIC_VBASE, irq, priority);
@@ -860,7 +905,7 @@ static void _sam_irq_srctype(uintptr_t base, int irq,
void sam_irq_srctype(int irq, enum sam_srctype_e srctype)
{
#if defined(CONFIG_SAMA5_HAVE_SAIC)
#if defined(CONFIG_SAMA5_SAIC)
if (sam_aic_issecure(irq))
{
_sam_irq_srctype(SAM_SAIC_VBASE, irq, srctype);