* (no subject)
From: Xiubo Li @ 2013-11-01 7:04 UTC (permalink / raw)
To: r65073, timur, lgirdwood, broonie
Cc: mark.rutland, alsa-devel, linux-doc, tiwai, b18965, perex, LW,
linux, b42378, oskar, grant.likely, devicetree, ian.campbell,
pawel.moll, swarren, rob.herring, linux-arm-kernel, fabio.estevam,
linux-kernel, rob, r64188, shawn.guo, linuxppc-dev
Hello,
This patch series is mostly Freescale's SAI SoC Digital Audio Interface driver implementation. And the implementation is only compatible with device tree definition.
This patch series is based on linux-next and has been tested on Vybrid VF610 Tower board using device tree.
Changed in v2:
- Use default settings for the generic dmaengine PCM driver.
- Separate receive and transmit setting in most functions, but some couldn't for the HW limitation.
- Drop some not reduntant code.
- Use devm_snd_soc_register_component() instead of snd_soc_register_component().
- Use devm_snd_soc_register_card() instead of devm_snd_soc_register_card().
- Adjust the code sentences sequence.
- Make the namespacing consistent.
- Rename CONFIG_SND_SOC_FSL_SGTL5000 to CONFIG_SND_SOC_FSL_SGTL5000_VF610.
- Drop some meaningless lines.
- Rename the binding document file.
Added in v1:
- Add SAI SoC Digital Audio Interface driver.
- Add Freescale SAI ALSA SoC Digital Audio Interface node for VF610.
- Enables SAI ALSA SoC DAI device for Vybrid VF610 TOWER board.
- Add device tree bindings for Freescale SAI.
- Revise the bugs about the sgt15000 codec.
- Add SGT15000 based audio machine driver.
- Enable SGT15000 codec based audio driver node for VF610.
- Add device tree bindings for Freescale VF610 sound.
^ permalink raw reply
* [PATCH RFC v5 5/5] HACK mmc: mxcmmc: enable clocks for the MPC512x
From: Alexander Popov @ 2013-11-01 7:19 UTC (permalink / raw)
To: Gerhard Sittig, Dan Williams, Vinod Koul, Lars-Peter Clausen,
Arnd Bergmann, Anatolij Gustschin, Alexander Popov, linuxppc-dev,
devicetree
In-Reply-To: <1383290374-17484-1-git-send-email-a13xp0p0v88@gmail.com>
From: Gerhard Sittig <gsi@denx.de>
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 <gsi@denx.de>
---
drivers/mmc/host/mxcmmc.c | 41 +++++++++++++++++++++++++++--------------
1 file changed, 27 insertions(+), 14 deletions(-)
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index c174c6a..ae13bc9 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -1123,20 +1123,29 @@ static int mxcmci_probe(struct platform_device *pdev)
host->res = r;
host->irq = irq;
- host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
- if (IS_ERR(host->clk_ipg)) {
- ret = PTR_ERR(host->clk_ipg);
- goto out_iounmap;
- }
+ if (!is_mpc512x_mmc(host)) {
+ host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(host->clk_ipg)) {
+ ret = PTR_ERR(host->clk_ipg);
+ goto out_iounmap;
+ }
- host->clk_per = devm_clk_get(&pdev->dev, "per");
- if (IS_ERR(host->clk_per)) {
- ret = PTR_ERR(host->clk_per);
- goto out_iounmap;
+ host->clk_per = devm_clk_get(&pdev->dev, "per");
+ if (IS_ERR(host->clk_per)) {
+ ret = PTR_ERR(host->clk_per);
+ goto out_iounmap;
+ }
+ } else {
+ host->clk_per = devm_clk_get(&pdev->dev, "sdhc_clk");
+ if (IS_ERR(host->clk_per)) {
+ ret = PTR_ERR(host->clk_per);
+ goto out_iounmap;
+ }
}
clk_prepare_enable(host->clk_per);
- clk_prepare_enable(host->clk_ipg);
+ if (host->clk_ipg)
+ clk_prepare_enable(host->clk_ipg);
mxcmci_softreset(host);
@@ -1206,7 +1215,8 @@ out_free_dma:
dma_release_channel(host->dma);
out_clk_put:
clk_disable_unprepare(host->clk_per);
- clk_disable_unprepare(host->clk_ipg);
+ if (host->clk_ipg)
+ clk_disable_unprepare(host->clk_ipg);
out_iounmap:
iounmap(host->base);
out_free:
@@ -1236,7 +1246,8 @@ static int mxcmci_remove(struct platform_device *pdev)
dma_release_channel(host->dma);
clk_disable_unprepare(host->clk_per);
- clk_disable_unprepare(host->clk_ipg);
+ if (host->clk_ipg)
+ clk_disable_unprepare(host->clk_ipg);
release_mem_region(host->res->start, resource_size(host->res));
@@ -1255,7 +1266,8 @@ static int mxcmci_suspend(struct device *dev)
if (mmc)
ret = mmc_suspend_host(mmc);
clk_disable_unprepare(host->clk_per);
- clk_disable_unprepare(host->clk_ipg);
+ if (host->clk_ipg)
+ clk_disable_unprepare(host->clk_ipg);
return ret;
}
@@ -1267,7 +1279,8 @@ static int mxcmci_resume(struct device *dev)
int ret = 0;
clk_prepare_enable(host->clk_per);
- clk_prepare_enable(host->clk_ipg);
+ if (host->clk_ipg)
+ clk_prepare_enable(host->clk_ipg);
if (mmc)
ret = mmc_resume_host(mmc);
--
1.7.11.3
^ permalink raw reply related
* [PATCH RFC v5 4/5] dma: mpc512x: register for device tree channel lookup
From: Alexander Popov @ 2013-11-01 7:19 UTC (permalink / raw)
To: Gerhard Sittig, Dan Williams, Vinod Koul, Lars-Peter Clausen,
Arnd Bergmann, Anatolij Gustschin, Alexander Popov, linuxppc-dev,
devicetree
In-Reply-To: <1383290374-17484-1-git-send-email-a13xp0p0v88@gmail.com>
From: Gerhard Sittig <gsi@denx.de>
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 <gsi@denx.de>
---
.../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
diff --git a/Documentation/devicetree/bindings/dma/mpc512x-dma.txt b/Documentation/devicetree/bindings/dma/mpc512x-dma.txt
new file mode 100644
index 0000000..a4867d5
--- /dev/null
+++ b/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 bd14c00..eb0058f 100644
--- a/arch/powerpc/boot/dts/mpc5121.dtsi
+++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -390,6 +390,7 @@
compatible = "fsl,mpc5121-dma";
reg = <0x14000 0x1800>;
interrupts = <65 0x8>;
+ #dma-cells = <1>;
};
};
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index d2ec42d..9929cdc 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -48,6 +48,7 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/of_device.h>
+#include <linux/of_dma.h>
#include <linux/of_platform.h>
#include <linux/random.h>
@@ -1013,11 +1014,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)
+ goto out_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");
}
+ return 0;
+
+out_irq:
+ devm_free_irq(dev, mdma->irq, mdma);
+ irq_dispose_mapping(mdma->irq);
return retval;
}
@@ -1026,6 +1039,8 @@ static int mpc_dma_remove(struct platform_device *op)
struct device *dev = &op->dev;
struct mpc_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);
--
1.7.11.3
^ permalink raw reply related
* [PATCH RFC v5 3/5] dma: of: Add common xlate function for matching by channel id
From: Alexander Popov @ 2013-11-01 7:19 UTC (permalink / raw)
To: Gerhard Sittig, Dan Williams, Vinod Koul, Lars-Peter Clausen,
Arnd Bergmann, Anatolij Gustschin, Alexander Popov, linuxppc-dev,
devicetree
In-Reply-To: <1383290374-17484-1-git-send-email-a13xp0p0v88@gmail.com>
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 <gsi@denx.de>
---
drivers/dma/of-dma.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/of_dma.h | 4 ++++
2 files changed, 51 insertions(+)
diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index 0b88dd3..aa9c425 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -215,3 +215,50 @@ struct dma_chan *of_dma_simple_xlate(struct 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);
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index ae36298..56bc026 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -41,6 +41,8 @@ extern struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
const char *name);
extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma);
+extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
+ struct of_dma *ofdma);
#else
static inline int of_dma_controller_register(struct device_node *np,
struct dma_chan *(*of_dma_xlate)
@@ -66,6 +68,8 @@ static inline struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_s
return NULL;
}
+#define of_dma_xlate_by_chan_id NULL
+
#endif
#endif /* __LINUX_OF_DMA_H */
--
1.7.11.3
^ permalink raw reply related
* [PATCH RFC v5 2/5] dma: mpc512x: add support for peripheral transfers
From: Alexander Popov @ 2013-11-01 7:19 UTC (permalink / raw)
To: Gerhard Sittig, Dan Williams, Vinod Koul, Lars-Peter Clausen,
Arnd Bergmann, Anatolij Gustschin, Alexander Popov, linuxppc-dev,
devicetree
In-Reply-To: <1383290374-17484-1-git-send-email-a13xp0p0v88@gmail.com>
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.
Signed-off-by: Alexander Popov <a13xp0p0v88@gmail.com>
---
drivers/dma/mpc512x_dma.c | 232 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 227 insertions(+), 5 deletions(-)
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index f41639f..d2ec42d 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -2,6 +2,7 @@
* Copyright (C) Freescale Semicondutor, Inc. 2007, 2008.
* Copyright (C) Semihalf 2009
* Copyright (C) Ilya Yanok, Emcraft Systems 2010
+ * Copyright (C) Alexander Popov, Promcontroller 2013
*
* Written by Piotr Ziecik <kosmo@semihalf.com>. Hardware description
* (defines, structures and comments) was taken from MPC5121 DMA driver
@@ -29,8 +30,15 @@
*/
/*
- * This is initial version of MPC5121 DMA driver. Only memory to memory
- * transfers are supported (tested using dmatest module).
+ * This version of MPC5121 DMA driver supports
+ * memory to memory data transfers (tested using dmatest module) and
+ * data transfers between memory and peripheral I/O memory
+ * by means of slave s/g with these limitations:
+ * - chunked transfers (transfers with more than one part) are refused
+ * as long as proper support for scatter/gather is missing;
+ * - transfers on MPC8308 always start from software as this SoC appears
+ * not to have external request lines for peripheral flow control;
+ * - minimal memory <-> I/O memory transfer size is 4 bytes.
*/
#include <linux/module.h>
@@ -187,6 +195,7 @@ struct mpc_dma_desc {
dma_addr_t tcd_paddr;
int error;
struct list_head node;
+ int will_access_peripheral;
};
struct mpc_dma_chan {
@@ -199,6 +208,10 @@ struct mpc_dma_chan {
struct mpc_dma_tcd *tcd;
dma_addr_t tcd_paddr;
+ /* Settings for access to peripheral FIFO */
+ dma_addr_t per_paddr; /* FIFO address */
+ u32 tcd_nunits;
+
/* Lock for this structure */
spinlock_t lock;
};
@@ -249,8 +262,21 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
struct mpc_dma_desc *mdesc;
int cid = mchan->chan.chan_id;
- /* Move all queued descriptors to active list */
- list_splice_tail_init(&mchan->queued, &mchan->active);
+ while (!list_empty(&mchan->queued)) {
+ mdesc = list_first_entry(&mchan->queued,
+ struct mpc_dma_desc, node);
+
+ /* Grab either several mem-to-mem transfer descriptors
+ * or one peripheral transfer descriptor,
+ * don't mix mem-to-mem and peripheral transfer descriptors
+ * within the same 'active' list. */
+ if (mdesc->will_access_peripheral) {
+ if (list_empty(&mchan->active))
+ list_move_tail(&mdesc->node, &mchan->active);
+ break;
+ } else
+ list_move_tail(&mdesc->node, &mchan->active);
+ }
/* Chain descriptors into one transaction */
list_for_each_entry(mdesc, &mchan->active, node) {
@@ -264,6 +290,8 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan)
prev->tcd->dlast_sga = mdesc->tcd_paddr;
prev->tcd->e_sg = 1;
+
+ /* software initiated start for chained transfers */
mdesc->tcd->start = 1;
prev = mdesc;
@@ -276,7 +304,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);
+ } else if (first->will_access_peripheral) {
+ /* peripherals involved, start by external request signal */
+ out_8(&mdma->regs->dmaserq, cid);
+ } else {
+ /* memory to memory transfer, software initiated start */
+ out_8(&mdma->regs->dmassrt, cid);
+ }
}
/* Handle interrupt on one half of DMA controller (32 channels) */
@@ -594,6 +632,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
}
mdesc->error = 0;
+ mdesc->will_access_peripheral = 0;
tcd = mdesc->tcd;
/* Prepare Transfer Control Descriptor for this transaction */
@@ -641,6 +680,186 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
return &mdesc->desc;
}
+static struct dma_async_tx_descriptor *mpc_dma_prep_slave_sg(
+ struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sg_len, enum dma_transfer_direction direction,
+ unsigned long flags, void *context)
+{
+ struct mpc_dma *mdma = dma_chan_to_mpc_dma(chan);
+ struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
+ struct mpc_dma_desc *mdesc = NULL;
+ dma_addr_t per_paddr;
+ u32 tcd_nunits;
+ struct mpc_dma_tcd *tcd;
+ unsigned long iflags;
+ struct scatterlist *sg;
+ size_t len;
+ int iter, i;
+
+ /* currently there is no proper support for scatter/gather */
+ if (sg_len != 1)
+ return NULL;
+
+ for_each_sg(sgl, sg, sg_len, i) {
+ spin_lock_irqsave(&mchan->lock, iflags);
+
+ mdesc = list_first_entry(&mchan->free, struct mpc_dma_desc,
+ node);
+ if (!mdesc) {
+ spin_unlock_irqrestore(&mchan->lock, iflags);
+ /* try to free completed descriptors */
+ mpc_dma_process_completed(mdma);
+ return NULL;
+ }
+
+ list_del(&mdesc->node);
+
+ per_paddr = mchan->per_paddr;
+ tcd_nunits = mchan->tcd_nunits;
+
+ spin_unlock_irqrestore(&mchan->lock, iflags);
+
+ if (per_paddr == 0 || tcd_nunits == 0)
+ goto err_prep;
+
+ mdesc->error = 0;
+ mdesc->will_access_peripheral = 1;
+ tcd = mdesc->tcd;
+
+ /* Prepare Transfer Control Descriptor for this transaction */
+
+ memset(tcd, 0, sizeof(struct mpc_dma_tcd));
+
+ if (!IS_ALIGNED(sg_dma_address(sg), 4))
+ goto err_prep;
+
+ if (direction == DMA_DEV_TO_MEM) {
+ tcd->saddr = per_paddr;
+ tcd->daddr = sg_dma_address(sg);
+ tcd->soff = 0;
+ tcd->doff = 4;
+ } else if (direction == DMA_MEM_TO_DEV) {
+ tcd->saddr = sg_dma_address(sg);
+ tcd->daddr = per_paddr;
+ tcd->soff = 4;
+ tcd->doff = 0;
+ } else
+ goto err_prep;
+
+ tcd->ssize = MPC_DMA_TSIZE_4;
+ tcd->dsize = MPC_DMA_TSIZE_4;
+
+ len = sg_dma_len(sg);
+ tcd->nbytes = tcd_nunits * 4;
+ if (!IS_ALIGNED(len, tcd->nbytes))
+ goto err_prep;
+
+ iter = len / tcd->nbytes;
+ if (iter >= 1 << 15) {
+ /* len is too big */
+ goto err_prep;
+ } 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 &mdesc->desc;
+
+ err_prep:
+ /* Put the descriptor back */
+ spin_lock_irqsave(&mchan->lock, iflags);
+ list_add_tail(&mdesc->node, &mchan->free);
+ spin_unlock_irqrestore(&mchan->lock, iflags);
+
+ return NULL;
+}
+
+static int mpc_dma_device_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+ unsigned long arg)
+{
+ struct mpc_dma_chan *mchan;
+ struct mpc_dma *mdma;
+ struct dma_slave_config *cfg;
+ unsigned long flags;
+
+ mchan = dma_chan_to_mpc_dma_chan(chan);
+ switch (cmd) {
+ case DMA_TERMINATE_ALL:
+ /* disable channel requests */
+ mdma = dma_chan_to_mpc_dma(chan);
+
+ spin_lock_irqsave(&mchan->lock, flags);
+
+ 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);
+
+ spin_unlock_irqrestore(&mchan->lock, flags);
+
+ return 0;
+ case DMA_SLAVE_CONFIG:
+ /* Constraints:
+ * - only transfers between a peripheral device and
+ * memory are supported;
+ * - minimal transfer size is 4 bytes and consequently
+ * source and destination addresses must be 4-byte aligned and
+ * transfer size must be aligned on (4 * maxburst) boundary;
+ * - RAM address is being incremented by minimal transfer size
+ * during the transfer;
+ * - peripheral port's address is constant during the transfer.
+ */
+
+ cfg = (void *)arg;
+
+ if (cfg->direction != DMA_DEV_TO_MEM &&
+ cfg->direction != DMA_MEM_TO_DEV)
+ return -EINVAL;
+
+ if (cfg->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES &&
+ cfg->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mchan->lock, flags);
+
+ 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;
+ }
+
+ if (!IS_ALIGNED(mchan->per_paddr, 4)) {
+ spin_unlock_irqrestore(&mchan->lock, flags);
+ return -EINVAL;
+ }
+
+ if (mchan->tcd_nunits == 0)
+ mchan->tcd_nunits = 64; /* apply default */
+
+ spin_unlock_irqrestore(&mchan->lock, flags);
+
+ return 0;
+ default:
+ return -ENOSYS;
+ }
+
+ return -EINVAL;
+}
+
static int mpc_dma_probe(struct platform_device *op)
{
struct device_node *dn = op->dev.of_node;
@@ -725,9 +944,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];
--
1.7.11.3
^ permalink raw reply related
* [PATCH RFC v5 1/5] dma: mpc512x: reorder mpc8308 specific instructions
From: Alexander Popov @ 2013-11-01 7:19 UTC (permalink / raw)
To: Gerhard Sittig, Dan Williams, Vinod Koul, Lars-Peter Clausen,
Arnd Bergmann, Anatolij Gustschin, Alexander Popov, linuxppc-dev,
devicetree
In-Reply-To: <1383290374-17484-1-git-send-email-a13xp0p0v88@gmail.com>
Concentrate the specific code for MPC8308 in the 'if' branch
and handle MPC512x in the 'else' branch.
This modification only reorders instructions but doesn't change behaviour.
Signed-off-by: Alexander Popov <a13xp0p0v88@gmail.com>
---
drivers/dma/mpc512x_dma.c | 42 +++++++++++++++++++++++++-----------------
1 file changed, 25 insertions(+), 17 deletions(-)
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 2fe4353..f41639f 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -50,9 +50,17 @@
#define MPC_DMA_DESCRIPTORS 64
/* Macro definitions */
-#define MPC_DMA_CHANNELS 64
#define MPC_DMA_TCD_OFFSET 0x1000
+/*
+ * Maximum channel counts for individual hardware variants
+ * and the maximum channel count over all supported controllers,
+ * used for data structure size
+ */
+#define MPC8308_DMACHAN_MAX 16
+#define MPC512x_DMACHAN_MAX 64
+#define MPC_DMA_CHANNELS 64
+
/* Arbitration mode of group and channel */
#define MPC_DMA_DMACR_EDCG (1 << 31)
#define MPC_DMA_DMACR_ERGA (1 << 3)
@@ -708,10 +716,10 @@ static int mpc_dma_probe(struct platform_device *op)
dma = &mdma->dma;
dma->dev = dev;
- if (!mdma->is_mpc8308)
- dma->chancnt = MPC_DMA_CHANNELS;
+ if (mdma->is_mpc8308)
+ dma->chancnt = MPC8308_DMACHAN_MAX;
else
- dma->chancnt = 16; /* MPC8308 DMA has only 16 channels */
+ dma->chancnt = MPC512x_DMACHAN_MAX;
dma->device_alloc_chan_resources = mpc_dma_alloc_chan_resources;
dma->device_free_chan_resources = mpc_dma_free_chan_resources;
dma->device_issue_pending = mpc_dma_issue_pending;
@@ -745,7 +753,19 @@ static int mpc_dma_probe(struct platform_device *op)
* - Round-robin group arbitration,
* - Round-robin channel arbitration.
*/
- if (!mdma->is_mpc8308) {
+ if (mdma->is_mpc8308) {
+ /* MPC8308 has 16 channels and lacks some registers */
+ out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_ERCA);
+
+ /* enable snooping */
+ out_be32(&mdma->regs->dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
+ /* Disable error interrupts */
+ out_be32(&mdma->regs->dmaeeil, 0);
+
+ /* Clear interrupts status */
+ out_be32(&mdma->regs->dmaintl, 0xFFFF);
+ out_be32(&mdma->regs->dmaerrl, 0xFFFF);
+ } else {
out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_EDCG |
MPC_DMA_DMACR_ERGA | MPC_DMA_DMACR_ERCA);
@@ -766,18 +786,6 @@ static int mpc_dma_probe(struct platform_device *op)
/* Route interrupts to IPIC */
out_be32(&mdma->regs->dmaihsa, 0);
out_be32(&mdma->regs->dmailsa, 0);
- } else {
- /* MPC8308 has 16 channels and lacks some registers */
- out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_ERCA);
-
- /* enable snooping */
- out_be32(&mdma->regs->dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE);
- /* Disable error interrupts */
- out_be32(&mdma->regs->dmaeeil, 0);
-
- /* Clear interrupts status */
- out_be32(&mdma->regs->dmaintl, 0xFFFF);
- out_be32(&mdma->regs->dmaerrl, 0xFFFF);
}
/* Register DMA engine */
--
1.7.11.3
^ permalink raw reply related
* [PATCH RFC v5 0/5] MPC512x DMA slave s/g support, OF DMA lookup
From: Alexander Popov @ 2013-11-01 7:19 UTC (permalink / raw)
To: Gerhard Sittig, Dan Williams, Vinod Koul, Lars-Peter Clausen,
Arnd Bergmann, Anatolij Gustschin, Alexander Popov, linuxppc-dev,
devicetree
03.10.2013 18:00, Alexander Popov <a13xp0p0v88@gmail.com>:
> v2013/7/14 Gerhard Sittig <gsi@denx.de>:
>> 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 in v2:
>> - 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 in v3 and v4:
> 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).
Changes in v5:
Part 2/5::
- add and improve comments;
- improve the code moving transfer descriptors from 'queued' to 'active' list
in mpc_dma_execute();
- allow mpc_dma_prep_slave_sg() to run with non-empty 'active' list;
- take 'mdesc' back to 'free' list in case of error in mpc_dma_prep_slave_sg();
- improve checks of the transfer parameters;
- provide the default value for 'maxburst' in mpc_dma_device_control().
Last 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 are chained correctly now).
>> 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
- adding support for transfers which don't increment the RAM address or
do increment the peripheral "port's" address is easy with
this implementation; but which options of the common API
should be used for specifying such transfers?
Alexander Popov (2):
dma: mpc512x: reorder mpc8308 specific instructions
dma: mpc512x: add support for peripheral transfers
Gerhard Sittig (2):
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 | 295 +++++++++++++++++++--
drivers/dma/of-dma.c | 47 ++++
drivers/mmc/host/mxcmmc.c | 41 ++-
include/linux/of_dma.h | 4 +
6 files changed, 404 insertions(+), 39 deletions(-)
create mode 100644 Documentation/devicetree/bindings/dma/mpc512x-dma.txt
--
1.7.11.3
^ permalink raw reply
* linux-next: manual merge of the leds tree with the powerpc tree
From: Stephen Rothwell @ 2013-11-01 6:30 UTC (permalink / raw)
To: Bryan Wu, Benjamin Herrenschmidt, linuxppc-dev
Cc: Sudeep KarkadaNagesha, linux-next, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1197 bytes --]
Hi Bryan,
Today's linux-next merge of the leds tree got a conflict in
include/linux/of.h between commit a3e31b458844 ("of: Move definition of
of_find_next_cache_node into common code") from the powerpc tree and
commit 954e04b9491a ("of: introduce of_get_available_child_count") from
the leds tree.
I fixed it up (see below) and can carry the fix as necessary (no action
is required).
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --cc include/linux/of.h
index 2567ccd32482,54c25606a997..000000000000
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@@ -228,8 -226,17 +228,19 @@@ static inline int of_get_child_count(co
return num;
}
+ static inline int of_get_available_child_count(const struct device_node *np)
+ {
+ struct device_node *child;
+ int num = 0;
+
+ for_each_available_child_of_node(np, child)
+ num++;
+
+ return num;
+ }
+
+/* cache lookup */
+extern struct device_node *of_find_next_cache_node(const struct device_node *);
extern struct device_node *of_find_node_with_property(
struct device_node *from, const char *prop_name);
#define for_each_node_with_property(dn, prop_name) \
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* linux-next: manual merge of the kvm-ppc tree with the tree
From: Stephen Rothwell @ 2013-11-01 6:05 UTC (permalink / raw)
To: Alexander Graf, Benjamin Herrenschmidt, linuxppc-dev
Cc: Scott Wood, linux-next, linux-kernel, Bharat Bhushan
[-- Attachment #1: Type: text/plain, Size: 498 bytes --]
Hi Alexander,
Today's linux-next merge of the kvm-ppc tree got a conflict in
arch/powerpc/include/asm/processor.h between commit 51ae8d4a2b9e
("powerpc: move debug registers in a structure") from the powerpc tree
and commit 95791988fec6 ("powerpc: move debug registers in a structure")
from the kvm-ppc tree.
Different version of the same patch. I used the powerpc tree version
(there wer other changes there).
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* linux-next: manual merge of the dt-rh tree with the powerpc tree
From: Stephen Rothwell @ 2013-11-01 5:20 UTC (permalink / raw)
To: Rob Herring; +Cc: Sudeep KarkadaNagesha, linux-next, linuxppc-dev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1198 bytes --]
Hi Rob,
Today's linux-next merge of the dt-rh tree got a conflict in
arch/powerpc/include/asm/prom.h between commit a3e31b458844 ("of: Move
definition of of_find_next_cache_node into common code") from the powerpc
tree and commit 0c3f061c195c ("of: implement of_node_to_nid as a weak
function") from the dt-rh tree.
I fixed it up (see below) and can carry the fix as necessary (no action
is required).
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --cc arch/powerpc/include/asm/prom.h
index bf09e5a065b8,7687f82a3217..000000000000
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@@ -44,13 -39,9 +39,6 @@@ void of_parse_dma_window(struct device_
extern void kdump_move_device_tree(void);
- #ifdef CONFIG_NUMA
- extern int of_node_to_nid(struct device_node *device);
- #else
- static inline int of_node_to_nid(struct device_node *device) { return 0; }
- #endif
- #define of_node_to_nid of_node_to_nid
-/* cache lookup */
-struct device_node *of_find_next_cache_node(struct device_node *np);
--
extern void of_instantiate_rtc(void);
extern int of_get_ibm_chip_id(struct device_node *np);
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [Suggestion] drivers: powercap: 'dev_attrs' has already removed from 'struct class'
From: Chen Gang @ 2013-11-01 1:28 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Greg KH, jacob.jun.pan, linuxppc-dev@lists.ozlabs.org,
srinivas.pandruvada
In-Reply-To: <52728461.2080901@intel.com>
On 11/01/2013 12:25 AM, Rafael J. Wysocki wrote:
> On 10/31/2013 3:18 AM, Chen Gang wrote:
>> Hello Maintainers
>>
>> It is removed by "bcc8edb driver core: remove dev_attrs from struct
>> class" in Oct 5 2013. But "75d2364 PowerCap: Add class driver" still
>> use it in Oct 11 2013.
>>
>> The related error (for powerpc with allmodconfig):
>>
>> CC drivers/powercap/powercap_sys.o
>> drivers/powercap/powercap_sys.c:484:2: error: unknown field
>> �dev_attrs� specified in initializer
>> drivers/powercap/powercap_sys.c:484:2: warning: initialization from
>> incompatible pointer type [enabled by default]
>> drivers/powercap/powercap_sys.c:484:2: warning: (near initialization
>> for �powercap_class.suspend�) [enabled by default]
>>
>>
>> Please give a check thanks.
>
> That should have been fixed in the current linux-next already.
>
OK, thanks.
> Thanks,
> Rafael
>
>
>
--
Chen Gang
^ permalink raw reply
* [V2 PATCH 3/3] powerpc: Fix Unaligned LE Floating Point Loads and Stores
From: Tom @ 2013-10-31 18:38 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tom Musta
In-Reply-To: <1383244738-5986-1-git-send-email-tommusta@gmail.com>
From: Tom Musta <tommusta@gmail.com>
This patch addresses unaligned single precision floating point loads
and stores in the single-step code. The old implementation
improperly treated an 8 byte structure as an array of two 4 byte
words, which is a classic little endian bug.
Signed-off-by: Tom Musta <tommusta@gmail.com>
---
arch/powerpc/lib/sstep.c | 52 +++++++++++++++++++++++++++++++++++----------
1 files changed, 40 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index c8743e1..1cfd150 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -355,22 +355,36 @@ static int __kprobes do_fp_load(int rn, int (*func)(int, unsigned long),
struct pt_regs *regs)
{
int err;
- unsigned long val[sizeof(double) / sizeof(long)];
+ union {
+ double dbl;
+ unsigned long ul[2];
+ struct {
+#ifdef __BIG_ENDIAN__
+ unsigned _pad_;
+ unsigned word;
+#endif
+#ifdef __LITTLE_ENDIAN__
+ unsigned word;
+ unsigned _pad_;
+#endif
+ } single;
+ } data;
unsigned long ptr;
if (!address_ok(regs, ea, nb))
return -EFAULT;
if ((ea & 3) == 0)
return (*func)(rn, ea);
- ptr = (unsigned long) &val[0];
+ ptr = (unsigned long) &data.ul;
if (sizeof(unsigned long) == 8 || nb == 4) {
- err = read_mem_unaligned(&val[0], ea, nb, regs);
- ptr += sizeof(unsigned long) - nb;
+ err = read_mem_unaligned(&data.ul[0], ea, nb, regs);
+ if (nb == 4)
+ ptr = (unsigned long)&(data.single.word);
} else {
/* reading a double on 32-bit */
- err = read_mem_unaligned(&val[0], ea, 4, regs);
+ err = read_mem_unaligned(&data.ul[0], ea, 4, regs);
if (!err)
- err = read_mem_unaligned(&val[1], ea + 4, 4, regs);
+ err = read_mem_unaligned(&data.ul[1], ea + 4, 4, regs);
}
if (err)
return err;
@@ -382,28 +396,42 @@ static int __kprobes do_fp_store(int rn, int (*func)(int, unsigned long),
struct pt_regs *regs)
{
int err;
- unsigned long val[sizeof(double) / sizeof(long)];
+ union {
+ double dbl;
+ unsigned long ul[2];
+ struct {
+#ifdef __BIG_ENDIAN__
+ unsigned _pad_;
+ unsigned word;
+#endif
+#ifdef __LITTLE_ENDIAN__
+ unsigned word;
+ unsigned _pad_;
+#endif
+ } single;
+ } data;
unsigned long ptr;
if (!address_ok(regs, ea, nb))
return -EFAULT;
if ((ea & 3) == 0)
return (*func)(rn, ea);
- ptr = (unsigned long) &val[0];
+ ptr = (unsigned long) &data.ul[0];
if (sizeof(unsigned long) == 8 || nb == 4) {
- ptr += sizeof(unsigned long) - nb;
+ if (nb == 4)
+ ptr = (unsigned long)&(data.single.word);
err = (*func)(rn, ptr);
if (err)
return err;
- err = write_mem_unaligned(val[0], ea, nb, regs);
+ err = write_mem_unaligned(data.ul[0], ea, nb, regs);
} else {
/* writing a double on 32-bit */
err = (*func)(rn, ptr);
if (err)
return err;
- err = write_mem_unaligned(val[0], ea, 4, regs);
+ err = write_mem_unaligned(data.ul[0], ea, 4, regs);
if (!err)
- err = write_mem_unaligned(val[1], ea + 4, 4, regs);
+ err = write_mem_unaligned(data.ul[1], ea + 4, 4, regs);
}
return err;
}
--
1.7.1
^ permalink raw reply related
* [V2 PATCH 2/3] powerpc: Fix Unaligned Fixed Point Loads and Stores
From: Tom @ 2013-10-31 18:38 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tom Musta
In-Reply-To: <1383244738-5986-1-git-send-email-tommusta@gmail.com>
From: Tom Musta <tommusta@gmail.com>
This patch modifies the unaligned access routines of the sstep.c
module so that it properly reverses the bytes of storage operands
in the little endian kernel kernel.
Signed-off-by: Tom Musta <tommusta@gmail.com>
---
arch/powerpc/lib/sstep.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 7bfaa9d..c8743e1 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -212,11 +212,19 @@ static int __kprobes read_mem_unaligned(unsigned long *dest, unsigned long ea,
{
int err;
unsigned long x, b, c;
+#ifdef __LITTLE_ENDIAN__
+ int len = nb; /* save a copy of the length for byte reversal */
+#endif
/* unaligned, do this in pieces */
x = 0;
for (; nb > 0; nb -= c) {
+#ifdef __LITTLE_ENDIAN__
+ c = 1;
+#endif
+#ifdef __BIG_ENDIAN__
c = max_align(ea);
+#endif
if (c > nb)
c = max_align(nb);
err = read_mem_aligned(&b, ea, c);
@@ -225,7 +233,24 @@ static int __kprobes read_mem_unaligned(unsigned long *dest, unsigned long ea,
x = (x << (8 * c)) + b;
ea += c;
}
+#ifdef __LITTLE_ENDIAN__
+ switch (len) {
+ case 2:
+ *dest = byterev_2(x);
+ break;
+ case 4:
+ *dest = byterev_4(x);
+ break;
+#ifdef __powerpc64__
+ case 8:
+ *dest = byterev_8(x);
+ break;
+#endif
+ }
+#endif
+#ifdef __BIG_ENDIAN__
*dest = x;
+#endif
return 0;
}
@@ -273,9 +298,29 @@ static int __kprobes write_mem_unaligned(unsigned long val, unsigned long ea,
int err;
unsigned long c;
+#ifdef __LITTLE_ENDIAN__
+ switch (nb) {
+ case 2:
+ val = byterev_2(val);
+ break;
+ case 4:
+ val = byterev_4(val);
+ break;
+#ifdef __powerpc64__
+ case 8:
+ val = byterev_8(val);
+ break;
+#endif
+ }
+#endif
/* unaligned or little-endian, do this in pieces */
for (; nb > 0; nb -= c) {
+#ifdef __LITTLE_ENDIAN__
+ c = 1;
+#endif
+#ifdef __BIG_ENDIAN__
c = max_align(ea);
+#endif
if (c > nb)
c = max_align(nb);
err = write_mem_aligned(val >> (nb - c) * 8, ea, c);
--
1.7.1
^ permalink raw reply related
* [V2 PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode
From: Tom @ 2013-10-31 18:38 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tom Musta
In-Reply-To: <1383244738-5986-1-git-send-email-tommusta@gmail.com>
From: Tom Musta <tommusta@gmail.com>
This patch modifies the endian chicken switch in the single step
emulation code (emulate_step()). The old (big endian) code bailed
early if a load or store instruction was to be emulated in little
endian mode.
The new code modifies the check and only bails in a cross-endian
situation (LE mode in a kernel compiled for BE and vice verse).
V2: fixed bug in MSR[LE] check identified by Andreas Schwab and
Geert Uytterhoeven.
Signed-off-by: Tom Musta <tommusta@gmail.com>
---
arch/powerpc/lib/sstep.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index b1faa15..7bfaa9d 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1222,12 +1222,18 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
}
/*
- * Following cases are for loads and stores, so bail out
- * if we're in little-endian mode.
+ * Following cases are for loads and stores and this
+ * implementation does not support cross-endian. So
+ * bail out if this is the case.
*/
+#ifdef __BIG_ENDIAN__
if (regs->msr & MSR_LE)
return 0;
-
+#endif
+#ifdef __LITTLE_ENDIAN__
+ if (!(regs->msr & MSR_LE))
+ return 0;
+#endif
/*
* Save register RA in case it's an update form load or store
* and the access faults.
--
1.7.1
^ permalink raw reply related
* [V2 PATCH 0/3] powerpc: Fix Little Endian Bugs in Single Step Code
From: Tom @ 2013-10-31 18:38 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tom Musta
From: Tom Musta <tommusta@gmail.com>
This patch series addresses bugs in the PowerPC single-step emulation
code (arch/powerpc/lib/sstep.c) pertaining to Little Endian.
The existing code has a chicken switch for little endian. The first
patch softens the restriction so that only cross-endian modes are not
supported.
There is a general problem with unaligned little endian loads and stores.
This is addressed by the second patch.
Finally, there is a problem with unaligned single precision floating point
loads and stores which is addressed by the third patch.
V2: fixed bug in MSR[LE] check identified by Andreas Schwab and
Geert Uytterhoeven.
Tom Musta (3):
powerpc: Enable emulate_step In Little Endian Mode
powerpc: Fix Unaligned Fixed Point Loads and Stores
powerpc: Fix Unaligned LE Floating Point Loads and Stores
arch/powerpc/lib/sstep.c | 109 +++++++++++++++++++++++++++++++++++++++------
1 files changed, 94 insertions(+), 15 deletions(-)
^ permalink raw reply
* Re: [PATCH v4 3/4] ASoC: fsl_ssi: Add dual fifo mode support
From: Mark Brown @ 2013-10-31 18:36 UTC (permalink / raw)
To: Nicolin Chen
Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
s.hauer, swarren, timur, rob.herring, linux-kernel,
ijc+devicetree, dmaengine, shawn.guo, linuxppc-dev,
linux-arm-kernel
In-Reply-To: <dda0bc1221f053405da616192577228c51821040.1383226444.git.b42378@freescale.com>
[-- Attachment #1: Type: text/plain, Size: 314 bytes --]
On Thu, Oct 31, 2013 at 09:44:15PM +0800, Nicolin Chen wrote:
> By enabling dual fifo mode, it would allow SSI enter a better performance
> to transimit/receive data without occasional hardware underrun/overrun.
>
> [ Passed compile-test with mpc85xx_defconfig ]
Acked-by: Mark Brown <broonie@linaro.org>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [Suggestion] drivers: powercap: 'dev_attrs' has already removed from 'struct class'
From: Rafael J. Wysocki @ 2013-10-31 16:25 UTC (permalink / raw)
To: Chen Gang, srinivas.pandruvada, jacob.jun.pan,
linuxppc-dev@lists.ozlabs.org
Cc: Greg KH
In-Reply-To: <5271BDFD.2050205@asianux.com>
On 10/31/2013 3:18 AM, Chen Gang wrote:
> Hello Maintainers
>
> It is removed by "bcc8edb driver core: remove dev_attrs from struct
> class" in Oct 5 2013. But "75d2364 PowerCap: Add class driver" still
> use it in Oct 11 2013.
>
> The related error (for powerpc with allmodconfig):
>
> CC drivers/powercap/powercap_sys.o
> drivers/powercap/powercap_sys.c:484:2: error: unknown field ‘dev_attrs’ specified in initializer
> drivers/powercap/powercap_sys.c:484:2: warning: initialization from incompatible pointer type [enabled by default]
> drivers/powercap/powercap_sys.c:484:2: warning: (near initialization for ‘powercap_class.suspend’) [enabled by default]
>
>
> Please give a check thanks.
That should have been fixed in the current linux-next already.
Thanks,
Rafael
^ permalink raw reply
* Re: perf events ring buffer memory barrier on powerpc
From: Peter Zijlstra @ 2013-10-31 15:19 UTC (permalink / raw)
To: Paul E. McKenney
Cc: Michael Neuling, Mathieu Desnoyers, LKML, Oleg Nesterov,
Linux PPC dev, Anton Blanchard, Frederic Weisbecker,
Victor Kaplansky
In-Reply-To: <20131031150756.GB4067@linux.vnet.ibm.com>
On Thu, Oct 31, 2013 at 08:07:56AM -0700, Paul E. McKenney wrote:
> On Thu, Oct 31, 2013 at 10:04:57AM +0100, Peter Zijlstra wrote:
> > On Wed, Oct 30, 2013 at 09:32:58PM -0700, Paul E. McKenney wrote:
> > > Before C/C++11, the closest thing to such a prohibition is use of
> > > volatile, for example, ACCESS_ONCE(). Even in C/C++11, you have to
> > > use atomics to get anything resembing this prohibition.
> > >
> > > If you just use normal variables, the compiler is within its rights
> > > to transform something like the following:
> > >
> > > if (a)
> > > b = 1;
> > > else
> > > b = 42;
> > >
> > > Into:
> > >
> > > b = 42;
> > > if (a)
> > > b = 1;
> > >
> > > Many other similar transformations are permitted. Some are used to all
> > > vector instructions to be used -- the compiler can do a write with an
> > > overly wide vector instruction, then clean up the clobbered variables
> > > later, if it wishes. Again, if the variables are not marked volatile,
> > > or, in C/C++11, atomic.
> >
> > While I've heard you tell this story before, my mind keeps boggling how
> > we've been able to use shared memory at all, all these years.
> >
> > It seems to me stuff should have broken left, right and center if
> > compilers were really aggressive about this.
>
> Sometimes having stupid compilers is a good thing. But they really are
> getting more aggressive.
But surely we cannot go mark all data structures lodged in shared memory
as volatile, that's insane.
I'm sure you're quite worried about this as well. Suppose we have:
struct foo {
unsigned long value;
void *ptr;
unsigned long value1;
};
And our ptr member is RCU managed. Then while the assignment using:
rcu_assign_ptr() will use the volatile cast, what stops the compiler
from wrecking ptr while writing either of the value* members and
'fixing' her up after?
This is a completely untenable position.
How do the C/C++ people propose to deal with this?
^ permalink raw reply
* Re: perf events ring buffer memory barrier on powerpc
From: Paul E. McKenney @ 2013-10-31 15:07 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Michael Neuling, Mathieu Desnoyers, LKML, Oleg Nesterov,
Linux PPC dev, Anton Blanchard, Frederic Weisbecker,
Victor Kaplansky
In-Reply-To: <20131031090457.GU19466@laptop.lan>
On Thu, Oct 31, 2013 at 10:04:57AM +0100, Peter Zijlstra wrote:
> On Wed, Oct 30, 2013 at 09:32:58PM -0700, Paul E. McKenney wrote:
> > Before C/C++11, the closest thing to such a prohibition is use of
> > volatile, for example, ACCESS_ONCE(). Even in C/C++11, you have to
> > use atomics to get anything resembing this prohibition.
> >
> > If you just use normal variables, the compiler is within its rights
> > to transform something like the following:
> >
> > if (a)
> > b = 1;
> > else
> > b = 42;
> >
> > Into:
> >
> > b = 42;
> > if (a)
> > b = 1;
> >
> > Many other similar transformations are permitted. Some are used to all
> > vector instructions to be used -- the compiler can do a write with an
> > overly wide vector instruction, then clean up the clobbered variables
> > later, if it wishes. Again, if the variables are not marked volatile,
> > or, in C/C++11, atomic.
>
> While I've heard you tell this story before, my mind keeps boggling how
> we've been able to use shared memory at all, all these years.
>
> It seems to me stuff should have broken left, right and center if
> compilers were really aggressive about this.
Sometimes having stupid compilers is a good thing. But they really are
getting more aggressive.
Thanx, Paul
^ permalink raw reply
* Re: [PATCH 19/51] DMA-API: media: dt3155v4l: replace dma_set_mask()+dma_set_coherent_mask() with new helper
From: Russell King - ARM Linux @ 2013-10-31 14:49 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: alsa-devel, linux-doc, linux-wireless, linux-fbdev, dri-devel,
Hans Verkuil, linux-ide, devel, linux-samsung-soc, linux-scsi,
e1000-devel, b43-dev, linux-media, devicetree, linux-nvme,
linux-tegra, linux-omap, linux-arm-kernel,
Solarflare linux maintainers, netdev, linux-usb, linux-mmc,
linux-crypto, Greg Kroah-Hartman, uclinux-dist-devel,
linuxppc-dev
In-Reply-To: <20131031094640.205840a2@samsung.com>
On Thu, Oct 31, 2013 at 09:46:40AM -0200, Mauro Carvalho Chehab wrote:
> Hi Russell,
>
> Em Mon, 30 Sep 2013 13:57:47 +0200
> Hans Verkuil <hverkuil@xs4all.nl> escreveu:
>
> > On 09/19/2013 11:44 PM, Russell King wrote:
> > > Replace the following sequence:
> > >
> > > dma_set_mask(dev, mask);
> > > dma_set_coherent_mask(dev, mask);
> > >
> > > with a call to the new helper dma_set_mask_and_coherent().
> > >
> > > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> >
> > Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
>
> Somehow, I lost your original post (I got unsubscribed on a few days
> from all vger mailing lists at the end of september).
>
> I suspect that you want to sent this via your tree, right?
Yes please.
> If so:
>
> Acked-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Added, thanks.
> > > - err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
> > > - if (err)
> > > - return -ENODEV;
> > > - err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
> > > + err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
> > > if (err)
> > > return -ENODEV;
One thing I've just noticed is that return should be "return err" not
"return -ENODEV" - are you okay for me to change that in this patch?
Thanks.
^ permalink raw reply
* [PATCH v4 4/4] ARM: dts: imx: use dual-fifo sdma script for ssi
From: Nicolin Chen @ 2013-10-31 13:44 UTC (permalink / raw)
To: timur, shawn.guo, broonie, s.hauer
Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
swarren, linux-kernel, rob.herring, dmaengine, ijc+devicetree,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <cover.1383226444.git.b42378@freescale.com>
Use dual-fifo sdma scripts instead of shared scripts for ssi on i.MX series.
Signed-off-by: Nicolin Chen <b42378@freescale.com>
---
arch/arm/boot/dts/imx51.dtsi | 4 ++--
arch/arm/boot/dts/imx53.dtsi | 4 ++--
arch/arm/boot/dts/imx6qdl.dtsi | 12 ++++++------
arch/arm/boot/dts/imx6sl.dtsi | 12 ++++++------
4 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 54cee65..1a71eac 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -154,8 +154,8 @@
reg = <0x70014000 0x4000>;
interrupts = <30>;
clocks = <&clks 49>;
- dmas = <&sdma 24 1 0>,
- <&sdma 25 1 0>;
+ dmas = <&sdma 24 22 0>,
+ <&sdma 25 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 4307e80..7208fde 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -153,8 +153,8 @@
reg = <0x50014000 0x4000>;
interrupts = <30>;
clocks = <&clks 49>;
- dmas = <&sdma 24 1 0>,
- <&sdma 25 1 0>;
+ dmas = <&sdma 24 22 0>,
+ <&sdma 25 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 57e9c38..6e096ca 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -223,8 +223,8 @@
reg = <0x02028000 0x4000>;
interrupts = <0 46 0x04>;
clocks = <&clks 178>;
- dmas = <&sdma 37 1 0>,
- <&sdma 38 1 0>;
+ dmas = <&sdma 37 22 0>,
+ <&sdma 38 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <38 37>;
@@ -236,8 +236,8 @@
reg = <0x0202c000 0x4000>;
interrupts = <0 47 0x04>;
clocks = <&clks 179>;
- dmas = <&sdma 41 1 0>,
- <&sdma 42 1 0>;
+ dmas = <&sdma 41 22 0>,
+ <&sdma 42 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <42 41>;
@@ -249,8 +249,8 @@
reg = <0x02030000 0x4000>;
interrupts = <0 48 0x04>;
clocks = <&clks 180>;
- dmas = <&sdma 45 1 0>,
- <&sdma 46 1 0>;
+ dmas = <&sdma 45 22 0>,
+ <&sdma 46 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
fsl,ssi-dma-events = <46 45>;
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index c46651e..b32ba99 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -195,8 +195,8 @@
reg = <0x02028000 0x4000>;
interrupts = <0 46 0x04>;
clocks = <&clks IMX6SL_CLK_SSI1>;
- dmas = <&sdma 37 1 0>,
- <&sdma 38 1 0>;
+ dmas = <&sdma 37 22 0>,
+ <&sdma 38 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
status = "disabled";
@@ -207,8 +207,8 @@
reg = <0x0202c000 0x4000>;
interrupts = <0 47 0x04>;
clocks = <&clks IMX6SL_CLK_SSI2>;
- dmas = <&sdma 41 1 0>,
- <&sdma 42 1 0>;
+ dmas = <&sdma 41 22 0>,
+ <&sdma 42 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
status = "disabled";
@@ -219,8 +219,8 @@
reg = <0x02030000 0x4000>;
interrupts = <0 48 0x04>;
clocks = <&clks IMX6SL_CLK_SSI3>;
- dmas = <&sdma 45 1 0>,
- <&sdma 46 1 0>;
+ dmas = <&sdma 45 22 0>,
+ <&sdma 46 22 0>;
dma-names = "rx", "tx";
fsl,fifo-depth = <15>;
status = "disabled";
--
1.8.4
^ permalink raw reply related
* [PATCH v4 3/4] ASoC: fsl_ssi: Add dual fifo mode support
From: Nicolin Chen @ 2013-10-31 13:44 UTC (permalink / raw)
To: timur, shawn.guo, broonie, s.hauer
Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
swarren, linux-kernel, rob.herring, dmaengine, ijc+devicetree,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <cover.1383226444.git.b42378@freescale.com>
By enabling dual fifo mode, it would allow SSI enter a better performance
to transimit/receive data without occasional hardware underrun/overrun.
[ Passed compile-test with mpc85xx_defconfig ]
Signed-off-by: Nicolin Chen <b42378@freescale.com>
---
sound/soc/fsl/fsl_ssi.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 35e2773..0892111 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -143,6 +143,7 @@ struct fsl_ssi_private {
bool ssi_on_imx;
bool imx_ac97;
bool use_dma;
+ bool use_dual_fifo;
struct clk *clk;
struct snd_dmaengine_dai_dma_data dma_params_tx;
struct snd_dmaengine_dai_dma_data dma_params_rx;
@@ -413,6 +414,12 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor);
}
+ if (ssi_private->use_dual_fifo) {
+ write_ssi_mask(&ssi->srcr, 0, CCSR_SSI_SRCR_RFEN1);
+ write_ssi_mask(&ssi->stcr, 0, CCSR_SSI_STCR_TFEN1);
+ write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_TCH_EN);
+ }
+
return 0;
}
@@ -947,7 +954,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
ssi_private->fifo_depth = 8;
if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) {
- u32 dma_events[2];
+ u32 dma_events[2], dmas[4];
ssi_private->ssi_on_imx = true;
ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
@@ -1001,6 +1008,15 @@ static int fsl_ssi_probe(struct platform_device *pdev)
dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
+ if (!of_property_read_u32_array(pdev->dev.of_node, "dmas", dmas, 4)
+ && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
+ ssi_private->use_dual_fifo = true;
+ /* When using dual fifo mode, we need to keep watermark
+ * as even numbers due to dma script limitation.
+ */
+ ssi_private->dma_params_tx.maxburst &= ~0x1;
+ ssi_private->dma_params_rx.maxburst &= ~0x1;
+ }
} else if (ssi_private->use_dma) {
/* The 'name' should not have any slashes in it. */
ret = devm_request_irq(&pdev->dev, ssi_private->irq,
--
1.8.4
^ permalink raw reply related
* [PATCH v4 2/4] dma: imx-sdma: Add new dma type for ssi dual fifo script
From: Nicolin Chen @ 2013-10-31 13:44 UTC (permalink / raw)
To: timur, shawn.guo, broonie, s.hauer
Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
swarren, linux-kernel, rob.herring, dmaengine, ijc+devicetree,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <cover.1383226444.git.b42378@freescale.com>
This patch adds a new DMA_TYPE for SSI dual FIFO script, included
in SDMA firmware version 2. This script would allow SSI use dual
fifo mode to transimit/receive data without occasional hardware
underrun/overrun.
Signed-off-by: Nicolin Chen <b42378@freescale.com>
---
Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt | 1 +
drivers/dma/imx-sdma.c | 4 ++++
include/linux/platform_data/dma-imx.h | 1 +
3 files changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
index 4fa814d..68b83ec 100644
--- a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
+++ b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
@@ -42,6 +42,7 @@ The full ID of peripheral types can be found below.
19 IPU Memory
20 ASRC
21 ESAI
+ 22 SSI Dual FIFO (needs firmware ver >= 2)
The third cell specifies the transfer priority as below.
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index c7ece8d..efaa9a9 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -725,6 +725,10 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
per_2_emi = sdma->script_addrs->app_2_mcu_addr;
emi_2_per = sdma->script_addrs->mcu_2_app_addr;
break;
+ case IMX_DMATYPE_SSI_DUAL:
+ per_2_emi = sdma->script_addrs->ssish_2_mcu_addr;
+ emi_2_per = sdma->script_addrs->mcu_2_ssish_addr;
+ break;
case IMX_DMATYPE_SSI_SP:
case IMX_DMATYPE_MMC:
case IMX_DMATYPE_SDHC:
diff --git a/include/linux/platform_data/dma-imx.h b/include/linux/platform_data/dma-imx.h
index beac6b8..bcbc6c3 100644
--- a/include/linux/platform_data/dma-imx.h
+++ b/include/linux/platform_data/dma-imx.h
@@ -39,6 +39,7 @@ enum sdma_peripheral_type {
IMX_DMATYPE_IPU_MEMORY, /* IPU Memory */
IMX_DMATYPE_ASRC, /* ASRC */
IMX_DMATYPE_ESAI, /* ESAI */
+ IMX_DMATYPE_SSI_DUAL, /* SSI Dual FIFO */
};
enum imx_dma_prio {
--
1.8.4
^ permalink raw reply related
* [PATCH v4 0/4] Add dual-fifo mode support of i.MX ssi
From: Nicolin Chen @ 2013-10-31 13:44 UTC (permalink / raw)
To: timur, shawn.guo, broonie, s.hauer
Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
swarren, linux-kernel, rob.herring, dmaengine, ijc+devicetree,
linuxppc-dev, linux-arm-kernel
Changelog
v4:
* PATCH-3: Drop useless register configuration.
*
* Nothing changes for the other three patches
v3:
* PATCH-1: Add comments to indicate the end of v1 and v2 array.
* PATCH-3: Use better way to keep watermark as even number.
*
* Nothing changes for PATCH-2 and PATCH-4
v2:
* Instead of adding rogue scripts to current SDMA driver based on firmware
* V1, we define the new SDMA firmware as version 2 and bisect the PATCH-1
* to two patches: The first is to add version check code to the SDMA driver;
* And the second is to add SSI dual FIFO DMATYPE.
*
* Nothing changes for the last two patches.
v1:
* SSI can reduce hardware overrun/underrun possibility when using dual
* fifo mode. To support this mode, we need to first update sdma sciprt
* list, and then enable dual fifo BIT in SSI driver, and last update DT
* bindings of i.MX series.
*
* ! This series of patches has a direct dependency between them. When
* ! applying them, we need to apply to one single branch. Otherwise,
* ! it would break currect branches.
Nicolin Chen (4):
dma: imx-sdma: Add sdma firmware version 2 support
dma: imx-sdma: Add new dma type for ssi dual fifo script
ASoC: fsl_ssi: Add dual fifo mode support
ARM: dts: imx: use dual-fifo sdma script for ssi
.../devicetree/bindings/dma/fsl-imx-sdma.txt | 1 +
arch/arm/boot/dts/imx51.dtsi | 4 ++--
arch/arm/boot/dts/imx53.dtsi | 4 ++--
arch/arm/boot/dts/imx6qdl.dtsi | 12 ++++++------
arch/arm/boot/dts/imx6sl.dtsi | 12 ++++++------
drivers/dma/imx-sdma.c | 19 ++++++++++++++++++-
include/linux/platform_data/dma-imx-sdma.h | 5 +++++
include/linux/platform_data/dma-imx.h | 1 +
sound/soc/fsl/fsl_ssi.c | 18 +++++++++++++++++-
9 files changed, 58 insertions(+), 18 deletions(-)
--
1.8.4
^ permalink raw reply
* [PATCH v4 1/4] dma: imx-sdma: Add sdma firmware version 2 support
From: Nicolin Chen @ 2013-10-31 13:44 UTC (permalink / raw)
To: timur, shawn.guo, broonie, s.hauer
Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
swarren, linux-kernel, rob.herring, dmaengine, ijc+devicetree,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <cover.1383226444.git.b42378@freescale.com>
On i.MX5/6 series, SDMA is using new version firmware to support SSI
dual FIFO feature and HDMI Audio (i.MX6Q/DL only). Thus add it.
Signed-off-by: Nicolin Chen <b42378@freescale.com>
---
drivers/dma/imx-sdma.c | 15 ++++++++++++++-
include/linux/platform_data/dma-imx-sdma.h | 5 +++++
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index fc43603..c7ece8d 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -323,6 +323,7 @@ struct sdma_engine {
struct clk *clk_ipg;
struct clk *clk_ahb;
spinlock_t channel_0_lock;
+ u32 script_number;
struct sdma_script_start_addrs *script_addrs;
const struct sdma_driver_data *drvdata;
};
@@ -1238,6 +1239,7 @@ static void sdma_issue_pending(struct dma_chan *chan)
}
#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1 34
+#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2 38
static void sdma_add_scripts(struct sdma_engine *sdma,
const struct sdma_script_start_addrs *addr)
@@ -1246,7 +1248,7 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
s32 *saddr_arr = (u32 *)sdma->script_addrs;
int i;
- for (i = 0; i < SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; i++)
+ for (i = 0; i < sdma->script_number; i++)
if (addr_arr[i] > 0)
saddr_arr[i] = addr_arr[i];
}
@@ -1272,6 +1274,17 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
goto err_firmware;
if (header->ram_code_start + header->ram_code_size > fw->size)
goto err_firmware;
+ switch (header->version_major) {
+ case 1:
+ sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
+ break;
+ case 2:
+ sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2;
+ break;
+ default:
+ dev_err(sdma->dev, "unknown firmware version\n");
+ return;
+ }
addr = (void *)header + header->script_addrs_start;
ram_code = (void *)header + header->ram_code_start;
diff --git a/include/linux/platform_data/dma-imx-sdma.h b/include/linux/platform_data/dma-imx-sdma.h
index 3a39428..eabac4e 100644
--- a/include/linux/platform_data/dma-imx-sdma.h
+++ b/include/linux/platform_data/dma-imx-sdma.h
@@ -43,6 +43,11 @@ struct sdma_script_start_addrs {
s32 dptc_dvfs_addr;
s32 utra_addr;
s32 ram_code_start_addr;
+ /* End of v1 array */
+ s32 mcu_2_ssish_addr;
+ s32 ssish_2_mcu_addr;
+ s32 hdmi_dma_addr;
+ /* End of v2 array */
};
/**
--
1.8.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox