[Sound-open-firmware] [PATCH_V2] GPDMA: refine GPDMA on CNL

Rander Wang rander.wang at intel.com
Fri Feb 9 04:27:09 CET 2018


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 at 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);
-- 
2.14.1



More information about the Sound-open-firmware mailing list