[PATCH 00/18] edma/ASoC: dmaengine PCM for AM335x and AM447x

classic Classic list List threaded Threaded
31 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 00/18] edma/ASoC: dmaengine PCM for AM335x and AM447x

Peter Ujfalusi
Hi,

With this series AM335x and AM447x will use the dmaengine PCM for audio. The
daVinci devices will keep using the davinci-pcm for now since I do not have
means to test them but the code is written in a way that they can be switched
to use the edma-pcm easily (DA850/OMAP-L138 has been tested and audio was
working fine).

To be able to use the dmaengine PCM I needed to make changes to the edma code in
arch/arm/common/ and in drivers/dma/ :
Adding support for DMA pause/resume
Possibility to select non default event queue/TC for cyclic (audio) dma
channels: all devices using the eDMA via dmaengine was assigned to the default
EQ/TC (mmc, i2c, spi, etc, and audio). This is not optimal from system
performance point of view since sharing the same EQ/TC can cause latency spikes
for cyclic channels (long DMA transfers for MMC for example).

While debugging the edma to get things sorted out I noticed that the debug was
too verbose and the important information was hidden even when the we did not
asked for verbose dmaengine debug.
I have included some debug cleanups for the edma dmaengine driver also.

On the ASoC side: the series has been tested on AM335x and AM447x. I have report
that DA850/OMAP-L138 works with this series (which boots w/o DT).

Regards,
Peter
---
Peter Ujfalusi (18):
  platform_data: edma: Be precise with the paRAM struct
  dma: edma: Add support for DMA_PAUSE/RESUME operation
  dma: edma: Set DMA_CYCLIC capability flag
  arm: common: edma: Select event queue 1 as default when booted with DT
  arm: common: edma: Save the number of event queues/TCs
  arm: common: edma: API to request non default queue for a channel
  DMA: edma: Use different eventq for cyclic channels
  dma: edma: Implement device_slave_caps callback
  dma: edma: Simplify direction configuration in edma_config_pset()
  dma: edma: Reduce debug print verbosity for non verbose debugging
  dma: edma: Prefix debug prints where the text were identical in prep
    callbacks
  dma: edma: Add channel number to debug prints
  dma: edma: Print the direction value as well when it is not supported
  ASoC: davinci: Add edma dmaengine platform driver
  ASoC: davinci-mcasp: Use dmaengine based platform driver for
    AM335x/447x
  ASoC: davinci-mcasp: Provide correct filter_data for dmaengine for
    non-DT boot
  ASoC: davinci-mcasp: Assign the dma_data earlier in dai_probe callback
  ASoC: davinci-mcasp: Place constraint on the period size based on FIFO
    config

 arch/arm/common/edma.c             |  34 ++++++++++++-
 drivers/dma/edma.c                 |  92 ++++++++++++++++++++++++++--------
 include/linux/platform_data/edma.h |  20 ++++----
 sound/soc/davinci/Kconfig          |   1 +
 sound/soc/davinci/Makefile         |   2 +-
 sound/soc/davinci/davinci-mcasp.c  | 100 ++++++++++++++++++++++++++++++-------
 sound/soc/davinci/edma-pcm.c       |  77 ++++++++++++++++++++++++++++
 sound/soc/davinci/edma-pcm.h       |  26 ++++++++++
 8 files changed, 303 insertions(+), 49 deletions(-)
 create mode 100644 sound/soc/davinci/edma-pcm.c
 create mode 100644 sound/soc/davinci/edma-pcm.h

--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 01/18] platform_data: edma: Be precise with the paRAM struct

Peter Ujfalusi
The edmacc_param struct should follow the layout of the paRAM area in the
HW. Be explicit on the size of the fields (u32) and also mark the struct
as packed to avoid any padding on non 32bit architectures.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 include/linux/platform_data/edma.h | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h
index f50821cb64be..923f8a3e4ce0 100644
--- a/include/linux/platform_data/edma.h
+++ b/include/linux/platform_data/edma.h
@@ -43,15 +43,15 @@
 
 /* PaRAM slots are laid out like this */
 struct edmacc_param {
- unsigned int opt;
- unsigned int src;
- unsigned int a_b_cnt;
- unsigned int dst;
- unsigned int src_dst_bidx;
- unsigned int link_bcntrld;
- unsigned int src_dst_cidx;
- unsigned int ccnt;
-};
+ u32 opt;
+ u32 src;
+ u32 a_b_cnt;
+ u32 dst;
+ u32 src_dst_bidx;
+ u32 link_bcntrld;
+ u32 src_dst_cidx;
+ u32 ccnt;
+} __packed;
 
 /* fields in edmacc_param.opt */
 #define SAM BIT(0)
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 02/18] dma: edma: Add support for DMA_PAUSE/RESUME operation

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
Pause/Resume can be used by the audio stack when the stream is paused/resumed
The edma platform code has support for this and the legacy audio stack used
this.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 drivers/dma/edma.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index cd04eb7b182e..b54cd2dedde0 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -240,6 +240,26 @@ static int edma_slave_config(struct edma_chan *echan,
  return 0;
 }
 
