All GPDMA share the same irq on cannonlake, this is different with appololake.The change is:probe GPDMA array when initilized, set the array to the irq function; check the interrupt status of GPDMA array in irq function, process the correct GPDMA that produces interrupt.
--- V2: refine it to build for other platform.
kernel:Pierre`s branch rimage:embargo-1.0 fw:master
Signed-off-by: Rander Wang rander.wang@intel.com --- src/drivers/dw-dma.c | 43 ++++++++++++++++------ src/platform/cannonlake/dma.c | 2 +- .../cannonlake/include/platform/platform.h | 1 + src/platform/cannonlake/platform.c | 14 ++----- 4 files changed, 37 insertions(+), 23 deletions(-)
diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c index 7a1805e..d6e05b9 100644 --- a/src/drivers/dw-dma.c +++ b/src/drivers/dw-dma.c @@ -1001,7 +1001,7 @@ static int dw_dma_probe(struct dma *dma) static void dw_dma_irq_handler(void *data) { struct dma *dma = (struct dma *)data; - struct dma_pdata *p = dma_get_drvdata(dma); + struct dma_pdata *p = NULL; struct dma_sg_elem next; uint32_t status_tfr = 0; uint32_t status_block = 0; @@ -1013,11 +1013,21 @@ static void dw_dma_irq_handler(void *data) int i;
status_intr = dw_read(dma, DW_INTR_STATUS); - if (!status_intr) + if (!status_intr) { +#ifdef CONFIG_CANNONLAKE + dma++; + status_intr = dw_read(dma, DW_INTR_STATUS); + if (!status_intr) + trace_dma_error("eI0"); +#else trace_dma_error("eI0"); +#endif + }
tracev_dma("DIr");
+ p = dma_get_drvdata(dma); + /* get the source of our IRQ. */ status_block = dw_read(dma, DW_STATUS_BLOCK); status_tfr = dw_read(dma, DW_STATUS_TFR); @@ -1100,21 +1110,30 @@ static void dw_dma_irq_handler(void *data) static int dw_dma_probe(struct dma *dma) { struct dma_pdata *dw_pdata; + struct dma *dmac = dma; int i; +#ifdef CONFIG_CANNONLAKE + int j;
- /* allocate private data */ - dw_pdata = rzalloc(RZONE_SYS, RFLAGS_NONE, sizeof(*dw_pdata)); - dma_set_drvdata(dma, dw_pdata); + for (j = 0; j < MAX_GPDMA_COUNT; j++) +#endif + { + /* allocate private data */ + dw_pdata = rzalloc(RZONE_SYS, RFLAGS_NONE, sizeof(*dw_pdata)); + dma_set_drvdata(dmac, dw_pdata);
- spinlock_init(&dma->lock); + spinlock_init(&dmac->lock);
- dw_dma_setup(dma); + dw_dma_setup(dmac);
- /* init work */ - for (i = 0; i < DW_MAX_CHAN; i++) { - dw_pdata->chan[i].dma = dma; - dw_pdata->chan[i].channel = i; - dw_pdata->chan[i].status = COMP_STATE_INIT; + /* init work */ + for (i = 0; i < DW_MAX_CHAN; i++) { + dw_pdata->chan[i].dma = dmac; + dw_pdata->chan[i].channel = i; + dw_pdata->chan[i].status = COMP_STATE_INIT; + } + + dmac++; }
/* register our IRQ handler */ diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c index 45bdee3..beac6cf 100644 --- a/src/platform/cannonlake/dma.c +++ b/src/platform/cannonlake/dma.c @@ -124,7 +124,7 @@ static struct dma dma[] = { .id = DMA_GP_LP_DMAC1, .base = LP_GP_DMA_BASE(1), .channels = 8, - .irq = IRQ_EXT_LP_GPDMA1_LVL4(0, 0), + .irq = IRQ_EXT_LP_GPDMA0_LVL5(0, 0), .drv_plat_data = &dmac1, }, .ops = &dw_dma_ops, diff --git a/src/platform/cannonlake/include/platform/platform.h b/src/platform/cannonlake/include/platform/platform.h index 00e0069..f29af95 100644 --- a/src/platform/cannonlake/include/platform/platform.h +++ b/src/platform/cannonlake/include/platform/platform.h @@ -40,6 +40,7 @@ struct reef;
#define PLATFORM_SSP_COUNT 3 +#define MAX_GPDMA_COUNT 2
/* Host page size */ #define HOST_PAGE_SIZE 4096 diff --git a/src/platform/cannonlake/platform.c b/src/platform/cannonlake/platform.c index 729364f..f387109 100644 --- a/src/platform/cannonlake/platform.c +++ b/src/platform/cannonlake/platform.c @@ -196,8 +196,7 @@ static struct timer platform_ext_timer = {
int platform_init(struct reef *reef) { - struct dma *dmac0; - struct dma *dmac1; + struct dma *dmac; struct dai *ssp; int i;
@@ -249,15 +248,10 @@ int platform_init(struct reef *reef)
/* init DMACs */ trace_point(TRACE_BOOT_PLATFORM_DMA); - dmac0 = dma_get(DMA_GP_LP_DMAC0); - if (dmac0 == NULL) + dmac = dma_get(DMA_GP_LP_DMAC0); + if (!dmac) return -ENODEV; - dma_probe(dmac0); - - dmac1 = dma_get(DMA_GP_LP_DMAC1); - if (dmac1 == NULL) - return -ENODEV; - dma_probe(dmac1); + dma_probe(dmac);
/* init SSP ports */ trace_point(TRACE_BOOT_PLATFORM_SSP);