From 38edc5289c5672b37daed30467d511c2759dc573 Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Fri, 13 Aug 2021 09:14:55 -0700 Subject: [PATCH] soc: intel_adsp: Add INTCTRL register interface Add a struct-based interrupt masking API to match the existing shim and IDC register interfaces. The existing interrupt controller code isn't using it yet. Signed-off-by: Andy Ross --- .../intel_adsp/common/include/cavs-idc.h | 64 +++++++++++++++++++ soc/xtensa/intel_adsp/common/soc_mp.c | 8 +-- 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/soc/xtensa/intel_adsp/common/include/cavs-idc.h b/soc/xtensa/intel_adsp/common/include/cavs-idc.h index beb40f793b1..048257fb934 100644 --- a/soc/xtensa/intel_adsp/common/include/cavs-idc.h +++ b/soc/xtensa/intel_adsp/common/include/cavs-idc.h @@ -81,4 +81,68 @@ struct cavs_idc { extern void soc_idc_init(void); +/* cAVS interrupt mask bits. Each core has one of these structs + * indexed in the intctrl[] array. Each external interrupt source + * indexes one bit in one of the state substructs (one each for Xtensa + * level 2-5 interrupts). The "mask" field shows the current masking + * state, with a 1 representing "interrupt disabled". The "status" + * field indicates interrupts that are currently latched and awaiting + * delivery. Write bits to "set" to set the mask bit to 1 and disable + * interrupts. Write a 1 bit to "clear" to force the mask bit to 0 + * and enable them. For example, for core "c": + * + * INTCTRL[c].l2.clear = 0x10; // unmask IDC interrupt + * + * INTCTRL[c].l3.set = 0xffffffff; // Mask all L3 interrupts + * + * Note that this interrupt controller is separate from the Xtensa + * architectural interrupt hardware controlled by the + * INTENABLE/INTERRUPT/INTSET/INTCLEAR special registers on each core + * which much also be configured for interrupts to arrive. Note also + * that some hardware (like IDC, see above) implements a third (!) + * layer of interrupt masking. + */ +struct cavs_intctrl { + struct { + uint32_t set, clear, mask, status; + } l2, l3, l4, l5; +}; + +/* Named interrupt bits in the above registers */ +#define CAVS_L2_HPGPDMA BIT(24) /* HP General Purpose DMA */ +#define CAVS_L2_DWCT1 BIT(23) /* DSP Wall Clock Timer 1 */ +#define CAVS_L2_DWCT0 BIT(22) /* DSP Wall Clock Timer 0 */ +#define CAVS_L2_L2ME BIT(21) /* L2 Memory Error */ +#define CAVS_L2_DTS BIT(20) /* DSP Timestamping */ +#define CAVS_L2_SHA BIT(16) /* SHA-256 */ +#define CAVS_L2_DCLC BIT(15) /* Demand Cache Line Command */ +#define CAVS_L2_IDC BIT(8) /* IDC */ +#define CAVS_L2_HIPC BIT(7) /* Host IPC */ +#define CAVS_L2_MIPC BIT(6) /* CSME IPC */ +#define CAVS_L2_PIPC BIT(5) /* PMC IPC */ +#define CAVS_L2_SIPC BIT(4) /* Sensor Hub IPC */ + +#define CAVS_L3_DSPGCL BIT(31) /* DSP Gateway Code Loader */ +#define CAVS_L3_DSPGHOS(n) BIT(16 + n) /* DSP Gateway Host Output Stream */ +#define CAVS_L3_HPGPDMA BIT(15) /* HP General Purpose DMA */ +#define CAVS_L3_DSPGHIS(n) BIT(n) /* DSP Gateway Host Input Stream */ + +#define CAVS_L4_DSPGLOS(n) BIT(16 + n) /* DSP Gateway Link Output Stream */ +#define CAVS_L4_LPGPGMA BIT(15) /* LP General Purpose DMA */ +#define CAVS_L4_DSPGLIS(n) BIT(n) /* DSP Gateway Link Input Stream */ + +#define CAVS_L5_LPGPDMA BIT(16) /* LP General Purpose DMA */ +#define CAVS_L5_DWCT1 BIT(15) /* DSP Wall CLock Timer 1 */ +#define CAVS_L5_DWCT0 BIT(14) /* DSP Wall Clock Timer 0 */ +#define CAVS_L5_DMIX BIT(13) /* Digital Mixer */ +#define CAVS_L5_ANC BIT(12) /* Active Noise Cancellation */ +#define CAVS_L5_SNDW BIT(11) /* SoundWire */ +#define CAVS_L5_SLIM BIT(10) /* Slimbus */ +#define CAVS_L5_DSPK BIT(9) /* Digital Speaker */ +#define CAVS_L5_DMIC BIT(8) /* Digital Mic */ +#define CAVS_L5_I2S(n) BIT(n) /* I2S */ + +#define CAVS_INTCTRL \ + ((volatile struct cavs_intctrl *)DT_REG_ADDR(DT_NODELABEL(cavs0))) + #endif /* ZEPHYR_SOC_INTEL_ADSP_CAVS_IDC_H_ */ diff --git a/soc/xtensa/intel_adsp/common/soc_mp.c b/soc/xtensa/intel_adsp/common/soc_mp.c index acfb99a3ea5..c7d26b1f36f 100644 --- a/soc/xtensa/intel_adsp/common/soc_mp.c +++ b/soc/xtensa/intel_adsp/common/soc_mp.c @@ -434,12 +434,10 @@ void soc_idc_init(void) IDC[core].busy_int |= coremask; IDC[core].done_int &= ~coremask; - /* Also unmask the interrupt for every core in the L2 - * mask register. Really this should have an API - * exposed out of the interrupt controller layer... + /* Also unmask the IDC interrupt for every core in the + * L2 mask register. */ - sys_set_bit(DT_REG_ADDR(DT_NODELABEL(cavs0)) + 0x04 + - CAVS_ICTL_INT_CPU_OFFSET(core), 8); + CAVS_INTCTRL[core].l2.clear = CAVS_L2_IDC; } }