[alsa-devel] [PATCH v4 0/4] Add dual-fifo mode support of i.MX ssi
* ! This series of patches has a direct dependency between them. When * ! applying them, we need to apply to one single branch. Otherwise, * ! it would break currect branches.
Changelog v4: * PATCH-3: Add period size constraint when using dual fifo mode * * Nothing changes for PATCH-1, PATCH-2 and PATCH-4 v3: * PATCH-1: Add comments to indicate the end of v1 and v2 array. * PATCH-3: Use better way to keep watermark as even number. * * Nothing changes for PATCH-2 and PATCH-4 v2: * Instead of adding rogue scripts to current SDMA driver based on firmware * V1, we define the new SDMA firmware as version 2 and bisect the PATCH-1 * to two patches: The first is to add version check code to the SDMA driver; * And the second is to add SSI dual FIFO DMATYPE. * * Nothing changes for the last two patches. v1: * SSI can reduce hardware overrun/underrun possibility when using dual * fifo mode. To support this mode, we need to first update sdma sciprt * list, and then enable dual fifo BIT in SSI driver, and last update DT * bindings of i.MX series.
Nicolin Chen (4): dma: imx-sdma: Add sdma firmware version 2 support dma: imx-sdma: Add new dma type for ssi dual fifo script ASoC: fsl_ssi: Add dual fifo mode support ARM: dts: imx: use dual-fifo sdma script for ssi
.../devicetree/bindings/dma/fsl-imx-sdma.txt | 1 + arch/arm/boot/dts/imx51.dtsi | 4 ++-- arch/arm/boot/dts/imx53.dtsi | 4 ++-- arch/arm/boot/dts/imx6qdl.dtsi | 12 +++++----- arch/arm/boot/dts/imx6sl.dtsi | 12 +++++----- drivers/dma/imx-sdma.c | 19 ++++++++++++++- include/linux/platform_data/dma-imx-sdma.h | 5 ++++ include/linux/platform_data/dma-imx.h | 1 + sound/soc/fsl/fsl_ssi.c | 27 +++++++++++++++++++++- 9 files changed, 67 insertions(+), 18 deletions(-)
On i.MX5/6 series, SDMA is using new version firmware to support SSI dual FIFO feature and HDMI Audio (i.MX6Q/DL only). Thus add it.
Signed-off-by: Nicolin Chen b42378@freescale.com --- drivers/dma/imx-sdma.c | 15 ++++++++++++++- include/linux/platform_data/dma-imx-sdma.h | 5 +++++ 2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index fc43603..c7ece8d 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -323,6 +323,7 @@ struct sdma_engine { struct clk *clk_ipg; struct clk *clk_ahb; spinlock_t channel_0_lock; + u32 script_number; struct sdma_script_start_addrs *script_addrs; const struct sdma_driver_data *drvdata; }; @@ -1238,6 +1239,7 @@ static void sdma_issue_pending(struct dma_chan *chan) }
#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1 34 +#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2 38
static void sdma_add_scripts(struct sdma_engine *sdma, const struct sdma_script_start_addrs *addr) @@ -1246,7 +1248,7 @@ static void sdma_add_scripts(struct sdma_engine *sdma, s32 *saddr_arr = (u32 *)sdma->script_addrs; int i;
- for (i = 0; i < SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; i++) + for (i = 0; i < sdma->script_number; i++) if (addr_arr[i] > 0) saddr_arr[i] = addr_arr[i]; } @@ -1272,6 +1274,17 @@ static void sdma_load_firmware(const struct firmware *fw, void *context) goto err_firmware; if (header->ram_code_start + header->ram_code_size > fw->size) goto err_firmware; + switch (header->version_major) { + case 1: + sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; + break; + case 2: + sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2; + break; + default: + dev_err(sdma->dev, "unknown firmware version\n"); + return; + }
addr = (void *)header + header->script_addrs_start; ram_code = (void *)header + header->ram_code_start; diff --git a/include/linux/platform_data/dma-imx-sdma.h b/include/linux/platform_data/dma-imx-sdma.h index 3a39428..eabac4e 100644 --- a/include/linux/platform_data/dma-imx-sdma.h +++ b/include/linux/platform_data/dma-imx-sdma.h @@ -43,6 +43,11 @@ struct sdma_script_start_addrs { s32 dptc_dvfs_addr; s32 utra_addr; s32 ram_code_start_addr; + /* End of v1 array */ + s32 mcu_2_ssish_addr; + s32 ssish_2_mcu_addr; + s32 hdmi_dma_addr; + /* End of v2 array */ };
/**
-----Original Message----- From: Linuxppc-dev [mailto:linuxppc-dev- bounces+bharat.bhushan=freescale.com@lists.ozlabs.org] On Behalf Of Nicolin Chen Sent: Friday, November 08, 2013 4:20 PM To: vinod.koul@intel.com; dan.j.williams@intel.com; s.hauer@pengutronix.de; timur@tabi.org; shawn.guo@linaro.org; broonie@kernel.org Cc: mark.rutland@arm.com; devicetree@vger.kernel.org; alsa-devel@alsa- project.org; pawel.moll@arm.com; linux-doc@vger.kernel.org; swarren@wwwdotorg.org; linux-kernel@vger.kernel.org; rob.herring@calxeda.com; dmaengine@vger.kernel.org; ijc+devicetree@hellion.org.uk; linuxppc- dev@lists.ozlabs.org; linux-arm-kernel@lists.infradead.org Subject: [PATCH v4 1/4] dma: imx-sdma: Add sdma firmware version 2 support
On i.MX5/6 series, SDMA is using new version firmware to support SSI dual FIFO feature and HDMI Audio (i.MX6Q/DL only). Thus add it.
Signed-off-by: Nicolin Chen b42378@freescale.com
drivers/dma/imx-sdma.c | 15 ++++++++++++++- include/linux/platform_data/dma-imx-sdma.h | 5 +++++ 2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index fc43603..c7ece8d 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -323,6 +323,7 @@ struct sdma_engine { struct clk *clk_ipg; struct clk *clk_ahb; spinlock_t channel_0_lock;
- u32 script_number; struct sdma_script_start_addrs *script_addrs; const struct sdma_driver_data *drvdata;
}; @@ -1238,6 +1239,7 @@ static void sdma_issue_pending(struct dma_chan *chan) }
#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1 34 +#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2 38
static void sdma_add_scripts(struct sdma_engine *sdma, const struct sdma_script_start_addrs *addr) @@ -1246,7 +1248,7 @@ static void sdma_add_scripts(struct sdma_engine *sdma, s32 *saddr_arr = (u32 *)sdma->script_addrs; int i;
- for (i = 0; i < SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; i++)
- for (i = 0; i < sdma->script_number; i++) if (addr_arr[i] > 0) saddr_arr[i] = addr_arr[i];
} @@ -1272,6 +1274,17 @@ static void sdma_load_firmware(const struct firmware *fw, void *context) goto err_firmware; if (header->ram_code_start + header->ram_code_size > fw->size) goto err_firmware;
- switch (header->version_major) {
case 1:
sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
break;
case 2:
sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2;
break;
default:
dev_err(sdma->dev, "unknown firmware version\n");
return;
Why return and not "goto err_firmware" ?
-Bharat
}
addr = (void *)header + header->script_addrs_start; ram_code = (void *)header + header->ram_code_start; diff --git
a/include/linux/platform_data/dma-imx-sdma.h b/include/linux/platform_data/dma- imx-sdma.h index 3a39428..eabac4e 100644 --- a/include/linux/platform_data/dma-imx-sdma.h +++ b/include/linux/platform_data/dma-imx-sdma.h @@ -43,6 +43,11 @@ struct sdma_script_start_addrs { s32 dptc_dvfs_addr; s32 utra_addr; s32 ram_code_start_addr;
- /* End of v1 array */
- s32 mcu_2_ssish_addr;
- s32 ssish_2_mcu_addr;
- s32 hdmi_dma_addr;
- /* End of v2 array */
};
/**
1.8.4
Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
This patch adds a new DMA_TYPE for SSI dual FIFO script, included in SDMA firmware version 2. This script would allow SSI use dual fifo mode to transimit/receive data without occasional hardware underrun/overrun.
Signed-off-by: Nicolin Chen b42378@freescale.com --- Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt | 1 + drivers/dma/imx-sdma.c | 4 ++++ include/linux/platform_data/dma-imx.h | 1 + 3 files changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt index 4fa814d..68b83ec 100644 --- a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt +++ b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt @@ -42,6 +42,7 @@ The full ID of peripheral types can be found below. 19 IPU Memory 20 ASRC 21 ESAI + 22 SSI Dual FIFO (needs firmware ver >= 2)
The third cell specifies the transfer priority as below.
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index c7ece8d..efaa9a9 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -725,6 +725,10 @@ static void sdma_get_pc(struct sdma_channel *sdmac, per_2_emi = sdma->script_addrs->app_2_mcu_addr; emi_2_per = sdma->script_addrs->mcu_2_app_addr; break; + case IMX_DMATYPE_SSI_DUAL: + per_2_emi = sdma->script_addrs->ssish_2_mcu_addr; + emi_2_per = sdma->script_addrs->mcu_2_ssish_addr; + break; case IMX_DMATYPE_SSI_SP: case IMX_DMATYPE_MMC: case IMX_DMATYPE_SDHC: diff --git a/include/linux/platform_data/dma-imx.h b/include/linux/platform_data/dma-imx.h index beac6b8..bcbc6c3 100644 --- a/include/linux/platform_data/dma-imx.h +++ b/include/linux/platform_data/dma-imx.h @@ -39,6 +39,7 @@ enum sdma_peripheral_type { IMX_DMATYPE_IPU_MEMORY, /* IPU Memory */ IMX_DMATYPE_ASRC, /* ASRC */ IMX_DMATYPE_ESAI, /* ESAI */ + IMX_DMATYPE_SSI_DUAL, /* SSI Dual FIFO */ };
enum imx_dma_prio {
By enabling dual fifo mode, it would allow SSI enter a better performance to transimit/receive data without occasional hardware underrun/overrun.
Signed-off-by: Nicolin Chen b42378@freescale.com --- sound/soc/fsl/fsl_ssi.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 6b81d0c..af6640c 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -143,6 +143,7 @@ struct fsl_ssi_private { bool ssi_on_imx; bool imx_ac97; bool use_dma; + bool use_dual_fifo; struct clk *clk; struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_rx; @@ -413,6 +414,12 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private) write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor); }
+ if (ssi_private->use_dual_fifo) { + write_ssi_mask(&ssi->srcr, 0, CCSR_SSI_SRCR_RFEN1); + write_ssi_mask(&ssi->stcr, 0, CCSR_SSI_STCR_TFEN1); + write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_TCH_EN); + } + return 0; }
@@ -487,6 +494,15 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, ssi_private->second_stream = substream; }
+ /* When using dual fifo mode, it is safer to ensure an even period + * size. If appearing to an odd number while DMA always starts its + * task from fifo0, fifo1 would be neglected at the end of each + * period. But SSI would still access fifo1 with an invalid data. + */ + if (ssi_private->use_dual_fifo) + snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); + return 0; }
@@ -954,7 +970,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) ssi_private->fifo_depth = 8;
if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) { - u32 dma_events[2]; + u32 dma_events[2], dmas[4]; ssi_private->ssi_on_imx = true;
ssi_private->clk = devm_clk_get(&pdev->dev, NULL); @@ -1008,6 +1024,15 @@ static int fsl_ssi_probe(struct platform_device *pdev) dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); + if (!of_property_read_u32_array(pdev->dev.of_node, "dmas", dmas, 4) + && dmas[2] == IMX_DMATYPE_SSI_DUAL) { + ssi_private->use_dual_fifo = true; + /* When using dual fifo mode, we need to keep watermark + * as even numbers due to dma script limitation. + */ + ssi_private->dma_params_tx.maxburst &= ~0x1; + ssi_private->dma_params_rx.maxburst &= ~0x1; + } } else if (ssi_private->use_dma) { /* The 'name' should not have any slashes in it. */ ret = devm_request_irq(&pdev->dev, ssi_private->irq,
Use dual-fifo sdma scripts instead of shared scripts for ssi on i.MX series.
Signed-off-by: Nicolin Chen b42378@freescale.com --- arch/arm/boot/dts/imx51.dtsi | 4 ++-- arch/arm/boot/dts/imx53.dtsi | 4 ++-- arch/arm/boot/dts/imx6qdl.dtsi | 12 ++++++------ arch/arm/boot/dts/imx6sl.dtsi | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index 54cee65..1a71eac 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi @@ -154,8 +154,8 @@ reg = <0x70014000 0x4000>; interrupts = <30>; clocks = <&clks 49>; - dmas = <&sdma 24 1 0>, - <&sdma 25 1 0>; + dmas = <&sdma 24 22 0>, + <&sdma 25 22 0>; dma-names = "rx", "tx"; fsl,fifo-depth = <15>; fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */ diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 4307e80..7208fde 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -153,8 +153,8 @@ reg = <0x50014000 0x4000>; interrupts = <30>; clocks = <&clks 49>; - dmas = <&sdma 24 1 0>, - <&sdma 25 1 0>; + dmas = <&sdma 24 22 0>, + <&sdma 25 22 0>; dma-names = "rx", "tx"; fsl,fifo-depth = <15>; fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */ diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 57e9c38..6e096ca 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -223,8 +223,8 @@ reg = <0x02028000 0x4000>; interrupts = <0 46 0x04>; clocks = <&clks 178>; - dmas = <&sdma 37 1 0>, - <&sdma 38 1 0>; + dmas = <&sdma 37 22 0>, + <&sdma 38 22 0>; dma-names = "rx", "tx"; fsl,fifo-depth = <15>; fsl,ssi-dma-events = <38 37>; @@ -236,8 +236,8 @@ reg = <0x0202c000 0x4000>; interrupts = <0 47 0x04>; clocks = <&clks 179>; - dmas = <&sdma 41 1 0>, - <&sdma 42 1 0>; + dmas = <&sdma 41 22 0>, + <&sdma 42 22 0>; dma-names = "rx", "tx"; fsl,fifo-depth = <15>; fsl,ssi-dma-events = <42 41>; @@ -249,8 +249,8 @@ reg = <0x02030000 0x4000>; interrupts = <0 48 0x04>; clocks = <&clks 180>; - dmas = <&sdma 45 1 0>, - <&sdma 46 1 0>; + dmas = <&sdma 45 22 0>, + <&sdma 46 22 0>; dma-names = "rx", "tx"; fsl,fifo-depth = <15>; fsl,ssi-dma-events = <46 45>; diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index c46651e..b32ba99 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -195,8 +195,8 @@ reg = <0x02028000 0x4000>; interrupts = <0 46 0x04>; clocks = <&clks IMX6SL_CLK_SSI1>; - dmas = <&sdma 37 1 0>, - <&sdma 38 1 0>; + dmas = <&sdma 37 22 0>, + <&sdma 38 22 0>; dma-names = "rx", "tx"; fsl,fifo-depth = <15>; status = "disabled"; @@ -207,8 +207,8 @@ reg = <0x0202c000 0x4000>; interrupts = <0 47 0x04>; clocks = <&clks IMX6SL_CLK_SSI2>; - dmas = <&sdma 41 1 0>, - <&sdma 42 1 0>; + dmas = <&sdma 41 22 0>, + <&sdma 42 22 0>; dma-names = "rx", "tx"; fsl,fifo-depth = <15>; status = "disabled"; @@ -219,8 +219,8 @@ reg = <0x02030000 0x4000>; interrupts = <0 48 0x04>; clocks = <&clks IMX6SL_CLK_SSI3>; - dmas = <&sdma 45 1 0>, - <&sdma 46 1 0>; + dmas = <&sdma 45 22 0>, + <&sdma 46 22 0>; dma-names = "rx", "tx"; fsl,fifo-depth = <15>; status = "disabled";
On Fri, Nov 08, 2013 at 06:49:32PM +0800, Nicolin Chen wrote:
- ! This series of patches has a direct dependency between them. When
- ! applying them, we need to apply to one single branch. Otherwise,
- ! it would break currect branches.
Changelog v4:
- PATCH-3: Add period size constraint when using dual fifo mode
- Nothing changes for PATCH-1, PATCH-2 and PATCH-4
Sorry all, I mistook the version number. It should be version 5.
Please ignore this series version.
I'll resend v5 soon.
Nicolin Chen
On Fri, Nov 08, 2013 at 07:29:20PM +0800, Nicolin Chen wrote:
Sorry all, I mistook the version number. It should be version 5.
Please ignore this series version.
There is no need to resend for things like getting the version number wrong in the subject line, that's just noise. Please only resend things if there's a change in the actual patches.
Oh, I am sorry about that.
I will follow the rule next time.
Thank you.
Sent by Android device.
Mark Brown broonie@kernel.org wrote:
On Fri, Nov 08, 2013 at 07:29:20PM +0800, Nicolin Chen wrote:
Sorry all, I mistook the version number. It should be version 5.
Please ignore this series version.
There is no need to resend for things like getting the version number wrong in the subject line, that's just noise. Please only resend things if there's a change in the actual patches.
participants (4)
-
Bharat Bhushan
-
Guangyu Chen
-
Mark Brown
-
Nicolin Chen