+static int edma_dma_pause(struct edma_chan *echan)
+{
+ /* Pause/Resume only allowed with cyclic mode */
+ if (!echan->edesc->cyclic)
+ return -EINVAL;
+
+ edma_pause(echan->ch_num);
+ return 0;
+}
+
+static int edma_dma_resume(struct edma_chan *echan)
+{
+ /* Pause/Resume only allowed with cyclic mode */
+ if (!echan->edesc->cyclic)
+ return -EINVAL;
+
+ edma_resume(echan->ch_num);
+ return 0;
+}
+
 static int edma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
  unsigned long arg)
 {
@@ -255,6 +275,14 @@ static int edma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
  config = (struct dma_slave_config *)arg;
  ret = edma_slave_config(echan, config);
  break;
+ case DMA_PAUSE:
+ ret = edma_dma_pause(echan);
+ break;
+
+ case DMA_RESUME:
+ ret = edma_dma_resume(echan);
+ break;
+
  default:
  ret = -ENOSYS;
  }
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 03/18] dma: edma: Set DMA_CYCLIC capability flag

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
Indicate that the edma dmaengine driver has support for cyclic mode.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 arch/arm/common/edma.c | 1 +
 drivers/dma/edma.c     | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index 41bca32409fc..86a8b263278f 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -1574,6 +1574,7 @@ static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
  return ERR_PTR(ret);
 
  dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap);
+ dma_cap_set(DMA_CYCLIC, edma_filter_info.dma_cap);
  of_dma_controller_register(dev->of_node, of_dma_simple_xlate,
    &edma_filter_info);
 
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index b54cd2dedde0..86d6a3fb0d92 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -887,6 +887,7 @@ static int edma_probe(struct platform_device *pdev)
 
  dma_cap_zero(ecc->dma_slave.cap_mask);
  dma_cap_set(DMA_SLAVE, ecc->dma_slave.cap_mask);
+ dma_cap_set(DMA_CYCLIC, ecc->dma_slave.cap_mask);
 
  edma_dma_init(ecc, &ecc->dma_slave, &pdev->dev);
 
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 04/18] arm: common: edma: Select event queue 1 as default when booted with DT

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
Use the EVENTQ_1 for default and leave the EVENTQ_0 to be used by high
priority channels, like audio.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 arch/arm/common/edma.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index 86a8b263278f..19520e2519d9 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -1546,7 +1546,8 @@ static int edma_of_parse_dt(struct device *dev,
 
  pdata->queue_priority_mapping = queue_priority_map;
 
- pdata->default_queue = 0;
+ /* select queue 1 as default */
+ pdata->default_queue = EVENTQ_1;
 
  prop = of_find_property(node, "ti,edma-xbar-event-map", &sz);
  if (prop)
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 05/18] arm: common: edma: Save the number of event queues/TCs

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
For later use save the number of queues available for the CC.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 arch/arm/common/edma.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index 19520e2519d9..be267b2080be 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -1770,6 +1770,9 @@ static int edma_probe(struct platform_device *pdev)
  map_queue_tc(j, queue_tc_mapping[i][0],
  queue_tc_mapping[i][1]);
 
+ /* Save the number of TCs */
+ edma_cc[j]->num_tc = i;
+
  /* Event queue priority mapping */
  for (i = 0; queue_priority_mapping[i][0] != -1; i++)
  assign_priority_to_queue(j,
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 06/18] arm: common: edma: API to request non default queue for a channel

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
When using eDMA3 via dmaengine all dma channels will use the default queue.
Since during request time we do not have means to change this it need to be done
later, before the DMA has been started.
With the added function it is possible to move the channel to a non default
queue if it is possible, otherwise (when only one EQ/TC is available for the CC)
the default queue is going to be used.
For example: For optimal system performance the audio (cyclic) DMA should
be placed to a separate queue which is different than what the rest of the
system is using.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 arch/arm/common/edma.c             | 27 +++++++++++++++++++++++++++
 include/linux/platform_data/edma.h |  2 ++
 2 files changed, 29 insertions(+)

diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index be267b2080be..eaf6dd19f082 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -712,6 +712,33 @@ int edma_alloc_channel(int channel,
 }
 EXPORT_SYMBOL(edma_alloc_channel);
 
