Commit a0594cefb7682dc0c32084d088b3ac0a85ed7395
Committed by
Jagan Teki
1 parent
18c61e9571
Exists in
v2017.01-smarct4x
and in
30 other branches
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 Inline Diff
drivers/dma/Kconfig
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" | ||
16 |
drivers/dma/Makefile
1 | # | 1 | # |
2 | # (C) Copyright 2006 | 2 | # (C) Copyright 2006 |
3 | # Wolfgang Denk, DENX Software Engineering, wd@denx.de. | 3 | # Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
4 | # | 4 | # |
5 | # SPDX-License-Identifier: GPL-2.0+ | 5 | # SPDX-License-Identifier: GPL-2.0+ |
6 | # | 6 | # |
7 | 7 | ||
8 | obj-$(CONFIG_DMA) += dma-uclass.o | ||
9 | |||
8 | obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o | 10 | obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o |
9 | obj-$(CONFIG_APBH_DMA) += apbh_dma.o | 11 | obj-$(CONFIG_APBH_DMA) += apbh_dma.o |
10 | obj-$(CONFIG_FSL_DMA) += fsl_dma.o | 12 | obj-$(CONFIG_FSL_DMA) += fsl_dma.o |
11 | obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o | 13 | obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o |
12 | obj-$(CONFIG_TI_EDMA3) += ti-edma3.o | 14 | obj-$(CONFIG_TI_EDMA3) += ti-edma3.o |
13 | obj-$(CONFIG_DMA_LPC32XX) += lpc32xx_dma.o | 15 | obj-$(CONFIG_DMA_LPC32XX) += lpc32xx_dma.o |
14 | 16 |
drivers/dma/dma-uclass.c
File was created | 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 | }; | ||
73 |
include/dm/uclass-id.h
1 | /* | 1 | /* |
2 | * Copyright (c) 2013 Google, Inc | 2 | * Copyright (c) 2013 Google, Inc |
3 | * | 3 | * |
4 | * (C) Copyright 2012 | 4 | * (C) Copyright 2012 |
5 | * Pavel Herrmann <morpheus.ibis@gmail.com> | 5 | * Pavel Herrmann <morpheus.ibis@gmail.com> |
6 | * | 6 | * |
7 | * SPDX-License-Identifier: GPL-2.0+ | 7 | * SPDX-License-Identifier: GPL-2.0+ |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #ifndef _DM_UCLASS_ID_H | 10 | #ifndef _DM_UCLASS_ID_H |
11 | #define _DM_UCLASS_ID_H | 11 | #define _DM_UCLASS_ID_H |
12 | 12 | ||
13 | /* TODO(sjg@chromium.org): this could be compile-time generated */ | 13 | /* TODO(sjg@chromium.org): this could be compile-time generated */ |
14 | enum uclass_id { | 14 | enum uclass_id { |
15 | /* These are used internally by driver model */ | 15 | /* These are used internally by driver model */ |
16 | UCLASS_ROOT = 0, | 16 | UCLASS_ROOT = 0, |
17 | UCLASS_DEMO, | 17 | UCLASS_DEMO, |
18 | UCLASS_TEST, | 18 | UCLASS_TEST, |
19 | UCLASS_TEST_FDT, | 19 | UCLASS_TEST_FDT, |
20 | UCLASS_TEST_BUS, | 20 | UCLASS_TEST_BUS, |
21 | UCLASS_SPI_EMUL, /* sandbox SPI device emulator */ | 21 | UCLASS_SPI_EMUL, /* sandbox SPI device emulator */ |
22 | UCLASS_I2C_EMUL, /* sandbox I2C device emulator */ | 22 | UCLASS_I2C_EMUL, /* sandbox I2C device emulator */ |
23 | UCLASS_PCI_EMUL, /* sandbox PCI device emulator */ | 23 | UCLASS_PCI_EMUL, /* sandbox PCI device emulator */ |
24 | UCLASS_USB_EMUL, /* sandbox USB bus device emulator */ | 24 | UCLASS_USB_EMUL, /* sandbox USB bus device emulator */ |
25 | UCLASS_SIMPLE_BUS, /* bus with child devices */ | 25 | UCLASS_SIMPLE_BUS, /* bus with child devices */ |
26 | 26 | ||
27 | /* U-Boot uclasses start here - in alphabetical order */ | 27 | /* U-Boot uclasses start here - in alphabetical order */ |
28 | UCLASS_ADC, /* Analog-to-digital converter */ | 28 | UCLASS_ADC, /* Analog-to-digital converter */ |
29 | UCLASS_CLK, /* Clock source, e.g. used by peripherals */ | 29 | UCLASS_CLK, /* Clock source, e.g. used by peripherals */ |
30 | UCLASS_CPU, /* CPU, typically part of an SoC */ | 30 | UCLASS_CPU, /* CPU, typically part of an SoC */ |
31 | UCLASS_CROS_EC, /* Chrome OS EC */ | 31 | UCLASS_CROS_EC, /* Chrome OS EC */ |
32 | UCLASS_DISK, /* Disk controller, e.g. SATA */ | 32 | UCLASS_DISK, /* Disk controller, e.g. SATA */ |
33 | UCLASS_DISPLAY, /* Display (e.g. DisplayPort, HDMI) */ | 33 | UCLASS_DISPLAY, /* Display (e.g. DisplayPort, HDMI) */ |
34 | UCLASS_DMA, /* Direct Memory Access */ | ||
34 | UCLASS_RAM, /* RAM controller */ | 35 | UCLASS_RAM, /* RAM controller */ |
35 | UCLASS_ETH, /* Ethernet device */ | 36 | UCLASS_ETH, /* Ethernet device */ |
36 | UCLASS_GPIO, /* Bank of general-purpose I/O pins */ | 37 | UCLASS_GPIO, /* Bank of general-purpose I/O pins */ |
37 | UCLASS_I2C, /* I2C bus */ | 38 | UCLASS_I2C, /* I2C bus */ |
38 | UCLASS_I2C_EEPROM, /* I2C EEPROM device */ | 39 | UCLASS_I2C_EEPROM, /* I2C EEPROM device */ |
39 | UCLASS_I2C_GENERIC, /* Generic I2C device */ | 40 | UCLASS_I2C_GENERIC, /* Generic I2C device */ |
40 | UCLASS_I2C_MUX, /* I2C multiplexer */ | 41 | UCLASS_I2C_MUX, /* I2C multiplexer */ |
41 | UCLASS_IRQ, /* Interrupt controller */ | 42 | UCLASS_IRQ, /* Interrupt controller */ |
42 | UCLASS_KEYBOARD, /* Keyboard input device */ | 43 | UCLASS_KEYBOARD, /* Keyboard input device */ |
43 | UCLASS_LED, /* Light-emitting diode (LED) */ | 44 | UCLASS_LED, /* Light-emitting diode (LED) */ |
44 | UCLASS_LPC, /* x86 'low pin count' interface */ | 45 | UCLASS_LPC, /* x86 'low pin count' interface */ |
45 | UCLASS_MASS_STORAGE, /* Mass storage device */ | 46 | UCLASS_MASS_STORAGE, /* Mass storage device */ |
46 | UCLASS_MISC, /* Miscellaneous device */ | 47 | UCLASS_MISC, /* Miscellaneous device */ |
47 | UCLASS_MMC, /* SD / MMC card or chip */ | 48 | UCLASS_MMC, /* SD / MMC card or chip */ |
48 | UCLASS_MOD_EXP, /* RSA Mod Exp device */ | 49 | UCLASS_MOD_EXP, /* RSA Mod Exp device */ |
49 | UCLASS_MTD, /* Memory Technology Device (MTD) device */ | 50 | UCLASS_MTD, /* Memory Technology Device (MTD) device */ |
50 | UCLASS_NORTHBRIDGE, /* Intel Northbridge / SDRAM controller */ | 51 | UCLASS_NORTHBRIDGE, /* Intel Northbridge / SDRAM controller */ |
51 | UCLASS_PANEL, /* Display panel, such as an LCD */ | 52 | UCLASS_PANEL, /* Display panel, such as an LCD */ |
52 | UCLASS_PANEL_BACKLIGHT, /* Backlight controller for panel */ | 53 | UCLASS_PANEL_BACKLIGHT, /* Backlight controller for panel */ |
53 | UCLASS_PCH, /* x86 platform controller hub */ | 54 | UCLASS_PCH, /* x86 platform controller hub */ |
54 | UCLASS_PCI, /* PCI bus */ | 55 | UCLASS_PCI, /* PCI bus */ |
55 | UCLASS_PCI_GENERIC, /* Generic PCI bus device */ | 56 | UCLASS_PCI_GENERIC, /* Generic PCI bus device */ |
56 | UCLASS_PINCTRL, /* Pinctrl (pin muxing/configuration) device */ | 57 | UCLASS_PINCTRL, /* Pinctrl (pin muxing/configuration) device */ |
57 | UCLASS_PINCONFIG, /* Pin configuration node device */ | 58 | UCLASS_PINCONFIG, /* Pin configuration node device */ |
58 | UCLASS_PMIC, /* PMIC I/O device */ | 59 | UCLASS_PMIC, /* PMIC I/O device */ |
59 | UCLASS_PWM, /* Pulse-width modulator */ | 60 | UCLASS_PWM, /* Pulse-width modulator */ |
60 | UCLASS_PWRSEQ, /* Power sequence device */ | 61 | UCLASS_PWRSEQ, /* Power sequence device */ |
61 | UCLASS_REGULATOR, /* Regulator device */ | 62 | UCLASS_REGULATOR, /* Regulator device */ |
62 | UCLASS_RESET, /* Reset device */ | 63 | UCLASS_RESET, /* Reset device */ |
63 | UCLASS_REMOTEPROC, /* Remote Processor device */ | 64 | UCLASS_REMOTEPROC, /* Remote Processor device */ |
64 | UCLASS_RTC, /* Real time clock device */ | 65 | UCLASS_RTC, /* Real time clock device */ |
65 | UCLASS_SERIAL, /* Serial UART */ | 66 | UCLASS_SERIAL, /* Serial UART */ |
66 | UCLASS_SPI, /* SPI bus */ | 67 | UCLASS_SPI, /* SPI bus */ |
67 | UCLASS_SPI_FLASH, /* SPI flash */ | 68 | UCLASS_SPI_FLASH, /* SPI flash */ |
68 | UCLASS_SPI_GENERIC, /* Generic SPI flash target */ | 69 | UCLASS_SPI_GENERIC, /* Generic SPI flash target */ |
69 | UCLASS_SYSCON, /* System configuration device */ | 70 | UCLASS_SYSCON, /* System configuration device */ |
70 | UCLASS_THERMAL, /* Thermal sensor */ | 71 | UCLASS_THERMAL, /* Thermal sensor */ |
71 | UCLASS_TIMER, /* Timer device */ | 72 | UCLASS_TIMER, /* Timer device */ |
72 | UCLASS_TPM, /* Trusted Platform Module TIS interface */ | 73 | UCLASS_TPM, /* Trusted Platform Module TIS interface */ |
73 | UCLASS_USB, /* USB bus */ | 74 | UCLASS_USB, /* USB bus */ |
74 | UCLASS_USB_DEV_GENERIC, /* USB generic device */ | 75 | UCLASS_USB_DEV_GENERIC, /* USB generic device */ |
75 | UCLASS_USB_HUB, /* USB hub */ | 76 | UCLASS_USB_HUB, /* USB hub */ |
76 | UCLASS_VIDEO, /* Video or LCD device */ | 77 | UCLASS_VIDEO, /* Video or LCD device */ |
77 | UCLASS_VIDEO_BRIDGE, /* Video bridge, e.g. DisplayPort to LVDS */ | 78 | UCLASS_VIDEO_BRIDGE, /* Video bridge, e.g. DisplayPort to LVDS */ |
78 | UCLASS_VIDEO_CONSOLE, /* Text console driver for video device */ | 79 | UCLASS_VIDEO_CONSOLE, /* Text console driver for video device */ |
79 | 80 | ||
80 | UCLASS_COUNT, | 81 | UCLASS_COUNT, |
81 | UCLASS_INVALID = -1, | 82 | UCLASS_INVALID = -1, |
82 | }; | 83 | }; |
83 | 84 | ||
84 | #endif | 85 | #endif |
85 | 86 |
include/dma.h
File was created | 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_ */ | ||
87 |