Skip to content

Commit b4a39b5

Browse files
committed
Merge branch 'sound/upstream-20220421' into merge/sound-upstream-20220421
2 parents fdc727f + e89e770 commit b4a39b5

37 files changed

Lines changed: 3368 additions & 495 deletions

Documentation/sound/alsa-configuration.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2246,7 +2246,7 @@ implicit_fb
22462246
Apply the generic implicit feedback sync mode. When this is set
22472247
and the playback stream sync mode is ASYNC, the driver tries to
22482248
tie an adjacent ASYNC capture stream as the implicit feedback
2249-
source.
2249+
source. This is equivalent with quirk_flags bit 17.
22502250
use_vmalloc
22512251
Use vmalloc() for allocations of the PCM buffers (default: yes).
22522252
For architectures with non-coherent memory like ARM or MIPS, the
@@ -2288,6 +2288,8 @@ quirk_flags
22882288
* bit 14: Ignore errors for mixer access
22892289
* bit 15: Support generic DSD raw U32_BE format
22902290
* bit 16: Set up the interface at first like UAC1
2291+
* bit 17: Apply the generic implicit feedback sync mode
2292+
* bit 18: Don't apply implicit feedback sync mode
22912293

22922294
This module supports multiple devices, autoprobe and hotplugging.
22932295

drivers/dma/imx-dma.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include <linux/of_dma.h>
2626

2727
#include <asm/irq.h>
28-
#include <linux/platform_data/dma-imx.h>
28+
#include <linux/dma/imx-dma.h>
2929

3030
#include "dmaengine.h"
3131
#define IMXDMA_MAX_CHAN_DESCRIPTORS 16

drivers/dma/imx-sdma.c

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/iopoll.h>
1515
#include <linux/module.h>
1616
#include <linux/types.h>
17+
#include <linux/bitfield.h>
1718
#include <linux/bitops.h>
1819
#include <linux/mm.h>
1920
#include <linux/interrupt.h>
@@ -35,7 +36,7 @@
3536
#include <linux/workqueue.h>
3637

3738
#include <asm/irq.h>
38-
#include <linux/platform_data/dma-imx.h>
39+
#include <linux/dma/imx-dma.h>
3940
#include <linux/regmap.h>
4041
#include <linux/mfd/syscon.h>
4142
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
@@ -73,6 +74,7 @@
7374
#define SDMA_CHNENBL0_IMX35 0x200
7475
#define SDMA_CHNENBL0_IMX31 0x080
7576
#define SDMA_CHNPRI_0 0x100
77+
#define SDMA_DONE0_CONFIG 0x1000
7678

7779
/*
7880
* Buffer descriptor status values.
@@ -180,6 +182,12 @@
180182
BIT(DMA_MEM_TO_DEV) | \
181183
BIT(DMA_DEV_TO_DEV))
182184

185+
#define SDMA_WATERMARK_LEVEL_N_FIFOS GENMASK(15, 12)
186+
#define SDMA_WATERMARK_LEVEL_SW_DONE BIT(23)
187+
188+
#define SDMA_DONE0_CONFIG_DONE_SEL BIT(7)
189+
#define SDMA_DONE0_CONFIG_DONE_DIS BIT(6)
190+
183191
/**
184192
* struct sdma_script_start_addrs - SDMA script start pointers
185193
*
@@ -441,6 +449,9 @@ struct sdma_channel {
441449
struct work_struct terminate_worker;
442450
struct list_head terminated;
443451
bool is_ram_script;
452+
unsigned int n_fifos_src;
453+
unsigned int n_fifos_dst;
454+
bool sw_done;
444455
};
445456

446457
#define IMX_DMA_SG_LOOP BIT(0)
@@ -778,6 +789,14 @@ static void sdma_event_enable(struct sdma_channel *sdmac, unsigned int event)
778789
val = readl_relaxed(sdma->regs + chnenbl);
779790
__set_bit(channel, &val);
780791
writel_relaxed(val, sdma->regs + chnenbl);
792+
793+
/* Set SDMA_DONEx_CONFIG is sw_done enabled */
794+
if (sdmac->sw_done) {
795+
val = readl_relaxed(sdma->regs + SDMA_DONE0_CONFIG);
796+
val |= SDMA_DONE0_CONFIG_DONE_SEL;
797+
val &= ~SDMA_DONE0_CONFIG_DONE_DIS;
798+
writel_relaxed(val, sdma->regs + SDMA_DONE0_CONFIG);
799+
}
781800
}
782801

