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_mode {
25 	EDMA_MODE_LEGACY = 0,
26 	EDMA_MODE_UNROLL
27 };
28 
29 enum dw_edma_request {
30 	EDMA_REQ_NONE = 0,
31 	EDMA_REQ_STOP,
32 	EDMA_REQ_PAUSE
33 };
34 
35 enum dw_edma_status {
36 	EDMA_ST_IDLE = 0,
37 	EDMA_ST_PAUSE,
38 	EDMA_ST_BUSY
39 };
40 
41 struct dw_edma_chan;
42 struct dw_edma_chunk;
43 
44 struct dw_edma_burst {
45 	struct list_head		list;
46 	u64				sar;
47 	u64				dar;
48 	u32				sz;
49 };
50 
51 struct dw_edma_region {
52 	phys_addr_t			paddr;
53 	void				__iomem *vaddr;
54 	size_t				sz;
55 };
56 
57 struct dw_edma_chunk {
58 	struct list_head		list;
59 	struct dw_edma_chan		*chan;
60 	struct dw_edma_burst		*burst;
61 
62 	u32				bursts_alloc;
63 
64 	u8				cb;
65 	struct dw_edma_region		ll_region;	/* Linked list */
66 };
67 
68 struct dw_edma_desc {
69 	struct virt_dma_desc		vd;
70 	struct dw_edma_chan		*chan;
71 	struct dw_edma_chunk		*chunk;
72 
73 	u32				chunks_alloc;
74 
75 	u32				alloc_sz;
76 	u32				xfer_sz;
77 };
78 
79 struct dw_edma_chan {
80 	struct virt_dma_chan		vc;
81 	struct dw_edma_chip		*chip;
82 	int				id;
83 	enum dw_edma_dir		dir;
84 
85 	off_t				ll_off;
86 	u32				ll_max;
87 
88 	off_t				dt_off;
89 
90 	struct msi_msg			msi;
91 
92 	enum dw_edma_request		request;
93 	enum dw_edma_status		status;
94 	u8				configured;
95 
96 	struct dma_slave_config		config;
97 };
98 
99 struct dw_edma_irq {
100 	struct msi_msg                  msi;
101 	u32				wr_mask;
102 	u32				rd_mask;
103 	struct dw_edma			*dw;
104 };
105 
106 struct dw_edma_core_ops {
107 	int	(*irq_vector)(struct device *dev, unsigned int nr);
108 };
109 
110 struct dw_edma {
111 	char				name[20];
112 
113 	struct dma_device		wr_edma;
114 	u16				wr_ch_cnt;
115 
116 	struct dma_device		rd_edma;
117 	u16				rd_ch_cnt;
118 
119 	struct dw_edma_region		rg_region;	/* Registers */
120 	struct dw_edma_region		ll_region;	/* Linked list */
121 	struct dw_edma_region		dt_region;	/* Data */
122 
123 	struct dw_edma_irq		*irq;
124 	int				nr_irqs;
125 
126 	u32				version;
127 	enum dw_edma_mode		mode;
128 
129 	struct dw_edma_chan		*chan;
130 	const struct dw_edma_core_ops	*ops;
131 
132 	raw_spinlock_t			lock;		/* Only for legacy */
133 };
134 
135 struct dw_edma_sg {
136 	struct scatterlist		*sgl;
137 	unsigned int			len;
138 };
139 
140 struct dw_edma_cyclic {
141 	dma_addr_t			paddr;
142 	size_t				len;
143 	size_t				cnt;
144 };
145 
146 struct dw_edma_transfer {
147 	struct dma_chan			*dchan;
148 	union dw_edma_xfer {
149 		struct dw_edma_sg	sg;
150 		struct dw_edma_cyclic	cyclic;
151 	} xfer;
152 	enum dma_transfer_direction	direction;
153 	unsigned long			flags;
154 	bool				cyclic;
155 };
156 
157 static inline
158 struct dw_edma_chan *vc2dw_edma_chan(struct virt_dma_chan *vc)
159 {
160 	return container_of(vc, struct dw_edma_chan, vc);
161 }
162 
163 static inline
164 struct dw_edma_chan *dchan2dw_edma_chan(struct dma_chan *dchan)
165 {
166 	return vc2dw_edma_chan(to_virt_chan(dchan));
167 }
168 
169 #endif /* _DW_EDMA_CORE_H */
170