18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates.
48c2ecf20Sopenharmony_ci * Synopsys DesignWare eDMA v0 core
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Author: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/bitfield.h>
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include "dw-edma-core.h"
128c2ecf20Sopenharmony_ci#include "dw-edma-v0-core.h"
138c2ecf20Sopenharmony_ci#include "dw-edma-v0-regs.h"
148c2ecf20Sopenharmony_ci#include "dw-edma-v0-debugfs.h"
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_cienum dw_edma_control {
178c2ecf20Sopenharmony_ci	DW_EDMA_V0_CB					= BIT(0),
188c2ecf20Sopenharmony_ci	DW_EDMA_V0_TCB					= BIT(1),
198c2ecf20Sopenharmony_ci	DW_EDMA_V0_LLP					= BIT(2),
208c2ecf20Sopenharmony_ci	DW_EDMA_V0_LIE					= BIT(3),
218c2ecf20Sopenharmony_ci	DW_EDMA_V0_RIE					= BIT(4),
228c2ecf20Sopenharmony_ci	DW_EDMA_V0_CCS					= BIT(8),
238c2ecf20Sopenharmony_ci	DW_EDMA_V0_LLE					= BIT(9),
248c2ecf20Sopenharmony_ci};
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_cistatic inline struct dw_edma_v0_regs __iomem *__dw_regs(struct dw_edma *dw)
278c2ecf20Sopenharmony_ci{
288c2ecf20Sopenharmony_ci	return dw->rg_region.vaddr;
298c2ecf20Sopenharmony_ci}
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#define SET(dw, name, value)				\
328c2ecf20Sopenharmony_ci	writel(value, &(__dw_regs(dw)->name))
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#define GET(dw, name)					\
358c2ecf20Sopenharmony_ci	readl(&(__dw_regs(dw)->name))
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#define SET_RW(dw, dir, name, value)			\
388c2ecf20Sopenharmony_ci	do {						\
398c2ecf20Sopenharmony_ci		if ((dir) == EDMA_DIR_WRITE)		\
408c2ecf20Sopenharmony_ci			SET(dw, wr_##name, value);	\
418c2ecf20Sopenharmony_ci		else					\
428c2ecf20Sopenharmony_ci			SET(dw, rd_##name, value);	\
438c2ecf20Sopenharmony_ci	} while (0)
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci#define GET_RW(dw, dir, name)				\
468c2ecf20Sopenharmony_ci	((dir) == EDMA_DIR_WRITE			\
478c2ecf20Sopenharmony_ci	  ? GET(dw, wr_##name)				\
488c2ecf20Sopenharmony_ci	  : GET(dw, rd_##name))
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci#define SET_BOTH(dw, name, value)			\
518c2ecf20Sopenharmony_ci	do {						\
528c2ecf20Sopenharmony_ci		SET(dw, wr_##name, value);		\
538c2ecf20Sopenharmony_ci		SET(dw, rd_##name, value);		\
548c2ecf20Sopenharmony_ci	} while (0)
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistatic inline struct dw_edma_v0_ch_regs __iomem *
578c2ecf20Sopenharmony_ci__dw_ch_regs(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	if (dw->mode == EDMA_MODE_LEGACY)
608c2ecf20Sopenharmony_ci		return &(__dw_regs(dw)->type.legacy.ch);
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	if (dir == EDMA_DIR_WRITE)
638c2ecf20Sopenharmony_ci		return &__dw_regs(dw)->type.unroll.ch[ch].wr;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	return &__dw_regs(dw)->type.unroll.ch[ch].rd;
668c2ecf20Sopenharmony_ci}
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cistatic inline void writel_ch(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch,
698c2ecf20Sopenharmony_ci			     u32 value, void __iomem *addr)
708c2ecf20Sopenharmony_ci{
718c2ecf20Sopenharmony_ci	if (dw->mode == EDMA_MODE_LEGACY) {
728c2ecf20Sopenharmony_ci		u32 viewport_sel;
738c2ecf20Sopenharmony_ci		unsigned long flags;
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci		raw_spin_lock_irqsave(&dw->lock, flags);
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci		viewport_sel = FIELD_PREP(EDMA_V0_VIEWPORT_MASK, ch);
788c2ecf20Sopenharmony_ci		if (dir == EDMA_DIR_READ)
798c2ecf20Sopenharmony_ci			viewport_sel |= BIT(31);
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci		writel(viewport_sel,
828c2ecf20Sopenharmony_ci		       &(__dw_regs(dw)->type.legacy.viewport_sel));
838c2ecf20Sopenharmony_ci		writel(value, addr);
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci		raw_spin_unlock_irqrestore(&dw->lock, flags);
868c2ecf20Sopenharmony_ci	} else {
878c2ecf20Sopenharmony_ci		writel(value, addr);
888c2ecf20Sopenharmony_ci	}
898c2ecf20Sopenharmony_ci}
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_cistatic inline u32 readl_ch(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch,
928c2ecf20Sopenharmony_ci			   const void __iomem *addr)
938c2ecf20Sopenharmony_ci{
948c2ecf20Sopenharmony_ci	u32 value;
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	if (dw->mode == EDMA_MODE_LEGACY) {
978c2ecf20Sopenharmony_ci		u32 viewport_sel;
988c2ecf20Sopenharmony_ci		unsigned long flags;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci		raw_spin_lock_irqsave(&dw->lock, flags);
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci		viewport_sel = FIELD_PREP(EDMA_V0_VIEWPORT_MASK, ch);
1038c2ecf20Sopenharmony_ci		if (dir == EDMA_DIR_READ)
1048c2ecf20Sopenharmony_ci			viewport_sel |= BIT(31);
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci		writel(viewport_sel,
1078c2ecf20Sopenharmony_ci		       &(__dw_regs(dw)->type.legacy.viewport_sel));
1088c2ecf20Sopenharmony_ci		value = readl(addr);
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci		raw_spin_unlock_irqrestore(&dw->lock, flags);
1118c2ecf20Sopenharmony_ci	} else {
1128c2ecf20Sopenharmony_ci		value = readl(addr);
1138c2ecf20Sopenharmony_ci	}
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	return value;
1168c2ecf20Sopenharmony_ci}
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci#define SET_CH(dw, dir, ch, name, value) \
1198c2ecf20Sopenharmony_ci	writel_ch(dw, dir, ch, value, &(__dw_ch_regs(dw, dir, ch)->name))
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci#define GET_CH(dw, dir, ch, name) \
1228c2ecf20Sopenharmony_ci	readl_ch(dw, dir, ch, &(__dw_ch_regs(dw, dir, ch)->name))
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci#define SET_LL(ll, value) \
1258c2ecf20Sopenharmony_ci	writel(value, ll)
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci/* eDMA management callbacks */
1288c2ecf20Sopenharmony_civoid dw_edma_v0_core_off(struct dw_edma *dw)
1298c2ecf20Sopenharmony_ci{
1308c2ecf20Sopenharmony_ci	SET_BOTH(dw, int_mask, EDMA_V0_DONE_INT_MASK | EDMA_V0_ABORT_INT_MASK);
1318c2ecf20Sopenharmony_ci	SET_BOTH(dw, int_clear, EDMA_V0_DONE_INT_MASK | EDMA_V0_ABORT_INT_MASK);
1328c2ecf20Sopenharmony_ci	SET_BOTH(dw, engine_en, 0);
1338c2ecf20Sopenharmony_ci}
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ciu16 dw_edma_v0_core_ch_count(struct dw_edma *dw, enum dw_edma_dir dir)
1368c2ecf20Sopenharmony_ci{
1378c2ecf20Sopenharmony_ci	u32 num_ch;
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci	if (dir == EDMA_DIR_WRITE)
1408c2ecf20Sopenharmony_ci		num_ch = FIELD_GET(EDMA_V0_WRITE_CH_COUNT_MASK, GET(dw, ctrl));
1418c2ecf20Sopenharmony_ci	else
1428c2ecf20Sopenharmony_ci		num_ch = FIELD_GET(EDMA_V0_READ_CH_COUNT_MASK, GET(dw, ctrl));
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci	if (num_ch > EDMA_V0_MAX_NR_CH)
1458c2ecf20Sopenharmony_ci		num_ch = EDMA_V0_MAX_NR_CH;
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	return (u16)num_ch;
1488c2ecf20Sopenharmony_ci}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_cienum dma_status dw_edma_v0_core_ch_status(struct dw_edma_chan *chan)
1518c2ecf20Sopenharmony_ci{
1528c2ecf20Sopenharmony_ci	struct dw_edma *dw = chan->chip->dw;
1538c2ecf20Sopenharmony_ci	u32 tmp;
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	tmp = FIELD_GET(EDMA_V0_CH_STATUS_MASK,
1568c2ecf20Sopenharmony_ci			GET_CH(dw, chan->dir, chan->id, ch_control1));
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci	if (tmp == 1)
1598c2ecf20Sopenharmony_ci		return DMA_IN_PROGRESS;
1608c2ecf20Sopenharmony_ci	else if (tmp == 3)
1618c2ecf20Sopenharmony_ci		return DMA_COMPLETE;
1628c2ecf20Sopenharmony_ci	else
1638c2ecf20Sopenharmony_ci		return DMA_ERROR;
1648c2ecf20Sopenharmony_ci}
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_civoid dw_edma_v0_core_clear_done_int(struct dw_edma_chan *chan)
1678c2ecf20Sopenharmony_ci{
1688c2ecf20Sopenharmony_ci	struct dw_edma *dw = chan->chip->dw;
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	SET_RW(dw, chan->dir, int_clear,
1718c2ecf20Sopenharmony_ci	       FIELD_PREP(EDMA_V0_DONE_INT_MASK, BIT(chan->id)));
1728c2ecf20Sopenharmony_ci}
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_civoid dw_edma_v0_core_clear_abort_int(struct dw_edma_chan *chan)
1758c2ecf20Sopenharmony_ci{
1768c2ecf20Sopenharmony_ci	struct dw_edma *dw = chan->chip->dw;
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	SET_RW(dw, chan->dir, int_clear,
1798c2ecf20Sopenharmony_ci	       FIELD_PREP(EDMA_V0_ABORT_INT_MASK, BIT(chan->id)));
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ciu32 dw_edma_v0_core_status_done_int(struct dw_edma *dw, enum dw_edma_dir dir)
1838c2ecf20Sopenharmony_ci{
1848c2ecf20Sopenharmony_ci	return FIELD_GET(EDMA_V0_DONE_INT_MASK, GET_RW(dw, dir, int_status));
1858c2ecf20Sopenharmony_ci}
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ciu32 dw_edma_v0_core_status_abort_int(struct dw_edma *dw, enum dw_edma_dir dir)
1888c2ecf20Sopenharmony_ci{
1898c2ecf20Sopenharmony_ci	return FIELD_GET(EDMA_V0_ABORT_INT_MASK, GET_RW(dw, dir, int_status));
1908c2ecf20Sopenharmony_ci}
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_cistatic void dw_edma_v0_core_write_chunk(struct dw_edma_chunk *chunk)
1938c2ecf20Sopenharmony_ci{
1948c2ecf20Sopenharmony_ci	struct dw_edma_burst *child;
1958c2ecf20Sopenharmony_ci	struct dw_edma_v0_lli __iomem *lli;
1968c2ecf20Sopenharmony_ci	struct dw_edma_v0_llp __iomem *llp;
1978c2ecf20Sopenharmony_ci	u32 control = 0, i = 0;
1988c2ecf20Sopenharmony_ci	int j;
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	lli = chunk->ll_region.vaddr;
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci	if (chunk->cb)
2038c2ecf20Sopenharmony_ci		control = DW_EDMA_V0_CB;
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci	j = chunk->bursts_alloc;
2068c2ecf20Sopenharmony_ci	list_for_each_entry(child, &chunk->burst->list, list) {
2078c2ecf20Sopenharmony_ci		j--;
2088c2ecf20Sopenharmony_ci		if (!j)
2098c2ecf20Sopenharmony_ci			control |= (DW_EDMA_V0_LIE | DW_EDMA_V0_RIE);
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci		/* Channel control */
2128c2ecf20Sopenharmony_ci		SET_LL(&lli[i].control, control);
2138c2ecf20Sopenharmony_ci		/* Transfer size */
2148c2ecf20Sopenharmony_ci		SET_LL(&lli[i].transfer_size, child->sz);
2158c2ecf20Sopenharmony_ci		/* SAR - low, high */
2168c2ecf20Sopenharmony_ci		SET_LL(&lli[i].sar_low, lower_32_bits(child->sar));
2178c2ecf20Sopenharmony_ci		SET_LL(&lli[i].sar_high, upper_32_bits(child->sar));
2188c2ecf20Sopenharmony_ci		/* DAR - low, high */
2198c2ecf20Sopenharmony_ci		SET_LL(&lli[i].dar_low, lower_32_bits(child->dar));
2208c2ecf20Sopenharmony_ci		SET_LL(&lli[i].dar_high, upper_32_bits(child->dar));
2218c2ecf20Sopenharmony_ci		i++;
2228c2ecf20Sopenharmony_ci	}
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci	llp = (void __iomem *)&lli[i];
2258c2ecf20Sopenharmony_ci	control = DW_EDMA_V0_LLP | DW_EDMA_V0_TCB;
2268c2ecf20Sopenharmony_ci	if (!chunk->cb)
2278c2ecf20Sopenharmony_ci		control |= DW_EDMA_V0_CB;
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	/* Channel control */
2308c2ecf20Sopenharmony_ci	SET_LL(&llp->control, control);
2318c2ecf20Sopenharmony_ci	/* Linked list  - low, high */
2328c2ecf20Sopenharmony_ci	SET_LL(&llp->llp_low, lower_32_bits(chunk->ll_region.paddr));
2338c2ecf20Sopenharmony_ci	SET_LL(&llp->llp_high, upper_32_bits(chunk->ll_region.paddr));
2348c2ecf20Sopenharmony_ci}
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_civoid dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
2378c2ecf20Sopenharmony_ci{
2388c2ecf20Sopenharmony_ci	struct dw_edma_chan *chan = chunk->chan;
2398c2ecf20Sopenharmony_ci	struct dw_edma *dw = chan->chip->dw;
2408c2ecf20Sopenharmony_ci	u32 tmp;
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci	dw_edma_v0_core_write_chunk(chunk);
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	if (first) {
2458c2ecf20Sopenharmony_ci		/* Enable engine */
2468c2ecf20Sopenharmony_ci		SET_RW(dw, chan->dir, engine_en, BIT(0));
2478c2ecf20Sopenharmony_ci		/* Interrupt unmask - done, abort */
2488c2ecf20Sopenharmony_ci		tmp = GET_RW(dw, chan->dir, int_mask);
2498c2ecf20Sopenharmony_ci		tmp &= ~FIELD_PREP(EDMA_V0_DONE_INT_MASK, BIT(chan->id));
2508c2ecf20Sopenharmony_ci		tmp &= ~FIELD_PREP(EDMA_V0_ABORT_INT_MASK, BIT(chan->id));
2518c2ecf20Sopenharmony_ci		SET_RW(dw, chan->dir, int_mask, tmp);
2528c2ecf20Sopenharmony_ci		/* Linked list error */
2538c2ecf20Sopenharmony_ci		tmp = GET_RW(dw, chan->dir, linked_list_err_en);
2548c2ecf20Sopenharmony_ci		tmp |= FIELD_PREP(EDMA_V0_LINKED_LIST_ERR_MASK, BIT(chan->id));
2558c2ecf20Sopenharmony_ci		SET_RW(dw, chan->dir, linked_list_err_en, tmp);
2568c2ecf20Sopenharmony_ci		/* Channel control */
2578c2ecf20Sopenharmony_ci		SET_CH(dw, chan->dir, chan->id, ch_control1,
2588c2ecf20Sopenharmony_ci		       (DW_EDMA_V0_CCS | DW_EDMA_V0_LLE));
2598c2ecf20Sopenharmony_ci		/* Linked list - low, high */
2608c2ecf20Sopenharmony_ci		SET_CH(dw, chan->dir, chan->id, llp_low,
2618c2ecf20Sopenharmony_ci		       lower_32_bits(chunk->ll_region.paddr));
2628c2ecf20Sopenharmony_ci		SET_CH(dw, chan->dir, chan->id, llp_high,
2638c2ecf20Sopenharmony_ci		       upper_32_bits(chunk->ll_region.paddr));
2648c2ecf20Sopenharmony_ci	}
2658c2ecf20Sopenharmony_ci	/* Doorbell */
2668c2ecf20Sopenharmony_ci	SET_RW(dw, chan->dir, doorbell,
2678c2ecf20Sopenharmony_ci	       FIELD_PREP(EDMA_V0_DOORBELL_CH_MASK, chan->id));
2688c2ecf20Sopenharmony_ci}
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ciint dw_edma_v0_core_device_config(struct dw_edma_chan *chan)
2718c2ecf20Sopenharmony_ci{
2728c2ecf20Sopenharmony_ci	struct dw_edma *dw = chan->chip->dw;
2738c2ecf20Sopenharmony_ci	u32 tmp = 0;
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci	/* MSI done addr - low, high */
2768c2ecf20Sopenharmony_ci	SET_RW(dw, chan->dir, done_imwr_low, chan->msi.address_lo);
2778c2ecf20Sopenharmony_ci	SET_RW(dw, chan->dir, done_imwr_high, chan->msi.address_hi);
2788c2ecf20Sopenharmony_ci	/* MSI abort addr - low, high */
2798c2ecf20Sopenharmony_ci	SET_RW(dw, chan->dir, abort_imwr_low, chan->msi.address_lo);
2808c2ecf20Sopenharmony_ci	SET_RW(dw, chan->dir, abort_imwr_high, chan->msi.address_hi);
2818c2ecf20Sopenharmony_ci	/* MSI data - low, high */
2828c2ecf20Sopenharmony_ci	switch (chan->id) {
2838c2ecf20Sopenharmony_ci	case 0:
2848c2ecf20Sopenharmony_ci	case 1:
2858c2ecf20Sopenharmony_ci		tmp = GET_RW(dw, chan->dir, ch01_imwr_data);
2868c2ecf20Sopenharmony_ci		break;
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci	case 2:
2898c2ecf20Sopenharmony_ci	case 3:
2908c2ecf20Sopenharmony_ci		tmp = GET_RW(dw, chan->dir, ch23_imwr_data);
2918c2ecf20Sopenharmony_ci		break;
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci	case 4:
2948c2ecf20Sopenharmony_ci	case 5:
2958c2ecf20Sopenharmony_ci		tmp = GET_RW(dw, chan->dir, ch45_imwr_data);
2968c2ecf20Sopenharmony_ci		break;
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	case 6:
2998c2ecf20Sopenharmony_ci	case 7:
3008c2ecf20Sopenharmony_ci		tmp = GET_RW(dw, chan->dir, ch67_imwr_data);
3018c2ecf20Sopenharmony_ci		break;
3028c2ecf20Sopenharmony_ci	}
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci	if (chan->id & BIT(0)) {
3058c2ecf20Sopenharmony_ci		/* Channel odd {1, 3, 5, 7} */
3068c2ecf20Sopenharmony_ci		tmp &= EDMA_V0_CH_EVEN_MSI_DATA_MASK;
3078c2ecf20Sopenharmony_ci		tmp |= FIELD_PREP(EDMA_V0_CH_ODD_MSI_DATA_MASK,
3088c2ecf20Sopenharmony_ci				  chan->msi.data);
3098c2ecf20Sopenharmony_ci	} else {
3108c2ecf20Sopenharmony_ci		/* Channel even {0, 2, 4, 6} */
3118c2ecf20Sopenharmony_ci		tmp &= EDMA_V0_CH_ODD_MSI_DATA_MASK;
3128c2ecf20Sopenharmony_ci		tmp |= FIELD_PREP(EDMA_V0_CH_EVEN_MSI_DATA_MASK,
3138c2ecf20Sopenharmony_ci				  chan->msi.data);
3148c2ecf20Sopenharmony_ci	}
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci	switch (chan->id) {
3178c2ecf20Sopenharmony_ci	case 0:
3188c2ecf20Sopenharmony_ci	case 1:
3198c2ecf20Sopenharmony_ci		SET_RW(dw, chan->dir, ch01_imwr_data, tmp);
3208c2ecf20Sopenharmony_ci		break;
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci	case 2:
3238c2ecf20Sopenharmony_ci	case 3:
3248c2ecf20Sopenharmony_ci		SET_RW(dw, chan->dir, ch23_imwr_data, tmp);
3258c2ecf20Sopenharmony_ci		break;
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ci	case 4:
3288c2ecf20Sopenharmony_ci	case 5:
3298c2ecf20Sopenharmony_ci		SET_RW(dw, chan->dir, ch45_imwr_data, tmp);
3308c2ecf20Sopenharmony_ci		break;
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ci	case 6:
3338c2ecf20Sopenharmony_ci	case 7:
3348c2ecf20Sopenharmony_ci		SET_RW(dw, chan->dir, ch67_imwr_data, tmp);
3358c2ecf20Sopenharmony_ci		break;
3368c2ecf20Sopenharmony_ci	}
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	return 0;
3398c2ecf20Sopenharmony_ci}
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_ci/* eDMA debugfs callbacks */
3428c2ecf20Sopenharmony_civoid dw_edma_v0_core_debugfs_on(struct dw_edma_chip *chip)
3438c2ecf20Sopenharmony_ci{
3448c2ecf20Sopenharmony_ci	dw_edma_v0_debugfs_on(chip);
3458c2ecf20Sopenharmony_ci}
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_civoid dw_edma_v0_core_debugfs_off(void)
3488c2ecf20Sopenharmony_ci{
3498c2ecf20Sopenharmony_ci	dw_edma_v0_debugfs_off();
3508c2ecf20Sopenharmony_ci}
351