1
0
Fork 0

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>
zero-colors
Viorel Suman 2017-04-30 18:11:00 +03:00 committed by Dong Aisheng
parent 096ff09cc5
commit eb267cdcaa
6 changed files with 134 additions and 22 deletions

View File

@ -8,7 +8,8 @@ three substreams within totally 10 channels.
Required properties:
- compatible : Contains "fsl,imx35-asrc" or "fsl,imx53-asrc".
- compatible : Contains "fsl,imx35-asrc", "fsl,imx53-asrc",
"fsl,imx8qm-asrc0" or "fsl,imx8qm-asrc1".
- reg : Offset and length of the register set for the device.

View File

@ -53,6 +53,28 @@ enum asrc_inclk {
INCLK_SSI3_TX = 0x0b,
INCLK_SPDIF_TX = 0x0c,
INCLK_ASRCK1_CLK = 0x0f,
/* imx8 */
INCLK_AUD_PLL_DIV_CLK0 = 0x10,
INCLK_AUD_PLL_DIV_CLK1 = 0x11,
INCLK_AUD_CLK0 = 0x12,
INCLK_AUD_CLK1 = 0x13,
INCLK_ESAI0_RX_CLK = 0x14,
INCLK_ESAI0_TX_CLK = 0x15,
INCLK_SPDIF0_RX = 0x16,
INCLK_SPDIF1_RX = 0x17,
INCLK_SAI0_RX_BCLK = 0x18,
INCLK_SAI0_TX_BCLK = 0x19,
INCLK_SAI1_RX_BCLK = 0x1a,
INCLK_SAI1_TX_BCLK = 0x1b,
INCLK_SAI2_RX_BCLK = 0x1c,
INCLK_SAI3_RX_BCLK = 0x1d,
INCLK_ASRC0_MUX_CLK = 0x1e,
INCLK_ESAI1_RX_CLK = 0x20,
INCLK_ESAI1_TX_CLK = 0x21,
INCLK_SAI6_TX_BCLK = 0x22,
INCLK_HDMI_RX_SAI0_RX_BCLK = 0x24,
INCLK_HDMI_TX_SAI0_TX_BCLK = 0x25,
};
enum asrc_outclk {
@ -70,6 +92,29 @@ enum asrc_outclk {
OUTCLK_SSI3_RX = 0x0b,
OUTCLK_SPDIF_RX = 0x0c,
OUTCLK_ASRCK1_CLK = 0x0f,
/* imx8 */
OUTCLK_AUD_PLL_DIV_CLK0 = 0x10,
OUTCLK_AUD_PLL_DIV_CLK1 = 0x11,
OUTCLK_AUD_CLK0 = 0x12,
OUTCLK_AUD_CLK1 = 0x13,
OUTCLK_ESAI0_RX_CLK = 0x14,
OUTCLK_ESAI0_TX_CLK = 0x15,
OUTCLK_SPDIF0_RX = 0x16,
OUTCLK_SPDIF1_RX = 0x17,
OUTCLK_SAI0_RX_BCLK = 0x18,
OUTCLK_SAI0_TX_BCLK = 0x19,
OUTCLK_SAI1_RX_BCLK = 0x1a,
OUTCLK_SAI1_TX_BCLK = 0x1b,
OUTCLK_SAI2_RX_BCLK = 0x1c,
OUTCLK_SAI3_RX_BCLK = 0x1d,
OUTCLK_ASRCO_MUX_CLK = 0x1e,
OUTCLK_ESAI1_RX_CLK = 0x20,
OUTCLK_ESAI1_TX_CLK = 0x21,
OUTCLK_SAI6_TX_BCLK = 0x22,
OUTCLK_HDMI_RX_SAI0_RX_BCLK = 0x24,
OUTCLK_HDMI_TX_SAI0_TX_BCLK = 0x25,
};
enum asrc_word_width {

View File

@ -49,23 +49,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];
/**
@ -963,10 +995,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);
@ -1119,6 +1159,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);

View File

@ -290,7 +290,6 @@
struct dma_block {
dma_addr_t dma_paddr;
void *dma_vaddr;
unsigned int length;
};

View File

@ -202,25 +202,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 (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);
}
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;
/* 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");
pair->dma_chan[dir] = dma_request_channel(mask, filter, &pair->dma_data);
if (!pair->dma_chan[dir]) {
dev_err(dev, "failed to request DMA channel for Back-End\n");
return -EINVAL;

View File

@ -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;
}