783802
static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event)
@@ -940,7 +959,7 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
940959
/*
941960
* sets the pc of SDMA script according to the peripheral type
942961
*/
943-
static void sdma_get_pc(struct sdma_channel *sdmac,
962+
static int sdma_get_pc(struct sdma_channel *sdmac,
944963
enum sdma_peripheral_type peripheral_type)
945964
{
946965
struct sdma_engine *sdma = sdmac->sdma;
@@ -1038,14 +1057,22 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
10381057
case IMX_DMATYPE_IPU_MEMORY:
10391058
emi_2_per = sdma->script_addrs->ext_mem_2_ipu_addr;
10401059
break;
1041-
default:
1060+
case IMX_DMATYPE_MULTI_SAI:
1061+
per_2_emi = sdma->script_addrs->sai_2_mcu_addr;
1062+
emi_2_per = sdma->script_addrs->mcu_2_sai_addr;
10421063
break;
1064+
default:
1065+
dev_err(sdma->dev, "Unsupported transfer type %d\n",
1066+
peripheral_type);
1067+
return -EINVAL;
10431068
}
10441069

10451070
sdmac->pc_from_device = per_2_emi;
10461071
sdmac->pc_to_device = emi_2_per;
10471072
sdmac->device_to_device = per_2_per;
10481073
sdmac->pc_to_pc = emi_2_emi;
1074+
1075+
return 0;
10491076
}
10501077

10511078
static int sdma_load_context(struct sdma_channel *sdmac)
@@ -1210,9 +1237,26 @@ static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
12101237
sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_CONT;
12111238
}
12121239

1240+
static void sdma_set_watermarklevel_for_sais(struct sdma_channel *sdmac)
1241+
{
1242+
unsigned int n_fifos;
1243+
1244+
if (sdmac->sw_done)
1245+
sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_SW_DONE;
1246+
1247+
if (sdmac->direction == DMA_DEV_TO_MEM)
1248+
n_fifos = sdmac->n_fifos_src;
1249+
else
1250+
n_fifos = sdmac->n_fifos_dst;
1251+
1252+
sdmac->watermark_level |=
1253+
FIELD_PREP(SDMA_WATERMARK_LEVEL_N_FIFOS, n_fifos);
1254+
}
1255+
12131256
static int sdma_config_channel(struct dma_chan *chan)
12141257
{
12151258
struct sdma_channel *sdmac = to_sdma_chan(chan);
1259+
int ret;
12161260

12171261
sdma_disable_channel(chan);
12181262

@@ -1233,7 +1277,9 @@ static int sdma_config_channel(struct dma_chan *chan)
12331277
break;
12341278
}
12351279

1236-
sdma_get_pc(sdmac, sdmac->peripheral_type);
1280+
ret = sdma_get_pc(sdmac, sdmac->peripheral_type);
1281+
if (ret)
1282+
return ret;
12371283

12381284
if ((sdmac->peripheral_type != IMX_DMATYPE_MEMORY) &&
12391285
(sdmac->peripheral_type != IMX_DMATYPE_DSP)) {
@@ -1243,6 +1289,10 @@ static int sdma_config_channel(struct dma_chan *chan)
12431289
sdmac->peripheral_type == IMX_DMATYPE_ASRC)
12441290
sdma_set_watermarklevel_for_p2p(sdmac);
12451291
} else {
1292+
if (sdmac->peripheral_type ==
1293+
IMX_DMATYPE_MULTI_SAI)
1294+
sdma_set_watermarklevel_for_sais(sdmac);
1295+
12461296
__set_bit(sdmac->event_id0, sdmac->event_mask);
12471297
}
12481298

@@ -1349,7 +1399,9 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
13491399
mem_data.dma_request2 = 0;
13501400
data = &mem_data;
13511401

1352-
sdma_get_pc(sdmac, IMX_DMATYPE_MEMORY);
1402+
ret = sdma_get_pc(sdmac, IMX_DMATYPE_MEMORY);
1403+
if (ret)
1404+
return ret;
13531405
}
13541406

