summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@freescale.com>2014-09-05 18:51:36 +0800
committerNitin Garg <nitin.garg@nxp.com>2016-01-14 10:59:35 -0600
commitf10eac3ca6c0cc01ed628b93237ec403865a6233 (patch)
treee9dfe735c5bdad47828d2d3fc0712b44e8fca561
parent9cda3c7d0df502757db38b14363be9d0cd70f6e5 (diff)
MLK-11344-7: dma: imx-sdma: Add hdmi audio support in sdma
cherry-pick below patch from v3.14.y: ENGR00329948-3: dma: imx-sdma: Add hdmi audio support in sdma There's a missing script for hdmi audio support in current sdma driver, thus add it. This HDMI script doesn't use bd to copy memory like a normal one does but only to update the memory address for HDMI internal AHB DMA and then trigger its procedure automatically. Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com> Signed-off-by: Robin Gong <b38343@freescale.com> (cherry picked from commit dafddac916a03ae4477e2de7c1b7ad291f956f68)
-rw-r--r--Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt1
-rw-r--r--drivers/dma/imx-sdma.c32
-rw-r--r--include/linux/platform_data/dma-imx.h3
3 files changed, 28 insertions, 8 deletions
diff --git a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
index 901ed92f767d..d29c17a91729 100644
--- a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
+++ b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
@@ -55,6 +55,7 @@ The full ID of peripheral types can be found below.
22 SSI Dual FIFO (needs firmware ver >= 2)
23 Shared ASRC
24 SAI
+ 25 HDMI Audio
The third cell specifies the transfer priority as below.
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index a67cdcdcb5f7..df8b1ed2f863 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -749,7 +749,8 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
int channel = fls(stat) - 1;
struct sdma_channel *sdmac = &sdma->channel[channel];
- if (sdmac->flags & IMX_DMA_SG_LOOP)
+ if ((sdmac->flags & IMX_DMA_SG_LOOP) &&
+ (sdmac->peripheral_type != IMX_DMATYPE_HDMI))
sdma_update_channel_loop(sdmac);
tasklet_schedule(&sdmac->tasklet);
@@ -846,6 +847,9 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
case IMX_DMATYPE_IPU_MEMORY:
emi_2_per = sdma->script_addrs->ext_mem_2_ipu_addr;
break;
+ case IMX_DMATYPE_HDMI:
+ emi_2_per = sdma->script_addrs->hdmi_dma_addr;
+ break;
default:
break;
}
@@ -890,11 +894,16 @@ static int sdma_load_context(struct sdma_channel *sdmac)
/* Send by context the event mask,base address for peripheral
* and watermark level
*/
- context->gReg[0] = sdmac->event_mask[1];
- context->gReg[1] = sdmac->event_mask[0];
- context->gReg[2] = sdmac->per_addr;
- context->gReg[6] = sdmac->shp_addr;
- context->gReg[7] = sdmac->watermark_level;
+ if (sdmac->peripheral_type == IMX_DMATYPE_HDMI) {
+ context->gReg[4] = sdmac->per_addr;
+ context->gReg[6] = sdmac->shp_addr;
+ } else {
+ context->gReg[0] = sdmac->event_mask[1];
+ context->gReg[1] = sdmac->event_mask[0];
+ context->gReg[2] = sdmac->per_addr;
+ context->gReg[6] = sdmac->shp_addr;
+ context->gReg[7] = sdmac->watermark_level;
+ }
bd0->mode.command = C0_SETDM;
bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
@@ -1264,9 +1273,9 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
{
struct sdma_channel *sdmac = to_sdma_chan(chan);
struct sdma_engine *sdma = sdmac->sdma;
- int num_periods = buf_len / period_len;
int channel = sdmac->channel;
int ret, i = 0, buf = 0;
+ int num_periods;
dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);
@@ -1284,6 +1293,11 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
if (ret)
goto err_out;
+ if (sdmac->peripheral_type == IMX_DMATYPE_HDMI)
+ return &sdmac->desc;
+ else
+ num_periods = buf_len / period_len;
+
if (num_periods > NUM_BD) {
dev_err(sdma->dev, "SDMA channel %d: maximum number of sg exceeded: %d > %d\n",
channel, num_periods, NUM_BD);
@@ -1358,6 +1372,10 @@ static int sdma_config(struct dma_chan *chan,
sdmac->watermark_level |= (dmaengine_cfg->dst_maxburst << 16) &
SDMA_WATERMARK_LEVEL_HWML;
sdmac->word_size = dmaengine_cfg->dst_addr_width;
+ } else if (sdmac->peripheral_type == IMX_DMATYPE_HDMI) {
+ sdmac->per_address = dmaengine_cfg->src_addr;
+ sdmac->per_address2 = dmaengine_cfg->dst_addr;
+ sdmac->watermark_level = 0;
} else {
sdmac->per_address = dmaengine_cfg->dst_addr;
sdmac->watermark_level = dmaengine_cfg->dst_maxburst *
diff --git a/include/linux/platform_data/dma-imx.h b/include/linux/platform_data/dma-imx.h
index 63fe0a0584d5..092133a3036d 100644
--- a/include/linux/platform_data/dma-imx.h
+++ b/include/linux/platform_data/dma-imx.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2015 Freescale Semiconductor, Inc. All Rights Reserved.
*
* 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
@@ -42,6 +42,7 @@ enum sdma_peripheral_type {
IMX_DMATYPE_SSI_DUAL, /* SSI Dual FIFO */
IMX_DMATYPE_ASRC_SP, /* Shared ASRC */
IMX_DMATYPE_SAI, /* SAI */
+ IMX_DMATYPE_HDMI, /* HDMI Audio */
};
enum imx_dma_prio {