[Sound-open-firmware] [PATCH 3/7] cnl-interrupt: refine interrupt setting for change in irq_desc
Liam Girdwood
liam.r.girdwood at linux.intel.com
Mon May 7 15:01:34 CEST 2018
On Fri, 2018-05-04 at 16:14 +0800, Rander Wang wrote:
> (1)Add core id check in interrupt register setting.
> (2)Check child list in interrupt function
> (3)Extend root irq_desc to support 4 core on cnl.
> (4)Refine macro for interrupt setting
>
> Signed-off-by: Rander Wang <rander.wang at linux.intel.com>
> Signed-off-by: Liam Girdwood <liam.r.girdwood at linux.intel.com>
> ---
> src/platform/cannonlake/dma.c | 2 +-
> .../cannonlake/include/platform/interrupt.h | 16 +-
> src/platform/cannonlake/include/platform/memory.h | 2 +-
> .../cannonlake/include/platform/platform.h | 2 +
> src/platform/cannonlake/interrupt.c | 220 +++++++++++++-------
> -
> 5 files changed, 150 insertions(+), 92 deletions(-)
>
> diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c
> index b606d1e..3f9d6cb 100644
> --- a/src/platform/cannonlake/dma.c
> +++ b/src/platform/cannonlake/dma.c
> @@ -125,7 +125,7 @@ static struct dma dma[] = {
> .id = DMA_GP_LP_DMAC1,
> .base = LP_GP_DMA_BASE(1),
> .channels = 8,
> - .irq = IRQ_EXT_LP_GPDMA0_LVL5(0, 0),
> + .irq = IRQ_EXT_LP_GPDMA1_LVL5(0, 0),
> .drv_plat_data = &dmac1,
> },
> .ops = &dw_dma_ops,
> diff --git a/src/platform/cannonlake/include/platform/interrupt.h
> b/src/platform/cannonlake/include/platform/interrupt.h
> index 03857a7..b14cfdf 100644
> --- a/src/platform/cannonlake/include/platform/interrupt.h
> +++ b/src/platform/cannonlake/include/platform/interrupt.h
> @@ -88,7 +88,7 @@
> #define IRQ_BIT_LVL5_DMIC 6
> #define IRQ_BIT_LVL5_SSP(x) (0 + x)
>
> -/* Level 2 Peripheral IRQ mappings */
> +/* Priority 2 Peripheral IRQ mappings */
> #define IRQ_EXT_HP_GPDMA_LVL2(xcpu) \
> SOF_IRQ(IRQ_BIT_LVL2_HP_GP_DMA0(0), 2, xcpu, IRQ_NUM_EXT_LEVEL2)
> #define IRQ_EXT_IDC_LVL2(xcpu) \
> @@ -106,7 +106,7 @@
> #define IRQ_EXT_SHA256_LVL2(xcpu) \
> SOF_IRQ(IRQ_BIT_LVL2_SHA256, 2, xcpu, IRQ_NUM_EXT_LEVEL2)
>
> -/* Level 3 Peripheral IRQ mappings */
> +/* Priority 3 Peripheral IRQ mappings */
> #define IRQ_EXT_CODE_DMA_LVL3(xcpu) \
> SOF_IRQ(IRQ_BIT_LVL3_CODE_LOADER, 3, xcpu, IRQ_NUM_EXT_LEVEL3)
> #define IRQ_EXT_HOST_DMA_IN_LVL3(xcpu, channel) \
> @@ -114,17 +114,17 @@
> #define IRQ_EXT_HOST_DMA_OUT_LVL3(xcpu, channel) \
> SOF_IRQ(IRQ_BIT_LVL3_HOST_STREAM_OUT(channel), 3, xcpu,
> IRQ_NUM_EXT_LEVEL3)
>
> -/* Level 4 Peripheral IRQ mappings */
> +/* Priority 4 Peripheral IRQ mappings */
> #define IRQ_EXT_LINK_DMA_IN_LVL4(xcpu, channel) \
> SOF_IRQ(IRQ_BIT_LVL4_LINK_STREAM_IN(channel), 4, xcpu,
> IRQ_NUM_EXT_LEVEL4)
> #define IRQ_EXT_LINK_DMA_OUT_LVL4(xcpu, channel) \
> SOF_IRQ(IRQ_BIT_LVL4_LINK_STREAM_OUT(channel), 4, xcpu,
> IRQ_NUM_EXT_LEVEL4)
>
> -/* Level 5 Peripheral IRQ mappings */
> +/* Priority 5 Peripheral IRQ mappings */
> #define IRQ_EXT_LP_GPDMA0_LVL5(xcpu, channel) \
> - SOF_IRQ(IRQ_BIT_LVL5_LP_GP_DMA0, 5, xcpu, IRQ_NUM_EXT_LEVEL5)
> -#define IRQ_EXT_LP_GPDMA1_LVL4(xcpu, channel) \
> - SOF_IRQ(IRQ_BIT_LVL5_LP_GP_DMA1, 4, xcpu, IRQ_NUM_EXT_LEVEL4)
> + SOF_ID_IRQ(0, IRQ_BIT_LVL5_LP_GP_DMA0, 5, xcpu, IRQ_NUM_EXT_LEVEL5)
> +#define IRQ_EXT_LP_GPDMA1_LVL5(xcpu, channel) \
> + SOF_ID_IRQ(1, IRQ_BIT_LVL5_LP_GP_DMA0, 5, xcpu, IRQ_NUM_EXT_LEVEL5)
> #define IRQ_EXT_SSP0_LVL5(xcpu) \
> SOF_IRQ(IRQ_BIT_LVL5_SSP(0), 5, xcpu, IRQ_NUM_EXT_LEVEL5)
> #define IRQ_EXT_SSP1_LVL5(xcpu) \
> @@ -161,7 +161,7 @@
>
> void platform_interrupt_init(void);
>
> -struct irq_parent *platform_irq_get_parent(uint32_t irq);
> +struct irq_desc *platform_irq_get_parent(uint32_t irq);
> void platform_interrupt_set(int irq);
> void platform_interrupt_clear(uint32_t irq, uint32_t mask);
> uint32_t platform_interrupt_get_enabled(void);
> diff --git a/src/platform/cannonlake/include/platform/memory.h
> b/src/platform/cannonlake/include/platform/memory.h
> index c7f4750..67f574a 100644
> --- a/src/platform/cannonlake/include/platform/memory.h
> +++ b/src/platform/cannonlake/include/platform/memory.h
> @@ -240,7 +240,7 @@
> #define SOF_TEXT_SIZE 0x18000
>
> /* initialized data */
> -#define SOF_DATA_SIZE 0x18000
> +#define SOF_DATA_SIZE 0x19000
>
> /* bss data */
> #define SOF_BSS_DATA_SIZE 0x8000
> diff --git a/src/platform/cannonlake/include/platform/platform.h
> b/src/platform/cannonlake/include/platform/platform.h
> index c5bf42a..3d262b4 100644
> --- a/src/platform/cannonlake/include/platform/platform.h
> +++ b/src/platform/cannonlake/include/platform/platform.h
> @@ -42,6 +42,8 @@ struct sof;
> #define PLATFORM_SSP_COUNT 3
> #define MAX_GPDMA_COUNT 2
>
> +#define MAX_CORE_COUNT 4
> +
> /* Host page size */
> #define HOST_PAGE_SIZE 4096
> #define PLATFORM_PAGE_TABLE_SIZE 256
> diff --git a/src/platform/cannonlake/interrupt.c
> b/src/platform/cannonlake/interrupt.c
> index 8c47e14..e9ef4e7 100644
> --- a/src/platform/cannonlake/interrupt.c
> +++ b/src/platform/cannonlake/interrupt.c
> @@ -39,19 +39,22 @@
> #include <stdint.h>
> #include <stdlib.h>
>
> -static void parent_level2_handler(void *data)
> +static void irq_lvl2_level2_handler(void *data)
> {
> - struct irq_parent *parent = (struct irq_parent *)data;
> - struct irq_child * child = NULL;
> + struct irq_desc *parent = (struct irq_desc *)data;
> + struct irq_desc *child = NULL;
> + struct list_item *clist;
> uint32_t status;
> uint32_t i = 0;
> + uint32_t unmask = 0;
> + int core = xthal_get_prid();
>
> /* mask the parent IRQ */
> arch_interrupt_disable_mask(1 << IRQ_NUM_EXT_LEVEL2);
>
> /* mask all child interrupts */
> - status = irq_read(REG_IRQ_IL2SD(0));
> - irq_write(REG_IRQ_IL2MSD(0), status);
> + status = irq_read(REG_IRQ_IL2SD(core));
> + irq_write(REG_IRQ_IL2MSD(core), status);
>
> /* handle each child */
> while (status) {
> @@ -61,17 +64,22 @@ static void parent_level2_handler(void *data)
> goto next;
>
> /* get child if any and run handler */
> - child = parent->child[i];
> - if (child && child->handler) {
> - child->handler(child->handler_arg);
> -
> - /* unmask this bit i interrupt */
> - irq_write(REG_IRQ_IL2MCD(0), 0x1 << i);
> - } else {
> - /* nobody cared ? */
> - trace_irq_error("nbc");
> + list_for_item(clist, &parent->child[i]) {
> + child = container_of(clist, struct irq_desc,
> irq_list);
> +
> + if (child && child->handler) {
> + child->handler(child->handler_arg);
> + unmask = 1;
> + } else {
> + /* nobody cared ? */
> + trace_irq_error("nbc");
> + }
> }
>
> + /* unmask this bit i interrupt */
> + if (unmask)
> + irq_write(REG_IRQ_IL2MCD(core), 0x1 << i);
> +
> next:
> status >>= 1;
> i++;
> @@ -82,19 +90,22 @@ next:
> arch_interrupt_enable_mask(1 << IRQ_NUM_EXT_LEVEL2);
> }
>
> -static void parent_level3_handler(void *data)
> +static void irq_lvl2_level3_handler(void *data)
> {
> - struct irq_parent *parent = (struct irq_parent *)data;
> - struct irq_child * child = NULL;
> + struct irq_desc *parent = (struct irq_desc *)data;
> + struct irq_desc *child = NULL;
> + struct list_item *clist;
> uint32_t status;
> uint32_t i = 0;
> + uint32_t unmask = 0;
> + int core = xthal_get_prid();
>
> /* mask the parent IRQ */
> arch_interrupt_disable_mask(1 << IRQ_NUM_EXT_LEVEL3);
>
> /* mask all child interrupts */
> - status = irq_read(REG_IRQ_IL3SD(0));
> - irq_write(REG_IRQ_IL3MSD(0), status);
> + status = irq_read(REG_IRQ_IL3SD(core));
> + irq_write(REG_IRQ_IL3MSD(core), status);
>
> /* handle each child */
> while (status) {
> @@ -104,17 +115,22 @@ static void parent_level3_handler(void *data)
> goto next;
>
> /* get child if any and run handler */
> - child = parent->child[i];
> - if (child && child->handler) {
> - child->handler(child->handler_arg);
> -
> - /* unmask this bit i interrupt */
> - irq_write(REG_IRQ_IL3MCD(0), 0x1 << i);
> - } else {
> - /* nobody cared ? */
> - trace_irq_error("nbc");
> + list_for_item(clist, &parent->child[i]) {
> + child = container_of(clist, struct irq_desc,
> irq_list);
> +
> + if (child && child->handler) {
> + child->handler(child->handler_arg);
> + unmask = 1;
> + } else {
> + /* nobody cared ? */
> + trace_irq_error("nbc");
> + }
> }
>
> + /* unmask this bit i interrupt */
> + if (unmask)
> + irq_write(REG_IRQ_IL3MCD(core), 0x1 << i);
> +
> next:
> status >>= 1;
> i++;
> @@ -125,19 +141,22 @@ next:
> arch_interrupt_enable_mask(1 << IRQ_NUM_EXT_LEVEL3);
> }
>
> -static void parent_level4_handler(void *data)
> +static void irq_lvl2_level4_handler(void *data)
> {
> - struct irq_parent *parent = (struct irq_parent *)data;
> - struct irq_child * child = NULL;
> + struct irq_desc *parent = (struct irq_desc *)data;
> + struct irq_desc *child = NULL;
> + struct list_item *clist;
> uint32_t status;
> uint32_t i = 0;
> + uint32_t unmask = 0;
> + int core = xthal_get_prid();
We cant call this directly in "generic" code. Can you send a separate patch that
wraps this as a static inline or better still does inline assembly (as a static
inline).
Liam
More information about the Sound-open-firmware
mailing list