Skip to content

Commit e8529dc

Browse files
committed
Merge tag 'dmaengine-fix-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine
Pull dmaengine fixes from Vinod Koul: - TI driver fix to set EOP for cyclic BCDMA transfers - sh rz-dmac driver fix for handling config with zero address * tag 'dmaengine-fix-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine: dmaengine: ti: k3-udma: Set EOP for all TRs in cyclic BCDMA transfer dmaengine: sh: rz-dmac: handle configs where one address is zero
2 parents 886b7e8 + d35f406 commit e8529dc

File tree

2 files changed

+61
-26
lines changed

2 files changed

+61
-26
lines changed

drivers/dma/sh/rz-dmac.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -601,22 +601,25 @@ static int rz_dmac_config(struct dma_chan *chan,
601601
struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
602602
u32 val;
603603

604-
channel->src_per_address = config->src_addr;
605604
channel->dst_per_address = config->dst_addr;
606-
607-
val = rz_dmac_ds_to_val_mapping(config->dst_addr_width);
608-
if (val == CHCFG_DS_INVALID)
609-
return -EINVAL;
610-
611605
channel->chcfg &= ~CHCFG_FILL_DDS_MASK;
612-
channel->chcfg |= FIELD_PREP(CHCFG_FILL_DDS_MASK, val);
606+
if (channel->dst_per_address) {
607+
val = rz_dmac_ds_to_val_mapping(config->dst_addr_width);
608+
if (val == CHCFG_DS_INVALID)
609+
return -EINVAL;
613610

614-
val = rz_dmac_ds_to_val_mapping(config->src_addr_width);
615-
if (val == CHCFG_DS_INVALID)
616-
return -EINVAL;
611+
channel->chcfg |= FIELD_PREP(CHCFG_FILL_DDS_MASK, val);
612+
}
617613

614+
channel->src_per_address = config->src_addr;
618615
channel->chcfg &= ~CHCFG_FILL_SDS_MASK;
619-
channel->chcfg |= FIELD_PREP(CHCFG_FILL_SDS_MASK, val);
616+
if (channel->src_per_address) {
617+
val = rz_dmac_ds_to_val_mapping(config->src_addr_width);
618+
if (val == CHCFG_DS_INVALID)
619+
return -EINVAL;
620+
621+
channel->chcfg |= FIELD_PREP(CHCFG_FILL_SDS_MASK, val);
622+
}
620623

621624
return 0;
622625
}

drivers/dma/ti/k3-udma.c

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3185,27 +3185,40 @@ static int udma_configure_statictr(struct udma_chan *uc, struct udma_desc *d,
31853185

31863186
d->static_tr.elcnt = elcnt;
31873187

3188-
/*
3189-
* PDMA must to close the packet when the channel is in packet mode.
3190-
* For TR mode when the channel is not cyclic we also need PDMA to close
3191-
* the packet otherwise the transfer will stall because PDMA holds on
3192-
* the data it has received from the peripheral.
3193-
*/
31943188
if (uc->config.pkt_mode || !uc->cyclic) {
3189+
/*
3190+
* PDMA must close the packet when the channel is in packet mode.
3191+
* For TR mode when the channel is not cyclic we also need PDMA
3192+
* to close the packet otherwise the transfer will stall because
3193+
* PDMA holds on the data it has received from the peripheral.
3194+
*/
31953195
unsigned int div = dev_width * elcnt;
31963196

31973197
if (uc->cyclic)
31983198
d->static_tr.bstcnt = d->residue / d->sglen / div;
31993199
else
32003200
d->static_tr.bstcnt = d->residue / div;
3201+
} else if (uc->ud->match_data->type == DMA_TYPE_BCDMA &&
3202+
uc->config.dir == DMA_DEV_TO_MEM &&
3203+
uc->cyclic) {
3204+
/*
3205+
* For cyclic mode with BCDMA we have to set EOP in each TR to
3206+
* prevent short packet errors seen on channel teardown. So the
3207+
* PDMA must close the packet after every TR transfer by setting
3208+
* burst count equal to the number of bytes transferred.
3209+
*/
3210+
struct cppi5_tr_type1_t *tr_req = d->hwdesc[0].tr_req_base;
32013211

3202-
if (uc->config.dir == DMA_DEV_TO_MEM &&
3203-
d->static_tr.bstcnt > uc->ud->match_data->statictr_z_mask)
3204-
return -EINVAL;
3212+
d->static_tr.bstcnt =
3213+
(tr_req->icnt0 * tr_req->icnt1) / dev_width;
32053214
} else {
32063215
d->static_tr.bstcnt = 0;
32073216
}
32083217

3218+
if (uc->config.dir == DMA_DEV_TO_MEM &&
3219+
d->static_tr.bstcnt > uc->ud->match_data->statictr_z_mask)
3220+
return -EINVAL;
3221+
32093222
return 0;
32103223
}
32113224

