Cortex-A9 GIC: Add an interface to set interrupt edge/level trigger
This commit is contained in:
parent
4feeb0c2b4
commit
e6728bac29
@ -523,4 +523,56 @@ int up_prioritize_irq(int irq, int priority)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: arm_gic_irq_trigger
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set the trigger type for the specificd IRQ source and the current CPU.
|
||||||
|
*
|
||||||
|
* Since this API is not supported on all architectures, it should be
|
||||||
|
* avoided in common implementations where possible.
|
||||||
|
*
|
||||||
|
* Input Paramters:
|
||||||
|
* irq - The interrupt request to modify.
|
||||||
|
* edge - False: Active HIGH level sensitive, True: Rising edge sensitive
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on success; a negated errno value is returned on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int arm_gic_irq_trigger(int irq, bool edge)
|
||||||
|
{
|
||||||
|
uintptr_t regaddr;
|
||||||
|
uint32_t regval;
|
||||||
|
uint32_t intcfg;
|
||||||
|
|
||||||
|
if (irq > GIC_IRQ_SGI15 && irq < NR_IRQS)
|
||||||
|
{
|
||||||
|
/* Get the address of the Interrupt Configuration Register for this
|
||||||
|
* irq.
|
||||||
|
*/
|
||||||
|
|
||||||
|
regaddr = GIC_ICDICFR(irq);
|
||||||
|
|
||||||
|
/* Get the new Interrupt configuration bit setting */
|
||||||
|
|
||||||
|
intcfg = (edge ? (INT_ICDICFR_EDGE | INT_ICDICFR_1N) : INT_ICDICFR_1N);
|
||||||
|
|
||||||
|
/* Write the correct interrupt trigger to the Interrupt Configuration
|
||||||
|
* Register.
|
||||||
|
*/
|
||||||
|
|
||||||
|
regval = getreg32(regaddr);
|
||||||
|
regval &= ~GIC_ICDICFR_ID_MASK(irq);
|
||||||
|
regval |= GIC_ICDICFR_ID(irq, intcfg);
|
||||||
|
putreg32(regval, regaddr);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* CONFIG_ARMV7A_HAVE_GICv2 */
|
#endif /* CONFIG_ARMV7A_HAVE_GICv2 */
|
||||||
|
@ -495,7 +495,7 @@
|
|||||||
#define INT_ICDICFR_EDGE 2 /* Bit n+2: 1=Edge sensitive */
|
#define INT_ICDICFR_EDGE 2 /* Bit n+2: 1=Edge sensitive */
|
||||||
|
|
||||||
#define GIC_ICDICFR_ID_SHIFT(n) GIC_SHIFT16(n)
|
#define GIC_ICDICFR_ID_SHIFT(n) GIC_SHIFT16(n)
|
||||||
#define GIC_ICDICFR_ID_MASK(n) GIC_MASK16(n
|
#define GIC_ICDICFR_ID_MASK(n) GIC_MASK16(n)
|
||||||
# define GIC_ICDICFR_ID(n,c) ((uint32_t)(c) << GIC_SHIFT16(n))
|
# define GIC_ICDICFR_ID(n,c) ((uint32_t)(c) << GIC_SHIFT16(n))
|
||||||
|
|
||||||
/* PPI Status Register */
|
/* PPI Status Register */
|
||||||
@ -720,6 +720,26 @@ void arm_gic0_initialize(void);
|
|||||||
|
|
||||||
void arm_gic_initialize(void);
|
void arm_gic_initialize(void);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: arm_gic_irq_trigger
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set the trigger type for the specificd IRQ source and the current CPU.
|
||||||
|
*
|
||||||
|
* Since this API is not supported on all architectures, it should be
|
||||||
|
* avoided in common implementations where possible.
|
||||||
|
*
|
||||||
|
* Input Paramters:
|
||||||
|
* irq - The interrupt request to modify.
|
||||||
|
* edge - False: Active HIGH level sensitive, True: Rising edge sensitive
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on success; a negated errno value is returned on any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int arm_gic_irq_trigger(int irq, bool edge);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: arm_decodeirq
|
* Name: arm_decodeirq
|
||||||
*
|
*
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
#include "up_arch.h"
|
#include "up_arch.h"
|
||||||
#include "up_internal.h"
|
#include "up_internal.h"
|
||||||
|
|
||||||
|
#include "gic.h"
|
||||||
#include "chip/imx_uart.h"
|
#include "chip/imx_uart.h"
|
||||||
#include "imx_config.h"
|
#include "imx_config.h"
|
||||||
#include "imx_lowputc.h"
|
#include "imx_lowputc.h"
|
||||||
@ -613,6 +614,10 @@ static int imx_attach(struct uart_dev_s *dev)
|
|||||||
ret = irq_attach(priv->irq, priv->handler);
|
ret = irq_attach(priv->irq, priv->handler);
|
||||||
if (ret == OK)
|
if (ret == OK)
|
||||||
{
|
{
|
||||||
|
/* Configure as a (high) level interrupt */
|
||||||
|
|
||||||
|
(void)arm_gic_irq_trigger(priv->irq, false);
|
||||||
|
|
||||||
/* Enable the interrupt (RX and TX interrupts are still disabled
|
/* Enable the interrupt (RX and TX interrupts are still disabled
|
||||||
* in the UART
|
* in the UART
|
||||||
*/
|
*/
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include <arch/irq.h>
|
#include <arch/irq.h>
|
||||||
|
|
||||||
#include "up_arch.h"
|
#include "up_arch.h"
|
||||||
|
#include "gic.h"
|
||||||
#include "chip/imx_ccm.h"
|
#include "chip/imx_ccm.h"
|
||||||
#include "chip/imx_gpt.h"
|
#include "chip/imx_gpt.h"
|
||||||
|
|
||||||
@ -235,6 +236,10 @@ void up_timer_initialize(void)
|
|||||||
cr |= GPT_CR_EN;
|
cr |= GPT_CR_EN;
|
||||||
putreg32(cr, IMX_GPT_CR);
|
putreg32(cr, IMX_GPT_CR);
|
||||||
|
|
||||||
|
/* Configure as a (rising) edge-triggered interrupt */
|
||||||
|
|
||||||
|
(void)arm_gic_irq_trigger(IMX_IRQ_GPT, true);
|
||||||
|
|
||||||
/* Attach the timer interrupt vector */
|
/* Attach the timer interrupt vector */
|
||||||
|
|
||||||
(void)irq_attach(IMX_IRQ_GPT, (xcpt_t)up_timerisr);
|
(void)irq_attach(IMX_IRQ_GPT, (xcpt_t)up_timerisr);
|
||||||
|
@ -46,6 +46,14 @@ no interrupt driver serial console output (syslog, printf).
|
|||||||
|
|
||||||
2016-05-16: I know get serial interrupts (but not timer interrupts). This
|
2016-05-16: I know get serial interrupts (but not timer interrupts). This
|
||||||
involves a few changes to GIC bit settings that I do not fully understand.
|
involves a few changes to GIC bit settings that I do not fully understand.
|
||||||
|
With this change, the NSH serial console works:
|
||||||
|
|
||||||
|
MX6Q SABRESD U-Boot > ABEFGHILMN
|
||||||
|
|
||||||
|
NuttShell (NSH)
|
||||||
|
nsh>
|
||||||
|
|
||||||
|
But there are still no timer interrupts.
|
||||||
|
|
||||||
Platform Features
|
Platform Features
|
||||||
=================
|
=================
|
||||||
|
Loading…
Reference in New Issue
Block a user