[Sound-open-firmware] [RFC PATCH v2 0/8] Introducing a new API for DMA_get()
This set of patches proposes a new API for dma_get() that procures a DMAC based on the requested copy capability and flags indicating shared/exclusive access. It also updates the existing user of dma_get() to use the new API based on the specific usage. The platform DMAC definitions have also been updated to include information about copy capabilities supported.
This has only been tested on the BYT platform with a Minnowboard Turbot board and a RT5651 codec where it has passed the sanity check test.
Further testing is required on other platforms to ensure there are no regressions. This patch is still RFC/RFT and needs testing on CNL/HSW.
The corresponding DMAC/DMAC channel definitions from topology/kernel driver need to be removed. This is still work in progress.
v2 changes: 1. dma_get() consolidated for all platforms 2. dmac definitions include copy capability 3. Added some helper api's to retreive platform DMAC info
Ranjani Sridharan (8): platform: dma: move dmac initialization dma: define platform DMAC capabilities dma: ops: introduce num_channels_busy to get number of busy channels in DMAC dma: add API's to retrieve platform DMAC information dma: introduce new API for requesting DMAC dma: use newly defined API for request DMAC dma: remove dmac id argument from dma_copy_context() trace: remove trace dmac id definition
src/arch/xtensa/Makefile.am | 1 + src/audio/dai.c | 3 +- src/audio/host.c | 20 +++-- src/drivers/dw-dma.c | 9 ++ src/drivers/hda-dma.c | 9 ++ src/host/common_test.c | 2 +- src/include/sof/dma.h | 26 +++++- src/ipc/apl-ipc.c | 4 +- src/ipc/byt-ipc.c | 4 +- src/ipc/cnl-ipc.c | 4 +- src/ipc/dma-copy.c | 5 +- src/ipc/hsw-ipc.c | 4 +- src/lib/Makefile.am | 11 +++ src/lib/dma-trace.c | 2 +- src/lib/dma.c | 84 +++++++++++++++++++ src/platform/apollolake/dma.c | 30 +++++-- .../apollolake/include/platform/platform.h | 3 - src/platform/apollolake/platform.c | 21 +---- src/platform/baytrail/dma.c | 23 +++-- .../baytrail/include/platform/platform.h | 3 - src/platform/baytrail/platform.c | 22 +---- src/platform/cannonlake/dma.c | 29 +++++-- .../cannonlake/include/platform/platform.h | 3 - src/platform/cannonlake/platform.c | 21 +---- src/platform/haswell/dma.c | 35 ++++++-- .../haswell/include/platform/platform.h | 3 - src/platform/haswell/platform.c | 20 +---- 27 files changed, 262 insertions(+), 139 deletions(-) create mode 100644 src/lib/dma.c
This patch proposes to move the platform DMAC initialization code to the dmac_init() routine.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/include/sof/dma.h | 3 +++ src/platform/apollolake/dma.c | 12 ++++++++++++ src/platform/apollolake/platform.c | 21 +-------------------- src/platform/baytrail/dma.c | 12 ++++++++++++ src/platform/baytrail/platform.c | 22 +--------------------- src/platform/cannonlake/dma.c | 12 ++++++++++++ src/platform/cannonlake/platform.c | 21 +-------------------- src/platform/haswell/dma.c | 19 +++++++++++++++++++ src/platform/haswell/platform.c | 20 +------------------- 9 files changed, 62 insertions(+), 80 deletions(-)
diff --git a/src/include/sof/dma.h b/src/include/sof/dma.h index 7ba1298..80ca880 100644 --- a/src/include/sof/dma.h +++ b/src/include/sof/dma.h @@ -140,6 +140,9 @@ struct dma_int {
struct dma *dma_get(int dmac_id);
+/* initialize all platform DMAC's */ +void dmac_init(void); + #define dma_set_drvdata(dma, data) \ dma->private = data #define dma_get_drvdata(dma) \ diff --git a/src/platform/apollolake/dma.c b/src/platform/apollolake/dma.c index 90dde96..da413e3 100644 --- a/src/platform/apollolake/dma.c +++ b/src/platform/apollolake/dma.c @@ -181,3 +181,15 @@ struct dma *dma_get(int dmac_id)
return NULL; } + +/* Initialize all platform DMAC's */ +void dmac_init(void) +{ + int i, ret; + + for (i = 0; i < ARRAY_SIZE(dma); i++) { + ret = dma_probe(&dma[i]); + if (ret < 0) + trace_error_value(ret); + } +} diff --git a/src/platform/apollolake/platform.c b/src/platform/apollolake/platform.c index 0b26ae5..589c77e 100644 --- a/src/platform/apollolake/platform.c +++ b/src/platform/apollolake/platform.c @@ -186,7 +186,6 @@ static void platform_memory_windows_init(void)
int platform_init(struct sof *sof) { - struct dma *dmac; struct dai *ssp; struct dai *dmic0; int i; @@ -244,25 +243,7 @@ int platform_init(struct sof *sof)
/* init DMACs */ trace_point(TRACE_BOOT_PLATFORM_DMA); - dmac = dma_get(DMA_GP_LP_DMAC0); - if (dmac == NULL) - return -ENODEV; - dma_probe(dmac); - - dmac = dma_get(DMA_GP_LP_DMAC1); - if (dmac == NULL) - return -ENODEV; - dma_probe(dmac); - - dmac = dma_get(DMA_HOST_OUT_DMAC); - if (dmac == NULL) - return -ENODEV; - dma_probe(dmac); - - dmac = dma_get(DMA_HOST_IN_DMAC); - if (dmac == NULL) - return -ENODEV; - dma_probe(dmac); + dmac_init();
/* init SSP ports */ trace_point(TRACE_BOOT_PLATFORM_SSP); diff --git a/src/platform/baytrail/dma.c b/src/platform/baytrail/dma.c index 53602f5..142b62a 100644 --- a/src/platform/baytrail/dma.c +++ b/src/platform/baytrail/dma.c @@ -186,3 +186,15 @@ struct dma *dma_get(int dmac_id)
return NULL; } + +/* Initialize all platform DMAC's */ +void dmac_init(void) +{ + int i, ret; + + for (i = 0; i < ARRAY_SIZE(dma); i++) { + ret = dma_probe(&dma[i]); + if (ret < 0) + trace_error_value(ret); + } +} diff --git a/src/platform/baytrail/platform.c b/src/platform/baytrail/platform.c index 562fabf..50acda9 100644 --- a/src/platform/baytrail/platform.c +++ b/src/platform/baytrail/platform.c @@ -290,15 +290,10 @@ void platform_interrupt_unmask(uint32_t irq, uint32_t mask) int platform_init(struct sof *sof) { #if defined CONFIG_BAYTRAIL - struct dma *dmac0; - struct dma *dmac1; struct dai *ssp0; struct dai *ssp1; struct dai *ssp2; #elif defined CONFIG_CHERRYTRAIL - struct dma *dmac0; - struct dma *dmac1; - struct dma *dmac2; struct dai *ssp0; struct dai *ssp1; struct dai *ssp2; @@ -356,22 +351,7 @@ int platform_init(struct sof *sof)
/* init DMACs */ trace_point(TRACE_BOOT_PLATFORM_DMA); - dmac0 = dma_get(DMA_ID_DMAC0); - if (dmac0 == NULL) - return -ENODEV; - dma_probe(dmac0); - - dmac1 = dma_get(DMA_ID_DMAC1); - if (dmac1 == NULL) - return -ENODEV; - dma_probe(dmac1); - -#if defined CONFIG_CHERRYTRAIL - dmac2 = dma_get(DMA_ID_DMAC1); - if (dmac2 == NULL) - return -ENODEV; - dma_probe(dmac2); -#endif + dmac_init();
/* mask SSP 0 - 2 interrupts */ shim_write(SHIM_PIMR, shim_read(SHIM_PIMR) | 0x00000038); diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c index 3f9d6cb..1d08a1f 100644 --- a/src/platform/cannonlake/dma.c +++ b/src/platform/cannonlake/dma.c @@ -182,3 +182,15 @@ struct dma *dma_get(int dmac_id)
return NULL; } + +/* Initialize all platform DMAC's */ +void dmac_init(void) +{ + int i, ret; + + for (i = 0; i < ARRAY_SIZE(dma); i++) { + ret = dma_probe(&dma[i]); + if (ret < 0) + trace_error_value(ret); + } +} diff --git a/src/platform/cannonlake/platform.c b/src/platform/cannonlake/platform.c index 2e85088..3ca48e5 100644 --- a/src/platform/cannonlake/platform.c +++ b/src/platform/cannonlake/platform.c @@ -208,7 +208,6 @@ static struct timer platform_ext_timer = {
int platform_init(struct sof *sof) { - struct dma *dmac; struct dai *ssp; struct dai *dmic0; int i; @@ -261,25 +260,7 @@ int platform_init(struct sof *sof)
/* init DMACs */ trace_point(TRACE_BOOT_PLATFORM_DMA); - dmac = dma_get(DMA_GP_LP_DMAC0); - if (!dmac) - return -ENODEV; - dma_probe(dmac); - - dmac = dma_get(DMA_GP_LP_DMAC1); - if (!dmac) - return -ENODEV; - dma_probe(dmac); - - dmac = dma_get(DMA_HOST_OUT_DMAC); - if (!dmac) - return -ENODEV; - dma_probe(dmac); - - dmac = dma_get(DMA_HOST_IN_DMAC); - if (!dmac) - return -ENODEV; - dma_probe(dmac); + dmac_init();
/* init SSP ports */ trace_point(TRACE_BOOT_PLATFORM_SSP); diff --git a/src/platform/haswell/dma.c b/src/platform/haswell/dma.c index 42df546..1bd424e 100644 --- a/src/platform/haswell/dma.c +++ b/src/platform/haswell/dma.c @@ -135,3 +135,22 @@ struct dma *dma_get(int dmac_id) return NULL; } } + +/* Initialize all platform DMAC's */ +void dmac_init(void) +{ + int i, ret; + + for (i = 0; i < ARRAY_SIZE(dma); i++) { + ret = dma_probe(&dma[i]); + if (ret < 0) + trace_error_value(ret); + } + + /* clear the masks for dsp of the dmacs */ + io_reg_update_bits(SHIM_BASE + SHIM_IMRD, + SHIM_IMRD_DMAC0, 0); + + io_reg_update_bits(SHIM_BASE + SHIM_IMRD, + SHIM_IMRD_DMAC1, 0); +} diff --git a/src/platform/haswell/platform.c b/src/platform/haswell/platform.c index 81ce67a..710400c 100644 --- a/src/platform/haswell/platform.c +++ b/src/platform/haswell/platform.c @@ -240,8 +240,6 @@ static void platform_init_shim(void)
int platform_init(struct sof *sof) { - struct dma *dmac0; - struct dma *dmac1; struct dai *ssp0; struct dai *ssp1;
@@ -280,23 +278,7 @@ int platform_init(struct sof *sof)
/* init DMACs */ trace_point(TRACE_BOOT_PLATFORM_DMA); - dmac0 = dma_get(DMA_ID_DMAC0); - if (dmac0 == NULL) - return -ENODEV; - dma_probe(dmac0); - - /* clear the masks for dsp of the dmac*/ - io_reg_update_bits(SHIM_BASE + SHIM_IMRD, - SHIM_IMRD_DMAC0, 0); - - dmac1 = dma_get(DMA_ID_DMAC1); - if (dmac1 == NULL) - return -ENODEV; - dma_probe(dmac1); - - /* clear the masks for dsp of the dmac*/ - io_reg_update_bits(SHIM_BASE + SHIM_IMRD, - SHIM_IMRD_DMAC1, 0); + dmac_init();
/* init SSP ports */ trace_point(TRACE_BOOT_PLATFORM_SSP);
On Wed, 2018-06-06 at 16:08 -0700, Ranjani Sridharan wrote:
This patch proposes to move the platform DMAC initialization code to the dmac_init() routine.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com
src/include/sof/dma.h | 3 +++ src/platform/apollolake/dma.c | 12 ++++++++++++ src/platform/apollolake/platform.c | 21 +-------------------- src/platform/baytrail/dma.c | 12 ++++++++++++ src/platform/baytrail/platform.c | 22 +--------------------- src/platform/cannonlake/dma.c | 12 ++++++++++++ src/platform/cannonlake/platform.c | 21 +-------------------- src/platform/haswell/dma.c | 19 +++++++++++++++++++ src/platform/haswell/platform.c | 20 +------------------- 9 files changed, 62 insertions(+), 80 deletions(-)
diff --git a/src/include/sof/dma.h b/src/include/sof/dma.h index 7ba1298..80ca880 100644 --- a/src/include/sof/dma.h +++ b/src/include/sof/dma.h @@ -140,6 +140,9 @@ struct dma_int {
struct dma *dma_get(int dmac_id);
+/* initialize all platform DMAC's */ +void dmac_init(void);
int dmac_init(void);
#define dma_set_drvdata(dma, data) \ dma->private = data #define dma_get_drvdata(dma) \ diff --git a/src/platform/apollolake/dma.c b/src/platform/apollolake/dma.c index 90dde96..da413e3 100644 --- a/src/platform/apollolake/dma.c +++ b/src/platform/apollolake/dma.c @@ -181,3 +181,15 @@ struct dma *dma_get(int dmac_id)
return NULL; }
+/* Initialize all platform DMAC's */ +void dmac_init(void) +{
- int i, ret;
- for (i = 0; i < ARRAY_SIZE(dma); i++) {
ret = dma_probe(&dma[i]);
if (ret < 0)
We should include the DMAC ID in the trace error, to help identy the DAM that failed.
trace_error_value(ret);
- }
+} diff --git a/src/platform/apollolake/platform.c b/src/platform/apollolake/platform.c index 0b26ae5..589c77e 100644 --- a/src/platform/apollolake/platform.c +++ b/src/platform/apollolake/platform.c @@ -186,7 +186,6 @@ static void platform_memory_windows_init(void)
int platform_init(struct sof *sof) {
- struct dma *dmac; struct dai *ssp; struct dai *dmic0; int i;
@@ -244,25 +243,7 @@ int platform_init(struct sof *sof)
/* init DMACs */ trace_point(TRACE_BOOT_PLATFORM_DMA);
- dmac = dma_get(DMA_GP_LP_DMAC0);
- if (dmac == NULL)
return -ENODEV;
- dma_probe(dmac);
- dmac = dma_get(DMA_GP_LP_DMAC1);
- if (dmac == NULL)
return -ENODEV;
- dma_probe(dmac);
- dmac = dma_get(DMA_HOST_OUT_DMAC);
- if (dmac == NULL)
return -ENODEV;
- dma_probe(dmac);
- dmac = dma_get(DMA_HOST_IN_DMAC);
- if (dmac == NULL)
return -ENODEV;
- dma_probe(dmac);
- dmac_init();
And check return code here, since further init may depend on it.
/* init SSP ports */ trace_point(TRACE_BOOT_PLATFORM_SSP); diff --git a/src/platform/baytrail/dma.c b/src/platform/baytrail/dma.c index 53602f5..142b62a 100644 --- a/src/platform/baytrail/dma.c +++ b/src/platform/baytrail/dma.c @@ -186,3 +186,15 @@ struct dma *dma_get(int dmac_id)
return NULL; }
+/* Initialize all platform DMAC's */ +void dmac_init(void) +{
- int i, ret;
- for (i = 0; i < ARRAY_SIZE(dma); i++) {
ret = dma_probe(&dma[i]);
if (ret < 0)
trace_error_value(ret);
- }
+} diff --git a/src/platform/baytrail/platform.c b/src/platform/baytrail/platform.c index 562fabf..50acda9 100644 --- a/src/platform/baytrail/platform.c +++ b/src/platform/baytrail/platform.c @@ -290,15 +290,10 @@ void platform_interrupt_unmask(uint32_t irq, uint32_t mask) int platform_init(struct sof *sof) { #if defined CONFIG_BAYTRAIL
- struct dma *dmac0;
- struct dma *dmac1; struct dai *ssp0; struct dai *ssp1; struct dai *ssp2;
#elif defined CONFIG_CHERRYTRAIL
- struct dma *dmac0;
- struct dma *dmac1;
- struct dma *dmac2; struct dai *ssp0; struct dai *ssp1; struct dai *ssp2;
@@ -356,22 +351,7 @@ int platform_init(struct sof *sof)
/* init DMACs */ trace_point(TRACE_BOOT_PLATFORM_DMA);
- dmac0 = dma_get(DMA_ID_DMAC0);
- if (dmac0 == NULL)
return -ENODEV;
- dma_probe(dmac0);
- dmac1 = dma_get(DMA_ID_DMAC1);
- if (dmac1 == NULL)
return -ENODEV;
- dma_probe(dmac1);
-#if defined CONFIG_CHERRYTRAIL
- dmac2 = dma_get(DMA_ID_DMAC1);
- if (dmac2 == NULL)
return -ENODEV;
- dma_probe(dmac2);
-#endif
dmac_init();
/* mask SSP 0 - 2 interrupts */ shim_write(SHIM_PIMR, shim_read(SHIM_PIMR) | 0x00000038);
diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c index 3f9d6cb..1d08a1f 100644 --- a/src/platform/cannonlake/dma.c +++ b/src/platform/cannonlake/dma.c @@ -182,3 +182,15 @@ struct dma *dma_get(int dmac_id)
return NULL; }
+/* Initialize all platform DMAC's */ +void dmac_init(void) +{
- int i, ret;
- for (i = 0; i < ARRAY_SIZE(dma); i++) {
ret = dma_probe(&dma[i]);
if (ret < 0)
trace_error_value(ret);
- }
+} diff --git a/src/platform/cannonlake/platform.c b/src/platform/cannonlake/platform.c index 2e85088..3ca48e5 100644 --- a/src/platform/cannonlake/platform.c +++ b/src/platform/cannonlake/platform.c @@ -208,7 +208,6 @@ static struct timer platform_ext_timer = {
int platform_init(struct sof *sof) {
- struct dma *dmac; struct dai *ssp; struct dai *dmic0; int i;
@@ -261,25 +260,7 @@ int platform_init(struct sof *sof)
/* init DMACs */ trace_point(TRACE_BOOT_PLATFORM_DMA);
- dmac = dma_get(DMA_GP_LP_DMAC0);
- if (!dmac)
return -ENODEV;
- dma_probe(dmac);
- dmac = dma_get(DMA_GP_LP_DMAC1);
- if (!dmac)
return -ENODEV;
- dma_probe(dmac);
- dmac = dma_get(DMA_HOST_OUT_DMAC);
- if (!dmac)
return -ENODEV;
- dma_probe(dmac);
- dmac = dma_get(DMA_HOST_IN_DMAC);
- if (!dmac)
return -ENODEV;
- dma_probe(dmac);
dmac_init();
/* init SSP ports */ trace_point(TRACE_BOOT_PLATFORM_SSP);
diff --git a/src/platform/haswell/dma.c b/src/platform/haswell/dma.c index 42df546..1bd424e 100644 --- a/src/platform/haswell/dma.c +++ b/src/platform/haswell/dma.c @@ -135,3 +135,22 @@ struct dma *dma_get(int dmac_id) return NULL; } }
+/* Initialize all platform DMAC's */ +void dmac_init(void) +{
- int i, ret;
- for (i = 0; i < ARRAY_SIZE(dma); i++) {
ret = dma_probe(&dma[i]);
if (ret < 0)
trace_error_value(ret);
- }
- /* clear the masks for dsp of the dmacs */
- io_reg_update_bits(SHIM_BASE + SHIM_IMRD,
SHIM_IMRD_DMAC0, 0);
- io_reg_update_bits(SHIM_BASE + SHIM_IMRD,
SHIM_IMRD_DMAC1, 0);
+} diff --git a/src/platform/haswell/platform.c b/src/platform/haswell/platform.c index 81ce67a..710400c 100644 --- a/src/platform/haswell/platform.c +++ b/src/platform/haswell/platform.c @@ -240,8 +240,6 @@ static void platform_init_shim(void)
int platform_init(struct sof *sof) {
- struct dma *dmac0;
- struct dma *dmac1; struct dai *ssp0; struct dai *ssp1;
@@ -280,23 +278,7 @@ int platform_init(struct sof *sof)
/* init DMACs */ trace_point(TRACE_BOOT_PLATFORM_DMA);
- dmac0 = dma_get(DMA_ID_DMAC0);
- if (dmac0 == NULL)
return -ENODEV;
- dma_probe(dmac0);
- /* clear the masks for dsp of the dmac*/
- io_reg_update_bits(SHIM_BASE + SHIM_IMRD,
SHIM_IMRD_DMAC0, 0);
- dmac1 = dma_get(DMA_ID_DMAC1);
- if (dmac1 == NULL)
return -ENODEV;
- dma_probe(dmac1);
- /* clear the masks for dsp of the dmac*/
- io_reg_update_bits(SHIM_BASE + SHIM_IMRD,
SHIM_IMRD_DMAC1, 0);
dmac_init();
/* init SSP ports */ trace_point(TRACE_BOOT_PLATFORM_SSP);
Add the link_to_mem and mem_to_link dma copy directions to the dma_copy_dir enum.
And define the DMAC copy capabilities for all platform DMAC's
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/include/sof/dma.h | 10 +++++++++- src/platform/apollolake/dma.c | 10 ++++++++++ src/platform/baytrail/dma.c | 3 +++ src/platform/cannonlake/dma.c | 9 +++++++++ src/platform/haswell/dma.c | 2 ++ 5 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/src/include/sof/dma.h b/src/include/sof/dma.h index 80ca880..142aafc 100644 --- a/src/include/sof/dma.h +++ b/src/include/sof/dma.h @@ -46,13 +46,20 @@ enum dma_copy_dir { DMA_DIR_MEM_TO_DEV, DMA_DIR_DEV_TO_MEM, DMA_DIR_DEV_TO_DEV, + DMA_DIR_MEM_TO_LINK, + DMA_DIR_LINK_TO_MEM, };
+/* + * DMAC copy capabilities with support for all directions + * enumerated by dma_copy_dir + */ +#define DMA_COPY_CAPS_ALL 0xFF + /* DMA IRQ types */ #define DMA_IRQ_TYPE_BLOCK (1 << 0) #define DMA_IRQ_TYPE_LLIST (1 << 1)
- /* We will use this macro in cb handler to inform dma that * we need to stop the reload for special purpose */ @@ -118,6 +125,7 @@ struct dma_ops { /* DMA platform data */ struct dma_plat_data { uint32_t id; + int dma_cap; /* copy capabilities supported by DMAC*/ uint32_t base; uint32_t channels; uint32_t irq; diff --git a/src/platform/apollolake/dma.c b/src/platform/apollolake/dma.c index da413e3..f5e492c 100644 --- a/src/platform/apollolake/dma.c +++ b/src/platform/apollolake/dma.c @@ -38,6 +38,9 @@ #include <stdint.h> #include <string.h>
+/* DMAC copy caps for GP LP DMA's*/ +#define DMA_GP_LP_CAPS 0x39 + static struct dw_drv_plat_data dmac0 = { .chan[0] = { .class = 1, @@ -112,6 +115,7 @@ static struct dma dma[] = { { /* Low Power GP DMAC 0 */ .plat_data = { .id = DMA_GP_LP_DMAC0, + .dma_cap = DMA_GP_LP_CAPS, .base = LP_GP_DMA_BASE(0), .channels = 8, .irq = IRQ_EXT_LP_GPDMA0_LVL5(0, 0), @@ -122,6 +126,8 @@ static struct dma dma[] = { { /* Low Power GP DMAC 1 */ .plat_data = { .id = DMA_GP_LP_DMAC1, + .dma_cap = DMA_GP_LP_CAPS, + .dma_cap = (1 << DMA_DIR_LMEM_TO_HMEM), .base = LP_GP_DMA_BASE(1), .channels = 8, .irq = IRQ_EXT_LP_GPDMA1_LVL5(0, 0), @@ -132,6 +138,7 @@ static struct dma dma[] = { { /* Host In DMAC */ .plat_data = { .id = DMA_HOST_IN_DMAC, + .dma_cap = (1 << DMA_DIR_LMEM_TO_HMEM), .base = GTW_HOST_IN_STREAM_BASE(0), .channels = 7, .irq = IRQ_EXT_HOST_DMA_IN_LVL3(0, 0), @@ -142,6 +149,7 @@ static struct dma dma[] = { { /* Host out DMAC */ .plat_data = { .id = DMA_HOST_OUT_DMAC, + .dma_cap = (1 << DMA_DIR_HMEM_TO_LMEM), .base = GTW_HOST_OUT_STREAM_BASE(0), .channels = 6, .irq = IRQ_EXT_HOST_DMA_OUT_LVL3(0, 0), @@ -152,6 +160,7 @@ static struct dma dma[] = { { /* Link In DMAC */ .plat_data = { .id = DMA_LINK_IN_DMAC, + .dma_cap = (1 << DMA_DIR_MEM_TO_LINK), .base = GTW_LINK_IN_STREAM_BASE(0), .channels = 8, .irq = IRQ_EXT_LINK_DMA_IN_LVL4(0, 0), @@ -162,6 +171,7 @@ static struct dma dma[] = { { /* Link out DMAC */ .plat_data = { .id = DMA_LINK_OUT_DMAC, + .dma_cap = (1 << DMA_DIR_LINK_TO_MEM), .base = GTW_LINK_OUT_STREAM_BASE(0), .channels = 8, .irq = IRQ_EXT_LINK_DMA_OUT_LVL4(0, 0), diff --git a/src/platform/baytrail/dma.c b/src/platform/baytrail/dma.c index 142b62a..95b836c 100644 --- a/src/platform/baytrail/dma.c +++ b/src/platform/baytrail/dma.c @@ -147,6 +147,7 @@ static struct dma dma[] = { { .plat_data = { .id = DMA_ID_DMAC0, + .dma_cap = DMA_COPY_CAPS_ALL, .base = DMA0_BASE, .irq = IRQ_NUM_EXT_DMAC0, .drv_plat_data = &dmac0, @@ -156,6 +157,7 @@ static struct dma dma[] = { { .plat_data = { .id = DMA_ID_DMAC1, + .dma_cap = DMA_COPY_CAPS_ALL, .base = DMA1_BASE, .irq = IRQ_NUM_EXT_DMAC1, .drv_plat_data = &dmac1, @@ -166,6 +168,7 @@ static struct dma dma[] = { { .plat_data = { .id = DMA_ID_DMAC2, + .dma_cap = DMA_COPY_CAPS_ALL, .base = DMA2_BASE, .irq = IRQ_NUM_EXT_DMAC2, .drv_plat_data = &dmac2, diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c index 1d08a1f..1ad989f 100644 --- a/src/platform/cannonlake/dma.c +++ b/src/platform/cannonlake/dma.c @@ -39,6 +39,9 @@ #include <stdint.h> #include <string.h>
+/* DMAC copy caps for GP LP DMA's*/ +#define DMA_GP_LP_CAPS 0x39 + static struct dw_drv_plat_data dmac0 = { .chan[0] = { .class = 6, @@ -113,6 +116,7 @@ static struct dma dma[] = { { /* Low Power GP DMAC 0 */ .plat_data = { .id = DMA_GP_LP_DMAC0, + .dma_cap = DMA_GP_LP_CAPS, .base = LP_GP_DMA_BASE(0), .channels = 8, .irq = IRQ_EXT_LP_GPDMA0_LVL5(0, 0), @@ -123,6 +127,7 @@ static struct dma dma[] = { { /* Low Power GP DMAC 1 */ .plat_data = { .id = DMA_GP_LP_DMAC1, + .dma_cap = DMA_GP_LP_CAPS, .base = LP_GP_DMA_BASE(1), .channels = 8, .irq = IRQ_EXT_LP_GPDMA1_LVL5(0, 0), @@ -133,6 +138,7 @@ static struct dma dma[] = { { /* Host In DMAC */ .plat_data = { .id = DMA_HOST_IN_DMAC, + .dma_cap = (1 << DMA_DIR_LMEM_TO_HMEM), .base = GTW_HOST_IN_STREAM_BASE(0), .channels = 7, .irq = IRQ_EXT_HOST_DMA_IN_LVL3(0, 0), @@ -143,6 +149,7 @@ static struct dma dma[] = { { /* Host out DMAC */ .plat_data = { .id = DMA_HOST_OUT_DMAC, + .dma_cap = (1 << DMA_DIR_HMEM_TO_LMEM), .base = GTW_HOST_OUT_STREAM_BASE(0), .channels = 9, .irq = IRQ_EXT_HOST_DMA_OUT_LVL3(0, 0), @@ -153,6 +160,7 @@ static struct dma dma[] = { { /* Link In DMAC */ .plat_data = { .id = DMA_LINK_IN_DMAC, + .dma_cap = (1 << DMA_DIR_MEM_TO_LINK), .base = GTW_LINK_IN_STREAM_BASE(0), .channels = 9, .irq = IRQ_EXT_LINK_DMA_IN_LVL4(0, 0), @@ -163,6 +171,7 @@ static struct dma dma[] = { { /* Link out DMAC */ .plat_data = { .id = DMA_LINK_OUT_DMAC, + .dma_cap = (1 << DMA_DIR_LINK_TO_MEM), .base = GTW_LINK_OUT_STREAM_BASE(0), .channels = 7, .irq = IRQ_EXT_LINK_DMA_OUT_LVL4(0, 0), diff --git a/src/platform/haswell/dma.c b/src/platform/haswell/dma.c index 1bd424e..ec48bc8 100644 --- a/src/platform/haswell/dma.c +++ b/src/platform/haswell/dma.c @@ -110,6 +110,7 @@ static struct dma dma[] = { { .plat_data = { .base = DMA0_BASE, + .dma_cap = (1 << DMA_DIR_MEM_TO_MEM), .irq = IRQ_NUM_EXT_DMAC0, .drv_plat_data = &dmac0, }, @@ -118,6 +119,7 @@ static struct dma dma[] = { { .plat_data = { .base = DMA1_BASE, + .dma_cap = DMA_COPY_CAPS_ALL, .irq = IRQ_NUM_EXT_DMAC1, .drv_plat_data = &dmac1, },
On Wed, 2018-06-06 at 16:08 -0700, Ranjani Sridharan wrote:
Add the link_to_mem and mem_to_link dma copy directions to the dma_copy_dir enum.
And define the DMAC copy capabilities for all platform DMAC's
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com
src/include/sof/dma.h | 10 +++++++++- src/platform/apollolake/dma.c | 10 ++++++++++ src/platform/baytrail/dma.c | 3 +++ src/platform/cannonlake/dma.c | 9 +++++++++ src/platform/haswell/dma.c | 2 ++ 5 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/src/include/sof/dma.h b/src/include/sof/dma.h index 80ca880..142aafc 100644 --- a/src/include/sof/dma.h +++ b/src/include/sof/dma.h @@ -46,13 +46,20 @@ enum dma_copy_dir { DMA_DIR_MEM_TO_DEV, DMA_DIR_DEV_TO_MEM, DMA_DIR_DEV_TO_DEV,
- DMA_DIR_MEM_TO_LINK,
The should be the same as MEM_TO_DEV ?
- DMA_DIR_LINK_TO_MEM,
DEV_TO_MEM
Probably good to define a bit mask of all DMAC capabilities, this would include permitted directions.
};
+/*
- DMAC copy capabilities with support for all directions
- enumerated by dma_copy_dir
- */
+#define DMA_COPY_CAPS_ALL 0xFF
We cant mix an enum with a bitmask.
/* DMA IRQ types */ #define DMA_IRQ_TYPE_BLOCK (1 << 0) #define DMA_IRQ_TYPE_LLIST (1 << 1)
/* We will use this macro in cb handler to inform dma that
- we need to stop the reload for special purpose
*/ @@ -118,6 +125,7 @@ struct dma_ops { /* DMA platform data */ struct dma_plat_data { uint32_t id;
- int dma_cap; /* copy capabilities supported by DMAC*/
bitmask should be unsigned
uint32_t base; uint32_t channels; uint32_t irq; diff --git a/src/platform/apollolake/dma.c b/src/platform/apollolake/dma.c index da413e3..f5e492c 100644 --- a/src/platform/apollolake/dma.c +++ b/src/platform/apollolake/dma.c @@ -38,6 +38,9 @@ #include <stdint.h> #include <string.h>
+/* DMAC copy caps for GP LP DMA's*/ +#define DMA_GP_LP_CAPS 0x39
Magic number 0x39 ?
static struct dw_drv_plat_data dmac0 = { .chan[0] = { .class = 1, @@ -112,6 +115,7 @@ static struct dma dma[] = { { /* Low Power GP DMAC 0 */ .plat_data = { .id = DMA_GP_LP_DMAC0,
.dma_cap = DMA_GP_LP_CAPS,
I'd expect to see caps like DMA_CAPS_LP | DMA_CAPS_MEM_TO_DEV | DMA_CAPS_DMIC etc,
.base = LP_GP_DMA_BASE(0), .channels = 8, .irq = IRQ_EXT_LP_GPDMA0_LVL5(0, 0),
@@ -122,6 +126,8 @@ static struct dma dma[] = { { /* Low Power GP DMAC 1 */ .plat_data = { .id = DMA_GP_LP_DMAC1,
.dma_cap = DMA_GP_LP_CAPS,
.base = LP_GP_DMA_BASE(1), .channels = 8, .irq = IRQ_EXT_LP_GPDMA1_LVL5(0, 0),.dma_cap = (1 << DMA_DIR_LMEM_TO_HMEM),
@@ -132,6 +138,7 @@ static struct dma dma[] = { { /* Host In DMAC */ .plat_data = { .id = DMA_HOST_IN_DMAC,
.base = GTW_HOST_IN_STREAM_BASE(0), .channels = 7, .irq = IRQ_EXT_HOST_DMA_IN_LVL3(0, 0),.dma_cap = (1 << DMA_DIR_LMEM_TO_HMEM),
@@ -142,6 +149,7 @@ static struct dma dma[] = { { /* Host out DMAC */ .plat_data = { .id = DMA_HOST_OUT_DMAC,
.base = GTW_HOST_OUT_STREAM_BASE(0), .channels = 6, .irq = IRQ_EXT_HOST_DMA_OUT_LVL3(0, 0),.dma_cap = (1 << DMA_DIR_HMEM_TO_LMEM),
@@ -152,6 +160,7 @@ static struct dma dma[] = { { /* Link In DMAC */ .plat_data = { .id = DMA_LINK_IN_DMAC,
.base = GTW_LINK_IN_STREAM_BASE(0), .channels = 8, .irq = IRQ_EXT_LINK_DMA_IN_LVL4(0, 0),.dma_cap = (1 << DMA_DIR_MEM_TO_LINK),
@@ -162,6 +171,7 @@ static struct dma dma[] = { { /* Link out DMAC */ .plat_data = { .id = DMA_LINK_OUT_DMAC,
.base = GTW_LINK_OUT_STREAM_BASE(0), .channels = 8, .irq = IRQ_EXT_LINK_DMA_OUT_LVL4(0, 0),.dma_cap = (1 << DMA_DIR_LINK_TO_MEM),
diff --git a/src/platform/baytrail/dma.c b/src/platform/baytrail/dma.c index 142b62a..95b836c 100644 --- a/src/platform/baytrail/dma.c +++ b/src/platform/baytrail/dma.c @@ -147,6 +147,7 @@ static struct dma dma[] = { { .plat_data = { .id = DMA_ID_DMAC0,
.base = DMA0_BASE, .irq = IRQ_NUM_EXT_DMAC0, .drv_plat_data = &dmac0,.dma_cap = DMA_COPY_CAPS_ALL,
@@ -156,6 +157,7 @@ static struct dma dma[] = { { .plat_data = { .id = DMA_ID_DMAC1,
.base = DMA1_BASE, .irq = IRQ_NUM_EXT_DMAC1, .drv_plat_data = &dmac1,.dma_cap = DMA_COPY_CAPS_ALL,
@@ -166,6 +168,7 @@ static struct dma dma[] = { { .plat_data = { .id = DMA_ID_DMAC2,
.base = DMA2_BASE, .irq = IRQ_NUM_EXT_DMAC2, .drv_plat_data = &dmac2,.dma_cap = DMA_COPY_CAPS_ALL,
diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c index 1d08a1f..1ad989f 100644 --- a/src/platform/cannonlake/dma.c +++ b/src/platform/cannonlake/dma.c @@ -39,6 +39,9 @@ #include <stdint.h> #include <string.h>
+/* DMAC copy caps for GP LP DMA's*/ +#define DMA_GP_LP_CAPS 0x39
static struct dw_drv_plat_data dmac0 = { .chan[0] = { .class = 6, @@ -113,6 +116,7 @@ static struct dma dma[] = { { /* Low Power GP DMAC 0 */ .plat_data = { .id = DMA_GP_LP_DMAC0,
.base = LP_GP_DMA_BASE(0), .channels = 8, .irq = IRQ_EXT_LP_GPDMA0_LVL5(0, 0),.dma_cap = DMA_GP_LP_CAPS,
@@ -123,6 +127,7 @@ static struct dma dma[] = { { /* Low Power GP DMAC 1 */ .plat_data = { .id = DMA_GP_LP_DMAC1,
.base = LP_GP_DMA_BASE(1), .channels = 8, .irq = IRQ_EXT_LP_GPDMA1_LVL5(0, 0),.dma_cap = DMA_GP_LP_CAPS,
@@ -133,6 +138,7 @@ static struct dma dma[] = { { /* Host In DMAC */ .plat_data = { .id = DMA_HOST_IN_DMAC,
.base = GTW_HOST_IN_STREAM_BASE(0), .channels = 7, .irq = IRQ_EXT_HOST_DMA_IN_LVL3(0, 0),.dma_cap = (1 << DMA_DIR_LMEM_TO_HMEM),
@@ -143,6 +149,7 @@ static struct dma dma[] = { { /* Host out DMAC */ .plat_data = { .id = DMA_HOST_OUT_DMAC,
.base = GTW_HOST_OUT_STREAM_BASE(0), .channels = 9, .irq = IRQ_EXT_HOST_DMA_OUT_LVL3(0, 0),.dma_cap = (1 << DMA_DIR_HMEM_TO_LMEM),
@@ -153,6 +160,7 @@ static struct dma dma[] = { { /* Link In DMAC */ .plat_data = { .id = DMA_LINK_IN_DMAC,
.base = GTW_LINK_IN_STREAM_BASE(0), .channels = 9, .irq = IRQ_EXT_LINK_DMA_IN_LVL4(0, 0),.dma_cap = (1 << DMA_DIR_MEM_TO_LINK),
@@ -163,6 +171,7 @@ static struct dma dma[] = { { /* Link out DMAC */ .plat_data = { .id = DMA_LINK_OUT_DMAC,
.base = GTW_LINK_OUT_STREAM_BASE(0), .channels = 7, .irq = IRQ_EXT_LINK_DMA_OUT_LVL4(0, 0),.dma_cap = (1 << DMA_DIR_LINK_TO_MEM),
diff --git a/src/platform/haswell/dma.c b/src/platform/haswell/dma.c index 1bd424e..ec48bc8 100644 --- a/src/platform/haswell/dma.c +++ b/src/platform/haswell/dma.c @@ -110,6 +110,7 @@ static struct dma dma[] = { { .plat_data = { .base = DMA0_BASE,
.irq = IRQ_NUM_EXT_DMAC0, .drv_plat_data = &dmac0, },.dma_cap = (1 << DMA_DIR_MEM_TO_MEM),
@@ -118,6 +119,7 @@ static struct dma dma[] = { { .plat_data = { .base = DMA1_BASE,
.irq = IRQ_NUM_EXT_DMAC1, .drv_plat_data = &dmac1, },.dma_cap = DMA_COPY_CAPS_ALL,
On Thu, 2018-06-07 at 12:46 +0100, Liam Girdwood wrote:
On Wed, 2018-06-06 at 16:08 -0700, Ranjani Sridharan wrote:
Add the link_to_mem and mem_to_link dma copy directions to the dma_copy_dir enum.
And define the DMAC copy capabilities for all platform DMAC's
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com
src/include/sof/dma.h | 10 +++++++++- src/platform/apollolake/dma.c | 10 ++++++++++ src/platform/baytrail/dma.c | 3 +++ src/platform/cannonlake/dma.c | 9 +++++++++ src/platform/haswell/dma.c | 2 ++ 5 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/src/include/sof/dma.h b/src/include/sof/dma.h index 80ca880..142aafc 100644 --- a/src/include/sof/dma.h +++ b/src/include/sof/dma.h @@ -46,13 +46,20 @@ enum dma_copy_dir { DMA_DIR_MEM_TO_DEV, DMA_DIR_DEV_TO_MEM, DMA_DIR_DEV_TO_DEV,
- DMA_DIR_MEM_TO_LINK,
The should be the same as MEM_TO_DEV ?
The intention for adding this was to distinguish between Link DMA and GP DMA.
As I understand GP DMA is used for MEM_TO_DEV ot DEV_TO_MEM for SSP/DMIC's. If MEM_TO_LINK is the same as MEM_TO_DEV, could you please give me a suggestion on how else to differentiate the Link DMA from GP DMA?
- DMA_DIR_LINK_TO_MEM,
DEV_TO_MEM
Probably good to define a bit mask of all DMAC capabilities, this would include permitted directions.
};
+/*
- DMAC copy capabilities with support for all directions
- enumerated by dma_copy_dir
- */
+#define DMA_COPY_CAPS_ALL 0xFF
We cant mix an enum with a bitmask.
/* DMA IRQ types */ #define DMA_IRQ_TYPE_BLOCK (1 << 0) #define DMA_IRQ_TYPE_LLIST (1 << 1)
/* We will use this macro in cb handler to inform dma that
- we need to stop the reload for special purpose
*/ @@ -118,6 +125,7 @@ struct dma_ops { /* DMA platform data */ struct dma_plat_data { uint32_t id;
- int dma_cap; /* copy capabilities supported by DMAC*/
bitmask should be unsigned
uint32_t base; uint32_t channels; uint32_t irq; diff --git a/src/platform/apollolake/dma.c b/src/platform/apollolake/dma.c index da413e3..f5e492c 100644 --- a/src/platform/apollolake/dma.c +++ b/src/platform/apollolake/dma.c @@ -38,6 +38,9 @@ #include <stdint.h> #include <string.h>
+/* DMAC copy caps for GP LP DMA's*/ +#define DMA_GP_LP_CAPS 0x39
Magic number 0x39 ?
static struct dw_drv_plat_data dmac0 = { .chan[0] = { .class = 1, @@ -112,6 +115,7 @@ static struct dma dma[] = { { /* Low Power GP DMAC 0 */ .plat_data = { .id = DMA_GP_LP_DMAC0,
.dma_cap = DMA_GP_LP_CAPS,
I'd expect to see caps like DMA_CAPS_LP | DMA_CAPS_MEM_TO_DEV | DMA_CAPS_DMIC etc,
.base = LP_GP_DMA_BASE(0), .channels = 8, .irq = IRQ_EXT_LP_GPDMA0_LVL5(0,
0), @@ -122,6 +126,8 @@ static struct dma dma[] = { { /* Low Power GP DMAC 1 */ .plat_data = { .id = DMA_GP_LP_DMAC1,
.dma_cap = DMA_GP_LP_CAPS,
.base = LP_GP_DMA_BASE(1), .channels = 8, .irq = IRQ_EXT_LP_GPDMA1_LVL5(0,.dma_cap = (1 << DMA_DIR_LMEM_TO_HMEM),
0), @@ -132,6 +138,7 @@ static struct dma dma[] = { { /* Host In DMAC */ .plat_data = { .id = DMA_HOST_IN_DMAC,
.base = GTW_HOST_IN_STREAM_BASE(0), .channels = 7, .irq = IRQ_EXT_HOST_DMA_IN_LVL3(0,.dma_cap = (1 << DMA_DIR_LMEM_TO_HMEM),
0), @@ -142,6 +149,7 @@ static struct dma dma[] = { { /* Host out DMAC */ .plat_data = { .id = DMA_HOST_OUT_DMAC,
.base =.dma_cap = (1 << DMA_DIR_HMEM_TO_LMEM),
GTW_HOST_OUT_STREAM_BASE(0), .channels = 6, .irq = IRQ_EXT_HOST_DMA_OUT_LVL3(0, 0), @@ -152,6 +160,7 @@ static struct dma dma[] = { { /* Link In DMAC */ .plat_data = { .id = DMA_LINK_IN_DMAC,
.base = GTW_LINK_IN_STREAM_BASE(0), .channels = 8, .irq = IRQ_EXT_LINK_DMA_IN_LVL4(0,.dma_cap = (1 << DMA_DIR_MEM_TO_LINK),
0), @@ -162,6 +171,7 @@ static struct dma dma[] = { { /* Link out DMAC */ .plat_data = { .id = DMA_LINK_OUT_DMAC,
.base =.dma_cap = (1 << DMA_DIR_LINK_TO_MEM),
GTW_LINK_OUT_STREAM_BASE(0), .channels = 8, .irq = IRQ_EXT_LINK_DMA_OUT_LVL4(0, 0), diff --git a/src/platform/baytrail/dma.c b/src/platform/baytrail/dma.c index 142b62a..95b836c 100644 --- a/src/platform/baytrail/dma.c +++ b/src/platform/baytrail/dma.c @@ -147,6 +147,7 @@ static struct dma dma[] = { { .plat_data = { .id = DMA_ID_DMAC0,
.base = DMA0_BASE, .irq = IRQ_NUM_EXT_DMAC0, .drv_plat_data = &dmac0,.dma_cap = DMA_COPY_CAPS_ALL,
@@ -156,6 +157,7 @@ static struct dma dma[] = { { .plat_data = { .id = DMA_ID_DMAC1,
.base = DMA1_BASE, .irq = IRQ_NUM_EXT_DMAC1, .drv_plat_data = &dmac1,.dma_cap = DMA_COPY_CAPS_ALL,
@@ -166,6 +168,7 @@ static struct dma dma[] = { { .plat_data = { .id = DMA_ID_DMAC2,
.base = DMA2_BASE, .irq = IRQ_NUM_EXT_DMAC2, .drv_plat_data = &dmac2,.dma_cap = DMA_COPY_CAPS_ALL,
diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c index 1d08a1f..1ad989f 100644 --- a/src/platform/cannonlake/dma.c +++ b/src/platform/cannonlake/dma.c @@ -39,6 +39,9 @@ #include <stdint.h> #include <string.h>
+/* DMAC copy caps for GP LP DMA's*/ +#define DMA_GP_LP_CAPS 0x39
static struct dw_drv_plat_data dmac0 = { .chan[0] = { .class = 6, @@ -113,6 +116,7 @@ static struct dma dma[] = { { /* Low Power GP DMAC 0 */ .plat_data = { .id = DMA_GP_LP_DMAC0,
.base = LP_GP_DMA_BASE(0), .channels = 8, .irq = IRQ_EXT_LP_GPDMA0_LVL5(0, 0),.dma_cap = DMA_GP_LP_CAPS,
@@ -123,6 +127,7 @@ static struct dma dma[] = { { /* Low Power GP DMAC 1 */ .plat_data = { .id = DMA_GP_LP_DMAC1,
.base = LP_GP_DMA_BASE(1), .channels = 8, .irq = IRQ_EXT_LP_GPDMA1_LVL5(0, 0),.dma_cap = DMA_GP_LP_CAPS,
@@ -133,6 +138,7 @@ static struct dma dma[] = { { /* Host In DMAC */ .plat_data = { .id = DMA_HOST_IN_DMAC,
.base = GTW_HOST_IN_STREAM_BASE(0), .channels = 7, .irq = IRQ_EXT_HOST_DMA_IN_LVL3(0, 0),.dma_cap = (1 << DMA_DIR_LMEM_TO_HMEM),
@@ -143,6 +149,7 @@ static struct dma dma[] = { { /* Host out DMAC */ .plat_data = { .id = DMA_HOST_OUT_DMAC,
.base =.dma_cap = (1 << DMA_DIR_HMEM_TO_LMEM),
GTW_HOST_OUT_STREAM_BASE(0), .channels = 9, .irq = IRQ_EXT_HOST_DMA_OUT_LVL3(0, 0), @@ -153,6 +160,7 @@ static struct dma dma[] = { { /* Link In DMAC */ .plat_data = { .id = DMA_LINK_IN_DMAC,
.base = GTW_LINK_IN_STREAM_BASE(0), .channels = 9, .irq = IRQ_EXT_LINK_DMA_IN_LVL4(0, 0),.dma_cap = (1 << DMA_DIR_MEM_TO_LINK),
@@ -163,6 +171,7 @@ static struct dma dma[] = { { /* Link out DMAC */ .plat_data = { .id = DMA_LINK_OUT_DMAC,
.base =.dma_cap = (1 << DMA_DIR_LINK_TO_MEM),
GTW_LINK_OUT_STREAM_BASE(0), .channels = 7, .irq = IRQ_EXT_LINK_DMA_OUT_LVL4(0, 0), diff --git a/src/platform/haswell/dma.c b/src/platform/haswell/dma.c index 1bd424e..ec48bc8 100644 --- a/src/platform/haswell/dma.c +++ b/src/platform/haswell/dma.c @@ -110,6 +110,7 @@ static struct dma dma[] = { { .plat_data = { .base = DMA0_BASE,
.irq = IRQ_NUM_EXT_DMAC0, .drv_plat_data = &dmac0, },.dma_cap = (1 << DMA_DIR_MEM_TO_MEM),
@@ -118,6 +119,7 @@ static struct dma dma[] = { { .plat_data = { .base = DMA1_BASE,
.irq = IRQ_NUM_EXT_DMAC1, .drv_plat_data = &dmac1, },.dma_cap = DMA_COPY_CAPS_ALL,
Sound-open-firmware mailing list Sound-open-firmware@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/sound-open-firmware
On Thu, 2018-06-07 at 09:34 -0700, Ranjani Sridharan wrote:
On Thu, 2018-06-07 at 12:46 +0100, Liam Girdwood wrote:
On Wed, 2018-06-06 at 16:08 -0700, Ranjani Sridharan wrote:
Add the link_to_mem and mem_to_link dma copy directions to the dma_copy_dir enum.
And define the DMAC copy capabilities for all platform DMAC's
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com
src/include/sof/dma.h | 10 +++++++++- src/platform/apollolake/dma.c | 10 ++++++++++ src/platform/baytrail/dma.c | 3 +++ src/platform/cannonlake/dma.c | 9 +++++++++ src/platform/haswell/dma.c | 2 ++ 5 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/src/include/sof/dma.h b/src/include/sof/dma.h index 80ca880..142aafc 100644 --- a/src/include/sof/dma.h +++ b/src/include/sof/dma.h @@ -46,13 +46,20 @@ enum dma_copy_dir { DMA_DIR_MEM_TO_DEV, DMA_DIR_DEV_TO_MEM, DMA_DIR_DEV_TO_DEV,
- DMA_DIR_MEM_TO_LINK,
The should be the same as MEM_TO_DEV ?
The intention for adding this was to distinguish between Link DMA and GP DMA.
As I understand GP DMA is used for MEM_TO_DEV ot DEV_TO_MEM for SSP/DMIC's. If MEM_TO_LINK is the same as MEM_TO_DEV, could you please give me a suggestion on how else to differentiate the Link DMA from GP DMA?
In capabilities and not direction alone. e.g CAPS_MEM_TO_DEV | CAPS_HDA_LINK
Liam
- DMA_DIR_LINK_TO_MEM,
DEV_TO_MEM
Probably good to define a bit mask of all DMAC capabilities, this would include permitted directions.
};
+/*
- DMAC copy capabilities with support for all directions
- enumerated by dma_copy_dir
- */
+#define DMA_COPY_CAPS_ALL 0xFF
We cant mix an enum with a bitmask.
/* DMA IRQ types */ #define DMA_IRQ_TYPE_BLOCK (1 << 0) #define DMA_IRQ_TYPE_LLIST (1 << 1)
/* We will use this macro in cb handler to inform dma that
- we need to stop the reload for special purpose
*/ @@ -118,6 +125,7 @@ struct dma_ops { /* DMA platform data */ struct dma_plat_data { uint32_t id;
- int dma_cap; /* copy capabilities supported by DMAC*/
bitmask should be unsigned
uint32_t base; uint32_t channels; uint32_t irq; diff --git a/src/platform/apollolake/dma.c b/src/platform/apollolake/dma.c index da413e3..f5e492c 100644 --- a/src/platform/apollolake/dma.c +++ b/src/platform/apollolake/dma.c @@ -38,6 +38,9 @@ #include <stdint.h> #include <string.h>
+/* DMAC copy caps for GP LP DMA's*/ +#define DMA_GP_LP_CAPS 0x39
Magic number 0x39 ?
static struct dw_drv_plat_data dmac0 = { .chan[0] = { .class = 1, @@ -112,6 +115,7 @@ static struct dma dma[] = { { /* Low Power GP DMAC 0 */ .plat_data = { .id = DMA_GP_LP_DMAC0,
.dma_cap = DMA_GP_LP_CAPS,
I'd expect to see caps like DMA_CAPS_LP | DMA_CAPS_MEM_TO_DEV | DMA_CAPS_DMIC etc,
.base = LP_GP_DMA_BASE(0), .channels = 8, .irq = IRQ_EXT_LP_GPDMA0_LVL5(0,
0), @@ -122,6 +126,8 @@ static struct dma dma[] = { { /* Low Power GP DMAC 1 */ .plat_data = { .id = DMA_GP_LP_DMAC1,
.dma_cap = DMA_GP_LP_CAPS,
.base = LP_GP_DMA_BASE(1), .channels = 8, .irq = IRQ_EXT_LP_GPDMA1_LVL5(0,.dma_cap = (1 << DMA_DIR_LMEM_TO_HMEM),
0), @@ -132,6 +138,7 @@ static struct dma dma[] = { { /* Host In DMAC */ .plat_data = { .id = DMA_HOST_IN_DMAC,
.base = GTW_HOST_IN_STREAM_BASE(0), .channels = 7, .irq = IRQ_EXT_HOST_DMA_IN_LVL3(0,.dma_cap = (1 << DMA_DIR_LMEM_TO_HMEM),
0), @@ -142,6 +149,7 @@ static struct dma dma[] = { { /* Host out DMAC */ .plat_data = { .id = DMA_HOST_OUT_DMAC,
.base =.dma_cap = (1 << DMA_DIR_HMEM_TO_LMEM),
GTW_HOST_OUT_STREAM_BASE(0), .channels = 6, .irq = IRQ_EXT_HOST_DMA_OUT_LVL3(0, 0), @@ -152,6 +160,7 @@ static struct dma dma[] = { { /* Link In DMAC */ .plat_data = { .id = DMA_LINK_IN_DMAC,
.base = GTW_LINK_IN_STREAM_BASE(0), .channels = 8, .irq = IRQ_EXT_LINK_DMA_IN_LVL4(0,.dma_cap = (1 << DMA_DIR_MEM_TO_LINK),
0), @@ -162,6 +171,7 @@ static struct dma dma[] = { { /* Link out DMAC */ .plat_data = { .id = DMA_LINK_OUT_DMAC,
.base =.dma_cap = (1 << DMA_DIR_LINK_TO_MEM),
GTW_LINK_OUT_STREAM_BASE(0), .channels = 8, .irq = IRQ_EXT_LINK_DMA_OUT_LVL4(0, 0), diff --git a/src/platform/baytrail/dma.c b/src/platform/baytrail/dma.c index 142b62a..95b836c 100644 --- a/src/platform/baytrail/dma.c +++ b/src/platform/baytrail/dma.c @@ -147,6 +147,7 @@ static struct dma dma[] = { { .plat_data = { .id = DMA_ID_DMAC0,
.base = DMA0_BASE, .irq = IRQ_NUM_EXT_DMAC0, .drv_plat_data = &dmac0,.dma_cap = DMA_COPY_CAPS_ALL,
@@ -156,6 +157,7 @@ static struct dma dma[] = { { .plat_data = { .id = DMA_ID_DMAC1,
.base = DMA1_BASE, .irq = IRQ_NUM_EXT_DMAC1, .drv_plat_data = &dmac1,.dma_cap = DMA_COPY_CAPS_ALL,
@@ -166,6 +168,7 @@ static struct dma dma[] = { { .plat_data = { .id = DMA_ID_DMAC2,
.base = DMA2_BASE, .irq = IRQ_NUM_EXT_DMAC2, .drv_plat_data = &dmac2,.dma_cap = DMA_COPY_CAPS_ALL,
diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c index 1d08a1f..1ad989f 100644 --- a/src/platform/cannonlake/dma.c +++ b/src/platform/cannonlake/dma.c @@ -39,6 +39,9 @@ #include <stdint.h> #include <string.h>
+/* DMAC copy caps for GP LP DMA's*/ +#define DMA_GP_LP_CAPS 0x39
static struct dw_drv_plat_data dmac0 = { .chan[0] = { .class = 6, @@ -113,6 +116,7 @@ static struct dma dma[] = { { /* Low Power GP DMAC 0 */ .plat_data = { .id = DMA_GP_LP_DMAC0,
.base = LP_GP_DMA_BASE(0), .channels = 8, .irq = IRQ_EXT_LP_GPDMA0_LVL5(0, 0),.dma_cap = DMA_GP_LP_CAPS,
@@ -123,6 +127,7 @@ static struct dma dma[] = { { /* Low Power GP DMAC 1 */ .plat_data = { .id = DMA_GP_LP_DMAC1,
.base = LP_GP_DMA_BASE(1), .channels = 8, .irq = IRQ_EXT_LP_GPDMA1_LVL5(0, 0),.dma_cap = DMA_GP_LP_CAPS,
@@ -133,6 +138,7 @@ static struct dma dma[] = { { /* Host In DMAC */ .plat_data = { .id = DMA_HOST_IN_DMAC,
.base = GTW_HOST_IN_STREAM_BASE(0), .channels = 7, .irq = IRQ_EXT_HOST_DMA_IN_LVL3(0, 0),.dma_cap = (1 << DMA_DIR_LMEM_TO_HMEM),
@@ -143,6 +149,7 @@ static struct dma dma[] = { { /* Host out DMAC */ .plat_data = { .id = DMA_HOST_OUT_DMAC,
.base =.dma_cap = (1 << DMA_DIR_HMEM_TO_LMEM),
GTW_HOST_OUT_STREAM_BASE(0), .channels = 9, .irq = IRQ_EXT_HOST_DMA_OUT_LVL3(0, 0), @@ -153,6 +160,7 @@ static struct dma dma[] = { { /* Link In DMAC */ .plat_data = { .id = DMA_LINK_IN_DMAC,
.base = GTW_LINK_IN_STREAM_BASE(0), .channels = 9, .irq = IRQ_EXT_LINK_DMA_IN_LVL4(0, 0),.dma_cap = (1 << DMA_DIR_MEM_TO_LINK),
@@ -163,6 +171,7 @@ static struct dma dma[] = { { /* Link out DMAC */ .plat_data = { .id = DMA_LINK_OUT_DMAC,
.base =.dma_cap = (1 << DMA_DIR_LINK_TO_MEM),
GTW_LINK_OUT_STREAM_BASE(0), .channels = 7, .irq = IRQ_EXT_LINK_DMA_OUT_LVL4(0, 0), diff --git a/src/platform/haswell/dma.c b/src/platform/haswell/dma.c index 1bd424e..ec48bc8 100644 --- a/src/platform/haswell/dma.c +++ b/src/platform/haswell/dma.c @@ -110,6 +110,7 @@ static struct dma dma[] = { { .plat_data = { .base = DMA0_BASE,
.irq = IRQ_NUM_EXT_DMAC0, .drv_plat_data = &dmac0, },.dma_cap = (1 << DMA_DIR_MEM_TO_MEM),
@@ -118,6 +119,7 @@ static struct dma dma[] = { { .plat_data = { .base = DMA1_BASE,
.irq = IRQ_NUM_EXT_DMAC1, .drv_plat_data = &dmac1, },.dma_cap = DMA_COPY_CAPS_ALL,
Sound-open-firmware mailing list Sound-open-firmware@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/sound-open-firmware
Sound-open-firmware mailing list Sound-open-firmware@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/sound-open-firmware
This patch adds the num_channels_busy member to the dma structure that stores the number of channels busy at any given time. This will be useful in providing basic and primitive QoS while allocating DMAC for various users.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/drivers/dw-dma.c | 9 +++++++++ src/drivers/hda-dma.c | 9 +++++++++ src/include/sof/dma.h | 1 + 3 files changed, 19 insertions(+)
diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c index c064330..5c43656 100644 --- a/src/drivers/dw-dma.c +++ b/src/drivers/dw-dma.c @@ -307,6 +307,9 @@ static int dw_dma_channel_get(struct dma *dma, int req_chan) if (p->chan[i].status != COMP_STATE_INIT) continue;
+ /* atomically increment num channels in use */ + __sync_fetch_and_add(&dma->num_channels_busy, 1); + p->chan[i].status = COMP_STATE_READY;
/* unmask block, transfer and error interrupts for channel */ @@ -357,6 +360,9 @@ static void dw_dma_channel_put(struct dma *dma, int channel) spin_lock_irq(&dma->lock, flags); dw_dma_channel_put_unlocked(dma, channel); spin_unlock_irq(&dma->lock, flags); + + /* atomically decrement num channels in use */ + __sync_fetch_and_sub(&dma->num_channels_busy, 1); }
static int dw_dma_start(struct dma *dma, int channel) @@ -1033,6 +1039,9 @@ static int dw_dma_probe(struct dma *dma) interrupt_enable(dma_int[i]->irq); }
+ /* initialize number of busy channels */ + dma->num_channels_busy = 0; + return 0; }
diff --git a/src/drivers/hda-dma.c b/src/drivers/hda-dma.c index 97ea0ef..731d4a9 100644 --- a/src/drivers/hda-dma.c +++ b/src/drivers/hda-dma.c @@ -145,6 +145,9 @@ static int hda_dma_channel_get(struct dma *dma, int channel) if (p->chan[channel].status == COMP_STATE_INIT) { p->chan[channel].status = COMP_STATE_READY;
+ /* atomically increment num channels in use */ + __sync_fetch_and_add(&dma->num_channels_busy, 1); + /* return channel */ spin_unlock_irq(&dma->lock, flags); return channel; @@ -163,6 +166,9 @@ static void hda_dma_channel_put_unlocked(struct dma *dma, int channel)
/* set new state */ p->chan[channel].status = COMP_STATE_INIT; + + /* atomically decrement num channels in use */ + __sync_fetch_and_sub(&dma->num_channels_busy, 1); }
/* channel must not be running when this is called */ @@ -400,6 +406,9 @@ static int hda_dma_probe(struct dma *dma) for (i = 0; i < HDA_DMA_MAX_CHANS; i++) hda_pdata->chan[i].status = COMP_STATE_INIT;
+ /* init number of busy channels */ + dma->num_channels_busy = 0; + return 0; }
diff --git a/src/include/sof/dma.h b/src/include/sof/dma.h index 142aafc..2ae4225 100644 --- a/src/include/sof/dma.h +++ b/src/include/sof/dma.h @@ -137,6 +137,7 @@ struct dma { struct dma_plat_data plat_data; spinlock_t lock; const struct dma_ops *ops; + uint32_t num_channels_busy; /* number of channels in use */ void *private; };
On Wed, 2018-06-06 at 16:09 -0700, Ranjani Sridharan wrote:
/* atomically increment num channels in use */
__sync_fetch_and_add(&dma->num_channels_busy, 1);
Cant see where this is defined so this wont compile ? Please see arch/atomic.h for atomic arithmetic.
Liam
On Thu, 2018-06-07 at 12:48 +0100, Liam Girdwood wrote:
On Wed, 2018-06-06 at 16:09 -0700, Ranjani Sridharan wrote:
/* atomically increment num channels in use */
__sync_fetch_and_add(&dma->num_channels_busy, 1);
Cant see where this is defined so this wont compile ? Please see arch/atomic.h for atomic arithmetic.
I have a question here:
Can I cast a uint32_t * to atomic_t * and then pass it to the atomic_add() function? Will it still be a atomic operation? Thanks, Ranjani
Liam
On Fri, 2018-06-08 at 00:51 -0700, Ranjani Sridharan wrote:
/* atomically increment num channels in use */
__sync_fetch_and_add(&dma->num_channels_busy, 1);
Cant see where this is defined so this wont compile ? Please see arch/atomic.h for atomic arithmetic.
I have a question here:
Can I cast a uint32_t * to atomic_t * and then pass it to the atomic_add() function? Will it still be a atomic operation?
Why do you need to do this ? atomic_t can be used like a uint32_t within your code already.
Liam
On Fri, 2018-06-08 at 09:32 +0100, Liam Girdwood wrote:
On Fri, 2018-06-08 at 00:51 -0700, Ranjani Sridharan wrote:
/* atomically increment num channels in use */
__sync_fetch_and_add(&dma->num_channels_busy,
1);
Cant see where this is defined so this wont compile ? Please see arch/atomic.h for atomic arithmetic.
I have a question here:
Can I cast a uint32_t * to atomic_t * and then pass it to the atomic_add() function? Will it still be a atomic operation?
Why do you need to do this ? atomic_t can be used like a uint32_t within your code already.
OK, thats what I thought too but just wanted to confirm. Thanks!
Liam _______________________________________________ Sound-open-firmware mailing list Sound-open-firmware@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/sound-open-firmware
This patch adds a couple of API's to retrieve platform DMAC information.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/include/sof/dma.h | 4 ++++ src/platform/apollolake/dma.c | 10 ++++++++++ src/platform/baytrail/dma.c | 10 ++++++++++ src/platform/cannonlake/dma.c | 10 ++++++++++ src/platform/haswell/dma.c | 10 ++++++++++ 5 files changed, 44 insertions(+)
diff --git a/src/include/sof/dma.h b/src/include/sof/dma.h index 2ae4225..8a6e645 100644 --- a/src/include/sof/dma.h +++ b/src/include/sof/dma.h @@ -149,6 +149,10 @@ struct dma_int {
struct dma *dma_get(int dmac_id);
+struct dma *get_platform_dmacs(void); + +int get_platform_num_dmacs(void); + /* initialize all platform DMAC's */ void dmac_init(void);
diff --git a/src/platform/apollolake/dma.c b/src/platform/apollolake/dma.c index f5e492c..396ad74 100644 --- a/src/platform/apollolake/dma.c +++ b/src/platform/apollolake/dma.c @@ -203,3 +203,13 @@ void dmac_init(void) trace_error_value(ret); } } + +struct dma *get_platform_dmacs(void) +{ + return &dma[0]; +} + +int get_platform_num_dmacs(void) +{ + return ARRAY_SIZE(dma); +} diff --git a/src/platform/baytrail/dma.c b/src/platform/baytrail/dma.c index 95b836c..b05eaa6 100644 --- a/src/platform/baytrail/dma.c +++ b/src/platform/baytrail/dma.c @@ -201,3 +201,13 @@ void dmac_init(void) trace_error_value(ret); } } + +struct dma *get_platform_dmacs(void) +{ + return &dma[0]; +} + +int get_platform_num_dmacs(void) +{ + return ARRAY_SIZE(dma); +} diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c index 1ad989f..49e2b71 100644 --- a/src/platform/cannonlake/dma.c +++ b/src/platform/cannonlake/dma.c @@ -203,3 +203,13 @@ void dmac_init(void) trace_error_value(ret); } } + +struct dma *get_platform_dmacs(void) +{ + return &dma[0]; +} + +int get_platform_num_dmacs(void) +{ + return ARRAY_SIZE(dma); +} diff --git a/src/platform/haswell/dma.c b/src/platform/haswell/dma.c index ec48bc8..09f5f6b 100644 --- a/src/platform/haswell/dma.c +++ b/src/platform/haswell/dma.c @@ -156,3 +156,13 @@ void dmac_init(void) io_reg_update_bits(SHIM_BASE + SHIM_IMRD, SHIM_IMRD_DMAC1, 0); } + +struct dma *get_platform_dmacs(void) +{ + return &dma[0]; +} + +int get_platform_num_dmacs(void) +{ + return ARRAY_SIZE(dma); +}
On Wed, 2018-06-06 at 16:09 -0700, Ranjani Sridharan wrote:
This patch adds a couple of API's to retrieve platform DMAC information.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com
src/include/sof/dma.h | 4 ++++ src/platform/apollolake/dma.c | 10 ++++++++++ src/platform/baytrail/dma.c | 10 ++++++++++ src/platform/cannonlake/dma.c | 10 ++++++++++ src/platform/haswell/dma.c | 10 ++++++++++ 5 files changed, 44 insertions(+)
diff --git a/src/include/sof/dma.h b/src/include/sof/dma.h index 2ae4225..8a6e645 100644 --- a/src/include/sof/dma.h +++ b/src/include/sof/dma.h @@ -149,6 +149,10 @@ struct dma_int {
struct dma *dma_get(int dmac_id);
+struct dma *get_platform_dmacs(void);
+int get_platform_num_dmacs(void);
/* initialize all platform DMAC's */ void dmac_init(void);
diff --git a/src/platform/apollolake/dma.c b/src/platform/apollolake/dma.c index f5e492c..396ad74 100644 --- a/src/platform/apollolake/dma.c +++ b/src/platform/apollolake/dma.c @@ -203,3 +203,13 @@ void dmac_init(void) trace_error_value(ret); } }
+struct dma *get_platform_dmacs(void) +{
- return &dma[0];
+}
+int get_platform_num_dmacs(void) +{
- return ARRAY_SIZE(dma);
+}
Can we just export struct dma *platform_dmac[PLATFORM_NUM_DMACS]; in platform/dma.h ?
diff --git a/src/platform/baytrail/dma.c b/src/platform/baytrail/dma.c index 95b836c..b05eaa6 100644 --- a/src/platform/baytrail/dma.c +++ b/src/platform/baytrail/dma.c @@ -201,3 +201,13 @@ void dmac_init(void) trace_error_value(ret); } }
+struct dma *get_platform_dmacs(void) +{
- return &dma[0];
+}
+int get_platform_num_dmacs(void) +{
- return ARRAY_SIZE(dma);
+} diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c index 1ad989f..49e2b71 100644 --- a/src/platform/cannonlake/dma.c +++ b/src/platform/cannonlake/dma.c @@ -203,3 +203,13 @@ void dmac_init(void) trace_error_value(ret); } }
+struct dma *get_platform_dmacs(void) +{
- return &dma[0];
+}
+int get_platform_num_dmacs(void) +{
- return ARRAY_SIZE(dma);
+} diff --git a/src/platform/haswell/dma.c b/src/platform/haswell/dma.c index ec48bc8..09f5f6b 100644 --- a/src/platform/haswell/dma.c +++ b/src/platform/haswell/dma.c @@ -156,3 +156,13 @@ void dmac_init(void) io_reg_update_bits(SHIM_BASE + SHIM_IMRD, SHIM_IMRD_DMAC1, 0); }
+struct dma *get_platform_dmacs(void) +{
- return &dma[0];
+}
+int get_platform_num_dmacs(void) +{
- return ARRAY_SIZE(dma);
+}
This patch introduces a new API for procuring the DMAC that takes into account the dma copy capability and access control requested by the user. With this new API DMAC's are allocated depending on the number of channels that are currently draining, thereby providing a primitive level of QoS and preventing DMAC overuse.
This patch also consolidates the dma_get() API into a common file.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/arch/xtensa/Makefile.am | 1 + src/include/sof/dma.h | 6 ++- src/lib/Makefile.am | 11 +++++ src/lib/dma.c | 84 +++++++++++++++++++++++++++++++++++ src/platform/apollolake/dma.c | 12 ----- src/platform/baytrail/dma.c | 12 ----- src/platform/cannonlake/dma.c | 12 ----- src/platform/haswell/dma.c | 12 ----- 8 files changed, 101 insertions(+), 49 deletions(-) create mode 100644 src/lib/dma.c
diff --git a/src/arch/xtensa/Makefile.am b/src/arch/xtensa/Makefile.am index 309635c..2712031 100644 --- a/src/arch/xtensa/Makefile.am +++ b/src/arch/xtensa/Makefile.am @@ -58,6 +58,7 @@ sof_LDADD = \ ../../lib/libcore.a \ ../../platform/$(PLATFORM)/libplatform.a \ ../../ipc/libsof_ipc.a \ + ../../lib/libdma.a \ ../../audio/libaudio.a \ ../../drivers/libdrivers.a \ ../../math/libsof_math.a \ diff --git a/src/include/sof/dma.h b/src/include/sof/dma.h index 8a6e645..e8a64e7 100644 --- a/src/include/sof/dma.h +++ b/src/include/sof/dma.h @@ -56,6 +56,10 @@ enum dma_copy_dir { */ #define DMA_COPY_CAPS_ALL 0xFF
+/* DMAC flags */ +#define DMAC_FLAGS_SHARED 0 +#define DMAC_FLAGS_EXCLUSIVE (1 << 0) + /* DMA IRQ types */ #define DMA_IRQ_TYPE_BLOCK (1 << 0) #define DMA_IRQ_TYPE_LLIST (1 << 1) @@ -147,7 +151,7 @@ struct dma_int { uint32_t irq; };
-struct dma *dma_get(int dmac_id); +struct dma *dma_get(int dma_cap, int flags);
struct dma *get_platform_dmacs(void);
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 825bfbd..28f8f6f 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -16,3 +16,14 @@ libcore_a_CFLAGS = \ $(ARCH_INCDIR) \ $(SOF_INCDIR) \ $(PLATFORM_INCDIR) + +noinst_LIBRARIES = libdma.a + +libdma_a_SOURCES = \ + dma.c + +libdma_a_CFLAGS = \ + $(ARCH_CFLAGS) \ + $(ARCH_INCDIR) \ + $(SOF_INCDIR) \ + $(PLATFORM_INCDIR) diff --git a/src/lib/dma.c b/src/lib/dma.c new file mode 100644 index 0000000..c72dd2b --- /dev/null +++ b/src/lib/dma.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Intel Corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Author: Ranjani Sridharan ranjani.sridharan@linux.intel.com + */ + +#include <sof/dma.h> +#include <sof/trace.h> + +/* + * get DMAC based on user type, copy dir and flags + * For BYT/CHT, ignore the dmac_type and copy_dir arguments + * "flags" is used to set the type of access requested + * (ex: shared/exclusive access) + */ +struct dma *dma_get(int dma_cap, int flags) +{ + struct dma *dma = get_platform_dmacs(); + int i, ch_count; + int min_ch_count = INT32_MAX; + int dma_index = -1; + + for (i = 0; i < get_platform_num_dmacs(); i++) { + + /* skip if this DMAC does not support the requested cap */ + if ((dma[i].plat_data.dma_cap & dma_cap) == 0) + continue; + + /* if exclusive access is requested */ + if (flags & DMAC_FLAGS_EXCLUSIVE) { + + /* ret DMA with no channel in use */ + if (!dma[i].num_channels_busy) + return &dma[i]; + } else { + + /* + * for shared access requests, return DMAC + * with the least number of channels in use + */ + + /* get number of channels in use for this DMAC*/ + ch_count = dma[i].num_channels_busy; + + /* Use this DMAC if its channel count is lower */ + if (ch_count < min_ch_count) { + dma_index = i; + min_ch_count = ch_count; + } + } + } + + /* return DMAC */ + if (dma_index >= 0) { + tracev_value(dma[dma_index].plat_data.id); + return &dma[dma_index]; + } + + return NULL; +} diff --git a/src/platform/apollolake/dma.c b/src/platform/apollolake/dma.c index 396ad74..07aaad9 100644 --- a/src/platform/apollolake/dma.c +++ b/src/platform/apollolake/dma.c @@ -180,18 +180,6 @@ static struct dma dma[] = { .ops = &hda_link_dma_ops, },};
-struct dma *dma_get(int dmac_id) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(dma); i++) { - if (dma[i].plat_data.id == dmac_id) - return &dma[i]; - } - - return NULL; -} - /* Initialize all platform DMAC's */ void dmac_init(void) { diff --git a/src/platform/baytrail/dma.c b/src/platform/baytrail/dma.c index b05eaa6..30d2304 100644 --- a/src/platform/baytrail/dma.c +++ b/src/platform/baytrail/dma.c @@ -178,18 +178,6 @@ static struct dma dma[] = { #endif };
-struct dma *dma_get(int dmac_id) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(dma); i++) { - if (dma[i].plat_data.id == dmac_id) - return &dma[i]; - } - - return NULL; -} - /* Initialize all platform DMAC's */ void dmac_init(void) { diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c index 49e2b71..21686db 100644 --- a/src/platform/cannonlake/dma.c +++ b/src/platform/cannonlake/dma.c @@ -180,18 +180,6 @@ static struct dma dma[] = { .ops = &hda_link_dma_ops, },};
-struct dma *dma_get(int dmac_id) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(dma); i++) { - if (dma[i].plat_data.id == dmac_id) - return &dma[i]; - } - - return NULL; -} - /* Initialize all platform DMAC's */ void dmac_init(void) { diff --git a/src/platform/haswell/dma.c b/src/platform/haswell/dma.c index 09f5f6b..ca7200e 100644 --- a/src/platform/haswell/dma.c +++ b/src/platform/haswell/dma.c @@ -126,18 +126,6 @@ static struct dma dma[] = { .ops = &dw_dma_ops, },};
-struct dma *dma_get(int dmac_id) -{ - switch (dmac_id) { - case DMA_ID_DMAC0: - return &dma[0]; - case DMA_ID_DMAC1: - return &dma[1]; - default: - return NULL; - } -} - /* Initialize all platform DMAC's */ void dmac_init(void) {
Use the new dma_get() API to procure DMAC's for all the users.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/audio/dai.c | 3 ++- src/audio/host.c | 20 ++++++++++++-------- src/host/common_test.c | 2 +- src/ipc/apl-ipc.c | 4 ++-- src/ipc/byt-ipc.c | 4 ++-- src/ipc/cnl-ipc.c | 4 ++-- src/ipc/dma-copy.c | 3 ++- src/ipc/hsw-ipc.c | 4 ++-- 8 files changed, 25 insertions(+), 19 deletions(-)
diff --git a/src/audio/dai.c b/src/audio/dai.c index 1eeecd2..b6e984d 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -201,7 +201,8 @@ static struct comp_dev *dai_new(struct sof_ipc_comp *comp) goto error; }
- dd->dma = dma_get(ipc_dai->dmac_id); + /* request DMAC with DMA_DIR_MEM_TO_DEV cap and shared access flag */ + dd->dma = dma_get((1 << DMA_DIR_MEM_TO_DEV), DMAC_FLAGS_SHARED); if (dd->dma == NULL) { trace_dai_error("eDd"); goto error; diff --git a/src/audio/host.c b/src/audio/host.c index c0f4e1b..2a3ab00 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -529,14 +529,18 @@ static struct comp_dev *host_new(struct sof_ipc_comp *comp)
comp_set_drvdata(dev, hd);
-#if !defined CONFIG_DMA_GW - hd->dma = dma_get(ipc_host->dmac_id); -#else - if (ipc_host->direction == SOF_IPC_STREAM_PLAYBACK) - hd->dma = dma_get(DMA_HOST_OUT_DMAC); - else - hd->dma = dma_get(DMA_HOST_IN_DMAC); -#endif + if (ipc_host->direction == SOF_IPC_STREAM_PLAYBACK) { + + /* get DMAC with DMA_DIR_HMEM_TO_LMEM cap & shared flag */ + hd->dma = dma_get((1 << DMA_DIR_HMEM_TO_LMEM), + DMAC_FLAGS_SHARED); + } else { + + /* get DMAC with DMA_DIR_LMEM_TO_HMEM cap & shared flag */ + hd->dma = dma_get((1 << DMA_DIR_LMEM_TO_HMEM), + DMAC_FLAGS_SHARED); + } + if (hd->dma == NULL) { trace_host_error("eDM"); goto error; diff --git a/src/host/common_test.c b/src/host/common_test.c index e286883..ef91577 100644 --- a/src/host/common_test.c +++ b/src/host/common_test.c @@ -200,7 +200,7 @@ struct dai *dai_get(uint32_t type, uint32_t index) return NULL; }
-struct dma *dma_get(int dmac_id) +struct dma *dma_get(int dma_cap, int flags) { return NULL; } diff --git a/src/ipc/apl-ipc.c b/src/ipc/apl-ipc.c index 78291d0..f08fc80 100644 --- a/src/ipc/apl-ipc.c +++ b/src/ipc/apl-ipc.c @@ -198,8 +198,8 @@ int platform_ipc_init(struct ipc *ipc) if (iipc->page_table) bzero(iipc->page_table, HOST_PAGE_SIZE);
- /* dma */ - iipc->dmac = dma_get(DMA_GP_LP_DMAC0); + /* request DMAC with DMA_DIR_HMEM_TO_LMEM and shared access flag */ + iipc->dmac = dma_get((1 << DMA_DIR_HMEM_TO_LMEM), DMAC_FLAGS_SHARED);
/* PM */ iipc->pm_prepare_D3 = 0; diff --git a/src/ipc/byt-ipc.c b/src/ipc/byt-ipc.c index 87e7949..f794f5d 100644 --- a/src/ipc/byt-ipc.c +++ b/src/ipc/byt-ipc.c @@ -225,8 +225,8 @@ int platform_ipc_init(struct ipc *ipc) if (iipc->page_table) bzero(iipc->page_table, PLATFORM_PAGE_TABLE_SIZE);
- /* dma */ - iipc->dmac = dma_get(DMA_ID_DMAC0); + /* request DMAC with DMA_DIR_HMEM_TO_LMEM and shared access flag */ + iipc->dmac = dma_get((1 << DMA_DIR_HMEM_TO_LMEM), DMAC_FLAGS_SHARED);
/* PM */ iipc->pm_prepare_D3 = 0; diff --git a/src/ipc/cnl-ipc.c b/src/ipc/cnl-ipc.c index ba65164..c92dd1f 100644 --- a/src/ipc/cnl-ipc.c +++ b/src/ipc/cnl-ipc.c @@ -198,8 +198,8 @@ int platform_ipc_init(struct ipc *ipc) if (iipc->page_table) bzero(iipc->page_table, HOST_PAGE_SIZE);
- /* dma */ - iipc->dmac = dma_get(DMA_GP_LP_DMAC0); + /* request DMAC with DMA_DIR_HMEM_TO_LMEM and shared access flag */ + iipc->dmac = dma_get((1 << DMA_DIR_HMEM_TO_LMEM), DMAC_FLAGS_SHARED);
/* PM */ iipc->pm_prepare_D3 = 0; diff --git a/src/ipc/dma-copy.c b/src/ipc/dma-copy.c index be72eb8..b801448 100644 --- a/src/ipc/dma-copy.c +++ b/src/ipc/dma-copy.c @@ -375,7 +375,8 @@ int dma_copy_from_host_nowait(struct dma_copy *dc, struct dma_sg_config *host_sg
int dma_copy_new(struct dma_copy *dc, int dmac) { - dc->dmac = dma_get(dmac); + /* request DMAC with DMA_DIR_LMEM_TO_HMEM and shared access flag */ + dc->dmac = dma_get((1 << DMA_DIR_LMEM_TO_HMEM), DMAC_FLAGS_SHARED); if (dc->dmac == NULL) { trace_dma_error("ec0"); return -ENODEV; diff --git a/src/ipc/hsw-ipc.c b/src/ipc/hsw-ipc.c index aa4d9e1..a2a169c 100644 --- a/src/ipc/hsw-ipc.c +++ b/src/ipc/hsw-ipc.c @@ -221,8 +221,8 @@ int platform_ipc_init(struct ipc *ipc) if (iipc->page_table) bzero(iipc->page_table, PLATFORM_PAGE_TABLE_SIZE);
- /* dma */ - iipc->dmac = dma_get(DMA_ID_DMAC1); + /* request DMAC with DMA_DIR_HMEM_TO_LMEM and shared access flag */ + iipc->dmac = dma_get((1 << DMA_DIR_HMEM_TO_LMEM), DMAC_FLAGS_SHARED);
/* PM */ iipc->pm_prepare_D3 = 0;
dma_copy_context() does not need DMAC ID argument anymore.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/include/sof/dma.h | 2 +- src/ipc/dma-copy.c | 2 +- src/lib/dma-trace.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/include/sof/dma.h b/src/include/sof/dma.h index e8a64e7..d76434c 100644 --- a/src/include/sof/dma.h +++ b/src/include/sof/dma.h @@ -278,7 +278,7 @@ struct dma_copy { };
/* init dma copy context */ -int dma_copy_new(struct dma_copy *dc, int dmac); +int dma_copy_new(struct dma_copy *dc);
/* free dma copy context resources */ static inline void dma_copy_free(struct dma_copy *dc) diff --git a/src/ipc/dma-copy.c b/src/ipc/dma-copy.c index b801448..9d40913 100644 --- a/src/ipc/dma-copy.c +++ b/src/ipc/dma-copy.c @@ -373,7 +373,7 @@ int dma_copy_from_host_nowait(struct dma_copy *dc, struct dma_sg_config *host_sg return local_sg_elem.size; }
-int dma_copy_new(struct dma_copy *dc, int dmac) +int dma_copy_new(struct dma_copy *dc) { /* request DMAC with DMA_DIR_LMEM_TO_HMEM and shared access flag */ dc->dmac = dma_get((1 << DMA_DIR_LMEM_TO_HMEM), DMAC_FLAGS_SHARED); diff --git a/src/lib/dma-trace.c b/src/lib/dma-trace.c index 01a9925..cff9171 100644 --- a/src/lib/dma-trace.c +++ b/src/lib/dma-trace.c @@ -180,7 +180,7 @@ int dma_trace_init_complete(struct dma_trace_data *d) trace_buffer("dtn");
/* init DMA copy context */ - ret = dma_copy_new(&d->dc, PLATFORM_TRACE_DMAC); + ret = dma_copy_new(&d->dc); if (ret < 0) { trace_buffer_error("edm"); rfree(buffer->addr);
The new dma_get() API procures a DMAC based on copy capability requested. So no need to define the DMAC ID for trace DMA anymore.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/platform/apollolake/include/platform/platform.h | 3 --- src/platform/baytrail/include/platform/platform.h | 3 --- src/platform/cannonlake/include/platform/platform.h | 3 --- src/platform/haswell/include/platform/platform.h | 3 --- 4 files changed, 12 deletions(-)
diff --git a/src/platform/apollolake/include/platform/platform.h b/src/platform/apollolake/include/platform/platform.h index aefa9b2..e77bf6f 100644 --- a/src/platform/apollolake/include/platform/platform.h +++ b/src/platform/apollolake/include/platform/platform.h @@ -103,9 +103,6 @@ struct sof; */ #define DMA_TRACE_RESCHEDULE_TIME 5000
-/* DMAC used for trace DMA */ -#define PLATFORM_TRACE_DMAC DMA_HOST_IN_DMAC - /* DSP should be idle in this time frame */ #define PLATFORM_IDLE_TIME 750000
diff --git a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h index 6a7ebc9..8a7d0a3 100644 --- a/src/platform/baytrail/include/platform/platform.h +++ b/src/platform/baytrail/include/platform/platform.h @@ -95,9 +95,6 @@ struct sof; */ #define DMA_TRACE_RESCHEDULE_TIME 5000
-/* DMAC used for trace DMA */ -#define PLATFORM_TRACE_DMAC DMA_ID_DMAC0 - /* DSP should be idle in this time frame */ #define PLATFORM_IDLE_TIME 750000
diff --git a/src/platform/cannonlake/include/platform/platform.h b/src/platform/cannonlake/include/platform/platform.h index 35219d7..91c1f71 100644 --- a/src/platform/cannonlake/include/platform/platform.h +++ b/src/platform/cannonlake/include/platform/platform.h @@ -109,9 +109,6 @@ struct sof; */ #define DMA_TRACE_RESCHEDULE_TIME 5000
-/* DMAC used for trace DMA */ -#define PLATFORM_TRACE_DMAC DMA_HOST_IN_DMAC - /* DSP should be idle in this time frame */ #define PLATFORM_IDLE_TIME 750000
diff --git a/src/platform/haswell/include/platform/platform.h b/src/platform/haswell/include/platform/platform.h index d30f329..768a63c 100644 --- a/src/platform/haswell/include/platform/platform.h +++ b/src/platform/haswell/include/platform/platform.h @@ -94,9 +94,6 @@ struct sof; */ #define DMA_TRACE_RESCHEDULE_TIME 5000
-/* DMAC used for trace DMA */ -#define PLATFORM_TRACE_DMAC DMA_ID_DMAC1 - /* DSP should be idle in this time frame */ #define PLATFORM_IDLE_TIME 750000
participants (2)
-
Liam Girdwood
-
Ranjani Sridharan