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

Commit d5adf235 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull slave-dmaengine updates from Vinod Koul:
 "Nothing exciting this time, odd fixes in a bunch of drivers"

* 'next' of git://git.infradead.org/users/vkoul/slave-dma:
  dmaengine: at_hdmac: take maxburst from slave configuration
  dmaengine: at_hdmac: remove ATC_DEFAULT_CTRLA constant
  dmaengine: at_hdmac: remove some at_dma_slave comments
  dma: imx-sdma: make channel0 operations atomic
  dmaengine: Fixup dmaengine_prep_slave_single() to be actually useful
  dmaengine: Use dma_sg_len(sg) instead of sg->length
  dmaengine: Use sg_dma_address instead of sg_phys
  DMA: PL330: Remove duplicate header file inclusion
  dma: imx-sdma: keep the callbacks invoked in the tasklet
  dmaengine: dw_dma: add Device Tree probing capability
  dmaengine: dw_dmac: Add clk_{un}prepare() support
  dma/amba-pl08x: add support for the Nomadik variant
  dma/amba-pl08x: check for terminal count status only
parents d484864d 1dd1ea8e
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
* Synopsys Designware DMA Controller

Required properties:
- compatible: "snps,dma-spear1340"
- reg: Address range of the DMAC registers
- interrupt-parent: Should be the phandle for the interrupt controller
  that services interrupts for this device
- interrupt: Should contain the DMAC interrupt number

Example:

	dma@fc000000 {
		compatible = "snps,dma-spear1340";
		reg = <0xfc000000 0x1000>;
		interrupt-parent = <&vic1>;
		interrupts = <12>;
	};
+2 −0
Original line number Diff line number Diff line
@@ -102,6 +102,8 @@
#define PL080_WIDTH_16BIT			(0x1)
#define PL080_WIDTH_32BIT			(0x2)

#define PL080N_CONFIG_ITPROT			(1 << 20)
#define PL080N_CONFIG_SECPROT			(1 << 19)
#define PL080_CONFIG_HALT			(1 << 18)
#define PL080_CONFIG_ACTIVE			(1 << 17)  /* RO */
#define PL080_CONFIG_LOCK			(1 << 16)
+0 −1
Original line number Diff line number Diff line
@@ -436,7 +436,6 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
	atslave->dma_dev = &at_hdmac_device.dev;
	atslave->cfg = ATC_FIFOCFG_HALFFIFO
			| ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW;
	atslave->ctrla = ATC_SCSIZE_16 | ATC_DCSIZE_16;
	if (mmc_id == 0)	/* MCI0 */
		atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0)
			      | ATC_DST_PER(AT_DMA_ID_MCI0);
+0 −26
Original line number Diff line number Diff line
@@ -26,18 +26,11 @@ struct at_dma_platform_data {
/**
 * struct at_dma_slave - Controller-specific information about a slave
 * @dma_dev: required DMA master device
 * @tx_reg: physical address of data register used for
 *	memory-to-peripheral transfers
 * @rx_reg: physical address of data register used for
 *	peripheral-to-memory transfers
 * @reg_width: peripheral register width
 * @cfg: Platform-specific initializer for the CFG register
 * @ctrla: Platform-specific initializer for the CTRLA register
 */
struct at_dma_slave {
	struct device		*dma_dev;
	u32			cfg;
	u32			ctrla;
};


@@ -64,24 +57,5 @@ struct at_dma_slave {
#define		ATC_FIFOCFG_HALFFIFO		(0x1 << 28)
#define		ATC_FIFOCFG_ENOUGHSPACE		(0x2 << 28)

/* Platform-configurable bits in CTRLA */
#define	ATC_SCSIZE_MASK		(0x7 << 16)	/* Source Chunk Transfer Size */
#define		ATC_SCSIZE_1		(0x0 << 16)
#define		ATC_SCSIZE_4		(0x1 << 16)
#define		ATC_SCSIZE_8		(0x2 << 16)
#define		ATC_SCSIZE_16		(0x3 << 16)
#define		ATC_SCSIZE_32		(0x4 << 16)
#define		ATC_SCSIZE_64		(0x5 << 16)
#define		ATC_SCSIZE_128		(0x6 << 16)
#define		ATC_SCSIZE_256		(0x7 << 16)
#define	ATC_DCSIZE_MASK		(0x7 << 20)	/* Destination Chunk Transfer Size */
#define		ATC_DCSIZE_1		(0x0 << 20)
#define		ATC_DCSIZE_4		(0x1 << 20)
#define		ATC_DCSIZE_8		(0x2 << 20)
#define		ATC_DCSIZE_16		(0x3 << 20)
#define		ATC_DCSIZE_32		(0x4 << 20)
#define		ATC_DCSIZE_64		(0x5 << 20)
#define		ATC_DCSIZE_128		(0x6 << 20)
#define		ATC_DCSIZE_256		(0x7 << 20)

#endif /* AT_HDMAC_H */
+41 −11
Original line number Diff line number Diff line
@@ -95,10 +95,14 @@ static struct amba_driver pl08x_amba_driver;
 * struct vendor_data - vendor-specific config parameters for PL08x derivatives
 * @channels: the number of channels available in this variant
 * @dualmaster: whether this version supports dual AHB masters or not.
 * @nomadik: whether the channels have Nomadik security extension bits
 *	that need to be checked for permission before use and some registers are
 *	missing
 */
struct vendor_data {
	u8 channels;
	bool dualmaster;
	bool nomadik;
};

/*
@@ -385,7 +389,7 @@ pl08x_get_phy_channel(struct pl08x_driver_data *pl08x,

		spin_lock_irqsave(&ch->lock, flags);

		if (!ch->serving) {
		if (!ch->locked && !ch->serving) {
			ch->serving = virt_chan;
			ch->signal = -1;
			spin_unlock_irqrestore(&ch->lock, flags);
@@ -1324,7 +1328,7 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
	int ret, tmp;

	dev_dbg(&pl08x->adev->dev, "%s prepare transaction of %d bytes from %s\n",
			__func__, sgl->length, plchan->name);
			__func__, sg_dma_len(sgl), plchan->name);

	txd = pl08x_get_txd(plchan, flags);
	if (!txd) {
@@ -1378,11 +1382,11 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(

		dsg->len = sg_dma_len(sg);
		if (direction == DMA_MEM_TO_DEV) {
			dsg->src_addr = sg_phys(sg);
			dsg->src_addr = sg_dma_address(sg);
			dsg->dst_addr = slave_addr;
		} else {
			dsg->src_addr = slave_addr;
			dsg->dst_addr = sg_phys(sg);
			dsg->dst_addr = sg_dma_address(sg);
		}
	}

@@ -1484,6 +1488,9 @@ bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
 */
static void pl08x_ensure_on(struct pl08x_driver_data *pl08x)
{
	/* The Nomadik variant does not have the config register */
	if (pl08x->vd->nomadik)
		return;
	writel(PL080_CONFIG_ENABLE, pl08x->base + PL080_CONFIG);
}

@@ -1616,7 +1623,7 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
			__func__, err);
		writel(err, pl08x->base + PL080_ERR_CLEAR);
	}
	tc = readl(pl08x->base + PL080_INT_STATUS);
	tc = readl(pl08x->base + PL080_TC_STATUS);
	if (tc)
		writel(tc, pl08x->base + PL080_TC_CLEAR);

