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>
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>
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.
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
783802static 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
10511078static 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+
12131256static 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 ;
0 commit comments