+/**
+ * edma_request_non_default_queue - try to map the channel to non default queue
+ * @channel: dma channel returned from edma_alloc_channel()
+ *
+ * For certain type of applications like audio it is preferred to not use the
+ * default event queue/tc to avoid eDMA caused latency.
+ *
+ * This function will iterate through the event queues available for the CC and
+ * picks the first EQ/TC which is not set as the default for the CC
+ */
+void edma_request_non_default_queue(int channel)
+{
+ unsigned ctlr = EDMA_CTLR(channel);
+ enum dma_event_q eventq_no = EVENTQ_DEFAULT;
+ int i;
+
+ for (i = 0; i < edma_cc[ctlr]->num_tc; i++) {
+ if (i != edma_cc[ctlr]->default_queue) {
+ eventq_no = i;
+ break;
+ }
+ }
+
+ channel = EDMA_CHAN_SLOT(channel);
+ map_dmach_queue(ctlr, channel, eventq_no);
+}
+EXPORT_SYMBOL(edma_request_non_default_queue);
 
 /**
  * edma_free_channel - deallocate DMA channel
diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h
index 923f8a3e4ce0..5d0a1b98f205 100644
--- a/include/linux/platform_data/edma.h
+++ b/include/linux/platform_data/edma.h
@@ -117,6 +117,8 @@ int edma_alloc_channel(int channel,
  void *data, enum dma_event_q);
 void edma_free_channel(unsigned channel);
 
+void edma_request_non_default_queue(int channel);
+
 /* alloc/free parameter RAM slots */
 int edma_alloc_slot(unsigned ctlr, int slot);
 void edma_free_slot(unsigned slot);
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 07/18] DMA: edma: Use different eventq for cyclic channels

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
To improve latency with cyclic DMA operation it is preferred to
use different eventq/tc than the default which is used by all
other drivers (mmc, spi, i2c, etc).
When preparing the cyclic dma ask for non default queue for the
channel which is going to be used with cyclic mode.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 drivers/dma/edma.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 86d6a3fb0d92..604c7c94c731 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -624,6 +624,9 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
  edesc->pset[i].opt |= TCINTEN;
  }
 
+ /* Use different eventq/tc for cyclic DMA to reduce latency */
+ edma_request_non_default_queue(echan->ch_num);
+
  return vchan_tx_prep(&echan->vchan, &edesc->vdesc, tx_flags);
 }
 
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 08/18] dma: edma: Implement device_slave_caps callback

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
With the callback implemented omap-dma can provide information to client
drivers regarding to supported address widths, directions, residue
granularity, etc.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 drivers/dma/edma.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 604c7c94c731..1877319379fc 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -851,6 +851,23 @@ static void __init edma_chan_init(struct edma_cc *ecc,
  }
 }
 
