Skip to content

Commit 5bc184c

Browse files
committed
dmaengine: stm32-dma3: set LL base address when transfer starts
Linked-list (LL) is allocated in stm32_dma3_chan_desc_alloc(). The LL is then used when starting the transfer in stm32_dma3_chan_start(). Nothing prevents a user from preparing another transfer before starting the previous one. If, for the same channel, another kind of transfer is prepared (using dmaengine_prep_xxx API), the LL base address may change. This address could be overwritten in the CxLBAR register if the channel is disabled, or the CxLBAR might not be updated if the channel is enabled, leading to a mismatch between the transfer being started and the LL pointed to by CxLBAR register. To avoid this, write the LL base address in CxLBAR when starting the transfer instead of when the linked-list is allocated. Change-Id: Ia8e8cb9b2e423b994545154f09feb46bc6b51e4e Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com> Reviewed-on: https://gerrit.st.com/c/mpu/oe/st/linux-stm32/+/521392 ACI: CIBUILD <MDG-smet-aci-builds@list.st.com> ACI: CITOOLS <MDG-smet-aci-reviews@list.st.com> Reviewed-by: Alain VOLMAT <alain.volmat@st.com>
1 parent be95b31 commit 5bc184c

1 file changed

Lines changed: 6 additions & 6 deletions

File tree

drivers/dma/stm32/stm32-dma3.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,6 @@ static struct stm32_dma3_swdesc *stm32_dma3_chan_desc_alloc(struct stm32_dma3_ch
668668
{
669669
struct stm32_dma3_ddata *ddata = to_stm32_dma3_ddata(chan);
670670
struct stm32_dma3_swdesc *swdesc;
671-
dma_addr_t base_addr;
672671
u32 lap = ddata->lap;
673672
int ret;
674673

@@ -713,11 +712,6 @@ static struct stm32_dma3_swdesc *stm32_dma3_chan_desc_alloc(struct stm32_dma3_ch
713712
/* Set LL allocated port */
714713
swdesc->ccr = FIELD_PREP(CCR_LAP, lap);
715714

716-
/* Set LL base address */
717-
base_addr = stm32_dma3_translate_addr(ddata, lap, ddata2dev(ddata),
718-
swdesc->lli[0].hwdesc_addr);
719-
writel_relaxed(base_addr & CLBAR_LBA, ddata->base + STM32_DMA3_CLBAR(chan->id));
720-
721715
return swdesc;
722716
}
723717

@@ -1073,6 +1067,7 @@ static void stm32_dma3_chan_start(struct stm32_dma3_chan *chan)
10731067
struct stm32_dma3_ddata *ddata = to_stm32_dma3_ddata(chan);
10741068
struct virt_dma_desc *vdesc;
10751069
struct stm32_dma3_hwdesc *hwdesc;
1070+
dma_addr_t base_addr;
10761071
u32 id = chan->id;
10771072
u32 csr, ccr;
10781073

@@ -1096,6 +1091,11 @@ static void stm32_dma3_chan_start(struct stm32_dma3_chan *chan)
10961091
writel_relaxed(hwdesc->cdar, ddata->base + STM32_DMA3_CDAR(id));
10971092
writel_relaxed(hwdesc->cllr, ddata->base + STM32_DMA3_CLLR(id));
10981093

1094+
/* Set LL base address */
1095+
base_addr = stm32_dma3_translate_addr(ddata, FIELD_GET(CCR_LAP, chan->swdesc->ccr),
1096+
ddata2dev(ddata), chan->swdesc->lli[0].hwdesc_addr);
1097+
writel_relaxed(base_addr & CLBAR_LBA, ddata->base + STM32_DMA3_CLBAR(chan->id));
1098+
10991099
/* Clear any pending interrupts */
11001100
csr = readl_relaxed(ddata->base + STM32_DMA3_CSR(id));
11011101
if (csr & CSR_ALL_F)

0 commit comments

Comments
 (0)