Skip to content

Commit 3439b2a

Browse files
committed
Merge tag 'dmaengine-fix-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine
Pull dmaengine fixes from Vinod Koul: "Driver fixes for: - stm32 dma residue calculation and chaining - stm32 mdma for setting inflight bytes, residue calculation and resume abort - channel request, channel enable and dma error in fsl_edma - runtime pm imbalance in ste_dma40 driver - deadlock fix in mediatek driver" * tag 'dmaengine-fix-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine: dmaengine: fsl-edma: fix all channels requested when call fsl_edma3_xlate() dmaengine: stm32-dma: fix residue in case of MDMA chaining dmaengine: stm32-dma: fix stm32_dma_prep_slave_sg in case of MDMA chaining dmaengine: stm32-mdma: set in_flight_bytes in case CRQA flag is set dmaengine: stm32-mdma: use Link Address Register to compute residue dmaengine: stm32-mdma: abort resume if no ongoing transfer dmaengine: ste_dma40: Fix PM disable depth imbalance in d40_probe dmaengine: mediatek: Fix deadlock caused by synchronize_irq() dmaengine: idxd: use spin_lock_irqsave before wait_event_lock_irq dmaengine: fsl-edma: fix edma4 channel enable failure on second attempt dt-bindings: dmaengine: zynqmp_dma: add xlnx,bus-width required property dmaengine: fsl-dma: fix DMA error when enabling sg if 'DONE' bit is set
2 parents 7c367d8 + 3fa5351 commit 3439b2a

File tree

9 files changed

+79
-24
lines changed

9 files changed

+79
-24
lines changed

Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ description: |
1313
1414
maintainers:
1515
- Michael Tretter <m.tretter@pengutronix.de>
16+
- Harini Katakam <harini.katakam@amd.com>
17+
- Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
1618

1719
allOf:
1820
- $ref: ../dma-controller.yaml#
@@ -65,6 +67,7 @@ required:
6567
- interrupts
6668
- clocks
6769
- clock-names
70+
- xlnx,bus-width
6871

6972
additionalProperties: false
7073

drivers/dma/fsl-edma-common.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,14 @@ static void fsl_edma3_enable_request(struct fsl_edma_chan *fsl_chan)
9292

9393
edma_writel_chreg(fsl_chan, val, ch_sbr);
9494

95-
if (flags & FSL_EDMA_DRV_HAS_CHMUX)
96-
edma_writel_chreg(fsl_chan, fsl_chan->srcid, ch_mux);
95+
if (flags & FSL_EDMA_DRV_HAS_CHMUX) {
96+
/*
97+
* ch_mux: With the exception of 0, attempts to write a value
98+
* already in use will be forced to 0.
99+
*/
100+
if (!edma_readl_chreg(fsl_chan, ch_mux))
101+
edma_writel_chreg(fsl_chan, fsl_chan->srcid, ch_mux);
102+
}
97103

98104
val = edma_readl_chreg(fsl_chan, ch_csr);
99105
val |= EDMA_V3_CH_CSR_ERQ;
@@ -448,12 +454,25 @@ static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
448454

449455
edma_write_tcdreg(fsl_chan, tcd->dlast_sga, dlast_sga);
450456

457+
csr = le16_to_cpu(tcd->csr);
458+
451459
if (fsl_chan->is_sw) {
452-
csr = le16_to_cpu(tcd->csr);
453460
csr |= EDMA_TCD_CSR_START;
454461
tcd->csr = cpu_to_le16(csr);
455462
}
456463

464+
/*
465+
* Must clear CHn_CSR[DONE] bit before enable TCDn_CSR[ESG] at EDMAv3
466+
* eDMAv4 have not such requirement.
467+
* Change MLINK need clear CHn_CSR[DONE] for both eDMAv3 and eDMAv4.
468+
*/
469+
if (((fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_CLEAR_DONE_E_SG) &&
470+
(csr & EDMA_TCD_CSR_E_SG)) ||
471+
((fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_CLEAR_DONE_E_LINK) &&
472+
(csr & EDMA_TCD_CSR_E_LINK)))
473+
edma_writel_chreg(fsl_chan, edma_readl_chreg(fsl_chan, ch_csr), ch_csr);
474+
475+
457476
edma_write_tcdreg(fsl_chan, tcd->csr, csr);
458477
}
459478