+#define EDMA_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
+
+static int edma_dma_device_slave_caps(struct dma_chan *dchan,
+      struct dma_slave_caps *caps)
+{
+ caps->src_addr_widths = EDMA_DMA_BUSWIDTHS;
+ caps->dstn_addr_widths = EDMA_DMA_BUSWIDTHS;
+ caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ caps->cmd_pause = true;
+ caps->cmd_terminate = true;
+ caps->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
+
+ return 0;
+}
+
 static void edma_dma_init(struct edma_cc *ecc, struct dma_device *dma,
   struct device *dev)
 {
@@ -861,6 +878,7 @@ static void edma_dma_init(struct edma_cc *ecc, struct dma_device *dma,
  dma->device_issue_pending = edma_issue_pending;
  dma->device_tx_status = edma_tx_status;
  dma->device_control = edma_control;
+ dma->device_slave_caps = edma_dma_device_slave_caps;
  dma->dev = dev;
 
  INIT_LIST_HEAD(&dma->channels);
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 09/18] dma: edma: Simplify direction configuration in edma_config_pset()

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
We only support DEV_TO_MEM or MEM_TO_DEV directions with edma driver and the
check for the direction has been already done in the function calling
edma_config_pset().
The error reporting is redundant and also the "else if ()" can be removed.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 drivers/dma/edma.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 1877319379fc..e4f4a0cef58c 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -368,14 +368,12 @@ static int edma_config_pset(struct dma_chan *chan, struct edmacc_param *pset,
  src_cidx = cidx;
  dst_bidx = 0;
  dst_cidx = 0;
- } else if (direction == DMA_DEV_TO_MEM)  {
+ } else {
+ /* DMA_DEV_TO_MEM */
  src_bidx = 0;
  src_cidx = 0;
  dst_bidx = acnt;
  dst_cidx = cidx;
- } else {
- dev_err(dev, "%s: direction not implemented yet\n", __func__);
- return -EINVAL;
  }
 
  pset->opt = EDMA_TCC(EDMA_CHAN_SLOT(echan->ch_num));
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 10/18] dma: edma: Reduce debug print verbosity for non verbose debugging

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
Do not print the paRAM information when verbose debugging is not asked and
also reduce the number of lines printed in edma_prep_dma_cyclic()

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 drivers/dma/edma.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index e4f4a0cef58c..e2aa42b8342f 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -141,7 +141,7 @@ static void edma_execute(struct edma_chan *echan)
  for (i = 0; i < nslots; i++) {
  j = i + edesc->processed;
  edma_write_slot(echan->slot[i], &edesc->pset[j]);
- dev_dbg(echan->vchan.chan.device->dev,
+ dev_vdbg(echan->vchan.chan.device->dev,
  "\n pset[%d]:\n"
  "  chnum\t%d\n"
  "  slot\t%d\n"
@@ -554,9 +554,8 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
  edesc->cyclic = 1;
  edesc->pset_nr = nslots;
 
- dev_dbg(dev, "%s: nslots=%d\n", __func__, nslots);
- dev_dbg(dev, "%s: period_len=%d\n", __func__, period_len);
- dev_dbg(dev, "%s: buf_len=%d\n", __func__, buf_len);
+ dev_dbg(dev, "%s: channel=%d nslots=%d period_len=%d buf_len=%d\n",
+ __func__, echan->ch_num, nslots, period_len, buf_len);
 
  for (i = 0; i < nslots; i++) {
  /* Allocate a PaRAM slot, if needed */
@@ -590,8 +589,8 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
  else
  src_addr += period_len;
 
- dev_dbg(dev, "%s: Configure period %d of buf:\n", __func__, i);
- dev_dbg(dev,
+ dev_vdbg(dev, "%s: Configure period %d of buf:\n", __func__, i);
+ dev_vdbg(dev,
  "\n pset[%d]:\n"
  "  chnum\t%d\n"
  "  slot\t%d\n"
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 11/18] dma: edma: Prefix debug prints where the text were identical in prep callbacks

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
prep_slave_sg and prep_dma_cyclic callbacks have mostly same failure cases
with the same texts printed in case we hit them. It helps when debugging if
we know exactly which callback generated the errors.
At the same time change the debug level for descriptor allocation failure
from dbg to err since all other error cases are dev_err and this failure is
similarly fatal as the other ones.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 drivers/dma/edma.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index e2aa42b8342f..07ac5f4eeb56 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -430,14 +430,14 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
  }
 
  if (dev_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) {
- dev_err(dev, "Undefined slave buswidth\n");
+ dev_err(dev, "%s: Undefined slave buswidth\n", __func__);
  return NULL;
  }
 
  edesc = kzalloc(sizeof(*edesc) + sg_len *
  sizeof(edesc->pset[0]), GFP_ATOMIC);
  if (!edesc) {
- dev_dbg(dev, "Failed to allocate a descriptor\n");
+ dev_err(dev, "%s: Failed to allocate a descriptor\n", __func__);
  return NULL;
  }
 
@@ -453,7 +453,8 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
  EDMA_SLOT_ANY);
  if (echan->slot[i] < 0) {
  kfree(edesc);
- dev_err(dev, "Failed to allocate slot\n");
+ dev_err(dev, "%s: Failed to allocate slot\n",
+ __func__);
  return NULL;
  }
  }
@@ -522,7 +523,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
  }
 
  if (dev_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) {
- dev_err(dev, "Undefined slave buswidth\n");
+ dev_err(dev, "%s: Undefined slave buswidth\n", __func__);
  return NULL;
  }
 
@@ -547,7 +548,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
  edesc = kzalloc(sizeof(*edesc) + nslots *
  sizeof(edesc->pset[0]), GFP_ATOMIC);
  if (!edesc) {
- dev_dbg(dev, "Failed to allocate a descriptor\n");
+ dev_err(dev, "%s: Failed to allocate a descriptor\n", __func__);
  return NULL;
  }
 
@@ -565,7 +566,8 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
  EDMA_SLOT_ANY);
  if (echan->slot[i] < 0) {
  kfree(edesc);
- dev_err(dev, "Failed to allocate slot\n");
+ dev_err(dev, "%s: Failed to allocate slot\n",
+ __func__);
  return NULL;
  }
  }
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 12/18] dma: edma: Add channel number to debug prints

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
It helps to identify issues if we have some information regarding to the
channel which the event is associated.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 drivers/dma/edma.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 07ac5f4eeb56..47abaac7eb18 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -185,7 +185,8 @@ static void edma_execute(struct edma_chan *echan)
  edma_resume(echan->ch_num);
 
  if (edesc->processed <= MAX_NR_SG) {
- dev_dbg(dev, "first transfer starting %d\n", echan->ch_num);
+ dev_dbg(dev, "first transfer starting on channel %d\n",
+ echan->ch_num);
  edma_start(echan->ch_num);
  }
 
