All of lore.kernel.org
 help / color / mirror / Atom feed
From: vinod.koul@intel.com (Vinod Koul)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 2/2] dmaengine: Add hisilicon k3 DMA engine driver
Date: Tue, 13 Aug 2013 16:50:43 +0530	[thread overview]
Message-ID: <20130813112043.GB32147@intel.com> (raw)
In-Reply-To: <1372423153-6742-3-git-send-email-zhangfei.gao@linaro.org>

On Fri, Jun 28, 2013 at 08:39:13PM +0800, Zhangfei Gao wrote:
> Add dmaengine driver for hisilicon k3 platform based on virt_dma
> 
> Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
> Tested-by: Kai Yang <jean.yangkai@huawei.com>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> ---

> +#define DRIVER_NAME		"k3-dma"
> +#define DMA_ALIGN		3
> +#define DMA_MAX_SIZE		0x1ffc
> +
> +#define INT_STAT		0x00
> +#define INT_TC1			0x04
> +#define INT_ERR1		0x0c
> +#define INT_ERR2		0x10
> +#define INT_TC1_MASK		0x18
> +#define INT_ERR1_MASK		0x20
> +#define INT_ERR2_MASK		0x24
> +#define INT_TC1_RAW		0x600
> +#define INT_ERR1_RAW		0x608
> +#define INT_ERR2_RAW		0x610
> +#define CH_PRI			0x688
> +#define CH_STAT			0x690
> +#define CX_CUR_CNT		0x704
> +#define CX_LLI			0x800
> +#define CX_CNT			0x810
> +#define CX_SRC			0x814
> +#define CX_DST			0x818
> +#define CX_CONFIG		0x81c
> +#define AXI_CONFIG		0x820
> +#define DEF_AXI_CONFIG		0x201201
> +
> +#define CX_LLI_CHAIN_EN		0x2
> +#define CCFG_EN			0x1
> +#define CCFG_MEM2PER		(0x1 << 2)
> +#define CCFG_PER2MEM		(0x2 << 2)
> +#define CCFG_SRCINCR		(0x1 << 31)
> +#define CCFG_DSTINCR		(0x1 << 30)
I see these are not namespace aptly and can collide..

