All of lore.kernel.org
 help / color / mirror / Atom feed
* Driver for tango DMA engine
@ 2016-11-23 16:48 Marc Gonzalez
  2016-11-23 16:49 ` [PATCH 1/6] dmaengine: Import tango MBUS driver Marc Gonzalez
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Marc Gonzalez @ 2016-11-23 16:48 UTC (permalink / raw)
  To: Mans Rullgard, Vinod Koul
  Cc: dmaengine, LKML, Sebastian Frias, Mason, Thibaud Cornic

Hello Mans,

I would like to push upstream the driver you wrote for the tango
DMA engine. Could you take a look at my fixes, perhaps some/all
can be squashed into the initial patch?

Vinod, can you take a look at this submission, and tell me if
you spot any issue?

Regards.


Mans Rullgard (1):
  dmaengine: Import tango MBUS driver

Marc Gonzalez (5):
  Provide names for SBOX register offsets
  Fixup for tango4 support
  Fixup tangox_dma_sbox_map
  Fixup tangox_dma_reset
  Relax write accesses

 drivers/dma/Kconfig     |   6 +
 drivers/dma/Makefile    |   1 +
 drivers/dma/tango-dma.c | 582 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 589 insertions(+)
 create mode 100644 drivers/dma/tango-dma.c

-- 
2.9.0

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/6] dmaengine: Import tango MBUS driver
  2016-11-23 16:48 Driver for tango DMA engine Marc Gonzalez
@ 2016-11-23 16:49 ` Marc Gonzalez
  2016-11-23 16:50 ` [PATCH 2/6] Provide names for SBOX register offsets Marc Gonzalez
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marc Gonzalez @ 2016-11-23 16:49 UTC (permalink / raw)
  To: Mans Rullgard, Vinod Koul
  Cc: dmaengine, LKML, Sebastian Frias, Mason, Thibaud Cornic

From: Mans Rullgard <mans@mansr.com>

https://github.com/mansr/linux-tangox/blob/master/drivers/dma/tangox-dma.c
---
 drivers/dma/Kconfig     |   6 +
 drivers/dma/Makefile    |   1 +
 drivers/dma/tango-dma.c | 583 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 590 insertions(+)
 create mode 100644 drivers/dma/tango-dma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index af63a6bcf564..1382cf31b68e 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -466,6 +466,12 @@ config TXX9_DMAC
 	  Support the TXx9 SoC internal DMA controller.  This can be
 	  integrated in chips such as the Toshiba TX4927/38/39.
 
+config TANGO_DMA
+	tristate "Sigma Designs SMP86xx DMA support"
+	depends on ARCH_TANGO
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+
 config TEGRA20_APB_DMA
 	bool "NVIDIA Tegra20 APB DMA support"
 	depends on ARCH_TEGRA
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index e4dc9cac7ee8..5f14c5b71a72 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
 obj-$(CONFIG_STM32_DMA) += stm32-dma.o
 obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o
 obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
+obj-$(CONFIG_TANGO_DMA) += tango-dma.o
 obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
 obj-$(CONFIG_TEGRA210_ADMA) += tegra210-adma.o
 obj-$(CONFIG_TIMB_DMA) += timb_dma.o
diff --git a/drivers/dma/tango-dma.c b/drivers/dma/tango-dma.c
new file mode 100644
index 000000000000..53f6c7f61599
--- /dev/null
+++ b/drivers/dma/tango-dma.c
@@ -0,0 +1,583 @@
+/*
+ * Copyright (C) 2014 Mans Rullgard <mans@mansr.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/dmaengine.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of_address.h>
+#include <linux/of_dma.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+
+#include "virt-dma.h"
+
+#define TANGOX_DMA_MAX_LEN 0x1fff
+
+#define TANGOX_DMA_MAX_CHANS 6
+#define TANGOX_DMA_MAX_PCHANS 6
+
+#define DMA_ADDR	0
+#define DMA_COUNT	4
+#define DMA_ADDR2	8
+#define DMA_STRIDE	DMA_ADDR2
+#define DMA_CMD		12
+
+#define DMA_MODE_SINGLE	1
+#define DMA_MODE_DOUBLE	2
+#define DMA_MODE_RECT	3
+
+struct tangox_dma_sg {
+	dma_addr_t addr;
+	unsigned int len;
+};
+
+struct tangox_dma_desc {
+	struct virt_dma_desc vd;
+	enum dma_transfer_direction direction;
+	unsigned int num_sgs;
+	struct tangox_dma_sg sg[];
+};
+
+struct tangox_dma_chan {
+	struct virt_dma_chan vc;
+	u32 id;
+};
+
+struct tangox_dma_pchan {
+	struct tangox_dma_device *dev;
+	enum dma_transfer_direction direction;
+	u32 sbox_id;
+	int slave_id;
+	void __iomem *base;
+	spinlock_t lock;
+	struct tangox_dma_desc *desc;
+	unsigned int next_sg;
+	unsigned long issued_len;
+};
+
+struct tangox_dma_device {
+	struct dma_device ddev;
+	void __iomem *sbox_base;
+	spinlock_t lock;
+	struct list_head desc_memtodev;
+	struct list_head desc_devtomem;
+	int nr_pchans;
+	struct tangox_dma_pchan pchan[TANGOX_DMA_MAX_PCHANS];
+	struct tangox_dma_chan chan[TANGOX_DMA_MAX_CHANS];
+};
+
+static inline struct tangox_dma_device *to_tangox_dma_device(
+	struct dma_device *ddev)
+{
+	return container_of(ddev, struct tangox_dma_device, ddev);
+}
+
+static inline struct tangox_dma_chan *to_tangox_dma_chan(struct dma_chan *c)
+{
+	return container_of(c, struct tangox_dma_chan, vc.chan);
+}
+
+static inline struct tangox_dma_desc *to_tangox_dma_desc(
+	struct virt_dma_desc *vdesc)
+{
+	return container_of(vdesc, struct tangox_dma_desc, vd);
+}
+
+static struct tangox_dma_desc *tangox_dma_alloc_desc(unsigned int num_sgs)
+{
+	return kzalloc(sizeof(struct tangox_dma_desc) +
+		sizeof(struct tangox_dma_sg) * num_sgs, GFP_ATOMIC);
+}
+
+static void tangox_dma_sbox_map(struct tangox_dma_device *dev, int src, int dst)
+{
+	void __iomem *addr = dev->sbox_base + 8;
+	int shift = (dst - 1) * 4;
+
+	if (shift > 31) {
+		addr += 4;
+		shift -= 32;
+	}
+
+	writel(src << shift, addr);
+	wmb();
+}
+
+static void tangox_dma_pchan_setup(struct tangox_dma_pchan *pchan,
+				   struct tangox_dma_desc *desc)
+{
+	struct tangox_dma_chan *chan = to_tangox_dma_chan(desc->vd.tx.chan);
+	struct tangox_dma_device *dev = pchan->dev;
+
+	BUG_ON(desc->direction != pchan->direction);
+
+	if (pchan->direction == DMA_DEV_TO_MEM)
+		tangox_dma_sbox_map(dev, chan->id, pchan->sbox_id);
+	else
+		tangox_dma_sbox_map(dev, pchan->sbox_id, chan->id);
+
+	pchan->slave_id = chan->id;
+}
+
+static void tangox_dma_pchan_detach(struct tangox_dma_pchan *pchan)
+{
+	struct tangox_dma_device *dev = pchan->dev;
+
+	BUG_ON(pchan->slave_id < 0);
+
+	if (pchan->direction == DMA_DEV_TO_MEM)
+		tangox_dma_sbox_map(dev, 0xf, pchan->sbox_id);
+	else
+		tangox_dma_sbox_map(dev, 0xf, pchan->slave_id);
+
+	pchan->slave_id = -1;
+}
+
+static int tangox_dma_issue_single(struct tangox_dma_pchan *pchan,
+				   struct tangox_dma_sg *sg, int flags)
+{
+	writel(sg->addr, pchan->base + DMA_ADDR);
+	writel(sg->len, pchan->base + DMA_COUNT);
+	wmb();
+	writel(flags << 2 | DMA_MODE_SINGLE, pchan->base + DMA_CMD);
+	wmb();
+
+	return sg->len;
+}
+
+static int tangox_dma_issue_double(struct tangox_dma_pchan *pchan,
+				   struct tangox_dma_sg *sg, int flags)
+{
+	unsigned int len1 = sg->len - TANGOX_DMA_MAX_LEN;
+
+	writel(sg->addr, pchan->base + DMA_ADDR);
+	writel(sg->addr + TANGOX_DMA_MAX_LEN, pchan->base + DMA_ADDR2);
+	writel(TANGOX_DMA_MAX_LEN | len1 << 16, pchan->base + DMA_COUNT);
+	wmb();
+	writel(flags << 2 | DMA_MODE_DOUBLE, pchan->base + DMA_CMD);
+	wmb();
+
+	return sg->len;
+}
+
+static int tangox_dma_issue_rect(struct tangox_dma_pchan *pchan,
+				 struct tangox_dma_sg *sg, int flags)
+{
+	int shift = min(__ffs(sg->len), 12ul);
+	int count = sg->len >> shift;
+	int width = 1 << shift;
+
+	if (count > TANGOX_DMA_MAX_LEN) {
+		count = TANGOX_DMA_MAX_LEN;
+		flags &= ~1;
+	}
+
+	writel(sg->addr, pchan->base + DMA_ADDR);
+	writel(width, pchan->base + DMA_STRIDE);
+	writel(width | count << 16, pchan->base + DMA_COUNT);
+	wmb();
+	writel(flags << 2 | DMA_MODE_RECT, pchan->base + DMA_CMD);
+	wmb();
+
+	return count << shift;
+}
+
+static int tangox_dma_pchan_issue(struct tangox_dma_pchan *pchan,
+				  struct tangox_dma_sg *sg)
+{
+	int flags;
+
+	if (pchan->next_sg == pchan->desc->num_sgs - 1)
+		flags = 1;
+	else
+		flags = 0;
+
+	if (sg->len <= TANGOX_DMA_MAX_LEN)
+		return tangox_dma_issue_single(pchan, sg, flags);
+
+	if (sg->len <= TANGOX_DMA_MAX_LEN * 2)
+		return tangox_dma_issue_double(pchan, sg, flags);
+
+	return tangox_dma_issue_rect(pchan, sg, flags);
+}
+
+static struct tangox_dma_desc *tangox_dma_next_desc(
+	struct tangox_dma_device *dev, enum dma_transfer_direction dir)
+{
+	struct tangox_dma_desc *desc;
+	struct list_head *list;
+	unsigned long flags;
+
+	if (dir == DMA_MEM_TO_DEV)
+		list = &dev->desc_memtodev;
+	else
+		list = &dev->desc_devtomem;
+
+	spin_lock_irqsave(&dev->lock, flags);
+
+	desc = list_first_entry_or_null(list, struct tangox_dma_desc, vd.node);
+	if (desc)
+		list_del(&desc->vd.node);
+
+	spin_unlock_irqrestore(&dev->lock, flags);
+
+	return desc;
+}
+
+static int tangox_dma_pchan_start(struct tangox_dma_pchan *pchan)
+{
+	struct tangox_dma_device *dev = pchan->dev;
+	struct tangox_dma_sg *sg;
+	int len;
+
+	if (!pchan->desc) {
+		pchan->desc = tangox_dma_next_desc(dev, pchan->direction);
+
+		if (!pchan->desc) {
+			tangox_dma_pchan_detach(pchan);
+			return 0;
+		}
+
+		pchan->next_sg = 0;
+		tangox_dma_pchan_setup(pchan, pchan->desc);
+	}
+
+	sg = &pchan->desc->sg[pchan->next_sg];
+
+	len = tangox_dma_pchan_issue(pchan, sg);
+
+	sg->addr += len;
+	sg->len  -= len;
+
+	if (!sg->len)
+		pchan->next_sg++;
+
+	pchan->issued_len = len;
+
+	return 0;
+}
+
+static void tangox_dma_queue_desc(struct tangox_dma_device *dev,
+				  struct tangox_dma_desc *desc)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->lock, flags);
+	if (desc->direction == DMA_MEM_TO_DEV)
+		list_add_tail(&desc->vd.node, &dev->desc_memtodev);
+	else
+		list_add_tail(&desc->vd.node, &dev->desc_devtomem);
+	spin_unlock_irqrestore(&dev->lock, flags);
+}
+
+static irqreturn_t tangox_dma_irq(int irq, void *irq_data)
+{
+	struct tangox_dma_pchan *pchan = irq_data;
+	struct tangox_dma_chan *chan;
+	struct tangox_dma_desc *desc;
+	struct virt_dma_desc *vdesc;
+
+	spin_lock(&pchan->lock);
+
+	if (pchan->desc) {
+		desc = pchan->desc;
+		chan = to_tangox_dma_chan(desc->vd.tx.chan);
+		this_cpu_ptr(chan->vc.chan.local)->bytes_transferred +=
+			pchan->issued_len;
+		if (pchan->next_sg == desc->num_sgs) {
+			spin_lock(&chan->vc.lock);
+			vchan_cookie_complete(&desc->vd);
+			vdesc = vchan_next_desc(&chan->vc);
+			if (vdesc) {
+				list_del(&vdesc->node);
+				desc = to_tangox_dma_desc(vdesc);
+				tangox_dma_queue_desc(pchan->dev, desc);
+			}
+			spin_unlock(&chan->vc.lock);
+			pchan->desc = NULL;
+		}
+	}
+
+	tangox_dma_pchan_start(pchan);
+
+	spin_unlock(&pchan->lock);
+
+	return IRQ_HANDLED;
+}
+
+static void tangox_dma_start(struct tangox_dma_device *dev,
+			     enum dma_transfer_direction dir)
+{
+	struct tangox_dma_pchan *pchan = NULL;
+	unsigned long flags;
+	int i;
+
+	for (i = 0; i < dev->nr_pchans; i++) {
+		pchan = &dev->pchan[i];
+		if (pchan->direction == dir && !pchan->desc)
+			break;
+	}
+
+	if (i == dev->nr_pchans)
+		return;
+
+	spin_lock_irqsave(&pchan->lock, flags);
+	if (!pchan->desc)
+		tangox_dma_pchan_start(pchan);
+	spin_unlock_irqrestore(&pchan->lock, flags);
+}
+
+static void tangox_dma_issue_pending(struct dma_chan *c)
+{
+	struct tangox_dma_device *dev = to_tangox_dma_device(c->device);
+	struct tangox_dma_chan *chan = to_tangox_dma_chan(c);
+	struct tangox_dma_desc *desc = NULL;
+	struct virt_dma_desc *vdesc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->vc.lock, flags);
+	if (vchan_issue_pending(&chan->vc)) {
+		vdesc = vchan_next_desc(&chan->vc);
+		list_del(&vdesc->node);
+		desc = to_tangox_dma_desc(vdesc);
+	}
+	spin_unlock_irqrestore(&chan->vc.lock, flags);
+
+	if (desc) {
+		tangox_dma_queue_desc(dev, desc);
+		tangox_dma_start(dev, desc->direction);
+	}
+}
+
+static struct dma_async_tx_descriptor *tangox_dma_prep_slave_sg(
+	struct dma_chan *c, struct scatterlist *sgl, unsigned int sg_len,
+	enum dma_transfer_direction direction,
+	unsigned long flags, void *context)
+{
+	struct tangox_dma_chan *chan = to_tangox_dma_chan(c);
+	struct tangox_dma_desc *desc;
+	struct scatterlist *sg;
+	unsigned int i;
+
+	desc = tangox_dma_alloc_desc(sg_len);
+	if (!desc)
+		return NULL;
+
+	for_each_sg(sgl, sg, sg_len, i) {
+		desc->sg[i].addr = sg_dma_address(sg);
+		desc->sg[i].len = sg_dma_len(sg);
+	}
+
+	desc->num_sgs = sg_len;
+	desc->direction = direction;
+
+	return vchan_tx_prep(&chan->vc, &desc->vd, flags);
+}
+
+static enum dma_status tangox_dma_tx_status(struct dma_chan *c,
+	dma_cookie_t cookie, struct dma_tx_state *state)
+{
+	return dma_cookie_status(c, cookie, state);
+}
+
+static int tangox_dma_alloc_chan_resources(struct dma_chan *c)
+{
+	return 0;
+}
+
+static void tangox_dma_free_chan_resources(struct dma_chan *c)
+{
+	vchan_free_chan_resources(to_virt_chan(c));
+}
+
+static void tangox_dma_desc_free(struct virt_dma_desc *vd)
+{
+	kfree(container_of(vd, struct tangox_dma_desc, vd));
+}
+
+static void tangox_dma_reset(struct tangox_dma_device *dev)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		writel(0xffffffff, dev->sbox_base);
+		writel(0xff00ff00, dev->sbox_base);
+		writel(0xffffffff, dev->sbox_base + 4);
+		writel(0xff00ff00, dev->sbox_base + 4);
+		udelay(2);
+	}
+
+	writel(0xffffffff, dev->sbox_base + 8);
+	writel(0xffffffff, dev->sbox_base + 12);
+}
+
+static struct dma_chan *tangox_dma_xlate(struct of_phandle_args *dma_spec,
+					 struct of_dma *ofdma)
+{
+	struct dma_device *dev = ofdma->of_dma_data;
+	struct tangox_dma_chan *chan;
+	struct dma_chan *c;
+
+	if (!dev || dma_spec->args_count != 1)
+		return NULL;
+
+	list_for_each_entry(c, &dev->channels, device_node) {
+		chan = to_tangox_dma_chan(c);
+		if (chan->id == dma_spec->args[0])
+			return dma_get_slave_channel(c);
+	}
+
+	return NULL;
+}
+
+static int tangox_dma_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *cnode;
+	struct tangox_dma_device *dmadev;
+	struct tangox_dma_pchan *pchan;
+	struct tangox_dma_chan *chan;
+	struct dma_device *dd;
+	struct resource *res;
+	struct resource cres;
+	int irq;
+	int err;
+	int i;
+
+	dmadev = devm_kzalloc(&pdev->dev, sizeof(*dmadev), GFP_KERNEL);
+	if (!dmadev)
+		return -ENOMEM;
+
+	dd = &dmadev->ddev;
+
+	dma_cap_set(DMA_SLAVE, dd->cap_mask);
+
+	dd->dev = &pdev->dev;
+
+	dd->directions = 1 << DMA_MEM_TO_DEV | 1 << DMA_DEV_TO_MEM;
+	dd->device_alloc_chan_resources = tangox_dma_alloc_chan_resources;
+	dd->device_free_chan_resources = tangox_dma_free_chan_resources;
+	dd->device_prep_slave_sg = tangox_dma_prep_slave_sg;
+	dd->device_tx_status = tangox_dma_tx_status;
+	dd->device_issue_pending = tangox_dma_issue_pending;
+
+	INIT_LIST_HEAD(&dd->channels);
+
+	for (i = 0; i < TANGOX_DMA_MAX_CHANS; i++) {
+		chan = &dmadev->chan[i];
+
+		if (of_property_read_u32_index(node, "sigma,slave-ids", i,
+					       &chan->id))
+			break;
+
+		chan->vc.desc_free = tangox_dma_desc_free;
+		vchan_init(&chan->vc, dd);
+	}
+
+	dd->chancnt = i;
+
+	spin_lock_init(&dmadev->lock);
+	INIT_LIST_HEAD(&dmadev->desc_memtodev);
+	INIT_LIST_HEAD(&dmadev->desc_devtomem);
+
+	for_each_child_of_node(node, cnode) {
+		pchan = &dmadev->pchan[dmadev->nr_pchans];
+		pchan->dev = dmadev;
+		spin_lock_init(&pchan->lock);
+
+		if (of_property_read_bool(cnode, "sigma,mem-to-dev"))
+			pchan->direction = DMA_MEM_TO_DEV;
+		else
+			pchan->direction = DMA_DEV_TO_MEM;
+
+		of_property_read_u32(cnode, "sigma,sbox-id", &pchan->sbox_id);
+
+		err = of_address_to_resource(cnode, 0, &cres);
+		if (err)
+			return err;
+
+		pchan->base = devm_ioremap_resource(&pdev->dev, &cres);
+		if (IS_ERR(pchan->base))
+			return PTR_ERR(pchan->base);
+
+		irq = irq_of_parse_and_map(cnode, 0);
+		if (!irq)
+			return -EINVAL;
+
+		err = devm_request_irq(&pdev->dev, irq, tangox_dma_irq, 0,
+				       dev_name(&pdev->dev), pchan);
+		if (err)
+			return err;
+
+		if (++dmadev->nr_pchans == TANGOX_DMA_MAX_PCHANS)
+			break;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -EINVAL;
+
+	dmadev->sbox_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dmadev->sbox_base))
+		return PTR_ERR(dmadev->sbox_base);
+
+	tangox_dma_reset(dmadev);
+
+	err = dma_async_device_register(dd);
+	if (err)
+		return err;
+
+	err = of_dma_controller_register(node, tangox_dma_xlate, dd);
+	if (err) {
+		dma_async_device_unregister(dd);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, dmadev);
+
+	dev_info(&pdev->dev, "SMP86xx DMA with %d channels, %d slaves\n",
+		 dmadev->nr_pchans, dd->chancnt);
+
+	return 0;
+}
+
+static int tangox_dma_remove(struct platform_device *pdev)
+{
+	struct tangox_dma_device *dmadev = platform_get_drvdata(pdev);
+
+	of_dma_controller_free(pdev->dev.of_node);
+	dma_async_device_unregister(&dmadev->ddev);
+
+	return 0;
+}
+
+static struct of_device_id tangox_dma_dt_ids[] = {
+	{ .compatible = "sigma,smp8640-dma" },
+	{ }
+};
+
+static struct platform_driver tangox_dma_driver = {
+	.probe	= tangox_dma_probe,
+	.remove	= tangox_dma_remove,
+	.driver	= {
+		.name		= "tangox-dma",
+		.of_match_table	= tangox_dma_dt_ids,
+	},
+};
+module_platform_driver(tangox_dma_driver);
+
+MODULE_AUTHOR("Mans Rullgard <mans@mansr.com>");
+MODULE_DESCRIPTION("SMP86xx DMA driver");
+MODULE_LICENSE("GPL");
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/6] Provide names for SBOX register offsets
  2016-11-23 16:48 Driver for tango DMA engine Marc Gonzalez
  2016-11-23 16:49 ` [PATCH 1/6] dmaengine: Import tango MBUS driver Marc Gonzalez
@ 2016-11-23 16:50 ` Marc Gonzalez
  2016-11-23 16:51 ` [PATCH 3/6] Fixup for tango4 support Marc Gonzalez
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marc Gonzalez @ 2016-11-23 16:50 UTC (permalink / raw)
  To: Mans Rullgard, Vinod Koul
  Cc: dmaengine, LKML, Sebastian Frias, Mason, Thibaud Cornic

---
 drivers/dma/tango-dma.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/dma/tango-dma.c b/drivers/dma/tango-dma.c
index 53f6c7f61599..494b046d1d3d 100644
--- a/drivers/dma/tango-dma.c
+++ b/drivers/dma/tango-dma.c
@@ -38,6 +38,11 @@
 #define DMA_MODE_DOUBLE	2
 #define DMA_MODE_RECT	3
 
+#define SBOX_RESET	0
+#define SBOX_RESET2	4
+#define SBOX_ROUTE	8
+#define SBOX_ROUTE2	12
+
 struct tangox_dma_sg {
 	dma_addr_t addr;
 	unsigned int len;
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/6] Fixup for tango4 support
  2016-11-23 16:48 Driver for tango DMA engine Marc Gonzalez
  2016-11-23 16:49 ` [PATCH 1/6] dmaengine: Import tango MBUS driver Marc Gonzalez
  2016-11-23 16:50 ` [PATCH 2/6] Provide names for SBOX register offsets Marc Gonzalez