@@ -195,7 +196,7 @@ static void edma_execute(struct edma_chan *echan)
  * MAX_NR_SG
  */
  if (echan->missed) {
- dev_dbg(dev, "missed event in execute detected\n");
+ dev_dbg(dev, "missed event on channel %d\n", echan->ch_num);
  edma_clean_channel(echan->ch_num);
  edma_stop(echan->ch_num);
  edma_start(echan->ch_num);
@@ -732,7 +733,7 @@ static int edma_alloc_chan_resources(struct dma_chan *chan)
  echan->alloced = true;
  echan->slot[0] = echan->ch_num;
 
- dev_dbg(dev, "allocated channel for %u:%u\n",
+ dev_dbg(dev, "allocated channel %d for %u:%u\n", echan->ch_num,
  EDMA_CTLR(echan->ch_num), EDMA_CHAN_SLOT(echan->ch_num));
 
  return 0;
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 13/18] dma: edma: Print the direction value as well when it is not supported

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
In case of not supported direction it is better to print the direction also.
It is unlikely, but in such an event it helps with the debugging.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 drivers/dma/edma.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 47abaac7eb18..69dd4e3de67e 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -426,7 +426,7 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
  dev_width = echan->cfg.dst_addr_width;
  burst = echan->cfg.dst_maxburst;
  } else {
- dev_err(dev, "%s: bad direction?\n", __func__);
+ dev_err(dev, "%s: bad direction: %d\n", __func__, direction);
  return NULL;
  }
 
@@ -519,7 +519,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
  dev_width = echan->cfg.dst_addr_width;
  burst = echan->cfg.dst_maxburst;
  } else {
- dev_err(dev, "%s: bad direction?\n", __func__);
+ dev_err(dev, "%s: bad direction: %d\n", __func__, direction);
  return NULL;
  }
 
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 14/18] ASoC: davinci: Add edma dmaengine platform driver

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
Platform driver glue for SoC using eDMA3 to use dmaengine PCM.
The maximum number of periods need to be limited to 19 since the
edma dmaengine driver limits the paRAM slot use for audio at
in cyclic mode.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 sound/soc/davinci/Kconfig    |  1 +
 sound/soc/davinci/Makefile   |  2 +-
 sound/soc/davinci/edma-pcm.c | 77 ++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/davinci/edma-pcm.h | 26 +++++++++++++++
 4 files changed, 105 insertions(+), 1 deletion(-)
 create mode 100644 sound/soc/davinci/edma-pcm.c
 create mode 100644 sound/soc/davinci/edma-pcm.h

diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index a8ec1fc3e4d0..f9d9f748e743 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -1,6 +1,7 @@
 config SND_DAVINCI_SOC
  tristate "SoC Audio for TI DAVINCI or AM33XX/AM43XX chips"
  depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM43XX
+ select SND_SOC_GENERIC_DMAENGINE_PCM
 
 config SND_DAVINCI_SOC_I2S
  tristate
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index 744d4d9a0184..97d05a2f1723 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -1,5 +1,5 @@
 # DAVINCI Platform Support
-snd-soc-davinci-objs := davinci-pcm.o
+snd-soc-davinci-objs := davinci-pcm.o edma-pcm.o
 snd-soc-davinci-i2s-objs := davinci-i2s.o
 snd-soc-davinci-mcasp-objs:= davinci-mcasp.o
 snd-soc-davinci-vcif-objs:= davinci-vcif.o
