Re: [PATCH 1/2] dmaengine: Add QCOM ADM DMA driver

2014-09-23 Thread Vinod Koul
On Tue, Sep 23, 2014 at 05:10:02PM -0500, Andy Gross wrote:
> 
> 
> > > + break;
> > > + default:
> > > + achan->slave.src_maxburst = 0;
> > > + achan->slave.dst_maxburst = 0;
> > Why clear these for error cases
> 
> With the return I shouldn't need to.  I'll fix this.
> 
> > > + ret = -EINVAL;
> > > + break;
> > > + }
> > > +
> > > + if (!ret)
> > > + writel(achan->blk_size,
> > > + adev->regs + HI_CRCI_CTL(achan->id, adev->ee));
> > and why do we write to HW on this. Shouldn't this be done when you program
> > the descriptor?
> 
> It could be deferred to later.  The main point is that I don't see the
> slave_config happening every transaction.  I was only modifying it now instead
> of making a register write for every transaction.
Well wouldn't it cause a problem if you write to hardware and a transaction
is already in progress.
So it makese sense to write every time at transaction start with latest
value programmed.

> > 
> > > +static enum dma_status adm_tx_status(struct dma_chan *chan, dma_cookie_t 
> > > cookie,
> > > + struct dma_tx_state *txstate)
> > > +{
> > > + struct adm_chan *achan = to_adm_chan(chan);
> > > + struct virt_dma_desc *vd;
> > > + enum dma_status ret;
> > > + unsigned long flags;
> > > + size_t residue = 0;
> > > +
> > > + ret = dma_cookie_status(chan, cookie, txstate);
> > > +
> > Last arg can be null to this, so before you do residue calcluation and block
> > interrupts would make sense to return from here if arg is NULL
> 
> Good catch.  Will fix.
> 
> > 
> > > + spin_lock_irqsave(>vc.lock, flags);
> > > +
> > > + vd = vchan_find_desc(>vc, cookie);
> > > + if (vd)
> > > + residue = container_of(vd, struct adm_async_desc, vd)->length;
> > > + else if (achan->curr_txd && achan->curr_txd->vd.tx.cookie == cookie)
> > > + residue = achan->curr_txd->length;
> > so this is current cookie, so you need to read from HW on current position
> 
> There is no way to get current position unfortunately without relying on
> unreliable debug registers.
In that case would it make sense to return complete txn length?

-- 
~Vinod
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] dmaengine: Add QCOM ADM DMA driver

2014-09-23 Thread Andy Gross


> > +   break;
> > +   default:
> > +   achan->slave.src_maxburst = 0;
> > +   achan->slave.dst_maxburst = 0;
> Why clear these for error cases

With the return I shouldn't need to.  I'll fix this.

> > +   ret = -EINVAL;
> > +   break;
> > +   }
> > +
> > +   if (!ret)
> > +   writel(achan->blk_size,
> > +   adev->regs + HI_CRCI_CTL(achan->id, adev->ee));
> and why do we write to HW on this. Shouldn't this be done when you program
> the descriptor?

It could be deferred to later.  The main point is that I don't see the
slave_config happening every transaction.  I was only modifying it now instead
of making a register write for every transaction.

> 
> > +static enum dma_status adm_tx_status(struct dma_chan *chan, dma_cookie_t 
> > cookie,
> > +   struct dma_tx_state *txstate)
> > +{
> > +   struct adm_chan *achan = to_adm_chan(chan);
> > +   struct virt_dma_desc *vd;
> > +   enum dma_status ret;
> > +   unsigned long flags;
> > +   size_t residue = 0;
> > +
> > +   ret = dma_cookie_status(chan, cookie, txstate);
> > +
> Last arg can be null to this, so before you do residue calcluation and block
> interrupts would make sense to return from here if arg is NULL

Good catch.  Will fix.

> 
> > +   spin_lock_irqsave(>vc.lock, flags);
> > +
> > +   vd = vchan_find_desc(>vc, cookie);
> > +   if (vd)
> > +   residue = container_of(vd, struct adm_async_desc, vd)->length;
> > +   else if (achan->curr_txd && achan->curr_txd->vd.tx.cookie == cookie)
> > +   residue = achan->curr_txd->length;
> so this is current cookie, so you need to read from HW on current position

There is no way to get current position unfortunately without relying on
unreliable debug registers.

> > +
> > +   spin_unlock_irqrestore(>vc.lock, flags);
> > +
> > +   dma_set_residue(txstate, residue);
> > +
> > +   if (achan->error)
> > +   return DMA_ERROR;
> > +
> > +   return ret;
> 
> -- 
> ~Vinod
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] dmaengine: Add QCOM ADM DMA driver

