2013-06-12 07:58:11

by Fabio Baltieri

[permalink] [raw]
Subject: [PATCH 0/3] DMA fixes for ux500 ASoC driver

Hi Mark,

The DMA driver used on ux500 has been recently reworked to make it
device-tree capable, but the rework required to drop some "features",
such as opportunistic channel allocation and hardcoded addresses, that
the ASoC driver was relying upon.

This series fixes the audio driver to make it work with the current
dma40 implementation, and works fine even when booting with device-tree.

Would you consider merging these for asoc/topic/ux500?

Thanks,
Fabio


Fabio Baltieri (3):
ASoC: ux500: Move DMA parameters into ux500_msp
ASoC: ux500: Set DMA address during device init
ASoC: ux500: Add DMA slave config prepare routine

sound/soc/ux500/ux500_msp_dai.c | 11 ++++-------
sound/soc/ux500/ux500_msp_dai.h | 2 --
sound/soc/ux500/ux500_msp_i2s.c | 13 +++++++++----
sound/soc/ux500/ux500_msp_i2s.h | 15 ++++++++-------
sound/soc/ux500/ux500_pcm.c | 30 ++++++++++++++++++++++++++++++
5 files changed, 51 insertions(+), 20 deletions(-)

--
1.8.2


2013-06-12 07:58:17

by Fabio Baltieri

[permalink] [raw]
Subject: [PATCH 1/3] ASoC: ux500: Move DMA parameters into ux500_msp

Move struct ux500_msp_dma_params declaration from ux500_msp_i2s_drvdata
to ux500_msp, this saves some confusing pointer passing and allows to
access all DMA configuration fields from ux500_msp_i2s.

Signed-off-by: Fabio Baltieri <[email protected]>
---
sound/soc/ux500/ux500_msp_dai.c | 11 ++++-------
sound/soc/ux500/ux500_msp_dai.h | 2 --
sound/soc/ux500/ux500_msp_i2s.c | 10 ++++++----
sound/soc/ux500/ux500_msp_i2s.h | 14 +++++++-------
4 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 7d5fc13..c6fb5cc 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -658,14 +658,11 @@ static int ux500_msp_dai_probe(struct snd_soc_dai *dai)
{
struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);

- drvdata->playback_dma_data.dma_cfg = drvdata->msp->dma_cfg_tx;
- drvdata->capture_dma_data.dma_cfg = drvdata->msp->dma_cfg_rx;
+ dai->playback_dma_data = &drvdata->msp->playback_dma_data;
+ dai->capture_dma_data = &drvdata->msp->capture_dma_data;

- dai->playback_dma_data = &drvdata->playback_dma_data;
- dai->capture_dma_data = &drvdata->capture_dma_data;
-
- drvdata->playback_dma_data.data_size = drvdata->slot_width;
- drvdata->capture_dma_data.data_size = drvdata->slot_width;
+ drvdata->msp->playback_dma_data.data_size = drvdata->slot_width;
+ drvdata->msp->capture_dma_data.data_size = drvdata->slot_width;