@@ -1773,8 +1780,10 @@ static int pl08x_debugfs_show(struct seq_file *s, void *data)
		spin_lock_irqsave(&ch->lock, flags);
		virt_chan = ch->serving;

		seq_printf(s, "%d\t\t%s\n",
			   ch->id, virt_chan ? virt_chan->name : "(none)");
		seq_printf(s, "%d\t\t%s%s\n",
			   ch->id,
			   virt_chan ? virt_chan->name : "(none)",
			   ch->locked ? " LOCKED" : "");

		spin_unlock_irqrestore(&ch->lock, flags);
	}
@@ -1918,7 +1927,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
	}

	/* Initialize physical channels */
	pl08x->phy_chans = kmalloc((vd->channels * sizeof(*pl08x->phy_chans)),
	pl08x->phy_chans = kzalloc((vd->channels * sizeof(*pl08x->phy_chans)),
			GFP_KERNEL);
	if (!pl08x->phy_chans) {
		dev_err(&adev->dev, "%s failed to allocate "
@@ -1933,8 +1942,23 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
		ch->id = i;
		ch->base = pl08x->base + PL080_Cx_BASE(i);
		spin_lock_init(&ch->lock);
		ch->serving = NULL;
		ch->signal = -1;

		/*
		 * Nomadik variants can have channels that are locked
		 * down for the secure world only. Lock up these channels
		 * by perpetually serving a dummy virtual channel.
		 */
		if (vd->nomadik) {
			u32 val;

			val = readl(ch->base + PL080_CH_CONFIG);
			if (val & (PL080N_CONFIG_ITPROT | PL080N_CONFIG_SECPROT)) {
				dev_info(&adev->dev, "physical channel %d reserved for secure access only\n", i);
				ch->locked = true;
			}
		}

		dev_dbg(&adev->dev, "physical channel %d is %s\n",
			i, pl08x_phy_channel_busy(ch) ? "BUSY" : "FREE");
	}
@@ -2017,6 +2041,12 @@ static struct vendor_data vendor_pl080 = {
	.dualmaster = true,
};

static struct vendor_data vendor_nomadik = {
	.channels = 8,
	.dualmaster = true,
	.nomadik = true,
};

static struct vendor_data vendor_pl081 = {
	.channels = 2,
	.dualmaster = false,
@@ -2037,9 +2067,9 @@ static struct amba_id pl08x_ids[] = {
	},
	/* Nomadik 8815 PL080 variant */
	{
		.id	= 0x00280880,
		.id	= 0x00280080,
		.mask	= 0x00ffffff,
		.data	= &vendor_pl080,
		.data	= &vendor_nomadik,
	},
	{ 0, 0 },
};
Loading