diff --git a/sound/soc/davinci/edma-pcm.c b/sound/soc/davinci/edma-pcm.c
new file mode 100644
index 000000000000..eeed927a2657
--- /dev/null
+++ b/sound/soc/davinci/edma-pcm.c
@@ -0,0 +1,77 @@
+/*
+ * edma-pcm.c - eDMA PCM driver using dmaengine for AM3xxx, AM4xxx
+ *
+ * Copyright (C) 2014 Texas Instruments, Inc.
+ *
+ * Author: Peter Ujfalusi <[hidden email]>
+ *
+ * Based on: sound/soc/tegra/tegra_pcm.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+#include <linux/edma.h>
+
+static const struct snd_pcm_hardware edma_pcm_hardware = {
+ .info = SNDRV_PCM_INFO_MMAP |
+  SNDRV_PCM_INFO_MMAP_VALID |
+  SNDRV_PCM_INFO_BATCH |
+  SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
+  SNDRV_PCM_INFO_INTERLEAVED,
+ .buffer_bytes_max = 128 * 1024,
+ .period_bytes_min = 32,
+ .period_bytes_max = 64 * 1024,
+ .periods_min = 2,
+ .periods_max = 19, /* Limit by edma dmaengine driver */
+};
+
+static const struct snd_dmaengine_pcm_config edma_dmaengine_pcm_config = {
+ .pcm_hardware = &edma_pcm_hardware,
+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
+ .prealloc_buffer_size = 128 * 1024,
+};
+
+static const struct snd_dmaengine_pcm_config edma_compat_dmaengine_pcm_config = {
+ .pcm_hardware = &edma_pcm_hardware,
+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
+ .compat_filter_fn = edma_filter_fn,
+ .prealloc_buffer_size = 128 * 1024,
+};
+
+int edma_pcm_platform_register(struct device *dev)
+{
+ if (dev->of_node)
+ return snd_dmaengine_pcm_register(dev,
+ &edma_dmaengine_pcm_config,
+ SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
+ else
+ return snd_dmaengine_pcm_register(dev,
+ &edma_compat_dmaengine_pcm_config,
+ SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
+ SND_DMAENGINE_PCM_FLAG_NO_DT |
+ SND_DMAENGINE_PCM_FLAG_COMPAT);
+}
+EXPORT_SYMBOL_GPL(edma_pcm_platform_register);
+
+void edma_pcm_platform_unregister(struct device *dev)
+{
+ snd_dmaengine_pcm_unregister(dev);
+}
+EXPORT_SYMBOL_GPL(edma_pcm_platform_unregister);
+
+MODULE_AUTHOR("Peter Ujfalusi <[hidden email]>");
+MODULE_DESCRIPTION("eDMA PCM ASoC platform driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/davinci/edma-pcm.h b/sound/soc/davinci/edma-pcm.h
new file mode 100644
index 000000000000..25dc8c7ff093
--- /dev/null
+++ b/sound/soc/davinci/edma-pcm.h
@@ -0,0 +1,26 @@
+/*
+ * edma-pcm.h - eDMA PCM driver using dmaengine for AM3xxx, AM4xxx
+ *
+ * Copyright (C) 2014 Texas Instruments, Inc.
+ *
+ * Author: Peter Ujfalusi <[hidden email]>
+ *
+ * Based on: sound/soc/tegra/tegra_pcm.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef __EDMA_PCM_H__
+#define __EDMA_PCM_H__
+
+int edma_pcm_platform_register(struct device *dev);
+void edma_pcm_platform_unregister(struct device *dev);
+
+#endif /* __EDMA_PCM_H__ */
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 15/18] ASoC: davinci-mcasp: Use dmaengine based platform driver for AM335x/447x

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
Use the edma-pcm with AM335x and AM447x SoCs.
Keep using the davinci-pcm for DaVinci devices, they can be switched to use
the dmaengine based driver later when they are verified to work correctly.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 sound/soc/davinci/davinci-mcasp.c | 46 +++++++++++++++++++++++++++++++++------
 1 file changed, 39 insertions(+), 7 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index b0ae0677f023..604aa982f5c4 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -36,6 +36,7 @@
 
 #include "davinci-pcm.h"
 #include "davinci-mcasp.h"
+#include "edma-pcm.h"
 
 struct davinci_mcasp_context {
  u32 txfmtctl;
@@ -721,10 +722,12 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
 {
  struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
 
- if (mcasp->version == MCASP_VERSION_4)
+ if (mcasp->version >= MCASP_VERSION_3)
+ /* Using dmaengine PCM */
  snd_soc_dai_set_dma_data(dai, substream,
  &mcasp->dma_data[substream->stream]);
  else
+ /* Using davinci-pcm */
  snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params);
 
  return 0;
@@ -1154,12 +1157,28 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
  if (ret != 0)
  goto err_release_clk;
 
- if (mcasp->version != MCASP_VERSION_4) {
+ /* Based on the McASP version use different platform driver */
+ switch (mcasp->version) {
+ case MCASP_VERSION_1:
+ case MCASP_VERSION_2:
  ret = davinci_soc_platform_register(&pdev->dev);
- if (ret) {
- dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
- goto err_unregister_component;
- }
+ break;
+ case MCASP_VERSION_3:
+ ret = edma_pcm_platform_register(&pdev->dev);
+ break;
+ case MCASP_VERSION_4:
+ /* Using omap-pcm as platform driver */
+ break;
+ default:
+ dev_err(&pdev->dev, "Invalid McASP version: %d\n",
+ mcasp->version);
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret) {
+ dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
+ goto err_unregister_component;
  }
 
  return 0;
@@ -1177,8 +1196,21 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
  struct davinci_mcasp *mcasp = dev_get_drvdata(&pdev->dev);
 
  snd_soc_unregister_component(&pdev->dev);
- if (mcasp->version != MCASP_VERSION_4)
+
+ switch (mcasp->version) {
+ case MCASP_VERSION_1:
+ case MCASP_VERSION_2:
  davinci_soc_platform_unregister(&pdev->dev);
+ break;
+ case MCASP_VERSION_3:
+ edma_pcm_platform_unregister(&pdev->dev);
+ break;
+ case MCASP_VERSION_4:
+ /* Using omap-pcm as platform driver */
+ break;
+ default:
+ break;
+ }
 
  pm_runtime_put_sync(&pdev->dev);
  pm_runtime_disable(&pdev->dev);
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 16/18] ASoC: davinci-mcasp: Provide correct filter_data for dmaengine for non-DT boot

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
When we boot with non-DT mode the damengine will need the channel number and
a filter function in order to get the channel.
The filter_data is filled in the DAI driver while the filter_function will
be provided by the edma-pcm driver.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 sound/soc/davinci/davinci-mcasp.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 604aa982f5c4..5428615413e2 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1029,6 +1029,7 @@ nodata:
 static int davinci_mcasp_probe(struct platform_device *pdev)
 {
  struct davinci_pcm_dma_params *dma_params;
+ struct snd_dmaengine_dai_dma_data *dma_data;
  struct resource *mem, *ioarea, *res, *dat;
  struct davinci_mcasp_pdata *pdata;
  struct davinci_mcasp *mcasp;
@@ -1098,6 +1099,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
  mcasp->dat_port = true;
 
  dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
+ dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
  dma_params->asp_chan_q = pdata->asp_chan_q;
  dma_params->ram_chan_q = pdata->ram_chan_q;
  dma_params->sram_pool = pdata->sram_pool;
@@ -1108,7 +1110,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
  dma_params->dma_addr = mem->start + pdata->tx_dma_offset;
 
  /* Unconditional dmaengine stuff */
- mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = dma_params->dma_addr;
+ dma_data->addr = dma_params->dma_addr;
 
  res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
  if (res)
@@ -1116,7 +1118,14 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
  else
  dma_params->channel = pdata->tx_dma_channel;
 
+ /* dmaengine filter data for DT and non-DT boot */
+ if (pdev->dev.of_node)
+ dma_data->filter_data = "tx";
+ else
+ dma_data->filter_data = &dma_params->channel;
+
  dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE];
+ dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE];
  dma_params->asp_chan_q = pdata->asp_chan_q;
  dma_params->ram_chan_q = pdata->ram_chan_q;
  dma_params->sram_pool = pdata->sram_pool;
@@ -1127,7 +1136,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
  dma_params->dma_addr = mem->start + pdata->rx_dma_offset;
 
  /* Unconditional dmaengine stuff */
- mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = dma_params->dma_addr;
+ dma_data->addr = dma_params->dma_addr;
 
  if (mcasp->version < MCASP_VERSION_3) {
  mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE;
@@ -1143,9 +1152,11 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
  else
  dma_params->channel = pdata->rx_dma_channel;
 
- /* Unconditional dmaengine stuff */
- mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = "tx";
- mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = "rx";
+ /* dmaengine filter data for DT and non-DT boot */
+ if (pdev->dev.of_node)
+ dma_data->filter_data = "rx";
+ else
+ dma_data->filter_data = &dma_params->channel;
 
  dev_set_drvdata(&pdev->dev, mcasp);
 
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 17/18] ASoC: davinci-mcasp: Assign the dma_data earlier in dai_probe callback

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
Remove the dai startup callback and do the dma_data setup for dmaengine
in the dai_probe function.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 sound/soc/davinci/davinci-mcasp.c | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 5428615413e2..958933614ca4 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -717,31 +717,33 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
  return ret;
 }
 
