* [RESEND PATCH v4 0/3] dmaengine: Add clock support for AXI DMAS
@ 2016-05-12 9:43 Kedareswara rao Appana
2016-05-12 9:43 ` [RESEND PATCH v4 1/3] dmaengine: vdma: Add config structure to differentiate dmas Kedareswara rao Appana
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Kedareswara rao Appana @ 2016-05-12 9:43 UTC (permalink / raw)
To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
michal.simek, soren.brinkmann, vinod.koul, dan.j.williams,
appanad, moritz.fischer, laurent.pinchart, luis, svemula, anirudh
Cc: devicetree, linux-arm-kernel, linux-kernel, dmaengine
This patch series adds basic clock support for AXI DMAS
This patch series is created on top of the dma-next branch.
Kedareswara rao Appana (3):
dmaengine: vdma: Add config structure to differentiate dmas
Documentation: DT: vdma: Add clock support for dmas
dmaengine: vdma: Add clock support
.../devicetree/bindings/dma/xilinx/xilinx_vdma.txt | 15 +
drivers/dma/xilinx/xilinx_vdma.c | 307 ++++++++++++++++++---
2 files changed, 289 insertions(+), 33 deletions(-)
--
2.1.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [RESEND PATCH v4 1/3] dmaengine: vdma: Add config structure to differentiate dmas
2016-05-12 9:43 [RESEND PATCH v4 0/3] dmaengine: Add clock support for AXI DMAS Kedareswara rao Appana
@ 2016-05-12 9:43 ` Kedareswara rao Appana
2016-05-12 16:09 ` Vinod Koul
[not found] ` <1463046228-21651-1-git-send-email-appanad-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
2016-05-12 9:43 ` [RESEND PATCH v4 3/3] dmaengine: vdma: Add clock support Kedareswara rao Appana
2 siblings, 1 reply; 6+ messages in thread
From: Kedareswara rao Appana @ 2016-05-12 9:43 UTC (permalink / raw)
To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
michal.simek, soren.brinkmann, vinod.koul, dan.j.williams,
appanad, moritz.fischer, laurent.pinchart, luis, svemula, anirudh
Cc: dmaengine, devicetree, linux-kernel, linux-arm-kernel
This patch adds config structure in the driver to differentiate
AXI DMA's and to add more features(clock support etc..) to these DMA's.
Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
drivers/dma/xilinx/xilinx_vdma.c | 83 ++++++++++++++++++++++++----------------
1 file changed, 51 insertions(+), 32 deletions(-)
diff --git a/drivers/dma/xilinx/xilinx_vdma.c b/drivers/dma/xilinx/xilinx_vdma.c
index 626939b..1d50e05 100644
--- a/drivers/dma/xilinx/xilinx_vdma.c
+++ b/drivers/dma/xilinx/xilinx_vdma.c
@@ -342,6 +342,10 @@ struct xilinx_dma_chan {
void (*start_transfer)(struct xilinx_dma_chan *chan);
};
+struct dma_config {
+ enum xdma_ip_type dmatype;
+};
+
/**
* struct xilinx_dma_device - DMA device structure
* @regs: I/O mapped base address
@@ -351,7 +355,7 @@ struct xilinx_dma_chan {
* @has_sg: Specifies whether Scatter-Gather is present or not
* @flush_on_fsync: Flush on frame sync
* @ext_addr: Indicates 64 bit addressing is supported by dma device
- * @dmatype: DMA ip type
+ * @dma_config: DMA config structure
*/
struct xilinx_dma_device {
void __iomem *regs;
@@ -361,7 +365,7 @@ struct xilinx_dma_device {
bool has_sg;
u32 flush_on_fsync;
bool ext_addr;
- enum xdma_ip_type dmatype;
+ const struct dma_config *dma_config;
};
/* Macros */
@@ -572,12 +576,12 @@ xilinx_dma_free_tx_descriptor(struct xilinx_dma_chan *chan,
if (!desc)
return;
- if (chan->xdev->dmatype == XDMA_TYPE_VDMA) {
+ if (chan->xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {
list_for_each_entry_safe(segment, next, &desc->segments, node) {
list_del(&segment->node);
xilinx_vdma_free_tx_segment(chan, segment);
}
- } else if (chan->xdev->dmatype == XDMA_TYPE_CDMA) {
+ } else if (chan->xdev->dma_config->dmatype == XDMA_TYPE_CDMA) {
list_for_each_entry_safe(cdma_segment, cdma_next,
&desc->segments, node) {
list_del(&cdma_segment->node);
@@ -640,7 +644,7 @@ static void xilinx_dma_free_chan_resources(struct dma_chan *dchan)
dev_dbg(chan->dev, "Free all channel resources.\n");
xilinx_dma_free_descriptors(chan);
- if (chan->xdev->dmatype == XDMA_TYPE_AXIDMA)
+ if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA)
xilinx_dma_free_tx_segment(chan, chan->seg_v);
dma_pool_destroy(chan->desc_pool);
chan->desc_pool = NULL;
@@ -710,13 +714,13 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
* We need the descriptor to be aligned to 64bytes
* for meeting Xilinx VDMA specification requirement.
*/
- if (chan->xdev->dmatype == XDMA_TYPE_AXIDMA) {
+ if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
chan->desc_pool = dma_pool_create("xilinx_dma_desc_pool",
chan->dev,
sizeof(struct xilinx_axidma_tx_segment),
__alignof__(struct xilinx_axidma_tx_segment),
0);
- } else if (chan->xdev->dmatype == XDMA_TYPE_CDMA) {
+ } else if (chan->xdev->dma_config->dmatype == XDMA_TYPE_CDMA) {
chan->desc_pool = dma_pool_create("xilinx_cdma_desc_pool",
chan->dev,
sizeof(struct xilinx_cdma_tx_segment),
@@ -737,7 +741,7 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
return -ENOMEM;
}
- if (chan->xdev->dmatype == XDMA_TYPE_AXIDMA)
+ if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA)
/*
* For AXI DMA case after submitting a pending_list, keep
* an extra segment allocated so that the "next descriptor"
@@ -750,7 +754,7 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
dma_cookie_init(dchan);
- if (chan->xdev->dmatype == XDMA_TYPE_AXIDMA) {
+ if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
/* For AXI DMA resetting once channel will reset the
* other channel as well so enable the interrupts here.
*/
@@ -758,7 +762,7 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
XILINX_DMA_DMAXR_ALL_IRQ_MASK);
}
- if ((chan->xdev->dmatype == XDMA_TYPE_CDMA) && chan->has_sg)
+ if ((chan->xdev->dma_config->dmatype == XDMA_TYPE_CDMA) && chan->has_sg)
dma_ctrl_set(chan, XILINX_DMA_REG_DMACR,
XILINX_CDMA_CR_SGMODE);
@@ -789,7 +793,7 @@ static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
if (ret == DMA_COMPLETE || !txstate)
return ret;
- if (chan->xdev->dmatype == XDMA_TYPE_AXIDMA) {
+ if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
spin_lock_irqsave(&chan->lock, flags);
desc = list_last_entry(&chan->active_list,
@@ -1331,12 +1335,12 @@ static void append_desc_queue(struct xilinx_dma_chan *chan,
*/
tail_desc = list_last_entry(&chan->pending_list,
struct xilinx_dma_tx_descriptor, node);
- if (chan->xdev->dmatype == XDMA_TYPE_VDMA) {
+ if (chan->xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {
tail_segment = list_last_entry(&tail_desc->segments,
struct xilinx_vdma_tx_segment,
node);
tail_segment->hw.next_desc = (u32)desc->async_tx.phys;
- } else if (chan->xdev->dmatype == XDMA_TYPE_CDMA) {
+ } else if (chan->xdev->dma_config->dmatype == XDMA_TYPE_CDMA) {
cdma_tail_segment = list_last_entry(&tail_desc->segments,
struct xilinx_cdma_tx_segment,
node);
@@ -1356,8 +1360,8 @@ append:
list_add_tail(&desc->node, &chan->pending_list);
chan->desc_pendingcount++;
- if (chan->has_sg && (chan->xdev->dmatype == XDMA_TYPE_VDMA) &&
- unlikely(chan->desc_pendingcount > chan->num_frms)) {
+ if (chan->has_sg && (chan->xdev->dma_config->dmatype == XDMA_TYPE_VDMA)
+ && unlikely(chan->desc_pendingcount > chan->num_frms)) {
dev_dbg(chan->dev, "desc pendingcount is too high\n");
chan->desc_pendingcount = chan->num_frms;
}
@@ -1810,7 +1814,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
chan->id = 0;
chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
- if (xdev->dmatype == XDMA_TYPE_VDMA) {
+ if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {
chan->desc_offset = XILINX_VDMA_MM2S_DESC_OFFSET;
if (xdev->flush_on_fsync == XILINX_DMA_FLUSH_BOTH ||
@@ -1823,7 +1827,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
chan->id = 1;
chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET;
- if (xdev->dmatype == XDMA_TYPE_VDMA) {
+ if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {
chan->desc_offset = XILINX_VDMA_S2MM_DESC_OFFSET;
if (xdev->flush_on_fsync == XILINX_DMA_FLUSH_BOTH ||
@@ -1844,9 +1848,9 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
return err;
}
- if (xdev->dmatype == XDMA_TYPE_AXIDMA)
+ if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA)
chan->start_transfer = xilinx_dma_start_transfer;
- else if (xdev->dmatype == XDMA_TYPE_CDMA)
+ else if (xdev->dma_config->dmatype == XDMA_TYPE_CDMA)
chan->start_transfer = xilinx_cdma_start_transfer;
else
chan->start_transfer = xilinx_vdma_start_transfer;
@@ -1893,13 +1897,22 @@ static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
return dma_get_slave_channel(&xdev->chan[chan_id]->common);
}
+static const struct dma_config axidma_config = {
+ .dmatype = XDMA_TYPE_AXIDMA,
+};
+
+static const struct dma_config axicdma_config = {
+ .dmatype = XDMA_TYPE_CDMA,
+};
+
+static const struct dma_config axivdma_config = {
+ .dmatype = XDMA_TYPE_VDMA,
+};
+
static const struct of_device_id xilinx_dma_of_ids[] = {
- { .compatible = "xlnx,axi-dma-1.00.a",
- .data = (void *)XDMA_TYPE_AXIDMA },
- { .compatible = "xlnx,axi-cdma-1.00.a",
- .data = (void *)XDMA_TYPE_CDMA },
- { .compatible = "xlnx,axi-vdma-1.00.a",
- .data = (void *)XDMA_TYPE_VDMA },
+ { .compatible = "xlnx,axi-dma-1.00.a", .data = &axidma_config },
+ { .compatible = "xlnx,axi-cdma-1.00.a", .data = &axicdma_config },
+ { .compatible = "xlnx,axi-vdma-1.00.a", .data = &axivdma_config },
{}
};
MODULE_DEVICE_TABLE(of, xilinx_dma_of_ids);
@@ -1914,7 +1927,7 @@ static int xilinx_dma_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct xilinx_dma_device *xdev;
- struct device_node *child;
+ struct device_node *child, *np = pdev->dev.of_node;
struct resource *io;
u32 num_frames, addr_width;
int i, err;
@@ -1925,7 +1938,13 @@ static int xilinx_dma_probe(struct platform_device *pdev)
return -ENOMEM;
xdev->dev = &pdev->dev;
- xdev->dmatype = (enum xdma_ip_type)of_device_get_match_data(&pdev->dev);
+ if (np) {
+ const struct of_device_id *match;
+
+ match = of_match_node(xilinx_dma_of_ids, np);
+ if (match && match->data)
+ xdev->dma_config = match->data;
+ }
/* Request and map I/O memory */
io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1936,7 +1955,7 @@ static int xilinx_dma_probe(struct platform_device *pdev)
/* Retrieve the DMA engine properties from the device tree */
xdev->has_sg = of_property_read_bool(node, "xlnx,include-sg");
- if (xdev->dmatype == XDMA_TYPE_VDMA) {
+ if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {
err = of_property_read_u32(node, "xlnx,num-fstores",
&num_frames);
if (err < 0) {
@@ -1968,7 +1987,7 @@ static int xilinx_dma_probe(struct platform_device *pdev)
xdev->common.dev = &pdev->dev;
INIT_LIST_HEAD(&xdev->common.channels);
- if (!(xdev->dmatype == XDMA_TYPE_CDMA)) {
+ if (!(xdev->dma_config->dmatype == XDMA_TYPE_CDMA)) {
dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
}
@@ -1980,12 +1999,12 @@ static int xilinx_dma_probe(struct platform_device *pdev)
xdev->common.device_terminate_all = xilinx_dma_terminate_all;
xdev->common.device_tx_status = xilinx_dma_tx_status;
xdev->common.device_issue_pending = xilinx_dma_issue_pending;
- if (xdev->dmatype == XDMA_TYPE_AXIDMA) {
+ if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg;
/* Residue calculation is supported by only AXI DMA */
xdev->common.residue_granularity =
DMA_RESIDUE_GRANULARITY_SEGMENT;
- } else if (xdev->dmatype == XDMA_TYPE_CDMA) {
+ } else if (xdev->dma_config->dmatype == XDMA_TYPE_CDMA) {
dma_cap_set(DMA_MEMCPY, xdev->common.cap_mask);
xdev->common.device_prep_dma_memcpy = xilinx_cdma_prep_memcpy;
} else {
@@ -2002,7 +2021,7 @@ static int xilinx_dma_probe(struct platform_device *pdev)
goto error;
}
- if (xdev->dmatype == XDMA_TYPE_VDMA) {
+ if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {
for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
if (xdev->chan[i])
xdev->chan[i]->num_frms = num_frames;
--
2.1.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RESEND PATCH v4 2/3] Documentation: DT: vdma: Add clock support for dmas
[not found] ` <1463046228-21651-1-git-send-email-appanad-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
@ 2016-05-12 9:43 ` Kedareswara rao Appana
0 siblings, 0 replies; 6+ messages in thread
From: Kedareswara rao Appana @ 2016-05-12 9:43 UTC (permalink / raw)
To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, michal.simek-gjFFaj9aHVfQT0dZR+AlfA,
soren.brinkmann-gjFFaj9aHVfQT0dZR+AlfA,
vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
appanad-gjFFaj9aHVfQT0dZR+AlfA,
moritz.fischer-+aYTwkv1SeIAvxtiuMwx3w,
laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw,
luis-HiykPkW1eAzzDCI4PIEvbQC/G2K4zDHf,
svemula-gjFFaj9aHVfQT0dZR+AlfA, anirudh-gjFFaj9aHVfQT0dZR+AlfA
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
dmaengine-u79uwXL29TY76Z2rM5mHXA
This patch updates the binding doc with clock description
for AXI DMA's.
Acked-by: Sören Brinkmann <soren.brinkmann-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Kedareswara rao Appana <appanad-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
---
.../devicetree/bindings/dma/xilinx/xilinx_vdma.txt | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt b/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt
index fcc2b65..a1f2683 100644
--- a/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt
+++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt
@@ -21,6 +21,18 @@ Required properties:
- dma-channel child node: Should have at least one channel and can have up to
two channels per device. This node specifies the properties of each
DMA channel (see child node properties below).
+- clocks: Input clock specifier. Refer to common clock bindings.
+- clock-names: List of input clocks
+ For VDMA:
+ Required elements: "s_axi_lite_aclk"
+ Optional elements: "m_axi_mm2s_aclk" "m_axi_s2mm_aclk",
+ "m_axis_mm2s_aclk", "s_axis_s2mm_aclk"
+ For CDMA:
+ Required elements: "s_axi_lite_aclk", "m_axi_aclk"
+ FOR AXIDMA:
+ Required elements: "s_axi_lite_aclk"
+ Optional elements: "m_axi_mm2s_aclk", "m_axi_s2mm_aclk",
+ "m_axi_sg_aclk"
Required properties for VDMA:
- xlnx,num-fstores: Should be the number of framebuffers as configured in h/w.
@@ -60,6 +72,9 @@ axi_vdma_0: axivdma@40030000 {
xlnx,num-fstores = <0x8>;
xlnx,flush-fsync = <0x1>;
xlnx,addrwidth = <0x20>;
+ clocks = <&clk 0>, <&clk 1>, <&clk 2>, <&clk 3>, <&clk 4>;
+ clock-names = "s_axi_lite_aclk", "m_axi_mm2s_aclk", "m_axi_s2mm_aclk",
+ "m_axis_mm2s_aclk", "s_axis_s2mm_aclk";
dma-channel@40030000 {
compatible = "xlnx,axi-vdma-mm2s-channel";
interrupts = < 0 54 4 >;
--
2.1.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RESEND PATCH v4 3/3] dmaengine: vdma: Add clock support
2016-05-12 9:43 [RESEND PATCH v4 0/3] dmaengine: Add clock support for AXI DMAS Kedareswara rao Appana
2016-05-12 9:43 ` [RESEND PATCH v4 1/3] dmaengine: vdma: Add config structure to differentiate dmas Kedareswara rao Appana
[not found] ` <1463046228-21651-1-git-send-email-appanad-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
@ 2016-05-12 9:43 ` Kedareswara rao Appana
2 siblings, 0 replies; 6+ messages in thread
From: Kedareswara rao Appana @ 2016-05-12 9:43 UTC (permalink / raw)
To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
michal.simek, soren.brinkmann, vinod.koul, dan.j.williams,
appanad, moritz.fischer, laurent.pinchart, luis, svemula, anirudh
Cc: devicetree, linux-arm-kernel, linux-kernel, dmaengine
Added basic clock support for axi dma's.
The clocks are requested at probe and released at remove.
Reviewed-by: Shubhrajyoti Datta <shubhraj@xilinx.com>
Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
drivers/dma/xilinx/xilinx_vdma.c | 226 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 224 insertions(+), 2 deletions(-)
diff --git a/drivers/dma/xilinx/xilinx_vdma.c b/drivers/dma/xilinx/xilinx_vdma.c
index 1d50e05..31ae528 100644
--- a/drivers/dma/xilinx/xilinx_vdma.c
+++ b/drivers/dma/xilinx/xilinx_vdma.c
@@ -44,6 +44,7 @@
#include <linux/of_platform.h>
#include <linux/of_irq.h>
#include <linux/slab.h>
+#include <linux/clk.h>
#include "../dmaengine.h"
@@ -344,6 +345,9 @@ struct xilinx_dma_chan {
struct dma_config {
enum xdma_ip_type dmatype;
+ int (*clk_init)(struct platform_device *pdev, struct clk **axi_clk,
+ struct clk **tx_clk, struct clk **txs_clk,
+ struct clk **rx_clk, struct clk **rxs_clk);
};
/**
@@ -355,7 +359,13 @@ struct dma_config {
* @has_sg: Specifies whether Scatter-Gather is present or not
* @flush_on_fsync: Flush on frame sync
* @ext_addr: Indicates 64 bit addressing is supported by dma device
+ * @pdev: Platform device structure pointer
* @dma_config: DMA config structure
+ * @axi_clk: DMA Axi4-lite interace clock
+ * @tx_clk: DMA mm2s clock
+ * @txs_clk: DMA mm2s stream clock
+ * @rx_clk: DMA s2mm clock
+ * @rxs_clk: DMA s2mm stream clock
*/
struct xilinx_dma_device {
void __iomem *regs;
@@ -365,7 +375,13 @@ struct xilinx_dma_device {
bool has_sg;
u32 flush_on_fsync;
bool ext_addr;
+ struct platform_device *pdev;
const struct dma_config *dma_config;
+ struct clk *axi_clk;
+ struct clk *tx_clk;
+ struct clk *txs_clk;
+ struct clk *rx_clk;
+ struct clk *rxs_clk;
};
/* Macros */
@@ -1756,6 +1772,195 @@ static void xilinx_dma_chan_remove(struct xilinx_dma_chan *chan)
list_del(&chan->common.device_node);
}
+static int axidma_clk_init(struct platform_device *pdev, struct clk **axi_clk,
+ struct clk **tx_clk, struct clk **rx_clk,
+ struct clk **sg_clk, struct clk **tmp_clk)
+{
+ int err;
+
+ *tmp_clk = NULL;
+
+ *axi_clk = devm_clk_get(&pdev->dev, "s_axi_lite_aclk");
+ if (IS_ERR(*axi_clk)) {
+ err = PTR_ERR(*axi_clk);
+ dev_err(&pdev->dev, "failed to get axi_aclk (%u)\n", err);
+ return err;
+ }
+
+ *tx_clk = devm_clk_get(&pdev->dev, "m_axi_mm2s_aclk");
+ if (IS_ERR(*tx_clk))
+ *tx_clk = NULL;
+
+ *rx_clk = devm_clk_get(&pdev->dev, "m_axi_s2mm_aclk");
+ if (IS_ERR(*rx_clk))
+ *rx_clk = NULL;
+
+ *sg_clk = devm_clk_get(&pdev->dev, "m_axi_sg_aclk");
+ if (IS_ERR(*sg_clk))
+ *sg_clk = NULL;
+
+ err = clk_prepare_enable(*axi_clk);
+ if (err) {
+ dev_err(&pdev->dev, "failed to enable axi_clk (%u)\n", err);
+ return err;
+ }
+
+ err = clk_prepare_enable(*tx_clk);
+ if (err) {
+ dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n", err);
+ goto err_disable_axiclk;
+ }
+
+ err = clk_prepare_enable(*rx_clk);
+ if (err) {
+ dev_err(&pdev->dev, "failed to enable rx_clk (%u)\n", err);
+ goto err_disable_txclk;
+ }
+
+ err = clk_prepare_enable(*sg_clk);
+ if (err) {
+ dev_err(&pdev->dev, "failed to enable sg_clk (%u)\n", err);
+ goto err_disable_rxclk;
+ }
+
+ return 0;
+
+err_disable_rxclk:
+ clk_disable_unprepare(*rx_clk);
+err_disable_txclk:
+ clk_disable_unprepare(*tx_clk);
+err_disable_axiclk:
+ clk_disable_unprepare(*axi_clk);
+
+ return err;
+}
+
+static int axicdma_clk_init(struct platform_device *pdev, struct clk **axi_clk,
+ struct clk **dev_clk, struct clk **tmp_clk,
+ struct clk **tmp1_clk, struct clk **tmp2_clk)
+{
+ int err;
+
+ *tmp_clk = NULL;
+ *tmp1_clk = NULL;
+ *tmp2_clk = NULL;
+
+ *axi_clk = devm_clk_get(&pdev->dev, "s_axi_lite_aclk");
+ if (IS_ERR(*axi_clk)) {
+ err = PTR_ERR(*axi_clk);
+ dev_err(&pdev->dev, "failed to get axi_clk (%u)\n", err);
+ return err;
+ }
+
+ *dev_clk = devm_clk_get(&pdev->dev, "m_axi_aclk");
+ if (IS_ERR(*dev_clk)) {
+ err = PTR_ERR(*dev_clk);
+ dev_err(&pdev->dev, "failed to get dev_clk (%u)\n", err);
+ return err;
+ }
+
+ err = clk_prepare_enable(*axi_clk);
+ if (err) {
+ dev_err(&pdev->dev, "failed to enable axi_clk (%u)\n", err);
+ return err;
+ }
+
+ err = clk_prepare_enable(*dev_clk);
+ if (err) {
+ dev_err(&pdev->dev, "failed to enable dev_clk (%u)\n", err);
+ goto err_disable_axiclk;
+ }
+
+ return 0;
+
+err_disable_axiclk:
+ clk_disable_unprepare(*axi_clk);
+
+ return err;
+}
+
+static int axivdma_clk_init(struct platform_device *pdev, struct clk **axi_clk,
+ struct clk **tx_clk, struct clk **txs_clk,
+ struct clk **rx_clk, struct clk **rxs_clk)
+{
+ int err;
+
+ *axi_clk = devm_clk_get(&pdev->dev, "s_axi_lite_aclk");
+ if (IS_ERR(*axi_clk)) {
+ err = PTR_ERR(*axi_clk);
+ dev_err(&pdev->dev, "failed to get axi_aclk (%u)\n", err);
+ return err;
+ }
+
+ *tx_clk = devm_clk_get(&pdev->dev, "m_axi_mm2s_aclk");
+ if (IS_ERR(*tx_clk))
+ *tx_clk = NULL;
+
+ *txs_clk = devm_clk_get(&pdev->dev, "m_axis_mm2s_aclk");
+ if (IS_ERR(*txs_clk))
+ *txs_clk = NULL;
+
+ *rx_clk = devm_clk_get(&pdev->dev, "m_axi_s2mm_aclk");
+ if (IS_ERR(*rx_clk))
+ *rx_clk = NULL;
+
+ *rxs_clk = devm_clk_get(&pdev->dev, "s_axis_s2mm_aclk");
+ if (IS_ERR(*rxs_clk))
+ *rxs_clk = NULL;
+
+ err = clk_prepare_enable(*axi_clk);
+ if (err) {
+ dev_err(&pdev->dev, "failed to enable axi_clk (%u)\n", err);
+ return err;
+ }
+
+ err = clk_prepare_enable(*tx_clk);
+ if (err) {
+ dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n", err);
+ goto err_disable_axiclk;
+ }
+
+ err = clk_prepare_enable(*txs_clk);
+ if (err) {
+ dev_err(&pdev->dev, "failed to enable txs_clk (%u)\n", err);
+ goto err_disable_txclk;
+ }
+
+ err = clk_prepare_enable(*rx_clk);
+ if (err) {
+ dev_err(&pdev->dev, "failed to enable rx_clk (%u)\n", err);
+ goto err_disable_txsclk;
+ }
+
+ err = clk_prepare_enable(*rxs_clk);
+ if (err) {
+ dev_err(&pdev->dev, "failed to enable rxs_clk (%u)\n", err);
+ goto err_disable_rxclk;
+ }
+
+ return 0;
+
+err_disable_rxclk:
+ clk_disable_unprepare(*rx_clk);
+err_disable_txsclk:
+ clk_disable_unprepare(*txs_clk);
+err_disable_txclk:
+ clk_disable_unprepare(*tx_clk);
+err_disable_axiclk:
+ clk_disable_unprepare(*axi_clk);
+
+ return err;
+}
+
+static void xdma_disable_allclks(struct xilinx_dma_device *xdev)
+{
+ clk_disable_unprepare(xdev->rxs_clk);
+ clk_disable_unprepare(xdev->rx_clk);
+ clk_disable_unprepare(xdev->txs_clk);
+ clk_disable_unprepare(xdev->tx_clk);
+ clk_disable_unprepare(xdev->axi_clk);
+}
+
/**
* xilinx_dma_chan_probe - Per Channel Probing
* It get channel features from the device tree entry and
@@ -1899,14 +2104,17 @@ static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
static const struct dma_config axidma_config = {
.dmatype = XDMA_TYPE_AXIDMA,
+ .clk_init = axidma_clk_init,
};
static const struct dma_config axicdma_config = {
.dmatype = XDMA_TYPE_CDMA,
+ .clk_init = axicdma_clk_init,
};
static const struct dma_config axivdma_config = {
.dmatype = XDMA_TYPE_VDMA,
+ .clk_init = axivdma_clk_init,
};
static const struct of_device_id xilinx_dma_of_ids[] = {
@@ -1925,6 +2133,9 @@ MODULE_DEVICE_TABLE(of, xilinx_dma_of_ids);
*/
static int xilinx_dma_probe(struct platform_device *pdev)
{
+ int (*clk_init)(struct platform_device *, struct clk **, struct clk **,
+ struct clk **, struct clk **, struct clk **)
+ = axivdma_clk_init;
struct device_node *node = pdev->dev.of_node;
struct xilinx_dma_device *xdev;
struct device_node *child, *np = pdev->dev.of_node;
@@ -1942,10 +2153,17 @@ static int xilinx_dma_probe(struct platform_device *pdev)
const struct of_device_id *match;
match = of_match_node(xilinx_dma_of_ids, np);
- if (match && match->data)
+ if (match && match->data) {
xdev->dma_config = match->data;
+ clk_init = xdev->dma_config->clk_init;
+ }
}
+ err = clk_init(pdev, &xdev->axi_clk, &xdev->tx_clk, &xdev->txs_clk,
+ &xdev->rx_clk, &xdev->rxs_clk);
+ if (err)
+ return err;
+
/* Request and map I/O memory */
io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
xdev->regs = devm_ioremap_resource(&pdev->dev, io);
@@ -2018,7 +2236,7 @@ static int xilinx_dma_probe(struct platform_device *pdev)
for_each_child_of_node(node, child) {
err = xilinx_dma_chan_probe(xdev, child);
if (err < 0)
- goto error;
+ goto disable_clks;
}
if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {
@@ -2042,6 +2260,8 @@ static int xilinx_dma_probe(struct platform_device *pdev)
return 0;
+disable_clks:
+ xdma_disable_allclks(xdev);
error:
for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
if (xdev->chan[i])
@@ -2069,6 +2289,8 @@ static int xilinx_dma_remove(struct platform_device *pdev)
if (xdev->chan[i])
xilinx_dma_chan_remove(xdev->chan[i]);
+ xdma_disable_allclks(xdev);
+
return 0;
}
--
2.1.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* RE: [RESEND PATCH v4 1/3] dmaengine: vdma: Add config structure to differentiate dmas
2016-05-12 16:09 ` Vinod Koul
@ 2016-05-12 16:09 ` Appana Durga Kedareswara Rao
0 siblings, 0 replies; 6+ messages in thread
From: Appana Durga Kedareswara Rao @ 2016-05-12 16:09 UTC (permalink / raw)
To: Vinod Koul
Cc: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com,
ijc+devicetree@hellion.org.uk, galak@codeaurora.org, Michal Simek,
Soren Brinkmann, dan.j.williams@intel.com,
moritz.fischer@ettus.com, laurent.pinchart@ideasonboard.com,
luis@debethencourt.com, Srikanth Vemula, Anirudha Sarangi,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org
Hi Vinod,
> On Thu, May 12, 2016 at 03:13:46PM +0530, Kedareswara rao Appana wrote:
> > This patch adds config structure in the driver to differentiate AXI
> > DMA's and to add more features(clock support etc..) to these DMA's.
> >
> > Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
> > ---
> > drivers/dma/xilinx/xilinx_vdma.c | 83
> > ++++++++++++++++++++++++----------------
> > 1 file changed, 51 insertions(+), 32 deletions(-)
> >
> > diff --git a/drivers/dma/xilinx/xilinx_vdma.c
> > b/drivers/dma/xilinx/xilinx_vdma.c
> > index 626939b..1d50e05 100644
> > --- a/drivers/dma/xilinx/xilinx_vdma.c
> > +++ b/drivers/dma/xilinx/xilinx_vdma.c
> > @@ -342,6 +342,10 @@ struct xilinx_dma_chan {
> > void (*start_transfer)(struct xilinx_dma_chan *chan); };
> >
> > +struct dma_config {
>
> xilinx_dma_config ?
Ok will fix in the next version...
>
> This makes reader believe that thismight be coething related to dmaengine core
>
> > static const struct of_device_id xilinx_dma_of_ids[] = {
> > - { .compatible = "xlnx,axi-dma-1.00.a",
> > - .data = (void *)XDMA_TYPE_AXIDMA },
> > - { .compatible = "xlnx,axi-cdma-1.00.a",
> > - .data = (void *)XDMA_TYPE_CDMA },
> > - { .compatible = "xlnx,axi-vdma-1.00.a",
> > - .data = (void *)XDMA_TYPE_VDMA },
> > + { .compatible = "xlnx,axi-dma-1.00.a", .data = &axidma_config },
> > + { .compatible = "xlnx,axi-cdma-1.00.a", .data = &axicdma_config },
> > + { .compatible = "xlnx,axi-vdma-1.00.a", .data = &axivdma_config },
>
> why do we want a struct for this and not pass XDMA_TYPE_xxx as .data
In the next patch of this series added clock configuration in the config structure.
As the number clocks for each of the IP varies and the clocks are configurable
That's why added a separate config struct instead of XDMA_TYPE...
Regards,
Kedar.
>
> --
> ~Vinod
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RESEND PATCH v4 1/3] dmaengine: vdma: Add config structure to differentiate dmas
2016-05-12 9:43 ` [RESEND PATCH v4 1/3] dmaengine: vdma: Add config structure to differentiate dmas Kedareswara rao Appana
@ 2016-05-12 16:09 ` Vinod Koul
2016-05-12 16:09 ` Appana Durga Kedareswara Rao
0 siblings, 1 reply; 6+ messages in thread
From: Vinod Koul @ 2016-05-12 16:09 UTC (permalink / raw)
To: Kedareswara rao Appana
Cc: mark.rutland, moritz.fischer, anirudh, pawel.moll, ijc+devicetree,
svemula, michal.simek, linux-kernel, devicetree, robh+dt,
laurent.pinchart, luis, galak, dmaengine, dan.j.williams, appanad,
soren.brinkmann, linux-arm-kernel
On Thu, May 12, 2016 at 03:13:46PM +0530, Kedareswara rao Appana wrote:
> This patch adds config structure in the driver to differentiate
> AXI DMA's and to add more features(clock support etc..) to these DMA's.
>
> Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
> ---
> drivers/dma/xilinx/xilinx_vdma.c | 83 ++++++++++++++++++++++++----------------
> 1 file changed, 51 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/dma/xilinx/xilinx_vdma.c b/drivers/dma/xilinx/xilinx_vdma.c
> index 626939b..1d50e05 100644
> --- a/drivers/dma/xilinx/xilinx_vdma.c
> +++ b/drivers/dma/xilinx/xilinx_vdma.c
> @@ -342,6 +342,10 @@ struct xilinx_dma_chan {
> void (*start_transfer)(struct xilinx_dma_chan *chan);
> };
>
> +struct dma_config {
xilinx_dma_config ?
This makes reader believe that thismight be coething related to dmaengine
core
> static const struct of_device_id xilinx_dma_of_ids[] = {
> - { .compatible = "xlnx,axi-dma-1.00.a",
> - .data = (void *)XDMA_TYPE_AXIDMA },
> - { .compatible = "xlnx,axi-cdma-1.00.a",
> - .data = (void *)XDMA_TYPE_CDMA },
> - { .compatible = "xlnx,axi-vdma-1.00.a",
> - .data = (void *)XDMA_TYPE_VDMA },
> + { .compatible = "xlnx,axi-dma-1.00.a", .data = &axidma_config },
> + { .compatible = "xlnx,axi-cdma-1.00.a", .data = &axicdma_config },
> + { .compatible = "xlnx,axi-vdma-1.00.a", .data = &axivdma_config },
why do we want a struct for this and not pass XDMA_TYPE_xxx as .data
--
~Vinod
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-05-12 16:09 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-12 9:43 [RESEND PATCH v4 0/3] dmaengine: Add clock support for AXI DMAS Kedareswara rao Appana
2016-05-12 9:43 ` [RESEND PATCH v4 1/3] dmaengine: vdma: Add config structure to differentiate dmas Kedareswara rao Appana
2016-05-12 16:09 ` Vinod Koul
2016-05-12 16:09 ` Appana Durga Kedareswara Rao
[not found] ` <1463046228-21651-1-git-send-email-appanad-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
2016-05-12 9:43 ` [RESEND PATCH v4 2/3] Documentation: DT: vdma: Add clock support for dmas Kedareswara rao Appana
2016-05-12 9:43 ` [RESEND PATCH v4 3/3] dmaengine: vdma: Add clock support Kedareswara rao Appana
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).