drivers/dma/fsl-edma-common.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,23 @@ struct fsl_edma_desc {
183183
#define FSL_EDMA_DRV_BUS_8BYTE BIT(10)
184184
#define FSL_EDMA_DRV_DEV_TO_DEV BIT(11)
185185
#define FSL_EDMA_DRV_ALIGN_64BYTE BIT(12)
186+
/* Need clean CHn_CSR DONE before enable TCD's ESG */
187+
#define FSL_EDMA_DRV_CLEAR_DONE_E_SG BIT(13)
188+
/* Need clean CHn_CSR DONE before enable TCD's MAJORELINK */
189+
#define FSL_EDMA_DRV_CLEAR_DONE_E_LINK BIT(14)
186190

187191
#define FSL_EDMA_DRV_EDMA3 (FSL_EDMA_DRV_SPLIT_REG | \
188192
FSL_EDMA_DRV_BUS_8BYTE | \
189193
FSL_EDMA_DRV_DEV_TO_DEV | \
190-
FSL_EDMA_DRV_ALIGN_64BYTE)
194+
FSL_EDMA_DRV_ALIGN_64BYTE | \
195+
FSL_EDMA_DRV_CLEAR_DONE_E_SG | \
196+
FSL_EDMA_DRV_CLEAR_DONE_E_LINK)
197+
198+
#define FSL_EDMA_DRV_EDMA4 (FSL_EDMA_DRV_SPLIT_REG | \
199+
FSL_EDMA_DRV_BUS_8BYTE | \
200+
FSL_EDMA_DRV_DEV_TO_DEV | \
201+
FSL_EDMA_DRV_ALIGN_64BYTE | \
202+
FSL_EDMA_DRV_CLEAR_DONE_E_LINK)
191203