-static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
+static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
+ .trigger = davinci_mcasp_trigger,
+ .hw_params = davinci_mcasp_hw_params,
+ .set_fmt = davinci_mcasp_set_dai_fmt,
+ .set_clkdiv = davinci_mcasp_set_clkdiv,
+ .set_sysclk = davinci_mcasp_set_sysclk,
+};
+
+static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
 {
  struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
 
- if (mcasp->version >= MCASP_VERSION_3)
+ if (mcasp->version >= MCASP_VERSION_3) {
  /* Using dmaengine PCM */
- snd_soc_dai_set_dma_data(dai, substream,
- &mcasp->dma_data[substream->stream]);
- else
+ dai->playback_dma_data =
+ &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
+ dai->capture_dma_data =
+ &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE];
+ } else {
  /* Using davinci-pcm */
- snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params);
+ dai->playback_dma_data = mcasp->dma_params;
+ dai->capture_dma_data = mcasp->dma_params;
+ }
 
  return 0;
 }
 
-static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
- .startup = davinci_mcasp_startup,
- .trigger = davinci_mcasp_trigger,
- .hw_params = davinci_mcasp_hw_params,
- .set_fmt = davinci_mcasp_set_dai_fmt,
- .set_clkdiv = davinci_mcasp_set_clkdiv,
- .set_sysclk = davinci_mcasp_set_sysclk,
-};
-
 #ifdef CONFIG_PM_SLEEP
 static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
 {
@@ -795,6 +797,7 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai)
 static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
  {
  .name = "davinci-mcasp.0",
+ .probe = davinci_mcasp_dai_probe,
  .suspend = davinci_mcasp_suspend,
  .resume = davinci_mcasp_resume,
  .playback = {
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 18/18] ASoC: davinci-mcasp: Place constraint on the period size based on FIFO config

Peter Ujfalusi
In reply to this post by Peter Ujfalusi
We need to place constraint on the period size (and indirectly to buffer
size) if the read or write AFIFO is enabled and it is configured for more
than one word otherwise the DMA will fail in buffer configuration where
the sizes are not aligned with the requested FIFO configuration.

Signed-off-by: Peter Ujfalusi <[hidden email]>
---
 sound/soc/davinci/davinci-mcasp.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 958933614ca4..17d1112bce24 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -717,7 +717,27 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
  return ret;
 }
 
