1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Direct Memory Access U-Class driver 4 * 5 * (C) Copyright 2015 6 * Texas Instruments Incorporated, <www.ti.com> 7 * 8 * Author: Mugunthan V N <mugunthanvnm@ti.com> 9 */ 10 11 #include <common.h> 12 #include <dma.h> 13 #include <dm.h> 14 #include <dm/uclass-internal.h> 15 #include <dm/device-internal.h> 16 #include <errno.h> 17 18 int dma_get_device(u32 transfer_type, struct udevice **devp) 19 { 20 struct udevice *dev; 21 int ret; 22 23 for (ret = uclass_first_device(UCLASS_DMA, &dev); dev && !ret; 24 ret = uclass_next_device(&dev)) { 25 struct dma_dev_priv *uc_priv; 26 27 uc_priv = dev_get_uclass_priv(dev); 28 if (uc_priv->supported & transfer_type) 29 break; 30 } 31 32 if (!dev) { 33 pr_err("No DMA device found that supports %x type\n", 34 transfer_type); 35 return -EPROTONOSUPPORT; 36 } 37 38 *devp = dev; 39 40 return ret; 41 } 42 43 int dma_memcpy(void *dst, void *src, size_t len) 44 { 45 struct udevice *dev; 46 const struct dma_ops *ops; 47 int ret; 48 49 ret = dma_get_device(DMA_SUPPORTS_MEM_TO_MEM, &dev); 50 if (ret < 0) 51 return ret; 52 53 ops = device_get_ops(dev); 54 if (!ops->transfer) 55 return -ENOSYS; 56 57 /* Invalidate the area, so no writeback into the RAM races with DMA */ 58 invalidate_dcache_range((unsigned long)dst, (unsigned long)dst + 59 roundup(len, ARCH_DMA_MINALIGN)); 60 61 return ops->transfer(dev, DMA_MEM_TO_MEM, dst, src, len); 62 } 63 64 UCLASS_DRIVER(dma) = { 65 .id = UCLASS_DMA, 66 .name = "dma", 67 .flags = DM_UC_FLAG_SEQ_ALIAS, 68 .per_device_auto_alloc_size = sizeof(struct dma_dev_priv), 69 }; 70