2024-03-04 04:33:43

by Frank Li

[permalink] [raw]
Subject: [PATCH 0/4] dmaengine: fsl-sdma: Some improvement for fsl-sdma

To: Vinod Koul <[email protected]>
To: Shawn Guo <[email protected]>
To: Sascha Hauer <[email protected]>
To: Pengutronix Kernel Team <[email protected]>
To: Fabio Estevam <[email protected]>
To: NXP Linux Team <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]

Signed-off-by: Frank Li <[email protected]>
---
Joy Zou (1):
dmaengine: imx-sdma: Add multi fifo for DEV_TO_DEV

Nicolin Chen (1):
dmaengine: imx-sdma: Support allocate memory from internal SRAM (iram)

Robin Gong (1):
dmaengine: imx-sdma: Add i2c dma support

Shengjiu Wang (1):
dmaengine: imx-sdma: Support 24bit/3bytes for sg mode

drivers/dma/imx-sdma.c | 71 ++++++++++++++++++++++++++++++++++++---------
include/linux/dma/imx-dma.h | 1 +
2 files changed, 59 insertions(+), 13 deletions(-)
---
base-commit: af20f396b91f335f907422249285cc499fb4e0d8
change-id: 20240303-sdma_upstream-acebfa5b97f7

Best regards,
--
Frank Li <[email protected]>



2024-03-04 04:33:57

by Frank Li

[permalink] [raw]
Subject: [PATCH 1/4] dmaengine: imx-sdma: Support allocate memory from internal SRAM (iram)

From: Nicolin Chen <[email protected]>

Allocate memory from SoC internal SRAM to reduce DDR access and keep DDR in
lower power state (such as self-referesh) longer.

Check iram_pool before sdma_init() so that ccb/context could be allocated
from iram because DDR maybe in self-referesh in lower power audio case
while sdma still running.

