linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: vinod.koul@intel.com (Vinod Koul)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 6/6] dma: mmp_pdma: Add support externel DMA requests
Date: Fri, 2 May 2014 21:39:49 +0530	[thread overview]
Message-ID: <20140502160949.GX32284@intel.com> (raw)
In-Reply-To: <1397574817-15559-7-git-send-email-laurent.pinchart@ideasonboard.com>

On Tue, Apr 15, 2014 at 05:13:37PM +0200, Laurent Pinchart wrote:
> The MMP/PXA DMA engine supports transfer initiation by external chips
> through DMA request (DREQ) signals. Support them by clearing pending DMA
> requests for the associated source when starting a channel.
> 
> The request ID to DREQ index mapping depends on the hardware and is
> passed through platform data or DT.
> 
> Cc: devicetree at vger.kernel.org
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  Documentation/devicetree/bindings/dma/mmp-dma.txt |  2 +
>  drivers/dma/mmp_pdma.c                            | 96 ++++++++++++++++++++---
>  include/linux/platform_data/mmp_dma.h             |  2 +
>  3 files changed, 87 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/dma/mmp-dma.txt b/Documentation/devicetree/bindings/dma/mmp-dma.txt
> index 7a802f6..edb9ff3 100644
> --- a/Documentation/devicetree/bindings/dma/mmp-dma.txt
> +++ b/Documentation/devicetree/bindings/dma/mmp-dma.txt
> @@ -12,6 +12,8 @@ Required properties:
>  Optional properties:
>  - #dma-channels: Number of DMA channels supported by the controller (defaults
>    to 32 when not specified)
> +- marvell,dreq: Array of the DMA request IDs corresponding to each of the
> +  external device request (DREQ) lines
>  
>  "marvell,pdma-1.0"
>  Used platforms: pxa25x, pxa27x, pxa3xx, pxa93x, pxa168, pxa910, pxa688.
Can you please split the binding to separate patch and we need to get an ACK on
it from DT folks.

The below looks fine to me

-- 
~Vinod

> diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
> index 849bf75..4546a1c 100644
> --- a/drivers/dma/mmp_pdma.c
> +++ b/drivers/dma/mmp_pdma.c
> @@ -27,6 +27,7 @@
>  
>  #define DCSR		0x0000
>  #define DALGN		0x00a0
> +#define DRQSR(n)	(0x00e0 + ((n) << 2))
>  #define DINT		0x00f0
>  #define DDADR		0x0200
>  #define DSADR		0x0204
> @@ -50,6 +51,9 @@
>  #define DCSR_CMPST	BIT(10)	/* The Descriptor Compare Status */
>  #define DCSR_EORINTR	BIT(9)	/* The end of Receive */
>  
> +#define DRQSR_CLR	BIT(8)	/* Clear Pending Requests */
> +#define DRQSR_REQPEND	0x1f	/* Requests Pending */
> +
>  #define DRCMR(n)	((((n) < 64) ? 0x0100 : 0x1100) + (((n) & 0x3f) << 2))
>  #define DRCMR_MAPVLD	BIT(7)	/* Map Valid (read / write) */
>  #define DRCMR_CHLNUM	0x1f	/* mask for Channel Number (read / write) */
> @@ -108,6 +112,7 @@ struct mmp_pdma_chan {
>  	u32 dcmd;
>  	u32 drcmr;
>  	u32 dev_addr;
> +	int drq;
>  
>  	/* list for desc */
>  	spinlock_t desc_lock;		/* Descriptor list lock */
> @@ -127,6 +132,8 @@ struct mmp_pdma_phy {
>  
>  struct mmp_pdma_device {
>  	int				dma_channels;
> +	unsigned int			num_dreq;
> +	const u32			*dreq;
>  	void __iomem			*base;
>  	struct device			*dev;
>  	struct dma_device		device;
> @@ -167,6 +174,9 @@ static void enable_chan(struct mmp_pdma_phy *phy)
>  		dalgn &= ~(1 << phy->idx);
>  	writel(dalgn, phy->base + DALGN);
>  
> +	if (phy->vchan->drq != -1)
> +		writel(DRQSR_CLR, phy->base + DRQSR(phy->vchan->drq));
> +
>  	reg = (phy->idx << 2) + DCSR;
>  	writel(readl(phy->base + reg) | DCSR_RUN, phy->base + reg);
>  }
> @@ -685,6 +695,22 @@ fail:
>  	return NULL;
>  }
>  
> +static void mmp_pdma_set_drcmr(struct mmp_pdma_chan *chan, unsigned int drmcr)
> +{
> +	struct mmp_pdma_device *pdev = to_mmp_pdma_dev(cchan->chan.device);
> +	unsigned int i;
> +
> +	chan->drcmr = drmcr;
> +	chan->drq = -1;
> +
> +	for (i = 0; i < pdev->num_dreq; ++i) {
> +		if (pdev->dreq[i] == drmcr) {
> +			chan->drq = i;
> +			break;
> +		}
> +	}
> +}
> +
>  static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
>  			    unsigned long arg)
>  {
> @@ -745,7 +771,7 @@ static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
>  		 * be removed.
>  		 */
>  		if (cfg->slave_id)
> -			chan->drcmr = cfg->slave_id;
> +			mmp_pdma_set_drcmr(chan, cfg->slave_id);
>  		break;
>  	default:
>  		return -ENOSYS;
> @@ -909,16 +935,64 @@ static struct dma_chan *mmp_pdma_dma_xlate(struct of_phandle_args *dma_spec,
>  	if (!chan)
>  		return NULL;
>  
> -	to_mmp_pdma_chan(chan)->drcmr = dma_spec->args[0];
> +	mmp_pdma_set_drcmr(to_mmp_pdma_chan(chan), dma_spec->args[0]);
>  
>  	return chan;
>  }
>  
> +static int mmap_pdma_parse_platform_data(struct mmp_pdma_device *pdev)
> +{
> +	struct device_node *np = pdev->dev->of_node;
> +	struct property *prop;
> +
> +	/* Default values: 32 channels, no external DREQ. */
> +	pdev->dma_channels = 32;
> +	pdev->num_dreq = 0;
> +
> +	if (!IS_ENABLED(CONFIG_OF) || !np) {
> +		struct mmp_dma_platdata *pdata = dev_get_platdata(pdev->dev);
> +
> +		if (!pdata)
> +			return 0;
> +
> +		if (pdata->dma_channels)
> +			pdev->dma_channels = pdata->dma_channels;
> +		if (pdata->num_dreq) {
> +			pdev->num_dreq = pdata->num_dreq;
> +			pdev->dreq = pdata->dreq;
> +		}
> +
> +		return 0;
> +	}
> +
> +	of_property_read_u32(np, "#dma-channels", &pdev->dma_channels);
> +
> +	prop = of_find_property(np, "marvell,dreq");
> +	if (prop) {
> +		unsigned int num_dreq = prop->length / sizeof(unsigned long);
> +		u32 *dreq;
> +
> +		dreq = devm_kcalloc(pdev->dev, num_dreq, sizeof(*pdreq),
> +				    GFP_KERNEL);
> +		if (dreq == NULL)
> +			return -ENOMEM;
> +
> +		ret = of_property_read_u32_array(np, "marvell,dreq", dreq,
> +						 num_dreq);
> +		if (ret < 0)
> +			return ret;
> +
> +		pdev->num_dreq = num_dreq;
> +		pdev->dreq = dreq;
> +	}
> +
> +	return 0;
> +}
> +
>  static int mmp_pdma_probe(struct platform_device *op)
>  {
>  	struct mmp_pdma_device *pdev;
>  	const struct of_device_id *of_id;
> -	struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev);
>  	struct resource *iores;
>  	int i, ret, irq = 0;
>  	int dma_channels = 0, irq_num = 0;
> @@ -936,15 +1010,11 @@ static int mmp_pdma_probe(struct platform_device *op)
>  	if (IS_ERR(pdev->base))
>  		return PTR_ERR(pdev->base);
>  
> -	of_id = of_match_device(mmp_pdma_dt_ids, pdev->dev);
> -	if (of_id)
> -		of_property_read_u32(pdev->dev->of_node, "#dma-channels",
> -				     &dma_channels);
> -	else if (pdata && pdata->dma_channels)
> -		dma_channels = pdata->dma_channels;
> -	else
> -		dma_channels = 32;	/* default 32 channel */
> -	pdev->dma_channels = dma_channels;
> +	ret = mmp_pdma_parse_platform_data(pdev);
> +	if (ret < 0)
> +		return ret;
> +
> +	dma_channels = pdev->dma_channels;
>  
>  	for (i = 0; i < dma_channels; i++) {
>  		if (platform_get_irq(op, i) > 0)
> @@ -1038,7 +1108,7 @@ bool mmp_pdma_filter_fn(struct dma_chan *chan, void *param)
>  	if (chan->device->dev->driver != &mmp_pdma_driver.driver)
>  		return false;
>  
> -	c->drcmr = *(unsigned int *)param;
> +	mmp_pdma_set_drcmr(c, *(unsigned int *)param);
>  
>  	return true;
>  }
> diff --git a/include/linux/platform_data/mmp_dma.h b/include/linux/platform_data/mmp_dma.h
> index 2a330ec..32595b8 100644
> --- a/include/linux/platform_data/mmp_dma.h
> +++ b/include/linux/platform_data/mmp_dma.h
> @@ -14,6 +14,8 @@
>  
>  struct mmp_dma_platdata {
>  	int dma_channels;
> +	unsigned int num_dreq;
> +	const u32 *dreq;
>  };
>  
>  #endif /* MMP_DMA_H */
> -- 
> 1.8.3.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

      reply	other threads:[~2014-05-02 16:09 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-15 15:13 [PATCH 0/6] dma: mmp_pdma: fly-by transfers and external DMA requests support Laurent Pinchart
2014-04-15 15:13 ` [PATCH 1/6] dmaengine: Add fly-by transfer flag to slave configuration structure Laurent Pinchart
2014-05-02 15:46   ` Vinod Koul
2014-05-02 15:47     ` Vinod Koul
2014-05-05 17:26   ` Lars-Peter Clausen
2014-04-15 15:13 ` [PATCH 2/6] dma: mmp_pdma: Fix the #dma-channels DT property documentation Laurent Pinchart
2014-05-02 15:50   ` Vinod Koul
2014-04-15 15:13 ` [PATCH 3/6] dma: mmp_pdma: Simplify access to channel drcmr value Laurent Pinchart
2014-05-02 15:51   ` Vinod Koul
2014-04-15 15:13 ` [PATCH 4/6] dma: mmp_pdma: Fix physical channel memory allocation size Laurent Pinchart
2014-05-02 15:52   ` Vinod Koul
2014-04-15 15:13 ` [PATCH 5/6] dma: mmp_pdma: Add support for fly-by transfers Laurent Pinchart
2014-04-15 15:13 ` [PATCH 6/6] dma: mmp_pdma: Add support externel DMA requests Laurent Pinchart
2014-05-02 16:09   ` Vinod Koul [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140502160949.GX32284@intel.com \
    --to=vinod.koul@intel.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).