Skip to content

Commit 955b176

Browse files
ADESTMvinodkoul
authored andcommitted
dmaengine: stm32-dma: direct mode support through device tree
Direct mode or FIFO mode is computed by stm32-dma driver. Add a way for the user to force direct mode, by setting bit 2 in the bitfield value specifying DMA features in the device tree. Signed-off-by: Amelie Delaunay <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 86e673f commit 955b176

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

drivers/dma/stm32-dma.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
#define STM32_DMA_FIFO_THRESHOLD_HALFFULL 0x01
118118
#define STM32_DMA_FIFO_THRESHOLD_3QUARTERSFULL 0x02
119119
#define STM32_DMA_FIFO_THRESHOLD_FULL 0x03
120+
#define STM32_DMA_FIFO_THRESHOLD_NONE 0x04
120121

121122
#define STM32_DMA_MAX_DATA_ITEMS 0xffff
122123
/*
@@ -136,6 +137,9 @@
136137
/* DMA Features */
137138
#define STM32_DMA_THRESHOLD_FTR_MASK GENMASK(1, 0)
138139
#define STM32_DMA_THRESHOLD_FTR_GET(n) ((n) & STM32_DMA_THRESHOLD_FTR_MASK)
140+
#define STM32_DMA_DIRECT_MODE_MASK BIT(2)
141+
#define STM32_DMA_DIRECT_MODE_GET(n) (((n) & STM32_DMA_DIRECT_MODE_MASK) \
142+
>> 2)
139143