Reviewed-by: Shengjiu Wang <[email protected]>
Signed-off-by: Nicolin Chen <[email protected]>
Signed-off-by: Joy Zou <[email protected]>
Signed-off-by: Frank Li <[email protected]>
---
drivers/dma/imx-sdma.c | 53 +++++++++++++++++++++++++++++++++++++-------------
1 file changed, 40 insertions(+), 13 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 9b42f5e96b1e0..9a6d8f1e9ff63 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -24,6 +24,7 @@
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/device.h>
+#include <linux/genalloc.h>
#include <linux/dma-mapping.h>
#include <linux/firmware.h>
#include <linux/slab.h>
@@ -516,6 +517,7 @@ struct sdma_engine {
void __iomem *regs;
struct sdma_context_data *context;
dma_addr_t context_phys;
+ dma_addr_t ccb_phys;
struct dma_device dma_device;
struct clk *clk_ipg;
struct clk *clk_ahb;
@@ -531,6 +533,7 @@ struct sdma_engine {
/* clock ratio for AHB:SDMA core. 1:1 is 1, 2:1 is 0*/
bool clk_ratio;
bool fw_loaded;
+ struct gen_pool *iram_pool;
};

static int sdma_config_write(struct dma_chan *chan,
@@ -1358,8 +1361,14 @@ static int sdma_request_channel0(struct sdma_engine *sdma)
{
int ret = -EBUSY;

- sdma->bd0 = dma_alloc_coherent(sdma->dev, PAGE_SIZE, &sdma->bd0_phys,
- GFP_NOWAIT);
+ if (sdma->iram_pool)
+ sdma->bd0 = gen_pool_dma_alloc(sdma->iram_pool,
+ sizeof(struct sdma_buffer_descriptor),
+ &sdma->bd0_phys);
+ else
+ sdma->bd0 = dma_alloc_coherent(sdma->dev,
+ sizeof(struct sdma_buffer_descriptor),
+ &sdma->bd0_phys, GFP_NOWAIT);
if (!sdma->bd0) {
ret = -ENOMEM;
goto out;
@@ -1379,10 +1388,14 @@ static int sdma_request_channel0(struct sdma_engine *sdma)
static int sdma_alloc_bd(struct sdma_desc *desc)
{
u32 bd_size = desc->num_bd * sizeof(struct sdma_buffer_descriptor);
+ struct sdma_engine *sdma = desc->sdmac->sdma;
int ret = 0;

- desc->bd = dma_alloc_coherent(desc->sdmac->sdma->dev, bd_size,
- &desc->bd_phys, GFP_NOWAIT);
+ if (sdma->iram_pool)
+ desc->bd = gen_pool_dma_alloc(sdma->iram_pool, bd_size, &desc->bd_phys);
+ else
+ desc->bd = dma_alloc_coherent(sdma->dev, bd_size, &desc->bd_phys, GFP_NOWAIT);
+
if (!desc->bd) {
ret = -ENOMEM;
goto out;
@@ -1394,9 +1407,12 @@ static int sdma_alloc_bd(struct sdma_desc *desc)
static void sdma_free_bd(struct sdma_desc *desc)
{
u32 bd_size = desc->num_bd * sizeof(struct sdma_buffer_descriptor);
+ struct sdma_engine *sdma = desc->sdmac->sdma;

- dma_free_coherent(desc->sdmac->sdma->dev, bd_size, desc->bd,
- desc->bd_phys);
+ if (sdma->iram_pool)
+ gen_pool_free(sdma->iram_pool, (unsigned long)desc->bd, bd_size);
+ else
+ dma_free_coherent(desc->sdmac->sdma->dev, bd_size, desc->bd, desc->bd_phys);
}

static void sdma_desc_free(struct virt_dma_desc *vd)
@@ -2066,8 +2082,8 @@ static int sdma_get_firmware(struct sdma_engine *sdma,

static int sdma_init(struct sdma_engine *sdma)
{
+ int ccbsize;
int i, ret;
- dma_addr_t ccb_phys;

ret = clk_enable(sdma->clk_ipg);
if (ret)
@@ -2083,10 +2099,15 @@ static int sdma_init(struct sdma_engine *sdma)
/* Be sure SDMA has not started yet */
writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);

- sdma->channel_control = dma_alloc_coherent(sdma->dev,
- MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control) +
- sizeof(struct sdma_context_data),
- &ccb_phys, GFP_KERNEL);
+ ccbsize = MAX_DMA_CHANNELS * (sizeof(struct sdma_channel_control)
+ + sizeof(struct sdma_context_data));
+
+ if (sdma->iram_pool)
+ sdma->channel_control = gen_pool_dma_alloc(sdma->iram_pool,
+ ccbsize, &sdma->ccb_phys);
+ else
+ sdma->channel_control = dma_alloc_coherent(sdma->dev, ccbsize, &sdma->ccb_phys,
+ GFP_KERNEL);

if (!sdma->channel_control) {
ret = -ENOMEM;
@@ -2095,7 +2116,7 @@ static int sdma_init(struct sdma_engine *sdma)

sdma->context = (void *)sdma->channel_control +
MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control);
- sdma->context_phys = ccb_phys +
+ sdma->context_phys = sdma->ccb_phys +
MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control);

/* disable all channels */
@@ -2121,7 +2142,7 @@ static int sdma_init(struct sdma_engine *sdma)
else
writel_relaxed(0, sdma->regs + SDMA_H_CONFIG);

- writel_relaxed(ccb_phys, sdma->regs + SDMA_H_C0PTR);
+ writel_relaxed(sdma->ccb_phys, sdma->regs + SDMA_H_C0PTR);

/* Initializes channel's priorities */
sdma_set_channel_priority(&sdma->channel[0], 7);
@@ -2272,6 +2293,12 @@ static int sdma_probe(struct platform_device *pdev)
vchan_init(&sdmac->vc, &sdma->dma_device);
}

+ if (np) {
+ sdma->iram_pool = of_gen_pool_get(np, "iram", 0);
+ if (sdma->iram_pool)
+ dev_info(&pdev->dev, "alloc bd from iram.\n");
+ }
+
ret = sdma_init(sdma);
if (ret)
goto err_init;

--
2.34.1


2024-03-04 04:34:06

by Frank Li

[permalink] [raw]
Subject: [PATCH 2/4] dmaengine: imx-sdma: Support 24bit/3bytes for sg mode

From: Shengjiu Wang <[email protected]>

Update 3bytes buswidth that is supported by sdma.

Signed-off-by: Shengjiu Wang <[email protected]>
Signed-off-by: Vipul Kumar <[email protected]>
Signed-off-by: Srikanth Krishnakar <[email protected]>
Acked-by: Robin Gong <[email protected]>
Signed-off-by: Frank Li <[email protected]>
---
drivers/dma/imx-sdma.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 9a6d8f1e9ff63..ef45420485dac 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -176,6 +176,7 @@

#define SDMA_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+ BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))

#define SDMA_DMA_DIRECTIONS (BIT(DMA_DEV_TO_MEM) | \
@@ -1659,6 +1660,9 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
if (count & 3 || sg->dma_address & 3)
goto err_bd_out;
break;
+ case DMA_SLAVE_BUSWIDTH_3_BYTES:
+ bd->mode.command = 3;
+ break;
case DMA_SLAVE_BUSWIDTH_2_BYTES:
bd->mode.command = 2;
if (count & 1 || sg->dma_address & 1)

--
2.34.1


2024-03-04 04:34:20

by Frank Li

[permalink] [raw]
Subject: [PATCH 3/4] dmaengine: imx-sdma: Add multi fifo for DEV_TO_DEV

From: Joy Zou <[email protected]>

Support multi fifo for DEV_TO_DEV.

Signed-off-by: Joy Zou <[email protected]>
Signed-off-by: Frank Li <[email protected]>
---
drivers/dma/imx-sdma.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index ef45420485dac..9b133990afa39 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -169,6 +169,8 @@
#define SDMA_WATERMARK_LEVEL_SPDIF BIT(10)
#define SDMA_WATERMARK_LEVEL_SP BIT(11)
#define SDMA_WATERMARK_LEVEL_DP BIT(12)
+#define SDMA_WATERMARK_LEVEL_SD BIT(13)
+#define SDMA_WATERMARK_LEVEL_DD BIT(14)
#define SDMA_WATERMARK_LEVEL_HWML (0xFF << 16)
#define SDMA_WATERMARK_LEVEL_LWE BIT(28)
#define SDMA_WATERMARK_LEVEL_HWE BIT(29)
@@ -1259,6 +1261,11 @@ static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_DP;

sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_CONT;
+
+ if (sdmac->n_fifos_src > 1)
+ sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_SD;
+ if (sdmac->n_fifos_dst > 1)
+ sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_DD;
}

static void sdma_set_watermarklevel_for_sais(struct sdma_channel *sdmac)

--
2.34.1


2024-03-04 04:34:37

by Frank Li

[permalink] [raw]
Subject: [PATCH 4/4] dmaengine: imx-sdma: Add i2c dma support

From: Robin Gong <[email protected]>

New sdma script support i2c. So add I2C dma support.

Signed-off-by: Robin Gong <[email protected]>
Acked-by: Clark Wang <[email protected]>
Signed-off-by: Frank Li <[email protected]>
---
drivers/dma/imx-sdma.c | 7 +++++++
include/linux/dma/imx-dma.h | 1 +
2 files changed, 8 insertions(+)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 9b133990afa39..832be7eccb335 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -247,6 +247,8 @@ struct sdma_script_start_addrs {
s32 sai_2_mcu_addr;
s32 uart_2_mcu_rom_addr;
s32 uartsh_2_mcu_rom_addr;
+ s32 i2c_2_mcu_addr;
+ s32 mcu_2_i2c_addr;
/* End of v3 array */
s32 mcu_2_zqspi_addr;
/* End of v4 array */
@@ -1078,6 +1080,11 @@ static int sdma_get_pc(struct sdma_channel *sdmac,
per_2_emi = sdma->script_addrs->sai_2_mcu_addr;
emi_2_per = sdma->script_addrs->mcu_2_sai_addr;
break;
+ case IMX_DMATYPE_I2C:
+ per_2_emi = sdma->script_addrs->i2c_2_mcu_addr;
+ emi_2_per = sdma->script_addrs->mcu_2_i2c_addr;
+ sdmac->is_ram_script = true;
+ break;
case IMX_DMATYPE_HDMI:
emi_2_per = sdma->script_addrs->hdmi_dma_addr;
sdmac->is_ram_script = true;
diff --git a/include/linux/dma/imx-dma.h b/include/linux/dma/imx-dma.h
index cfec5f946e237..76a8de9ae1517 100644
--- a/include/linux/dma/imx-dma.h
+++ b/include/linux/dma/imx-dma.h
@@ -41,6 +41,7 @@ enum sdma_peripheral_type {
IMX_DMATYPE_SAI, /* SAI */
IMX_DMATYPE_MULTI_SAI, /* MULTI FIFOs For Audio */
IMX_DMATYPE_HDMI, /* HDMI Audio */
+ IMX_DMATYPE_I2C, /* I2C */
};

enum imx_dma_prio {

--
2.34.1


2024-03-04 11:13:51

by Fabio Estevam

[permalink] [raw]
Subject: Re: [PATCH 4/4] dmaengine: imx-sdma: Add i2c dma support

On Mon, Mar 4, 2024 at 1:33 AM Frank Li <[email protected]> wrote:
>
> From: Robin Gong <[email protected]>
>
> New sdma script support i2c. So add I2C dma support.

What is the SDMA firmware version that corresponds to this "new SDMA script"?

In which SoC has this been tested?

2024-03-04 11:44:45

by Daniel Baluta

[permalink] [raw]
Subject: Re: [PATCH 0/4] dmaengine: fsl-sdma: Some improvement for fsl-sdma

On Mon, Mar 4, 2024 at 6:33 AM Frank Li <[email protected]> wrote:
>
> To: Vinod Koul <[email protected]>
> To: Shawn Guo <[email protected]>
> To: Sascha Hauer <[email protected]>
> To: Pengutronix Kernel Team <[email protected]>
> To: Fabio Estevam <[email protected]>
> To: NXP Linux Team <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
>
> Signed-off-by: Frank Li <[email protected]>

Looks good to me. For all patches in the series.

Reviewed-by: Daniel Baluta <[email protected]>

2024-03-05 15:39:38

by Frank Li

[permalink] [raw]
Subject: Re: [PATCH 4/4] dmaengine: imx-sdma: Add i2c dma support

On Mon, Mar 04, 2024 at 08:12:09AM -0300, Fabio Estevam wrote:
> On Mon, Mar 4, 2024 at 1:33 AM Frank Li <[email protected]> wrote:
> >
> > From: Robin Gong <[email protected]>
> >
> > New sdma script support i2c. So add I2C dma support.
>
> What is the SDMA firmware version that corresponds to this "new SDMA script"?

sdma-6q: v3.5
sdma-7d: v4.5

>
> In which SoC has this been tested?
>

imx8mp and imx6ull.

> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

2024-03-06 08:44:03

by Daniel Baluta

[permalink] [raw]
Subject: Re: [PATCH 4/4] dmaengine: imx-sdma: Add i2c dma support

On Tue, Mar 5, 2024 at 5:39 PM Frank Li <[email protected]> wrote:
>
> On Mon, Mar 04, 2024 at 08:12:09AM -0300, Fabio Estevam wrote:
> > On Mon, Mar 4, 2024 at 1:33 AM Frank Li <[email protected]> wrote:
> > >
> > > From: Robin Gong <[email protected]>
> > >
> > > New sdma script support i2c. So add I2C dma support.
> >
> > What is the SDMA firmware version that corresponds to this "new SDMA script"?
>
> sdma-6q: v3.5
> sdma-7d: v4.5
>
> >
> > In which SoC has this been tested?
> >
>
> imx8mp and imx6ull.


This information should be present in the commit message.

2024-03-06 09:56:02

by Alexander Stein

[permalink] [raw]
Subject: Re: [PATCH 1/4] dmaengine: imx-sdma: Support allocate memory from internal SRAM (iram)

Hi Frank,

thanks for the patch.

Am Montag, 4. M?rz 2024, 05:32:53 CET schrieb Frank Li:
> From: Nicolin Chen <[email protected]>
>
> Allocate memory from SoC internal SRAM to reduce DDR access and keep DDR in
> lower power state (such as self-referesh) longer.
>
> Check iram_pool before sdma_init() so that ccb/context could be allocated
> from iram because DDR maybe in self-referesh in lower power audio case
> while sdma still running.
>
> Reviewed-by: Shengjiu Wang <[email protected]>
> Signed-off-by: Nicolin Chen <[email protected]>
> Signed-off-by: Joy Zou <[email protected]>
> Signed-off-by: Frank Li <[email protected]>
> ---
> drivers/dma/imx-sdma.c | 53 +++++++++++++++++++++++++++++++++++++-------------
> 1 file changed, 40 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index 9b42f5e96b1e0..9a6d8f1e9ff63 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -24,6 +24,7 @@
> #include <linux/semaphore.h>
> #include <linux/spinlock.h>
> #include <linux/device.h>
> +#include <linux/genalloc.h>
> #include <linux/dma-mapping.h>
> #include <linux/firmware.h>
> #include <linux/slab.h>
> @@ -516,6 +517,7 @@ struct sdma_engine {
> void __iomem *regs;
> struct sdma_context_data *context;
> dma_addr_t context_phys;
> + dma_addr_t ccb_phys;
> struct dma_device dma_device;
> struct clk *clk_ipg;
> struct clk *clk_ahb;
> @@ -531,6 +533,7 @@ struct sdma_engine {
> /* clock ratio for AHB:SDMA core. 1:1 is 1, 2:1 is 0*/
> bool clk_ratio;
> bool fw_loaded;
> + struct gen_pool *iram_pool;
> };
>
> static int sdma_config_write(struct dma_chan *chan,
> @@ -1358,8 +1361,14 @@ static int sdma_request_channel0(struct sdma_engine *sdma)
> {
> int ret = -EBUSY;
>
> - sdma->bd0 = dma_alloc_coherent(sdma->dev, PAGE_SIZE, &sdma->bd0_phys,
> - GFP_NOWAIT);
> + if (sdma->iram_pool)
> + sdma->bd0 = gen_pool_dma_alloc(sdma->iram_pool,
> + sizeof(struct sdma_buffer_descriptor),
> + &sdma->bd0_phys);
> + else
> + sdma->bd0 = dma_alloc_coherent(sdma->dev,
> + sizeof(struct sdma_buffer_descriptor),
> + &sdma->bd0_phys, GFP_NOWAIT);
> if (!sdma->bd0) {
> ret = -ENOMEM;
> goto out;
> @@ -1379,10 +1388,14 @@ static int sdma_request_channel0(struct sdma_engine *sdma)
> static int sdma_alloc_bd(struct sdma_desc *desc)
> {
> u32 bd_size = desc->num_bd * sizeof(struct sdma_buffer_descriptor);
> + struct sdma_engine *sdma = desc->sdmac->sdma;
> int ret = 0;
>
> - desc->bd = dma_alloc_coherent(desc->sdmac->sdma->dev, bd_size,
> - &desc->bd_phys, GFP_NOWAIT);
> + if (sdma->iram_pool)
> + desc->bd = gen_pool_dma_alloc(sdma->iram_pool, bd_size, &desc->bd_phys);
> + else
> + desc->bd = dma_alloc_coherent(sdma->dev, bd_size, &desc->bd_phys, GFP_NOWAIT);
> +
> if (!desc->bd) {
> ret = -ENOMEM;
> goto out;
> @@ -1394,9 +1407,12 @@ static int sdma_alloc_bd(struct sdma_desc *desc)
> static void sdma_free_bd(struct sdma_desc *desc)
> {
> u32 bd_size = desc->num_bd * sizeof(struct sdma_buffer_descriptor);
> + struct sdma_engine *sdma = desc->sdmac->sdma;
>
> - dma_free_coherent(desc->sdmac->sdma->dev, bd_size, desc->bd,
> - desc->bd_phys);
> + if (sdma->iram_pool)
> + gen_pool_free(sdma->iram_pool, (unsigned long)desc->bd, bd_size);
> + else
> + dma_free_coherent(desc->sdmac->sdma->dev, bd_size, desc->bd, desc->bd_phys);
> }
>
> static void sdma_desc_free(struct virt_dma_desc *vd)
> @@ -2066,8 +2082,8 @@ static int sdma_get_firmware(struct sdma_engine *sdma,
>
> static int sdma_init(struct sdma_engine *sdma)
> {
> + int ccbsize;
> int i, ret;
> - dma_addr_t ccb_phys;

What is the motivation to put ccb_phys to struct sdma_engine? AFAICS
this is only used in sdma_init. Also the following patches of this series
are not using the struct member.

Best regards,
Alexander

>
> ret = clk_enable(sdma->clk_ipg);
> if (ret)
> @@ -2083,10 +2099,15 @@ static int sdma_init(struct sdma_engine *sdma)
> /* Be sure SDMA has not started yet */
> writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);
>
> - sdma->channel_control = dma_alloc_coherent(sdma->dev,
> - MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control) +
> - sizeof(struct sdma_context_data),
> - &ccb_phys, GFP_KERNEL);
> + ccbsize = MAX_DMA_CHANNELS * (sizeof(struct sdma_channel_control)
> + + sizeof(struct sdma_context_data));
> +
> + if (sdma->iram_pool)
> + sdma->channel_control = gen_pool_dma_alloc(sdma->iram_pool,
> + ccbsize, &sdma->ccb_phys);
> + else
> + sdma->channel_control = dma_alloc_coherent(sdma->dev, ccbsize, &sdma->ccb_phys,
> + GFP_KERNEL);
>
> if (!sdma->channel_control) {
> ret = -ENOMEM;
> @@ -2095,7 +2116,7 @@ static int sdma_init(struct sdma_engine *sdma)
>
> sdma->context = (void *)sdma->channel_control +
> MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control);
> - sdma->context_phys = ccb_phys +
> + sdma->context_phys = sdma->ccb_phys +
> MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control);
>
> /* disable all channels */
> @@ -2121,7 +2142,7 @@ static int sdma_init(struct sdma_engine *sdma)
> else
> writel_relaxed(0, sdma->regs + SDMA_H_CONFIG);
>
> - writel_relaxed(ccb_phys, sdma->regs + SDMA_H_C0PTR);
> + writel_relaxed(sdma->ccb_phys, sdma->regs + SDMA_H_C0PTR);
>
> /* Initializes channel's priorities */
> sdma_set_channel_priority(&sdma->channel[0], 7);
> @@ -2272,6 +2293,12 @@ static int sdma_probe(struct platform_device *pdev)
> vchan_init(&sdmac->vc, &sdma->dma_device);
> }
>
> + if (np) {
> + sdma->iram_pool = of_gen_pool_get(np, "iram", 0);
> + if (sdma->iram_pool)
> + dev_info(&pdev->dev, "alloc bd from iram.\n");
> + }
> +
> ret = sdma_init(sdma);
> if (ret)
> goto err_init;
>
>


--
TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht M?nchen, HRB 105018
Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
http://www.tq-group.com/



2024-03-06 15:23:51

by Frank Li

[permalink] [raw]
Subject: Re: [PATCH 1/4] dmaengine: imx-sdma: Support allocate memory from internal SRAM (iram)

On Wed, Mar 06, 2024 at 10:55:00AM +0100, Alexander Stein wrote:
> Hi Frank,
>
> thanks for the patch.
>
> Am Montag, 4. M?rz 2024, 05:32:53 CET schrieb Frank Li:
> > From: Nicolin Chen <[email protected]>
> >
> > Allocate memory from SoC internal SRAM to reduce DDR access and keep DDR in
> > lower power state (such as self-referesh) longer.
> >
> > Check iram_pool before sdma_init() so that ccb/context could be allocated
> > from iram because DDR maybe in self-referesh in lower power audio case
> > while sdma still running.
> >
> > Reviewed-by: Shengjiu Wang <[email protected]>
> > Signed-off-by: Nicolin Chen <[email protected]>
> > Signed-off-by: Joy Zou <[email protected]>
> > Signed-off-by: Frank Li <[email protected]>
> > ---
> > drivers/dma/imx-sdma.c | 53 +++++++++++++++++++++++++++++++++++++-------------
> > 1 file changed, 40 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> > index 9b42f5e96b1e0..9a6d8f1e9ff63 100644
> > --- a/drivers/dma/imx-sdma.c
> > +++ b/drivers/dma/imx-sdma.c
> > @@ -24,6 +24,7 @@
> > #include <linux/semaphore.h>
> > #include <linux/spinlock.h>
> > #include <linux/device.h>
> > +#include <linux/genalloc.h>
> > #include <linux/dma-mapping.h>
> > #include <linux/firmware.h>
> > #include <linux/slab.h>
> > @@ -516,6 +517,7 @@ struct sdma_engine {
> > void __iomem *regs;
> > struct sdma_context_data *context;
> > dma_addr_t context_phys;
> > + dma_addr_t ccb_phys;
> > struct dma_device dma_device;
> > struct clk *clk_ipg;
> > struct clk *clk_ahb;
> > @@ -531,6 +533,7 @@ struct sdma_engine {
> > /* clock ratio for AHB:SDMA core. 1:1 is 1, 2:1 is 0*/
> > bool clk_ratio;
> > bool fw_loaded;
> > + struct gen_pool *iram_pool;
> > };
> >
> > static int sdma_config_write(struct dma_chan *chan,
> > @@ -1358,8 +1361,14 @@ static int sdma_request_channel0(struct sdma_engine *sdma)
> > {
> > int ret = -EBUSY;
> >
> > - sdma->bd0 = dma_alloc_coherent(sdma->dev, PAGE_SIZE, &sdma->bd0_phys,
> > - GFP_NOWAIT);
> > + if (sdma->iram_pool)
> > + sdma->bd0 = gen_pool_dma_alloc(sdma->iram_pool,
> > + sizeof(struct sdma_buffer_descriptor),
> > + &sdma->bd0_phys);
> > + else
> > + sdma->bd0 = dma_alloc_coherent(sdma->dev,
> > + sizeof(struct sdma_buffer_descriptor),
> > + &sdma->bd0_phys, GFP_NOWAIT);
> > if (!sdma->bd0) {
> > ret = -ENOMEM;
> > goto out;
> > @@ -1379,10 +1388,14 @@ static int sdma_request_channel0(struct sdma_engine *sdma)
> > static int sdma_alloc_bd(struct sdma_desc *desc)
> > {
> > u32 bd_size = desc->num_bd * sizeof(struct sdma_buffer_descriptor);
> > + struct sdma_engine *sdma = desc->sdmac->sdma;
> > int ret = 0;
> >
> > - desc->bd = dma_alloc_coherent(desc->sdmac->sdma->dev, bd_size,
> > - &desc->bd_phys, GFP_NOWAIT);
> > + if (sdma->iram_pool)
> > + desc->bd = gen_pool_dma_alloc(sdma->iram_pool, bd_size, &desc->bd_phys);
> > + else
> > + desc->bd = dma_alloc_coherent(sdma->dev, bd_size, &desc->bd_phys, GFP_NOWAIT);
> > +
> > if (!desc->bd) {
> > ret = -ENOMEM;
> > goto out;
> > @@ -1394,9 +1407,12 @@ static int sdma_alloc_bd(struct sdma_desc *desc)
> > static void sdma_free_bd(struct sdma_desc *desc)
> > {
> > u32 bd_size = desc->num_bd * sizeof(struct sdma_buffer_descriptor);
> > + struct sdma_engine *sdma = desc->sdmac->sdma;
> >
> > - dma_free_coherent(desc->sdmac->sdma->dev, bd_size, desc->bd,
> > - desc->bd_phys);
> > + if (sdma->iram_pool)
> > + gen_pool_free(sdma->iram_pool, (unsigned long)desc->bd, bd_size);
> > + else
> > + dma_free_coherent(desc->sdmac->sdma->dev, bd_size, desc->bd, desc->bd_phys);
> > }
> >
> > static void sdma_desc_free(struct virt_dma_desc *vd)
> > @@ -2066,8 +2082,8 @@ static int sdma_get_firmware(struct sdma_engine *sdma,
> >
> > static int sdma_init(struct sdma_engine *sdma)
> > {
> > + int ccbsize;
> > int i, ret;
> > - dma_addr_t ccb_phys;
>
> What is the motivation to put ccb_phys to struct sdma_engine? AFAICS
> this is only used in sdma_init. Also the following patches of this series
> are not using the struct member.

You are right. let me check other donwstream patches. If no one use it, it
should be local variable.

>
> Best regards,
> Alexander
>
> >
> > ret = clk_enable(sdma->clk_ipg);
> > if (ret)
> > @@ -2083,10 +2099,15 @@ static int sdma_init(struct sdma_engine *sdma)
> > /* Be sure SDMA has not started yet */
> > writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);
> >
> > - sdma->channel_control = dma_alloc_coherent(sdma->dev,
> > - MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control) +
> > - sizeof(struct sdma_context_data),
> > - &ccb_phys, GFP_KERNEL);
> > + ccbsize = MAX_DMA_CHANNELS * (sizeof(struct sdma_channel_control)
> > + + sizeof(struct sdma_context_data));
> > +
> > + if (sdma->iram_pool)
> > + sdma->channel_control = gen_pool_dma_alloc(sdma->iram_pool,
> > + ccbsize, &sdma->ccb_phys);
> > + else
> > + sdma->channel_control = dma_alloc_coherent(sdma->dev, ccbsize, &sdma->ccb_phys,
> > + GFP_KERNEL);
> >
> > if (!sdma->channel_control) {
> > ret = -ENOMEM;
> > @@ -2095,7 +2116,7 @@ static int sdma_init(struct sdma_engine *sdma)
> >
> > sdma->context = (void *)sdma->channel_control +
> > MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control);
> > - sdma->context_phys = ccb_phys +
> > + sdma->context_phys = sdma->ccb_phys +
> > MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control);
> >
> > /* disable all channels */
> > @@ -2121,7 +2142,7 @@ static int sdma_init(struct sdma_engine *sdma)
> > else
> > writel_relaxed(0, sdma->regs + SDMA_H_CONFIG);
> >
> > - writel_relaxed(ccb_phys, sdma->regs + SDMA_H_C0PTR);
> > + writel_relaxed(sdma->ccb_phys, sdma->regs + SDMA_H_C0PTR);
> >
> > /* Initializes channel's priorities */
> > sdma_set_channel_priority(&sdma->channel[0], 7);
> > @@ -2272,6 +2293,12 @@ static int sdma_probe(struct platform_device *pdev)
> > vchan_init(&sdmac->vc, &sdma->dma_device);
> > }
> >
> > + if (np) {
> > + sdma->iram_pool = of_gen_pool_get(np, "iram", 0);
> > + if (sdma->iram_pool)
> > + dev_info(&pdev->dev, "alloc bd from iram.\n");
> > + }
> > +
> > ret = sdma_init(sdma);
> > if (ret)
> > goto err_init;
> >
> >
>
>
> --
> TQ-Systems GmbH | M?hlstra?e 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht M?nchen, HRB 105018
> Gesch?ftsf?hrer: Detlef Schneider, R?diger Stahl, Stefan Schneider
> http://www.tq-group.com/
>
>

2024-03-07 08:22:37

by Joy Zou

[permalink] [raw]
Subject: RE: [PATCH 1/4] dmaengine: imx-sdma: Support allocate memory from internal SRAM (iram)


> -----Original Message-----
> From: Frank Li <[email protected]>
> Sent: 2024年3月6日 23:23
> To: Alexander Stein <[email protected]>
> Cc: Vinod Koul <[email protected]>; Shawn Guo <[email protected]>;
> Sascha Hauer <[email protected]>; Pengutronix Kernel Team
> <[email protected]>; Fabio Estevam <[email protected]>;
> dl-linux-imx <[email protected]>; [email protected];
> [email protected]; [email protected];
> [email protected]; Nicolin Chen <[email protected]>; S.J. Wang
> <[email protected]>; Joy Zou <[email protected]>
> Subject: Re: [PATCH 1/4] dmaengine: imx-sdma: Support allocate memory
> from internal SRAM (iram)
>
> On Wed, Mar 06, 2024 at 10:55:00AM +0100, Alexander Stein wrote:
> > Hi Frank,
> >
> > thanks for the patch.
> >
> > Am Montag, 4. März 2024, 05:32:53 CET schrieb Frank Li:
> > > From: Nicolin Chen <[email protected]>
> > >
> > > Allocate memory from SoC internal SRAM to reduce DDR access and keep
> > > DDR in lower power state (such as self-referesh) longer.
> > >
> > > Check iram_pool before sdma_init() so that ccb/context could be
> > > allocated from iram because DDR maybe in self-referesh in lower
> > > power audio case while sdma still running.
> > >
> > > Reviewed-by: Shengjiu Wang <[email protected]>
> > > Signed-off-by: Nicolin Chen <[email protected]>
> > > Signed-off-by: Joy Zou <[email protected]>
> > > Signed-off-by: Frank Li <[email protected]>
> > > ---
> > > drivers/dma/imx-sdma.c | 53
> > > +++++++++++++++++++++++++++++++++++++-------------
> > > 1 file changed, 40 insertions(+), 13 deletions(-)
> > >
> > > diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index
> > > 9b42f5e96b1e0..9a6d8f1e9ff63 100644
> > > --- a/drivers/dma/imx-sdma.c
> > > +++ b/drivers/dma/imx-sdma.c
> > > @@ -24,6 +24,7 @@
> > > #include <linux/semaphore.h>
> > > #include <linux/spinlock.h>
> > > #include <linux/device.h>
> > > +#include <linux/genalloc.h>
> > > #include <linux/dma-mapping.h>
> > > #include <linux/firmware.h>
> > > #include <linux/slab.h>
> > > @@ -516,6 +517,7 @@ struct sdma_engine {
> > > void __iomem *regs;
> > > struct sdma_context_data *context;
> > > dma_addr_t context_phys;
> > > + dma_addr_t ccb_phys;
> > > struct dma_device dma_device;
> > > struct clk *clk_ipg;
> > > struct clk *clk_ahb;
> > > @@ -531,6 +533,7 @@ struct sdma_engine {
> > > /* clock ratio for AHB:SDMA core. 1:1 is 1, 2:1 is 0*/
> > > bool clk_ratio;
> > > bool fw_loaded;
> > > + struct gen_pool *iram_pool;
> > > };
> > >
> > > static int sdma_config_write(struct dma_chan *chan, @@ -1358,8
> > > +1361,14 @@ static int sdma_request_channel0(struct sdma_engine
> > > *sdma) {
> > > int ret = -EBUSY;
> > >
> > > - sdma->bd0 = dma_alloc_coherent(sdma->dev, PAGE_SIZE,
> &sdma->bd0_phys,
> > > - GFP_NOWAIT);
> > > + if (sdma->iram_pool)
> > > + sdma->bd0 = gen_pool_dma_alloc(sdma->iram_pool,
> > > + sizeof(struct sdma_buffer_descriptor),
> > > + &sdma->bd0_phys);
> > > + else
> > > + sdma->bd0 = dma_alloc_coherent(sdma->dev,
> > > + sizeof(struct sdma_buffer_descriptor),
> > > + &sdma->bd0_phys, GFP_NOWAIT);
> > > if (!sdma->bd0) {
> > > ret = -ENOMEM;
> > > goto out;
> > > @@ -1379,10 +1388,14 @@ static int sdma_request_channel0(struct
> > > sdma_engine *sdma) static int sdma_alloc_bd(struct sdma_desc *desc)
> > > {
> > > u32 bd_size = desc->num_bd * sizeof(struct
> > > sdma_buffer_descriptor);
> > > + struct sdma_engine *sdma = desc->sdmac->sdma;
> > > int ret = 0;
> > >
> > > - desc->bd = dma_alloc_coherent(desc->sdmac->sdma->dev, bd_size,
> > > - &desc->bd_phys, GFP_NOWAIT);
> > > + if (sdma->iram_pool)
> > > + desc->bd = gen_pool_dma_alloc(sdma->iram_pool, bd_size,
> &desc->bd_phys);
> > > + else
> > > + desc->bd = dma_alloc_coherent(sdma->dev, bd_size,
> &desc->bd_phys,
> > > +GFP_NOWAIT);
> > > +
> > > if (!desc->bd) {
> > > ret = -ENOMEM;
> > > goto out;
> > > @@ -1394,9 +1407,12 @@ static int sdma_alloc_bd(struct sdma_desc
> > > *desc) static void sdma_free_bd(struct sdma_desc *desc) {
> > > u32 bd_size = desc->num_bd * sizeof(struct
> > > sdma_buffer_descriptor);
> > > + struct sdma_engine *sdma = desc->sdmac->sdma;
> > >
> > > - dma_free_coherent(desc->sdmac->sdma->dev, bd_size, desc->bd,
> > > - desc->bd_phys);
> > > + if (sdma->iram_pool)
> > > + gen_pool_free(sdma->iram_pool, (unsigned long)desc->bd,
> bd_size);
> > > + else
> > > + dma_free_coherent(desc->sdmac->sdma->dev, bd_size,
> desc->bd,
> > > +desc->bd_phys);
> > > }
> > >
> > > static void sdma_desc_free(struct virt_dma_desc *vd) @@ -2066,8
> > > +2082,8 @@ static int sdma_get_firmware(struct sdma_engine *sdma,
> > >
> > > static int sdma_init(struct sdma_engine *sdma) {
> > > + int ccbsize;
> > > int i, ret;
> > > - dma_addr_t ccb_phys;
> >
> > What is the motivation to put ccb_phys to struct sdma_engine? AFAICS
> > this is only used in sdma_init. Also the following patches of this
> > series are not using the struct member.
>
> You are right. let me check other donwstream patches. If no one use it, it
> should be local variable.
Hi frank,
Yes, it should be local variable in current patch. I have checked downstream patches. We have optimized the sdma_init function in other patch, this patch need to put ccb_phys to struct sdma_engine.

BR
Joy Zou
> >
> > Best regards,
> > Alexander
> >
> > >
> > > ret = clk_enable(sdma->clk_ipg);
> > > if (ret)
> > > @@ -2083,10 +2099,15 @@ static int sdma_init(struct sdma_engine
> *sdma)
> > > /* Be sure SDMA has not started yet */
> > > writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);
> > >
> > > - sdma->channel_control = dma_alloc_coherent(sdma->dev,
> > > - MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control)
> +
> > > - sizeof(struct sdma_context_data),
> > > - &ccb_phys, GFP_KERNEL);
> > > + ccbsize = MAX_DMA_CHANNELS * (sizeof(struct
> sdma_channel_control)
> > > + + sizeof(struct sdma_context_data));
> > > +
> > > + if (sdma->iram_pool)
> > > + sdma->channel_control =
> gen_pool_dma_alloc(sdma->iram_pool,
> > > + ccbsize, &sdma->ccb_phys);
> > > + else
> > > + sdma->channel_control = dma_alloc_coherent(sdma->dev,
> ccbsize, &sdma->ccb_phys,
> > > + GFP_KERNEL);
> > >
> > > if (!sdma->channel_control) {
> > > ret = -ENOMEM;
> > > @@ -2095,7 +2116,7 @@ static int sdma_init(struct sdma_engine
> *sdma)
> > >
> > > sdma->context = (void *)sdma->channel_control +
> > > MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control);
> > > - sdma->context_phys = ccb_phys +
> > > + sdma->context_phys = sdma->ccb_phys +
> > > MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control);
> > >
> > > /* disable all channels */
> > > @@ -2121,7 +2142,7 @@ static int sdma_init(struct sdma_engine
> *sdma)
> > > else
> > > writel_relaxed(0, sdma->regs + SDMA_H_CONFIG);
> > >
> > > - writel_relaxed(ccb_phys, sdma->regs + SDMA_H_C0PTR);
> > > + writel_relaxed(sdma->ccb_phys, sdma->regs + SDMA_H_C0PTR);
> > >
> > > /* Initializes channel's priorities */
> > > sdma_set_channel_priority(&sdma->channel[0], 7); @@ -2272,6
> > > +2293,12 @@ static int sdma_probe(struct platform_device *pdev)
> > > vchan_init(&sdmac->vc, &sdma->dma_device);
> > > }
> > >
> > > + if (np) {
> > > + sdma->iram_pool = of_gen_pool_get(np, "iram", 0);
> > > + if (sdma->iram_pool)
> > > + dev_info(&pdev->dev, "alloc bd from iram.\n");
> > > + }
> > > +
> > > ret = sdma_init(sdma);
> > > if (ret)
> > > goto err_init;
> > >
> > >
> >
> >
> > --
> > TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
> > Amtsgericht München, HRB 105018
> > Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
> > http://www.tq-group.com/
> >
> >

2024-03-07 08:35:09

by Joy Zou

[permalink] [raw]
Subject: RE: [PATCH 4/4] dmaengine: imx-sdma: Add i2c dma support



> -----Original Message-----
> From: Frank Li <[email protected]>
> Sent: 2024年3月4日 12:33
> To: Vinod Koul <[email protected]>; Shawn Guo <[email protected]>;
> Sascha Hauer <[email protected]>; Pengutronix Kernel Team
> <[email protected]>; Fabio Estevam <[email protected]>;
> dl-linux-imx <[email protected]>
> Cc: [email protected]; [email protected];
> [email protected]; [email protected]; Frank Li
> <[email protected]>; Robin Gong <[email protected]>; Clark Wang
> <[email protected]>
> Subject: [PATCH 4/4] dmaengine: imx-sdma: Add i2c dma support
>
> From: Robin Gong <[email protected]>
>
> New sdma script support i2c. So add I2C dma support.
>
> Signed-off-by: Robin Gong <[email protected]>
> Acked-by: Clark Wang <[email protected]>
> Signed-off-by: Frank Li <[email protected]>

Reviewed-by: Joy Zou <[email protected]>
BR
Joy Zou
> ---
> drivers/dma/imx-sdma.c | 7 +++++++
> include/linux/dma/imx-dma.h | 1 +
> 2 files changed, 8 insertions(+)
>
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index
> 9b133990afa39..832be7eccb335 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -247,6 +247,8 @@ struct sdma_script_start_addrs {
> s32 sai_2_mcu_addr;
> s32 uart_2_mcu_rom_addr;
> s32 uartsh_2_mcu_rom_addr;
> + s32 i2c_2_mcu_addr;
> + s32 mcu_2_i2c_addr;
> /* End of v3 array */
> s32 mcu_2_zqspi_addr;
> /* End of v4 array */
> @@ -1078,6 +1080,11 @@ static int sdma_get_pc(struct sdma_channel
> *sdmac,
> per_2_emi = sdma->script_addrs->sai_2_mcu_addr;
> emi_2_per = sdma->script_addrs->mcu_2_sai_addr;
> break;
> + case IMX_DMATYPE_I2C:
> + per_2_emi = sdma->script_addrs->i2c_2_mcu_addr;
> + emi_2_per = sdma->script_addrs->mcu_2_i2c_addr;
> + sdmac->is_ram_script = true;
> + break;
> case IMX_DMATYPE_HDMI:
> emi_2_per = sdma->script_addrs->hdmi_dma_addr;
> sdmac->is_ram_script = true;
> diff --git a/include/linux/dma/imx-dma.h b/include/linux/dma/imx-dma.h
> index cfec5f946e237..76a8de9ae1517 100644
> --- a/include/linux/dma/imx-dma.h
> +++ b/include/linux/dma/imx-dma.h
> @@ -41,6 +41,7 @@ enum sdma_peripheral_type {
> IMX_DMATYPE_SAI, /* SAI */
> IMX_DMATYPE_MULTI_SAI, /* MULTI FIFOs For Audio */
> IMX_DMATYPE_HDMI, /* HDMI Audio */
> + IMX_DMATYPE_I2C, /* I2C */
> };
>
> enum imx_dma_prio {
>
> --
> 2.34.1

2024-03-07 09:05:38

by Joy Zou

[permalink] [raw]
Subject: RE: [PATCH 2/4] dmaengine: imx-sdma: Support 24bit/3bytes for sg mode


> -----Original Message-----
> From: Frank Li <[email protected]>
> Sent: 2024年3月4日 12:33
> To: Vinod Koul <[email protected]>; Shawn Guo <[email protected]>;
> Sascha Hauer <[email protected]>; Pengutronix Kernel Team
> <[email protected]>; Fabio Estevam <[email protected]>;
> dl-linux-imx <[email protected]>
> Cc: [email protected]; [email protected];
> [email protected]; [email protected]; Frank Li
> <[email protected]>; S.J. Wang <[email protected]>; Vipul Kumar
> <[email protected]>; Srikanth Krishnakar
> <[email protected]>; Robin Gong <[email protected]>
> Subject: [PATCH 2/4] dmaengine: imx-sdma: Support 24bit/3bytes for sg
> mode
>
> From: Shengjiu Wang <[email protected]>
>
> Update 3bytes buswidth that is supported by sdma.
>
> Signed-off-by: Shengjiu Wang <[email protected]>
> Signed-off-by: Vipul Kumar <[email protected]>
> Signed-off-by: Srikanth Krishnakar <[email protected]>
> Acked-by: Robin Gong <[email protected]>
> Signed-off-by: Frank Li <[email protected]>
Reviewed-by: Joy Zou <[email protected]>
BR
Joy Zou
> ---
> drivers/dma/imx-sdma.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index
> 9a6d8f1e9ff63..ef45420485dac 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -176,6 +176,7 @@
>
> #define SDMA_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE)
> | \
> BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
> + BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
> BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
>
> #define SDMA_DMA_DIRECTIONS (BIT(DMA_DEV_TO_MEM) | \
> @@ -1659,6 +1660,9 @@ static struct dma_async_tx_descriptor
> *sdma_prep_slave_sg(
> if (count & 3 || sg->dma_address & 3)
> goto err_bd_out;
> break;
> + case DMA_SLAVE_BUSWIDTH_3_BYTES:
> + bd->mode.command = 3;
> + break;
> case DMA_SLAVE_BUSWIDTH_2_BYTES:
> bd->mode.command = 2;
> if (count & 1 || sg->dma_address & 1)
>
> --
> 2.34.1

2024-03-07 09:06:38

by Joy Zou

[permalink] [raw]
Subject: RE: [PATCH 3/4] dmaengine: imx-sdma: Add multi fifo for DEV_TO_DEV


> -----Original Message-----
> From: Frank Li <[email protected]>
> Sent: 2024年3月4日 12:33
> To: Vinod Koul <[email protected]>; Shawn Guo <[email protected]>;
> Sascha Hauer <[email protected]>; Pengutronix Kernel Team
> <[email protected]>; Fabio Estevam <[email protected]>;
> dl-linux-imx <[email protected]>
> Cc: [email protected]; [email protected];
> [email protected]; [email protected]; Frank Li
> <[email protected]>; Joy Zou <[email protected]>
> Subject: [PATCH 3/4] dmaengine: imx-sdma: Add multi fifo for DEV_TO_DEV
>
> From: Joy Zou <[email protected]>
>
> Support multi fifo for DEV_TO_DEV.
>
> Signed-off-by: Joy Zou <[email protected]>
> Signed-off-by: Frank Li <[email protected]>
Reviewed-by: Joy Zou <[email protected]>
BR
Joy Zou
> ---
> drivers/dma/imx-sdma.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index
> ef45420485dac..9b133990afa39 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -169,6 +169,8 @@
> #define SDMA_WATERMARK_LEVEL_SPDIF BIT(10)
> #define SDMA_WATERMARK_LEVEL_SP BIT(11)
> #define SDMA_WATERMARK_LEVEL_DP BIT(12)
> +#define SDMA_WATERMARK_LEVEL_SD BIT(13)
> +#define SDMA_WATERMARK_LEVEL_DD BIT(14)
> #define SDMA_WATERMARK_LEVEL_HWML (0xFF << 16)
> #define SDMA_WATERMARK_LEVEL_LWE BIT(28)
> #define SDMA_WATERMARK_LEVEL_HWE BIT(29)
> @@ -1259,6 +1261,11 @@ static void
> sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
> sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_DP;
>
> sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_CONT;
> +
> + if (sdmac->n_fifos_src > 1)
> + sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_SD;
> + if (sdmac->n_fifos_dst > 1)
> + sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_DD;
> }
>
> static void sdma_set_watermarklevel_for_sais(struct sdma_channel *sdmac)
>
> --
> 2.34.1