Re: [Patch v8 2/2] dmaengine: add Qualcomm BAM dma driver

2014-03-07 Thread Andy Gross
On Mon, Mar 03, 2014 at 09:38:03AM +, Shevchenko, Andriy wrote:



> > +   if (IS_ERR(bdev->bamclk))
> > +   return PTR_ERR(bdev->bamclk);
> > +
> > +   ret = clk_prepare_enable(bdev->bamclk);
> > +   if (ret) {
> > +   dev_err(bdev->dev, "failed to prepare/enable clock\n");
> > +   return ret;
> > +   }
> > +
> > +   ret = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &bdev->ee);
> > +   if (ret) {
> > +   dev_err(bdev->dev, "Execution environment unspecified\n");
> > +   return ret;
> 
> goto err_disable_clk; ?
> 
> > 
> > +   }
> > +
> > +   ret = bam_init(bdev);
> > +   if (ret)
> > +   return ret;
> 
> Ditto.
> 

Good catch.  I'll fix both of those.

-- 
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 v8 2/2] dmaengine: add Qualcomm BAM dma driver

2014-03-07 Thread Andy Gross
On Sat, Mar 08, 2014 at 12:29:49AM +0200, Stanimir Vabanov wrote:
> > +#define BAM_IRQ_SRCS_EE(pipe)  (0x0800 + ((pipe) * 0x80))
> > +#define BAM_IRQ_SRCS_MSK_EE(pipe)  (0x0804 + ((pipe) * 0x80))
> 
> s/pipe/ee ?
> 

Ah good catch.  I'll fix that.

> > +struct bam_chan {
> > +   struct virt_dma_chan vc;
> > +
> > +   struct bam_device *bdev;
> > +
> > +   /* configuration from device tree */
> > +   u32 id;
> > +   u32 ee;
> > +
> 
> do we need per channel ee? I'm asking because failed to find references
> to it.
> 

You're right.  This is dead variable.  I had transitioned from channel to
device when I modified the bindings.  Device is where it belongs.  I'll fix
this.


> > +
> > +/**
> > + * bam_alloc_chan - Allocate channel resources for DMA channel.
> > + * @chan: specified channel
> > + *
> > + * This function allocates the FIFO descriptor memory
> > + */
> > +static int bam_alloc_chan(struct dma_chan *chan)
> > +{
> > +   struct bam_chan *bchan = to_bam_chan(chan);
> > +   struct bam_device *bdev = bchan->bdev;
> > +
> 
> you could invert the logic and avoid extra indentation.
>   if (bchan->fifo_virt)
>   return 0;
> 

True.  I'll flip that.

-- 
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 v8 2/2] dmaengine: add Qualcomm BAM dma driver

2014-03-07 Thread Stanimir Vabanov
Hi Andy,

Thanks for the patch.



> +#define BAM_IRQ_SRCS_EE(pipe)(0x0800 + ((pipe) * 0x80))
> +#define BAM_IRQ_SRCS_MSK_EE(pipe)(0x0804 + ((pipe) * 0x80))

s/pipe/ee ?



> +struct bam_chan {
> + struct virt_dma_chan vc;
> +
> + struct bam_device *bdev;
> +
> + /* configuration from device tree */
> + u32 id;
> + u32 ee;
> +

do we need per channel ee? I'm asking because failed to find references
to it.

> + struct bam_async_desc *curr_txd;/* current running dma */
> +
> + /* runtime configuration */
> + struct dma_slave_config slave;
> +
> + /* fifo storage */
> + struct bam_desc_hw *fifo_virt;
> + dma_addr_t fifo_phys;
> +
> + /* fifo markers */
> + unsigned short head;/* start of active descriptor entries */
> + unsigned short tail;/* end of active descriptor entries */
> +
> + unsigned int initialized;   /* is the channel hw initialized? */
> + unsigned int paused;/* is the channel paused? */
> + unsigned int reconfigure;   /* new slave config? */
> +
> + struct list_head node;
> +};
> +



> +
> +/**
> + * bam_alloc_chan - Allocate channel resources for DMA channel.
> + * @chan: specified channel
> + *
> + * This function allocates the FIFO descriptor memory
> + */
> +static int bam_alloc_chan(struct dma_chan *chan)
> +{
> + struct bam_chan *bchan = to_bam_chan(chan);
> + struct bam_device *bdev = bchan->bdev;
> +

you could invert the logic and avoid extra indentation.
if (bchan->fifo_virt)
return 0;

> + /* allocate FIFO descriptor space, but only if necessary */
> + if (!bchan->fifo_virt) {
> + bchan->fifo_virt = dma_alloc_writecombine(bdev->dev,
> + BAM_DESC_FIFO_SIZE, &bchan->fifo_phys,
> + GFP_KERNEL);
> +
> + if (!bchan->fifo_virt) {
> + dev_err(bdev->dev, "Failed to allocate desc fifo\n");
> + return -ENOMEM;
> + }
> + }
> +
> + return 0;
> +}
> +



regards,
Stan
--
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 v8 2/2] dmaengine: add Qualcomm BAM dma driver