2014-09-23 Thread Vinod Koul
On Wed, Sep 10, 2014 at 09:18:52PM -0500, Andy Gross wrote:

> +static int adm_slave_config(struct adm_chan *achan,
> + struct dma_slave_config *cfg)
> +{
> + int ret = 0;
> + u32 burst;
> + struct adm_device *adev = achan->adev;
> +
> + memcpy(>slave, cfg, sizeof(*cfg));
> +
> + /* set channel CRCI burst, if applicable */
> + if (achan->crci) {
> + burst = max_t(u32, cfg->src_maxburst, cfg->dst_maxburst);
> +
> + switch (burst) {
> + case 16:
> + achan->blk_size = 0;
> + break;
> + case 32:
> + achan->blk_size = 1;
> + break;
> + case 64:
> + achan->blk_size = 2;
> + break;
> + case 128:
> + achan->blk_size = 3;
> + break;
> + case 192:
> + achan->blk_size = 4;
> + break;
> + case 256:
> + achan->blk_size = 5;
> + break;
> + default:
> + achan->slave.src_maxburst = 0;
> + achan->slave.dst_maxburst = 0;
Why clear these for error cases
> + ret = -EINVAL;
> + break;
> + }
> +
> + if (!ret)
> + writel(achan->blk_size,
> + adev->regs + HI_CRCI_CTL(achan->id, adev->ee));
and why do we write to HW on this. Shouldn't this be done when you program
the descriptor?

> +static enum dma_status adm_tx_status(struct dma_chan *chan, dma_cookie_t 
> cookie,
> + struct dma_tx_state *txstate)
> +{
> + struct adm_chan *achan = to_adm_chan(chan);
> + struct virt_dma_desc *vd;
> + enum dma_status ret;
> + unsigned long flags;
> + size_t residue = 0;
> +
> + ret = dma_cookie_status(chan, cookie, txstate);
> +
Last arg can be null to this, so before you do residue calcluation and block
interrupts would make sense to return from here if arg is NULL

> + spin_lock_irqsave(>vc.lock, flags);
> +
> + vd = vchan_find_desc(>vc, cookie);
> + if (vd)
> + residue = container_of(vd, struct adm_async_desc, vd)->length;
> + else if (achan->curr_txd && achan->curr_txd->vd.tx.cookie == cookie)
> + residue = achan->curr_txd->length;
so this is current cookie, so you need to read from HW on current position
> +
> + spin_unlock_irqrestore(>vc.lock, flags);
> +
> + dma_set_residue(txstate, residue);
> +
> + if (achan->error)
> + return DMA_ERROR;
> +
> + return ret;

-- 
~Vinod

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] dmaengine: Add QCOM ADM DMA driver

2014-09-23 Thread Vinod Koul
On Wed, Sep 10, 2014 at 09:18:52PM -0500, Andy Gross wrote:

 +static int adm_slave_config(struct adm_chan *achan,
 + struct dma_slave_config *cfg)
 +{
 + int ret = 0;
 + u32 burst;
 + struct adm_device *adev = achan-adev;
 +
 + memcpy(achan-slave, cfg, sizeof(*cfg));
 +
 + /* set channel CRCI burst, if applicable */
 + if (achan-crci) {
 + burst = max_t(u32, cfg-src_maxburst, cfg-dst_maxburst);
 +
 + switch (burst) {
 + case 16:
 + achan-blk_size = 0;
 + break;
 + case 32:
 + achan-blk_size = 1;
 + break;
 + case 64:
 + achan-blk_size = 2;
 + break;
 + case 128:
 + achan-blk_size = 3;
 + break;
 + case 192:
 + achan-blk_size = 4;
 + break;
 + case 256:
 + achan-blk_size = 5;
 + break;
 + default:
 + achan-slave.src_maxburst = 0;
 + achan-slave.dst_maxburst = 0;
Why clear these for error cases
 + ret = -EINVAL;
 + break;
 + }
 +
 + if (!ret)
 + writel(achan-blk_size,
 + adev-regs + HI_CRCI_CTL(achan-id, adev-ee));
and why do we write to HW on this. Shouldn't this be done when you program
the descriptor?

 +static enum dma_status adm_tx_status(struct dma_chan *chan, dma_cookie_t 
 cookie,
 + struct dma_tx_state *txstate)
 +{
 + struct adm_chan *achan = to_adm_chan(chan);
 + struct virt_dma_desc *vd;
 + enum dma_status ret;
 + unsigned long flags;
 + size_t residue = 0;
 +
 + ret = dma_cookie_status(chan, cookie, txstate);
 +
Last arg can be null to this, so before you do residue calcluation and block
interrupts would make sense to return from here if arg is NULL

 + spin_lock_irqsave(achan-vc.lock, flags);
 +
 + vd = vchan_find_desc(achan-vc, cookie);
 + if (vd)
 + residue = container_of(vd, struct adm_async_desc, vd)-length;
 + else if (achan-curr_txd  achan-curr_txd-vd.tx.cookie == cookie)
 + residue = achan-curr_txd-length;
so this is current cookie, so you need to read from HW on current position
 +
 + spin_unlock_irqrestore(achan-vc.lock, flags);
 +
 + dma_set_residue(txstate, residue);
 +
 + if (achan-error)
 + return DMA_ERROR;
 +
 + return ret;

-- 
~Vinod

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] dmaengine: Add QCOM ADM DMA driver

2014-09-23 Thread Andy Gross
snip

  +   break;
  +   default:
  +   achan-slave.src_maxburst = 0;
  +   achan-slave.dst_maxburst = 0;
 Why clear these for error cases

With the return I shouldn't need to.  I'll fix this.

  +   ret = -EINVAL;
  +   break;
  +   }
  +
  +   if (!ret)
  +   writel(achan-blk_size,
  +   adev-regs + HI_CRCI_CTL(achan-id, adev-ee));
 and why do we write to HW on this. Shouldn't this be done when you program
 the descriptor?

It could be deferred to later.  The main point is that I don't see the
slave_config happening every transaction.  I was only modifying it now instead
of making a register write for every transaction.

 
  +static enum dma_status adm_tx_status(struct dma_chan *chan, dma_cookie_t 
  cookie,
  +   struct dma_tx_state *txstate)
  +{
  +   struct adm_chan *achan = to_adm_chan(chan);
  +   struct virt_dma_desc *vd;
  +   enum dma_status ret;
  +   unsigned long flags;
  +   size_t residue = 0;
  +
  +   ret = dma_cookie_status(chan, cookie, txstate);
  +
 Last arg can be null to this, so before you do residue calcluation and block
 interrupts would make sense to return from here if arg is NULL

Good catch.  Will fix.

 
  +   spin_lock_irqsave(achan-vc.lock, flags);
  +
  +   vd = vchan_find_desc(achan-vc, cookie);
  +   if (vd)
  +   residue = container_of(vd, struct adm_async_desc, vd)-length;
  +   else if (achan-curr_txd  achan-curr_txd-vd.tx.cookie == cookie)
  +   residue = achan-curr_txd-length;
 so this is current cookie, so you need to read from HW on current position

There is no way to get current position unfortunately without relying on
unreliable debug registers.

  +
  +   spin_unlock_irqrestore(achan-vc.lock, flags);
  +
  +   dma_set_residue(txstate, residue);
  +
  +   if (achan-error)
  +   return DMA_ERROR;
  +
  +   return ret;
 
 -- 
 ~Vinod
 
 --
 To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] dmaengine: Add QCOM ADM DMA driver

2014-09-23 Thread Vinod Koul
On Tue, Sep 23, 2014 at 05:10:02PM -0500, Andy Gross wrote:
 snip
 
   + break;
   + default:
   + achan-slave.src_maxburst = 0;
   + achan-slave.dst_maxburst = 0;
  Why clear these for error cases
 
 With the return I shouldn't need to.  I'll fix this.
 
   + ret = -EINVAL;
   + break;
   + }
   +
   + if (!ret)
   + writel(achan-blk_size,
   + adev-regs + HI_CRCI_CTL(achan-id, adev-ee));
  and why do we write to HW on this. Shouldn't this be done when you program
  the descriptor?
 
 It could be deferred to later.  The main point is that I don't see the
 slave_config happening every transaction.  I was only modifying it now instead
 of making a register write for every transaction.
Well wouldn't it cause a problem if you write to hardware and a transaction
is already in progress.
So it makese sense to write every time at transaction start with latest
value programmed.

  
   +static enum dma_status adm_tx_status(struct dma_chan *chan, dma_cookie_t 
   cookie,
   + struct dma_tx_state *txstate)
   +{
   + struct adm_chan *achan = to_adm_chan(chan);
   + struct virt_dma_desc *vd;
   + enum dma_status ret;
   + unsigned long flags;
   + size_t residue = 0;
   +
   + ret = dma_cookie_status(chan, cookie, txstate);
   +
  Last arg can be null to this, so before you do residue calcluation and block
  interrupts would make sense to return from here if arg is NULL
 
 Good catch.  Will fix.
 
  
   + spin_lock_irqsave(achan-vc.lock, flags);
   +
   + vd = vchan_find_desc(achan-vc, cookie);
   + if (vd)
   + residue = container_of(vd, struct adm_async_desc, vd)-length;
   + else if (achan-curr_txd  achan-curr_txd-vd.tx.cookie == cookie)
   + residue = achan-curr_txd-length;
  so this is current cookie, so you need to read from HW on current position
 
 There is no way to get current position unfortunately without relying on
 unreliable debug registers.
In that case would it make sense to return complete txn length?

-- 
~Vinod
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] dmaengine: Add QCOM ADM DMA driver

2014-09-10 Thread Andy Gross
Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
controller found in the MSM8960 and IPQ/APQ8064 platforms.

The ADM supports both memory to memory transactions and memory
to/from peripheral device transactions.  The controller also provides flow
control capabilities for transactions to/from peripheral devices.

The initial release of this driver supports slave transfers to/from peripherals
and also incorporates CRCI (client rate control interface) flow control.

Signed-off-by: Andy Gross 
---
 drivers/dma/Kconfig|   10 +
 drivers/dma/Makefile   |1 +
 drivers/dma/qcom_adm.c |  872 
 3 files changed, 883 insertions(+)
 create mode 100644 drivers/dma/qcom_adm.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 9b1ea0e..88291ec 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -469,4 +469,14 @@ config QCOM_BAM_DMA
  Enable support for the QCOM BAM DMA controller.  This controller
  provides DMA capabilities for a variety of on-chip devices.
 
+config QCOM_ADM
+   tristate "Qualcomm ADM support"
+   depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   ---help---
+ Enable support for the Qualcomm ADM DMA controller.  This controller
+ provides DMA capabilities for both general purpose and on-chip
+ peripheral devices.
+
 endif
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index c6adb92..3bad47d 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -50,3 +50,4 @@ obj-y += xilinx/
 obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
 obj-$(CONFIG_NBPFAXI_DMA) += nbpfaxi.o
 obj-$(CONFIG_DMA_SUN6I) += sun6i-dma.o
+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
diff --git a/drivers/dma/qcom_adm.c b/drivers/dma/qcom_adm.c
new file mode 100644
index 000..7680bfc
--- /dev/null
+++ b/drivers/dma/qcom_adm.c
@@ -0,0 +1,872 @@
+/*
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+/* ADM registers - calculated from channel number and security domain */
+#define HI_CH_CMD_PTR(chan, ee)(4*chan + 0x20800*ee)
+#define HI_CH_RSLT(chan, ee)   (0x40 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE0(chan, ee)   (0x80 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE1(chan, ee)   (0xc0 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE2(chan, ee)   (0x100 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE3(chan, ee)   (0x140 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE4(chan, ee)   (0x180 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE5(chan, ee)   (0x1c0 + 4*chan + 0x20800*ee)
+#define HI_CH_STATUS_SD(chan, ee)  (0x200 + 4*chan + 0x20800*ee)
+#define HI_CH_CONF(chan)   (0x240 + 4*chan)
+#define HI_CH_RSLT_CONF(chan, ee)  (0x300 + 4*chan + 0x20800*ee)
+#define HI_SEC_DOMAIN_IRQ_STATUS(ee)   (0x380 + 0x20800*ee)
+#define HI_CI_CONF(ci) (0x390 + 4*ci)
+#define HI_CRCI_CONF0  0x3d0
+#define HI_CRCI_CONF1  0x3d4
+#define HI_GP_CTL  0x3d8
+#define HI_CRCI_CTL(chan, ee)  (0x400 + 0x4*chan + 0x20800*ee)
+
+/* channel status */
+#define CH_STATUS_VALIDBIT(1)
+
+/* channel result */
+#define CH_RSLT_VALID  BIT(31)
+#define CH_RSLT_ERRBIT(3)
+#define CH_RSLT_FLUSH  BIT(2)
+#define CH_RSLT_TPDBIT(1)
+
+/* channel conf */
+#define CH_CONF_MPU_DISABLEBIT(11)
+#define CH_CONF_PERM_MPU_CONF  BIT(9)
+#define CH_CONF_FLUSH_RSLT_EN  BIT(8)
+#define CH_CONF_FORCE_RSLT_EN  BIT(7)
+#define CH_CONF_IRQ_EN BIT(6)
+
+/* channel result conf */
+#define CH_RSLT_CONF_FLUSH_EN  BIT(1)
+#define CH_RSLT_CONF_IRQ_ENBIT(0)
+
+/* CRCI CTL */
+#define CRCI_CTL_RST   BIT(17)
+
+/* CI configuration */
+#define CI_RANGE_END(x)(x << 24)
+#define CI_RANGE_START(x)  (x << 16)
+#define CI_BURST_4_WORDS   0x4
+#define CI_BURST_8_WORDS   0x8
+
+/* GP CTL */
+#define GP_CTL_LP_EN   BIT(12)
+#define GP_CTL_LP_CNT(x)   (x << 8)
+
+/* Command pointer list entry */
+#define CPLE_LPBIT(31)
+
+/* Command list entry */
+#define CMD_LC BIT(31)
+#define CMD_DST_CRCI(n)(((n) & 0xf) << 7)

[PATCH 1/2] dmaengine: Add QCOM ADM DMA driver

2014-09-10 Thread Andy Gross
Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
controller found in the MSM8960 and IPQ/APQ8064 platforms.

The ADM supports both memory to memory transactions and memory
to/from peripheral device transactions.  The controller also provides flow
control capabilities for transactions to/from peripheral devices.

The initial release of this driver supports slave transfers to/from peripherals
and also incorporates CRCI (client rate control interface) flow control.

Signed-off-by: Andy Gross agr...@codeaurora.org
---
 drivers/dma/Kconfig|   10 +
 drivers/dma/Makefile   |1 +
 drivers/dma/qcom_adm.c |  872 
 3 files changed, 883 insertions(+)
 create mode 100644 drivers/dma/qcom_adm.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 9b1ea0e..88291ec 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -469,4 +469,14 @@ config QCOM_BAM_DMA
  Enable support for the QCOM BAM DMA controller.  This controller
  provides DMA capabilities for a variety of on-chip devices.
 
+config QCOM_ADM
+   tristate Qualcomm ADM support
+   depends on ARCH_QCOM || (COMPILE_TEST  OF  ARM)
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   ---help---
+ Enable support for the Qualcomm ADM DMA controller.  This controller
+ provides DMA capabilities for both general purpose and on-chip
+ peripheral devices.
+
 endif
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index c6adb92..3bad47d 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -50,3 +50,4 @@ obj-y += xilinx/
 obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
 obj-$(CONFIG_NBPFAXI_DMA) += nbpfaxi.o
 obj-$(CONFIG_DMA_SUN6I) += sun6i-dma.o
+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
diff --git a/drivers/dma/qcom_adm.c b/drivers/dma/qcom_adm.c
new file mode 100644
index 000..7680bfc
--- /dev/null
+++ b/drivers/dma/qcom_adm.c
@@ -0,0 +1,872 @@
+/*
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include linux/kernel.h
+#include linux/io.h
+#include linux/init.h
+#include linux/slab.h
+#include linux/module.h
+#include linux/interrupt.h
+#include linux/dma-mapping.h
+#include linux/scatterlist.h
+#include linux/device.h
+#include linux/platform_device.h
+#include linux/of.h
+#include linux/of_address.h
+#include linux/of_irq.h
+#include linux/of_dma.h
+#include linux/reset.h
+#include linux/clk.h
+#include linux/dmaengine.h
+
+#include dmaengine.h
+#include virt-dma.h
+
+/* ADM registers - calculated from channel number and security domain */
+#define HI_CH_CMD_PTR(chan, ee)(4*chan + 0x20800*ee)
+#define HI_CH_RSLT(chan, ee)   (0x40 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE0(chan, ee)   (0x80 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE1(chan, ee)   (0xc0 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE2(chan, ee)   (0x100 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE3(chan, ee)   (0x140 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE4(chan, ee)   (0x180 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE5(chan, ee)   (0x1c0 + 4*chan + 0x20800*ee)
+#define HI_CH_STATUS_SD(chan, ee)  (0x200 + 4*chan + 0x20800*ee)
+#define HI_CH_CONF(chan)   (0x240 + 4*chan)
+#define HI_CH_RSLT_CONF(chan, ee)  (0x300 + 4*chan + 0x20800*ee)
+#define HI_SEC_DOMAIN_IRQ_STATUS(ee)   (0x380 + 0x20800*ee)
+#define HI_CI_CONF(ci) (0x390 + 4*ci)
+#define HI_CRCI_CONF0  0x3d0
+#define HI_CRCI_CONF1  0x3d4
+#define HI_GP_CTL  0x3d8
+#define HI_CRCI_CTL(chan, ee)  (0x400 + 0x4*chan + 0x20800*ee)
+
+/* channel status */
+#define CH_STATUS_VALIDBIT(1)
+
+/* channel result */
+#define CH_RSLT_VALID  BIT(31)
+#define CH_RSLT_ERRBIT(3)
+#define CH_RSLT_FLUSH  BIT(2)
+#define CH_RSLT_TPDBIT(1)
+
+/* channel conf */
+#define CH_CONF_MPU_DISABLEBIT(11)
+#define CH_CONF_PERM_MPU_CONF  BIT(9)
+#define CH_CONF_FLUSH_RSLT_EN  BIT(8)
+#define CH_CONF_FORCE_RSLT_EN  BIT(7)
+#define CH_CONF_IRQ_EN BIT(6)
+
+/* channel result conf */
+#define CH_RSLT_CONF_FLUSH_EN  BIT(1)
+#define CH_RSLT_CONF_IRQ_ENBIT(0)
+
+/* CRCI CTL */
+#define CRCI_CTL_RST   BIT(17)
+
+/* CI configuration */
+#define CI_RANGE_END(x)(x  24)
+#define CI_RANGE_START(x)  (x  16)
+#define CI_BURST_4_WORDS   0x4
+#define CI_BURST_8_WORDS   0x8
+
+/* GP CTL */
+#define GP_CTL_LP_EN   

[PATCH 1/2] dmaengine: Add QCOM ADM DMA driver

2014-06-26 Thread Andy Gross
Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
controller found in the MSM8960 and IPQ/APQ8064 platforms.

The ADM supports both memory to memory transactions and memory
to/from peripheral device transactions.  The controller also provides flow
control capabilities for transactions to/from peripheral devices.

The initial release of this driver supports slave transfers to/from peripherals
and also incorporates CRCI (client rate control interface) flow control.

Signed-off-by: Andy Gross 
---
 drivers/dma/Kconfig|   10 +
 drivers/dma/Makefile   |1 +
 drivers/dma/qcom_adm.c |  872 
 3 files changed, 883 insertions(+)
 create mode 100644 drivers/dma/qcom_adm.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 1eca7b9..8969bc7 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -434,4 +434,14 @@ config QCOM_BAM_DMA
  Enable support for the QCOM BAM DMA controller.  This controller
  provides DMA capabilities for a variety of on-chip devices.
 
+config QCOM_ADM
+   tristate "Qualcomm ADM support"
+   depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   ---help---
+ Enable support for the Qualcomm ADM DMA controller.  This controller
+ provides DMA capabilities for both general purpose and on-chip
+ peripheral devices.
+
 endif
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index c779e1e..b3defae 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -47,3 +47,4 @@ obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
 obj-$(CONFIG_FSL_EDMA) += fsl-edma.o
 obj-$(CONFIG_QCOM_BAM_DMA) += qcom_bam_dma.o
 obj-y += xilinx/
+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
diff --git a/drivers/dma/qcom_adm.c b/drivers/dma/qcom_adm.c
new file mode 100644
index 000..7680bfc
--- /dev/null
+++ b/drivers/dma/qcom_adm.c
@@ -0,0 +1,872 @@
+/*
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+/* ADM registers - calculated from channel number and security domain */
+#define HI_CH_CMD_PTR(chan, ee)(4*chan + 0x20800*ee)
+#define HI_CH_RSLT(chan, ee)   (0x40 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE0(chan, ee)   (0x80 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE1(chan, ee)   (0xc0 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE2(chan, ee)   (0x100 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE3(chan, ee)   (0x140 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE4(chan, ee)   (0x180 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE5(chan, ee)   (0x1c0 + 4*chan + 0x20800*ee)
+#define HI_CH_STATUS_SD(chan, ee)  (0x200 + 4*chan + 0x20800*ee)
+#define HI_CH_CONF(chan)   (0x240 + 4*chan)
+#define HI_CH_RSLT_CONF(chan, ee)  (0x300 + 4*chan + 0x20800*ee)
+#define HI_SEC_DOMAIN_IRQ_STATUS(ee)   (0x380 + 0x20800*ee)
+#define HI_CI_CONF(ci) (0x390 + 4*ci)
+#define HI_CRCI_CONF0  0x3d0
+#define HI_CRCI_CONF1  0x3d4
+#define HI_GP_CTL  0x3d8
+#define HI_CRCI_CTL(chan, ee)  (0x400 + 0x4*chan + 0x20800*ee)
+
+/* channel status */
+#define CH_STATUS_VALIDBIT(1)
+
+/* channel result */
+#define CH_RSLT_VALID  BIT(31)
+#define CH_RSLT_ERRBIT(3)
+#define CH_RSLT_FLUSH  BIT(2)
+#define CH_RSLT_TPDBIT(1)
+
+/* channel conf */
+#define CH_CONF_MPU_DISABLEBIT(11)
+#define CH_CONF_PERM_MPU_CONF  BIT(9)
+#define CH_CONF_FLUSH_RSLT_EN  BIT(8)
+#define CH_CONF_FORCE_RSLT_EN  BIT(7)
+#define CH_CONF_IRQ_EN BIT(6)
+
+/* channel result conf */
+#define CH_RSLT_CONF_FLUSH_EN  BIT(1)
+#define CH_RSLT_CONF_IRQ_ENBIT(0)
+
+/* CRCI CTL */
+#define CRCI_CTL_RST   BIT(17)
+
+/* CI configuration */
+#define CI_RANGE_END(x)(x << 24)
+#define CI_RANGE_START(x)  (x << 16)
+#define CI_BURST_4_WORDS   0x4
+#define CI_BURST_8_WORDS   0x8
+
+/* GP CTL */
+#define GP_CTL_LP_EN   BIT(12)
+#define GP_CTL_LP_CNT(x)   (x << 8)
+
+/* Command pointer list entry */
+#define CPLE_LPBIT(31)
+
+/* Command list entry */
+#define CMD_LC BIT(31)
+#define CMD_DST_CRCI(n)(((n) & 0xf) << 7)

[PATCH 1/2] dmaengine: Add QCOM ADM DMA driver

2014-06-26 Thread Andy Gross
Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
controller found in the MSM8960 and IPQ/APQ8064 platforms.

The ADM supports both memory to memory transactions and memory
to/from peripheral device transactions.  The controller also provides flow
control capabilities for transactions to/from peripheral devices.

The initial release of this driver supports slave transfers to/from peripherals
and also incorporates CRCI (client rate control interface) flow control.

Signed-off-by: Andy Gross agr...@codeaurora.org
---
 drivers/dma/Kconfig|   10 +
 drivers/dma/Makefile   |1 +
 drivers/dma/qcom_adm.c |  872 
 3 files changed, 883 insertions(+)
 create mode 100644 drivers/dma/qcom_adm.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 1eca7b9..8969bc7 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -434,4 +434,14 @@ config QCOM_BAM_DMA
  Enable support for the QCOM BAM DMA controller.  This controller
  provides DMA capabilities for a variety of on-chip devices.
 
+config QCOM_ADM
+   tristate Qualcomm ADM support
+   depends on ARCH_QCOM || (COMPILE_TEST  OF  ARM)
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   ---help---
+ Enable support for the Qualcomm ADM DMA controller.  This controller
+ provides DMA capabilities for both general purpose and on-chip
+ peripheral devices.
+
 endif
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index c779e1e..b3defae 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -47,3 +47,4 @@ obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
 obj-$(CONFIG_FSL_EDMA) += fsl-edma.o
 obj-$(CONFIG_QCOM_BAM_DMA) += qcom_bam_dma.o
 obj-y += xilinx/
+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
diff --git a/drivers/dma/qcom_adm.c b/drivers/dma/qcom_adm.c
new file mode 100644
index 000..7680bfc
--- /dev/null
+++ b/drivers/dma/qcom_adm.c
@@ -0,0 +1,872 @@
+/*
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include linux/kernel.h
+#include linux/io.h
+#include linux/init.h
+#include linux/slab.h
+#include linux/module.h
+#include linux/interrupt.h
+#include linux/dma-mapping.h
+#include linux/scatterlist.h
+#include linux/device.h
+#include linux/platform_device.h
+#include linux/of.h
+#include linux/of_address.h
+#include linux/of_irq.h
+#include linux/of_dma.h
+#include linux/reset.h
+#include linux/clk.h
+#include linux/dmaengine.h
+
+#include dmaengine.h
+#include virt-dma.h
+
+/* ADM registers - calculated from channel number and security domain */
+#define HI_CH_CMD_PTR(chan, ee)(4*chan + 0x20800*ee)
+#define HI_CH_RSLT(chan, ee)   (0x40 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE0(chan, ee)   (0x80 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE1(chan, ee)   (0xc0 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE2(chan, ee)   (0x100 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE3(chan, ee)   (0x140 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE4(chan, ee)   (0x180 + 4*chan + 0x20800*ee)
+#define HI_CH_FLUSH_STATE5(chan, ee)   (0x1c0 + 4*chan + 0x20800*ee)
+#define HI_CH_STATUS_SD(chan, ee)  (0x200 + 4*chan + 0x20800*ee)
+#define HI_CH_CONF(chan)   (0x240 + 4*chan)
+#define HI_CH_RSLT_CONF(chan, ee)  (0x300 + 4*chan + 0x20800*ee)
+#define HI_SEC_DOMAIN_IRQ_STATUS(ee)   (0x380 + 0x20800*ee)
+#define HI_CI_CONF(ci) (0x390 + 4*ci)
+#define HI_CRCI_CONF0  0x3d0
+#define HI_CRCI_CONF1  0x3d4
+#define HI_GP_CTL  0x3d8
+#define HI_CRCI_CTL(chan, ee)  (0x400 + 0x4*chan + 0x20800*ee)
+
+/* channel status */
+#define CH_STATUS_VALIDBIT(1)
+
+/* channel result */
+#define CH_RSLT_VALID  BIT(31)
+#define CH_RSLT_ERRBIT(3)
+#define CH_RSLT_FLUSH  BIT(2)
+#define CH_RSLT_TPDBIT(1)
+
+/* channel conf */
+#define CH_CONF_MPU_DISABLEBIT(11)
+#define CH_CONF_PERM_MPU_CONF  BIT(9)
+#define CH_CONF_FLUSH_RSLT_EN  BIT(8)
+#define CH_CONF_FORCE_RSLT_EN  BIT(7)
+#define CH_CONF_IRQ_EN BIT(6)
+
+/* channel result conf */
+#define CH_RSLT_CONF_FLUSH_EN  BIT(1)
+#define CH_RSLT_CONF_IRQ_ENBIT(0)
+
+/* CRCI CTL */
+#define CRCI_CTL_RST   BIT(17)
+
+/* CI configuration */
+#define CI_RANGE_END(x)(x  24)
+#define CI_RANGE_START(x)  (x  16)
+#define CI_BURST_4_WORDS   0x4
+#define CI_BURST_8_WORDS   0x8
+
+/* GP CTL */
+#define GP_CTL_LP_EN