Skip to content

Commit

Permalink
Merge branch 'next' of git://git.infradead.org/users/vkoul/slave-dma
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Linus Torvalds committed May 25, 2012
2 parents d484864 + 1dd1ea8 commit d5adf23
Show file tree
Hide file tree
Showing 19 changed files with 169 additions and 105 deletions.
17 changes: 17 additions & 0 deletions Documentation/devicetree/bindings/dma/snps-dma.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
* 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 changes: 2 additions & 0 deletions arch/arm/include/asm/hardware/pl080.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 0 additions & 1 deletion arch/arm/mach-at91/at91sam9g45_devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
26 changes: 0 additions & 26 deletions arch/arm/mach-at91/include/mach/at_hdmac.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};


Expand All @@ -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 */
52 changes: 41 additions & 11 deletions drivers/dma/amba-pl08x.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/*
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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 "
Expand All @@ -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");
}
Expand Down Expand Up @@ -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,
Expand All @@ -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 },
};
Expand Down
15 changes: 7 additions & 8 deletions drivers/dma/at_hdmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
*/

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

Expand Down Expand Up @@ -574,7 +573,6 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
return NULL;
}

ctrla = ATC_DEFAULT_CTRLA;
ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN
| ATC_SRC_ADDR_MODE_INCR
| ATC_DST_ADDR_MODE_INCR
Expand All @@ -585,13 +583,13 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
* of the most common optimization.
*/
if (!((src | dest | len) & 3)) {
ctrla |= ATC_SRC_WIDTH_WORD | ATC_DST_WIDTH_WORD;
ctrla = ATC_SRC_WIDTH_WORD | ATC_DST_WIDTH_WORD;
src_width = dst_width = 2;
} else if (!((src | dest | len) & 1)) {
ctrla |= ATC_SRC_WIDTH_HALFWORD | ATC_DST_WIDTH_HALFWORD;
ctrla = ATC_SRC_WIDTH_HALFWORD | ATC_DST_WIDTH_HALFWORD;
src_width = dst_width = 1;
} else {
ctrla |= ATC_SRC_WIDTH_BYTE | ATC_DST_WIDTH_BYTE;
ctrla = ATC_SRC_WIDTH_BYTE | ATC_DST_WIDTH_BYTE;
src_width = dst_width = 0;
}

Expand Down Expand Up @@ -668,7 +666,8 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
return NULL;
}

ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla;
ctrla = ATC_SCSIZE(sconfig->src_maxburst)
| ATC_DCSIZE(sconfig->dst_maxburst);
ctrlb = ATC_IEN;

switch (direction) {
Expand Down Expand Up @@ -796,12 +795,12 @@ atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc,
enum dma_transfer_direction direction)
{
struct at_dma_chan *atchan = to_at_dma_chan(chan);
struct at_dma_slave *atslave = chan->private;
struct dma_slave_config *sconfig = &atchan->dma_sconfig;
u32 ctrla;

/* prepare common CRTLA value */
ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla
ctrla = ATC_SCSIZE(sconfig->src_maxburst)
| ATC_DCSIZE(sconfig->dst_maxburst)
| ATC_DST_WIDTH(reg_width)
| ATC_SRC_WIDTH(reg_width)
| period_len >> reg_width;
Expand Down
21 changes: 20 additions & 1 deletion drivers/dma/at_hdmac_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,26 @@
/* Bitfields in CTRLA */
#define ATC_BTSIZE_MAX 0xFFFFUL /* Maximum Buffer Transfer Size */
#define ATC_BTSIZE(x) (ATC_BTSIZE_MAX & (x)) /* Buffer Transfer Size */
/* Chunck Tranfer size definitions are in at_hdmac.h */
#define ATC_SCSIZE_MASK (0x7 << 16) /* Source Chunk Transfer Size */
#define ATC_SCSIZE(x) (ATC_SCSIZE_MASK & ((x) << 16))
#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(x) (ATC_DCSIZE_MASK & ((x) << 20))
#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)
#define ATC_SRC_WIDTH_MASK (0x3 << 24) /* Source Single Transfer Size */
#define ATC_SRC_WIDTH(x) ((x) << 24)
#define ATC_SRC_WIDTH_BYTE (0x0 << 24)
Expand Down
2 changes: 1 addition & 1 deletion drivers/dma/coh901318.c
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,7 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,

if (!sgl)
goto out;
if (sgl->length == 0)
if (sg_dma_len(sgl) == 0)
goto out;

spin_lock_irqsave(&cohc->lock, flg);
Expand Down
4 changes: 2 additions & 2 deletions drivers/dma/coh901318_lli.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,10 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,

if (dir == DMA_MEM_TO_DEV)
/* increment source address */
src = sg_phys(sg);
src = sg_dma_address(sg);
else
/* increment destination address */
dst = sg_phys(sg);
dst = sg_dma_address(sg);

bytes_to_transfer = sg_dma_len(sg);

Expand Down
Loading

0 comments on commit d5adf23

Please sign in to comment.