1 /*
2  * Copyright (c) 2022 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 0x78840
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