diff options
author | Viorel Suman <viorel.suman@nxp.com> | 2017-04-30 18:11:00 +0300 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:26:24 +0800 |
commit | b791083c0c38b324dc0544532c1e2398a5fd0e66 (patch) | |
tree | b00e465ab92e04790ab7cb8aab00edf73951050e /sound | |
parent | c31c995c4a4f3c7a5f88458ced069a2b683b9fb7 (diff) |
ASoC: fsl: refine the asrc driver for imx8qm
The clock source of ASRC in imx8qm is changed.
Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/fsl/fsl_asrc.c | 44 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_asrc.h | 1 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_asrc_dma.c | 50 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_asrc_m2m.c | 17 |
4 files changed, 89 insertions, 23 deletions
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 0e8bf263ed1a..9d85c2ee9fc3 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -54,23 +54,55 @@ static struct snd_pcm_hw_constraint_list fsl_asrc_rate_constraints = { */ static unsigned char input_clk_map_imx35[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, }; static unsigned char output_clk_map_imx35[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, }; /* i.MX53 uses the same map for input and output */ static unsigned char input_clk_map_imx53[] = { /* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */ 0x0, 0x1, 0x2, 0x7, 0x4, 0x5, 0x6, 0x3, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xe, 0xd, + 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, + 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, }; static unsigned char output_clk_map_imx53[] = { /* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */ 0x8, 0x9, 0xa, 0x7, 0xc, 0x5, 0x6, 0xb, 0x0, 0x1, 0x2, 0x3, 0x4, 0xf, 0xe, 0xd, + 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, + 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, }; +/* i.MX8 uses the same map for input and output */ +static unsigned char input_clk_map_imx8_0[] = { + 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, +}; + +static unsigned char output_clk_map_imx8_0[] = { + 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, +}; + +static unsigned char input_clk_map_imx8_1[] = { + 0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0, + 0x0, 0x1, 0x2, 0x3, 0xb, 0xc, 0xf, 0xf, 0xd, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, + 0x4, 0x5, 0x6, 0xf, 0x8, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, +}; + +static unsigned char output_clk_map_imx8_1[] = { + 0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0, + 0x0, 0x1, 0x2, 0x3, 0xb, 0xc, 0xf, 0xf, 0xd, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, + 0x4, 0x5, 0x6, 0xf, 0x8, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, +}; static unsigned char *clk_map[2]; /** @@ -1037,10 +1069,18 @@ static int fsl_asrc_probe(struct platform_device *pdev) asrc_priv->channel_bits = 3; clk_map[IN] = input_clk_map_imx35; clk_map[OUT] = output_clk_map_imx35; - } else { + } else if (of_device_is_compatible(np, "fsl,imx53-asrc")) { asrc_priv->channel_bits = 4; clk_map[IN] = input_clk_map_imx53; clk_map[OUT] = output_clk_map_imx53; + } else if (of_device_is_compatible(np, "fsl,imx8qm-asrc0")) { + asrc_priv->channel_bits = 4; + clk_map[IN] = input_clk_map_imx8_0; + clk_map[OUT] = output_clk_map_imx8_0; + } else if (of_device_is_compatible(np, "fsl,imx8qm-asrc1")) { + asrc_priv->channel_bits = 4; + clk_map[IN] = input_clk_map_imx8_1; + clk_map[OUT] = output_clk_map_imx8_1; } ret = fsl_asrc_init(asrc_priv); @@ -1204,6 +1244,8 @@ static const struct dev_pm_ops fsl_asrc_pm = { static const struct of_device_id fsl_asrc_ids[] = { { .compatible = "fsl,imx35-asrc", }, { .compatible = "fsl,imx53-asrc", }, + { .compatible = "fsl,imx8qm-asrc0", }, + { .compatible = "fsl,imx8qm-asrc1", }, {} }; MODULE_DEVICE_TABLE(of, fsl_asrc_ids); diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index df332fc9afcb..f4d7faf20262 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h @@ -293,7 +293,6 @@ struct dma_block { - dma_addr_t dma_paddr; void *dma_vaddr; unsigned int length; }; diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index cdbba974c5e9..4c35a37a3110 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c @@ -211,25 +211,43 @@ static int fsl_asrc_dma_hw_params(struct snd_pcm_substream *substream, /* Get DMA request of Back-End */ tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx"); - tmp_data = tmp_chan->private; - pair->dma_data.dma_request = tmp_data->dma_request; - be_peripheral_type = tmp_data->peripheral_type; - dma_release_channel(tmp_chan); + if (tmp_chan) { + tmp_data = tmp_chan->private; + if (tmp_data) { + pair->dma_data.dma_request = tmp_data->dma_request; + be_peripheral_type = tmp_data->peripheral_type; + if (tx && be_peripheral_type == IMX_DMATYPE_SSI_DUAL) + pair->dma_data.dst_dualfifo = true; + if (!tx && be_peripheral_type == IMX_DMATYPE_SSI_DUAL) + pair->dma_data.src_dualfifo = true; + } + dma_release_channel(tmp_chan); + } /* Get DMA request of Front-End */ tmp_chan = fsl_asrc_get_dma_channel(pair, dir); - tmp_data = tmp_chan->private; - pair->dma_data.dma_request2 = tmp_data->dma_request; - pair->dma_data.peripheral_type = tmp_data->peripheral_type; - pair->dma_data.priority = tmp_data->priority; - dma_release_channel(tmp_chan); - - if (tx && be_peripheral_type == IMX_DMATYPE_SSI_DUAL) - pair->dma_data.dst_dualfifo = true; - if (!tx && be_peripheral_type == IMX_DMATYPE_SSI_DUAL) - pair->dma_data.src_dualfifo = true; - - pair->dma_chan[dir] = dma_request_channel(mask, filter, &pair->dma_data); + if (tmp_chan) { + tmp_data = tmp_chan->private; + if (tmp_data) { + pair->dma_data.dma_request2 = tmp_data->dma_request; + pair->dma_data.peripheral_type = + tmp_data->peripheral_type; + pair->dma_data.priority = tmp_data->priority; + } + dma_release_channel(tmp_chan); + } + + /* For sdma DEV_TO_DEV, there is two dma request + * But for emda DEV_TO_DEV, there is only one dma request, which is + * from the BE. + */ + if (pair->dma_data.dma_request2 != pair->dma_data.dma_request) + pair->dma_chan[dir] = + dma_request_channel(mask, filter, &pair->dma_data); + else + pair->dma_chan[dir] = + dma_request_slave_channel(dev_be, tx ? "tx" : "rx"); + if (!pair->dma_chan[dir]) { dev_err(dev, "failed to request DMA channel for Back-End\n"); return -EINVAL; diff --git a/sound/soc/fsl/fsl_asrc_m2m.c b/sound/soc/fsl/fsl_asrc_m2m.c index 7363dc003aa6..f0b335697445 100644 --- a/sound/soc/fsl/fsl_asrc_m2m.c +++ b/sound/soc/fsl/fsl_asrc_m2m.c @@ -134,14 +134,12 @@ static int fsl_allocate_dma_buf(struct fsl_asrc_pair *pair) pair_err("failed to allocate input DMA buffer\n"); return -ENOMEM; } - input->dma_paddr = virt_to_dma(NULL, input->dma_vaddr); output->dma_vaddr = kzalloc(output->length, GFP_KERNEL); if (!output->dma_vaddr) { pair_err("failed to allocate output DMA buffer\n"); goto exit; } - output->dma_paddr = virt_to_dma(NULL, output->dma_vaddr); return 0; @@ -812,6 +810,7 @@ static int fsl_asrc_open(struct inode *inode, struct file *file) struct fsl_asrc_pair *pair; struct fsl_asrc_m2m *m2m; int ret; + int i; ret = signal_pending(current); if (ret) { @@ -839,7 +838,11 @@ static int fsl_asrc_open(struct inode *inode, struct file *file) file->private_data = pair; - pm_runtime_get_sync(dev); + clk_prepare_enable(asrc_priv->mem_clk); + clk_prepare_enable(asrc_priv->ipg_clk); + clk_prepare_enable(asrc_priv->spba_clk); + for (i = 0; i < ASRC_CLK_MAX_NUM; i++) + clk_prepare_enable(asrc_priv->asrck_clk[i]); return 0; out: @@ -853,8 +856,8 @@ static int fsl_asrc_close(struct inode *inode, struct file *file) struct fsl_asrc_pair *pair = file->private_data; struct fsl_asrc_m2m *m2m = pair->private; struct fsl_asrc *asrc_priv = pair->asrc_priv; - struct device *dev = &asrc_priv->pdev->dev; unsigned long lock_flags; + int i; if (m2m->asrc_active) { m2m->asrc_active = 0; @@ -890,7 +893,11 @@ static int fsl_asrc_close(struct inode *inode, struct file *file) spin_unlock_irqrestore(&asrc_priv->lock, lock_flags); file->private_data = NULL; - pm_runtime_put_sync(dev); + for (i = 0; i < ASRC_CLK_MAX_NUM; i++) + clk_disable_unprepare(asrc_priv->asrck_clk[i]); + clk_disable_unprepare(asrc_priv->spba_clk); + clk_disable_unprepare(asrc_priv->ipg_clk); + clk_disable_unprepare(asrc_priv->mem_clk); return 0; } |