mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 06:57:57 +00:00
793f8ab62c
Add kernel patches for version 6.1. Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
116 lines
3.4 KiB
Diff
116 lines
3.4 KiB
Diff
From 793023dc148830c18c437b58d88a118a72091038 Mon Sep 17 00:00:00 2001
|
|
From: Maxime Ripard <maxime@cerno.tech>
|
|
Date: Thu, 13 Apr 2023 16:47:10 +0200
|
|
Subject: [PATCH] dmaengine: bcm2835: Fix descriptors usage for 40-bits
|
|
channels
|
|
|
|
The bcm2835_dma_create_cb_chain() function is in charge of building up
|
|
the descriptors chain for a given transfer.
|
|
|
|
It was initially supporting only the BCM2835-style DMA controller, and
|
|
was later expanded to support controllers with 40-bits channels that use
|
|
a different descriptor layout.
|
|
|
|
However, some part of the function only use the old style descriptor,
|
|
even when building a chain of new-style descriptors, resulting in weird
|
|
bugs.
|
|
|
|
Fixes: 9a52a9918306 ("bcm2835-dma: Add proper 40-bit DMA support")
|
|
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
|
---
|
|
drivers/dma/bcm2835-dma.c | 69 ++++++++++++++++++++++++++++-----------
|
|
1 file changed, 50 insertions(+), 19 deletions(-)
|
|
|
|
--- a/drivers/dma/bcm2835-dma.c
|
|
+++ b/drivers/dma/bcm2835-dma.c
|
|
@@ -543,7 +543,10 @@ static struct bcm2835_desc *bcm2835_dma_
|
|
cyclic ? finalextrainfo : 0);
|
|
|
|
/* calculate new remaining length */
|
|
- len -= control_block->length;
|
|
+ if (c->is_40bit_channel)
|
|
+ len -= ((struct bcm2711_dma40_scb *)control_block)->len;
|
|
+ else
|
|
+ len -= control_block->length;
|
|
}
|
|
|
|
/* link this the last controlblock */
|
|
@@ -555,10 +558,19 @@ static struct bcm2835_desc *bcm2835_dma_
|
|
d->cb_list[frame - 1].cb->next = cb_entry->paddr;
|
|
|
|
/* update src and dst and length */
|
|
- if (src && (info & BCM2835_DMA_S_INC))
|
|
- src += control_block->length;
|
|
- if (dst && (info & BCM2835_DMA_D_INC))
|
|
- dst += control_block->length;
|
|
+ if (src && (info & BCM2835_DMA_S_INC)) {
|
|
+ if (c->is_40bit_channel)
|
|
+ src += ((struct bcm2711_dma40_scb *)control_block)->len;
|
|
+ else
|
|
+ src += control_block->length;
|
|
+ }
|
|
+
|
|
+ if (dst && (info & BCM2835_DMA_D_INC)) {
|
|
+ if (c->is_40bit_channel)
|
|
+ dst += ((struct bcm2711_dma40_scb *)control_block)->len;
|
|
+ else
|
|
+ dst += control_block->length;
|
|
+ }
|
|
|
|
/* Length of total transfer */
|
|
if (c->is_40bit_channel)
|
|
@@ -779,20 +791,39 @@ static size_t bcm2835_dma_desc_size_pos(
|
|
unsigned int i;
|
|
size_t size;
|
|
|
|
- for (size = i = 0; i < d->frames; i++) {
|
|
- struct bcm2835_dma_cb *control_block = d->cb_list[i].cb;
|
|
- size_t this_size = control_block->length;
|
|
- dma_addr_t dma;
|
|
-
|
|
- if (d->dir == DMA_DEV_TO_MEM)
|
|
- dma = control_block->dst;
|
|
- else
|
|
- dma = control_block->src;
|
|
-
|
|
- if (size)
|
|
- size += this_size;
|
|
- else if (addr >= dma && addr < dma + this_size)
|
|
- size += dma + this_size - addr;
|
|
+ if (d->c->is_40bit_channel) {
|
|
+ for (size = i = 0; i < d->frames; i++) {
|
|
+ struct bcm2711_dma40_scb *control_block =
|
|
+ (struct bcm2711_dma40_scb *)d->cb_list[i].cb;
|
|
+ size_t this_size = control_block->len;
|
|
+ dma_addr_t dma;
|
|
+
|
|
+ if (d->dir == DMA_DEV_TO_MEM)
|
|
+ dma = control_block->dst;
|
|
+ else
|
|
+ dma = control_block->src;
|
|
+
|
|
+ if (size)
|
|
+ size += this_size;
|
|
+ else if (addr >= dma && addr < dma + this_size)
|
|
+ size += dma + this_size - addr;
|
|
+ }
|
|
+ } else {
|
|
+ for (size = i = 0; i < d->frames; i++) {
|
|
+ struct bcm2835_dma_cb *control_block = d->cb_list[i].cb;
|
|
+ size_t this_size = control_block->length;
|
|
+ dma_addr_t dma;
|
|
+
|
|
+ if (d->dir == DMA_DEV_TO_MEM)
|
|
+ dma = control_block->dst;
|
|
+ else
|
|
+ dma = control_block->src;
|
|
+
|
|
+ if (size)
|
|
+ size += this_size;
|
|
+ else if (addr >= dma && addr < dma + this_size)
|
|
+ size += dma + this_size - addr;
|
|
+ }
|
|
}
|
|
|
|
return size;
|