Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/dma/dw-edma/dw-edma-core.h
26282 views
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 <[email protected]>
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[32];
100
101
struct dma_device dma;
102
103
u16 wr_ch_cnt;
104
u16 rd_ch_cnt;
105
106
struct dw_edma_irq *irq;
107
int nr_irqs;
108
109
struct dw_edma_chan *chan;
110
111
raw_spinlock_t lock; /* Only for legacy */
112
113
struct dw_edma_chip *chip;
114
115
const struct dw_edma_core_ops *core;
116
};
117
118
typedef void (*dw_edma_handler_t)(struct dw_edma_chan *);
119
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);
129
};
130
131
struct dw_edma_sg {
132
struct scatterlist *sgl;
133
unsigned int len;
134
};
135
136
struct dw_edma_cyclic {
137
dma_addr_t paddr;
138
size_t len;
139
size_t cnt;
140
};
141
142
struct dw_edma_transfer {
143
struct dma_chan *dchan;
144
union dw_edma_xfer {
145
struct dw_edma_sg sg;
146
struct dw_edma_cyclic cyclic;
147
struct dma_interleaved_template *il;
148
} xfer;
149
enum dma_transfer_direction direction;
150
unsigned long flags;
151
enum dw_edma_xfer_type type;
152
};
153
154
static inline
155
struct dw_edma_chan *vc2dw_edma_chan(struct virt_dma_chan *vc)
156
{
157
return container_of(vc, struct dw_edma_chan, vc);
158
}
159
160
static inline
161
struct dw_edma_chan *dchan2dw_edma_chan(struct dma_chan *dchan)
162
{
163
return vc2dw_edma_chan(to_virt_chan(dchan));
164
}
165
166
static inline
167
void dw_edma_core_off(struct dw_edma *dw)
168
{
169
dw->core->off(dw);
170
}
171
172
static inline
173
u16 dw_edma_core_ch_count(struct dw_edma *dw, enum dw_edma_dir dir)
174
{
175
return dw->core->ch_count(dw, dir);
176
}
177
178
static inline
179
enum dma_status dw_edma_core_ch_status(struct dw_edma_chan *chan)
180
{
181
return chan->dw->core->ch_status(chan);
182
}
183
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)
187
{
188
return dw_irq->dw->core->handle_int(dw_irq, dir, done, abort);
189
}
190
191
static inline
192
void dw_edma_core_start(struct dw_edma *dw, struct dw_edma_chunk *chunk, bool first)
193
{
194
dw->core->start(chunk, first);
195
}
196
197
static inline
198
void dw_edma_core_ch_config(struct dw_edma_chan *chan)
199
{
200
chan->dw->core->ch_config(chan);
201
}
202
203
static inline
204
void dw_edma_core_debugfs_on(struct dw_edma *dw)
205
{
206
dw->core->debugfs_on(dw);
207
}
208
209
#endif /* _DW_EDMA_CORE_H */
210
211