2014-03-03 Thread Shevchenko, Andriy
On Mon, 2014-03-03 at 00:30 -0600, Andy Gross wrote:
> Add the DMA engine driver for the QCOM Bus Access Manager (BAM) DMA controller
> found in the MSM 8x74 platforms.
> 
> Each BAM DMA device is associated with a specific on-chip peripheral.  Each
> channel provides a uni-directional data transfer engine that is capable of
> transferring data between the peripheral and system memory (System mode), or
> between two peripherals (BAM2BAM).
> 
> The initial release of this driver only supports slave transfers between
> peripherals and system memory.

One comment below related to error path in probe().

> 
> Signed-off-by: Andy Gross 
> ---
>  drivers/dma/Kconfig|9 +
>  drivers/dma/Makefile   |1 +
>  drivers/dma/qcom_bam_dma.c | 1110 
> 
>  3 files changed, 1120 insertions(+)
>  create mode 100644 drivers/dma/qcom_bam_dma.c
> 
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 605b016..f87cef9 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -401,4 +401,13 @@ config DMATEST
>  config DMA_ENGINE_RAID
>   bool
>  
> +config QCOM_BAM_DMA
> + tristate "QCOM BAM DMA support"
> + depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
> + select DMA_ENGINE
> + select DMA_VIRTUAL_CHANNELS
> + ---help---
> +   Enable support for the QCOM BAM DMA controller.  This controller
> +   provides DMA capabilities for a variety of on-chip devices.
> +
>  endif
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index a029d0f4..907b915 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -44,3 +44,4 @@ obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
>  obj-$(CONFIG_TI_CPPI41) += cppi41.o
>  obj-$(CONFIG_K3_DMA) += k3dma.o
>  obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
> +obj-$(CONFIG_QCOM_BAM_DMA) += qcom_bam_dma.o
> diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c
> new file mode 100644
> index 000..3210983
> --- /dev/null
> +++ b/drivers/dma/qcom_bam_dma.c
> @@ -0,0 +1,1110 @@
> +/*
> + * 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.
> + *
> + */
> +/*
> + * QCOM BAM DMA engine driver
> + *
> + * QCOM BAM DMA blocks are distributed amongst a number of the on-chip
> + * peripherals on the MSM 8x74.  The configuration of the channels are 
> dependent
> + * on the way they are hard wired to that specific peripheral.  The 
> peripheral
> + * device tree entries specify the configuration of each channel.
> + *
> + * The DMA controller requires the use of external memory for storage of the
> + * hardware descriptors for each channel.  The descriptor FIFO is accessed 
> as a
> + * circular buffer and operations are managed according to the offset within 
> the
> + * FIFO.  After pipe/channel reset, all of the pipe registers and internal 
> state
> + * are back to defaults.
> + *
> + * During DMA operations, we write descriptors to the FIFO, being careful to
> + * handle wrapping and then write the last FIFO offset to that channel's
> + * P_EVNT_REG register to kick off the transaction.  The P_SW_OFSTS register
> + * indicates the current FIFO offset that is being processed, so there is 
> some
> + * indication of where the hardware is currently working.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "dmaengine.h"
> +#include "virt-dma.h"
> +
> +struct bam_desc_hw {
> + u32 addr;   /* Buffer physical address */
> + u16 size;   /* Buffer size in bytes */
> + u16 flags;
> +};
> +
> +#define DESC_FLAG_INT BIT(15)
> +#define DESC_FLAG_EOT BIT(14)
> +#define DESC_FLAG_EOB BIT(13)
> +
> +struct bam_async_desc {
> + struct virt_dma_desc vd;
> +
> + u32 num_desc;
> + u32 xfer_len;
> + struct bam_desc_hw *curr_desc;
> +
> + enum dma_transfer_direction dir;
> + size_t length;
> + struct bam_desc_hw desc[0];
> +};
> +
> +#define BAM_CTRL 0x
> +#define BAM_REVISION 0x0004
> +#define BAM_SW_REVISION  0x0080
> +#define BAM_NUM_PIPES0x003C
> +#define BAM_TIMER0x0040
> +#define BAM_TIMER_CTRL   0x0044
> +#define BAM_DESC_CNT_TRSHLD  0x0008
> +#define BAM_IRQ_SRCS 0x000C
> +#define BAM_IRQ_SRCS_MSK