@@ -3450,8 +3463,9 @@ udma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
34503463
/* static TR for remote PDMA */
34513464
if (udma_configure_statictr(uc, d, dev_width, burst)) {
34523465
dev_err(uc->ud->dev,
3453-
"%s: StaticTR Z is limited to maximum 4095 (%u)\n",
3454-
__func__, d->static_tr.bstcnt);
3466+
"%s: StaticTR Z is limited to maximum %u (%u)\n",
3467+
__func__, uc->ud->match_data->statictr_z_mask,
3468+
d->static_tr.bstcnt);
34553469

34563470
udma_free_hwdesc(uc, d);
34573471
kfree(d);
@@ -3476,6 +3490,7 @@ udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr,
34763490
u16 tr0_cnt0, tr0_cnt1, tr1_cnt0;
34773491
unsigned int i;
34783492
int num_tr;
3493+
u32 period_csf = 0;
34793494

34803495
num_tr = udma_get_tr_counters(period_len, __ffs(buf_addr), &tr0_cnt0,
34813496
&tr0_cnt1, &tr1_cnt0);
@@ -3498,6 +3513,20 @@ udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr,
34983513
period_addr = buf_addr |
34993514
((u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT);
35003515

3516+
/*
3517+
* For BCDMA <-> PDMA transfers, the EOP flag needs to be set on the
3518+
* last TR of a descriptor, to mark the packet as complete.
3519+
* This is required for getting the teardown completion message in case
3520+
* of TX, and to avoid short-packet error in case of RX.
3521+
*
3522+
* As we are in cyclic mode, we do not know which period might be the
3523+
* last one, so set the flag for each period.
3524+
*/
3525+
if (uc->config.ep_type == PSIL_EP_PDMA_XY &&
3526+
uc->ud->match_data->type == DMA_TYPE_BCDMA) {
3527+
period_csf = CPPI5_TR_CSF_EOP;
3528+
}
3529+
35013530
for (i = 0; i < periods; i++) {
35023531
int tr_idx = i * num_tr;
35033532

@@ -3525,8 +3554,10 @@ udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr,
35253554
}
35263555

35273556
if (!(flags & DMA_PREP_INTERRUPT))
3528-
cppi5_tr_csf_set(&tr_req[tr_idx].flags,
3529-
CPPI5_TR_CSF_SUPR_EVT);
3557+
period_csf |= CPPI5_TR_CSF_SUPR_EVT;
3558+
3559+
if (period_csf)
3560+
cppi5_tr_csf_set(&tr_req[tr_idx].flags, period_csf);
35303561

35313562
period_addr += period_len;
35323563
}
@@ -3655,8 +3686,9 @@ udma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
36553686
/* static TR for remote PDMA */
36563687
if (udma_configure_statictr(uc, d, dev_width, burst)) {
36573688
dev_err(uc->ud->dev,
3658-
"%s: StaticTR Z is limited to maximum 4095 (%u)\n",
3659-
__func__, d->static_tr.bstcnt);
3689+
"%s: StaticTR Z is limited to maximum %u (%u)\n",
3690+
__func__, uc->ud->match_data->statictr_z_mask,
3691+
d->static_tr.bstcnt);
36603692

36613693
udma_free_hwdesc(uc, d);
36623694
kfree(d);

0 commit comments

Comments
 (0)