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