@ 2016-11-23 16:51 ` Marc Gonzalez
  2016-11-23 16:51 ` [PATCH 4/6] Fixup tangox_dma_sbox_map Marc Gonzalez
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marc Gonzalez @ 2016-11-23 16:51 UTC (permalink / raw)
  To: Mans Rullgard, Vinod Koul
  Cc: dmaengine, LKML, Sebastian Frias, Mason, Thibaud Cornic

---
 drivers/dma/tango-dma.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/tango-dma.c b/drivers/dma/tango-dma.c
index 494b046d1d3d..6a32d234ffb0 100644
--- a/drivers/dma/tango-dma.c
+++ b/drivers/dma/tango-dma.c
@@ -156,7 +156,7 @@ static int tangox_dma_issue_single(struct tangox_dma_pchan *pchan,
 	writel(sg->addr, pchan->base + DMA_ADDR);
 	writel(sg->len, pchan->base + DMA_COUNT);
 	wmb();
-	writel(flags << 2 | DMA_MODE_SINGLE, pchan->base + DMA_CMD);
+	writel(DMA_MODE_SINGLE << 1 | flags, pchan->base + DMA_CMD);
 	wmb();
 
 	return sg->len;
@@ -569,7 +569,7 @@ static int tangox_dma_remove(struct platform_device *pdev)
 }
 
 static struct of_device_id tangox_dma_dt_ids[] = {
-	{ .compatible = "sigma,smp8640-dma" },
+	{ .compatible = "sigma,smp8758-dma" },
 	{ }
 };
 
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/6] Fixup tangox_dma_sbox_map
  2016-11-23 16:48 Driver for tango DMA engine Marc Gonzalez
                   ` (2 preceding siblings ...)
  2016-11-23 16:51 ` [PATCH 3/6] Fixup for tango4 support Marc Gonzalez