192204
struct fsl_edma_drvdata {
193205
u32 dmamuxs; /* only used before v3 */

drivers/dma/fsl-edma-main.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,18 +154,20 @@ static struct dma_chan *fsl_edma3_xlate(struct of_phandle_args *dma_spec,
154154
fsl_chan = to_fsl_edma_chan(chan);
155155
i = fsl_chan - fsl_edma->chans;
156156

157-
chan = dma_get_slave_channel(chan);
158-
chan->device->privatecnt++;
159157
fsl_chan->priority = dma_spec->args[1];
160158
fsl_chan->is_rxchan = dma_spec->args[2] & ARGS_RX;
161159
fsl_chan->is_remote = dma_spec->args[2] & ARGS_REMOTE;
162160
fsl_chan->is_multi_fifo = dma_spec->args[2] & ARGS_MULTI_FIFO;
163161

164162
if (!b_chmux && i == dma_spec->args[0]) {
163+
chan = dma_get_slave_channel(chan);
164+
chan->device->privatecnt++;
165165
mutex_unlock(&fsl_edma->fsl_edma_mutex);
166166
return chan;
167167
} else if (b_chmux && !fsl_chan->srcid) {
168168
/* if controller support channel mux, choose a free channel */
169+
chan = dma_get_slave_channel(chan);
170+
chan->device->privatecnt++;
169171
fsl_chan->srcid = dma_spec->args[0];
170172
mutex_unlock(&fsl_edma->fsl_edma_mutex);
171173
return chan;
@@ -355,7 +357,7 @@ static struct fsl_edma_drvdata imx93_data3 = {
355357
};
356358

357359
static struct fsl_edma_drvdata imx93_data4 = {
358-
.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA3,
360+
.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA4,
359361
.chreg_space_sz = 0x8000,
360362
.chreg_off = 0x10000,
361363
.setup_irq = fsl_edma3_irq_init,

drivers/dma/idxd/device.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand,
477477
union idxd_command_reg cmd;
478478
DECLARE_COMPLETION_ONSTACK(done);
479479
u32 stat;
480+
unsigned long flags;
480481

481482
if (idxd_device_is_halted(idxd)) {
482483
dev_warn(&idxd->pdev->dev, "Device is HALTED!\n");
@@ -490,7 +491,7 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand,
490491
cmd.operand = operand;
491492
cmd.int_req = 1;
492493

493-
spin_lock(&idxd->cmd_lock);
494+
spin_lock_irqsave(&idxd->cmd_lock, flags);
494495
wait_event_lock_irq(idxd->cmd_waitq,
495496
!test_bit(IDXD_FLAG_CMD_RUNNING, &idxd->flags),
496497
idxd->cmd_lock);
@@ -507,7 +508,7 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand,
507508
* After command submitted, release lock and go to sleep until
508509
* the command completes via interrupt.
509510
*/
510-
spin_unlock(&idxd->cmd_lock);
511+
spin_unlock_irqrestore(&idxd->cmd_lock, flags);
511512
wait_for_completion(&done);
512513
stat = ioread32(idxd->reg_base + IDXD_CMDSTS_OFFSET);
513514
spin_lock(&idxd->cmd_lock);

drivers/dma/mediatek/mtk-uart-apdma.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,9 +450,8 @@ static int mtk_uart_apdma_device_pause(struct dma_chan *chan)
450450
mtk_uart_apdma_write(c, VFF_EN, VFF_EN_CLR_B);
451451
mtk_uart_apdma_write(c, VFF_INT_EN, VFF_INT_EN_CLR_B);
452452

453-
synchronize_irq(c->irq);
454-
455453
spin_unlock_irqrestore(&c->vc.lock, flags);
454+
synchronize_irq(c->irq);
456455

457456
return 0;
458457
}

drivers/dma/ste_dma40.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3668,6 +3668,7 @@ static int __init d40_probe(struct platform_device *pdev)
36683668
regulator_disable(base->lcpa_regulator);
36693669
regulator_put(base->lcpa_regulator);
36703670
}
3671+
pm_runtime_disable(base->dev);
36713672

36723673
report_failure:
36733674
d40_err(dev, "probe failed\n");

drivers/dma/stm32-dma.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,8 +1113,10 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_slave_sg(
11131113
chan->chan_reg.dma_scr &= ~STM32_DMA_SCR_PFCTRL;
11141114

11151115
/* Activate Double Buffer Mode if DMA triggers STM32 MDMA and more than 1 sg */
1116-
if (chan->trig_mdma && sg_len > 1)
1116+
if (chan->trig_mdma && sg_len > 1) {
11171117
chan->chan_reg.dma_scr |= STM32_DMA_SCR_DBM;
1118+
chan->chan_reg.dma_scr &= ~STM32_DMA_SCR_CT;
1119+
}
11181120

11191121
for_each_sg(sgl, sg, sg_len, i) {
11201122
ret = stm32_dma_set_xfer_param(chan, direction, &buswidth,
@@ -1387,11 +1389,12 @@ static size_t stm32_dma_desc_residue(struct stm32_dma_chan *chan,
13871389

13881390
residue = stm32_dma_get_remaining_bytes(chan);
13891391

1390-
if (chan->desc->cyclic && !stm32_dma_is_current_sg(chan)) {
1392+
if ((chan->desc->cyclic || chan->trig_mdma) && !stm32_dma_is_current_sg(chan)) {
13911393
n_sg++;
13921394
if (n_sg == chan->desc->num_sgs)
13931395
n_sg = 0;
1394-
residue = sg_req->len;
1396+
if (!chan->trig_mdma)
1397+
residue = sg_req->len;
13951398
}
13961399

13971400
/*
@@ -1401,7 +1404,7 @@ static size_t stm32_dma_desc_residue(struct stm32_dma_chan *chan,
14011404
* residue = remaining bytes from NDTR + remaining
14021405
* periods/sg to be transferred
14031406
*/
1404-
if (!chan->desc->cyclic || n_sg != 0)
1407+
if ((!chan->desc->cyclic && !chan->trig_mdma) || n_sg != 0)
14051408
for (i = n_sg; i < desc->num_sgs; i++)
14061409
residue += desc->sg_req[i].len;
14071410

drivers/dma/stm32-mdma.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -777,8 +777,6 @@ static int stm32_mdma_setup_xfer(struct stm32_mdma_chan *chan,
777777
/* Enable interrupts */
778778
ccr &= ~STM32_MDMA_CCR_IRQ_MASK;
779779
ccr |= STM32_MDMA_CCR_TEIE | STM32_MDMA_CCR_CTCIE;
780-
if (sg_len > 1)
781-
ccr |= STM32_MDMA_CCR_BTIE;
782780
desc->ccr = ccr;
783781

784782
return 0;
@@ -1236,6 +1234,10 @@ static int stm32_mdma_resume(struct dma_chan *c)
12361234
unsigned long flags;
12371235
u32 status, reg;
12381236

1237+
/* Transfer can be terminated */
1238+
if (!chan->desc || (stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & STM32_MDMA_CCR_EN))
1239+
return -EPERM;
1240+
12391241
hwdesc = chan->desc->node[chan->curr_hwdesc].hwdesc;
12401242

12411243
spin_lock_irqsave(&chan->vchan.lock, flags);
@@ -1316,21 +1318,35 @@ static int stm32_mdma_slave_config(struct dma_chan *c,
13161318

13171319
static size_t stm32_mdma_desc_residue(struct stm32_mdma_chan *chan,
13181320
struct stm32_mdma_desc *desc,
1319-
u32 curr_hwdesc)
1321+
u32 curr_hwdesc,
1322+
struct dma_tx_state *state)
13201323
{
13211324
struct stm32_mdma_device *dmadev = stm32_mdma_get_dev(chan);
13221325
struct stm32_mdma_hwdesc *hwdesc;
1323-
u32 cbndtr, residue, modulo, burst_size;
1326+
u32 cisr, clar, cbndtr, residue, modulo, burst_size;
13241327
int i;
13251328

1329+
cisr = stm32_mdma_read(dmadev, STM32_MDMA_CISR(chan->id));
1330+
13261331
residue = 0;
1327-
for (i = curr_hwdesc + 1; i < desc->count; i++) {
1332+
/* Get the next hw descriptor to process from current transfer */
1333+
clar = stm32_mdma_read(dmadev, STM32_MDMA_CLAR(chan->id));
1334+
for (i = desc->count - 1; i >= 0; i--) {
13281335
hwdesc = desc->node[i].hwdesc;
1336+
1337+
if (hwdesc->clar == clar)
1338+
break;/* Current transfer found, stop cumulating */
1339+
1340+
/* Cumulate residue of unprocessed hw descriptors */
13291341
residue += STM32_MDMA_CBNDTR_BNDT(hwdesc->cbndtr);
13301342
}
13311343
cbndtr = stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id));
13321344
residue += cbndtr & STM32_MDMA_CBNDTR_BNDT_MASK;
13331345

1346+
state->in_flight_bytes = 0;
1347+
if (chan->chan_config.m2m_hw && (cisr & STM32_MDMA_CISR_CRQA))
1348+
state->in_flight_bytes = cbndtr & STM32_MDMA_CBNDTR_BNDT_MASK;
1349+
13341350
if (!chan->mem_burst)
13351351
return residue;
13361352

@@ -1360,11 +1376,10 @@ static enum dma_status stm32_mdma_tx_status(struct dma_chan *c,
13601376

13611377
vdesc = vchan_find_desc(&chan->vchan, cookie);
13621378
if (chan->desc && cookie == chan->desc->vdesc.tx.cookie)
1363-
residue = stm32_mdma_desc_residue(chan, chan->desc,
1364-
chan->curr_hwdesc);
1379+
residue = stm32_mdma_desc_residue(chan, chan->desc, chan->curr_hwdesc, state);
13651380
else if (vdesc)
1366-
residue = stm32_mdma_desc_residue(chan,
1367-
to_stm32_mdma_desc(vdesc), 0);
1381+
residue = stm32_mdma_desc_residue(chan, to_stm32_mdma_desc(vdesc), 0, state);
1382+
13681383
dma_set_residue(state, residue);
13691384

13701385
spin_unlock_irqrestore(&chan->vchan.lock, flags);

0 commit comments

Comments
 (0)