[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