@ -40,24 +40,16 @@
@@ -40,24 +40,16 @@
# define CONTEXT_ENABLE_BASE 0x2000
# define CONTEXT_ENABLE_SIZE 0x80
# define CONTEXT_PENDING_BASE 0x1000
/*
* Trigger type is mentioned , but not defined in the RISCV PLIC specs .
* However , it is defined and supported by at least the Andes & Telink datasheet , and supported
* in Linux ' s SiFive PLIC driver
*/
# ifdef CONFIG_PLIC_SUPPORTS_TRIG_TYPE
# define PLIC_TRIG_LEVEL ((uint32_t)0)
# define PLIC_TRIG_EDGE ((uint32_t)1)
# define PLIC_DRV_HAS_COMPAT(compat) \
DT_NODE_HAS_COMPAT ( DT_COMPAT_GET_ANY_STATUS_OKAY ( DT_DRV_COMPAT ) , compat )
# if PLIC_DRV_HAS_COMPAT(andestech_nceplic100)
# define PLIC_SUPPORTS_TRIG_TYPE 1
# define PLIC_REG_TRIG_TYPE_WIDTH 1
# define PLIC_REG_TRIG_TYPE_OFFSET 0x1080
# else
/* Trigger-type not supported */
# define PLIC_REG_TRIG_TYPE_WIDTH 0
# endif
# endif /* CONFIG_PLIC_SUPPORTS_TRIG_TYPE */
/* PLIC registers are 32-bit memory-mapped */
# define PLIC_REG_SIZE 32
@ -91,7 +83,9 @@ struct plic_config {
@@ -91,7 +83,9 @@ struct plic_config {
# ifdef CONFIG_PLIC_SUPPORTS_SOFT_INTERRUPT
mem_addr_t pend ;
# endif /* CONFIG_PLIC_SUPPORTS_SOFT_INTERRUPT */
# ifdef CONFIG_PLIC_SUPPORTS_TRIG_TYPE
mem_addr_t trig ;
# endif /* CONFIG_PLIC_SUPPORTS_TRIG_TYPE */
uint32_t max_prio ;
/* Number of IRQs that the PLIC physically supports */
uint32_t riscv_ndev ;
@ -233,6 +227,7 @@ static inline const struct device *get_plic_dev_from_irq(uint32_t irq)
@@ -233,6 +227,7 @@ static inline const struct device *get_plic_dev_from_irq(uint32_t irq)
# endif
}
# ifdef CONFIG_PLIC_SUPPORTS_TRIG_TYPE
/**
* @ brief Return the value of the trigger type register for the IRQ
*
@ -245,18 +240,15 @@ static inline const struct device *get_plic_dev_from_irq(uint32_t irq)
@@ -245,18 +240,15 @@ static inline const struct device *get_plic_dev_from_irq(uint32_t irq)
*
* @ return Trigger type register value if PLIC supports trigger type , PLIC_TRIG_LEVEL otherwise
*/
static uint32_t __maybe_unused riscv_plic_irq_trig_val ( const struct device * dev , uint32_t local_irq )
static uint32_t riscv_plic_irq_trig_val ( const struct device * dev , uint32_t local_irq )
{
if ( ! IS_ENABLED ( PLIC_SUPPORTS_TRIG_TYPE ) ) {
return PLIC_TRIG_LEVEL ;
}
const struct plic_config * config = dev - > config ;
mem_addr_t trig_addr = config - > trig + local_irq_to_reg_offset ( local_irq ) ;
uint32_t offset = local_irq * PLIC_REG_ TRIG_TYPE_WIDTH ;
uint32_t offset = local_irq * CONFIG_PLIC_TRIG_TYPE_BITWIDTH ;
return sys_read32 ( trig_addr ) & GENMASK ( offset + PLIC_REG_ TRIG_TYPE_WIDTH - 1 , offset ) ;
return sys_read32 ( trig_addr ) & GENMASK ( offset + CONFIG_ PLIC_TRIG_TYPE_BIT WIDTH - 1 , offset ) ;
}
# endif /* CONFIG_PLIC_SUPPORTS_TRIG_TYPE */
static void plic_irq_enable_set_state ( uint32_t irq , bool enable )
{
@ -493,7 +485,6 @@ static void plic_irq_handler(const struct device *dev)
@@ -493,7 +485,6 @@ static void plic_irq_handler(const struct device *dev)
const struct plic_config * config = dev - > config ;
mem_addr_t claim_complete_addr = get_claim_complete_addr ( dev ) ;
struct _isr_table_entry * ite ;
uint32_t __maybe_unused trig_val ;
uint32_t cpu_id = arch_proc_id ( ) ;
/* Get the IRQ number generating the interrupt */
const uint32_t local_irq = sys_read32 ( claim_complete_addr ) ;
@ -540,16 +531,16 @@ static void plic_irq_handler(const struct device *dev)
@@ -540,16 +531,16 @@ static void plic_irq_handler(const struct device *dev)
z_irq_spurious ( NULL ) ;
}
# if PLIC_DRV_HAS_COMPAT(andestech_nceplic100)
trig_val = riscv_plic_irq_trig_val ( dev , local_irq ) ;
# ifdef CONFIG_PLIC_SUPPORTS_TRIG_EDGE
uint32_t trig_val = riscv_plic_irq_trig_val ( dev , local_irq ) ;
/*
* Edge - triggered interrupts on Andes NCEPLIC100 have to be acknowledged first before
* Edge - triggered interrupts have to be acknowledged first before
* getting handled so that we don ' t miss on the next edge - triggered interrupt .
*/
if ( trig_val = = PLIC_TRIG_EDGE ) {
sys_write32 ( local_irq , claim_complete_addr ) ;
}
# endif
# endif /* CONFIG_PLIC_SUPPORTS_TRIG_EDGE */
/* Call the corresponding IRQ handler in _sw_isr_table */
ite = & config - > isr_table [ local_irq ] ;
@ -560,14 +551,14 @@ static void plic_irq_handler(const struct device *dev)
@@ -560,14 +551,14 @@ static void plic_irq_handler(const struct device *dev)
* PLIC controller that the IRQ has been handled
* for level triggered interrupts .
*/
# if PLIC_DRV_HAS_COMPAT(andestech_nceplic100)
/* For NCEPLIC100, h andle only if level-triggered */
# ifdef CONFIG_PLIC_SUPPORTS_TRIG_EDGE
/* H andle only if level-triggered */
if ( trig_val = = PLIC_TRIG_LEVEL ) {
sys_write32 ( local_irq , claim_complete_addr ) ;
}
# else
sys_write32 ( local_irq , claim_complete_addr ) ;
# endif
# endif /* #ifdef CONFIG_PLIC_SUPPORTS_TRIG_EDGE */
}
/**
@ -911,8 +902,8 @@ SHELL_CMD_REGISTER(plic, &plic_cmds, "PLIC shell commands", NULL);
@@ -911,8 +902,8 @@ SHELL_CMD_REGISTER(plic, &plic_cmds, "PLIC shell commands", NULL);
. reg = PLIC_BASE_ADDR ( n ) + CONTEXT_BASE , \
IF_ENABLED ( CONFIG_PLIC_SUPPORTS_SOFT_INTERRUPT , \
( . pend = PLIC_BASE_ADDR ( n ) + CONTEXT_PENDING_BASE , ) ) \
IF_ENABLED ( PLIC_SUPPORTS_TRIG_TYPE , \
( . trig = PLIC_BASE_ADDR ( n ) + PLIC_REG_ TRIG_TYPE_OFFSET , ) ) \
IF_ENABLED ( CONFIG_ PLIC_SUPPORTS_TRIG_TYPE, \
( . trig = PLIC_BASE_ADDR ( n ) + CONFIG_ PLIC_TRIG_TYPE_REG _OFFSET, ) ) \
. max_prio = DT_INST_PROP ( n , riscv_max_priority ) , \
. riscv_ndev = DT_INST_PROP ( n , riscv_ndev ) , \
. nr_irqs = PLIC_MIN_IRQ_NUM ( n ) , \