1 /*
2  * Copyright (c) 2024 Intel Corporation
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #ifndef ZEPHYR_SOC_INTEL_ADSP_INTERRUPT_H_
7 #define ZEPHYR_SOC_INTEL_ADSP_INTERRUPT_H_
8 
9 /* Low priority interrupt indices */
10 #define ACE_INTL_HIPC     0
11 #define ACE_INTL_SBIPC    1
12 #define ACE_INTL_ML       2
13 #define ACE_INTL_IDCA     3
14 #define ACE_INTL_LPVML    4
15 #define ACE_INTL_SHA      5
16 #define ACE_INTL_L1L2M    6
17 #define ACE_INTL_I2S      7
18 #define ACE_INTL_DMIC     8
19 #define ACE_INTL_SNDW     9
20 #define ACE_INTL_TTS      10
21 #define ACE_INTL_WDT      11
22 #define ACE_INTL_HDAHIDMA 12
23 #define ACE_INTL_HDAHODMA 13
24 #define ACE_INTL_HDALIDMA 14
25 #define ACE_INTL_HDALODMA 15
26 #define ACE_INTL_I3C      16
27 #define ACE_INTL_GPDMA    17
28 #define ACE_INTL_PWM      18
29 #define ACE_INTL_I2C      19
30 #define ACE_INTL_SPI      20
31 #define ACE_INTL_UART     21
32 #define ACE_INTL_GPIO     22
33 #define ACE_INTL_UAOL     23
34 #define ACE_INTL_IDCB     24
35 #define ACE_INTL_DCW      25
36 #define ACE_INTL_DTF      26
37 #define ACE_INTL_FLV      27
38 #define ACE_INTL_DPDMA    28
39 
40 /* Device interrupt control for the low priority interrupts.  It
41  * provides per-core masking and status checking: ACE_DINT is an array
42  * of these structs, one per core.  The state is in the bottom bits,
43  * indexed by ACE_INTL_*.  Note that some of these use more than one
44  * bit to discriminate sources (e.g. TTS's bits 0-2 are
45  * timestamp/comparator0/comparator1).  It seems safe to write all 1's
46  * to the short to "just enable everything", but drivers should
47  * probably implement proper logic.
48  *
49  * Note that this block is independent of the Designware controller
50  * that manages the shared IRQ.  Interrupts need to unmasked in both
51  * in order to be delivered to software.  Per simulator source code,
52  * this is "upstream" of DW: an interrupt will not be latched into the
53  * status registers of the DW controller unless the IE bits here are
54  * set.  That seems unlikely to correctly capture the hardware
55  * behavior (it would mean that the DW controller was being
56  * independently triggered multiple times by each core!).  Beware.
57  *
58  * Enable an interrupt for a core with e.g.:
59  *
60  *    ACE_DINT[core_id].ie[ACE_INTL_TTS] = 0xffff;
61  */
62 struct ace_dint {
63 	uint16_t ie[32];  /* enable */
64 	uint16_t is[32];  /* status (potentially masked by ie)   */
65 	uint16_t irs[32]; /* "raw" status (hardware input state) */
66 	uint32_t unused[16];
67 };
68 
69 /* This register enables (1) or disable (0) the interrupt of
70  * each host inter-processor communication capability instance in a single register.
71  */
72 #define DXHIPCIE_REG 0x91040
73 
74 #define ACE_DINT             ((volatile struct ace_dint *)DXHIPCIE_REG)
75 #define XTENSA_IRQ_NUM_MASK  0xff
76 #define XTENSA_IRQ_NUM_SHIFT 0
77 
78 #define XTENSA_IRQ_NUMBER(_irq)   ((_irq >> XTENSA_IRQ_NUM_SHIFT) & XTENSA_IRQ_NUM_MASK)
79 /* Convert between IRQ_CONNECT() numbers and ACE_INTL_* interrupts */
80 #define ACE_IRQ_NUM_SHIFT         8
81 #define ACE_IRQ_NUM_MASK          0xFFU
82 #define ACE_IRQ_FROM_ZEPHYR(_irq) (((_irq >> ACE_IRQ_NUM_SHIFT) & ACE_IRQ_NUM_MASK) - 1)
83 
84 #define ACE_INTC_IRQ DT_IRQN(DT_NODELABEL(ace_intc))
85 #define ACE_IRQ_TO_ZEPHYR(_irq)                                                                    \
86 	((((_irq + 1) & ACE_IRQ_NUM_MASK) << ACE_IRQ_NUM_SHIFT) + ACE_INTC_IRQ)
87 
88 #endif
89