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@linux.intel.com Signed-off-by: Liam Girdwood liam.r.girdwood@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),
.drv_plat_data = &dmac1, }, .ops = &dw_dma_ops,.irq = IRQ_EXT_LP_GPDMA1_LVL5(0, 0),
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