1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * Copyright (c) 2018-2019 Synopsys, Inc. and/or its affiliates.
4 * Synopsys DesignWare eDMA core driver
5 *
6 * Author: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
7 */
8
9 #ifndef _DW_EDMA_CORE_H
10 #define _DW_EDMA_CORE_H
11
12 #include <linux/msi.h>
13 #include <linux/dma/edma.h>
14
15 #include "../virt-dma.h"
16
17 #define EDMA_LL_SZ 24
18
19 enum dw_edma_dir {
20 EDMA_DIR_WRITE = 0,
21 EDMA_DIR_READ
22 };
23
24 enum dw_edma_request {
25 EDMA_REQ_NONE = 0,
26 EDMA_REQ_STOP,
27 EDMA_REQ_PAUSE
28 };
29
30 enum dw_edma_status {
31 EDMA_ST_IDLE = 0,
32 EDMA_ST_PAUSE,
33 EDMA_ST_BUSY
34 };
35
36 enum dw_edma_xfer_type {
37 EDMA_XFER_SCATTER_GATHER = 0,
38 EDMA_XFER_CYCLIC,
39 EDMA_XFER_INTERLEAVED
40 };
41
42 struct dw_edma_chan;
43 struct dw_edma_chunk;
44
45 struct dw_edma_burst {
46 struct list_head list;
47 u64 sar;
48 u64 dar;
49 u32 sz;
50 };
51
52 struct dw_edma_chunk {
53 struct list_head list;
54 struct dw_edma_chan *chan;
55 struct dw_edma_burst *burst;
56
57 u32 bursts_alloc;
58
59 u8 cb;
60 struct dw_edma_region ll_region; /* Linked list */
61 };
62
63 struct dw_edma_desc {
64 struct virt_dma_desc vd;
65 struct dw_edma_chan *chan;
66 struct dw_edma_chunk *chunk;
67
68 u32 chunks_alloc;
69
70 u32 alloc_sz;
71 u32 xfer_sz;
72 };
73
74 struct dw_edma_chan {
75 struct virt_dma_chan vc;
76 struct dw_edma *dw;
77 int id;
78 enum dw_edma_dir dir;
79
80 u32 ll_max;
81
82 struct msi_msg msi;
83
84 enum dw_edma_request request;
85 enum dw_edma_status status;
86 u8 configured;
87
88 struct dma_slave_config config;
89 };
90
91 struct dw_edma_irq {
92 struct msi_msg msi;
93 u32 wr_mask;
94 u32 rd_mask;
95 struct dw_edma *dw;
96 };
97
98 struct dw_edma {
99 char name[20];
100
101 struct dma_device wr_edma;
102 u16 wr_ch_cnt;
103
104 struct dma_device rd_edma;
105 u16 rd_ch_cnt;
106
107 struct dw_edma_irq *irq;
108 int nr_irqs;
109
110 struct dw_edma_chan *chan;
111
112 raw_spinlock_t lock; /* Only for legacy */
113
114 struct dw_edma_chip *chip;
115 #ifdef CONFIG_DEBUG_FS
116 struct dentry *debugfs;
117 #endif /* CONFIG_DEBUG_FS */
118 };
119
120 struct dw_edma_sg {
121 struct scatterlist *sgl;
122 unsigned int len;
123 };
124
125 struct dw_edma_cyclic {
126 dma_addr_t paddr;
127 size_t len;
128 size_t cnt;
129 };
130
131 struct dw_edma_transfer {
132 struct dma_chan *dchan;
133 union dw_edma_xfer {
134 struct dw_edma_sg sg;
135 struct dw_edma_cyclic cyclic;
136 struct dma_interleaved_template *il;
137 } xfer;
138 enum dma_transfer_direction direction;
139 unsigned long flags;
140 enum dw_edma_xfer_type type;
141 };
142
143 static inline
vc2dw_edma_chan(struct virt_dma_chan * vc)144 struct dw_edma_chan *vc2dw_edma_chan(struct virt_dma_chan *vc)
145 {
146 return container_of(vc, struct dw_edma_chan, vc);
147 }
148
149 static inline
dchan2dw_edma_chan(struct dma_chan * dchan)150 struct dw_edma_chan *dchan2dw_edma_chan(struct dma_chan *dchan)
151 {
152 return vc2dw_edma_chan(to_virt_chan(dchan));
153 }
154
155 #endif /* _DW_EDMA_CORE_H */
156