return 0;
}
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h
index c721282..312ae53 100644
--- a/sound/soc/ux500/ux500_msp_dai.h
+++ b/sound/soc/ux500/ux500_msp_dai.h
@@ -51,8 +51,6 @@ enum ux500_msp_clock_id {
struct ux500_msp_i2s_drvdata {
struct ux500_msp *msp;
struct regulator *reg_vape;
- struct ux500_msp_dma_params playback_dma_data;
- struct ux500_msp_dma_params capture_dma_data;
unsigned int fmt;
unsigned int tx_mask;
unsigned int rx_mask;
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index cba0e86..14a4a5b 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -367,12 +367,14 @@ static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
}

/* Make sure the correct DMA-directions are configured */
- if ((config->direction & MSP_DIR_RX) && (!msp->dma_cfg_rx)) {
+ if ((config->direction & MSP_DIR_RX) &&
+ !msp->capture_dma_data.dma_cfg) {
dev_err(msp->dev, "%s: ERROR: MSP RX-mode is not configured!",
__func__);
return -EINVAL;
}
- if ((config->direction == MSP_DIR_TX) && (!msp->dma_cfg_tx)) {
+ if ((config->direction == MSP_DIR_TX) &&
+ !msp->playback_dma_data.dma_cfg) {
dev_err(msp->dev, "%s: ERROR: MSP TX-mode is not configured!",
__func__);
return -EINVAL;
@@ -673,8 +675,8 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,

msp->id = platform_data->id;
msp->dev = &pdev->dev;
- msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx;
- msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx;
+ msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx;
+ msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx;

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
index 189a375..8796171 100644
--- a/sound/soc/ux500/ux500_msp_i2s.h
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -468,12 +468,17 @@ struct ux500_msp_config {
unsigned int iodelay;
};

+struct ux500_msp_dma_params {
+ unsigned int data_size;
+ struct stedma40_chan_cfg *dma_cfg;
+};
+
struct ux500_msp {
enum msp_i2s_id id;
void __iomem *registers;
struct device *dev;
- struct stedma40_chan_cfg *dma_cfg_rx;
- struct stedma40_chan_cfg *dma_cfg_tx;
+ struct ux500_msp_dma_params playback_dma_data;
+ struct ux500_msp_dma_params capture_dma_data;
enum msp_state msp_state;
int def_elem_len;
unsigned int dir_busy;
@@ -481,11 +486,6 @@ struct ux500_msp {
unsigned int f_bitclk;
};

-struct ux500_msp_dma_params {
- unsigned int data_size;
- struct stedma40_chan_cfg *dma_cfg;
-};
-
struct msp_i2s_platform_data;
int ux500_msp_i2s_init_msp(struct platform_device *pdev,
struct ux500_msp **msp_p,
--
1.8.2

2013-06-12 07:58:21

by Fabio Baltieri

[permalink] [raw]
Subject: [PATCH 2/3] ASoC: ux500: Set DMA address during device init

Add a field with the tx/rx register address to the DMA parameters
structure, and set it to the correct address during device
initialization.

This address used to be hardcoded in the DMA controller driver, it now
needs to be explicitly figured out by the device driver.

Signed-off-by: Fabio Baltieri <[email protected]>
---
sound/soc/ux500/ux500_msp_i2s.c | 3 +++
sound/soc/ux500/ux500_msp_i2s.h | 1 +
2 files changed, 4 insertions(+)

diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index 14a4a5b..1ca8b08 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -685,6 +685,9 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
return -ENOMEM;
}

+ msp->playback_dma_data.tx_rx_addr = res->start + MSP_DR;
+ msp->capture_dma_data.tx_rx_addr = res->start + MSP_DR;
+
msp->registers = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (msp->registers == NULL) {
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
index 8796171..258d0bc 100644
--- a/sound/soc/ux500/ux500_msp_i2s.h
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -470,6 +470,7 @@ struct ux500_msp_config {

struct ux500_msp_dma_params {
unsigned int data_size;
+ dma_addr_t tx_rx_addr;
struct stedma40_chan_cfg *dma_cfg;
};

--
1.8.2

2013-06-12 07:58:26

by Fabio Baltieri

[permalink] [raw]
Subject: [PATCH 3/3] ASoC: ux500: Add DMA slave config prepare routine

Implement a DMA slave config prepare routine, as until now the MSP
driver depended on the DMA controller completing the channel
configuration on its own, but this is not the case anymore since the
recent DMA driver updates.

Signed-off-by: Fabio Baltieri <[email protected]>
---
sound/soc/ux500/ux500_pcm.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)

diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
index b6e5ae2..5f01c19 100644
--- a/sound/soc/ux500/ux500_pcm.c
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -103,10 +103,40 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
return snd_dmaengine_pcm_request_channel(stedma40_filter, dma_cfg);
}

+static int ux500_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct dma_slave_config *slave_config)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct ux500_msp_dma_params *dma_params;
+ struct stedma40_chan_cfg *dma_cfg;
+ int ret;
+
+ dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+ dma_cfg = dma_params->dma_cfg;
+
+ ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
+ if (ret)
+ return ret;
+
+ slave_config->dst_maxburst = 4;
+ slave_config->dst_addr_width = dma_cfg->dst_info.data_width;
+ slave_config->src_maxburst = 4;
+ slave_config->src_addr_width = dma_cfg->src_info.data_width;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ slave_config->dst_addr = dma_params->tx_rx_addr;
+ else
+ slave_config->src_addr = dma_params->tx_rx_addr;
+
+ return 0;
+}
+
static const struct snd_dmaengine_pcm_config ux500_dmaengine_pcm_config = {
.pcm_hardware = &ux500_pcm_hw,
.compat_request_channel = ux500_pcm_request_chan,
.prealloc_buffer_size = 128 * 1024,
+ .prepare_slave_config = ux500_pcm_prepare_slave_config,
};

int ux500_pcm_register_platform(struct platform_device *pdev)
--
1.8.2

2013-06-12 09:51:35

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 0/3] DMA fixes for ux500 ASoC driver

On Wed, Jun 12, 2013 at 9:57 AM, Fabio Baltieri
<[email protected]> wrote:

> The DMA driver used on ux500 has been recently reworked to make it
> device-tree capable, but the rework required to drop some "features",
> such as opportunistic channel allocation and hardcoded addresses, that
> the ASoC driver was relying upon.
>
> This series fixes the audio driver to make it work with the current
> dma40 implementation, and works fine even when booting with device-tree.

FWIW: all look good to me.
Acked-by: Linus Walleij <[email protected]>

Yours,
Linus Walleij

2013-06-12 10:49:19

by Lee Jones

[permalink] [raw]
Subject: Re: [PATCH 0/3] DMA fixes for ux500 ASoC driver

On Wed, 12 Jun 2013, Fabio Baltieri wrote:

> Hi Mark,
>
> The DMA driver used on ux500 has been recently reworked to make it
> device-tree capable, but the rework required to drop some "features",
> such as opportunistic channel allocation and hardcoded addresses, that
> the ASoC driver was relying upon.
>
> This series fixes the audio driver to make it work with the current
> dma40 implementation, and works fine even when booting with device-tree.
>
> Would you consider merging these for asoc/topic/ux500?
>
> Thanks,
> Fabio
>
>
> Fabio Baltieri (3):
> ASoC: ux500: Move DMA parameters into ux500_msp
> ASoC: ux500: Set DMA address during device init
> ASoC: ux500: Add DMA slave config prepare routine
>
> sound/soc/ux500/ux500_msp_dai.c | 11 ++++-------
> sound/soc/ux500/ux500_msp_dai.h | 2 --
> sound/soc/ux500/ux500_msp_i2s.c | 13 +++++++++----
> sound/soc/ux500/ux500_msp_i2s.h | 15 ++++++++-------
> sound/soc/ux500/ux500_pcm.c | 30 ++++++++++++++++++++++++++++++
> 5 files changed, 51 insertions(+), 20 deletions(-)

I don't see anything visually wrong with them, so as long as they work
for you, then you can apply my:

Acked-by: Lee Jones <[email protected]>

--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

2013-06-12 16:03:23

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH 0/3] DMA fixes for ux500 ASoC driver

On Wed, Jun 12, 2013 at 09:57:56AM +0200, Fabio Baltieri wrote:
> Hi Mark,
>
> The DMA driver used on ux500 has been recently reworked to make it
> device-tree capable, but the rework required to drop some "features",
> such as opportunistic channel allocation and hardcoded addresses, that
> the ASoC driver was relying upon.

Applied all, thanks.


Attachments:
(No filename) (350.00 B)
signature.asc (836.00 B)
Digital signature
Download all attachments