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 */