@ 2016-11-23 16:51 ` Marc Gonzalez
  2016-11-23 16:56 ` [PATCH 5/6] Fixup tangox_dma_reset Marc Gonzalez
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marc Gonzalez @ 2016-11-23 16:51 UTC (permalink / raw)
  To: Mans Rullgard, Vinod Koul
  Cc: dmaengine, LKML, Sebastian Frias, Mason, Thibaud Cornic

---
 drivers/dma/tango-dma.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/tango-dma.c b/drivers/dma/tango-dma.c
index 6a32d234ffb0..5250c053a7b9 100644
--- a/drivers/dma/tango-dma.c
+++ b/drivers/dma/tango-dma.c
@@ -108,11 +108,11 @@ static struct tangox_dma_desc *tangox_dma_alloc_desc(unsigned int num_sgs)
 
 static void tangox_dma_sbox_map(struct tangox_dma_device *dev, int src, int dst)
 {
-	void __iomem *addr = dev->sbox_base + 8;
+	void __iomem *addr = dev->sbox_base + SBOX_ROUTE;
 	int shift = (dst - 1) * 4;
 
-	if (shift > 31) {
-		addr += 4;
+	if (dst > 8) {
+		addr = dev->sbox_base + SBOX_ROUTE2;
 		shift -= 32;
 	}
 
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/6] Fixup tangox_dma_reset
  2016-11-23 16:48 Driver for tango DMA engine Marc Gonzalez
                   ` (3 preceding siblings ...)
  2016-11-23 16:51 ` [PATCH 4/6] Fixup tangox_dma_sbox_map Marc Gonzalez
@ 2016-11-23 16:56 ` Marc Gonzalez
  2016-11-23 16:56 ` [PATCH 6/6] Relax write accesses Marc Gonzalez
  2016-11-23 17:27 ` Driver for tango DMA engine Måns Rullgård
  6 siblings, 0 replies; 8+ messages in thread
From: Marc Gonzalez @ 2016-11-23 16:56 UTC (permalink / raw)
  To: Mans Rullgard, Vinod Koul
  Cc: dmaengine, LKML, Sebastian Frias, Mason, Thibaud Cornic

---
 drivers/dma/tango-dma.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/dma/tango-dma.c b/drivers/dma/tango-dma.c
index 5250c053a7b9..24e124942a2f 100644
--- a/drivers/dma/tango-dma.c
+++ b/drivers/dma/tango-dma.c
@@ -414,18 +414,14 @@ static void tangox_dma_desc_free(struct virt_dma_desc *vd)
 
 static void tangox_dma_reset(struct tangox_dma_device *dev)
 {
-	int i;
+	writel(0xffffffff, dev->sbox_base + SBOX_RESET);
+	writel(0xffffffff, dev->sbox_base + SBOX_RESET2);
 
-	for (i = 0; i < 2; i++) {
-		writel(0xffffffff, dev->sbox_base);
-		writel(0xff00ff00, dev->sbox_base);
-		writel(0xffffffff, dev->sbox_base + 4);
-		writel(0xff00ff00, dev->sbox_base + 4);
-		udelay(2);
-	}
+	writel(0xff00ff00, dev->sbox_base + SBOX_RESET);
+	writel(0xff00ff00, dev->sbox_base + SBOX_RESET2);
 
-	writel(0xffffffff, dev->sbox_base + 8);
-	writel(0xffffffff, dev->sbox_base + 12);
+	writel(0xffffffff, dev->sbox_base + SBOX_ROUTE);
+	writel(0xffffffff, dev->sbox_base + SBOX_ROUTE2);
 }
 
 static struct dma_chan *tangox_dma_xlate(struct of_phandle_args *dma_spec,
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/6] Relax write accesses
  2016-11-23 16:48 Driver for tango DMA engine Marc Gonzalez
                   ` (4 preceding siblings ...)
  2016-11-23 16:56 ` [PATCH 5/6] Fixup tangox_dma_reset Marc Gonzalez
@ 2016-11-23 16:56 ` Marc Gonzalez
  2016-11-23 17:27 ` Driver for tango DMA engine Måns Rullgård
  6 siblings, 0 replies; 8+ messages in thread
From: Marc Gonzalez @ 2016-11-23 16:56 UTC (permalink / raw)
  To: Mans Rullgard, Vinod Koul
  Cc: dmaengine, LKML, Sebastian Frias, Mason, Thibaud Cornic

---
 drivers/dma/tango-dma.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/tango-dma.c b/drivers/dma/tango-dma.c
index 24e124942a2f..7049b7c3c0db 100644
--- a/drivers/dma/tango-dma.c
+++ b/drivers/dma/tango-dma.c
@@ -153,11 +153,9 @@ static void tangox_dma_pchan_detach(struct tangox_dma_pchan *pchan)
 static int tangox_dma_issue_single(struct tangox_dma_pchan *pchan,
 				   struct tangox_dma_sg *sg, int flags)
 {
-	writel(sg->addr, pchan->base + DMA_ADDR);
-	writel(sg->len, pchan->base + DMA_COUNT);
-	wmb();
-	writel(DMA_MODE_SINGLE << 1 | flags, pchan->base + DMA_CMD);
-	wmb();
+	writel_relaxed(sg->addr, pchan->base + DMA_ADDR);
+	writel_relaxed(sg->len, pchan->base + DMA_COUNT);
+	writel_relaxed(DMA_MODE_SINGLE << 1 | flags, pchan->base + DMA_CMD);
 
 	return sg->len;
 }
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: Driver for tango DMA engine
  2016-11-23 16:48 Driver for tango DMA engine Marc Gonzalez
                   ` (5 preceding siblings ...)
  2016-11-23 16:56 ` [PATCH 6/6] Relax write accesses Marc Gonzalez
@ 2016-11-23 17:27 ` Måns Rullgård
  6 siblings, 0 replies; 8+ messages in thread
From: Måns Rullgård @ 2016-11-23 17:27 UTC (permalink / raw)
  To: Marc Gonzalez
  Cc: Vinod Koul, dmaengine, LKML, Sebastian Frias, Mason,
	Thibaud Cornic

Marc Gonzalez <marc_gonzalez@sigmadesigns.com> writes:

> Hello Mans,
>
> I would like to push upstream the driver you wrote for the tango
> DMA engine. Could you take a look at my fixes, perhaps some/all
> can be squashed into the initial patch?
>
> Vinod, can you take a look at this submission, and tell me if
> you spot any issue?
>
> Regards.
>
> Mans Rullgard (1):
>   dmaengine: Import tango MBUS driver
>
> Marc Gonzalez (5):
>   Provide names for SBOX register offsets
>   Fixup for tango4 support
>   Fixup tangox_dma_sbox_map
>   Fixup tangox_dma_reset
>   Relax write accesses

I have some other and conflicting fixes not in the github repo.  You
should have asked me before sending this.

Since I'll end up supporting this, I'd really appreciate a little more
cooperation from your side.

-- 
Måns Rullgård

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-11-23 17:28 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-23 16:48 Driver for tango DMA engine Marc Gonzalez
2016-11-23 16:49 ` [PATCH 1/6] dmaengine: Import tango MBUS driver Marc Gonzalez
2016-11-23 16:50 ` [PATCH 2/6] Provide names for SBOX register offsets Marc Gonzalez
2016-11-23 16:51 ` [PATCH 3/6] Fixup for tango4 support Marc Gonzalez
2016-11-23 16:51 ` [PATCH 4/6] Fixup tangox_dma_sbox_map Marc Gonzalez
2016-11-23 16:56 ` [PATCH 5/6] Fixup tangox_dma_reset Marc Gonzalez
2016-11-23 16:56 ` [PATCH 6/6] Relax write accesses Marc Gonzalez
2016-11-23 17:27 ` Driver for tango DMA engine Måns Rullgård

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.