13551407
switch (data->priority) {
@@ -1698,9 +1750,23 @@ static int sdma_config(struct dma_chan *chan,
16981750
struct dma_slave_config *dmaengine_cfg)
16991751
{
17001752
struct sdma_channel *sdmac = to_sdma_chan(chan);
1753+
struct sdma_engine *sdma = sdmac->sdma;
17011754

17021755
memcpy(&sdmac->slave_config, dmaengine_cfg, sizeof(*dmaengine_cfg));
17031756

1757+
if (dmaengine_cfg->peripheral_config) {
1758+
struct sdma_peripheral_config *sdmacfg = dmaengine_cfg->peripheral_config;
1759+
if (dmaengine_cfg->peripheral_size != sizeof(struct sdma_peripheral_config)) {
1760+
dev_err(sdma->dev, "Invalid peripheral size %zu, expected %zu\n",
1761+
dmaengine_cfg->peripheral_size,
1762+
sizeof(struct sdma_peripheral_config));
1763+
return -EINVAL;
1764+
}
1765+
sdmac->n_fifos_src = sdmacfg->n_fifos_src;
1766+
sdmac->n_fifos_dst = sdmacfg->n_fifos_dst;
1767+
sdmac->sw_done = sdmacfg->sw_done;
1768+
}
1769+
17041770
/* Set ENBLn earlier to make sure dma request triggered after that */
17051771
if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events)
17061772
return -EINVAL;

drivers/mmc/host/mxcmmc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
#include <asm/irq.h>
4040
#include <linux/platform_data/mmc-mxcmmc.h>
4141

42-
#include <linux/platform_data/dma-imx.h>
42+
#include <linux/dma/imx-dma.h>
4343

4444
#define DRIVER_NAME "mxc-mmc"
4545
#define MXCMCI_TIMEOUT_MS 10000

drivers/spi/spi-fsl-lpspi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include <linux/of_device.h>
2121
#include <linux/pinctrl/consumer.h>
2222
#include <linux/platform_device.h>
23-
#include <linux/platform_data/dma-imx.h>
23+
#include <linux/dma/imx-dma.h>
2424
#include <linux/pm_runtime.h>
2525
#include <linux/slab.h>
2626
#include <linux/spi/spi.h>

drivers/spi/spi-imx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include <linux/of_device.h>
2525
#include <linux/property.h>
2626

27-
#include <linux/platform_data/dma-imx.h>
27+
#include <linux/dma/imx-dma.h>
2828

2929
#define DRIVER_NAME "spi_imx"
3030

drivers/tty/serial/imx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#include <linux/dma-mapping.h>
3131

3232
#include <asm/irq.h>
33-
#include <linux/platform_data/dma-imx.h>
33+
#include <linux/dma/imx-dma.h>
3434

3535
#include "serial_mctrl_gpio.h"
3636

drivers/video/fbdev/mx3fb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include <linux/dma/ipu-dma.h>
2727
#include <linux/backlight.h>
2828

29-
#include <linux/platform_data/dma-imx.h>
29+
#include <linux/dma/imx-dma.h>
3030
#include <linux/platform_data/video-mx3fb.h>
3131

3232
#include <asm/io.h>
Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
* Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
44
*/
55

6-
#ifndef __ASM_ARCH_MXC_DMA_H__
7-
#define __ASM_ARCH_MXC_DMA_H__
6+
#ifndef __LINUX_DMA_IMX_H
7+
#define __LINUX_DMA_IMX_H
88

99
#include <linux/scatterlist.h>
1010
#include <linux/device.h>
@@ -39,6 +39,7 @@ enum sdma_peripheral_type {
3939
IMX_DMATYPE_SSI_DUAL, /* SSI Dual FIFO */
4040
IMX_DMATYPE_ASRC_SP, /* Shared ASRC */
4141
IMX_DMATYPE_SAI, /* SAI */
42+
IMX_DMATYPE_MULTI_SAI, /* MULTI FIFOs For Audio */
4243
};
4344

4445
enum imx_dma_prio {
@@ -65,4 +66,23 @@ static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
6566
!strcmp(chan->device->dev->driver->name, "imx-dma");
6667
}
6768

68-
#endif
69+
/**
70+
* struct sdma_peripheral_config - SDMA config for audio
71+
* @n_fifos_src: Number of FIFOs for recording
72+
* @n_fifos_dst: Number of FIFOs for playback
73+
* @sw_done: Use software done. Needed for PDM (micfil)
74+
*
75+
* Some i.MX Audio devices (SAI, micfil) have multiple successive FIFO
76+
* registers. For multichannel recording/playback the SAI/micfil have
77+
* one FIFO register per channel and the SDMA engine has to read/write
78+
* the next channel from/to the next register and wrap around to the
79+
* first register when all channels are handled. The number of active
80+
* channels must be communicated to the SDMA engine using this struct.
81+
*/
82+
struct sdma_peripheral_config {
83+
int n_fifos_src;
84+
int n_fifos_dst;
85+
bool sw_done;
86+
};
87+
88+
#endif /* __LINUX_DMA_IMX_H */

0 commit comments

Comments
 (0)