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
19enum dw_edma_dir {
20	EDMA_DIR_WRITE = 0,
21	EDMA_DIR_READ
22};
23
24enum dw_edma_mode {
25	EDMA_MODE_LEGACY = 0,
26	EDMA_MODE_UNROLL
27};
28
29enum dw_edma_request {
30	EDMA_REQ_NONE = 0,
31	EDMA_REQ_STOP,
32	EDMA_REQ_PAUSE
33};
34
35enum dw_edma_status {
36	EDMA_ST_IDLE = 0,
37	EDMA_ST_PAUSE,
38	EDMA_ST_BUSY
39};
40
41struct dw_edma_chan;
42struct dw_edma_chunk;
43
44struct dw_edma_burst {
45	struct list_head		list;
46	u64				sar;
47	u64				dar;
48	u32				sz;
49};
50
51struct dw_edma_region {
52	phys_addr_t			paddr;
53	void				__iomem *vaddr;
54	size_t				sz;
55};
56
57struct 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
68struct 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
79struct 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
99struct dw_edma_irq {
100	struct msi_msg                  msi;
101	u32				wr_mask;
102	u32				rd_mask;
103	struct dw_edma			*dw;
104};
105
106struct dw_edma_core_ops {
107	int	(*irq_vector)(struct device *dev, unsigned int nr);
108};
109
110struct 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
135struct dw_edma_sg {
136	struct scatterlist		*sgl;
137	unsigned int			len;
138};
139
140struct dw_edma_cyclic {
141	dma_addr_t			paddr;
142	size_t				len;
143	size_t				cnt;
144};
145
146struct 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
157static inline
158struct dw_edma_chan *vc2dw_edma_chan(struct virt_dma_chan *vc)
159{
160	return container_of(vc, struct dw_edma_chan, vc);
161}
162
163static inline
164struct 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