xref: /freebsd/sys/dev/xdma/xdma.h (revision b0b1dbdd)
1 /*-
2  * Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
3  * All rights reserved.
4  *
5  * This software was developed by SRI International and the University of
6  * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
7  * ("CTSRD"), as part of the DARPA CRASH research programme.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * $FreeBSD$
31  */
32 
33 #ifndef _DEV_EXTRES_XDMA_H_
34 #define _DEV_EXTRES_XDMA_H_
35 
36 enum xdma_direction {
37 	XDMA_MEM_TO_MEM,
38 	XDMA_MEM_TO_DEV,
39 	XDMA_DEV_TO_MEM,
40 	XDMA_DEV_TO_DEV,
41 };
42 
43 enum xdma_operation_type {
44 	XDMA_MEMCPY,
45 	XDMA_SG,
46 	XDMA_CYCLIC,
47 };
48 
49 enum xdma_command {
50 	XDMA_CMD_BEGIN,
51 	XDMA_CMD_PAUSE,
52 	XDMA_CMD_TERMINATE,
53 	XDMA_CMD_TERMINATE_ALL,
54 };
55 
56 struct xdma_controller {
57 	device_t dev;		/* DMA consumer device_t. */
58 	device_t dma_dev;	/* A real DMA device_t. */
59 	void *data;		/* OFW MD part. */
60 
61 	/* List of virtual channels allocated. */
62 	TAILQ_HEAD(xdma_channel_list, xdma_channel)	channels;
63 };
64 
65 typedef struct xdma_controller xdma_controller_t;
66 
67 struct xdma_channel_config {
68 	enum xdma_direction	direction;
69 	uintptr_t		src_addr;	/* Physical address. */
70 	uintptr_t		dst_addr;	/* Physical address. */
71 	int			block_len;	/* In bytes. */
72 	int			block_num;	/* Count of blocks. */
73 	int			src_width;	/* In bytes. */
74 	int			dst_width;	/* In bytes. */
75 };
76 
77 typedef struct xdma_channel_config xdma_config_t;
78 
79 struct xdma_descriptor {
80 	bus_addr_t	ds_addr;
81 	bus_size_t	ds_len;
82 };
83 
84 typedef struct xdma_descriptor xdma_descriptor_t;
85 
86 struct xdma_channel {
87 	xdma_controller_t		*xdma;
88 	xdma_config_t			conf;
89 
90 	uint8_t				flags;
91 #define	XCHAN_DESC_ALLOCATED		(1 << 0)
92 #define	XCHAN_CONFIGURED		(1 << 1)
93 #define	XCHAN_TYPE_CYCLIC		(1 << 2)
94 #define	XCHAN_TYPE_MEMCPY		(1 << 3)
95 
96 	/* A real hardware driver channel. */
97 	void				*chan;
98 
99 	/* Interrupt handlers. */
100 	TAILQ_HEAD(, xdma_intr_handler)	ie_handlers;
101 
102 	/* Descriptors. */
103 	bus_dma_tag_t			dma_tag;
104 	bus_dmamap_t			dma_map;
105 	void				*descs;
106 	xdma_descriptor_t		*descs_phys;
107 	uint8_t				map_err;
108 
109 	struct mtx			mtx_lock;
110 
111 	TAILQ_ENTRY(xdma_channel)	xchan_next;
112 };
113 
114 typedef struct xdma_channel xdma_channel_t;
115 
116 /* xDMA controller alloc/free */
117 xdma_controller_t *xdma_ofw_get(device_t dev, const char *prop);
118 int xdma_put(xdma_controller_t *xdma);
119 
120 xdma_channel_t * xdma_channel_alloc(xdma_controller_t *);
121 int xdma_channel_free(xdma_channel_t *);
122 
123 int xdma_prep_cyclic(xdma_channel_t *, enum xdma_direction,
124     uintptr_t, uintptr_t, int, int, int, int);
125 int xdma_prep_memcpy(xdma_channel_t *, uintptr_t, uintptr_t, size_t len);
126 int xdma_desc_alloc(xdma_channel_t *, uint32_t, uint32_t);
127 int xdma_desc_free(xdma_channel_t *xchan);
128 
129 /* Channel Control */
130 int xdma_begin(xdma_channel_t *xchan);
131 int xdma_pause(xdma_channel_t *xchan);
132 int xdma_terminate(xdma_channel_t *xchan);
133 
134 /* Interrupt callback */
135 int xdma_setup_intr(xdma_channel_t *xchan, int (*cb)(void *), void *arg, void **);
136 int xdma_teardown_intr(xdma_channel_t *xchan, struct xdma_intr_handler *ih);
137 int xdma_teardown_all_intr(xdma_channel_t *xchan);
138 int xdma_callback(struct xdma_channel *xchan);
139 void xdma_assert_locked(void);
140 
141 struct xdma_intr_handler {
142 	int				(*cb)(void *);
143 	void				*cb_user;
144 	struct mtx			ih_lock;
145 	TAILQ_ENTRY(xdma_intr_handler)	ih_next;
146 };
147 
148 #endif /* !_DEV_EXTRES_XDMA_H_ */
149