From: Gerhard Sittig <hidden> Date: 2013-07-14 12:01:56
this series
- introduces slave s/g support (that's support for DMA transfers which
involve peripherals in contrast to mem-to-mem transfers)
- adds device tree based lookup support for DMA channels
- combines floating patches and related feedback which already covered
several aspects of what the suggested LPB driver needs, to demonstrate
how integration might be done
- carries Q&D SD card support to enable another DMA client during test,
while this patch needs to get dropped upon pickup
changes since v1:
- re-order mpc8308 related code paths for improved readability, no
change in behaviour, introduction of symbolic channel names here
already
- squash 'execute() start condition' and 'terminate all' into the
introduction of 'slave s/g prep' and 'device control' support; refuse
s/g lists with more than one item since slave support is operational
yet proper s/g support is missing (can get addressed later)
- always start transfers from software on MPC8308 as there are no
external request lines for peripheral flow control
- drop dt-bindings header file and symbolic channel names in OF nodes
known issues:
- it's yet to get confirmed whether MPC8308 can use slave support or
whether the DMA controller's driver shall actively reject it, the
information that's available so far suggests that peripheral transfers
to IP bus attached I/O is useful and shall not get blocked right away
- currently encoded constraints do work for SD card and LPB test suite
(all known DMA clients ATM), but will need more tuning or support for
automatic adjustment for transfers of arbitrary length
oh, and I'd like to get feedback on whether attribution handling is
appropriate, as I had to squash patches from several authors to not
break bisectability (compilation had worked, but the code had not run
successfully on all previously supported hardware)
Alexander, when you pickup this series and improve slave s/g support and
adjust it for more general use, you have my OK to incorporate and
further adjust the parts that I've contributed
Alexander Popov (1):
dma: mpc512x: add support for peripheral transfers
Gerhard Sittig (3):
dma: mpc512x: re-order mpc8308 specific instructions
dma: mpc512x: register for device tree channel lookup
HACK mmc: mxcmmc: enable clocks for the MPC512x
Lars-Peter Clausen (1):
dma: of: Add common xlate function for matching by channel id
.../devicetree/bindings/dma/mpc512x-dma.txt | 55 +++++
arch/powerpc/boot/dts/mpc5121.dtsi | 1 +
drivers/dma/mpc512x_dma.c | 237 +++++++++++++++++---
drivers/dma/of-dma.c | 47 ++++
drivers/mmc/host/mxcmmc.c | 41 ++--
include/linux/of_dma.h | 4 +
6 files changed, 344 insertions(+), 41 deletions(-)
create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt
--
1.7.10.4
From: Gerhard Sittig <hidden> Date: 2013-07-14 12:01:57
it's rather unexpected to have the MPC8308 specific code in the 'else'
branch so distant from the "is MPC8308?" check
concentrate the test and the specific code for MPC8308 in the 'if'
branch and handle MPC512x in the 'else' branch; use a symbolic channel
count which in combination with the re-ordering obsoletes a comment
this modification only re-orders instructions but doesn't change behaviour
Signed-off-by: Gerhard Sittig <redacted>
---
drivers/dma/mpc512x_dma.c | 48 +++++++++++++++++++++++++++++----------------
1 file changed, 31 insertions(+), 17 deletions(-)
From: Gerhard Sittig <hidden> Date: 2013-07-14 12:01:58
From: Alexander Popov <redacted>
introduce support for slave s/g transfer preparation and the associated
device control callback in the MPC512x DMA controller driver, which adds
support for data transfers between memory and peripheral I/O to the
previously supported mem-to-mem transfers
refuse to prepare chunked transfers (transfers with more than one part)
as long as proper support for scatter/gather is lacking
keep MPC8308 operational by always starting transfers from software,
this SoC appears to not have request lines for flow control when
peripherals are involved in transfers
[ introduction of slave s/g preparation and device control ]
Signed-off-by: Alexander Popov <redacted>
[ execute() start condition, mpc8308 compat, terminate all, s/g length check, reworded commit msg ]
Signed-off-by: Gerhard Sittig <redacted>
---
drivers/dma/mpc512x_dma.c | 168 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 161 insertions(+), 7 deletions(-)
@@ -282,7 +288,17 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)if(first!=prev)mdma->tcd[cid].e_sg=1;-out_8(&mdma->regs->dmassrt,cid);++if(mdma->is_mpc8308){+/* MPC8308, no request lines, software initiated start */+out_8(&mdma->regs->dmassrt,cid);+}elseif(cid==MPC512x_DMACHAN_MDDRC){+/* memory to memory transfer, software initiated start */+out_8(&mdma->regs->dmassrt,cid);+}else{+/* peripherals involved, use external request line */+out_8(&mdma->regs->dmaserq,cid);+}}/* Handle interrupt on one half of DMA controller (32 channels) */
@@ -655,6 +671,141 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,return&mdesc->desc;}+staticstructdma_async_tx_descriptor*mpc_dma_prep_slave_sg(+structdma_chan*chan,structscatterlist*sgl,+unsignedintsg_len,enumdma_transfer_directiondirection,+unsignedlongflags,void*context)+{+structmpc_dma*mdma=dma_chan_to_mpc_dma(chan);+structmpc_dma_chan*mchan=dma_chan_to_mpc_dma_chan(chan);+structmpc_dma_desc*mdesc=NULL;+structmpc_dma_tcd*tcd;+unsignedlongiflags;+structscatterlist*sg;+size_tlen;+intiter,i;++if(!list_empty(&mchan->active))+returnNULL;++/* currently there is no proper support for scatter/gather */+if(sg_len>1)+returnNULL;++for_each_sg(sgl,sg,sg_len,i){+spin_lock_irqsave(&mchan->lock,iflags);++mdesc=list_first_entry(&mchan->free,structmpc_dma_desc,+node);+if(!mdesc){+spin_unlock_irqrestore(&mchan->lock,iflags);+/* try to free completed descriptors */+mpc_dma_process_completed(mdma);+returnNULL;+}++list_del(&mdesc->node);++spin_unlock_irqrestore(&mchan->lock,iflags);++mdesc->error=0;+tcd=mdesc->tcd;++/* Prepare Transfer Control Descriptor for this transaction */+memset(tcd,0,sizeof(structmpc_dma_tcd));++if(!IS_ALIGNED(sg_dma_address(sg),4))+returnNULL;++if(direction==DMA_DEV_TO_MEM){+tcd->saddr=mchan->per_paddr;+tcd->daddr=sg_dma_address(sg);+tcd->soff=0;+tcd->doff=4;+}elseif(direction==DMA_MEM_TO_DEV){+tcd->saddr=sg_dma_address(sg);+tcd->daddr=mchan->per_paddr;+tcd->soff=4;+tcd->doff=0;+}else{+returnNULL;+}+tcd->ssize=MPC_DMA_TSIZE_4;+tcd->dsize=MPC_DMA_TSIZE_4;++len=sg_dma_len(sg);++if(mchan->tcd_nunits)+tcd->nbytes=mchan->tcd_nunits*4;+else+tcd->nbytes=64;++if(!IS_ALIGNED(len,tcd->nbytes))+returnNULL;++iter=len/tcd->nbytes;+if(iter>((1<<15)-1)){/* maximum biter */+returnNULL;/* len is too big */+}else{+/* citer_linkch contains the high bits of iter */+tcd->biter=iter&0x1ff;+tcd->biter_linkch=iter>>9;+tcd->citer=tcd->biter;+tcd->citer_linkch=tcd->biter_linkch;+}++tcd->e_sg=0;+tcd->d_req=1;++/* Place descriptor in prepared list */+spin_lock_irqsave(&mchan->lock,iflags);+list_add_tail(&mdesc->node,&mchan->prepared);+spin_unlock_irqrestore(&mchan->lock,iflags);+}++/* Return the last descriptor */+return&mdesc->desc;+}++staticintmpc_dma_device_control(structdma_chan*chan,enumdma_ctrl_cmdcmd,+unsignedlongarg)+{+structmpc_dma_chan*mchan;+structmpc_dma*mdma;+structdma_slave_config*cfg;++mchan=dma_chan_to_mpc_dma_chan(chan);+switch(cmd){+caseDMA_TERMINATE_ALL:+/* disable channel requests */+mdma=dma_chan_to_mpc_dma(chan);+out_8(&mdma->regs->dmacerq,chan->chan_id);+list_splice_tail_init(&mchan->prepared,&mchan->free);+list_splice_tail_init(&mchan->queued,&mchan->free);+list_splice_tail_init(&mchan->active,&mchan->free);+return0;+caseDMA_SLAVE_CONFIG:+cfg=(void*)arg;+if(cfg->src_addr_width!=DMA_SLAVE_BUSWIDTH_4_BYTES&&+cfg->dst_addr_width!=DMA_SLAVE_BUSWIDTH_4_BYTES)+return-EINVAL;++if(cfg->direction==DMA_DEV_TO_MEM){+mchan->per_paddr=cfg->src_addr;+mchan->tcd_nunits=cfg->src_maxburst;+}else{+mchan->per_paddr=cfg->dst_addr;+mchan->tcd_nunits=cfg->dst_maxburst;+}++return0;+default:+return-ENOSYS;+}++return-EINVAL;+}+staticintmpc_dma_probe(structplatform_device*op){structdevice_node*dn=op->dev.of_node;
@@ -739,9 +890,12 @@ static int mpc_dma_probe(struct platform_device *op)dma->device_issue_pending=mpc_dma_issue_pending;dma->device_tx_status=mpc_dma_tx_status;dma->device_prep_dma_memcpy=mpc_dma_prep_memcpy;+dma->device_prep_slave_sg=mpc_dma_prep_slave_sg;+dma->device_control=mpc_dma_device_control;INIT_LIST_HEAD(&dma->channels);dma_cap_set(DMA_MEMCPY,dma->cap_mask);+dma_cap_set(DMA_SLAVE,dma->cap_mask);for(i=0;i<dma->chancnt;i++){mchan=&mdma->channels[i];
From: Gerhard Sittig <hidden> Date: 2013-07-14 12:01:59
From: Lars-Peter Clausen <lars@metafoo.de>
This patch adds a new common OF dma xlate callback function which will match a
channel by it's id. The binding expects one integer argument which it will use to
lookup the channel by the id.
Unlike of_dma_simple_xlate this function is able to handle a system with
multiple DMA controllers. When registering the of dma provider with
of_dma_controller_register a pointer to the dma_device struct which is
associated with the dt node needs to passed as the data parameter. The filter
function will use this pointer to match only channels which belong to the
specified DMA controller.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Gerhard Sittig <redacted>
---
drivers/dma/of-dma.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/of_dma.h | 4 ++++
2 files changed, 51 insertions(+)
From: Gerhard Sittig <hidden> Date: 2013-07-14 12:02:00
register the controller for device tree based lookup of DMA channels
(non-fatal for backwards compatibility with older device trees), provide
the '#dma-cells' property in the shared mpc5121.dtsi file, and introduce
a bindings document for the MPC512x DMA controller
Signed-off-by: Gerhard Sittig <redacted>
---
.../devicetree/bindings/dma/mpc512x-dma.txt | 55 ++++++++++++++++++++
arch/powerpc/boot/dts/mpc5121.dtsi | 1 +
drivers/dma/mpc512x_dma.c | 21 ++++++--
3 files changed, 74 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt
@@ -0,0 +1,55 @@+* Freescale MPC512x DMA Controller++The DMA controller in the Freescale MPC512x SoC can move blocks of+memory contents between memory and peripherals or memory to memory.++Refer to the "Generic DMA Controller and DMA request bindings" description+in the dma.txt file for a more detailled discussion of the binding. The+MPC512x DMA engine binding follows the common scheme, but doesn't provide+support for the optional channels and requests counters (those values are+derived from the detected hardware features) and has a fixed client+specifier length of 1 integer cell (the value is the DMA channel, since+the DMA controller uses a fixed assignment of request lines per channel).+++DMA controller node properties:++Required properties:+- compatible: should be "fsl,mpc5121-dma"+- reg: address and size of the DMA controller's register set+- interrupts: interrupt spec for the DMA controller++Optional properties:+- #dma-cells: must be <1>, describes the number of integer cells+ needed to specify the 'dmas' property in client nodes,+ strongly recommended since common client helper code+ uses this property++Example:++ dma0: dma@14000 {+ compatible = "fsl,mpc5121-dma";+ reg = <0x14000 0x1800>;+ interrupts = <65 0x8>;+ #dma-cells = <1>;+ };+++Client node properties:++Required properties:+- dmas: list of DMA specifiers, consisting each of a handle+ for the DMA controller and integer cells to specify+ the channel used within the DMA controller+- dma-names: list of identifier strings for the DMA specifiers,+ client device driver code uses these strings to+ have DMA channels looked up at the controller++Example:++ sdhc@1500 {+ compatible = "fsl,mpc5121-sdhc";+ /* ... */+ dmas = <&dma0 30>;+ dma-names = "rx-tx";+ };
@@ -959,11 +960,23 @@ static int mpc_dma_probe(struct platform_device *op)/* Register DMA engine */dev_set_drvdata(dev,mdma);retval=dma_async_device_register(dma);-if(retval){-devm_free_irq(dev,mdma->irq,mdma);-irq_dispose_mapping(mdma->irq);+if(retval)+gotoout_irq;++/* register with OF helpers for DMA lookups (nonfatal) */+if(dev->of_node){+retval=of_dma_controller_register(dev->of_node,+of_dma_xlate_by_chan_id,+mdma);+if(retval)+dev_warn(dev,"could not register for OF lookup\n");}+return0;++out_irq:+devm_free_irq(dev,mdma->irq,mdma);+irq_dispose_mapping(mdma->irq);returnretval;}
@@ -972,6 +985,8 @@ static int mpc_dma_remove(struct platform_device *op)structdevice*dev=&op->dev;structmpc_dma*mdma=dev_get_drvdata(dev);+if(dev->of_node)+of_dma_controller_free(dev->of_node);dma_async_device_unregister(&mdma->dma);devm_free_irq(dev,mdma->irq,mdma);irq_dispose_mapping(mdma->irq);
From: Gerhard Sittig <hidden> Date: 2013-07-14 12:02:01
Q&D HACK to enable SD card support without correct COMMON_CLK support,
best viewed with 'git diff -w -b', NOT acceptable for mainline (NAKed)
Signed-off-by: Gerhard Sittig <redacted>
---
drivers/mmc/host/mxcmmc.c | 41 +++++++++++++++++++++++++++--------------
1 file changed, 27 insertions(+), 14 deletions(-)
From: Alexander Popov <hidden> Date: 2013-07-16 09:27:23
Hello everyone!
Hello Gerhard!
Thanks for your work.
2013/7/14 Gerhard Sittig [off-list ref]:
known issues:
- currently encoded constraints do work for SD card and LPB test suite
(all known DMA clients ATM), but will need more tuning or support for
automatic adjustment for transfers of arbitrary length
NBYTES of data is read from / written to DMA client's port in one burst
after DMA controller receives service request from that DMA client.
Different DMA clients want different NBYTES:
SCLPC wants 4 and SD card wants 64, other clients might want something
different.
So having default case with magic number 64 is totally wrong.
What if we simply remove it from [PATCH RFC v2 2/5]:
len = sg_dma_len(sg);
if (mchan->tcd_nunits)
tcd->nbytes = mchan->tcd_nunits * 4;
- else
- tcd->nbytes = 64;
if (!IS_ALIGNED(len, tcd->nbytes))
return NULL;
and make SD card driver use fields
src_addr_width, dst_addr_width and src_maxburst / dst_maxburst
of dma_slave_config which is a part of standard API (dmaengine.h):
#define DEFAULT_WORDS_PER_TRANSFER 16
...
struct dma_slave_config dma_conf = {};
...
if (dma_conf.direction = DMA_MEM_TO_DEV) {
dma_conf.dst_maxburst = DEFAULT_WORDS_PER_TRANSFER;
} else {
dma_conf.src_maxburst = DEFAULT_WORDS_PER_TRANSFER;
}
dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
...
if (dma_dev->device_control(chan, DMA_SLAVE_CONFIG,
(unsigned long)&dma_conf)) {
goto err_dma_prep;
}
This code for SD card driver would be very similar to the code from
SCLPC driver.
Best regards,
Alexander
From: Alexander Popov <redacted>
introduce support for slave s/g transfer preparation and the associated
device control callback in the MPC512x DMA controller driver, which adds
support for data transfers between memory and peripheral I/O to the
previously supported mem-to-mem transfers
refuse to prepare chunked transfers (transfers with more than one part)
as long as proper support for scatter/gather is lacking
keep MPC8308 operational by always starting transfers from software,
this SoC appears to not have request lines for flow control when
peripherals are involved in transfers
I had a look at the current driver and it seems that any channel can be used
for memcpy operation not only the MDDRC channel. Since the dmaengine API
will just pick one of the currently free channels when performing a memcpy
operation I think this patch breaks memcpy operations. You probably need to
register two dma controllers, one for memcpy operations one for slave
operations, that way you can ensure that only the MDDRC channel is used for
memcpy operations.
[ introduction of slave s/g preparation and device control ]
Signed-off-by: Alexander Popov <redacted>
[ execute() start condition, mpc8308 compat, terminate all, s/g length check, reworded commit msg ]
Signed-off-by: Gerhard Sittig <redacted>
---
From: Alexander Popov <hidden> Date: 2013-08-12 13:37:35
Hello everyone!
Changes offered in this letter:
- Adding a flag "will_access_peripheral" to DMA transfer descriptor
according recommendations of Gerhard Sittig.
This flag is set in mpc_dma_prep_memcpy() and mpc_dma_prep_slave_sg()
and is evaluated in mpc_dma_execute().
- Adding locking and removing default nbytes value according
recommendations of Lars-Peter Clausen.
I tested these changes on MPC5125
with SCLPC driver (transfers between dev and mem work fine)
and dmatest module (all 64 DMA channels can perform mem-to-mem transfers
which can be chained in one DMA transaction).
2013/7/14 Gerhard Sittig [off-list ref]:
quoted hunk
From: Alexander Popov <redacted>
introduce support for slave s/g transfer preparation and the associated
device control callback in the MPC512x DMA controller driver, which adds
support for data transfers between memory and peripheral I/O to the
previously supported mem-to-mem transfers
refuse to prepare chunked transfers (transfers with more than one part)
as long as proper support for scatter/gather is lacking
keep MPC8308 operational by always starting transfers from software,
this SoC appears to not have request lines for flow control when
peripherals are involved in transfers
[ introduction of slave s/g preparation and device control ]
Signed-off-by: Alexander Popov <redacted>
[ execute() start condition, mpc8308 compat, terminate all, s/g length check, reworded commit msg ]
Signed-off-by: Gerhard Sittig <redacted>
---
drivers/dma/mpc512x_dma.c | 168 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 161 insertions(+), 7 deletions(-)
We can't chain together descriptors of transfers which involve peripherals
because each of such transfers needs hardware initiated start.
@@ -253,10 +248,27 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan) struct mpc_dma_desc *first = NULL; struct mpc_dma_desc *prev = NULL; struct mpc_dma_desc *mdesc;+ int staffed = 0; int cid = mchan->chan.chan_id;- /* Move all queued descriptors to active list */- list_splice_tail_init(&mchan->queued, &mchan->active);+ /*+ * Mem-to-mem transfers can be chained+ * together into one transaction.+ * But each transfer which involves peripherals+ * must be executed separately.+ */+ while (!staffed) {+ mdesc = list_first_entry(&mchan->queued,+ struct mpc_dma_desc, node);++ if (!mdesc->will_access_peripheral)+ list_move_tail(&mdesc->node, &mchan->active);+ else {+ staffed = 1;+ if (list_empty(&mchan->active))+ list_move_tail(&mdesc->node, &mchan->active);+ }+ } /* Chain descriptors into one transaction */ list_for_each_entry(mdesc, &mchan->active, node) {
These 4 lines should be changed to:
+ if (tcd_nunits)
+ tcd->nbytes = tcd_nunits * 4;
+ else
+ return NULL;
The last line means that client kernel modules must set
src_maxburst and dst_maxburst fields of dma_slave_config (dmaengine.h).
+
+ if (!IS_ALIGNED(len, tcd->nbytes))
+ return NULL;
+
+ iter = len / tcd->nbytes;
+ if (iter > ((1 << 15) - 1)) { /* maximum biter */
+ return NULL; /* len is too big */
+ } else {
+ /* citer_linkch contains the high bits of iter */
+ tcd->biter = iter & 0x1ff;
+ tcd->biter_linkch = iter >> 9;
+ tcd->citer = tcd->biter;
+ tcd->citer_linkch = tcd->biter_linkch;
+ }
+
+ tcd->e_sg = 0;
+ tcd->d_req = 1;
+
+ /* Place descriptor in prepared list */
+ spin_lock_irqsave(&mchan->lock, iflags);
+ list_add_tail(&mdesc->node, &mchan->prepared);
+ spin_unlock_irqrestore(&mchan->lock, iflags);
+ }
+
+ /* Return the last descriptor */
From: Alexander Popov <hidden> Date: 2013-08-12 13:38:25
Hello everyone!
2013/7/14 Gerhard Sittig [off-list ref]:
quoted hunk
@@ -50,9 +50,23 @@ #define MPC_DMA_DESCRIPTORS 64 /* Macro definitions */-#define MPC_DMA_CHANNELS 64 #define MPC_DMA_TCD_OFFSET 0x1000+/*+ * the maximum channel count, and specific channels which need+ * special processing, for individual hardware variants+ *+ * and the maximum channel count over all supported controllers,+ * used for data structure sizes+ */+enum mpc8308_dmachan_id_t {+ MPC8308_DMACHAN_MAX = 16,+};+enum mpc512x_dmachan_id_t {+ MPC512x_DMACHAN_MAX = 64,+};+#define MPC_DMA_CHANNELS 64+
I offer to use #define instead of enum here
since individual channels don't require special handling.
Best regards,
Alexander.
From: Alexander Popov <hidden> Date: 2013-10-03 14:00:29
v2013/7/14 Gerhard Sittig [off-list ref]:
this series
- introduces slave s/g support (that's support for DMA transfers which
involve peripherals in contrast to mem-to-mem transfers)
- adds device tree based lookup support for DMA channels
- combines floating patches and related feedback which already covered
several aspects of what the suggested LPB driver needs, to demonstrate
how integration might be done
- carries Q&D SD card support to enable another DMA client during test,
while this patch needs to get dropped upon pickup
changes since v1:
- re-order mpc8308 related code paths for improved readability, no
change in behaviour, introduction of symbolic channel names here
already
- squash 'execute() start condition' and 'terminate all' into the
introduction of 'slave s/g prep' and 'device control' support; refuse
s/g lists with more than one item since slave support is operational
yet proper s/g support is missing (can get addressed later)
- always start transfers from software on MPC8308 as there are no
external request lines for peripheral flow control
- drop dt-bindings header file and symbolic channel names in OF nodes
Changes since v2 (RFC v3 was badly formed, excuse me for that):
Part 1/5:
- use #define instead of enum since individual channels don't require
special handling.
Part 2/5:
- add a flag "will_access_peripheral" to DMA transfer descriptor
according recommendations of Gerhard Sittig.
This flag is set in mpc_dma_prep_memcpy() and mpc_dma_prep_slave_sg()
and is evaluated in mpc_dma_execute() to choose a type of start for
the transfer.
- prevent descriptors of transfers which involve peripherals from
being chained together;
each of such transfers needs hardware initiated start.
- add locking while working with struct mpc_dma_chan
according recommendations of Lars-Peter Clausen.
- remove default nbytes value. Client kernel modules must set
src_maxburst and dst_maxburst fields of struct dma_slave_config (dmaengine.h).
Part 6/8:
unchanged.
Part 7/8:
unchanged.
Part 8/8:
unchanged.
These changes are tested on MPC5125
- with SCLPC driver (transfers between dev and mem work fine).
- with dmatest module (all 64 DMA channels can perform mem-to-mem transfers
which can be chained in one DMA transaction).
known issues:
- it's yet to get confirmed whether MPC8308 can use slave support or
whether the DMA controller's driver shall actively reject it, the
information that's available so far suggests that peripheral transfers
to IP bus attached I/O is useful and shall not get blocked right away
From: Alexander Popov <hidden> Date: 2013-10-03 14:05:16
From: Lars-Peter Clausen <lars@metafoo.de>
This patch adds a new common OF dma xlate callback function which will match a
channel by it's id. The binding expects one integer argument which it
will use to
lookup the channel by the id.
Unlike of_dma_simple_xlate this function is able to handle a system with
multiple DMA controllers. When registering the of dma provider with
of_dma_controller_register a pointer to the dma_device struct which is
associated with the dt node needs to passed as the data parameter. The filter
function will use this pointer to match only channels which belong to the
specified DMA controller.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Gerhard Sittig <redacted>
---
drivers/dma/of-dma.c | 47 ++++++++++++++++++++++++++++++
+++++++++++++++++
include/linux/of_dma.h | 4 ++++
2 files changed, 51 insertions(+)
of_phandle_args *dma_spec,
&dma_spec->args[0]);
}
EXPORT_SYMBOL_GPL(of_dma_simple_xlate);
+
+struct of_dma_filter_by_chan_id_args {
+ struct dma_device *dev;
+ unsigned int chan_id;
+};
+
+static bool of_dma_filter_by_chan_id(struct dma_chan *chan, void *params)
+{
+ struct of_dma_filter_by_chan_id_args *args = params;
+
+ return chan->device == args->dev && chan->chan_id == args->chan_id;
+}
+
+/**
+ * of_dma_xlate_by_chan_id - Translate dt property to DMA channel by channel id
+ * @dma_spec: pointer to DMA specifier as found in the device tree
+ * @of_dma: pointer to DMA controller data
+ *
+ * This function can be used as the of xlate callback for DMA driver
which wants
+ * to match the channel based on the channel id. When using this xlate function
+ * the #dma-cells propety of the DMA controller dt node needs to be set to 1.
+ * The data parameter of of_dma_controller_register must be a pointer to the
+ * dma_device struct the function should match upon.
+ *
+ * Returns pointer to appropriate dma channel on success or NULL on error.
+ */
+struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
+ struct of_dma *ofdma)
+{
+ struct of_dma_filter_by_chan_id_args args;
+ dma_cap_mask_t cap;
+
+ args.dev = ofdma->of_dma_data;
+ if (!args.dev)
+ return NULL;
+
+ if (dma_spec->args_count != 1)
+ return NULL;
+
+ dma_cap_zero(cap);
+ dma_cap_set(DMA_SLAVE, cap);
+
+ args.chan_id = dma_spec->args[0];
+
+ return dma_request_channel(cap, of_dma_filter_by_chan_id, &args);
+}
+EXPORT_SYMBOL_GPL(of_dma_xlate_by_chan_id);
From: Alexander Popov <hidden> Date: 2013-10-03 14:06:19
From: Gerhard Sittig <redacted>
register the controller for device tree based lookup of DMA channels
(non-fatal for backwards compatibility with older device trees), provide
the '#dma-cells' property in the shared mpc5121.dtsi file, and introduce
a bindings document for the MPC512x DMA controller
Signed-off-by: Gerhard Sittig <redacted>
---
.../devicetree/bindings/dma/
mpc512x-dma.txt | 55 ++++++++++++++++++++
arch/powerpc/boot/dts/mpc5121.dtsi | 1 +
drivers/dma/mpc512x_dma.c | 21 ++++++--
3 files changed, 74 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt
@@ -0,0 +1,55 @@+* Freescale MPC512x DMA Controller++The DMA controller in the Freescale MPC512x SoC can move blocks of+memory contents between memory and peripherals or memory to memory.++Refer to the "Generic DMA Controller and DMA request bindings" description+in the dma.txt file for a more detailled discussion of the binding. The+MPC512x DMA engine binding follows the common scheme, but doesn't provide+support for the optional channels and requests counters (those values are+derived from the detected hardware features) and has a fixed client+specifier length of 1 integer cell (the value is the DMA channel, since+the DMA controller uses a fixed assignment of request lines per channel).+++DMA controller node properties:++Required properties:+- compatible: should be "fsl,mpc5121-dma"+- reg: address and size of the DMA controller's register set+- interrupts: interrupt spec for the DMA controller++Optional properties:+- #dma-cells: must be <1>, describes the number of integer cells+ needed to specify the 'dmas' property in client nodes,+ strongly recommended since common client helper code+ uses this property++Example:++ dma0: dma@14000 {+ compatible = "fsl,mpc5121-dma";+ reg = <0x14000 0x1800>;+ interrupts = <65 0x8>;+ #dma-cells = <1>;+ };+++Client node properties:++Required properties:+- dmas: list of DMA specifiers, consisting
each of a handle
+ for the DMA controller and integer cells to specify
+ the channel used within the DMA controller
+- dma-names: list of identifier strings for the DMA specifiers,
+ client device driver code uses these strings to
+ have DMA channels looked up at the controller
+
+Example:
+
+ sdhc@1500 {
+ compatible = "fsl,mpc5121-sdhc";
+ /* ... */
+ dmas = <&dma0 30>;
+ dma-names = "rx-tx";
+ };
diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi
b/arch/powerpc/boot/dts/mpc5121.dtsi
index 384e692..dae99b7 100644
@@ -939,11 +940,23 @@ static int mpc_dma_probe(struct platform_device *op)/* Register DMA engine */dev_set_drvdata(dev,mdma);retval=dma_async_device_register(dma);-if(retval){-devm_free_irq(dev,mdma->irq,mdma);-irq_dispose_mapping(mdma->irq);+if(retval)+gotoout_irq;++/* register with OF helpers for DMA lookups (nonfatal) */+if(dev->of_node){+retval=of_dma_controller_register(dev->of_node,+of_dma_xlate_by_chan_id,+mdma);+if(retval)+dev_warn(dev,"could not register for OF lookup\n");}+return0;++out_irq:+devm_free_irq(dev,mdma->irq,mdma);+irq_dispose_mapping(mdma->irq);returnretval;}
@@ -952,6 +965,8 @@ static int mpc_dma_remove(struct platform_device *op)structdevice*dev=&op->dev;structmpc_dma*mdma=dev_get_drvdata(dev);+if(dev->of_node)+of_dma_controller_free(dev->of_node);dma_async_device_unregister(&mdma->dma);devm_free_irq(dev,mdma->irq,mdma);irq_dispose_mapping(mdma->irq);--
From: Alexander Popov <hidden> Date: 2013-10-03 14:07:00
From: Gerhard Sittig <redacted>
Q&D HACK to enable SD card support without correct COMMON_CLK support,
best viewed with 'git diff -w -b', NOT acceptable for mainline (NAKed)
Signed-off-by: Gerhard Sittig <redacted>
---
drivers/mmc/host/mxcmmc.c | 41 +++++++++++++++++++++++++++---
-----------
1 file changed, 27 insertions(+), 14 deletions(-)
From: Gerhard Sittig <hidden> Date: 2013-10-06 10:01:38
On Thu, Oct 03, 2013 at 18:00 +0400, Alexander Popov wrote:
v2013/7/14 Gerhard Sittig [off-list ref]:
quoted
this series
- introduces slave s/g support (that's support for DMA transfers which
involve peripherals in contrast to mem-to-mem transfers)
- adds device tree based lookup support for DMA channels
- combines floating patches and related feedback which already covered
several aspects of what the suggested LPB driver needs, to demonstrate
how integration might be done
- carries Q&D SD card support to enable another DMA client during test,
while this patch needs to get dropped upon pickup
changes since v1:
- re-order mpc8308 related code paths for improved readability, no
change in behaviour, introduction of symbolic channel names here
already
- squash 'execute() start condition' and 'terminate all' into the
introduction of 'slave s/g prep' and 'device control' support; refuse
s/g lists with more than one item since slave support is operational
yet proper s/g support is missing (can get addressed later)
- always start transfers from software on MPC8308 as there are no
external request lines for peripheral flow control
- drop dt-bindings header file and symbolic channel names in OF nodes
Changes since v2 (RFC v3 was badly formed, excuse me for that):
Part 1/5:
- use #define instead of enum since individual channels don't require
special handling.
Part 2/5:
- add a flag "will_access_peripheral" to DMA transfer descriptor
according recommendations of Gerhard Sittig.
This flag is set in mpc_dma_prep_memcpy() and mpc_dma_prep_slave_sg()
and is evaluated in mpc_dma_execute() to choose a type of start for
the transfer.
- prevent descriptors of transfers which involve peripherals from
being chained together;
each of such transfers needs hardware initiated start.
- add locking while working with struct mpc_dma_chan
according recommendations of Lars-Peter Clausen.
- remove default nbytes value. Client kernel modules must set
src_maxburst and dst_maxburst fields of struct dma_slave_config (dmaengine.h).
Part 6/8:
unchanged.
Part 7/8:
unchanged.
Part 8/8:
unchanged.
These changes are tested on MPC5125
- with SCLPC driver (transfers between dev and mem work fine).
- with dmatest module (all 64 DMA channels can perform mem-to-mem transfers
which can be chained in one DMA transaction).
quoted
known issues:
- it's yet to get confirmed whether MPC8308 can use slave support or
whether the DMA controller's driver shall actively reject it, the
information that's available so far suggests that peripheral transfers
to IP bus attached I/O is useful and shall not get blocked right away
I'm not certain whether keeping the "cover letter" in threaded
form is appropriate. But speaking about non-existent parts
(6-8/8), not saying what the current version is, missing stats
certainly isn't right.
Your submission style adds more work to doing review and
providing feedback than what's necessary. You assume that others
would keep the history for you, or would do the archeology and
collect individual pieces from the past, to recover what you fail
to send out.
The messages show up in an unexpected order here (3, 4, 5, 0
first on one thread, 1, 2 then in another thread, with some 2800
messages between them) and carry conflicting subjects or version
numbers. Formatting was broken in transport, patches won't apply.
Please do consider checking what you send out, and how you can
improve the reception's side of the process. Try to help those
people you want to receive help from. Try to support both kinds
of review for people coming new to the subject as well as those
who have seen a former version.
virtually yours
Gerhard Sittig
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr. 5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de