1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates.
4 * Synopsys DesignWare eDMA core driver
6 * Author: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
9 #ifndef _DW_EDMA_CORE_H
10 #define _DW_EDMA_CORE_H
12 #include <linux/msi.h>
13 #include <linux/dma/edma.h>
15 #include "../virt-dma.h"
24 enum dw_edma_request {
36 enum dw_edma_xfer_type {
37 EDMA_XFER_SCATTER_GATHER = 0,
45 struct dw_edma_burst {
46 struct list_head list;
52 struct dw_edma_chunk {
53 struct list_head list;
54 struct dw_edma_chan *chan;
55 struct dw_edma_burst *burst;
60 struct dw_edma_region ll_region; /* Linked list */
64 struct virt_dma_desc vd;
65 struct dw_edma_chan *chan;
66 struct dw_edma_chunk *chunk;
75 struct virt_dma_chan vc;
84 enum dw_edma_request request;
85 enum dw_edma_status status;
88 struct dma_slave_config config;
101 struct dma_device dma;
106 struct dw_edma_irq *irq;
109 struct dw_edma_chan *chan;
111 raw_spinlock_t lock; /* Only for legacy */
113 struct dw_edma_chip *chip;
115 const struct dw_edma_core_ops *core;
118 typedef void (*dw_edma_handler_t)(struct dw_edma_chan *);
120 struct dw_edma_core_ops {
121 void (*off)(struct dw_edma *dw);
122 u16 (*ch_count)(struct dw_edma *dw, enum dw_edma_dir dir);
123 enum dma_status (*ch_status)(struct dw_edma_chan *chan);
124 irqreturn_t (*handle_int)(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir,
125 dw_edma_handler_t done, dw_edma_handler_t abort);
126 void (*start)(struct dw_edma_chunk *chunk, bool first);
127 void (*ch_config)(struct dw_edma_chan *chan);
128 void (*debugfs_on)(struct dw_edma *dw);
132 struct scatterlist *sgl;
136 struct dw_edma_cyclic {
142 struct dw_edma_transfer {
143 struct dma_chan *dchan;
145 struct dw_edma_sg sg;
146 struct dw_edma_cyclic cyclic;
147 struct dma_interleaved_template *il;
149 enum dma_transfer_direction direction;
151 enum dw_edma_xfer_type type;
155 struct dw_edma_chan *vc2dw_edma_chan(struct virt_dma_chan *vc)
157 return container_of(vc, struct dw_edma_chan, vc);
161 struct dw_edma_chan *dchan2dw_edma_chan(struct dma_chan *dchan)
163 return vc2dw_edma_chan(to_virt_chan(dchan));
167 void dw_edma_core_off(struct dw_edma *dw)
173 u16 dw_edma_core_ch_count(struct dw_edma *dw, enum dw_edma_dir dir)
175 return dw->core->ch_count(dw, dir);
179 enum dma_status dw_edma_core_ch_status(struct dw_edma_chan *chan)
181 return chan->dw->core->ch_status(chan);
184 static inline irqreturn_t
185 dw_edma_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir,
186 dw_edma_handler_t done, dw_edma_handler_t abort)
188 return dw_irq->dw->core->handle_int(dw_irq, dir, done, abort);
192 void dw_edma_core_start(struct dw_edma *dw, struct dw_edma_chunk *chunk, bool first)
194 dw->core->start(chunk, first);
198 void dw_edma_core_ch_config(struct dw_edma_chan *chan)
200 chan->dw->core->ch_config(chan);
204 void dw_edma_core_debugfs_on(struct dw_edma *dw)
206 dw->core->debugfs_on(dw);
209 #endif /* _DW_EDMA_CORE_H */