+static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *cpu_dai)
+{
+ struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
+ int afifo_numevt;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ afifo_numevt = mcasp->txnumevt;
+ else
+ afifo_numevt = mcasp->rxnumevt;
+
+ if (afifo_numevt > 1)
+ snd_pcm_hw_constraint_step(substream->runtime, 0,
+   SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+   afifo_numevt);
+
+ return 0;
+}
+
 static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
+ .startup = davinci_mcasp_startup,
  .trigger = davinci_mcasp_trigger,
  .hw_params = davinci_mcasp_hw_params,
  .set_fmt = davinci_mcasp_set_dai_fmt,
--
1.9.0

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [alsa-devel] [PATCH 14/18] ASoC: davinci: Add edma dmaengine platform driver

Lars-Peter Clausen
In reply to this post by Peter Ujfalusi
On 03/13/2014 10:18 AM, Peter Ujfalusi wrote:
[...]

> +static const struct snd_pcm_hardware edma_pcm_hardware = {
> + .info = SNDRV_PCM_INFO_MMAP |
> +  SNDRV_PCM_INFO_MMAP_VALID |
> +  SNDRV_PCM_INFO_BATCH |
> +  SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
> +  SNDRV_PCM_INFO_INTERLEAVED,
> + .buffer_bytes_max = 128 * 1024,
> + .period_bytes_min = 32,
> + .period_bytes_max = 64 * 1024,
> + .periods_min = 2,
> + .periods_max = 19, /* Limit by edma dmaengine driver */
> +};

The idea is that we can auto-discover all the things using the
dma_slave_caps API. Too bad we removed the possibility to specify the
maximum number of segments from the API. Maybe we need to add it back. Is
the 19 a hard-limit or could it be worked around by software in the
dmaengine driver?

> +
> +static const struct snd_dmaengine_pcm_config edma_dmaengine_pcm_config = {
> + .pcm_hardware = &edma_pcm_hardware,
> + .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
> + .prealloc_buffer_size = 128 * 1024,

Unless there is a very good reason for exactly this size, just leave it 0
and let the generic dmaengine driver use the default.

> +};
> +
> +static const struct snd_dmaengine_pcm_config edma_compat_dmaengine_pcm_config = {
> + .pcm_hardware = &edma_pcm_hardware,
> + .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
> + .compat_filter_fn = edma_filter_fn,
> + .prealloc_buffer_size = 128 * 1024,
> +};

There is no need for different configs for DT and non-DT.

> +
> +int edma_pcm_platform_register(struct device *dev)
> +{
> + if (dev->of_node)
> + return snd_dmaengine_pcm_register(dev,
> + &edma_dmaengine_pcm_config,
> + SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);

Since the edma dmaengine driver implements the slave cap API there is no
need to manually specify SND_DMAENGINE_PCM_FLAG_NO_RESIDUE manually. But
since the edma driver sets the granularity to
DMA_RESIDUE_GRANULARITY_DESCRIPTOR in this case the generic dmaengine will
not set SND_DMAENGINE_PCM_FLAG_NO_RESIDUE automatically since it assumes
that the dmaengine driver is capable of properly reporting the DMA position.

> + else
> + return snd_dmaengine_pcm_register(dev,
> + &edma_compat_dmaengine_pcm_config,
> + SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
> + SND_DMAENGINE_PCM_FLAG_NO_DT |
> + SND_DMAENGINE_PCM_FLAG_COMPAT);


If you set the flags to just SND_DMAENGINE_PCM_FLAG_COMPAT it will do the
right thing in the generic dmaengine driver depending on whether
dev->of_node is set or not.


There is also a devm_ version of snd_dmaengine_pcm_register() it probably
makes sense to use it here.

_______________________________________________
Davinci-linux-open-source mailing list
[hidden email]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
12
Loading...