Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ae14d4b5 authored by Nicolas Ferre's avatar Nicolas Ferre Committed by Vinod Koul
Browse files

dmaengine: at_hdmac: specialize AHB interfaces to optimize transfers



DMA controller has two AHB interfaces on the SOC internal
matrix.
It is more efficient to specialize each interface as the
access to memory can introduce latencies that are not compatible
with peripheral accesses requirements.

Signed-off-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
parent 2f432823
Loading
Loading
Loading
Loading
+15 −11
Original line number Diff line number Diff line
@@ -37,8 +37,8 @@

#define	ATC_DEFAULT_CFG		(ATC_FIFOCFG_HALFFIFO)
#define	ATC_DEFAULT_CTRLA	(0)
#define	ATC_DEFAULT_CTRLB	(ATC_SIF(0)	\
				|ATC_DIF(1))
#define	ATC_DEFAULT_CTRLB	(ATC_SIF(AT_DMA_MEM_IF) \
				|ATC_DIF(AT_DMA_MEM_IF))

/*
 * Initial number of descriptors to allocate for each channel. This could
@@ -693,14 +693,15 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
	reg_width = atslave->reg_width;

	ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla;
	ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN;
	ctrlb = ATC_IEN;

	switch (direction) {
	case DMA_TO_DEVICE:
		ctrla |=  ATC_DST_WIDTH(reg_width);
		ctrlb |=  ATC_DST_ADDR_MODE_FIXED
			| ATC_SRC_ADDR_MODE_INCR
			| ATC_FC_MEM2PER;
			| ATC_FC_MEM2PER
			| ATC_SIF(AT_DMA_MEM_IF) | ATC_DIF(AT_DMA_PER_IF);
		reg = atslave->tx_reg;
		for_each_sg(sgl, sg, sg_len, i) {
			struct at_desc	*desc;
@@ -741,7 +742,8 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
		ctrla |=  ATC_SRC_WIDTH(reg_width);
		ctrlb |=  ATC_DST_ADDR_MODE_INCR
			| ATC_SRC_ADDR_MODE_FIXED
			| ATC_FC_PER2MEM;
			| ATC_FC_PER2MEM
			| ATC_SIF(AT_DMA_PER_IF) | ATC_DIF(AT_DMA_MEM_IF);

		reg = atslave->rx_reg;
		for_each_sg(sgl, sg, sg_len, i) {
@@ -846,20 +848,22 @@ atc_dma_cyclic_fill_desc(struct at_dma_slave *atslave, struct at_desc *desc,
		desc->lli.saddr = buf_addr + (period_len * period_index);
		desc->lli.daddr = atslave->tx_reg;
		desc->lli.ctrla = ctrla;
		desc->lli.ctrlb = ATC_DEFAULT_CTRLB
				| ATC_DST_ADDR_MODE_FIXED
		desc->lli.ctrlb = ATC_DST_ADDR_MODE_FIXED
				| ATC_SRC_ADDR_MODE_INCR
				| ATC_FC_MEM2PER;
				| ATC_FC_MEM2PER
				| ATC_SIF(AT_DMA_MEM_IF)
				| ATC_DIF(AT_DMA_PER_IF);
		break;

	case DMA_FROM_DEVICE:
		desc->lli.saddr = atslave->rx_reg;
		desc->lli.daddr = buf_addr + (period_len * period_index);
		desc->lli.ctrla = ctrla;
		desc->lli.ctrlb = ATC_DEFAULT_CTRLB
				| ATC_DST_ADDR_MODE_INCR
		desc->lli.ctrlb = ATC_DST_ADDR_MODE_INCR
				| ATC_SRC_ADDR_MODE_FIXED
				| ATC_FC_PER2MEM;
				| ATC_FC_PER2MEM
				| ATC_SIF(AT_DMA_PER_IF)
				| ATC_DIF(AT_DMA_MEM_IF);
		break;

	default:
+4 −0
Original line number Diff line number Diff line
@@ -103,6 +103,10 @@
/* Bitfields in CTRLB */
#define	ATC_SIF(i)		(0x3 & (i))	/* Src tx done via AHB-Lite Interface i */
#define	ATC_DIF(i)		((0x3 & (i)) <<  4)	/* Dst tx done via AHB-Lite Interface i */
				  /* Specify AHB interfaces */
#define AT_DMA_MEM_IF		0 /* interface 0 as memory interface */
#define AT_DMA_PER_IF		1 /* interface 1 as peripheral interface */

#define	ATC_SRC_PIP		(0x1 <<  8)	/* Source Picture-in-Picture enabled */
#define	ATC_DST_PIP		(0x1 << 12)	/* Destination Picture-in-Picture enabled */
#define	ATC_SRC_DSCR_DIS	(0x1 << 16)	/* Src Descriptor fetch disable */