Commit a0594cefb7682dc0c32084d088b3ac0a85ed7395

Authored by Mugunthan V N
Committed by Jagan Teki
1 parent 18c61e9571

dm: implement a DMA uclass

Implement a DMA uclass so that the devices like ethernet, spi,
mmc etc can offload the data transfers from/to the device and
memory.

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Jagan Teki <jteki@openedev.com>

Showing 5 changed files with 176 additions and 0 deletions Side-by-side Diff

  1 +menu "DMA Support"
  2 +
  3 +config DMA
  4 + bool "Enable Driver Model for DMA drivers"
  5 + depends on DM
  6 + help
  7 + Enable driver model for DMA. DMA engines can do
  8 + asynchronous data transfers without involving the host
  9 + CPU. Currently, this framework can be used to offload
  10 + memory copies to and from devices like qspi, ethernet
  11 + etc Drivers provide methods to access the DMA devices
  12 + buses that is used to transfer data to and from memory.
  13 + The uclass interface is defined in include/dma.h.
  14 +
  15 +endmenu # menu "DMA Support"
drivers/dma/Makefile
... ... @@ -5,6 +5,8 @@
5 5 # SPDX-License-Identifier: GPL-2.0+
6 6 #
7 7  
  8 +obj-$(CONFIG_DMA) += dma-uclass.o
  9 +
8 10 obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
9 11 obj-$(CONFIG_APBH_DMA) += apbh_dma.o
10 12 obj-$(CONFIG_FSL_DMA) += fsl_dma.o
drivers/dma/dma-uclass.c
  1 +/*
  2 + * Direct Memory Access U-Class driver
  3 + *
  4 + * (C) Copyright 2015
  5 + * Texas Instruments Incorporated, <www.ti.com>
  6 + *
  7 + * Author: Mugunthan V N <mugunthanvnm@ti.com>
  8 + *
  9 + * SPDX-License-Identifier: GPL-2.0+
  10 + */
  11 +
  12 +#include <common.h>
  13 +#include <dma.h>
  14 +#include <dm.h>
  15 +#include <dm/uclass-internal.h>
  16 +#include <dm/device-internal.h>
  17 +#include <errno.h>
  18 +
  19 +DECLARE_GLOBAL_DATA_PTR;
  20 +
  21 +int dma_get_device(u32 transfer_type, struct udevice **devp)
  22 +{
  23 + struct udevice *dev;
  24 + int ret;
  25 +
  26 + for (ret = uclass_first_device(UCLASS_DMA, &dev); dev && !ret;
  27 + ret = uclass_next_device(&dev)) {
  28 + struct dma_dev_priv *uc_priv;
  29 +
  30 + uc_priv = dev_get_uclass_priv(dev);
  31 + if (uc_priv->supported & transfer_type)
  32 + break;
  33 + }
  34 +
  35 + if (!dev) {
  36 + error("No DMA device found that supports %x type\n",
  37 + transfer_type);
  38 + return -EPROTONOSUPPORT;
  39 + }
  40 +
  41 + *devp = dev;
  42 +
  43 + return ret;
  44 +}
  45 +
  46 +int dma_memcpy(void *dst, void *src, size_t len)
  47 +{
  48 + struct udevice *dev;
  49 + const struct dma_ops *ops;
  50 + int ret;
  51 +
  52 + ret = dma_get_device(DMA_SUPPORTS_MEM_TO_MEM, &dev);
  53 + if (ret < 0)
  54 + return ret;
  55 +
  56 + ops = device_get_ops(dev);
  57 + if (!ops->transfer)
  58 + return -ENOSYS;
  59 +
  60 + /* Invalidate the area, so no writeback into the RAM races with DMA */
  61 + invalidate_dcache_range((unsigned long)dst, (unsigned long)dst +
  62 + roundup(len, ARCH_DMA_MINALIGN));
  63 +
  64 + return ops->transfer(dev, DMA_MEM_TO_MEM, dst, src, len);
  65 +}
  66 +
  67 +UCLASS_DRIVER(dma) = {
  68 + .id = UCLASS_DMA,
  69 + .name = "dma",
  70 + .flags = DM_UC_FLAG_SEQ_ALIAS,
  71 + .per_device_auto_alloc_size = sizeof(struct dma_dev_priv),
  72 +};
