Commit d57dd2d2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull dmaengine fixes from Vinod Koul:

 - dw-edma fixes to improve driver and remote HDMA setup

 - fsl-edma fixes for SoC hange, irq init and byte calculations and
   sparse fixes

 - idxd: safe user copy of completion record fix

 - ptdma: consistent DMA mask fix

* tag 'dmaengine-fix2-6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine:
  dmaengine: ptdma: use consistent DMA masks
  dmaengine: fsl-qdma: add __iomem and struct in union to fix sparse warning
  dmaengine: idxd: Ensure safe user copy of completion record
  dmaengine: fsl-edma: correct max_segment_size setting
  dmaengine: idxd: Remove shadow Event Log head stored in idxd
  dmaengine: fsl-edma: correct calculation of 'nbytes' in multi-fifo scenario
  dmaengine: fsl-qdma: init irq after reg initialization
  dmaengine: fsl-qdma: fix SoC may hang on 16 byte unaligned read
  dmaengine: dw-edma: eDMA: Add sync read before starting the DMA transfer in remote setup
  dmaengine: dw-edma: HDMA: Add sync read before starting the DMA transfer in remote setup
  dmaengine: dw-edma: Add HDMA remote interrupt configuration
  dmaengine: dw-edma: HDMA_V0_REMOTEL_STOP_INT_EN typo fix
  dmaengine: dw-edma: Fix wrong interrupt bit set for HDMA
  dmaengine: dw-edma: Fix the ch_count hdma callback
parents e4f79000 df2515a1
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -346,6 +346,20 @@ static void dw_edma_v0_core_write_chunk(struct dw_edma_chunk *chunk)
	dw_edma_v0_write_ll_link(chunk, i, control, chunk->ll_region.paddr);
}

static void dw_edma_v0_sync_ll_data(struct dw_edma_chunk *chunk)
{
	/*
	 * In case of remote eDMA engine setup, the DW PCIe RP/EP internal
	 * configuration registers and application memory are normally accessed
	 * over different buses. Ensure LL-data reaches the memory before the
	 * doorbell register is toggled by issuing the dummy-read from the remote
	 * LL memory in a hope that the MRd TLP will return only after the
	 * last MWr TLP is completed
	 */
	if (!(chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL))
		readl(chunk->ll_region.vaddr.io);
}

static void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
{
	struct dw_edma_chan *chan = chunk->chan;
@@ -412,6 +426,9 @@ static void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
		SET_CH_32(dw, chan->dir, chan->id, llp.msb,
			  upper_32_bits(chunk->ll_region.paddr));
	}

	dw_edma_v0_sync_ll_data(chunk);

	/* Doorbell */
	SET_RW_32(dw, chan->dir, doorbell,
		  FIELD_PREP(EDMA_V0_DOORBELL_CH_MASK, chan->id));
+26 −13
Original line number Diff line number Diff line
@@ -65,18 +65,12 @@ static void dw_hdma_v0_core_off(struct dw_edma *dw)

static u16 dw_hdma_v0_core_ch_count(struct dw_edma *dw, enum dw_edma_dir dir)
{
	u32 num_ch = 0;
	int id;

	for (id = 0; id < HDMA_V0_MAX_NR_CH; id++) {
		if (GET_CH_32(dw, id, dir, ch_en) & BIT(0))
			num_ch++;
	}

	if (num_ch > HDMA_V0_MAX_NR_CH)
		num_ch = HDMA_V0_MAX_NR_CH;

	return (u16)num_ch;
	/*
	 * The HDMA IP have no way to know the number of hardware channels
	 * available, we set it to maximum channels and let the platform
	 * set the right number of channels.
	 */
	return HDMA_V0_MAX_NR_CH;
}

static enum dma_status dw_hdma_v0_core_ch_status(struct dw_edma_chan *chan)
@@ -228,6 +222,20 @@ static void dw_hdma_v0_core_write_chunk(struct dw_edma_chunk *chunk)
	dw_hdma_v0_write_ll_link(chunk, i, control, chunk->ll_region.paddr);
}

