summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.4/0396-dmaengine-bcm2835-limit-max-length-based-on-channel-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-4.4/0396-dmaengine-bcm2835-limit-max-length-based-on-channel-.patch')
-rw-r--r--target/linux/brcm2708/patches-4.4/0396-dmaengine-bcm2835-limit-max-length-based-on-channel-.patch114
1 files changed, 0 insertions, 114 deletions
diff --git a/target/linux/brcm2708/patches-4.4/0396-dmaengine-bcm2835-limit-max-length-based-on-channel-.patch b/target/linux/brcm2708/patches-4.4/0396-dmaengine-bcm2835-limit-max-length-based-on-channel-.patch
deleted file mode 100644
index 20fb886903..0000000000
--- a/target/linux/brcm2708/patches-4.4/0396-dmaengine-bcm2835-limit-max-length-based-on-channel-.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From 426f54e1e932f40b666b238ef37d0610fd35d0d0 Mon Sep 17 00:00:00 2001
-From: Martin Sperl <kernel@martin.sperl.org>
-Date: Wed, 16 Mar 2016 12:25:00 -0700
-Subject: [PATCH] dmaengine: bcm2835: limit max length based on channel type
-
-The bcm2835 dma system has 2 basic types of dma-channels:
-* "normal" channels
-* "light" channels
-
-Lite channels are limited in several aspects:
-* internal data-structure is 128 bit (not 256)
-* does not support BCM2835_DMA_TDMODE (2D)
-* DMA length register is limited to 16 bit.
- so 0-65535 (not 0-65536 as mentioned in the official datasheet)
-* BCM2835_DMA_S/D_IGNORE are not supported
-
-The detection of the type of mode is implemented by looking at
-the LITE bit in the DEBUG register for each channel.
-This allows automatic detection.
-
-Based on this the maximum block size is set to (64K - 4) or to 1G
-and this limit is honored during generation of control block
-chains. The effect is that when a LITE channel is used more
-control blocks are used to do the same transfer (compared
-to a normal channel).
-
-As there are several sources/target DREQS that are 32 bit wide
-we need to have the transfer to be a multiple of 4 as this would
-break the transfer otherwise.
-
-This is why the limit of (64K - 4) was chosen over the
-alternative of (64K - 4K).
-
-Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
-Reviewed-by: Eric Anholt <eric@anholt.net>
-Signed-off-by: Eric Anholt <eric@anholt.net>
-Signed-off-by: Vinod Koul <vinod.koul@intel.com>
----
- drivers/dma/bcm2835-dma.c | 29 ++++++++++++++++++++++++++---
- 1 file changed, 26 insertions(+), 3 deletions(-)
-
---- a/drivers/dma/bcm2835-dma.c
-+++ b/drivers/dma/bcm2835-dma.c
-@@ -81,6 +81,8 @@ struct bcm2835_chan {
-
- void __iomem *chan_base;
- int irq_number;
-+
-+ bool is_lite_channel;
- };
-
- struct bcm2835_desc {
-@@ -169,6 +171,16 @@ struct bcm2835_desc {
- #define BCM2835_DMA_CHAN(n) ((n) << 8) /* Base address */
- #define BCM2835_DMA_CHANIO(base, n) ((base) + BCM2835_DMA_CHAN(n))
-
-+/* the max dma length for different channels */
-+#define MAX_DMA_LEN SZ_1G
-+#define MAX_LITE_DMA_LEN (SZ_64K - 4)
-+
-+static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c)
-+{
-+ /* lite and normal channels have different max frame length */
-+ return c->is_lite_channel ? MAX_LITE_DMA_LEN : MAX_DMA_LEN;
-+}
-+
- /* how many frames of max_len size do we need to transfer len bytes */
- static inline size_t bcm2835_dma_frames_for_length(size_t len,
- size_t max_len)
-@@ -217,8 +229,10 @@ static void bcm2835_dma_create_cb_set_le
- size_t *total_len,
- u32 finalextrainfo)
- {
-- /* set the length */
-- control_block->length = len;
-+ size_t max_len = bcm2835_dma_max_frame_length(chan);
-+
-+ /* set the length taking lite-channel limitations into account */
-+ control_block->length = min_t(u32, len, max_len);
-
- /* finished if we have no period_length */
- if (!period_len)
-@@ -544,6 +558,7 @@ static struct dma_async_tx_descriptor *b
- dma_addr_t src, dst;
- u32 info = BCM2835_DMA_WAIT_RESP;
- u32 extra = BCM2835_DMA_INT_EN;
-+ size_t max_len = bcm2835_dma_max_frame_length(c);
- size_t frames;
-
- /* Grab configuration */
-@@ -586,7 +601,10 @@ static struct dma_async_tx_descriptor *b
- }
-
- /* calculate number of frames */
-- frames = DIV_ROUND_UP(buf_len, period_len);
-+ frames = /* number of periods */
-+ DIV_ROUND_UP(buf_len, period_len) *
-+ /* number of frames per period */
-+ bcm2835_dma_frames_for_length(period_len, max_len);
-
- /*
- * allocate the CB chain
-@@ -685,6 +703,11 @@ static int bcm2835_dma_chan_init(struct
- c->ch = chan_id;
- c->irq_number = irq;
-
-+ /* check in DEBUG register if this is a LITE channel */
-+ if (readl(c->chan_base + BCM2835_DMA_DEBUG) &
-+ BCM2835_DMA_DEBUG_LITE)
-+ c->is_lite_channel = true;
-+
- return 0;
- }
-