aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/bcm2835-dma.c
diff options
context:
space:
mode:
authorMartin Sperl <kernel@martin.sperl.org>2016-03-16 15:25:00 -0400
committerVinod Koul <vinod.koul@intel.com>2016-04-15 00:27:22 -0400
commit4087412258276be37c5660fc6caf5d4e08920193 (patch)
tree0face52cfbe964411291f74a1032c65a916bb996 /drivers/dma/bcm2835-dma.c
parent92153bb534fa4c2f0a1fdc3745cab25edaf10dca (diff)
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>
Diffstat (limited to 'drivers/dma/bcm2835-dma.c')
-rw-r--r--drivers/dma/bcm2835-dma.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 4db0e232fab8..59c5ef36d970 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -81,6 +81,8 @@ struct bcm2835_chan {
81 81
82 void __iomem *chan_base; 82 void __iomem *chan_base;
83 int irq_number; 83 int irq_number;
84
85 bool is_lite_channel;
84}; 86};
85 87
86struct bcm2835_desc { 88struct bcm2835_desc {
@@ -169,6 +171,16 @@ struct bcm2835_desc {
169#define BCM2835_DMA_CHAN(n) ((n) << 8) /* Base address */ 171#define BCM2835_DMA_CHAN(n) ((n) << 8) /* Base address */
170#define BCM2835_DMA_CHANIO(base, n) ((base) + BCM2835_DMA_CHAN(n)) 172#define BCM2835_DMA_CHANIO(base, n) ((base) + BCM2835_DMA_CHAN(n))
171 173
174/* the max dma length for different channels */
175#define MAX_DMA_LEN SZ_1G
176#define MAX_LITE_DMA_LEN (SZ_64K - 4)
177
178static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c)
179{
180 /* lite and normal channels have different max frame length */
181 return c->is_lite_channel ? MAX_LITE_DMA_LEN : MAX_DMA_LEN;
182}
183
172/* how many frames of max_len size do we need to transfer len bytes */ 184/* how many frames of max_len size do we need to transfer len bytes */
173static inline size_t bcm2835_dma_frames_for_length(size_t len, 185static inline size_t bcm2835_dma_frames_for_length(size_t len,
174 size_t max_len) 186 size_t max_len)
@@ -217,8 +229,10 @@ static void bcm2835_dma_create_cb_set_length(
217 size_t *total_len, 229 size_t *total_len,
218 u32 finalextrainfo) 230 u32 finalextrainfo)
219{ 231{
220 /* set the length */ 232 size_t max_len = bcm2835_dma_max_frame_length(chan);
221 control_block->length = len; 233
234 /* set the length taking lite-channel limitations into account */
235 control_block->length = min_t(u32, len, max_len);
222 236
223 /* finished if we have no period_length */ 237 /* finished if we have no period_length */
224 if (!period_len) 238 if (!period_len)
@@ -544,6 +558,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
544 dma_addr_t src, dst; 558 dma_addr_t src, dst;
545 u32 info = BCM2835_DMA_WAIT_RESP; 559 u32 info = BCM2835_DMA_WAIT_RESP;
546 u32 extra = BCM2835_DMA_INT_EN; 560 u32 extra = BCM2835_DMA_INT_EN;
561 size_t max_len = bcm2835_dma_max_frame_length(c);
547 size_t frames; 562 size_t frames;
548 563
549 /* Grab configuration */ 564 /* Grab configuration */
@@ -586,7 +601,10 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
586 } 601 }
587 602
588 /* calculate number of frames */ 603 /* calculate number of frames */
589 frames = DIV_ROUND_UP(buf_len, period_len); 604 frames = /* number of periods */
605 DIV_ROUND_UP(buf_len, period_len) *
606 /* number of frames per period */
607 bcm2835_dma_frames_for_length(period_len, max_len);
590 608
591 /* 609 /*
592 * allocate the CB chain 610 * allocate the CB chain
@@ -685,6 +703,11 @@ static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, int irq)
685 c->ch = chan_id; 703 c->ch = chan_id;
686 c->irq_number = irq; 704 c->irq_number = irq;
687 705
706 /* check in DEBUG register if this is a LITE channel */
707 if (readl(c->chan_base + BCM2835_DMA_DEBUG) &
708 BCM2835_DMA_DEBUG_LITE)
709 c->is_lite_channel = true;
710
688 return 0; 711 return 0;
689} 712}
690 713