140144
enum stm32_dma_width {
141145
STM32_DMA_BYTE,
@@ -281,6 +285,9 @@ static bool stm32_dma_fifo_threshold_is_allowed(u32 burst, u32 threshold,
281285
{
282286
u32 remaining;
283287

288+
if (threshold == STM32_DMA_FIFO_THRESHOLD_NONE)
289+
return false;
290+
284291
if (width != DMA_SLAVE_BUSWIDTH_UNDEFINED) {
285292
if (burst != 0) {
286293
/*
@@ -302,6 +309,10 @@ static bool stm32_dma_fifo_threshold_is_allowed(u32 burst, u32 threshold,
302309

303310
static bool stm32_dma_is_burst_possible(u32 buf_len, u32 threshold)
304311
{
312+
/* If FIFO direct mode, burst is not possible */
313+
if (threshold == STM32_DMA_FIFO_THRESHOLD_NONE)
314+
return false;
315+
305316
/*
306317
* Buffer or period length has to be aligned on FIFO depth.
307318
* Otherwise bytes may be stuck within FIFO at buffer or period
@@ -657,6 +668,12 @@ static irqreturn_t stm32_dma_chan_irq(int irq, void *devid)
657668
dev_dbg(chan2dev(chan), "FIFO over/underrun\n");
658669
}
659670
}
671+
if (status & STM32_DMA_DMEI) {
672+
stm32_dma_irq_clear(chan, STM32_DMA_DMEI);
673+
status &= ~STM32_DMA_DMEI;
674+
if (sfcr & STM32_DMA_SCR_DMEIE)
675+
dev_dbg(chan2dev(chan), "Direct mode overrun\n");
676+
}
660677
if (status) {
661678
stm32_dma_irq_clear(chan, status);
662679
dev_err(chan2dev(chan), "DMA error: status=0x%08x\n", status);
@@ -692,13 +709,13 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
692709
int src_bus_width, dst_bus_width;
693710
int src_burst_size, dst_burst_size;
694711
u32 src_maxburst, dst_maxburst, src_best_burst, dst_best_burst;
695-
u32 dma_scr, threshold;
712+
u32 dma_scr, fifoth;
696713

697714
src_addr_width = chan->dma_sconfig.src_addr_width;
698715
dst_addr_width = chan->dma_sconfig.dst_addr_width;
699716
src_maxburst = chan->dma_sconfig.src_maxburst;
700717
dst_maxburst = chan->dma_sconfig.dst_maxburst;
701-
threshold = chan->threshold;
718+
fifoth = chan->threshold;
702719

703720
switch (direction) {
704721
case DMA_MEM_TO_DEV:
@@ -710,15 +727,15 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
710727
/* Set device burst size */
711728
dst_best_burst = stm32_dma_get_best_burst(buf_len,
712729
dst_maxburst,
713-
threshold,
730+
fifoth,
714731
dst_addr_width);
715732

716733
dst_burst_size = stm32_dma_get_burst(chan, dst_best_burst);
717734
if (dst_burst_size < 0)
718735
return dst_burst_size;
719736

720737
/* Set memory data size */
721-
src_addr_width = stm32_dma_get_max_width(buf_len, threshold);
738+
src_addr_width = stm32_dma_get_max_width(buf_len, fifoth);
722739
chan->mem_width = src_addr_width;
723740
src_bus_width = stm32_dma_get_width(chan, src_addr_width);
724741
if (src_bus_width < 0)
@@ -728,7 +745,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
728745
src_maxburst = STM32_DMA_MAX_BURST;
729746
src_best_burst = stm32_dma_get_best_burst(buf_len,
730747
src_maxburst,
731-
threshold,
748+
fifoth,
732749
src_addr_width);
733750
src_burst_size = stm32_dma_get_burst(chan, src_best_burst);
734751
if (src_burst_size < 0)
@@ -742,7 +759,8 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
742759

743760
/* Set FIFO threshold */
744761
chan->chan_reg.dma_sfcr &= ~STM32_DMA_SFCR_FTH_MASK;
745-
chan->chan_reg.dma_sfcr |= STM32_DMA_SFCR_FTH(threshold);
762+
if (fifoth != STM32_DMA_FIFO_THRESHOLD_NONE)
763+
chan->chan_reg.dma_sfcr |= STM32_DMA_SFCR_FTH(fifoth);
746764

747765
/* Set peripheral address */
748766
chan->chan_reg.dma_spar = chan->dma_sconfig.dst_addr;
@@ -758,15 +776,15 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
758776
/* Set device burst size */
759777
src_best_burst = stm32_dma_get_best_burst(buf_len,
760778
src_maxburst,
761-
threshold,
779+
fifoth,
762780
src_addr_width);
763781
chan->mem_burst = src_best_burst;
764782
src_burst_size = stm32_dma_get_burst(chan, src_best_burst);
765783
if (src_burst_size < 0)
766784
return src_burst_size;
767785

768786
/* Set memory data size */
769-
dst_addr_width = stm32_dma_get_max_width(buf_len, threshold);
787+
dst_addr_width = stm32_dma_get_max_width(buf_len, fifoth);
770788
chan->mem_width = dst_addr_width;
771789
dst_bus_width = stm32_dma_get_width(chan, dst_addr_width);
772790
if (dst_bus_width < 0)
@@ -776,7 +794,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
776794
dst_maxburst = STM32_DMA_MAX_BURST;
777795
dst_best_burst = stm32_dma_get_best_burst(buf_len,
778796
dst_maxburst,
779-
threshold,
797+
fifoth,
780798
dst_addr_width);
781799
chan->mem_burst = dst_best_burst;
782800
dst_burst_size = stm32_dma_get_burst(chan, dst_best_burst);
@@ -791,7 +809,8 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
791809

792810
/* Set FIFO threshold */
793811
chan->chan_reg.dma_sfcr &= ~STM32_DMA_SFCR_FTH_MASK;
794-
chan->chan_reg.dma_sfcr |= STM32_DMA_SFCR_FTH(threshold);
812+
if (fifoth != STM32_DMA_FIFO_THRESHOLD_NONE)
813+
chan->chan_reg.dma_sfcr |= STM32_DMA_SFCR_FTH(fifoth);
795814

796815
/* Set peripheral address */
797816
chan->chan_reg.dma_spar = chan->dma_sconfig.src_addr;
@@ -1216,6 +1235,8 @@ static void stm32_dma_set_config(struct stm32_dma_chan *chan,
12161235
chan->chan_reg.dma_scr |= STM32_DMA_SCR_TEIE | STM32_DMA_SCR_TCIE;
12171236

12181237
chan->threshold = STM32_DMA_THRESHOLD_FTR_GET(cfg->features);
1238+
if (STM32_DMA_DIRECT_MODE_GET(cfg->features))
1239+
chan->threshold = STM32_DMA_FIFO_THRESHOLD_NONE;
12191240
}
12201241

12211242
static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec,

0 commit comments

Comments
 (0)