Re: [Patch v8 2/2] dmaengine: add Qualcomm BAM dma driver

2014-03-02 Thread Joe Perches
On Mon, 2014-03-03 at 00:30 -0600, Andy Gross wrote:
> Add the DMA engine driver for the QCOM Bus Access Manager (BAM) DMA controller
> found in the MSM 8x74 platforms.
> 
> Each BAM DMA device is associated with a specific on-chip peripheral.  Each
> channel provides a uni-directional data transfer engine that is capable of
> transferring data between the peripheral and system memory (System mode), or
> between two peripherals (BAM2BAM).
[]

trivia:

> +static u32 process_channel_irqs(struct bam_device *bdev)
> +{
[]
> + for (i = 0; i < bdev->num_channels; i++) {
> + struct bam_chan *bchan = &bdev->channels[i];
> + if (srcs & BIT(i)) {
> + /* clear pipe irq */
> + pipe_stts = readl_relaxed(bdev->regs +
> + BAM_P_IRQ_STTS(i));
> +
> + writel_relaxed(pipe_stts, bdev->regs +
> + BAM_P_IRQ_CLR(i));
> +
> + spin_lock_irqsave(&bchan->vc.lock, flags);
> + async_desc = bchan->curr_txd;
> +
> + if (async_desc) {
> + async_desc->num_desc -= async_desc->xfer_len;
> + async_desc->curr_desc += async_desc->xfer_len;
> + bchan->curr_txd = NULL;
> +
> + /* manage FIFO */
> + bchan->head += async_desc->xfer_len;
> + bchan->head %= MAX_DESCRIPTORS;
> +
> + /*
> +  * if complete, process cookie.  Otherwise
> +  * push back to front of desc_issued so that
> +  * it gets restarted by the tasklet
> +  */
> + if (!async_desc->num_desc)
> + vchan_cookie_complete(&async_desc->vd);
> + else
> + list_add(&async_desc->vd.node,
> + &bchan->vc.desc_issued);
> + }
> +
> + spin_unlock_irqrestore(&bchan->vc.lock, flags);
> + }
> + }

This could be written with fewer indents using continue
(and maybe faster using ffs too)

for (i = 0; i < bdev->num_channels; i++) {
struct bam_chan *bchan;

if (!(srcs & BIT(i)))
continue;

bchan = &bdev->channels[i];

/* clear pipe irq */
pipe_stts = readl_relaxed(bdev->regs + BAM_P_IRQ_STTS(i));
writel_relaxed(pipe_stts, bdev->regs + BAM_P_IRQ_CLR(i));

etc...


--
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/