Blame view
include/dma.h
10.2 KB
83d290c56 SPDX: Convert all... |
1 |
/* SPDX-License-Identifier: GPL-2.0+ */ |
a0594cefb dm: implement a D... |
2 |
/* |
27ab27f85 dma: add channels... |
3 4 5 6 |
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com> * Copyright (C) 2015 - 2018 Texas Instruments Incorporated <www.ti.com> * Written by Mugunthan V N <mugunthanvnm@ti.com> * |
a0594cefb dm: implement a D... |
7 8 9 10 |
*/ #ifndef _DMA_H_ #define _DMA_H_ |
27ab27f85 dma: add channels... |
11 12 |
#include <linux/errno.h> #include <linux/types.h> |
a0594cefb dm: implement a D... |
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
/* * enum dma_direction - dma transfer direction indicator * @DMA_MEM_TO_MEM: Memcpy mode * @DMA_MEM_TO_DEV: From Memory to Device * @DMA_DEV_TO_MEM: From Device to Memory * @DMA_DEV_TO_DEV: From Device to Device */ enum dma_direction { DMA_MEM_TO_MEM, DMA_MEM_TO_DEV, DMA_DEV_TO_MEM, DMA_DEV_TO_DEV, }; #define DMA_SUPPORTS_MEM_TO_MEM BIT(0) #define DMA_SUPPORTS_MEM_TO_DEV BIT(1) #define DMA_SUPPORTS_DEV_TO_MEM BIT(2) #define DMA_SUPPORTS_DEV_TO_DEV BIT(3) /* |
a0594cefb dm: implement a D... |
33 34 35 36 37 38 39 40 |
* struct dma_dev_priv - information about a device used by the uclass * * @supported: mode of transfers that DMA can support, should be * one/multiple of DMA_SUPPORTS_* */ struct dma_dev_priv { u32 supported; }; |
27ab27f85 dma: add channels... |
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
#ifdef CONFIG_DMA_CHANNELS /** * A DMA is a feature of computer systems that allows certain hardware * subsystems to access main system memory, independent of the CPU. * DMA channels are typically generated externally to the HW module * consuming them, by an entity this API calls a DMA provider. This API * provides a standard means for drivers to enable and disable DMAs, and to * copy, send and receive data using DMA. * * A driver that implements UCLASS_DMA is a DMA provider. A provider will * often implement multiple separate DMAs, since the hardware it manages * often has this capability. dma_uclass.h describes the interface which * DMA providers must implement. * * DMA consumers/clients are the HW modules driven by the DMA channels. This * header file describes the API used by drivers for those HW modules. * * DMA consumer DMA_MEM_TO_DEV (transmit) usage example (based on networking). * Note. dma_send() is sync operation always - it'll start transfer and will * poll for it to complete: * - get/request dma channel * struct dma dma_tx; * ret = dma_get_by_name(common->dev, "tx0", &dma_tx); * if (ret) ... * * - enable dma channel * ret = dma_enable(&dma_tx); * if (ret) ... * * - dma transmit DMA_MEM_TO_DEV. * struct ti_drv_packet_data packet_data; * * packet_data.opt1 = val1; * packet_data.opt2 = val2; * ret = dma_send(&dma_tx, packet, length, &packet_data); * if (ret) .. * * DMA consumer DMA_DEV_TO_MEM (receive) usage example (based on networking). * Note. dma_receive() is sync operation always - it'll start transfer * (if required) and will poll for it to complete (or for any previously * configured dev2mem transfer to complete): * - get/request dma channel * struct dma dma_rx; * ret = dma_get_by_name(common->dev, "rx0", &dma_rx); * if (ret) ... * * - enable dma channel * ret = dma_enable(&dma_rx); * if (ret) ... * * - dma receive DMA_DEV_TO_MEM. * struct ti_drv_packet_data packet_data; * * len = dma_receive(&dma_rx, (void **)packet, &packet_data); * if (ret < 0) ... * * DMA consumer DMA_DEV_TO_MEM (receive) zero-copy usage example (based on * networking). Networking subsystem allows to configure and use few receive * buffers (dev2mem), as Networking RX DMA channels usually implemented * as streaming interface * - get/request dma channel * struct dma dma_rx; * ret = dma_get_by_name(common->dev, "rx0", &dma_rx); * if (ret) ... * * for (i = 0; i < RX_DESC_NUM; i++) { * ret = dma_prepare_rcv_buf(&dma_rx, * net_rx_packets[i], * RX_BUF_SIZE); * if (ret) ... * } * * - enable dma channel * ret = dma_enable(&dma_rx); * if (ret) ... * * - dma receive DMA_DEV_TO_MEM. * struct ti_drv_packet_data packet_data; * * len = dma_receive(&dma_rx, (void **)packet, &packet_data); * if (ret < 0) .. * * -- process packet -- * * - return buffer back to DAM channel * ret = dma_prepare_rcv_buf(&dma_rx, * net_rx_packets[rx_next], * RX_BUF_SIZE); */ struct udevice; /** * struct dma - A handle to (allowing control of) a single DMA. * * Clients provide storage for DMA handles. The content of the structure is * managed solely by the DMA API and DMA drivers. A DMA struct is * initialized by "get"ing the DMA struct. The DMA struct is passed to all * other DMA APIs to identify which DMA channel to operate upon. * * @dev: The device which implements the DMA channel. * @id: The DMA channel ID within the provider. * * Currently, the DMA API assumes that a single integer ID is enough to * identify and configure any DMA channel for any DMA provider. If this * assumption becomes invalid in the future, the struct could be expanded to * either (a) add more fields to allow DMA providers to store additional * information, or (b) replace the id field with an opaque pointer, which the * provider would dynamically allocated during its .of_xlate op, and process * during is .request op. This may require the addition of an extra op to clean * up the allocation. */ struct dma { struct udevice *dev; /* * Written by of_xlate. We assume a single id is enough for now. In the * future, we might add more fields here. */ unsigned long id; }; # if CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(DMA) /** * dma_get_by_index - Get/request a DMA by integer index. * * This looks up and requests a DMA. The index is relative to the client * device; each device is assumed to have n DMAs associated with it somehow, * and this function finds and requests one of them. The mapping of client * device DMA indices to provider DMAs may be via device-tree properties, * board-provided mapping tables, or some other mechanism. * * @dev: The client device. * @index: The index of the DMA to request, within the client's list of * DMA channels. * @dma: A pointer to a DMA struct to initialize. * @return 0 if OK, or a negative error code. */ int dma_get_by_index(struct udevice *dev, int index, struct dma *dma); /** * dma_get_by_name - Get/request a DMA by name. * * This looks up and requests a DMA. The name is relative to the client * device; each device is assumed to have n DMAs associated with it somehow, * and this function finds and requests one of them. The mapping of client * device DMA names to provider DMAs may be via device-tree properties, * board-provided mapping tables, or some other mechanism. * * @dev: The client device. * @name: The name of the DMA to request, within the client's list of * DMA channels. * @dma: A pointer to a DMA struct to initialize. * @return 0 if OK, or a negative error code. */ int dma_get_by_name(struct udevice *dev, const char *name, struct dma *dma); # else static inline int dma_get_by_index(struct udevice *dev, int index, struct dma *dma) { return -ENOSYS; } static inline int dma_get_by_name(struct udevice *dev, const char *name, struct dma *dma) { return -ENOSYS; } # endif /** * dma_request - Request a DMA by provider-specific ID. * * This requests a DMA using a provider-specific ID. Generally, this function * should not be used, since dma_get_by_index/name() provide an interface that * better separates clients from intimate knowledge of DMA providers. * However, this function may be useful in core SoC-specific code. * * @dev: The DMA provider device. * @dma: A pointer to a DMA struct to initialize. The caller must * have already initialized any field in this struct which the * DMA provider uses to identify the DMA channel. * @return 0 if OK, or a negative error code. */ int dma_request(struct udevice *dev, struct dma *dma); /** * dma_free - Free a previously requested DMA. * * @dma: A DMA struct that was previously successfully requested by * dma_request/get_by_*(). * @return 0 if OK, or a negative error code. */ int dma_free(struct dma *dma); /** * dma_enable() - Enable (turn on) a DMA channel. * * @dma: A DMA struct that was previously successfully requested by * dma_request/get_by_*(). * @return zero on success, or -ve error code. */ int dma_enable(struct dma *dma); /** * dma_disable() - Disable (turn off) a DMA channel. * * @dma: A DMA struct that was previously successfully requested by * dma_request/get_by_*(). * @return zero on success, or -ve error code. */ int dma_disable(struct dma *dma); /** * dma_prepare_rcv_buf() - Prepare/add receive DMA buffer. * * It allows to implement zero-copy async DMA_DEV_TO_MEM (receive) transactions * if supported by DMA providers. * * @dma: A DMA struct that was previously successfully requested by * dma_request/get_by_*(). * @dst: The receive buffer pointer. * @size: The receive buffer size * @return zero on success, or -ve error code. */ int dma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size); /** * dma_receive() - Receive a DMA transfer. * * @dma: A DMA struct that was previously successfully requested by * dma_request/get_by_*(). * @dst: The destination pointer. * @metadata: DMA driver's channel specific data * @return length of received data on success, or zero - no data, * or -ve error code. */ int dma_receive(struct dma *dma, void **dst, void *metadata); /** * dma_send() - Send a DMA transfer. * * @dma: A DMA struct that was previously successfully requested by * dma_request/get_by_*(). * @src: The source pointer. * @len: Length of the data to be sent (number of bytes). * @metadata: DMA driver's channel specific data * @return zero on success, or -ve error code. */ int dma_send(struct dma *dma, void *src, size_t len, void *metadata); #endif /* CONFIG_DMA_CHANNELS */ |
a0594cefb dm: implement a D... |
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
/* * dma_get_device - get a DMA device which supports transfer * type of transfer_type * * @transfer_type - transfer type should be one/multiple of * DMA_SUPPORTS_* * @devp - udevice pointer to return the found device * @return - will return on success and devp will hold the * pointer to the device */ int dma_get_device(u32 transfer_type, struct udevice **devp); /* * dma_memcpy - try to use DMA to do a mem copy which will be * much faster than CPU mem copy * * @dst - destination pointer * @src - souce pointer * @len - data length to be copied * @return - on successful transfer returns no of bytes transferred and on failure return error code. */ int dma_memcpy(void *dst, void *src, size_t len); #endif /* _DMA_H_ */ |