drivers: intc: plic: convert trigger type to use Kconfig
Convert the compilation of the trigger type feature to depend on Kconfig, following the same pattern of software-triggered interrupt. Signed-off-by: Yong Cong Sin <ycsin@meta.com> Signed-off-by: Yong Cong Sin <yongcong.sin@gmail.com>
This commit is contained in:
parent
65fb61bc68
commit
9109cfe346
|
@ -20,6 +20,37 @@ config PLIC_SUPPORTS_SOFT_INTERRUPT
|
|||
help
|
||||
Enabled when the PLIC supports software-triggered interrupts.
|
||||
|
||||
config PLIC_SUPPORTS_TRIG_TYPE
|
||||
bool
|
||||
default y
|
||||
depends on DT_HAS_ANDESTECH_NCEPLIC100_ENABLED
|
||||
help
|
||||
Enabled when the PLIC supports multiple trigger types,
|
||||
such as level, edge, etc.
|
||||
|
||||
if PLIC_SUPPORTS_TRIG_TYPE
|
||||
|
||||
config PLIC_TRIG_TYPE_REG_OFFSET
|
||||
hex "Trigger type register offset"
|
||||
default 0x1080 if DT_HAS_ANDESTECH_NCEPLIC100_ENABLED
|
||||
help
|
||||
Offset to the 'trigger type' register.
|
||||
|
||||
config PLIC_TRIG_TYPE_BITWIDTH
|
||||
int "Trigger type bitwidth"
|
||||
default 1
|
||||
help
|
||||
Number of bits required to differentiate between the trigger types.
|
||||
|
||||
config PLIC_SUPPORTS_TRIG_EDGE
|
||||
bool
|
||||
default y
|
||||
depends on DT_HAS_ANDESTECH_NCEPLIC100_ENABLED
|
||||
help
|
||||
Enabled when the PLIC supports edge-triggered interrupt.
|
||||
|
||||
endif # PLIC_SUPPORTS_TRIG_TYPE
|
||||
|
||||
config PLIC_IRQ_AFFINITY
|
||||
bool "Configure IRQ affinity"
|
||||
depends on SMP
|
||||
|
|
|
@ -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 {
|
|||
#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)
|
|||
#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)
|
|||
*
|
||||
* @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_BITWIDTH - 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)
|
|||
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)
|
|||
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)
|
|||
* PLIC controller that the IRQ has been handled
|
||||
* for level triggered interrupts.
|
||||
*/
|
||||
#if PLIC_DRV_HAS_COMPAT(andestech_nceplic100)
|
||||
/* For NCEPLIC100, handle only if level-triggered */
|
||||
#ifdef CONFIG_PLIC_SUPPORTS_TRIG_EDGE
|
||||
/* Handle 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);
|
|||
.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), \
|
||||
|
|
Loading…
Reference in New Issue