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