xref: /openbmc/linux/drivers/dma/sh/rz-dmac.c (revision c6ec8c83)
15000d370SBiju Das // SPDX-License-Identifier: GPL-2.0
25000d370SBiju Das /*
35000d370SBiju Das  * Renesas RZ/G2L DMA Controller Driver
45000d370SBiju Das  *
55000d370SBiju Das  * Based on imx-dma.c
65000d370SBiju Das  *
75000d370SBiju Das  * Copyright (C) 2021 Renesas Electronics Corp.
85000d370SBiju Das  * Copyright 2010 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
95000d370SBiju Das  * Copyright 2012 Javier Martin, Vista Silicon <javier.martin@vista-silicon.com>
105000d370SBiju Das  */
115000d370SBiju Das 
12*c6ec8c83SHien Huynh #include <linux/bitfield.h>
135000d370SBiju Das #include <linux/dma-mapping.h>
145000d370SBiju Das #include <linux/dmaengine.h>
155000d370SBiju Das #include <linux/interrupt.h>
167d3a3aaaSBiju Das #include <linux/iopoll.h>
175000d370SBiju Das #include <linux/list.h>
185000d370SBiju Das #include <linux/module.h>
195000d370SBiju Das #include <linux/of.h>
205000d370SBiju Das #include <linux/of_dma.h>
215000d370SBiju Das #include <linux/of_platform.h>
225000d370SBiju Das #include <linux/platform_device.h>
23161596fdSBiju Das #include <linux/pm_runtime.h>
24d1e71a3aSBiju Das #include <linux/reset.h>
255000d370SBiju Das #include <linux/slab.h>
265000d370SBiju Das #include <linux/spinlock.h>
275000d370SBiju Das 
285000d370SBiju Das #include "../dmaengine.h"
295000d370SBiju Das #include "../virt-dma.h"
305000d370SBiju Das 
315000d370SBiju Das enum  rz_dmac_prep_type {
325000d370SBiju Das 	RZ_DMAC_DESC_MEMCPY,
335000d370SBiju Das 	RZ_DMAC_DESC_SLAVE_SG,
345000d370SBiju Das };
355000d370SBiju Das 
365000d370SBiju Das struct rz_lmdesc {
375000d370SBiju Das 	u32 header;
385000d370SBiju Das 	u32 sa;
395000d370SBiju Das 	u32 da;
405000d370SBiju Das 	u32 tb;
415000d370SBiju Das 	u32 chcfg;
425000d370SBiju Das 	u32 chitvl;
435000d370SBiju Das 	u32 chext;
445000d370SBiju Das 	u32 nxla;
455000d370SBiju Das };
465000d370SBiju Das 
475000d370SBiju Das struct rz_dmac_desc {
485000d370SBiju Das 	struct virt_dma_desc vd;
495000d370SBiju Das 	dma_addr_t src;
505000d370SBiju Das 	dma_addr_t dest;
515000d370SBiju Das 	size_t len;
525000d370SBiju Das 	struct list_head node;
535000d370SBiju Das 	enum dma_transfer_direction direction;
545000d370SBiju Das 	enum rz_dmac_prep_type type;
555000d370SBiju Das 	/* For slave sg */
565000d370SBiju Das 	struct scatterlist *sg;
575000d370SBiju Das 	unsigned int sgcount;
585000d370SBiju Das };
595000d370SBiju Das 
605000d370SBiju Das #define to_rz_dmac_desc(d)	container_of(d, struct rz_dmac_desc, vd)
615000d370SBiju Das 
625000d370SBiju Das struct rz_dmac_chan {
635000d370SBiju Das 	struct virt_dma_chan vc;
645000d370SBiju Das 	void __iomem *ch_base;
655000d370SBiju Das 	void __iomem *ch_cmn_base;
665000d370SBiju Das 	unsigned int index;
675000d370SBiju Das 	int irq;
685000d370SBiju Das 	struct rz_dmac_desc *desc;
695000d370SBiju Das 	int descs_allocated;
705000d370SBiju Das 
715000d370SBiju Das 	dma_addr_t src_per_address;
725000d370SBiju Das 	dma_addr_t dst_per_address;
735000d370SBiju Das 
745000d370SBiju Das 	u32 chcfg;
755000d370SBiju Das 	u32 chctrl;
765000d370SBiju Das 	int mid_rid;
775000d370SBiju Das 
785000d370SBiju Das 	struct list_head ld_free;
795000d370SBiju Das 	struct list_head ld_queue;
805000d370SBiju Das 	struct list_head ld_active;
815000d370SBiju Das 
825000d370SBiju Das 	struct {
835000d370SBiju Das 		struct rz_lmdesc *base;
845000d370SBiju Das 		struct rz_lmdesc *head;
855000d370SBiju Das 		struct rz_lmdesc *tail;
865000d370SBiju Das 		dma_addr_t base_dma;
875000d370SBiju Das 	} lmdesc;
885000d370SBiju Das };
895000d370SBiju Das 
905000d370SBiju Das #define to_rz_dmac_chan(c)	container_of(c, struct rz_dmac_chan, vc.chan)
915000d370SBiju Das 
925000d370SBiju Das struct rz_dmac {
935000d370SBiju Das 	struct dma_device engine;
945000d370SBiju Das 	struct device *dev;
95d1e71a3aSBiju Das 	struct reset_control *rstc;
965000d370SBiju Das 	void __iomem *base;
975000d370SBiju Das 	void __iomem *ext_base;
985000d370SBiju Das 
995000d370SBiju Das 	unsigned int n_channels;
1005000d370SBiju Das 	struct rz_dmac_chan *channels;
1015000d370SBiju Das 
1025000d370SBiju Das 	DECLARE_BITMAP(modules, 1024);
1035000d370SBiju Das };
1045000d370SBiju Das 
1055000d370SBiju Das #define to_rz_dmac(d)	container_of(d, struct rz_dmac, engine)
1065000d370SBiju Das 
1075000d370SBiju Das /*
1085000d370SBiju Das  * -----------------------------------------------------------------------------
1095000d370SBiju Das  * Registers
1105000d370SBiju Das  */
1115000d370SBiju Das 
1125000d370SBiju Das #define CHSTAT				0x0024
1135000d370SBiju Das #define CHCTRL				0x0028
1145000d370SBiju Das #define CHCFG				0x002c
1155000d370SBiju Das #define NXLA				0x0038
1165000d370SBiju Das 
1175000d370SBiju Das #define DCTRL				0x0000
1185000d370SBiju Das 
1195000d370SBiju Das #define EACH_CHANNEL_OFFSET		0x0040
1205000d370SBiju Das #define CHANNEL_0_7_OFFSET		0x0000
1215000d370SBiju Das #define CHANNEL_0_7_COMMON_BASE		0x0300
1225000d370SBiju Das #define CHANNEL_8_15_OFFSET		0x0400
1235000d370SBiju Das #define CHANNEL_8_15_COMMON_BASE	0x0700
1245000d370SBiju Das 
1255000d370SBiju Das #define CHSTAT_ER			BIT(4)
1265000d370SBiju Das #define CHSTAT_EN			BIT(0)
1275000d370SBiju Das 
1285000d370SBiju Das #define CHCTRL_CLRINTMSK		BIT(17)
1295000d370SBiju Das #define CHCTRL_CLRSUS			BIT(9)
1305000d370SBiju Das #define CHCTRL_CLRTC			BIT(6)
1315000d370SBiju Das #define CHCTRL_CLREND			BIT(5)
1325000d370SBiju Das #define CHCTRL_CLRRQ			BIT(4)
1335000d370SBiju Das #define CHCTRL_SWRST			BIT(3)
1345000d370SBiju Das #define CHCTRL_STG			BIT(2)
1355000d370SBiju Das #define CHCTRL_CLREN			BIT(1)
1365000d370SBiju Das #define CHCTRL_SETEN			BIT(0)
1375000d370SBiju Das #define CHCTRL_DEFAULT			(CHCTRL_CLRINTMSK | CHCTRL_CLRSUS | \
1385000d370SBiju Das 					 CHCTRL_CLRTC |	CHCTRL_CLREND | \
1395000d370SBiju Das 					 CHCTRL_CLRRQ | CHCTRL_SWRST | \
1405000d370SBiju Das 					 CHCTRL_CLREN)
1415000d370SBiju Das 
1425000d370SBiju Das #define CHCFG_DMS			BIT(31)
1435000d370SBiju Das #define CHCFG_DEM			BIT(24)
1445000d370SBiju Das #define CHCFG_DAD			BIT(21)
1455000d370SBiju Das #define CHCFG_SAD			BIT(20)
1465000d370SBiju Das #define CHCFG_REQD			BIT(3)
1475000d370SBiju Das #define CHCFG_SEL(bits)			((bits) & 0x07)
1485000d370SBiju Das #define CHCFG_MEM_COPY			(0x80400008)
149*c6ec8c83SHien Huynh #define CHCFG_FILL_DDS_MASK		GENMASK(19, 16)
150*c6ec8c83SHien Huynh #define CHCFG_FILL_SDS_MASK		GENMASK(15, 12)
1515000d370SBiju Das #define CHCFG_FILL_TM(a)		(((a) & BIT(5)) << 22)
1525000d370SBiju Das #define CHCFG_FILL_AM(a)		(((a) & GENMASK(4, 2)) << 6)
1535000d370SBiju Das #define CHCFG_FILL_LVL(a)		(((a) & BIT(1)) << 5)
1545000d370SBiju Das #define CHCFG_FILL_HIEN(a)		(((a) & BIT(0)) << 5)
1555000d370SBiju Das 
1565000d370SBiju Das #define MID_RID_MASK			GENMASK(9, 0)
1575000d370SBiju Das #define CHCFG_MASK			GENMASK(15, 10)
1585000d370SBiju Das #define CHCFG_DS_INVALID		0xFF
1595000d370SBiju Das #define DCTRL_LVINT			BIT(1)
1605000d370SBiju Das #define DCTRL_PR			BIT(0)
1615000d370SBiju Das #define DCTRL_DEFAULT			(DCTRL_LVINT | DCTRL_PR)
1625000d370SBiju Das 
1635000d370SBiju Das /* LINK MODE DESCRIPTOR */
1645000d370SBiju Das #define HEADER_LV			BIT(0)
1655000d370SBiju Das 
1665000d370SBiju Das #define RZ_DMAC_MAX_CHAN_DESCRIPTORS	16
1675000d370SBiju Das #define RZ_DMAC_MAX_CHANNELS		16
1685000d370SBiju Das #define DMAC_NR_LMDESC			64
1695000d370SBiju Das 
1705000d370SBiju Das /*
1715000d370SBiju Das  * -----------------------------------------------------------------------------
1725000d370SBiju Das  * Device access
1735000d370SBiju Das  */
1745000d370SBiju Das 
rz_dmac_writel(struct rz_dmac * dmac,unsigned int val,unsigned int offset)1755000d370SBiju Das static void rz_dmac_writel(struct rz_dmac *dmac, unsigned int val,
1765000d370SBiju Das 			   unsigned int offset)
1775000d370SBiju Das {
1785000d370SBiju Das 	writel(val, dmac->base + offset);
1795000d370SBiju Das }
1805000d370SBiju Das 
rz_dmac_ext_writel(struct rz_dmac * dmac,unsigned int val,unsigned int offset)1815000d370SBiju Das static void rz_dmac_ext_writel(struct rz_dmac *dmac, unsigned int val,
1825000d370SBiju Das 			       unsigned int offset)
1835000d370SBiju Das {
1845000d370SBiju Das 	writel(val, dmac->ext_base + offset);
1855000d370SBiju Das }
1865000d370SBiju Das 
rz_dmac_ext_readl(struct rz_dmac * dmac,unsigned int offset)1875000d370SBiju Das static u32 rz_dmac_ext_readl(struct rz_dmac *dmac, unsigned int offset)
1885000d370SBiju Das {
1895000d370SBiju Das 	return readl(dmac->ext_base + offset);
1905000d370SBiju Das }
1915000d370SBiju Das 
rz_dmac_ch_writel(struct rz_dmac_chan * channel,unsigned int val,unsigned int offset,int which)1925000d370SBiju Das static void rz_dmac_ch_writel(struct rz_dmac_chan *channel, unsigned int val,
1935000d370SBiju Das 			      unsigned int offset, int which)
1945000d370SBiju Das {
1955000d370SBiju Das 	if (which)
1965000d370SBiju Das 		writel(val, channel->ch_base + offset);
1975000d370SBiju Das 	else
1985000d370SBiju Das 		writel(val, channel->ch_cmn_base + offset);
1995000d370SBiju Das }
2005000d370SBiju Das 
rz_dmac_ch_readl(struct rz_dmac_chan * channel,unsigned int offset,int which)2015000d370SBiju Das static u32 rz_dmac_ch_readl(struct rz_dmac_chan *channel,
2025000d370SBiju Das 			    unsigned int offset, int which)
2035000d370SBiju Das {
2045000d370SBiju Das 	if (which)
2055000d370SBiju Das 		return readl(channel->ch_base + offset);
2065000d370SBiju Das 	else
2075000d370SBiju Das 		return readl(channel->ch_cmn_base + offset);
2085000d370SBiju Das }
2095000d370SBiju Das 
2105000d370SBiju Das /*
2115000d370SBiju Das  * -----------------------------------------------------------------------------
2125000d370SBiju Das  * Initialization
2135000d370SBiju Das  */
2145000d370SBiju Das 
rz_lmdesc_setup(struct rz_dmac_chan * channel,struct rz_lmdesc * lmdesc)2155000d370SBiju Das static void rz_lmdesc_setup(struct rz_dmac_chan *channel,
2165000d370SBiju Das 			    struct rz_lmdesc *lmdesc)
2175000d370SBiju Das {
2185000d370SBiju Das 	u32 nxla;
2195000d370SBiju Das 
2205000d370SBiju Das 	channel->lmdesc.base = lmdesc;
2215000d370SBiju Das 	channel->lmdesc.head = lmdesc;
2225000d370SBiju Das 	channel->lmdesc.tail = lmdesc;
2235000d370SBiju Das 	nxla = channel->lmdesc.base_dma;
2245000d370SBiju Das 	while (lmdesc < (channel->lmdesc.base + (DMAC_NR_LMDESC - 1))) {
2255000d370SBiju Das 		lmdesc->header = 0;
2265000d370SBiju Das 		nxla += sizeof(*lmdesc);
2275000d370SBiju Das 		lmdesc->nxla = nxla;
2285000d370SBiju Das 		lmdesc++;
2295000d370SBiju Das 	}
2305000d370SBiju Das 
2315000d370SBiju Das 	lmdesc->header = 0;
2325000d370SBiju Das 	lmdesc->nxla = channel->lmdesc.base_dma;
2335000d370SBiju Das }
2345000d370SBiju Das 
2355000d370SBiju Das /*
2365000d370SBiju Das  * -----------------------------------------------------------------------------
2375000d370SBiju Das  * Descriptors preparation
2385000d370SBiju Das  */
2395000d370SBiju Das 
rz_dmac_lmdesc_recycle(struct rz_dmac_chan * channel)2405000d370SBiju Das static void rz_dmac_lmdesc_recycle(struct rz_dmac_chan *channel)
2415000d370SBiju Das {
2425000d370SBiju Das 	struct rz_lmdesc *lmdesc = channel->lmdesc.head;
2435000d370SBiju Das 
2445000d370SBiju Das 	while (!(lmdesc->header & HEADER_LV)) {
2455000d370SBiju Das 		lmdesc->header = 0;
2465000d370SBiju Das 		lmdesc++;
2475000d370SBiju Das 		if (lmdesc >= (channel->lmdesc.base + DMAC_NR_LMDESC))
2485000d370SBiju Das 			lmdesc = channel->lmdesc.base;
2495000d370SBiju Das 	}
2505000d370SBiju Das 	channel->lmdesc.head = lmdesc;
2515000d370SBiju Das }
2525000d370SBiju Das 
rz_dmac_enable_hw(struct rz_dmac_chan * channel)2535000d370SBiju Das static void rz_dmac_enable_hw(struct rz_dmac_chan *channel)
2545000d370SBiju Das {
2555000d370SBiju Das 	struct dma_chan *chan = &channel->vc.chan;
2565000d370SBiju Das 	struct rz_dmac *dmac = to_rz_dmac(chan->device);
2575000d370SBiju Das 	unsigned long flags;
2585000d370SBiju Das 	u32 nxla;
2595000d370SBiju Das 	u32 chctrl;
2605000d370SBiju Das 	u32 chstat;
2615000d370SBiju Das 
2625000d370SBiju Das 	dev_dbg(dmac->dev, "%s channel %d\n", __func__, channel->index);
2635000d370SBiju Das 
2645000d370SBiju Das 	local_irq_save(flags);
2655000d370SBiju Das 
2665000d370SBiju Das 	rz_dmac_lmdesc_recycle(channel);
2675000d370SBiju Das 
2685000d370SBiju Das 	nxla = channel->lmdesc.base_dma +
2695000d370SBiju Das 		(sizeof(struct rz_lmdesc) * (channel->lmdesc.head -
2705000d370SBiju Das 					     channel->lmdesc.base));
2715000d370SBiju Das 
2725000d370SBiju Das 	chstat = rz_dmac_ch_readl(channel, CHSTAT, 1);
2735000d370SBiju Das 	if (!(chstat & CHSTAT_EN)) {
2745000d370SBiju Das 		chctrl = (channel->chctrl | CHCTRL_SETEN);
2755000d370SBiju Das 		rz_dmac_ch_writel(channel, nxla, NXLA, 1);
2765000d370SBiju Das 		rz_dmac_ch_writel(channel, channel->chcfg, CHCFG, 1);
2775000d370SBiju Das 		rz_dmac_ch_writel(channel, CHCTRL_SWRST, CHCTRL, 1);
2785000d370SBiju Das 		rz_dmac_ch_writel(channel, chctrl, CHCTRL, 1);
2795000d370SBiju Das 	}
2805000d370SBiju Das 
2815000d370SBiju Das 	local_irq_restore(flags);
2825000d370SBiju Das }
2835000d370SBiju Das 
rz_dmac_disable_hw(struct rz_dmac_chan * channel)2845000d370SBiju Das static void rz_dmac_disable_hw(struct rz_dmac_chan *channel)
2855000d370SBiju Das {
2865000d370SBiju Das 	struct dma_chan *chan = &channel->vc.chan;
2875000d370SBiju Das 	struct rz_dmac *dmac = to_rz_dmac(chan->device);
2885000d370SBiju Das 	unsigned long flags;
2895000d370SBiju Das 
2905000d370SBiju Das 	dev_dbg(dmac->dev, "%s channel %d\n", __func__, channel->index);
2915000d370SBiju Das 
2925000d370SBiju Das 	local_irq_save(flags);
2935000d370SBiju Das 	rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1);
2945000d370SBiju Das 	local_irq_restore(flags);
2955000d370SBiju Das }
2965000d370SBiju Das 
rz_dmac_set_dmars_register(struct rz_dmac * dmac,int nr,u32 dmars)2975000d370SBiju Das static void rz_dmac_set_dmars_register(struct rz_dmac *dmac, int nr, u32 dmars)
2985000d370SBiju Das {
2995000d370SBiju Das 	u32 dmars_offset = (nr / 2) * 4;
3005000d370SBiju Das 	u32 shift = (nr % 2) * 16;
3015000d370SBiju Das 	u32 dmars32;
3025000d370SBiju Das 
3035000d370SBiju Das 	dmars32 = rz_dmac_ext_readl(dmac, dmars_offset);
3045000d370SBiju Das 	dmars32 &= ~(0xffff << shift);
3055000d370SBiju Das 	dmars32 |= dmars << shift;
3065000d370SBiju Das 
3075000d370SBiju Das 	rz_dmac_ext_writel(dmac, dmars32, dmars_offset);
3085000d370SBiju Das }
3095000d370SBiju Das 
rz_dmac_prepare_desc_for_memcpy(struct rz_dmac_chan * channel)3105000d370SBiju Das static void rz_dmac_prepare_desc_for_memcpy(struct rz_dmac_chan *channel)
3115000d370SBiju Das {
3125000d370SBiju Das 	struct dma_chan *chan = &channel->vc.chan;
3135000d370SBiju Das 	struct rz_dmac *dmac = to_rz_dmac(chan->device);
3141e008336SColin Ian King 	struct rz_lmdesc *lmdesc = channel->lmdesc.tail;
3155000d370SBiju Das 	struct rz_dmac_desc *d = channel->desc;
3165000d370SBiju Das 	u32 chcfg = CHCFG_MEM_COPY;
3175000d370SBiju Das 
3185000d370SBiju Das 	/* prepare descriptor */
3195000d370SBiju Das 	lmdesc->sa = d->src;
3205000d370SBiju Das 	lmdesc->da = d->dest;
3215000d370SBiju Das 	lmdesc->tb = d->len;
3225000d370SBiju Das 	lmdesc->chcfg = chcfg;
3235000d370SBiju Das 	lmdesc->chitvl = 0;
3245000d370SBiju Das 	lmdesc->chext = 0;
3255000d370SBiju Das 	lmdesc->header = HEADER_LV;
3265000d370SBiju Das 
3275000d370SBiju Das 	rz_dmac_set_dmars_register(dmac, channel->index, 0);
3285000d370SBiju Das 
3295000d370SBiju Das 	channel->chcfg = chcfg;
3305000d370SBiju Das 	channel->chctrl = CHCTRL_STG | CHCTRL_SETEN;
3315000d370SBiju Das }
3325000d370SBiju Das 
rz_dmac_prepare_descs_for_slave_sg(struct rz_dmac_chan * channel)3335000d370SBiju Das static void rz_dmac_prepare_descs_for_slave_sg(struct rz_dmac_chan *channel)
3345000d370SBiju Das {
3355000d370SBiju Das 	struct dma_chan *chan = &channel->vc.chan;
3365000d370SBiju Das 	struct rz_dmac *dmac = to_rz_dmac(chan->device);
3375000d370SBiju Das 	struct rz_dmac_desc *d = channel->desc;
3385000d370SBiju Das 	struct scatterlist *sg, *sgl = d->sg;
3395000d370SBiju Das 	struct rz_lmdesc *lmdesc;
3405000d370SBiju Das 	unsigned int i, sg_len = d->sgcount;
3415000d370SBiju Das 
3425000d370SBiju Das 	channel->chcfg |= CHCFG_SEL(channel->index) | CHCFG_DEM | CHCFG_DMS;
3435000d370SBiju Das 
3445000d370SBiju Das 	if (d->direction == DMA_DEV_TO_MEM) {
3455000d370SBiju Das 		channel->chcfg |= CHCFG_SAD;
3465000d370SBiju Das 		channel->chcfg &= ~CHCFG_REQD;
3475000d370SBiju Das 	} else {
3485000d370SBiju Das 		channel->chcfg |= CHCFG_DAD | CHCFG_REQD;
3495000d370SBiju Das 	}
3505000d370SBiju Das 
3515000d370SBiju Das 	lmdesc = channel->lmdesc.tail;
3525000d370SBiju Das 
3535000d370SBiju Das 	for (i = 0, sg = sgl; i < sg_len; i++, sg = sg_next(sg)) {
3545000d370SBiju Das 		if (d->direction == DMA_DEV_TO_MEM) {
3555000d370SBiju Das 			lmdesc->sa = channel->src_per_address;
3565000d370SBiju Das 			lmdesc->da = sg_dma_address(sg);
3575000d370SBiju Das 		} else {
3585000d370SBiju Das 			lmdesc->sa = sg_dma_address(sg);
3595000d370SBiju Das 			lmdesc->da = channel->dst_per_address;
3605000d370SBiju Das 		}
3615000d370SBiju Das 
3625000d370SBiju Das 		lmdesc->tb = sg_dma_len(sg);
3635000d370SBiju Das 		lmdesc->chitvl = 0;
3645000d370SBiju Das 		lmdesc->chext = 0;
3655000d370SBiju Das 		if (i == (sg_len - 1)) {
3665000d370SBiju Das 			lmdesc->chcfg = (channel->chcfg & ~CHCFG_DEM);
3675000d370SBiju Das 			lmdesc->header = HEADER_LV;
3685000d370SBiju Das 		} else {
3695000d370SBiju Das 			lmdesc->chcfg = channel->chcfg;
3705000d370SBiju Das 			lmdesc->header = HEADER_LV;
3715000d370SBiju Das 		}
3725000d370SBiju Das 		if (++lmdesc >= (channel->lmdesc.base + DMAC_NR_LMDESC))
3735000d370SBiju Das 			lmdesc = channel->lmdesc.base;
3745000d370SBiju Das 	}
3755000d370SBiju Das 
3765000d370SBiju Das 	channel->lmdesc.tail = lmdesc;
3775000d370SBiju Das 
3785000d370SBiju Das 	rz_dmac_set_dmars_register(dmac, channel->index, channel->mid_rid);
3795000d370SBiju Das 	channel->chctrl = CHCTRL_SETEN;
3805000d370SBiju Das }
3815000d370SBiju Das 
rz_dmac_xfer_desc(struct rz_dmac_chan * chan)3825000d370SBiju Das static int rz_dmac_xfer_desc(struct rz_dmac_chan *chan)
3835000d370SBiju Das {
3845000d370SBiju Das 	struct rz_dmac_desc *d = chan->desc;
3855000d370SBiju Das 	struct virt_dma_desc *vd;
3865000d370SBiju Das 
3875000d370SBiju Das 	vd = vchan_next_desc(&chan->vc);
3885000d370SBiju Das 	if (!vd)
3895000d370SBiju Das 		return 0;
3905000d370SBiju Das 
3915000d370SBiju Das 	list_del(&vd->node);
3925000d370SBiju Das 
3935000d370SBiju Das 	switch (d->type) {
3945000d370SBiju Das 	case RZ_DMAC_DESC_MEMCPY:
3955000d370SBiju Das 		rz_dmac_prepare_desc_for_memcpy(chan);
3965000d370SBiju Das 		break;
3975000d370SBiju Das 
3985000d370SBiju Das 	case RZ_DMAC_DESC_SLAVE_SG:
3995000d370SBiju Das 		rz_dmac_prepare_descs_for_slave_sg(chan);
4005000d370SBiju Das 		break;
4015000d370SBiju Das 
4025000d370SBiju Das 	default:
4035000d370SBiju Das 		return -EINVAL;
4045000d370SBiju Das 	}
4055000d370SBiju Das 
4065000d370SBiju Das 	rz_dmac_enable_hw(chan);
4075000d370SBiju Das 
4085000d370SBiju Das 	return 0;
4095000d370SBiju Das }
4105000d370SBiju Das 
4115000d370SBiju Das /*
4125000d370SBiju Das  * -----------------------------------------------------------------------------
4135000d370SBiju Das  * DMA engine operations
4145000d370SBiju Das  */
4155000d370SBiju Das 
rz_dmac_alloc_chan_resources(struct dma_chan * chan)4165000d370SBiju Das static int rz_dmac_alloc_chan_resources(struct dma_chan *chan)
4175000d370SBiju Das {
4185000d370SBiju Das 	struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
4195000d370SBiju Das 
4205000d370SBiju Das 	while (channel->descs_allocated < RZ_DMAC_MAX_CHAN_DESCRIPTORS) {
4215000d370SBiju Das 		struct rz_dmac_desc *desc;
4225000d370SBiju Das 
4235000d370SBiju Das 		desc = kzalloc(sizeof(*desc), GFP_KERNEL);
4245000d370SBiju Das 		if (!desc)
4255000d370SBiju Das 			break;
4265000d370SBiju Das 
4275000d370SBiju Das 		list_add_tail(&desc->node, &channel->ld_free);
4285000d370SBiju Das 		channel->descs_allocated++;
4295000d370SBiju Das 	}
4305000d370SBiju Das 
4315000d370SBiju Das 	if (!channel->descs_allocated)
4325000d370SBiju Das 		return -ENOMEM;
4335000d370SBiju Das 
4345000d370SBiju Das 	return channel->descs_allocated;
4355000d370SBiju Das }
4365000d370SBiju Das 
rz_dmac_free_chan_resources(struct dma_chan * chan)4375000d370SBiju Das static void rz_dmac_free_chan_resources(struct dma_chan *chan)
4385000d370SBiju Das {
4395000d370SBiju Das 	struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
4405000d370SBiju Das 	struct rz_dmac *dmac = to_rz_dmac(chan->device);
4415000d370SBiju Das 	struct rz_lmdesc *lmdesc = channel->lmdesc.base;
4425000d370SBiju Das 	struct rz_dmac_desc *desc, *_desc;
4435000d370SBiju Das 	unsigned long flags;
4445000d370SBiju Das 	unsigned int i;
4455000d370SBiju Das 
4465000d370SBiju Das 	spin_lock_irqsave(&channel->vc.lock, flags);
4475000d370SBiju Das 
4485000d370SBiju Das 	for (i = 0; i < DMAC_NR_LMDESC; i++)
4495000d370SBiju Das 		lmdesc[i].header = 0;
4505000d370SBiju Das 
4515000d370SBiju Das 	rz_dmac_disable_hw(channel);
4525000d370SBiju Das 	list_splice_tail_init(&channel->ld_active, &channel->ld_free);
4535000d370SBiju Das 	list_splice_tail_init(&channel->ld_queue, &channel->ld_free);
4545000d370SBiju Das 
4555000d370SBiju Das 	if (channel->mid_rid >= 0) {
4565000d370SBiju Das 		clear_bit(channel->mid_rid, dmac->modules);
4575000d370SBiju Das 		channel->mid_rid = -EINVAL;
4585000d370SBiju Das 	}
4595000d370SBiju Das 
4605000d370SBiju Das 	spin_unlock_irqrestore(&channel->vc.lock, flags);
4615000d370SBiju Das 
4625000d370SBiju Das 	list_for_each_entry_safe(desc, _desc, &channel->ld_free, node) {
4635000d370SBiju Das 		kfree(desc);
4645000d370SBiju Das 		channel->descs_allocated--;
4655000d370SBiju Das 	}
4665000d370SBiju Das 
4675000d370SBiju Das 	INIT_LIST_HEAD(&channel->ld_free);
4685000d370SBiju Das 	vchan_free_chan_resources(&channel->vc);
4695000d370SBiju Das }
4705000d370SBiju Das 
4715000d370SBiju Das static struct dma_async_tx_descriptor *
rz_dmac_prep_dma_memcpy(struct dma_chan * chan,dma_addr_t dest,dma_addr_t src,size_t len,unsigned long flags)4725000d370SBiju Das rz_dmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
4735000d370SBiju Das 			size_t len, unsigned long flags)
4745000d370SBiju Das {
4755000d370SBiju Das 	struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
4765000d370SBiju Das 	struct rz_dmac *dmac = to_rz_dmac(chan->device);
4775000d370SBiju Das 	struct rz_dmac_desc *desc;
4785000d370SBiju Das 
4795000d370SBiju Das 	dev_dbg(dmac->dev, "%s channel: %d src=0x%pad dst=0x%pad len=%zu\n",
4805000d370SBiju Das 		__func__, channel->index, &src, &dest, len);
4815000d370SBiju Das 
4825000d370SBiju Das 	if (list_empty(&channel->ld_free))
4835000d370SBiju Das 		return NULL;
4845000d370SBiju Das 
4855000d370SBiju Das 	desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node);
4865000d370SBiju Das 
4875000d370SBiju Das 	desc->type = RZ_DMAC_DESC_MEMCPY;
4885000d370SBiju Das 	desc->src = src;
4895000d370SBiju Das 	desc->dest = dest;
4905000d370SBiju Das 	desc->len = len;
4915000d370SBiju Das 	desc->direction = DMA_MEM_TO_MEM;
4925000d370SBiju Das 
4935000d370SBiju Das 	list_move_tail(channel->ld_free.next, &channel->ld_queue);
4945000d370SBiju Das 	return vchan_tx_prep(&channel->vc, &desc->vd, flags);
4955000d370SBiju Das }
4965000d370SBiju Das 
4975000d370SBiju Das static struct dma_async_tx_descriptor *
rz_dmac_prep_slave_sg(struct dma_chan * chan,struct scatterlist * sgl,unsigned int sg_len,enum dma_transfer_direction direction,unsigned long flags,void * context)4985000d370SBiju Das rz_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
4995000d370SBiju Das 		      unsigned int sg_len,
5005000d370SBiju Das 		      enum dma_transfer_direction direction,
5015000d370SBiju Das 		      unsigned long flags, void *context)
5025000d370SBiju Das {
5035000d370SBiju Das 	struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
5045000d370SBiju Das 	struct rz_dmac_desc *desc;
5055000d370SBiju Das 	struct scatterlist *sg;
5065000d370SBiju Das 	int dma_length = 0;
5075000d370SBiju Das 	int i = 0;
5085000d370SBiju Das 
5095000d370SBiju Das 	if (list_empty(&channel->ld_free))
5105000d370SBiju Das 		return NULL;
5115000d370SBiju Das 
5125000d370SBiju Das 	desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node);
5135000d370SBiju Das 
5145000d370SBiju Das 	for_each_sg(sgl, sg, sg_len, i) {
5155000d370SBiju Das 		dma_length += sg_dma_len(sg);
5165000d370SBiju Das 	}
5175000d370SBiju Das 
5185000d370SBiju Das 	desc->type = RZ_DMAC_DESC_SLAVE_SG;
5195000d370SBiju Das 	desc->sg = sgl;
5205000d370SBiju Das 	desc->sgcount = sg_len;
5215000d370SBiju Das 	desc->len = dma_length;
5225000d370SBiju Das 	desc->direction = direction;
5235000d370SBiju Das 
5245000d370SBiju Das 	if (direction == DMA_DEV_TO_MEM)
5255000d370SBiju Das 		desc->src = channel->src_per_address;
5265000d370SBiju Das 	else
5275000d370SBiju Das 		desc->dest = channel->dst_per_address;
5285000d370SBiju Das 
5295000d370SBiju Das 	list_move_tail(channel->ld_free.next, &channel->ld_queue);
5305000d370SBiju Das 	return vchan_tx_prep(&channel->vc, &desc->vd, flags);
5315000d370SBiju Das }
5325000d370SBiju Das 
rz_dmac_terminate_all(struct dma_chan * chan)5335000d370SBiju Das static int rz_dmac_terminate_all(struct dma_chan *chan)
5345000d370SBiju Das {
5355000d370SBiju Das 	struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
5365000d370SBiju Das 	unsigned long flags;
5375000d370SBiju Das 	LIST_HEAD(head);
5385000d370SBiju Das 
5395000d370SBiju Das 	rz_dmac_disable_hw(channel);
5405000d370SBiju Das 	spin_lock_irqsave(&channel->vc.lock, flags);
5415000d370SBiju Das 	list_splice_tail_init(&channel->ld_active, &channel->ld_free);
5425000d370SBiju Das 	list_splice_tail_init(&channel->ld_queue, &channel->ld_free);
5435000d370SBiju Das 	spin_unlock_irqrestore(&channel->vc.lock, flags);
5445000d370SBiju Das 	vchan_get_all_descriptors(&channel->vc, &head);
5455000d370SBiju Das 	vchan_dma_desc_free_list(&channel->vc, &head);
5465000d370SBiju Das 
5475000d370SBiju Das 	return 0;
5485000d370SBiju Das }
5495000d370SBiju Das 
rz_dmac_issue_pending(struct dma_chan * chan)5505000d370SBiju Das static void rz_dmac_issue_pending(struct dma_chan *chan)
5515000d370SBiju Das {
5525000d370SBiju Das 	struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
5535000d370SBiju Das 	struct rz_dmac *dmac = to_rz_dmac(chan->device);
5545000d370SBiju Das 	struct rz_dmac_desc *desc;
5555000d370SBiju Das 	unsigned long flags;
5565000d370SBiju Das 
5575000d370SBiju Das 	spin_lock_irqsave(&channel->vc.lock, flags);
5585000d370SBiju Das 
5595000d370SBiju Das 	if (!list_empty(&channel->ld_queue)) {
5605000d370SBiju Das 		desc = list_first_entry(&channel->ld_queue,
5615000d370SBiju Das 					struct rz_dmac_desc, node);
5625000d370SBiju Das 		channel->desc = desc;
5635000d370SBiju Das 		if (vchan_issue_pending(&channel->vc)) {
5645000d370SBiju Das 			if (rz_dmac_xfer_desc(channel) < 0)
5655000d370SBiju Das 				dev_warn(dmac->dev, "ch: %d couldn't issue DMA xfer\n",
5665000d370SBiju Das 					 channel->index);
5675000d370SBiju Das 			else
5685000d370SBiju Das 				list_move_tail(channel->ld_queue.next,
5695000d370SBiju Das 					       &channel->ld_active);
5705000d370SBiju Das 		}
5715000d370SBiju Das 	}
5725000d370SBiju Das 
5735000d370SBiju Das 	spin_unlock_irqrestore(&channel->vc.lock, flags);
5745000d370SBiju Das }
5755000d370SBiju Das 
rz_dmac_ds_to_val_mapping(enum dma_slave_buswidth ds)5765000d370SBiju Das static u8 rz_dmac_ds_to_val_mapping(enum dma_slave_buswidth ds)
5775000d370SBiju Das {
5785000d370SBiju Das 	u8 i;
5794c0eee50SColin Ian King 	static const enum dma_slave_buswidth ds_lut[] = {
5805000d370SBiju Das 		DMA_SLAVE_BUSWIDTH_1_BYTE,
5815000d370SBiju Das 		DMA_SLAVE_BUSWIDTH_2_BYTES,
5825000d370SBiju Das 		DMA_SLAVE_BUSWIDTH_4_BYTES,
5835000d370SBiju Das 		DMA_SLAVE_BUSWIDTH_8_BYTES,
5845000d370SBiju Das 		DMA_SLAVE_BUSWIDTH_16_BYTES,
5855000d370SBiju Das 		DMA_SLAVE_BUSWIDTH_32_BYTES,
5865000d370SBiju Das 		DMA_SLAVE_BUSWIDTH_64_BYTES,
5875000d370SBiju Das 		DMA_SLAVE_BUSWIDTH_128_BYTES,
5885000d370SBiju Das 	};
5895000d370SBiju Das 
5905000d370SBiju Das 	for (i = 0; i < ARRAY_SIZE(ds_lut); i++) {
5915000d370SBiju Das 		if (ds_lut[i] == ds)
5925000d370SBiju Das 			return i;
5935000d370SBiju Das 	}
5945000d370SBiju Das 
5955000d370SBiju Das 	return CHCFG_DS_INVALID;
5965000d370SBiju Das }
5975000d370SBiju Das 
rz_dmac_config(struct dma_chan * chan,struct dma_slave_config * config)5985000d370SBiju Das static int rz_dmac_config(struct dma_chan *chan,
5995000d370SBiju Das 			  struct dma_slave_config *config)
6005000d370SBiju Das {
6015000d370SBiju Das 	struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
6025000d370SBiju Das 	u32 val;
6035000d370SBiju Das 
6045000d370SBiju Das 	channel->src_per_address = config->src_addr;
6055000d370SBiju Das 	channel->dst_per_address = config->dst_addr;
6065000d370SBiju Das 
6075000d370SBiju Das 	val = rz_dmac_ds_to_val_mapping(config->dst_addr_width);
6085000d370SBiju Das 	if (val == CHCFG_DS_INVALID)
6095000d370SBiju Das 		return -EINVAL;
6105000d370SBiju Das 
611*c6ec8c83SHien Huynh 	channel->chcfg &= ~CHCFG_FILL_DDS_MASK;
612*c6ec8c83SHien Huynh 	channel->chcfg |= FIELD_PREP(CHCFG_FILL_DDS_MASK, val);
6135000d370SBiju Das 
6145000d370SBiju Das 	val = rz_dmac_ds_to_val_mapping(config->src_addr_width);
6155000d370SBiju Das 	if (val == CHCFG_DS_INVALID)
6165000d370SBiju Das 		return -EINVAL;
6175000d370SBiju Das 
618*c6ec8c83SHien Huynh 	channel->chcfg &= ~CHCFG_FILL_SDS_MASK;
619*c6ec8c83SHien Huynh 	channel->chcfg |= FIELD_PREP(CHCFG_FILL_SDS_MASK, val);
6205000d370SBiju Das 
6215000d370SBiju Das 	return 0;
6225000d370SBiju Das }
6235000d370SBiju Das 
rz_dmac_virt_desc_free(struct virt_dma_desc * vd)6245000d370SBiju Das static void rz_dmac_virt_desc_free(struct virt_dma_desc *vd)
6255000d370SBiju Das {
6265000d370SBiju Das 	/*
6275000d370SBiju Das 	 * Place holder
6285000d370SBiju Das 	 * Descriptor allocation is done during alloc_chan_resources and
6295000d370SBiju Das 	 * get freed during free_chan_resources.
6305000d370SBiju Das 	 * list is used to manage the descriptors and avoid any memory
6315000d370SBiju Das 	 * allocation/free during DMA read/write.
6325000d370SBiju Das 	 */
6335000d370SBiju Das }
6345000d370SBiju Das 
rz_dmac_device_synchronize(struct dma_chan * chan)6357d3a3aaaSBiju Das static void rz_dmac_device_synchronize(struct dma_chan *chan)
6367d3a3aaaSBiju Das {
6377d3a3aaaSBiju Das 	struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
6387d3a3aaaSBiju Das 	struct rz_dmac *dmac = to_rz_dmac(chan->device);
6397d3a3aaaSBiju Das 	u32 chstat;
6407d3a3aaaSBiju Das 	int ret;
6417d3a3aaaSBiju Das 
6427d3a3aaaSBiju Das 	ret = read_poll_timeout(rz_dmac_ch_readl, chstat, !(chstat & CHSTAT_EN),
6437d3a3aaaSBiju Das 				100, 100000, false, channel, CHSTAT, 1);
6447d3a3aaaSBiju Das 	if (ret < 0)
6457d3a3aaaSBiju Das 		dev_warn(dmac->dev, "DMA Timeout");
6467d3a3aaaSBiju Das 
6477d3a3aaaSBiju Das 	rz_dmac_set_dmars_register(dmac, channel->index, 0);
6487d3a3aaaSBiju Das }
6497d3a3aaaSBiju Das 
6505000d370SBiju Das /*
6515000d370SBiju Das  * -----------------------------------------------------------------------------
6525000d370SBiju Das  * IRQ handling
6535000d370SBiju Das  */
6545000d370SBiju Das 
rz_dmac_irq_handle_channel(struct rz_dmac_chan * channel)6555000d370SBiju Das static void rz_dmac_irq_handle_channel(struct rz_dmac_chan *channel)
6565000d370SBiju Das {
6575000d370SBiju Das 	struct dma_chan *chan = &channel->vc.chan;
6585000d370SBiju Das 	struct rz_dmac *dmac = to_rz_dmac(chan->device);
6595000d370SBiju Das 	u32 chstat, chctrl;
6605000d370SBiju Das 
6615000d370SBiju Das 	chstat = rz_dmac_ch_readl(channel, CHSTAT, 1);
6625000d370SBiju Das 	if (chstat & CHSTAT_ER) {
6635000d370SBiju Das 		dev_err(dmac->dev, "DMAC err CHSTAT_%d = %08X\n",
6645000d370SBiju Das 			channel->index, chstat);
6655000d370SBiju Das 		rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1);
6665000d370SBiju Das 		goto done;
6675000d370SBiju Das 	}
6685000d370SBiju Das 
6695000d370SBiju Das 	chctrl = rz_dmac_ch_readl(channel, CHCTRL, 1);
6705000d370SBiju Das 	rz_dmac_ch_writel(channel, chctrl | CHCTRL_CLREND, CHCTRL, 1);
6715000d370SBiju Das done:
6725000d370SBiju Das 	return;
6735000d370SBiju Das }
6745000d370SBiju Das 
rz_dmac_irq_handler(int irq,void * dev_id)6755000d370SBiju Das static irqreturn_t rz_dmac_irq_handler(int irq, void *dev_id)
6765000d370SBiju Das {
6775000d370SBiju Das 	struct rz_dmac_chan *channel = dev_id;
6785000d370SBiju Das 
6795000d370SBiju Das 	if (channel) {
6805000d370SBiju Das 		rz_dmac_irq_handle_channel(channel);
6815000d370SBiju Das 		return IRQ_WAKE_THREAD;
6825000d370SBiju Das 	}
6835000d370SBiju Das 	/* handle DMAERR irq */
6845000d370SBiju Das 	return IRQ_HANDLED;
6855000d370SBiju Das }
6865000d370SBiju Das 
rz_dmac_irq_handler_thread(int irq,void * dev_id)6875000d370SBiju Das static irqreturn_t rz_dmac_irq_handler_thread(int irq, void *dev_id)
6885000d370SBiju Das {
6895000d370SBiju Das 	struct rz_dmac_chan *channel = dev_id;
6905000d370SBiju Das 	struct rz_dmac_desc *desc = NULL;
6915000d370SBiju Das 	unsigned long flags;
6925000d370SBiju Das 
6935000d370SBiju Das 	spin_lock_irqsave(&channel->vc.lock, flags);
6945000d370SBiju Das 
6955000d370SBiju Das 	if (list_empty(&channel->ld_active)) {
6965000d370SBiju Das 		/* Someone might have called terminate all */
6975000d370SBiju Das 		goto out;
6985000d370SBiju Das 	}
6995000d370SBiju Das 
7005000d370SBiju Das 	desc = list_first_entry(&channel->ld_active, struct rz_dmac_desc, node);
7015000d370SBiju Das 	vchan_cookie_complete(&desc->vd);
7025000d370SBiju Das 	list_move_tail(channel->ld_active.next, &channel->ld_free);
7035000d370SBiju Das 	if (!list_empty(&channel->ld_queue)) {
7045000d370SBiju Das 		desc = list_first_entry(&channel->ld_queue, struct rz_dmac_desc,
7055000d370SBiju Das 					node);
7065000d370SBiju Das 		channel->desc = desc;
7075000d370SBiju Das 		if (rz_dmac_xfer_desc(channel) == 0)
7085000d370SBiju Das 			list_move_tail(channel->ld_queue.next, &channel->ld_active);
7095000d370SBiju Das 	}
7105000d370SBiju Das out:
7115000d370SBiju Das 	spin_unlock_irqrestore(&channel->vc.lock, flags);
7125000d370SBiju Das 
7135000d370SBiju Das 	return IRQ_HANDLED;
7145000d370SBiju Das }
7155000d370SBiju Das 
7165000d370SBiju Das /*
7175000d370SBiju Das  * -----------------------------------------------------------------------------
7185000d370SBiju Das  * OF xlate and channel filter
7195000d370SBiju Das  */
7205000d370SBiju Das 
rz_dmac_chan_filter(struct dma_chan * chan,void * arg)7215000d370SBiju Das static bool rz_dmac_chan_filter(struct dma_chan *chan, void *arg)
7225000d370SBiju Das {
7235000d370SBiju Das 	struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
7245000d370SBiju Das 	struct rz_dmac *dmac = to_rz_dmac(chan->device);
7255000d370SBiju Das 	struct of_phandle_args *dma_spec = arg;
7265000d370SBiju Das 	u32 ch_cfg;
7275000d370SBiju Das 
7285000d370SBiju Das 	channel->mid_rid = dma_spec->args[0] & MID_RID_MASK;
7295000d370SBiju Das 	ch_cfg = (dma_spec->args[0] & CHCFG_MASK) >> 10;
7305000d370SBiju Das 	channel->chcfg = CHCFG_FILL_TM(ch_cfg) | CHCFG_FILL_AM(ch_cfg) |
7315000d370SBiju Das 			 CHCFG_FILL_LVL(ch_cfg) | CHCFG_FILL_HIEN(ch_cfg);
7325000d370SBiju Das 
7335000d370SBiju Das 	return !test_and_set_bit(channel->mid_rid, dmac->modules);
7345000d370SBiju Das }
7355000d370SBiju Das 
rz_dmac_of_xlate(struct of_phandle_args * dma_spec,struct of_dma * ofdma)7365000d370SBiju Das static struct dma_chan *rz_dmac_of_xlate(struct of_phandle_args *dma_spec,
7375000d370SBiju Das 					 struct of_dma *ofdma)
7385000d370SBiju Das {
7395000d370SBiju Das 	dma_cap_mask_t mask;
7405000d370SBiju Das 
7415000d370SBiju Das 	if (dma_spec->args_count != 1)
7425000d370SBiju Das 		return NULL;
7435000d370SBiju Das 
7445000d370SBiju Das 	/* Only slave DMA channels can be allocated via DT */
7455000d370SBiju Das 	dma_cap_zero(mask);
7465000d370SBiju Das 	dma_cap_set(DMA_SLAVE, mask);
7475000d370SBiju Das 
7485000d370SBiju Das 	return dma_request_channel(mask, rz_dmac_chan_filter, dma_spec);
7495000d370SBiju Das }
7505000d370SBiju Das 
7515000d370SBiju Das /*
7525000d370SBiju Das  * -----------------------------------------------------------------------------
7535000d370SBiju Das  * Probe and remove
7545000d370SBiju Das  */
7555000d370SBiju Das 
rz_dmac_chan_probe(struct rz_dmac * dmac,struct rz_dmac_chan * channel,unsigned int index)7565000d370SBiju Das static int rz_dmac_chan_probe(struct rz_dmac *dmac,
7575000d370SBiju Das 			      struct rz_dmac_chan *channel,
7585000d370SBiju Das 			      unsigned int index)
7595000d370SBiju Das {
7605000d370SBiju Das 	struct platform_device *pdev = to_platform_device(dmac->dev);
7615000d370SBiju Das 	struct rz_lmdesc *lmdesc;
7625000d370SBiju Das 	char pdev_irqname[5];
7635000d370SBiju Das 	char *irqname;
7645000d370SBiju Das 	int ret;
7655000d370SBiju Das 
7665000d370SBiju Das 	channel->index = index;
7675000d370SBiju Das 	channel->mid_rid = -EINVAL;
7685000d370SBiju Das 
7695000d370SBiju Das 	/* Request the channel interrupt. */
7705000d370SBiju Das 	sprintf(pdev_irqname, "ch%u", index);
7715000d370SBiju Das 	channel->irq = platform_get_irq_byname(pdev, pdev_irqname);
7725000d370SBiju Das 	if (channel->irq < 0)
7735000d370SBiju Das 		return channel->irq;
7745000d370SBiju Das 
7755000d370SBiju Das 	irqname = devm_kasprintf(dmac->dev, GFP_KERNEL, "%s:%u",
7765000d370SBiju Das 				 dev_name(dmac->dev), index);
7775000d370SBiju Das 	if (!irqname)
7785000d370SBiju Das 		return -ENOMEM;
7795000d370SBiju Das 
7805000d370SBiju Das 	ret = devm_request_threaded_irq(dmac->dev, channel->irq,
7815000d370SBiju Das 					rz_dmac_irq_handler,
7825000d370SBiju Das 					rz_dmac_irq_handler_thread, 0,
7835000d370SBiju Das 					irqname, channel);
7845000d370SBiju Das 	if (ret) {
7855000d370SBiju Das 		dev_err(dmac->dev, "failed to request IRQ %u (%d)\n",
7865000d370SBiju Das 			channel->irq, ret);
7875000d370SBiju Das 		return ret;
7885000d370SBiju Das 	}
7895000d370SBiju Das 
7905000d370SBiju Das 	/* Set io base address for each channel */
7915000d370SBiju Das 	if (index < 8) {
7925000d370SBiju Das 		channel->ch_base = dmac->base + CHANNEL_0_7_OFFSET +
7935000d370SBiju Das 			EACH_CHANNEL_OFFSET * index;
7945000d370SBiju Das 		channel->ch_cmn_base = dmac->base + CHANNEL_0_7_COMMON_BASE;
7955000d370SBiju Das 	} else {
7965000d370SBiju Das 		channel->ch_base = dmac->base + CHANNEL_8_15_OFFSET +
7975000d370SBiju Das 			EACH_CHANNEL_OFFSET * (index - 8);
7985000d370SBiju Das 		channel->ch_cmn_base = dmac->base + CHANNEL_8_15_COMMON_BASE;
7995000d370SBiju Das 	}
8005000d370SBiju Das 
8015000d370SBiju Das 	/* Allocate descriptors */
8025000d370SBiju Das 	lmdesc = dma_alloc_coherent(&pdev->dev,
8035000d370SBiju Das 				    sizeof(struct rz_lmdesc) * DMAC_NR_LMDESC,
8045000d370SBiju Das 				    &channel->lmdesc.base_dma, GFP_KERNEL);
8055000d370SBiju Das 	if (!lmdesc) {
8065000d370SBiju Das 		dev_err(&pdev->dev, "Can't allocate memory (lmdesc)\n");
8075000d370SBiju Das 		return -ENOMEM;
8085000d370SBiju Das 	}
8095000d370SBiju Das 	rz_lmdesc_setup(channel, lmdesc);
8105000d370SBiju Das 
8115000d370SBiju Das 	/* Initialize register for each channel */
8125000d370SBiju Das 	rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1);
8135000d370SBiju Das 
8145000d370SBiju Das 	channel->vc.desc_free = rz_dmac_virt_desc_free;
8155000d370SBiju Das 	vchan_init(&channel->vc, &dmac->engine);
8165000d370SBiju Das 	INIT_LIST_HEAD(&channel->ld_queue);
8175000d370SBiju Das 	INIT_LIST_HEAD(&channel->ld_free);
8185000d370SBiju Das 	INIT_LIST_HEAD(&channel->ld_active);
8195000d370SBiju Das 
8205000d370SBiju Das 	return 0;
8215000d370SBiju Das }
8225000d370SBiju Das 
rz_dmac_parse_of(struct device * dev,struct rz_dmac * dmac)8235000d370SBiju Das static int rz_dmac_parse_of(struct device *dev, struct rz_dmac *dmac)
8245000d370SBiju Das {
8255000d370SBiju Das 	struct device_node *np = dev->of_node;
8265000d370SBiju Das 	int ret;
8275000d370SBiju Das 
8285000d370SBiju Das 	ret = of_property_read_u32(np, "dma-channels", &dmac->n_channels);
8295000d370SBiju Das 	if (ret < 0) {
8305000d370SBiju Das 		dev_err(dev, "unable to read dma-channels property\n");
8315000d370SBiju Das 		return ret;
8325000d370SBiju Das 	}
8335000d370SBiju Das 
8345000d370SBiju Das 	if (!dmac->n_channels || dmac->n_channels > RZ_DMAC_MAX_CHANNELS) {
8355000d370SBiju Das 		dev_err(dev, "invalid number of channels %u\n", dmac->n_channels);
8365000d370SBiju Das 		return -EINVAL;
8375000d370SBiju Das 	}
8385000d370SBiju Das 
8395000d370SBiju Das 	return 0;
8405000d370SBiju Das }
8415000d370SBiju Das 
rz_dmac_probe(struct platform_device * pdev)8425000d370SBiju Das static int rz_dmac_probe(struct platform_device *pdev)
8435000d370SBiju Das {
8445000d370SBiju Das 	const char *irqname = "error";
8455000d370SBiju Das 	struct dma_device *engine;
8465000d370SBiju Das 	struct rz_dmac *dmac;
8475000d370SBiju Das 	int channel_num;
8485000d370SBiju Das 	unsigned int i;
8495000d370SBiju Das 	int ret;
8505000d370SBiju Das 	int irq;
8515000d370SBiju Das 
8525000d370SBiju Das 	dmac = devm_kzalloc(&pdev->dev, sizeof(*dmac), GFP_KERNEL);
8535000d370SBiju Das 	if (!dmac)
8545000d370SBiju Das 		return -ENOMEM;
8555000d370SBiju Das 
8565000d370SBiju Das 	dmac->dev = &pdev->dev;
8575000d370SBiju Das 	platform_set_drvdata(pdev, dmac);
8585000d370SBiju Das 
8595000d370SBiju Das 	ret = rz_dmac_parse_of(&pdev->dev, dmac);
8605000d370SBiju Das 	if (ret < 0)
8615000d370SBiju Das 		return ret;
8625000d370SBiju Das 
8635000d370SBiju Das 	dmac->channels = devm_kcalloc(&pdev->dev, dmac->n_channels,
8645000d370SBiju Das 				      sizeof(*dmac->channels), GFP_KERNEL);
8655000d370SBiju Das 	if (!dmac->channels)
8665000d370SBiju Das 		return -ENOMEM;
8675000d370SBiju Das 
8685000d370SBiju Das 	/* Request resources */
8695000d370SBiju Das 	dmac->base = devm_platform_ioremap_resource(pdev, 0);
8705000d370SBiju Das 	if (IS_ERR(dmac->base))
8715000d370SBiju Das 		return PTR_ERR(dmac->base);
8725000d370SBiju Das 
8735000d370SBiju Das 	dmac->ext_base = devm_platform_ioremap_resource(pdev, 1);
8745000d370SBiju Das 	if (IS_ERR(dmac->ext_base))
8755000d370SBiju Das 		return PTR_ERR(dmac->ext_base);
8765000d370SBiju Das 
8775000d370SBiju Das 	/* Register interrupt handler for error */
8785000d370SBiju Das 	irq = platform_get_irq_byname(pdev, irqname);
8795000d370SBiju Das 	if (irq < 0)
8805000d370SBiju Das 		return irq;
8815000d370SBiju Das 
8825000d370SBiju Das 	ret = devm_request_irq(&pdev->dev, irq, rz_dmac_irq_handler, 0,
8835000d370SBiju Das 			       irqname, NULL);
8845000d370SBiju Das 	if (ret) {
8855000d370SBiju Das 		dev_err(&pdev->dev, "failed to request IRQ %u (%d)\n",
8865000d370SBiju Das 			irq, ret);
8875000d370SBiju Das 		return ret;
8885000d370SBiju Das 	}
8895000d370SBiju Das 
8905000d370SBiju Das 	/* Initialize the channels. */
8915000d370SBiju Das 	INIT_LIST_HEAD(&dmac->engine.channels);
8925000d370SBiju Das 
893d1e71a3aSBiju Das 	dmac->rstc = devm_reset_control_array_get_exclusive(&pdev->dev);
894d1e71a3aSBiju Das 	if (IS_ERR(dmac->rstc))
895d1e71a3aSBiju Das 		return dev_err_probe(&pdev->dev, PTR_ERR(dmac->rstc),
896d1e71a3aSBiju Das 				     "failed to get resets\n");
897d1e71a3aSBiju Das 
898161596fdSBiju Das 	pm_runtime_enable(&pdev->dev);
899161596fdSBiju Das 	ret = pm_runtime_resume_and_get(&pdev->dev);
900161596fdSBiju Das 	if (ret < 0) {
901161596fdSBiju Das 		dev_err(&pdev->dev, "pm_runtime_resume_and_get failed\n");
902161596fdSBiju Das 		goto err_pm_disable;
903161596fdSBiju Das 	}
904161596fdSBiju Das 
905d1e71a3aSBiju Das 	ret = reset_control_deassert(dmac->rstc);
906d1e71a3aSBiju Das 	if (ret)
907d1e71a3aSBiju Das 		goto err_pm_runtime_put;
908d1e71a3aSBiju Das 
9095000d370SBiju Das 	for (i = 0; i < dmac->n_channels; i++) {
9105000d370SBiju Das 		ret = rz_dmac_chan_probe(dmac, &dmac->channels[i], i);
9115000d370SBiju Das 		if (ret < 0)
9125000d370SBiju Das 			goto err;
9135000d370SBiju Das 	}
9145000d370SBiju Das 
9155000d370SBiju Das 	/* Register the DMAC as a DMA provider for DT. */
9165000d370SBiju Das 	ret = of_dma_controller_register(pdev->dev.of_node, rz_dmac_of_xlate,
9175000d370SBiju Das 					 NULL);
9185000d370SBiju Das 	if (ret < 0)
9195000d370SBiju Das 		goto err;
9205000d370SBiju Das 
9215000d370SBiju Das 	/* Register the DMA engine device. */
9225000d370SBiju Das 	engine = &dmac->engine;
9235000d370SBiju Das 	dma_cap_set(DMA_SLAVE, engine->cap_mask);
9245000d370SBiju Das 	dma_cap_set(DMA_MEMCPY, engine->cap_mask);
9255000d370SBiju Das 	rz_dmac_writel(dmac, DCTRL_DEFAULT, CHANNEL_0_7_COMMON_BASE + DCTRL);
9265000d370SBiju Das 	rz_dmac_writel(dmac, DCTRL_DEFAULT, CHANNEL_8_15_COMMON_BASE + DCTRL);
9275000d370SBiju Das 
9285000d370SBiju Das 	engine->dev = &pdev->dev;
9295000d370SBiju Das 
9305000d370SBiju Das 	engine->device_alloc_chan_resources = rz_dmac_alloc_chan_resources;
9315000d370SBiju Das 	engine->device_free_chan_resources = rz_dmac_free_chan_resources;
9325000d370SBiju Das 	engine->device_tx_status = dma_cookie_status;
9335000d370SBiju Das 	engine->device_prep_slave_sg = rz_dmac_prep_slave_sg;
9345000d370SBiju Das 	engine->device_prep_dma_memcpy = rz_dmac_prep_dma_memcpy;
9355000d370SBiju Das 	engine->device_config = rz_dmac_config;
9365000d370SBiju Das 	engine->device_terminate_all = rz_dmac_terminate_all;
9375000d370SBiju Das 	engine->device_issue_pending = rz_dmac_issue_pending;
9387d3a3aaaSBiju Das 	engine->device_synchronize = rz_dmac_device_synchronize;
9395000d370SBiju Das 
9405000d370SBiju Das 	engine->copy_align = DMAENGINE_ALIGN_1_BYTE;
9415000d370SBiju Das 	dma_set_max_seg_size(engine->dev, U32_MAX);
9425000d370SBiju Das 
9435000d370SBiju Das 	ret = dma_async_device_register(engine);
9445000d370SBiju Das 	if (ret < 0) {
9455000d370SBiju Das 		dev_err(&pdev->dev, "unable to register\n");
9465000d370SBiju Das 		goto dma_register_err;
9475000d370SBiju Das 	}
9485000d370SBiju Das 	return 0;
9495000d370SBiju Das 
9505000d370SBiju Das dma_register_err:
9515000d370SBiju Das 	of_dma_controller_free(pdev->dev.of_node);
9525000d370SBiju Das err:
9535000d370SBiju Das 	channel_num = i ? i - 1 : 0;
9545000d370SBiju Das 	for (i = 0; i < channel_num; i++) {
9555000d370SBiju Das 		struct rz_dmac_chan *channel = &dmac->channels[i];
9565000d370SBiju Das 
95711a427beSDan Carpenter 		dma_free_coherent(&pdev->dev,
9585000d370SBiju Das 				  sizeof(struct rz_lmdesc) * DMAC_NR_LMDESC,
9595000d370SBiju Das 				  channel->lmdesc.base,
9605000d370SBiju Das 				  channel->lmdesc.base_dma);
9615000d370SBiju Das 	}
9625000d370SBiju Das 
9637ab04b7cSBiju Das 	reset_control_assert(dmac->rstc);
964d1e71a3aSBiju Das err_pm_runtime_put:
965161596fdSBiju Das 	pm_runtime_put(&pdev->dev);
966161596fdSBiju Das err_pm_disable:
967161596fdSBiju Das 	pm_runtime_disable(&pdev->dev);
968161596fdSBiju Das 
9695000d370SBiju Das 	return ret;
9705000d370SBiju Das }
9715000d370SBiju Das 
rz_dmac_remove(struct platform_device * pdev)9725000d370SBiju Das static int rz_dmac_remove(struct platform_device *pdev)
9735000d370SBiju Das {
9745000d370SBiju Das 	struct rz_dmac *dmac = platform_get_drvdata(pdev);
9755000d370SBiju Das 	unsigned int i;
9765000d370SBiju Das 
9777ab04b7cSBiju Das 	dma_async_device_unregister(&dmac->engine);
9787ab04b7cSBiju Das 	of_dma_controller_free(pdev->dev.of_node);
9795000d370SBiju Das 	for (i = 0; i < dmac->n_channels; i++) {
9805000d370SBiju Das 		struct rz_dmac_chan *channel = &dmac->channels[i];
9815000d370SBiju Das 
98211a427beSDan Carpenter 		dma_free_coherent(&pdev->dev,
9835000d370SBiju Das 				  sizeof(struct rz_lmdesc) * DMAC_NR_LMDESC,
9845000d370SBiju Das 				  channel->lmdesc.base,
9855000d370SBiju Das 				  channel->lmdesc.base_dma);
9865000d370SBiju Das 	}
987d1e71a3aSBiju Das 	reset_control_assert(dmac->rstc);
988161596fdSBiju Das 	pm_runtime_put(&pdev->dev);
989161596fdSBiju Das 	pm_runtime_disable(&pdev->dev);
9905000d370SBiju Das 
9915000d370SBiju Das 	return 0;
9925000d370SBiju Das }
9935000d370SBiju Das 
9945000d370SBiju Das static const struct of_device_id of_rz_dmac_match[] = {
9955000d370SBiju Das 	{ .compatible = "renesas,rz-dmac", },
9965000d370SBiju Das 	{ /* Sentinel */ }
9975000d370SBiju Das };
9985000d370SBiju Das MODULE_DEVICE_TABLE(of, of_rz_dmac_match);
9995000d370SBiju Das 
10005000d370SBiju Das static struct platform_driver rz_dmac_driver = {
10015000d370SBiju Das 	.driver		= {
10025000d370SBiju Das 		.name	= "rz-dmac",
10035000d370SBiju Das 		.of_match_table = of_rz_dmac_match,
10045000d370SBiju Das 	},
10055000d370SBiju Das 	.probe		= rz_dmac_probe,
10065000d370SBiju Das 	.remove		= rz_dmac_remove,
10075000d370SBiju Das };
10085000d370SBiju Das 
10095000d370SBiju Das module_platform_driver(rz_dmac_driver);
10105000d370SBiju Das 
10115000d370SBiju Das MODULE_DESCRIPTION("Renesas RZ/G2L DMA Controller Driver");
10125000d370SBiju Das MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
10135000d370SBiju Das MODULE_LICENSE("GPL v2");
1014