static void dw_hdma_v0_sync_ll_data(struct dw_edma_chunk *chunk)
{
	/*
	 * In case of remote HDMA engine setup, the DW PCIe RP/EP internal
	 * configuration registers and application memory are normally accessed
	 * over different buses. Ensure LL-data reaches the memory before the
	 * doorbell register is toggled by issuing the dummy-read from the remote
	 * LL memory in a hope that the MRd TLP will return only after the
	 * last MWr TLP is completed
	 */
	if (!(chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL))
		readl(chunk->ll_region.vaddr.io);
}

static void dw_hdma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
{
	struct dw_edma_chan *chan = chunk->chan;
@@ -242,7 +250,9 @@ static void dw_hdma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
		/* Interrupt enable&unmask - done, abort */
		tmp = GET_CH_32(dw, chan->dir, chan->id, int_setup) |
		      HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK |
		      HDMA_V0_LOCAL_STOP_INT_EN | HDMA_V0_LOCAL_STOP_INT_EN;
		      HDMA_V0_LOCAL_STOP_INT_EN | HDMA_V0_LOCAL_ABORT_INT_EN;
		if (!(dw->chip->flags & DW_EDMA_CHIP_LOCAL))
			tmp |= HDMA_V0_REMOTE_STOP_INT_EN | HDMA_V0_REMOTE_ABORT_INT_EN;
		SET_CH_32(dw, chan->dir, chan->id, int_setup, tmp);
		/* Channel control */
		SET_CH_32(dw, chan->dir, chan->id, control1, HDMA_V0_LINKLIST_EN);
@@ -256,6 +266,9 @@ static void dw_hdma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
	/* Set consumer cycle */
	SET_CH_32(dw, chan->dir, chan->id, cycle_sync,
		  HDMA_V0_CONSUMER_CYCLE_STAT | HDMA_V0_CONSUMER_CYCLE_BIT);

	dw_hdma_v0_sync_ll_data(chunk);

	/* Doorbell */
	SET_CH_32(dw, chan->dir, chan->id, doorbell, HDMA_V0_DOORBELL_START);
}
+1 −1
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
#define HDMA_V0_LOCAL_ABORT_INT_EN		BIT(6)
#define HDMA_V0_REMOTE_ABORT_INT_EN		BIT(5)
#define HDMA_V0_LOCAL_STOP_INT_EN		BIT(4)
#define HDMA_V0_REMOTEL_STOP_INT_EN		BIT(3)
#define HDMA_V0_REMOTE_STOP_INT_EN		BIT(3)
#define HDMA_V0_ABORT_INT_MASK			BIT(2)
#define HDMA_V0_STOP_INT_MASK			BIT(0)
#define HDMA_V0_LINKLIST_EN			BIT(0)
+1 −1
Original line number Diff line number Diff line
@@ -503,7 +503,7 @@ void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan,
	if (fsl_chan->is_multi_fifo) {
		/* set mloff to support multiple fifo */
		burst = cfg->direction == DMA_DEV_TO_MEM ?
				cfg->src_addr_width : cfg->dst_addr_width;
				cfg->src_maxburst : cfg->dst_maxburst;
		nbytes |= EDMA_V3_TCD_NBYTES_MLOFF(-(burst * 4));
		/* enable DMLOE/SMLOE */
		if (cfg->direction == DMA_MEM_TO_DEV) {
+3 −2
Original line number Diff line number Diff line
@@ -30,8 +30,9 @@
#define EDMA_TCD_ATTR_SSIZE(x)		(((x) & GENMASK(2, 0)) << 8)
#define EDMA_TCD_ATTR_SMOD(x)		(((x) & GENMASK(4, 0)) << 11)

#define EDMA_TCD_CITER_CITER(x)		((x) & GENMASK(14, 0))
#define EDMA_TCD_BITER_BITER(x)		((x) & GENMASK(14, 0))
#define EDMA_TCD_ITER_MASK		GENMASK(14, 0)
#define EDMA_TCD_CITER_CITER(x)		((x) & EDMA_TCD_ITER_MASK)
#define EDMA_TCD_BITER_BITER(x)		((x) & EDMA_TCD_ITER_MASK)

#define EDMA_TCD_CSR_START		BIT(0)
#define EDMA_TCD_CSR_INT_MAJOR		BIT(1)
Loading