> +static int k3_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
> +	unsigned long arg)
> +{
> +	struct k3_dma_chan *c = to_k3_chan(chan);
> +	struct k3_dma_dev *d = to_k3_dma(chan->device);
> +	struct dma_slave_config *cfg = (void *)arg;
> +	struct k3_dma_phy *p = NULL;
> +	unsigned long flags;
> +	u32 maxburst = 0, val = 0;
> +	enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
> +	LIST_HEAD(head);
> +
> +	if (c)
> +		p = c->phy;
> +
> +	switch (cmd) {
> +	case DMA_SLAVE_CONFIG:
> +		if (cfg == NULL)
> +			return -EINVAL;
> +		c->dir = cfg->direction;
> +		if (c->dir == DMA_DEV_TO_MEM) {
> +			c->ccfg = CCFG_DSTINCR;
> +			c->dev_addr = cfg->src_addr;
> +			maxburst = cfg->src_maxburst;
> +			width = cfg->src_addr_width;
> +		} else if (c->dir == DMA_MEM_TO_DEV) {
> +			c->ccfg = CCFG_SRCINCR;
> +			c->dev_addr = cfg->dst_addr;
> +			maxburst = cfg->dst_maxburst;
> +			width = cfg->dst_addr_width;
> +		}
> +		switch (width) {
> +		case DMA_SLAVE_BUSWIDTH_1_BYTE:
> +			val = 0;
> +			break;
> +		case DMA_SLAVE_BUSWIDTH_2_BYTES:
> +			val = 1;
> +			break;
> +		case DMA_SLAVE_BUSWIDTH_4_BYTES:
> +			val = 2;
> +			break;
> +		case DMA_SLAVE_BUSWIDTH_8_BYTES:
> +			val = 3;
DMA_SLAVE_BUSWIDTHS are 1, 2, 4, 8...
so if you can do val = ffs(width) as well?


> +	case DMA_PAUSE:
> +		dev_dbg(d->slave.dev, "vchan %p: pause\n", &c->vc);
> +		if (c->status == DMA_IN_PROGRESS) {
> +			c->status = DMA_PAUSED;
> +			if (p) {
> +				k3_dma_pause_dma(p, false);
> +			} else {
> +				spin_lock(&d->lock);
> +				list_del_init(&c->node);
> +				spin_unlock(&d->lock);
> +			}
why do we need the else part here?

> +		}
> +		break;
> +
> +	case DMA_RESUME:
> +		dev_dbg(d->slave.dev, "vchan %p: resume\n", &c->vc);
> +		spin_lock_irqsave(&c->vc.lock, flags);
> +		if (c->status == DMA_PAUSED) {
> +			c->status = DMA_IN_PROGRESS;
> +			if (p) {
> +				k3_dma_pause_dma(p, true);
> +			} else if (!list_empty(&c->vc.desc_issued)) {
> +				spin_lock(&d->lock);
> +				list_add_tail(&c->node, &d->chan_pending);
> +				spin_unlock(&d->lock);
> +			}
ditto?

> +		}
> +		spin_unlock_irqrestore(&c->vc.lock, flags);
> +		break;
> +	default:
> +		return -ENXIO;
> +	}
> +	return 0;
> +}
> +

> +
> +#ifdef CONFIG_PM_SLEEP
> +static int k3_dma_pltfm_suspend(struct device *dev)
> +{
> +	struct k3_dma_dev *d = dev_get_drvdata(dev);
> +	u32 stat = 0;
> +
> +	stat = k3_dma_get_chan_stat(d);
> +	if (stat) {
> +		dev_warn(d->slave.dev,
> +			"chan %d is running fail to suspend\n", stat);
> +		return -1;
> +	}
> +	k3_dma_enable_dma(d, false);
> +	clk_disable_unprepare(d->clk);
> +	return 0;
> +}
> +
> +static int k3_dma_pltfm_resume(struct device *dev)
> +{
> +	struct k3_dma_dev *d = dev_get_drvdata(dev);
> +	int ret = 0;
> +
> +	ret = clk_prepare_enable(d->clk);
> +	if (ret < 0) {
> +		dev_err(d->slave.dev, "clk_prepare_enable failed: %d\n", ret);
> +		return -EINVAL;
> +	}
> +	k3_dma_enable_dma(d, true);
> +	return 0;
> +}
> +#else
> +#define k3_dma_pltfm_suspend	NULL
> +#define k3_dma_pltfm_resume	NULL
> +#endif /* CONFIG_PM_SLEEP */
you dont need #ifdef here, then whats the use of SIMPLE_DEV_PM_OPS below?
> +
> +SIMPLE_DEV_PM_OPS(k3_dma_pltfm_pmops, k3_dma_pltfm_suspend, k3_dma_pltfm_resume);
pltfm... can we skip this or use platform, plat...
> +
> +static struct platform_driver k3_pdma_driver = {
> +	.driver		= {
> +		.name	= DRIVER_NAME,
> +		.owner  = THIS_MODULE,
> +		.pm	= &k3_dma_pltfm_pmops,
> +		.of_match_table = k3_pdma_dt_ids,
> +	},
> +	.probe		= k3_dma_probe,
> +	.remove		= k3_dma_remove,
> +};
> +
> +module_platform_driver(k3_pdma_driver);
> +
> +MODULE_DESCRIPTION("Hisilicon k3 DMA Driver");
> +MODULE_LICENSE("GPL v2");
MODULE_ALIAS?

~Vinod

  reply	other threads:[~2013-08-13 11:20 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-28 12:39 [PATCH v2 0/2] dmaengine: add k3dma Zhangfei Gao
2013-06-28 12:39 ` [PATCH v2 1/2] dmaengine: add interface of dma_get_slave_channel Zhangfei Gao
2013-06-28 14:32   ` Arnd Bergmann
2013-08-13 11:04   ` Vinod Koul
2013-06-28 12:39 ` [PATCH v2 2/2] dmaengine: Add hisilicon k3 DMA engine driver Zhangfei Gao
2013-08-13 11:20   ` Vinod Koul [this message]
2013-08-15  5:54     ` zhangfei gao
2013-08-19  5:35       ` Vinod Koul
2013-08-20  7:55         ` zhangfei gao
2013-08-20  8:27           ` Vinod Koul
2013-08-20  9:23             ` zhangfei
2013-08-20  8:50               ` Vinod Koul
2013-08-20 13:36                 ` zhangfei gao
2013-08-21  4:58                   ` Vinod Koul
2013-08-21  8:02                     ` zhangfei gao
2013-08-25  9:14                       ` Vinod Koul
2013-08-22  1:39                     ` zhangfei gao

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=20130813112043.GB32147@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 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.