1 /*
2  * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <soc/timer_group_reg.h>
8 #include <soc/ext_mem_defs.h>
9 #include <soc/gpio_reg.h>
10 #include <soc/system_reg.h>
11 #include <riscv/interrupt.h>
12 #include <soc/interrupt_reg.h>
13 #include <soc/periph_defs.h>
14 #include <zephyr/drivers/interrupt_controller/intc_esp32c3.h>
15 
16 #include <zephyr/kernel_structs.h>
17 #include <string.h>
18 #include <zephyr/toolchain/gcc.h>
19 #include <soc.h>
20 #include <zephyr/arch/riscv/arch.h>
21 
22 #define ESP32C6_INTSTATUS_REG1_THRESHOLD	32
23 #define ESP32C6_INTSTATUS_REG2_THRESHOLD	64
24 
arch_irq_enable(unsigned int irq)25 void arch_irq_enable(unsigned int irq)
26 {
27 	esp_intr_enable(irq);
28 }
29 
arch_irq_disable(unsigned int irq)30 void arch_irq_disable(unsigned int irq)
31 {
32 	esp_intr_disable(irq);
33 }
34 
arch_irq_is_enabled(unsigned int irq)35 int arch_irq_is_enabled(unsigned int irq)
36 {
37 	bool res = false;
38 	uint32_t key = irq_lock();
39 
40 	if (irq < 32) {
41 		res = esp_intr_get_enabled_intmask(0) & BIT(irq);
42 	} else if (irq < 64) {
43 		res = esp_intr_get_enabled_intmask(1) & BIT(irq - 32);
44 	} else {
45 		res = esp_intr_get_enabled_intmask(2) & BIT(irq - 64);
46 	}
47 
48 	irq_unlock(key);
49 
50 	return res;
51 }
52 
soc_intr_get_next_source(void)53 uint32_t soc_intr_get_next_source(void)
54 {
55 	uint32_t status;
56 	uint32_t source;
57 
58 	/* Status register for interrupt sources 0 ~ 31 */
59 	status = REG_READ(INTMTX_CORE0_INT_STATUS_REG_0_REG) &
60 		esp_intr_get_enabled_intmask(0);
61 
62 	if (status) {
63 		source = __builtin_ffs(status) - 1;
64 		goto ret;
65 	}
66 
67 	/* Status register for interrupt sources 32 ~ 63 */
68 	status = REG_READ(INTMTX_CORE0_INT_STATUS_REG_1_REG) &
69 		esp_intr_get_enabled_intmask(1);
70 
71 	if (status) {
72 		source = (__builtin_ffs(status) - 1 + ESP32C6_INTSTATUS_REG1_THRESHOLD);
73 		goto ret;
74 	}
75 
76 	/* Status register for interrupt sources 64 ~ 76 */
77 	status = REG_READ(INTMTX_CORE0_INT_STATUS_REG_2_REG) &
78 		esp_intr_get_enabled_intmask(2);
79 
80 	source = (__builtin_ffs(status) - 1 + ESP32C6_INTSTATUS_REG2_THRESHOLD);
81 
82 ret:
83 	return source;
84 }
85