include/dm/uclass-id.h
... ... @@ -31,6 +31,7 @@
31 31 UCLASS_CROS_EC, /* Chrome OS EC */
32 32 UCLASS_DISK, /* Disk controller, e.g. SATA */
33 33 UCLASS_DISPLAY, /* Display (e.g. DisplayPort, HDMI) */
  34 + UCLASS_DMA, /* Direct Memory Access */
34 35 UCLASS_RAM, /* RAM controller */
35 36 UCLASS_ETH, /* Ethernet device */
36 37 UCLASS_GPIO, /* Bank of general-purpose I/O pins */
  1 +/*
  2 + * (C) Copyright 2015
  3 + * Texas Instruments Incorporated, <www.ti.com>
  4 + *
  5 + * SPDX-License-Identifier: GPL-2.0+
  6 + */
  7 +
  8 +#ifndef _DMA_H_
  9 +#define _DMA_H_
  10 +
  11 +/*
  12 + * enum dma_direction - dma transfer direction indicator
  13 + * @DMA_MEM_TO_MEM: Memcpy mode
  14 + * @DMA_MEM_TO_DEV: From Memory to Device
  15 + * @DMA_DEV_TO_MEM: From Device to Memory
  16 + * @DMA_DEV_TO_DEV: From Device to Device
  17 + */
  18 +enum dma_direction {
  19 + DMA_MEM_TO_MEM,
  20 + DMA_MEM_TO_DEV,
  21 + DMA_DEV_TO_MEM,
  22 + DMA_DEV_TO_DEV,
  23 +};
  24 +
  25 +#define DMA_SUPPORTS_MEM_TO_MEM BIT(0)
  26 +#define DMA_SUPPORTS_MEM_TO_DEV BIT(1)
  27 +#define DMA_SUPPORTS_DEV_TO_MEM BIT(2)
  28 +#define DMA_SUPPORTS_DEV_TO_DEV BIT(3)
  29 +
  30 +/*
  31 + * struct dma_ops - Driver model DMA operations
  32 + *
  33 + * The uclass interface is implemented by all DMA devices which use
  34 + * driver model.
  35 + */
  36 +struct dma_ops {
  37 + /*
  38 + * Get the current timer count
  39 + *
  40 + * @dev: The DMA device
  41 + * @direction: direction of data transfer should be one from
  42 + enum dma_direction
  43 + * @dst: Destination pointer
  44 + * @src: Source pointer
  45 + * @len: Length of the data to be copied.
  46 + * @return: 0 if OK, -ve on error
  47 + */
  48 + int (*transfer)(struct udevice *dev, int direction, void *dst,
  49 + void *src, size_t len);
  50 +};
  51 +
  52 +/*
  53 + * struct dma_dev_priv - information about a device used by the uclass
  54 + *
  55 + * @supported: mode of transfers that DMA can support, should be
  56 + * one/multiple of DMA_SUPPORTS_*
  57 + */
  58 +struct dma_dev_priv {
  59 + u32 supported;
  60 +};
  61 +
  62 +/*
  63 + * dma_get_device - get a DMA device which supports transfer
  64 + * type of transfer_type
  65 + *
  66 + * @transfer_type - transfer type should be one/multiple of
  67 + * DMA_SUPPORTS_*
  68 + * @devp - udevice pointer to return the found device
  69 + * @return - will return on success and devp will hold the
  70 + * pointer to the device
  71 + */
  72 +int dma_get_device(u32 transfer_type, struct udevice **devp);
  73 +
  74 +/*
  75 + * dma_memcpy - try to use DMA to do a mem copy which will be
  76 + * much faster than CPU mem copy
  77 + *
  78 + * @dst - destination pointer
  79 + * @src - souce pointer
  80 + * @len - data length to be copied
  81 + * @return - on successful transfer returns no of bytes
  82 + transferred and on failure return error code.
  83 + */
  84 +int dma_memcpy(void *dst, void *src, size_t len);
  85 +
  86 +#endif /* _DMA_H_ */