SAMA5 PIO: Add support for secure interrupts; Fix PIO debug output

This commit is contained in:
Gregory Nutt 2014-06-29 17:46:55 -06:00
parent e681a582a7
commit ce710bb94a
3 changed files with 103 additions and 36 deletions

View File

@ -137,7 +137,7 @@ static inline int sam_piopin(pio_pinset_t cfgset)
static inline int sam_configinput(uintptr_t base, uint32_t pin,
pio_pinset_t cfgset)
{
#if defined(PIO_HAVE_SCHMITT) || defined(PIO_HAVE_DRIVE)
#if defined(PIO_HAVE_SCHMITT) || defined(PIO_HAVE_DRIVE) || defined(SAM_PIO_ISLR_OFFSET)
uint32_t regval;
#endif
#if defined(PIO_HAVE_DRIVE)
@ -151,6 +151,14 @@ static inline int sam_configinput(uintptr_t base, uint32_t pin,
putreg32(pin, base + SAM_PIO_IDR_OFFSET);
#if defined(SAM_PIO_ISLR_OFFSET)
/* Assume unsecure */
regval = getreg32(base + SAM_PIO_ISLR_OFFSET);
regval |= pin;
putreg32(regval, base + SAM_PIO_ISLR_OFFSET);
#endif
/* Enable/disable the pull-up as requested */
if ((cfgset & PIO_CFG_PULLUP) != 0)
@ -248,10 +256,22 @@ static inline int sam_configinput(uintptr_t base, uint32_t pin,
static inline int sam_configoutput(uintptr_t base, uint32_t pin,
pio_pinset_t cfgset)
{
#if defined(SAM_PIO_ISLR_OFFSET)
uint32_t regval;
#endif
/* Disable interrupts on the pin */
putreg32(pin, base + SAM_PIO_IDR_OFFSET);
#if defined(SAM_PIO_ISLR_OFFSET)
/* Assume unsecure */
regval = getreg32(base + SAM_PIO_ISLR_OFFSET);
regval |= pin;
putreg32(regval, base + SAM_PIO_ISLR_OFFSET);
#endif
/* Enable/disable the pull-up as requested */
if ((cfgset & PIO_CFG_PULLUP) != 0)
@ -323,6 +343,14 @@ static inline int sam_configperiph(uintptr_t base, uint32_t pin,
putreg32(pin, base + SAM_PIO_IDR_OFFSET);
#if defined(SAM_PIO_ISLR_OFFSET)
/* Assume unsecure */
regval = getreg32(base + SAM_PIO_ISLR_OFFSET);
regval |= pin;
putreg32(regval, base + SAM_PIO_ISLR_OFFSET);
#endif
/* Enable/disable the pull-up as requested */
if ((cfgset & PIO_CFG_PULLUP) != 0)
@ -548,45 +576,53 @@ int sam_dumppio(uint32_t pinset, const char *msg)
{
irqstate_t flags;
uintptr_t base;
unsigned int pin;
unsigned int port;
/* Get the base address associated with the PIO port */
pin = sam_piopin(pinset);
port = (pinset & PIO_PORT_MASK) >> PIO_PORT_SHIFT;
base = SAM_PION_BASE(port);
base = SAM_PION_VBASE(port);
/* The following requires exclusive access to the PIO registers */
flags = irqsave();
lldbg("PIO%c pinset: %08x base: %08x -- %s\n",
g_portchar[port], pinset, base, msg);
lldbg(" PSR: %08x OSR: %08x IFSR: %08x ODSR: %08x\n",
#ifdef SAM_PIO_ISLR_OFFSET
lldbg(" PSR: %08x ISLR: %08x OSR: %08x IFSR: %08x\n",
getreg32(base + SAM_PIO_PSR_OFFSET), getreg32(base + SAM_PIO_ISLR_OFFSET),
getreg32(base + SAM_PIO_OSR_OFFSET), getreg32(base + SAM_PIO_IFSR_OFFSET));
#else
lldbg(" PSR: %08x OSR: %08x IFSR: %08x\n",
getreg32(base + SAM_PIO_PSR_OFFSET), getreg32(base + SAM_PIO_OSR_OFFSET),
getreg32(base + SAM_PIO_IFSR_OFFSET), getreg32(base + SAM_PIO_ODSR_OFFSET));
lldbg(" PDSR: %08x IMR: %08x ISR: %08x MDSR: %08x\n",
getreg32(base + SAM_PIO_PDSR_OFFSET), getreg32(base + SAM_PIO_IMR_OFFSET),
getreg32(base + SAM_PIO_ISR_OFFSET), getreg32(base + SAM_PIO_MDSR_OFFSET));
lldbg(" ABCDSR: %08x %08x IFSCSR: %08x PPDSR: %08x\n",
getreg32(base + SAM_PIO_ABCDSR1_OFFSET), getreg32(base + SAM_PIO_ABCDSR2_OFFSET),
getreg32(base + SAM_PIO_IFSCSR_OFFSET), getreg32(base + SAM_PIOC_PPDSR));
lldbg(" PUSR: %08x SCDR: %08x OWSR: %08x AIMMR: %08x\n",
getreg32(base + SAM_PIO_PUSR_OFFSET), getreg32(base + SAM_PIO_SCDR_OFFSET),
getreg32(base + SAM_PIO_OWSR_OFFSET), getreg32(base + SAM_PIO_AIMMR_OFFSET));
lldbg(" ESR: %08x LSR: %08x ELSR: %08x FELLSR: %08x\n",
getreg32(base + SAM_PIO_ESR_OFFSET), getreg32(base + SAM_PIO_LSR_OFFSET),
getreg32(base + SAM_PIO_ELSR_OFFSET), getreg32(base + SAM_PIO_FELLSR_OFFSET));
lldbg(" FRLHSR: %08x LOCKSR: %08x WPMR: %08x WPSR: %08x\n",
getreg32(base + SAM_PIO_FRLHSR_OFFSET), getreg32(base + SAM_PIO_LOCKSR_OFFSET),
getreg32(base + SAM_PIO_IFSR_OFFSET));
#endif
lldbg(" ODSR: %08x PDSR: %08x IMR: %08x ISR: %08x\n",
getreg32(base + SAM_PIO_ODSR_OFFSET), getreg32(base + SAM_PIO_PDSR_OFFSET),
getreg32(base + SAM_PIO_IMR_OFFSET), getreg32(base + SAM_PIO_ISR_OFFSET));
lldbg(" MDSR: %08x PUSR: %08x ABDCSR: %08x %08x\n",
getreg32(base + SAM_PIO_MDSR_OFFSET), getreg32(base + SAM_PIO_PUSR_OFFSET),
getreg32(base + SAM_PIO_ABCDSR1_OFFSET), getreg32(base + SAM_PIO_ABCDSR2_OFFSET));
lldbg(" IFSCSR: %08x SCDR: %08x PPDSR: %08x OWSR: %08x\n",
getreg32(base + SAM_PIO_IFSCSR_OFFSET), getreg32(base + SAM_PIO_SCDR_OFFSET),
getreg32(base + SAM_PIO_PPDSR_OFFSET), getreg32(base + SAM_PIO_OWSR_OFFSET));
#ifdef SAM_PIO_LOCKSR_OFFSET
lldbg(" AIMMR: %08x ELSR: %08x FRLHSR: %08x LOCKSR: %08x\n",
getreg32(base + SAM_PIO_AIMMR_OFFSET), getreg32(base + SAM_PIO_ELSR_OFFSET),
getreg32(base + SAM_PIO_FRLHSR_OFFSET), getreg32(base + SAM_PIO_LOCKSR_OFFSET));
#else
lldbg(" AIMMR: %08x ELSR: %08x FRLHSR: %08x\n",
getreg32(base + SAM_PIO_AIMMR_OFFSET), getreg32(base + SAM_PIO_ELSR_OFFSET),
getreg32(base + SAM_PIO_FRLHSR_OFFSET));
#endif
lldbg("SCHMITT: %08x DRIVER: %08x %08x\n",
getreg32(base + SAM_PIO_SCHMITT_OFFSET), getreg32(base + SAM_PIO_DRIVER1_OFFSET),
getreg32(base + SAM_PIO_DRIVER2_OFFSET));
lldbg(" WPMR: %08x WPSR: %08x\n",
getreg32(base + SAM_PIO_WPMR_OFFSET), getreg32(base + SAM_PIO_WPSR_OFFSET));
lldbg(" PCMR: %08x PCIMR: %08x PCISR: %08x PCRHR: %08x\n",
getreg32(base + SAM_PIO_PCMR_OFFSET), getreg32(base + SAM_PIO_PCIMR_OFFSET),
getreg32(base + SAM_PIO_PCISR_OFFSET), getreg32(base + SAM_PIO_PCRHR_OFFSET));
lldbg("SCHMITT: %08x\n",
getreg32(base + SAM_PIO_SCHMITT_OFFSET));
irqrestore(flags);
return OK;
}
#endif

View File

@ -73,15 +73,15 @@
/* 32-bit Encoding:
*
* .... .... ..MM MCCC CCDD IIIV PPPB BBBB
* .... .... .MMM CCCC CDDI IISV PPPB BBBB
*/
/* Input/Output mode:
*
* .... .... ..MM M... .... .... .... ....
* .... .... .MMM .... .... .... .... ....
*/
#define PIO_MODE_SHIFT (19) /* Bits 19-21: PIO mode */
#define PIO_MODE_SHIFT (20) /* Bits 20-22: PIO mode */
#define PIO_MODE_MASK (7 << PIO_MODE_SHIFT)
# define PIO_INPUT (0 << PIO_MODE_SHIFT) /* Input */
# define PIO_OUTPUT (1 << PIO_MODE_SHIFT) /* Output */
@ -93,10 +93,10 @@
/* These bits set the configuration of the pin:
* NOTE: No definitions for parallel capture mode
*
* .... .... .... .CCC CC.. .... .... ....
* .... .... .... CCCC C... .... .... ....
*/
#define PIO_CFG_SHIFT (14) /* Bits 14-18: PIO configuration bits */
#define PIO_CFG_SHIFT (15) /* Bits 15-19: PIO configuration bits */
#define PIO_CFG_MASK (31 << PIO_CFG_SHIFT)
# define PIO_CFG_DEFAULT (0 << PIO_CFG_SHIFT) /* Default, no attribute */
# define PIO_CFG_PULLUP (1 << PIO_CFG_SHIFT) /* Bit 11: Internal pull-up */
@ -107,10 +107,10 @@
/* Drive Strength:
*
* .... .... .... .... ..DD .... .... ....
* .... .... .... .... .DD. .... .... ....
*/
#define PIO_DRIVE_SHIFT (12) /* Bits 12-13: Drive strength */
#define PIO_DRIVE_SHIFT (13) /* Bits 13-14: Drive strength */
#define PIO_DRIVE_MASK (7 << PIO_DRIVE_SHIFT)
# define PIO_DRIVE_LOW (0 << PIO_DRIVE_SHIFT)
# define PIO_DRIVE_MEDIUM (2 << PIO_DRIVE_SHIFT)
@ -118,10 +118,10 @@
/* Additional interrupt modes:
*
* .... .... .... .... .... III. .... ....
* .... .... .... .... ...I II.. .... ....
*/
#define PIO_INT_SHIFT (9) /* Bits 9-11: PIO interrupt bits */
#define PIO_INT_SHIFT (10) /* Bits 9-12: PIO interrupt bits */
#define PIO_INT_MASK (7 << PIO_INT_SHIFT)
# define _PIO_INT_AIM (1 << 10) /* Bit 10: Additional Interrupt modes */
# define _PIO_INT_LEVEL (1 << 9) /* Bit 9: Level detection interrupt */
@ -135,12 +135,24 @@
# define PIO_INT_FALLING (_PIO_INT_AIM | _PIO_INT_EDGE | _PIO_INT_FL)
# define PIO_INT_BOTHEDGES (0)
/* If the pin is an interrupt, then this determines if the pin is a secure interrupt:
*
* .... .... .... .... .... ..S. .... ....
*/
#ifdef SAMA5_SAIC
# define PIO_INT_SECURE (1 << 9) /* Bit 9: Secure interrupt */
#else
# define PIO_INT_SECURE (0)
#endif
#define PIO_INT_UNSECURE (0)
/* If the pin is an PIO output, then this identifies the initial output value:
*
* .... .... .... .... .... ...V .... ....
*/
#define PIO_OUTPUT_SET (1 << 8) /* Bit 8: Inital value of output */
#define PIO_OUTPUT_SET (1 << 8) /* Bit 8: Initial value of output */
#define PIO_OUTPUT_CLEAR (0)
/* This identifies the PIO port:

View File

@ -378,6 +378,21 @@ void sam_pioirq(pio_pinset_t pinset)
uint32_t base = sam_piobase(pinset);
int pin = sam_piopin(pinset);
/* Enable writing to PIO registers */
putreg32(PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET);
#if defined(SAMA5_SAIC) && defined(SAM_PIO_ISLR_OFFSET)
/* Is the interrupt secure? */
if ((pinset & PIO_INT_SECURE) != 0)
{
uint32_t regval = getreg32(base + SAM_PIO_ISLR_OFFSET);
regval &= ~pin;
putreg32(regval, base + SAM_PIO_ISLR_OFFSET);
}
#endif
/* Are any additional interrupt modes selected? */
if ((pinset & _PIO_INT_AIM) != 0)
@ -414,6 +429,10 @@ void sam_pioirq(pio_pinset_t pinset)
putreg32(pin, base + SAM_PIO_AIMDR_OFFSET);
}
/* Disable writing to PIO registers */
putreg32(PIO_WPMR_WPEN | PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET);
}
/************************************************************************************