bmips: add bcm6348-enet support
Subsystems (5)
cover bmips: add bcm6348-enet support
In order to add bcm6348-enet support, dma-uclass must be extended to support dma channels and rewordked to operate like the other dm uclass (clk, reset...).
This is an RFC, so please give you feedback on the things that I should fix or rework.
Álvaro Fernández Rojas (14):
dma: add dma channels support and improve uclass
dma: add bcm6348-iudma support
bmips: bcm6338: add bcm6348-iudma support
bmips: bcm6348: add bcm6348-iudma support
bmips: bcm6358: add bcm6348-iudma support
phy: add support for internal phys
net: add support for bcm6348-enet
bmips: bcm6338: add support for bcm6348-enet
bmips: enable f at st1704 enet support
bmips: bcm6348: add support for bcm6348-enet
bmips: enable ct-5361 enet support
bmips: bcm6358: add support for bcm6348-enet
bmips: enable hg556a enet support
bmips: enable nb4-ser enet support
arch/mips/dts/brcm,bcm6338.dtsi | 29 ++ arch/mips/dts/brcm,bcm6348.dtsi | 42 +++ arch/mips/dts/brcm,bcm6358.dtsi | 46 +++ arch/mips/dts/comtrend,ct-5361.dts | 12 + arch/mips/dts/huawei,hg556a.dts | 12 + arch/mips/dts/sagem,f at st1704.dts | 12 + arch/mips/dts/sfr,nb4-ser.dts | 24 ++ configs/comtrend_ct5361_ram_defconfig | 8 +- configs/huawei_hg556a_ram_defconfig | 8 +- configs/sagem_f at st1704_ram_defconfig | 9 +- configs/sfr_nb4-ser_ram_defconfig | 8 +- drivers/dma/Kconfig | 8 + drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 498 ++++++++++++++++++++++++++++++++ drivers/dma/dma-uclass.c | 212 +++++++++++--- drivers/mtd/spi/sf-uclass.c | 17 ++ drivers/mtd/spi/spi_flash.c | 11 +- drivers/net/Kconfig | 9 + drivers/net/Makefile | 1 + drivers/net/bcm6348-eth.c | 517 ++++++++++++++++++++++++++++++++++ include/configs/bmips_common.h | 5 +- include/dma-uclass.h | 110 ++++++++ include/dma.h | 226 +++++++++++---- include/dt-bindings/dma/bcm6338-dma.h | 15 + include/dt-bindings/dma/bcm6348-dma.h | 17 ++ include/dt-bindings/dma/bcm6358-dma.h | 17 ++ include/phy.h | 2 + include/spi_flash.h | 3 + 28 files changed, 1780 insertions(+), 99 deletions(-) create mode 100644 drivers/dma/bcm6348-iudma.c create mode 100644 drivers/net/bcm6348-eth.c create mode 100644 include/dma-uclass.h create mode 100644 include/dt-bindings/dma/bcm6338-dma.h create mode 100644 include/dt-bindings/dma/bcm6348-dma.h create mode 100644 include/dt-bindings/dma/bcm6358-dma.h
Signature · 1 line
2.11.0
RFC 1/14 dma: add dma channels support and improve uclass
--- drivers/dma/dma-uclass.c | 212 ++++++++++++++++++++++++++++++++++------- drivers/mtd/spi/sf-uclass.c | 17 ++++ drivers/mtd/spi/spi_flash.c | 11 ++- include/dma-uclass.h | 110 +++++++++++++++++++++ include/dma.h | 226 +++++++++++++++++++++++++++++++++----------- include/spi_flash.h | 3 + 6 files changed, 485 insertions(+), 94 deletions(-) create mode 100644 include/dma-uclass.h
drivers/dma/dma-uclass.c +176 -36
@@ -1,59 +1,176 @@/* -* Direct Memory Access U-Class driver +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated, <www.ti.com> +* Written by Mugunthan V N <[email protected]> * -* (C) Copyright 2015 -* Texas Instruments Incorporated, <www.ti.com> -* -* Author: Mugunthan V N <[email protected]> -* -* SPDX-License-Identifier: GPL-2.0+ +* SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> -#include <dma.h> #include <dm.h> -#include <dm/uclass-internal.h> -#include <dm/device-internal.h> +#include <dma.h> +#include <dma-uclass.h> +#include <dt-structs.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ; -int dma_get_device (u32 transfer_type,struct udevice **devp) +static inline struct dma_ops *dma_dev_ops (struct udevice *dev) +{ +return (struct dma_ops *)dev->driver->ops; +} + +#if CONFIG_IS_ENABLED (OF_CONTROL ) +# if CONFIG_IS_ENABLED (OF_PLATDATA ) +int dma_get_by_index_platdata (struct udevice *dev,int index, +struct phandle_2_cell *cells,struct dma *dma) { -struct udevice *dev;int ret; -for (ret =uclass_first_device (UCLASS_DMA , &dev); dev && !ret; - ret =uclass_next_device (&dev)) { -struct dma_dev_priv *uc_priv; +if (index !=0 ) +return -ENOSYS ; + ret =uclass_get_device (UCLASS_DMA ,0 , &dma->dev); +if (ret) +return ret; + dma->id = cells[0 ].id; - uc_priv =dev_get_uclass_priv (dev); -if (uc_priv->supported & transfer_type) -break ; - } +return 0 ; +} +# else +static int dma_of_xlate_default (struct dma *dma, +struct fdtdec_phandle_args *args) +{ +debug ("%s(dma=%p)\n" , __func__, dma); -if (!dev) { -pr_err ("No DMA device found that supports %x type\n" , - transfer_type); -return -EPROTONOSUPPORT ; +if (args->args_count >1 ) { +pr_err ("Invaild args_count: %d\n" , args->args_count); +return -EINVAL ; } - *devp = dev; +if (args->args_count) + dma->id = args->args[0 ]; +else + dma->id =0 ; -return ret; +return 0 ; } -int dma_memcpy (void *dst,void *src,size_t len) +int dma_get_by_index (struct udevice *dev,int index,struct dma *dma) { -struct udevice *dev; -const struct dma_ops *ops;int ret; +struct fdtdec_phandle_args args; +struct udevice *dev_dma; +struct dma_ops *ops; + +debug ("%s(dev=%p, index=%d, dma=%p)\n" , __func__, dev, index, dma); - ret =dma_get_device (DMA_SUPPORTS_MEM_TO_MEM , &dev); -if (ret <0 ) +assert (dma); + ret =fdtdec_parse_phandle_with_args (gd->fdt_blob,dev_of_offset (dev), +"dmas" ,"#dma-cells" ,0 , index, + &args); +if (ret) { +pr_err ("%s: fdtdec_parse_phandle_with_args failed: err=%d\n" , + __func__, ret);return ret; + } + + ret =uclass_get_device_by_of_offset (UCLASS_DMA , args.node, &dev_dma); +if (ret) { +pr_err ("%s: uclass_get_device_by_of_offset failed: err=%d\n" , + __func__, ret); +return ret; + } + + dma->dev = dev_dma; + + ops =dma_dev_ops (dev_dma); + +if (ops->of_xlate) + ret = ops->of_xlate (dma, &args); +else + ret =dma_of_xlate_default (dma, &args); +if (ret) { +pr_err ("of_xlate() failed: %d\n" , ret); +return ret; + } + +return dma_request (dev_dma, dma); +} +# endif /* OF_PLATDATA */ + +int dma_get_by_name (struct udevice *dev,const char *name,struct dma *dma) +{ +int index; + +debug ("%s(dev=%p, name=%s, dma=%p)\n" , __func__, dev, name, dma); + + index =fdt_stringlist_search (gd->fdt_blob,dev_of_offset (dev), +"dma-names" , name); +if (index <0 ) { +pr_err ("fdt_stringlist_search() failed: %d\n" , index); +return index; + } + +return dma_get_by_index (dev, index, dma); +} +#endif /* OF_CONTROL */ + +int dma_request (struct udevice *dev,struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dev); + +debug ("%s(dev=%p, dma=%p)\n" , __func__, dev, dma); + + dma->dev = dev; + +if (!ops->request) +return 0 ; + +return ops->request (dma); +} + +int dma_free (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->free) +return 0 ; + +return ops->free (dma); +} + +int dma_enable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->enable) +return -ENOSYS ; + +return ops->enable (dma); +} + +int dma_disable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->disable) +return -ENOSYS ; + +return ops->disable (dma); +} + +int dma_memcpy (struct dma *dma,void *dst,void *src,size_t len) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); - ops =device_get_ops (dev);if (!ops->transfer)return -ENOSYS ;
@@ -61,12 +178,35 @@ int dma_memcpy(void *dst, void *src, size_t len)invalidate_dcache_range ((unsigned long )dst, (unsigned long )dst +roundup (len,ARCH_DMA_MINALIGN )); -return ops->transfer (dev,DMA_MEM_TO_MEM , dst, src, len); +return ops->transfer (dma,DMA_MEM_TO_MEM , dst, src, len); +} + +int dma_receive (struct dma *dma,void **dst) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->receive) +return -1 ; + +return ops->receive (dma, dst); +} + +int dma_send (struct dma *dma,void *src,size_t len) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->send) +return -1 ; + +return ops->send (dma, src, len); }UCLASS_DRIVER (dma) = { - .id =UCLASS_DMA , - .name ="dma" , - .flags =DM_UC_FLAG_SEQ_ALIAS , - .per_device_auto_alloc_size =sizeof (struct dma_dev_priv ), + .id =UCLASS_DMA , + .name ="dma" , + .flags =DM_UC_FLAG_SEQ_ALIAS , };
drivers/mtd/spi/sf-uclass.c +17 -0
@@ -6,6 +6,7 @@#include <common.h> #include <dm.h> +#include <dma.h> #include <spi.h> #include <spi_flash.h> #include <dm/device-internal.h>
@@ -72,6 +73,22 @@ int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,return ret; *devp = slave->dev; + +#ifdef CONFIG_DMA +if (fdtdec_lookup_phandle (gd->fdt_blob,dev_of_offset (*devp), +"dmas" ) >0 ) { +struct spi_flash *priv =dev_get_uclass_priv (*devp); + + priv->dma =calloc (1 ,sizeof (struct dma )); +if (!priv->dma) +return -ENOMEM ; + + ret =dma_get_by_index (*devp,0 , priv->dma); +if (ret) +return -EINVAL ; + } +#endif +return 0 ; }
drivers/mtd/spi/spi_flash.c +6 -5
@@ -458,10 +458,6 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,*/ void __weak spi_flash_copy_mmap (void *data,void *offset,size_t len) { -#ifdef CONFIG_DMA -if (!dma_memcpy (data, offset, len)) -return ; -#endif memcpy (data, offset, len); }
@@ -482,7 +478,12 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,return ret; }spi_xfer (spi,0 ,NULL ,NULL ,SPI_XFER_MMAP ); -spi_flash_copy_mmap (data, flash->memory_map + offset, len); +if (flash->dma) +dma_memcpy (flash->dma, data, + flash->memory_map + offset, len); +else +spi_flash_copy_mmap (data, flash->memory_map + offset, + len);spi_xfer (spi,0 ,NULL ,NULL ,SPI_XFER_MMAP_END );spi_release_bus (spi);return 0 ;
include/dma-uclass.h new file +110 -0
110 lines not on this page · raw message
include/dma.h +173 -53
259 lines not on this page · raw message
include/spi_flash.h +3 -0
@@ -65,6 +65,9 @@ struct spi_flash {#ifdef CONFIG_DM_SPI_FLASH struct udevice *dev;#endif +#ifdef CONFIG_DMA +struct dma *dma; +#endif const char *name;u8 dual_flash;u8 shift;
Signature · 1 line
2.11.0
Vignesh R
maintainerRFC 1/14 dma: add dma channels support and improve uclass
Please add a commit message as this is a pretty big change providing a overview what is being added and why?
Quoted 3 lines · Álvaro Fernández Rojas
Signed-off-by Álvaro Fernández Rojas <[email protected]>--- drivers/dma/dma-uclass.c | 212 ++++++++++++++++++++++++++++++++++-------
This patch definitely breaks drivers/dma/ti-edma3.c which implements current definition of dma-uclass.
One of the assumption of current dma_memcpy() implementation is that the client's DT node need not have "dmas" entry to specify which DMA provider and DMA channel to use for dma memcpy. (This is true in linux kernel as well). Most DMA HWs have general purpose channels that are not tied to any peripherals and can be used for mem to mem transfers. So, if the client device's DT node does not populate "dmas" property then dma_memcpy() API should try to find a DMA provider that supports memcpy operation, request a memcpy capable channel from the provider and use it to transfer data. Please keep the current behavior as is. Or, provide a API for clients to request such a channel.
Quoted 160 lines
drivers/mtd/spi/sf-uclass.c | 17 ++++ drivers/mtd/spi/spi_flash.c | 11 ++- include/dma-uclass.h | 110 +++++++++++++++++++++ include/dma.h | 226 +++++++++++++++++++++++++++++++++----------- include/spi_flash.h | 3 + 6 files changed, 485 insertions(+), 94 deletions(-) create mode 100644 include/dma-uclass.hdrivers/dma/dma-uclass.c +93
-30@@ -1,59 +1,176 @@/* -* Direct Memory Access U-Class driver +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated, <www.ti.com> +* Written by Mugunthan V N <[email protected]> * -* (C) Copyright 2015 -* Texas Instruments Incorporated, <www.ti.com> -* -* Author: Mugunthan V N <[email protected]> -* -* SPDX-License-Identifier: GPL-2.0+ +* SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> -#include <dma.h> #include <dm.h> -#include <dm/uclass-internal.h> -#include <dm/device-internal.h> +#include <dma.h> +#include <dma-uclass.h> +#include <dt-structs.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ; -int dma_get_device (u32 transfer_type,struct udevice **devp) +static inline struct dma_ops *dma_dev_ops (struct udevice *dev) +{ +return (struct dma_ops *)dev->driver->ops; +} + +#if CONFIG_IS_ENABLED (OF_CONTROL ) +# if CONFIG_IS_ENABLED (OF_PLATDATA ) +int dma_get_by_index_platdata (struct udevice *dev,int index, +struct phandle_2_cell *cells,struct dma *dma) { -struct udevice *dev;int ret; -for (ret =uclass_first_device (UCLASS_DMA , &dev); dev && !ret; - ret =uclass_next_device (&dev)) { -struct dma_dev_priv *uc_priv; +if (index !=0 ) +return -ENOSYS ; + ret =uclass_get_device (UCLASS_DMA ,0 , &dma->dev); +if (ret) +return ret; + dma->id = cells[0 ].id; - uc_priv =dev_get_uclass_priv (dev); -if (uc_priv->supported & transfer_type) -break ; - } +return 0 ; +} +# else +static int dma_of_xlate_default (struct dma *dma, +struct fdtdec_phandle_args *args) +{ +debug ("%s(dma=%p)\n" , __func__, dma); -if (!dev) { -pr_err ("No DMA device found that supports %x type\n" , - transfer_type); -return -EPROTONOSUPPORT ; +if (args->args_count >1 ) { +pr_err ("Invaild args_count: %d\n" , args->args_count); +return -EINVAL ; } - *devp = dev; +if (args->args_count) + dma->id = args->args[0 ]; +else + dma->id =0 ; -return ret; +return 0 ; } -int dma_memcpy (void *dst,void *src,size_t len) +int dma_get_by_index (struct udevice *dev,int index,struct dma *dma) { -struct udevice *dev; -const struct dma_ops *ops;int ret; +struct fdtdec_phandle_args args; +struct udevice *dev_dma; +struct dma_ops *ops; + +debug ("%s(dev=%p, index=%d, dma=%p)\n" , __func__, dev, index, dma); - ret =dma_get_device (DMA_SUPPORTS_MEM_TO_MEM , &dev); -if (ret <0 ) +assert (dma); + ret =fdtdec_parse_phandle_with_args (gd->fdt_blob,dev_of_offset (dev), +"dmas" ,"#dma-cells" ,0 , index, + &args); +if (ret) { +pr_err ("%s: fdtdec_parse_phandle_with_args failed: err=%d\n" , + __func__, ret);return ret; + } + + ret =uclass_get_device_by_of_offset (UCLASS_DMA , args.node, &dev_dma); +if (ret) { +pr_err ("%s: uclass_get_device_by_of_offset failed: err=%d\n" , + __func__, ret); +return ret; + } + + dma->dev = dev_dma; + + ops =dma_dev_ops (dev_dma); + +if (ops->of_xlate) + ret = ops->of_xlate (dma, &args); +else + ret =dma_of_xlate_default (dma, &args); +if (ret) { +pr_err ("of_xlate() failed: %d\n" , ret); +return ret; + } + +return dma_request (dev_dma, dma); +} +# endif /* OF_PLATDATA */ + +int dma_get_by_name (struct udevice *dev,const char *name,struct dma *dma) +{ +int index; + +debug ("%s(dev=%p, name=%s, dma=%p)\n" , __func__, dev, name, dma); + + index =fdt_stringlist_search (gd->fdt_blob,dev_of_offset (dev), +"dma-names" , name); +if (index <0 ) { +pr_err ("fdt_stringlist_search() failed: %d\n" , index); +return index; + } + +return dma_get_by_index (dev, index, dma); +} +#endif /* OF_CONTROL */ +
drivers/dma/dma-uclass.c line 127
Quoted 10 lines
drivers/dma/dma-uclass.c +10
-0+int dma_request (struct udevice *dev,struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dev); + +debug ("%s(dev=%p, dma=%p)\n" , __func__, dev, dma); + + dma->dev = dev; + +if (!ops->request) +return 0 ;
return 0? I guess you meant to return -ENOSYS or something.
drivers/dma/dma-uclass.c line 140
Quoted 13 lines
drivers/dma/dma-uclass.c +13
-0+ +return ops->request (dma); +} + +int dma_free (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->free) +return 0 ; +
Same as above
Quoted 43 lines
drivers/dma/dma-uclass.c +33
-2+return ops->free (dma); +} + +int dma_enable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->enable) +return -ENOSYS ; + +return ops->enable (dma); +} + +int dma_disable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->disable) +return -ENOSYS ; + +return ops->disable (dma); +} + +int dma_memcpy (struct dma *dma,void *dst,void *src,size_t len) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); - ops =device_get_ops (dev);if (!ops->transfer)return -ENOSYS ;@@ -61,12 +178,35 @@ int dma_memcpy(void *dst, void *src, size_t len)invalidate_dcache_range ((unsigned long )dst, (unsigned long )dst +roundup (len,ARCH_DMA_MINALIGN )); -return ops->transfer (dev,DMA_MEM_TO_MEM , dst, src, len); +return ops->transfer (dma,DMA_MEM_TO_MEM , dst, src, len);
drivers/dma/dma-uclass.c int dma_memcpy(void *dst, void *src, size_t len) · line 191
Quoted 10 lines
drivers/dma/dma-uclass.c +10
-0+} + +int dma_receive (struct dma *dma,void **dst) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->receive) +return -1 ;
-ENOSYS?
drivers/dma/dma-uclass.c int dma_memcpy(void *dst, void *src, size_t len) · line 203
Quoted 12 lines
drivers/dma/dma-uclass.c +12
-0+ +return ops->receive (dma, dst); +} + +int dma_send (struct dma *dma,void *src,size_t len) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->send) +return -1 ;
-ENOSYS?
Quoted 180 lines
drivers/dma/dma-uclass.c +5
-4+ +return ops->send (dma, src, len); }UCLASS_DRIVER (dma) = { - .id =UCLASS_DMA , - .name ="dma" , - .flags =DM_UC_FLAG_SEQ_ALIAS , - .per_device_auto_alloc_size =sizeof (struct dma_dev_priv ), + .id =UCLASS_DMA , + .name ="dma" , + .flags =DM_UC_FLAG_SEQ_ALIAS , };drivers/mtd/spi/sf-uclass.c +17
-0@@ -6,6 +6,7 @@#include <common.h> #include <dm.h> +#include <dma.h> #include <spi.h> #include <spi_flash.h> #include <dm/device-internal.h> @@ -72,6 +73,22 @@ int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,return ret; *devp = slave->dev; + +#ifdef CONFIG_DMA +if (fdtdec_lookup_phandle (gd->fdt_blob,dev_of_offset (*devp), +"dmas" ) >0 ) { +struct spi_flash *priv =dev_get_uclass_priv (*devp); + + priv->dma =calloc (1 ,sizeof (struct dma )); +if (!priv->dma) +return -ENOMEM ; + + ret =dma_get_by_index (*devp,0 , priv->dma); +if (ret) +return -EINVAL ; + } +#endif +return 0 ; }drivers/mtd/spi/spi_flash.c +6
-5@@ -458,10 +458,6 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,*/ void __weak spi_flash_copy_mmap (void *data,void *offset,size_t len) { -#ifdef CONFIG_DMA -if (!dma_memcpy (data, offset, len)) -return ; -#endif memcpy (data, offset, len); }@@ -482,7 +478,12 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,return ret; }spi_xfer (spi,0 ,NULL ,NULL ,SPI_XFER_MMAP ); -spi_flash_copy_mmap (data, flash->memory_map + offset, len); +if (flash->dma) +dma_memcpy (flash->dma, data, + flash->memory_map + offset, len); +else +spi_flash_copy_mmap (data, flash->memory_map + offset, + len);spi_xfer (spi,0 ,NULL ,NULL ,SPI_XFER_MMAP_END );spi_release_bus (spi);return 0 ;include/dma-uclass.h new file +97
-0@@ -0,0 +1,110 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated, <www.ti.com> +* Written by Mugunthan V N <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _DMA_UCLASS_H +#define _DMA_UCLASS_H + +/* See dma.h for background documentation. */ + +#include <dma.h> +#include <fdtdec.h> + +/** + * struct dma_ops - The functions that a DMA driver must implement. + */ +struct dma_ops { + /** + * of_xlate - Translate a client's device-tree (OF) DMA specifier. + * + * The DMA core calls this function as the first step in implementing + * a client's dma_get_by_*() call. + * + * If this function pointer is set to NULL, the DMA core will use a + * default implementation, which assumes #dma-cells = <1>, and that + * the DT cell contains a simple integer DMA Channel. + * + * At present, the DMA API solely supports device-tree. If this + * changes, other xxx_xlate() functions may be added to support those + * other mechanisms. + * + * @dma: The dma struct to hold the translation result. + * @args: The dma specifier values from device tree. + * @return 0 if OK, or a negative error code. + */ + int (*of_xlate)(struct dma *dma, + struct fdtdec_phandle_args *args); + /** + * request - Request a translated DMA. + * + * The DMA core calls this function as the second step in + * implementing a client's dma_get_by_*() call, following a successful + * xxx_xlate() call, or as the only step in implementing a client's + * dma_request() call. + * + * @dma: The DMA struct to request; this has been filled in by + * a previoux xxx_xlate() function call, or by the caller of + * dma_request(). + * @return 0 if OK, or a negative error code. + */ + int (*request)(struct dma *dma); + /** + * free - Free a previously requested dma. + * + * This is the implementation of the client dma_free() API. + * + * @dma: The DMA to free. + * @return 0 if OK, or a negative error code. + */ + int (*free)(struct dma *dma); + /** + * enable() - Enable a DMA Channel. + * + * @dma: The DMA Channel to manipulate. + * @return zero on success, or -ve error code. + */ + int (*enable)(struct dma *dma); + /** + * disable() - Disable a DMA Channel. + * + * @dma: The DMA Channel to manipulate. + * @return zero on success, or -ve error code. + */ + int (*disable)(struct dma *dma); + /** + * transfer() - Issue a DMA transfer. + * + * @dma: The DMA Channel to manipulate. + * @dir: The direction of data transfer. + * @dst: The destination pointer. + * @src: The source pointer. + * @len: Length of the data to be copied. + * @return zero on success, or -ve error code. + */ + int (*transfer)(struct dma *dma, enum dma_transfer_direction dir, + void *dst, void *src, size_t len); + /** + * receive() - Receive a DMA transfer. + * + * @dma: The DMA Channel to manipulate. + * @dst: The destination pointer. + * @return zero on success, or -ve error code. + */ + int (*receive)(struct dma *dma, void **dst);
include/dma-uclass.h line 107
Quoted 10 lines
include/dma-uclass.h new file +10
-0+/** +* send() - Send a DMA transfer. +* +* @dma: The DMA Channel to manipulate. +* @src: The source pointer. +* @len: Length of the data to be copied. +* @return zero on success, or -ve error code. +*/ +int (*send)(struct dma *dma,void *src,size_t len); +
I wonder why separate send()/receive() is needed. Isn't transfer() alone sufficient with appropriate direction flags? If its very specific to networking use case then, please explain that more clearly as to why this interface is provided in the comments (especially receive() interface that does not pass length).
Regards
Vignesh
Quoted 282 lines
include/dma-uclass.h new file +3
-0+}; + +#endif /* _DMA_UCLASS_H */ include/dma.h +173
-53@@ -1,86 +1,206 @@/* -* (C) Copyright 2015 -* Texas Instruments Incorporated, <www.ti.com> +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated, <www.ti.com> +* Written by Mugunthan V N <[email protected]> * -* SPDX-License-Identifier: GPL-2.0+ +* SPDX-License-Identifier: GPL-2.0+ */ #ifndef _DMA_H_#define _DMA_H_ +#include <linux/errno.h> +#include <linux/types.h> +/* -* enum dma_direction - dma transfer direction indicator +* enum dma_transfer_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 { +enum dma_transfer_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) +/** +* 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. +*/ -/* -* struct dma_ops - Driver model DMA operations +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. * -* The uclass interface is implemented by all DMA devices which use -* driver model. +* @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_ops { +struct dma { +struct udevice *dev;/* -* Get the current timer count -* -* @dev: The DMA device -* @direction: direction of data transfer should be one from -enum dma_direction -* @dst: Destination pointer -* @src: Source pointer -* @len: Length of the data to be copied. -* @return: 0 if OK, -ve on error +* Written by of_xlate. We assume a single id is enough for now. In the +* future, we might add more fields here. */ -int (*transfer)(struct udevice *dev,int direction,void *dst, -void *src,size_t len); +unsigned long id; }; -/* -* struct dma_dev_priv - information about a device used by the uclass +#if CONFIG_IS_ENABLED (OF_CONTROL ) &&CONFIG_IS_ENABLED (DMA ) +struct phandle_2_cell ; +int dma_get_by_index_platdata (struct udevice *dev,int index, +struct phandle_2_cell *cells,struct dma *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. * -* @supported: mode of transfers that DMA can support, should be -* one/multiple of DMA_SUPPORTS_* +* @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. */ -struct dma_dev_priv { -u32 supported; -}; +int dma_get_by_index (struct udevice *dev,int index,struct dma *dma); -/* -* 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 +/** +* 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_device (u32 transfer_type,struct udevice **devp); +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 ; +} -/* -* 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. +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_memcpy() - Try to use DMA to do a mem copy which will be much faster +* than CPU mem copy. +* +* @dma: A DMA struct that was previously successfully requested by +* dma_request/get_by_*(). +* @dst: The destination pointer. +* @src: The source pointer. +* @len: Length of the data to be copied. +* @return zero on success, or -ve error code. +*/ +int dma_memcpy (struct dma *dma,void *dst,void *src,size_t len); + +/** +* dma_receive() - Receive a DMA transfer. +* +* @dma: A DMA struct that was previously successfully requested by +* dma_request/get_by_*(). +* @dst: The destination pointer. +* @return zero on success, or -ve error code. +*/ +int dma_receive (struct dma *dma,void **dst); + +/** +* 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 copied. +* @return zero on success, or -ve error code. */ -int dma_memcpy (void *dst,void *src,size_t len); +int dma_send (struct dma *dma,void *src,size_t len); -#endif /* _DMA_H_ */ +#endif /* _DMA_H_ */ include/spi_flash.h +3
-0@@ -65,6 +65,9 @@ struct spi_flash {#ifdef CONFIG_DM_SPI_FLASH struct udevice *dev;#endif +#ifdef CONFIG_DMA +struct dma *dma; +#endif const char *name;u8 dual_flash;u8 shift;
Signature · 2 lines
Regards Vignesh
RFC 2/14 dma: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas--- drivers/dma/Kconfig | 8 + drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 498 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 507 insertions(+) create mode 100644 drivers/dma/bcm6348-iudma.c
drivers/dma/Kconfig +8 -0
@@ -12,6 +12,14 @@ config DMA buses that is used to transfer data to and from memory. The uclass interface is defined in include/dma.h. +config BCM6348_IUDMA + bool "BCM6348 IUDMA driver" + depends on ARCH_BMIPS + help + Enable the BCM6348 IUDMA driver. + This driver support data transfer from devices to + memory and from memory to devices. + config TI_EDMA3 bool "TI EDMA3 driver" help
drivers/dma/Makefile +1 -0
@@ -9,6 +9,7 @@ obj-$(CONFIG_DMA) += dma-uclass.o obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o obj-$(CONFIG_APBH_DMA) += apbh_dma.o +obj-$(CONFIG_BCM6348_IUDMA) += bcm6348-iudma.o obj-$(CONFIG_FSL_DMA) += fsl_dma.o obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o obj-$(CONFIG_TI_EDMA3) += ti-edma3.o
drivers/dma/bcm6348-iudma.c new file +498 -0
498 lines not on this page · raw message
Signature · 1 line
2.11.0
RFC 3/14 bmips: bcm6338: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas--- arch/mips/dts/brcm,bcm6338.dtsi | 14 ++++++++++++++ include/dt-bindings/dma/bcm6338-dma.h | 15 +++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6338-dma.h
arch/mips/dts/brcm,bcm6338.dtsi +14 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6338-clock.h> +#include <dt-bindings/dma/bcm6338-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6338-reset.h> #include "skeleton.dtsi"
@@ -131,5 +132,18 @@ reg = <0xfffe3100 0x38>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller at fffe2400 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe2400 0x1c>, + <0xfffe2500 0x60>, + <0xfffe2600 0x60>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <6>; + resets = <&periph_rst BCM6338_RST_DMAMEM>; + }; }; };
include/dt-bindings/dma/bcm6338-dma.h new file +15 -0
@@ -0,0 +1,15 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6338_H +#define __DT_BINDINGS_DMA_BCM6338_H + +#define BCM6338_DMA_ENET_RX 0 +#define BCM6338_DMA_ENET_TX 1 + +#endif /* __DT_BINDINGS_DMA_BCM6338_H */
Signature · 1 line
2.11.0
RFC 4/14 bmips: bcm6348: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas--- arch/mips/dts/brcm,bcm6348.dtsi | 16 ++++++++++++++++ include/dt-bindings/dma/bcm6348-dma.h | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6348-dma.h
arch/mips/dts/brcm,bcm6348.dtsi +16 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6348-clock.h> +#include <dt-bindings/dma/bcm6348-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6348-reset.h> #include "skeleton.dtsi"
@@ -160,5 +161,20 @@ reg = <0xfffe2300 0x38>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller at fffe7000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe7000 0x1c>, + <0xfffe7100 0x40>, + <0xfffe7200 0x40>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <4>; + clocks = <&periph_clk BCM6348_CLK_ENET>; + resets = <&periph_rst BCM6348_RST_ENET>, + <&periph_rst BCM6348_RST_DMAMEM>; + }; }; };
include/dt-bindings/dma/bcm6348-dma.h new file +17 -0
@@ -0,0 +1,17 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6348_H +#define __DT_BINDINGS_DMA_BCM6348_H + +#define BCM6348_DMA_ENET0_RX 0 +#define BCM6348_DMA_ENET0_TX 1 +#define BCM6348_DMA_ENET1_RX 2 +#define BCM6348_DMA_ENET1_TX 3 + +#endif /* __DT_BINDINGS_DMA_BCM6348_H */
Signature · 1 line
2.11.0
RFC 5/14 bmips: bcm6358: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas--- arch/mips/dts/brcm,bcm6358.dtsi | 18 ++++++++++++++++++ include/dt-bindings/dma/bcm6358-dma.h | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6358-dma.h
arch/mips/dts/brcm,bcm6358.dtsi +18 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6358-clock.h> +#include <dt-bindings/dma/bcm6358-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6358-reset.h> #include "skeleton.dtsi"
@@ -191,5 +192,22 @@ status = "disabled"; }; + + iudma: dma-controller at fffe5000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe5000 0x24>, + <0xfffe5100 0x80>, + <0xfffe5200 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + clocks = <&periph_clk BCM6358_CLK_EMUSB>, + <&periph_clk BCM6358_CLK_USBSU>, + <&periph_clk BCM6358_CLK_EPHY>; + resets = <&periph_rst BCM6358_RST_ENET>, + <&periph_rst BCM6358_RST_EPHY>; + }; }; };
include/dt-bindings/dma/bcm6358-dma.h new file +17 -0
@@ -0,0 +1,17 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6358_H +#define __DT_BINDINGS_DMA_BCM6358_H + +#define BCM6358_DMA_ENET0_RX 0 +#define BCM6358_DMA_ENET0_TX 1 +#define BCM6358_DMA_ENET1_RX 2 +#define BCM6358_DMA_ENET1_TX 3 + +#endif /* __DT_BINDINGS_DMA_BCM6358_H */
Signature · 1 line
2.11.0
RFC 6/14 phy: add support for internal phys
In reply to Álvaro Fernández Rojas--- include/phy.h | 2 ++ 1 file changed, 2 insertions(+)
include/phy.h +2 -0
@@ -50,6 +50,7 @@ typedef enum { + PHY_INTERFACE_MODE_INTERNAL, PHY_INTERFACE_MODE_MII, PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_SGMII,
@@ -72,6 +73,7 @@ typedef enum { } phy_interface_t;static const char *phy_interface_strings[] = { + [PHY_INTERFACE_MODE_INTERNAL ] ="internal" , [PHY_INTERFACE_MODE_MII ] ="mii" , [PHY_INTERFACE_MODE_GMII ] ="gmii" , [PHY_INTERFACE_MODE_SGMII ] ="sgmii" ,
Signature · 1 line
2.11.0
RFC 7/14 net: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas--- drivers/net/Kconfig | 9 + drivers/net/Makefile | 1 + drivers/net/bcm6348-eth.c | 517 +++++++++++++++++++++++++++++++++++++++++ include/configs/bmips_common.h | 5 +- 4 files changed, 531 insertions(+), 1 deletion(-) create mode 100644 drivers/net/bcm6348-eth.c
drivers/net/Kconfig +9 -0
@@ -71,6 +71,15 @@ config BCM_SF2_ETH_GMAC by the BCM_SF2_ETH driver. Say Y to any bcmcygnus based platforms. +config BCM6348_ETH + bool "BCM6348 EMAC support" + depends on DM_ETH && ARCH_BMIPS + select DMA + select MII + select PHYLIB + help + This driver supports the BCM6348 Ethernet MAC. + config DWC_ETH_QOS bool "Synopsys DWC Ethernet QOS device support" depends on DM_ETH
drivers/net/Makefile +1 -0
@@ -8,6 +8,7 @@ obj-$(CONFIG_ALTERA_TSE) += altera_tse.o obj-$(CONFIG_AG7XXX) += ag7xxx.o obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o +obj-$(CONFIG_BCM6348_ETH) += bcm6348-eth.o obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o obj-$(CONFIG_DRIVER_AX88180) += ax88180.o obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
drivers/net/bcm6348-eth.c new file +517 -0
517 lines not on this page · raw message
include/configs/bmips_common.h +4 -1
@@ -7,6 +7,9 @@#ifndef __CONFIG_BMIPS_COMMON_H#define __CONFIG_BMIPS_COMMON_H +/* ETH */ +#define CONFIG_PHY_RESET_DELAY 20 +/* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ 230400, 500000, 1500000 }
@@ -17,7 +20,7 @@/* Memory usage */ #define CONFIG_SYS_MAXARGS 24 -#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) +#define CONFIG_SYS_MALLOC_LEN (2 * 1024 * 1024)#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)#define CONFIG_SYS_CBSIZE 512
Signature · 1 line
2.11.0
RFC 8/14 bmips: bcm6338: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas--- arch/mips/dts/brcm,bcm6338.dtsi | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
arch/mips/dts/brcm,bcm6338.dtsi +15 -0
@@ -145,5 +145,20 @@ dma-channels = <6>; resets = <&periph_rst BCM6338_RST_DMAMEM>; }; + + enet: ethernet at fffe2800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe2800 0x2dc>; + clocks = <&periph_clk BCM6338_CLK_ENET>; + resets = <&periph_rst BCM6338_RST_ENET>; + dmas = <&iudma BCM6338_DMA_ENET_RX>, + <&iudma BCM6338_DMA_ENET_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; }; };
Signature · 1 line
2.11.0
RFC 9/14 bmips: enable f@st1704 enet support
In reply to Álvaro Fernández Rojas--- arch/mips/dts/sagem,f at st1704.dts | 12 ++++++++++++ configs/sagem_f at st1704_ram_defconfig | 9 ++++++++- 2 files changed, 20 insertions(+), 1 deletion(-)
arch/mips/dts/sagem,f at st1704.dts +12 -0
@@ -40,6 +40,18 @@ }; }; +&enet { + status = "okay"; + phy = <&enetphy>; + phy-mode = "mii"; + + enetphy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio { status = "okay"; };
configs/sagem_f at st1704_ram_defconfig +8 -1
@@ -28,11 +28,15 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_SF=y CONFIG_CMD_SPI=y -# CONFIG_CMD_NET is not set +CONFIG_CMD_DHCP=y # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -41,6 +45,9 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_DM_RESET=y CONFIG_RESET_BCM6345=y # CONFIG_SPL_SERIAL_PRESENT is not set
Signature · 1 line
2.11.0
RFC 10/14 bmips: bcm6348: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas--- arch/mips/dts/brcm,bcm6348.dtsi | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
arch/mips/dts/brcm,bcm6348.dtsi +26 -0
@@ -162,6 +162,32 @@ u-boot,dm-pre-reloc; }; + enet0: ethernet at fffe6000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6000 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET0_RX>, + <&iudma BCM6348_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet at fffe6800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6800 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET1_RX>, + <&iudma BCM6348_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + iudma: dma-controller at fffe7000 { compatible = "brcm,bcm6348-iudma"; reg = <0xfffe7000 0x1c>,
Signature · 1 line
2.11.0
RFC 11/14 bmips: enable ct-5361 enet support
In reply to Álvaro Fernández Rojas--- arch/mips/dts/comtrend,ct-5361.dts | 12 ++++++++++++ configs/comtrend_ct5361_ram_defconfig | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
arch/mips/dts/comtrend,ct-5361.dts +12 -0
@@ -35,6 +35,18 @@ }; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/comtrend_ct5361_ram_defconfig +7 -1
@@ -26,11 +26,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -38,6 +41,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6348_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
RFC 12/14 bmips: bcm6358: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas--- arch/mips/dts/brcm,bcm6358.dtsi | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
arch/mips/dts/brcm,bcm6358.dtsi +28 -0
@@ -193,6 +193,34 @@ status = "disabled"; }; + enet0: ethernet at fffe4000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4000 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET0>; + dmas = <&iudma BCM6358_DMA_ENET0_RX>, + <&iudma BCM6358_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet at fffe4800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4800 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET1>; + dmas = <&iudma BCM6358_DMA_ENET1_RX>, + <&iudma BCM6358_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + iudma: dma-controller at fffe5000 { compatible = "brcm,bcm6348-iudma"; reg = <0xfffe5000 0x24>,
Signature · 1 line
2.11.0
RFC 13/14 bmips: enable hg556a enet support
In reply to Álvaro Fernández Rojas--- arch/mips/dts/huawei,hg556a.dts | 12 ++++++++++++ configs/huawei_hg556a_ram_defconfig | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
arch/mips/dts/huawei,hg556a.dts +12 -0
@@ -94,6 +94,18 @@ status = "okay"; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/huawei_hg556a_ram_defconfig +7 -1
@@ -26,11 +26,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -38,6 +41,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6358_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
RFC 14/14 bmips: enable nb4-ser enet support
In reply to Álvaro Fernández Rojas--- arch/mips/dts/sfr,nb4-ser.dts | 24 ++++++++++++++++++++++++ configs/sfr_nb4-ser_ram_defconfig | 8 +++++++- 2 files changed, 31 insertions(+), 1 deletion(-)
arch/mips/dts/sfr,nb4-ser.dts +24 -0
@@ -54,6 +54,30 @@ status = "okay"; }; +&enet0 { + status = "okay"; + phy = <&enet0phy>; + phy-mode = "internal"; + + enet0phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/sfr_nb4-ser_ram_defconfig +7 -1
@@ -27,11 +27,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -40,6 +43,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6358_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
cover bmips: add bcm6348-enet support
In reply to Álvaro Fernández RojasNo comments about DMA?
2018-02-12 17:38 GMT+01:00 Álvaro Fernández Rojas <[email protected]>:
Quoted 66 lines
In order to add bcm6348-enet support, dma-uclass must be extended to support
dma channels and rewordked to operate like the other dm uclass (clk, reset...).This is an RFC, so please give you feedback on the things that I should fix or rework.
Álvaro Fernández Rojas (14):
dma: add dma channels support and improve uclass
dma: add bcm6348-iudma support
bmips: bcm6338: add bcm6348-iudma support
bmips: bcm6348: add bcm6348-iudma support
bmips: bcm6358: add bcm6348-iudma support
phy: add support for internal phys
net: add support for bcm6348-enet
bmips: bcm6338: add support for bcm6348-enet
bmips: enable f at st1704 enet support
bmips: bcm6348: add support for bcm6348-enet
bmips: enable ct-5361 enet support
bmips: bcm6358: add support for bcm6348-enet
bmips: enable hg556a enet support
bmips: enable nb4-ser enet supportarch/mips/dts/brcm,bcm6338.dtsi | 29 ++ arch/mips/dts/brcm,bcm6348.dtsi | 42 +++ arch/mips/dts/brcm,bcm6358.dtsi | 46 +++ arch/mips/dts/comtrend,ct-5361.dts | 12 + arch/mips/dts/huawei,hg556a.dts | 12 + arch/mips/dts/sagem,f at st1704.dts | 12 + arch/mips/dts/sfr,nb4-ser.dts | 24 ++ configs/comtrend_ct5361_ram_defconfig | 8 +- configs/huawei_hg556a_ram_defconfig | 8 +- configs/sagem_f at st1704_ram_defconfig | 9 +- configs/sfr_nb4-ser_ram_defconfig | 8 +- drivers/dma/Kconfig | 8 + drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 498 ++++++++++++++++++++++++++++++ ++ drivers/dma/dma-uclass.c | 212 +++++++++++--- drivers/mtd/spi/sf-uclass.c | 17 ++ drivers/mtd/spi/spi_flash.c | 11 +- drivers/net/Kconfig | 9 + drivers/net/Makefile | 1 + drivers/net/bcm6348-eth.c | 517 ++++++++++++++++++++++++++++++ ++++ include/configs/bmips_common.h | 5 +- include/dma-uclass.h | 110 ++++++++ include/dma.h | 226 +++++++++++---- include/dt-bindings/dma/bcm6338-dma.h | 15 + include/dt-bindings/dma/bcm6348-dma.h | 17 ++ include/dt-bindings/dma/bcm6358-dma.h | 17 ++ include/phy.h | 2 + include/spi_flash.h | 3 + 28 files changed, 1780 insertions(+), 99 deletions(-) create mode 100644 drivers/dma/bcm6348-iudma.c create mode 100644 drivers/net/bcm6348-eth.c create mode 100644 include/dma-uclass.h create mode 100644 include/dt-bindings/dma/bcm6338-dma.h create mode 100644 include/dt-bindings/dma/bcm6348-dma.h create mode 100644 include/dt-bindings/dma/bcm6358-dma.h--
2.11.0
v2 cover bmips: add bcm6348-enet support
In reply to Álvaro Fernández RojasIn order to add bcm6348-enet support, dma-uclass must be extended to support dma channels and reworked to operate like the other dm uclass (clk, reset...).
This is a RFC, so please give you feedback on the things that I should fix or rework.
v2: Introduce changes reported by Vignesh:
- Respect current dma implementation.
- Let dma_memcpy find a compatible dma device.
Other changes:
- Fix bcm6348-iudma rx burst config.
Álvaro Fernández Rojas (15):
dma: move dma_ops to dma-uclass.h
dma: add channels support
dma: add bcm6348-iudma support
bmips: bcm6338: add bcm6348-iudma support
bmips: bcm6348: add bcm6348-iudma support
bmips: bcm6358: add bcm6348-iudma support
phy: add support for internal phys
net: add support for bcm6348-enet
bmips: bcm6338: add support for bcm6348-enet
bmips: enable f at st1704 enet support
bmips: bcm6348: add support for bcm6348-enet
bmips: enable ct-5361 enet support
bmips: bcm6358: add support for bcm6348-enet
bmips: enable hg556a enet support
bmips: enable nb4-ser enet support
arch/mips/dts/brcm,bcm6338.dtsi | 29 ++ arch/mips/dts/brcm,bcm6348.dtsi | 42 +++ arch/mips/dts/brcm,bcm6358.dtsi | 46 +++ arch/mips/dts/comtrend,ct-5361.dts | 12 + arch/mips/dts/huawei,hg556a.dts | 12 + arch/mips/dts/sagem,f at st1704.dts | 12 + arch/mips/dts/sfr,nb4-ser.dts | 24 ++ configs/comtrend_ct5361_ram_defconfig | 8 +- configs/huawei_hg556a_ram_defconfig | 8 +- configs/sagem_f at st1704_ram_defconfig | 9 +- configs/sfr_nb4-ser_ram_defconfig | 8 +- drivers/dma/Kconfig | 16 ++ drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 505 +++++++++++++++++++++++++++++++++ drivers/dma/dma-uclass.c | 180 +++++++++++- drivers/net/Kconfig | 10 + drivers/net/Makefile | 1 + drivers/net/bcm6348-eth.c | 517 ++++++++++++++++++++++++++++++++++ include/configs/bmips_common.h | 5 +- include/dma-uclass.h | 115 ++++++++ include/dma.h | 191 +++++++++++-- include/dt-bindings/dma/bcm6338-dma.h | 15 + include/dt-bindings/dma/bcm6348-dma.h | 17 ++ include/dt-bindings/dma/bcm6358-dma.h | 17 ++ include/phy.h | 2 + 25 files changed, 1774 insertions(+), 28 deletions(-) create mode 100644 drivers/dma/bcm6348-iudma.c create mode 100644 drivers/net/bcm6348-eth.c create mode 100644 include/dma-uclass.h create mode 100644 include/dt-bindings/dma/bcm6338-dma.h create mode 100644 include/dt-bindings/dma/bcm6348-dma.h create mode 100644 include/dt-bindings/dma/bcm6358-dma.h
Signature · 1 line
2.11.0
RFC v2 1/15 dma: move dma_ops to dma-uclass.h
Move dma_ops to a separate header file, following other uclass implementations.
--- drivers/dma/dma-uclass.c | 3 ++- include/dma-uclass.h | 38 ++++++++++++++++++++++++++++++++++++++ include/dma.h | 22 ---------------------- 3 files changed, 40 insertions(+), 23 deletions(-) create mode 100644 include/dma-uclass.h
drivers/dma/dma-uclass.c +2 -1
@@ -10,10 +10,11 @@*/ #include <common.h> -#include <dma.h> #include <dm.h> #include <dm/uclass-internal.h> #include <dm/device-internal.h> +#include <dma.h> +#include <dma-uclass.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ;
include/dma-uclass.h new file +38 -0
@@ -0,0 +1,38 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated, <www.ti.com> +* Written by Mugunthan V N <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _DMA_UCLASS_H +#define _DMA_UCLASS_H + +/* See dma.h for background documentation. */ + +#include <dma.h> + +/* +* struct dma_ops - Driver model DMA operations +* +* The uclass interface is implemented by all DMA devices which use +* driver model. +*/ +struct dma_ops { +/* +* Get the current timer count +* +* @dev: The DMA device +* @direction: direction of data transfer should be one from +enum dma_direction +* @dst: Destination pointer +* @src: Source pointer +* @len: Length of the data to be copied. +* @return: 0 if OK, -ve on error +*/ +int (*transfer)(struct udevice *dev,int direction,void *dst, +void *src,size_t len); +}; + +#endif /* _DMA_UCLASS_H */
include/dma.h +0 -22
@@ -28,28 +28,6 @@ enum dma_direction {#define DMA_SUPPORTS_DEV_TO_DEV BIT(3)/* -* struct dma_ops - Driver model DMA operations -* -* The uclass interface is implemented by all DMA devices which use -* driver model. -*/ -struct dma_ops { -/* -* Get the current timer count -* -* @dev: The DMA device -* @direction: direction of data transfer should be one from -enum dma_direction -* @dst: Destination pointer -* @src: Source pointer -* @len: Length of the data to be copied. -* @return: 0 if OK, -ve on error -*/ -int (*transfer)(struct udevice *dev,int direction,void *dst, -void *src,size_t len); -}; - -/* * struct dma_dev_priv - information about a device used by the uclass * * @supported: mode of transfers that DMA can support, should be
Signature · 1 line
2.11.0
RFC v2 1/15 dma: move dma_ops to dma-uclass.h
Hi Alvaro,
Quoted 47 lines · Álvaro Fernández Rojas
Move
dma_opsto a separate header file, following other uclass implementations.Signed-off-by Álvaro Fernández Rojas <[email protected]>--- drivers/dma/dma-uclass.c | 3 ++- include/dma-uclass.h | 38 ++++++++++++++++++++++++++++++++++++++ include/dma.h | 22 ---------------------- 3 files changed, 40 insertions(+), 23 deletions(-) create mode 100644 include/dma-uclass.hdrivers/dma/dma-uclass.c +2
-1@@ -10,10 +10,11 @@*/ #include <common.h> -#include <dma.h> #include <dm.h> #include <dm/uclass-internal.h> #include <dm/device-internal.h> +#include <dma.h> +#include <dma-uclass.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ;include/dma-uclass.h new file +14
-0@@ -0,0 +1,38 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated, <www.ti.com> +* Written by Mugunthan V N <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _DMA_UCLASS_H +#define _DMA_UCLASS_H + +/* See dma.h for background documentation. */ + +#include <dma.h>
include/dma-uclass.h line 24
Quoted 10 lines
include/dma-uclass.h new file +10
-0+ +/* +* struct dma_ops - Driver model DMA operations +* +* The uclass interface is implemented by all DMA devices which use +* driver model. +*/ +struct dma_ops { +/* +* Get the current timer count
Is this the correct purpose for the transfer() method?
include/dma-uclass.h line 31
Quoted 7 lines
include/dma-uclass.h new file +7
-0+* +* @dev: The DMA device +* @direction: direction of data transfer should be one from +enum dma_direction +* @dst: Destination pointer +* @src: Source pointer +* @len: Length of the data to be copied.
Is this the number of bytes
What does this function actually do? Does it queue a transfer which completes later? How do I check if it is done?
Please add a lot more docs here.
Quoted 41 lines
include/dma-uclass.h new file +7
-0+* @return: 0 if OK, -ve on error +*/ +int (*transfer)(struct udevice *dev,int direction,void *dst, + void *src, size_t len); +}; + +#endif /* _DMA_UCLASS_H */ include/dma.h +0
-23@@ -28,28 +28,6 @@ enum dma_direction {#define DMA_SUPPORTS_DEV_TO_DEV BIT(3)/* -* struct dma_ops - Driver model DMA operations -* -* The uclass interface is implemented by all DMA devices which use -* driver model. -*/ -struct dma_ops { -/* -* Get the current timer count -* -* @dev: The DMA device -* @direction: direction of data transfer should be one from -enum dma_direction -* @dst: Destination pointer -* @src: Source pointer -* @len: Length of the data to be copied. -* @return: 0 if OK, -ve on error -*/ -int (*transfer)(struct udevice *dev,int direction,void *dst, -void *src,size_t len); -}; - -/* * struct dma_dev_priv - information about a device used by the uclass * * @supported: mode of transfers that DMA can support, should be --
Quoted 2 lines
2.11.0
Regards,
Simon
RFC v2 1/15 dma: move dma_ops to dma-uclass.h
Hi Simon,
Quoted 53 lines · Simon Glass
Hi Alvaro,
Quoted 50 lines · Álvaro Fernández Rojas
Move
dma_opsto a separate header file, following other uclass implementations.Signed-off-by Álvaro Fernández Rojas <[email protected]>--- drivers/dma/dma-uclass.c | 3 ++- include/dma-uclass.h | 38 ++++++++++++++++++++++++++++++++++++++ include/dma.h | 22 ---------------------- 3 files changed, 40 insertions(+), 23 deletions(-)create mode 100644
include/dma-uclass.hdrivers/dma/dma-uclass.c +2
-1@@ -10,10 +10,11 @@*/ #include <common.h> -#include <dma.h> #include <dm.h> #include <dm/uclass-internal.h> #include <dm/device-internal.h> +#include <dma.h> +#include <dma-uclass.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ;include/dma-uclass.h new file +17
-0@@ -0,0 +1,38 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated, <www.ti.com> +* Written by Mugunthan V N <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _DMA_UCLASS_H +#define _DMA_UCLASS_H + +/* See dma.h for background documentation. */ + +#include <dma.h> + +/* +* struct dma_ops - Driver model DMA operations
Quoted 8 lines
include/dma-uclass.h line 24
Quoted 7 lines
include/dma-uclass.h new file +7
-0+* +* The uclass interface is implemented by all DMA devices which use +* driver model. +*/ +struct dma_ops { +/* +* Get the current timer count Is this the correct purpose for the
transfer()method?
This is just a copy&paste, that's what you can find in upstream dma.h ;D Anyway, I will fix that.
Quoted 7 lines
include/dma-uclass.h line 31
Quoted 7 lines
include/dma-uclass.h new file +7
-0+* +* @dev: The DMA device +* @direction: direction of data transfer should be one from +enum dma_direction +* @dst: Destination pointer +* @src: Source pointer +* @len: Length of the data to be copied.
Quoted 6 lines
Is this the number of bytes
What does this function actually do? Does it queue a transfer which completes later? How do I check if it is done?
Please add a lot more docs here.
Same as above.
Quoted 38 lines
Quoted 38 lines
include/dma-uclass.h new file +7
-0+* @return: 0 if OK, -ve on error +*/ +int (*transfer)(struct udevice *dev,int direction,void *dst, + void *src, size_t len); +}; + +#endif /* _DMA_UCLASS_H */ include/dma.h +0
-22@@ -28,28 +28,6 @@ enum dma_direction {#define DMA_SUPPORTS_DEV_TO_DEV BIT(3)/* -* struct dma_ops - Driver model DMA operations -* -* The uclass interface is implemented by all DMA devices which use -* driver model. -*/ -struct dma_ops { -/* -* Get the current timer count -* -* @dev: The DMA device -* @direction: direction of data transfer should be one from -enum dma_direction -* @dst: Destination pointer -* @src: Source pointer -* @len: Length of the data to be copied. -* @return: 0 if OK, -ve on error -*/ -int (*transfer)(struct udevice *dev,int direction,void *dst, -void *src,size_t len); -}; - -/*
Quoted 8 lines
Quoted 6 lines
include/dma.h +0
-1* struct dma_dev_priv - information about a device used by the uclass * * @supported: mode of transfers that DMA can support, should be -- 2.11.0
Regards,
Simon
Regards,
Álvaro.
RFC v2 2/15 dma: add channels support
In reply to Álvaro Fernández RojasThis adds channels support for dma controllers that have multiple channels which can transfer data to/from different devices (enet, usb...).
---
v2: Introduce changes reported by Vignesh:
- Respect current dma implementation.
- Let dma_memcpy find a compatible dma device.
drivers/dma/Kconfig | 7 ++ drivers/dma/dma-uclass.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++ include/dma-uclass.h | 77 +++++++++++++++++++++ include/dma.h | 169 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 430 insertions(+)
drivers/dma/Kconfig +7 -0
@@ -12,6 +12,13 @@ config DMA buses that is used to transfer data to and from memory. The uclass interface is defined in include/dma.h. +config DMA_CHANNELS + bool "Enable DMA channels support" + depends on DMA + help + Enable channels support for DMA. Some DMA controllers have multiple + channels which can either transfer data to/from different devices. + config TI_EDMA3 bool "TI EDMA3 driver" help
drivers/dma/dma-uclass.c +177 -0
187 lines not on this page · raw message
include/dma-uclass.h +77 -0
89 lines not on this page · raw message
include/dma.h +169 -0
181 lines not on this page · raw message
Signature · 1 line
2.11.0
RFC v2 2/15 dma: add channels support
Hi Alvaro,
Quoted 90 lines · Álvaro Fernández Rojas
This adds channels support for dma controllers that have multiple channels which can transfer data to/from different devices (enet, usb...).
Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v2: Introduce changes reported by Vignesh:
- Respect current dma implementation.
- Letdma_memcpyfind a compatible dma device.drivers/dma/Kconfig | 7 ++ drivers/dma/dma-uclass.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++ include/dma-uclass.h | 77 +++++++++++++++++++++ include/dma.h | 169 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 430 insertions(+)drivers/dma/Kconfig +7
-0@@ -12,6 +12,13 @@ config DMA buses that is used to transfer data to and from memory. The uclass interface is defined in include/dma.h. +config DMA_CHANNELS + bool "Enable DMA channels support" + depends on DMA + help + Enable channels support for DMA. Some DMA controllers have multiple + channels which can either transfer data to/from different devices. + config TI_EDMA3 bool "TI EDMA3 driver" helpdrivers/dma/dma-uclass.c +45
-0@@ -15,10 +15,187 @@#include <dm/device-internal.h> #include <dma.h> #include <dma-uclass.h> +#include <dt-structs.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ; +#ifdef CONFIG_DMA_CHANNELS +static inline struct dma_ops *dma_dev_ops(struct udevice *dev) +{ + return (struct dma_ops *)dev->driver->ops; +} + +# if CONFIG_IS_ENABLED(OF_CONTROL) +# if CONFIG_IS_ENABLED(OF_PLATDATA) +int dma_get_by_index_platdata(struct udevice *dev, int index, + struct phandle_2_cell *cells, struct dma *dma) +{ + int ret; + + if (index != 0) + return -ENOSYS; + ret = uclass_get_device(UCLASS_DMA, 0, &dma->dev); + if (ret) + return ret; + dma->id = cells[0].id; + + return 0; +} +# else +static int dma_of_xlate_default(struct dma *dma, + struct fdtdec_phandle_args *args) +{ + debug("%s(dma=%p)\n", __func__, dma); + + if (args->args_count > 1) { + pr_err("Invaild args_count: %d\n", args->args_count); + return -EINVAL; + } + + if (args->args_count) + dma->id = args->args[0]; + else + dma->id = 0; + + return 0; +} + +int dma_get_by_index(struct udevice *dev, int index, struct dma *dma) +{ + int ret;
drivers/dma/dma-uclass.c line 76
Quoted 10 lines
drivers/dma/dma-uclass.c +10
-0+struct fdtdec_phandle_args args; +struct udevice *dev_dma; +struct dma_ops *ops; + +debug ("%s(dev=%p, index=%d, dma=%p)\n" , __func__, dev, index, dma); + +assert (dma); + ret =fdtdec_parse_phandle_with_args (gd->fdt_blob,dev_of_offset (dev), +"dmas" ,"#dma-cells" ,0 , index, + &args);
Can you please use the livetree API? E.g. see dev_read_phandle_with_args()
Also please move this into an ofdata_to_platdata function rather than doing it each time this function is called.
Quoted 28 lines
drivers/dma/dma-uclass.c +28
-0+if (ret) { +pr_err ("%s: fdtdec_parse_phandle_with_args failed: err=%d\n" , + __func__, ret); +return ret; + } + + ret =uclass_get_device_by_of_offset (UCLASS_DMA , args.node, &dev_dma); +if (ret) { +pr_err ("%s: uclass_get_device_by_of_offset failed: err=%d\n" , + __func__, ret); +return ret; + } + + dma->dev = dev_dma; + + ops =dma_dev_ops (dev_dma); + +if (ops->of_xlate) + ret = ops->of_xlate (dma, &args); +else + ret =dma_of_xlate_default (dma, &args); +if (ret) { +pr_err ("of_xlate() failed: %d\n" , ret); +return ret; + } + +return dma_request (dev_dma, dma); +}
drivers/dma/dma-uclass.c line 114
Quoted 10 lines
drivers/dma/dma-uclass.c +10
-0+# endif /* OF_PLATDATA */ + +int dma_get_by_name (struct udevice *dev,const char *name,struct dma *dma) +{ +int index; + +debug ("%s(dev=%p, name=%s, dma=%p)\n" , __func__, dev, name, dma); + + index =fdt_stringlist_search (gd->fdt_blob,dev_of_offset (dev), +"dma-names" , name);
dev_read...
Quoted 114 lines
drivers/dma/dma-uclass.c +84
-0+if (index <0 ) { +pr_err ("fdt_stringlist_search() failed: %d\n" , index); +return index; + } + +return dma_get_by_index (dev, index, dma); +} +# endif /* OF_CONTROL */ + +int dma_request (struct udevice *dev,struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dev); + +debug ("%s(dev=%p, dma=%p)\n" , __func__, dev, dma); + + dma->dev = dev; + +if (!ops->request) +return 0 ; + +return ops->request (dma); +} + +int dma_free (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->free) +return 0 ; + +return ops->free (dma); +} + +int dma_enable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->enable) +return -ENOSYS ; + +return ops->enable (dma); +} + +int dma_disable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->disable) +return -ENOSYS ; + +return ops->disable (dma); +} + +int dma_receive (struct dma *dma,void **dst) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->receive) +return -1 ; + +return ops->receive (dma, dst); +} + +int dma_send (struct dma *dma,void *src,size_t len) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->send) +return -1 ; + +return ops->send (dma, src, len); +} +#endif /* CONFIG_DMA_CHANNELS */ +int dma_get_device (u32 transfer_type,struct udevice **devp) {struct udevice *dev;include/dma-uclass.h +12
-0@@ -12,6 +12,7 @@/* See dma.h for background documentation. */ #include <dma.h> +#include <fdtdec.h> /* * struct dma_ops - Driver model DMA operations @@ -20,6 +21,82 @@* driver model. */ struct dma_ops { +#ifdef CONFIG_DMA_CHANNELS +/** +* of_xlate - Translate a client's device-tree (OF) DMA specifier. +* +* The DMA core calls this function as the first step in implementing +* a client's dma_get_by_*() call. +* +* If this function pointer is set to NULL, the DMA core will use a +* default implementation, which assumes #dma-cells = <1>, and that +* the DT cell contains a simple integer DMA Channel. +*
include/dma-uclass.h line 44
Quoted 10 lines
include/dma-uclass.h +10
-0+* At present, the DMA API solely supports device-tree. If this +* changes, other xxx_xlate() functions may be added to support those +* other mechanisms. +* +* @dma: The dma struct to hold the translation result. +* @args: The dma specifier values from device tree. +* @return 0 if OK, or a negative error code. +*/ +int (*of_xlate)(struct dma *dma, +struct fdtdec_phandle_args *args);
Use new livetree struct here
Regards,
Simon
RFC v2 2/15 dma: add channels support
Hi Simon,
Quoted 105 lines · Simon Glass
Hi Alvaro,
Quoted 90 lines · Álvaro Fernández Rojas
This adds channels support for dma controllers that have multiple channels which can transfer data to/from different devices (enet, usb...).
Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v2: Introduce changes reported by Vignesh:
- Respect current dma implementation.
- Letdma_memcpyfind a compatible dma device.drivers/dma/Kconfig | 7 ++ drivers/dma/dma-uclass.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++ include/dma-uclass.h | 77 +++++++++++++++++++++ include/dma.h | 169 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 430 insertions(+)drivers/dma/Kconfig +7
-0@@ -12,6 +12,13 @@ config DMA buses that is used to transfer data to and from memory. The uclass interface is defined in include/dma.h. +config DMA_CHANNELS + bool "Enable DMA channels support" + depends on DMA + help + Enable channels support for DMA. Some DMA controllers have multiple + channels which can either transfer data to/from different devices. + config TI_EDMA3 bool "TI EDMA3 driver" helpdrivers/dma/dma-uclass.c +45
-0@@ -15,10 +15,187 @@#include <dm/device-internal.h> #include <dma.h> #include <dma-uclass.h> +#include <dt-structs.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ; +#ifdef CONFIG_DMA_CHANNELS +static inline struct dma_ops *dma_dev_ops(struct udevice *dev) +{ + return (struct dma_ops *)dev->driver->ops; +} + +# if CONFIG_IS_ENABLED(OF_CONTROL) +# if CONFIG_IS_ENABLED(OF_PLATDATA) +int dma_get_by_index_platdata(struct udevice *dev, int index, + struct phandle_2_cell *cells, struct dma *dma) +{ + int ret; + + if (index != 0) + return -ENOSYS; + ret = uclass_get_device(UCLASS_DMA, 0, &dma->dev); + if (ret) + return ret; + dma->id = cells[0].id; + + return 0; +} +# else +static int dma_of_xlate_default(struct dma *dma, + struct fdtdec_phandle_args *args) +{ + debug("%s(dma=%p)\n", __func__, dma); + + if (args->args_count > 1) { + pr_err("Invaild args_count: %d\n", args->args_count); + return -EINVAL; + } + + if (args->args_count) + dma->id = args->args[0]; + else + dma->id = 0; + + return 0; +} + +int dma_get_by_index(struct udevice *dev, int index, struct dma *dma) +{ + int ret;drivers/dma/dma-uclass.c line 76
Quoted 10 lines
drivers/dma/dma-uclass.c +10
-0+struct fdtdec_phandle_args args; +struct udevice *dev_dma; +struct dma_ops *ops; + +debug ("%s(dev=%p, index=%d, dma=%p)\n" , __func__, dev, index, dma); + +assert (dma); + ret =fdtdec_parse_phandle_with_args (gd->fdt_blob,dev_of_offset (dev), +"dmas" ,"#dma-cells" ,0 , index, + &args);Can you please use the livetree API? E.g. see
dev_read_phandle_with_args()
Quoted 2 lines
Also please move this into an
ofdata_to_platdatafunction rather than doing it each time this function is called.
Ok, I did this some time ago and I used an older version of clk-uclass as a starting point.
I will switch to livetree in the next patch version.
Quoted 32 lines
Quoted 32 lines
drivers/dma/dma-uclass.c +31
-0+if (ret) { +pr_err ("%s: fdtdec_parse_phandle_with_args failed: err=%d\n" , + __func__, ret); +return ret; + } + + ret =uclass_get_device_by_of_offset (UCLASS_DMA , args.node, &dev_dma); +if (ret) { +pr_err ("%s: uclass_get_device_by_of_offset failed: err=%d\n" , + __func__, ret); +return ret; + } + + dma->dev = dev_dma; + + ops =dma_dev_ops (dev_dma); + +if (ops->of_xlate) + ret = ops->of_xlate (dma, &args); +else + ret =dma_of_xlate_default (dma, &args); +if (ret) { +pr_err ("of_xlate() failed: %d\n" , ret); +return ret; + } + + return dma_request(dev_dma, dma); +} +# endif /* OF_PLATDATA */ + +int dma_get_by_name (struct udevice *dev,const char *name,struct dma *dma)
Quoted 8 lines
drivers/dma/dma-uclass.c line 114
Quoted 7 lines
drivers/dma/dma-uclass.c +7
-0+{ +int index; + +debug ("%s(dev=%p, name=%s, dma=%p)\n" , __func__, dev, name, dma); + + index =fdt_stringlist_search (gd->fdt_blob,dev_of_offset (dev), +"dma-names" , name);
dev_read...
Ok.
Quoted 118 lines
Quoted 118 lines
drivers/dma/dma-uclass.c +84
-0+if (index <0 ) { +pr_err ("fdt_stringlist_search() failed: %d\n" , index); +return index; + } + +return dma_get_by_index (dev, index, dma); +} +# endif /* OF_CONTROL */ + +int dma_request (struct udevice *dev,struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dev); + +debug ("%s(dev=%p, dma=%p)\n" , __func__, dev, dma); + + dma->dev = dev; + +if (!ops->request) +return 0 ; + +return ops->request (dma); +} + +int dma_free (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->free) +return 0 ; + +return ops->free (dma); +} + +int dma_enable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->enable) +return -ENOSYS ; + +return ops->enable (dma); +} + +int dma_disable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->disable) +return -ENOSYS ; + +return ops->disable (dma); +} + +int dma_receive (struct dma *dma,void **dst) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->receive) +return -1 ; + +return ops->receive (dma, dst); +} + +int dma_send (struct dma *dma,void *src,size_t len) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->send) +return -1 ; + +return ops->send (dma, src, len); +} +#endif /* CONFIG_DMA_CHANNELS */ +int dma_get_device (u32 transfer_type,struct udevice **devp) {struct udevice *dev;include/dma-uclass.h +15
-0@@ -12,6 +12,7 @@/* See dma.h for background documentation. */ #include <dma.h> +#include <fdtdec.h> /* * struct dma_ops - Driver model DMA operations @@ -20,6 +21,82 @@* driver model. */ struct dma_ops { +#ifdef CONFIG_DMA_CHANNELS +/** +* of_xlate - Translate a client's device-tree (OF) DMA specifier. +* +* The DMA core calls this function as the first step in implementing +* a client's dma_get_by_*() call. +* +* If this function pointer is set to NULL, the DMA core will use a +* default implementation, which assumes #dma-cells = <1>, and that +* the DT cell contains a simple integer DMA Channel. +* +* At present, the DMA API solely supports device-tree. If this +* changes, other xxx_xlate() functions may be added to support those +* other mechanisms.
Quoted 8 lines
include/dma-uclass.h line 44
Quoted 7 lines
include/dma-uclass.h +7
-0+* +* @dma: The dma struct to hold the translation result. +* @args: The dma specifier values from device tree. +* @return 0 if OK, or a negative error code. +*/ +int (*of_xlate)(struct dma *dma, +struct fdtdec_phandle_args *args);Use new livetree struct here
Ok.
Quoted 3 lines
Regards,
Simon
Regards,
Álvaro.
RFC v2 2/15 dma: add channels support
In reply to Simon GlassHi Simon,
Quoted 105 lines · Simon Glass
Hi Alvaro,
Quoted 90 lines · Álvaro Fernández Rojas
This adds channels support for dma controllers that have multiple channels which can transfer data to/from different devices (enet, usb...).
Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v2: Introduce changes reported by Vignesh:
- Respect current dma implementation.
- Letdma_memcpyfind a compatible dma device.drivers/dma/Kconfig | 7 ++ drivers/dma/dma-uclass.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++ include/dma-uclass.h | 77 +++++++++++++++++++++ include/dma.h | 169 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 430 insertions(+)drivers/dma/Kconfig +7
-0@@ -12,6 +12,13 @@ config DMA buses that is used to transfer data to and from memory. The uclass interface is defined in include/dma.h. +config DMA_CHANNELS + bool "Enable DMA channels support" + depends on DMA + help + Enable channels support for DMA. Some DMA controllers have multiple + channels which can either transfer data to/from different devices. + config TI_EDMA3 bool "TI EDMA3 driver" helpdrivers/dma/dma-uclass.c +45
-0@@ -15,10 +15,187 @@#include <dm/device-internal.h> #include <dma.h> #include <dma-uclass.h> +#include <dt-structs.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ; +#ifdef CONFIG_DMA_CHANNELS +static inline struct dma_ops *dma_dev_ops(struct udevice *dev) +{ + return (struct dma_ops *)dev->driver->ops; +} + +# if CONFIG_IS_ENABLED(OF_CONTROL) +# if CONFIG_IS_ENABLED(OF_PLATDATA) +int dma_get_by_index_platdata(struct udevice *dev, int index, + struct phandle_2_cell *cells, struct dma *dma) +{ + int ret; + + if (index != 0) + return -ENOSYS; + ret = uclass_get_device(UCLASS_DMA, 0, &dma->dev); + if (ret) + return ret; + dma->id = cells[0].id; + + return 0; +} +# else +static int dma_of_xlate_default(struct dma *dma, + struct fdtdec_phandle_args *args) +{ + debug("%s(dma=%p)\n", __func__, dma); + + if (args->args_count > 1) { + pr_err("Invaild args_count: %d\n", args->args_count); + return -EINVAL; + } + + if (args->args_count) + dma->id = args->args[0]; + else + dma->id = 0; + + return 0; +} + +int dma_get_by_index(struct udevice *dev, int index, struct dma *dma) +{ + int ret;drivers/dma/dma-uclass.c line 76
Quoted 10 lines
drivers/dma/dma-uclass.c +10
-0+struct fdtdec_phandle_args args; +struct udevice *dev_dma; +struct dma_ops *ops; + +debug ("%s(dev=%p, index=%d, dma=%p)\n" , __func__, dev, index, dma); + +assert (dma); + ret =fdtdec_parse_phandle_with_args (gd->fdt_blob,dev_of_offset (dev), +"dmas" ,"#dma-cells" ,0 , index, + &args);Can you please use the livetree API? E.g. see
dev_read_phandle_with_args()
Quoted 2 lines
Also please move this into an
ofdata_to_platdatafunction rather than doing it each time this function is called.
I don't really get what you mean by moving this into an ofdata_to_platdata function.
This code is copied from other uclasses:
https://github.com/Noltari/u-boot/blob/master/drivers/clk/clk-uclass.c#L71
https://github.com/Noltari/u-boot/blob/master/drivers/power/domain/power-domain-uclass.c#L43
https://github.com/Noltari/u-boot/blob/master/drivers/reset/reset-uclass.c#L47
Quoted 167 lines
Quoted 29 lines
drivers/dma/dma-uclass.c +28
-0+if (ret) { +pr_err ("%s: fdtdec_parse_phandle_with_args failed: err=%d\n" , + __func__, ret); +return ret; + } + + ret =uclass_get_device_by_of_offset (UCLASS_DMA , args.node, &dev_dma); +if (ret) { +pr_err ("%s: uclass_get_device_by_of_offset failed: err=%d\n" , + __func__, ret); +return ret; + } + + dma->dev = dev_dma; + + ops =dma_dev_ops (dev_dma); + +if (ops->of_xlate) + ret = ops->of_xlate (dma, &args); +else + ret =dma_of_xlate_default (dma, &args); +if (ret) { +pr_err ("of_xlate() failed: %d\n" , ret); +return ret; + } + +return dma_request (dev_dma, dma); +}drivers/dma/dma-uclass.c line 114
Quoted 10 lines
drivers/dma/dma-uclass.c +10
-0+# endif /* OF_PLATDATA */ + +int dma_get_by_name (struct udevice *dev,const char *name,struct dma *dma) +{ +int index; + +debug ("%s(dev=%p, name=%s, dma=%p)\n" , __func__, dev, name, dma); + + index =fdt_stringlist_search (gd->fdt_blob,dev_of_offset (dev), +"dma-names" , name);
dev_read...Quoted 114 lines
drivers/dma/dma-uclass.c +84
-0+if (index <0 ) { +pr_err ("fdt_stringlist_search() failed: %d\n" , index); +return index; + } + +return dma_get_by_index (dev, index, dma); +} +# endif /* OF_CONTROL */ + +int dma_request (struct udevice *dev,struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dev); + +debug ("%s(dev=%p, dma=%p)\n" , __func__, dev, dma); + + dma->dev = dev; + +if (!ops->request) +return 0 ; + +return ops->request (dma); +} + +int dma_free (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->free) +return 0 ; + +return ops->free (dma); +} + +int dma_enable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->enable) +return -ENOSYS ; + +return ops->enable (dma); +} + +int dma_disable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->disable) +return -ENOSYS ; + +return ops->disable (dma); +} + +int dma_receive (struct dma *dma,void **dst) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->receive) +return -1 ; + +return ops->receive (dma, dst); +} + +int dma_send (struct dma *dma,void *src,size_t len) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->send) +return -1 ; + +return ops->send (dma, src, len); +} +#endif /* CONFIG_DMA_CHANNELS */ +int dma_get_device (u32 transfer_type,struct udevice **devp) {struct udevice *dev;include/dma-uclass.h +12
-0@@ -12,6 +12,7 @@/* See dma.h for background documentation. */ #include <dma.h> +#include <fdtdec.h> /* * struct dma_ops - Driver model DMA operations @@ -20,6 +21,82 @@* driver model. */ struct dma_ops { +#ifdef CONFIG_DMA_CHANNELS +/** +* of_xlate - Translate a client's device-tree (OF) DMA specifier. +* +* The DMA core calls this function as the first step in implementing +* a client's dma_get_by_*() call. +* +* If this function pointer is set to NULL, the DMA core will use a +* default implementation, which assumes #dma-cells = <1>, and that +* the DT cell contains a simple integer DMA Channel. +* include/dma-uclass.h line 44
Quoted 10 lines
include/dma-uclass.h +10
-0+* At present, the DMA API solely supports device-tree. If this +* changes, other xxx_xlate() functions may be added to support those +* other mechanisms. +* +* @dma: The dma struct to hold the translation result. +* @args: The dma specifier values from device tree. +* @return 0 if OK, or a negative error code. +*/ +int (*of_xlate)(struct dma *dma, +struct fdtdec_phandle_args *args);Use new livetree struct here
Quoted 2 lines
Regards,
Simon
Regards,
Álvaro.
RFC v2 3/15 dma: add bcm6348-iudma support
In reply to Álvaro Fernández RojasBCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
---
v2: Fix dma rx burst config and select DMA_CHANNELS.
drivers/dma/Kconfig | 9 + drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 505 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 515 insertions(+) create mode 100644 drivers/dma/bcm6348-iudma.c
drivers/dma/Kconfig +9 -0
@@ -19,6 +19,15 @@ config DMA_CHANNELS Enable channels support for DMA. Some DMA controllers have multiple channels which can either transfer data to/from different devices. +config BCM6348_IUDMA + bool "BCM6348 IUDMA driver" + depends on ARCH_BMIPS + select DMA_CHANNELS + help + Enable the BCM6348 IUDMA driver. + This driver support data transfer from devices to + memory and from memory to devices. + config TI_EDMA3 bool "TI EDMA3 driver" help
drivers/dma/Makefile +1 -0
@@ -9,6 +9,7 @@ obj-$(CONFIG_DMA) += dma-uclass.o obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o obj-$(CONFIG_APBH_DMA) += apbh_dma.o +obj-$(CONFIG_BCM6348_IUDMA) += bcm6348-iudma.o obj-$(CONFIG_FSL_DMA) += fsl_dma.o obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o obj-$(CONFIG_TI_EDMA3) += ti-edma3.o
drivers/dma/bcm6348-iudma.c new file +505 -0
505 lines not on this page · raw message
Signature · 1 line
2.11.0
RFC v2 4/15 bmips: bcm6338: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas---
v2: no changes
arch/mips/dts/brcm,bcm6338.dtsi | 14 ++++++++++++++ include/dt-bindings/dma/bcm6338-dma.h | 15 +++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6338-dma.h
arch/mips/dts/brcm,bcm6338.dtsi +14 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6338-clock.h> +#include <dt-bindings/dma/bcm6338-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6338-reset.h> #include "skeleton.dtsi"
@@ -131,5 +132,18 @@ reg = <0xfffe3100 0x38>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller at fffe2400 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe2400 0x1c>, + <0xfffe2500 0x60>, + <0xfffe2600 0x60>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <6>; + resets = <&periph_rst BCM6338_RST_DMAMEM>; + }; }; };
include/dt-bindings/dma/bcm6338-dma.h new file +15 -0
@@ -0,0 +1,15 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6338_H +#define __DT_BINDINGS_DMA_BCM6338_H + +#define BCM6338_DMA_ENET_RX 0 +#define BCM6338_DMA_ENET_TX 1 + +#endif /* __DT_BINDINGS_DMA_BCM6338_H */
Signature · 1 line
2.11.0
RFC v2 5/15 bmips: bcm6348: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas---
v2: no changes
arch/mips/dts/brcm,bcm6348.dtsi | 16 ++++++++++++++++ include/dt-bindings/dma/bcm6348-dma.h | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6348-dma.h
arch/mips/dts/brcm,bcm6348.dtsi +16 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6348-clock.h> +#include <dt-bindings/dma/bcm6348-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6348-reset.h> #include "skeleton.dtsi"
@@ -160,5 +161,20 @@ reg = <0xfffe2300 0x38>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller at fffe7000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe7000 0x1c>, + <0xfffe7100 0x40>, + <0xfffe7200 0x40>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <4>; + clocks = <&periph_clk BCM6348_CLK_ENET>; + resets = <&periph_rst BCM6348_RST_ENET>, + <&periph_rst BCM6348_RST_DMAMEM>; + }; }; };
include/dt-bindings/dma/bcm6348-dma.h new file +17 -0
@@ -0,0 +1,17 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6348_H +#define __DT_BINDINGS_DMA_BCM6348_H + +#define BCM6348_DMA_ENET0_RX 0 +#define BCM6348_DMA_ENET0_TX 1 +#define BCM6348_DMA_ENET1_RX 2 +#define BCM6348_DMA_ENET1_TX 3 + +#endif /* __DT_BINDINGS_DMA_BCM6348_H */
Signature · 1 line
2.11.0
RFC v2 6/15 bmips: bcm6358: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas---
v2: no changes
arch/mips/dts/brcm,bcm6358.dtsi | 18 ++++++++++++++++++ include/dt-bindings/dma/bcm6358-dma.h | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6358-dma.h
arch/mips/dts/brcm,bcm6358.dtsi +18 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6358-clock.h> +#include <dt-bindings/dma/bcm6358-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6358-reset.h> #include "skeleton.dtsi"
@@ -191,5 +192,22 @@ status = "disabled"; }; + + iudma: dma-controller at fffe5000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe5000 0x24>, + <0xfffe5100 0x80>, + <0xfffe5200 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + clocks = <&periph_clk BCM6358_CLK_EMUSB>, + <&periph_clk BCM6358_CLK_USBSU>, + <&periph_clk BCM6358_CLK_EPHY>; + resets = <&periph_rst BCM6358_RST_ENET>, + <&periph_rst BCM6358_RST_EPHY>; + }; }; };
include/dt-bindings/dma/bcm6358-dma.h new file +17 -0
@@ -0,0 +1,17 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6358_H +#define __DT_BINDINGS_DMA_BCM6358_H + +#define BCM6358_DMA_ENET0_RX 0 +#define BCM6358_DMA_ENET0_TX 1 +#define BCM6358_DMA_ENET1_RX 2 +#define BCM6358_DMA_ENET1_TX 3 + +#endif /* __DT_BINDINGS_DMA_BCM6358_H */
Signature · 1 line
2.11.0
RFC v2 7/15 phy: add support for internal phys
In reply to Álvaro Fernández Rojas---
v2: no changes
include/phy.h | 2 ++ 1 file changed, 2 insertions(+)
include/phy.h +2 -0
@@ -50,6 +50,7 @@ typedef enum { + PHY_INTERFACE_MODE_INTERNAL, PHY_INTERFACE_MODE_MII, PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_SGMII,
@@ -72,6 +73,7 @@ typedef enum { } phy_interface_t;static const char *phy_interface_strings[] = { + [PHY_INTERFACE_MODE_INTERNAL ] ="internal" , [PHY_INTERFACE_MODE_MII ] ="mii" , [PHY_INTERFACE_MODE_GMII ] ="gmii" , [PHY_INTERFACE_MODE_SGMII ] ="sgmii" ,
Signature · 1 line
2.11.0
RFC v2 8/15 net: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v2: select DMA_CHANNELS.
drivers/net/Kconfig | 10 + drivers/net/Makefile | 1 + drivers/net/bcm6348-eth.c | 517 +++++++++++++++++++++++++++++++++++++++++ include/configs/bmips_common.h | 5 +- 4 files changed, 532 insertions(+), 1 deletion(-) create mode 100644 drivers/net/bcm6348-eth.c
drivers/net/Kconfig +10 -0
@@ -71,6 +71,16 @@ config BCM_SF2_ETH_GMAC by the BCM_SF2_ETH driver. Say Y to any bcmcygnus based platforms. +config BCM6348_ETH + bool "BCM6348 EMAC support" + depends on DM_ETH && ARCH_BMIPS + select DMA + select DMA_CHANNELS + select MII + select PHYLIB + help + This driver supports the BCM6348 Ethernet MAC. + config DWC_ETH_QOS bool "Synopsys DWC Ethernet QOS device support" depends on DM_ETH
drivers/net/Makefile +1 -0
@@ -8,6 +8,7 @@ obj-$(CONFIG_ALTERA_TSE) += altera_tse.o obj-$(CONFIG_AG7XXX) += ag7xxx.o obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o +obj-$(CONFIG_BCM6348_ETH) += bcm6348-eth.o obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o obj-$(CONFIG_DRIVER_AX88180) += ax88180.o obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
drivers/net/bcm6348-eth.c new file +517 -0
517 lines not on this page · raw message
include/configs/bmips_common.h +4 -1
@@ -7,6 +7,9 @@#ifndef __CONFIG_BMIPS_COMMON_H#define __CONFIG_BMIPS_COMMON_H +/* ETH */ +#define CONFIG_PHY_RESET_DELAY 20 +/* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ 230400, 500000, 1500000 }
@@ -17,7 +20,7 @@/* Memory usage */ #define CONFIG_SYS_MAXARGS 24 -#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) +#define CONFIG_SYS_MALLOC_LEN (2 * 1024 * 1024)#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)#define CONFIG_SYS_CBSIZE 512
Signature · 1 line
2.11.0
RFC v2 9/15 bmips: bcm6338: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v2: no changes
arch/mips/dts/brcm,bcm6338.dtsi | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
arch/mips/dts/brcm,bcm6338.dtsi +15 -0
@@ -145,5 +145,20 @@ dma-channels = <6>; resets = <&periph_rst BCM6338_RST_DMAMEM>; }; + + enet: ethernet at fffe2800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe2800 0x2dc>; + clocks = <&periph_clk BCM6338_CLK_ENET>; + resets = <&periph_rst BCM6338_RST_ENET>; + dmas = <&iudma BCM6338_DMA_ENET_RX>, + <&iudma BCM6338_DMA_ENET_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; }; };
Signature · 1 line
2.11.0
RFC v2 10/15 bmips: enable f@st1704 enet support
In reply to Álvaro Fernández Rojas---
v2: no changes
arch/mips/dts/sagem,f at st1704.dts | 12 ++++++++++++ configs/sagem_f at st1704_ram_defconfig | 9 ++++++++- 2 files changed, 20 insertions(+), 1 deletion(-)
arch/mips/dts/sagem,f at st1704.dts +12 -0
@@ -40,6 +40,18 @@ }; }; +&enet { + status = "okay"; + phy = <&enetphy>; + phy-mode = "mii"; + + enetphy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio { status = "okay"; };
configs/sagem_f at st1704_ram_defconfig +8 -1
@@ -28,11 +28,15 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_SF=y CONFIG_CMD_SPI=y -# CONFIG_CMD_NET is not set +CONFIG_CMD_DHCP=y # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -41,6 +45,9 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_DM_RESET=y CONFIG_RESET_BCM6345=y # CONFIG_SPL_SERIAL_PRESENT is not set
Signature · 1 line
2.11.0
RFC v2 11/15 bmips: bcm6348: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v2: no changes
arch/mips/dts/brcm,bcm6348.dtsi | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
arch/mips/dts/brcm,bcm6348.dtsi +26 -0
@@ -162,6 +162,32 @@ u-boot,dm-pre-reloc; }; + enet0: ethernet at fffe6000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6000 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET0_RX>, + <&iudma BCM6348_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet at fffe6800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6800 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET1_RX>, + <&iudma BCM6348_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + iudma: dma-controller at fffe7000 { compatible = "brcm,bcm6348-iudma"; reg = <0xfffe7000 0x1c>,
Signature · 1 line
2.11.0
RFC v2 12/15 bmips: enable ct-5361 enet support
In reply to Álvaro Fernández Rojas---
v2: no changes
arch/mips/dts/comtrend,ct-5361.dts | 12 ++++++++++++ configs/comtrend_ct5361_ram_defconfig | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
arch/mips/dts/comtrend,ct-5361.dts +12 -0
@@ -35,6 +35,18 @@ }; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/comtrend_ct5361_ram_defconfig +7 -1
@@ -26,11 +26,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -38,6 +41,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6348_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
RFC v2 13/15 bmips: bcm6358: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v2: no changes
arch/mips/dts/brcm,bcm6358.dtsi | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
arch/mips/dts/brcm,bcm6358.dtsi +28 -0
@@ -193,6 +193,34 @@ status = "disabled"; }; + enet0: ethernet at fffe4000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4000 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET0>; + dmas = <&iudma BCM6358_DMA_ENET0_RX>, + <&iudma BCM6358_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet at fffe4800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4800 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET1>; + dmas = <&iudma BCM6358_DMA_ENET1_RX>, + <&iudma BCM6358_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + iudma: dma-controller at fffe5000 { compatible = "brcm,bcm6348-iudma"; reg = <0xfffe5000 0x24>,
Signature · 1 line
2.11.0
RFC v2 14/15 bmips: enable hg556a enet support
In reply to Álvaro Fernández Rojas---
v2: no changes
arch/mips/dts/huawei,hg556a.dts | 12 ++++++++++++ configs/huawei_hg556a_ram_defconfig | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
arch/mips/dts/huawei,hg556a.dts +12 -0
@@ -94,6 +94,18 @@ status = "okay"; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/huawei_hg556a_ram_defconfig +7 -1
@@ -26,11 +26,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -38,6 +41,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6358_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
RFC v2 15/15 bmips: enable nb4-ser enet support
In reply to Álvaro Fernández Rojas---
v2: no changes
arch/mips/dts/sfr,nb4-ser.dts | 24 ++++++++++++++++++++++++ configs/sfr_nb4-ser_ram_defconfig | 8 +++++++- 2 files changed, 31 insertions(+), 1 deletion(-)
arch/mips/dts/sfr,nb4-ser.dts +24 -0
@@ -54,6 +54,30 @@ status = "okay"; }; +&enet0 { + status = "okay"; + phy = <&enet0phy>; + phy-mode = "internal"; + + enet0phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/sfr_nb4-ser_ram_defconfig +7 -1
@@ -27,11 +27,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -40,6 +43,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6358_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
v3 cover bmips: add bcm6348-enet support
In reply to Álvaro Fernández RojasIn order to add bcm6348-enet support, dma-uclass must be extended to support dma channels and reworked to operate like the other dm uclass (clk, reset...).
This is a RFC, so please give you feedback on the things that I should fix or rework.
v3: Introduce changes reported by Simon Glass:
- Improve dma-uclass.h documentation.
- Switch to live tree API.
v2: Introduce changes reported by Vignesh:
- Respect current dma implementation.
- Let dma_memcpy find a compatible dma device.
Other changes:
- Fix bcm6348-iudma rx burst config.
Álvaro Fernández Rojas (15):
dma: move dma_ops to dma-uclass.h
dma: add channels support
dma: add bcm6348-iudma support
bmips: bcm6338: add bcm6348-iudma support
bmips: bcm6348: add bcm6348-iudma support
bmips: bcm6358: add bcm6348-iudma support
phy: add support for internal phys
net: add support for bcm6348-enet
bmips: bcm6338: add support for bcm6348-enet
bmips: enable f at st1704 enet support
bmips: bcm6348: add support for bcm6348-enet
bmips: enable ct-5361 enet support
bmips: bcm6358: add support for bcm6348-enet
bmips: enable hg556a enet support
bmips: enable nb4-ser enet support
arch/mips/dts/brcm,bcm6338.dtsi | 29 ++ arch/mips/dts/brcm,bcm6348.dtsi | 42 +++ arch/mips/dts/brcm,bcm6358.dtsi | 46 +++ arch/mips/dts/comtrend,ct-5361.dts | 12 + arch/mips/dts/huawei,hg556a.dts | 12 + arch/mips/dts/sagem,f at st1704.dts | 12 + arch/mips/dts/sfr,nb4-ser.dts | 24 ++ configs/comtrend_ct5361_ram_defconfig | 8 +- configs/huawei_hg556a_ram_defconfig | 8 +- configs/sagem_f at st1704_ram_defconfig | 9 +- configs/sfr_nb4-ser_ram_defconfig | 8 +- drivers/dma/Kconfig | 16 ++ drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 505 +++++++++++++++++++++++++++++++++ drivers/dma/dma-uclass.c | 191 ++++++++++++- drivers/net/Kconfig | 10 + drivers/net/Makefile | 1 + drivers/net/bcm6348-eth.c | 517 ++++++++++++++++++++++++++++++++++ include/configs/bmips_common.h | 5 +- include/dma-uclass.h | 117 ++++++++ include/dma.h | 196 +++++++++++-- include/dt-bindings/dma/bcm6338-dma.h | 15 + include/dt-bindings/dma/bcm6348-dma.h | 17 ++ include/dt-bindings/dma/bcm6358-dma.h | 17 ++ include/phy.h | 2 + 25 files changed, 1784 insertions(+), 36 deletions(-) create mode 100644 drivers/dma/bcm6348-iudma.c create mode 100644 drivers/net/bcm6348-eth.c create mode 100644 include/dma-uclass.h create mode 100644 include/dt-bindings/dma/bcm6338-dma.h create mode 100644 include/dt-bindings/dma/bcm6348-dma.h create mode 100644 include/dt-bindings/dma/bcm6358-dma.h
Signature · 1 line
2.11.0
RFC v3 1/15 dma: move dma_ops to dma-uclass.h
Move dma_ops to a separate header file, following other uclass implementations. While doing so, this patch also improves dma_ops documentation.
---
v3: Introduce changes reported by Simon Glass:
- Improve dma-uclass.h documentation.
- Switch to live tree API.
drivers/dma/dma-uclass.c | 3 ++- include/dma-uclass.h | 39 +++++++++++++++++++++++++++++++++++++++ include/dma.h | 22 ---------------------- 3 files changed, 41 insertions(+), 23 deletions(-) create mode 100644 include/dma-uclass.h
drivers/dma/dma-uclass.c +2 -1
@@ -10,10 +10,11 @@*/ #include <common.h> -#include <dma.h> #include <dm.h> #include <dm/uclass-internal.h> #include <dm/device-internal.h> +#include <dma.h> +#include <dma-uclass.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ;
include/dma-uclass.h new file +39 -0
@@ -0,0 +1,39 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com> +* Written by Mugunthan V N <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _DMA_UCLASS_H +#define _DMA_UCLASS_H + +/* See dma.h for background documentation. */ + +#include <dma.h> + +/* +* struct dma_ops - Driver model DMA operations +* +* The uclass interface is implemented by all DMA devices which use +* driver model. +*/ +struct dma_ops { +/** +* transfer() - Issue a DMA transfer. The implementation must +* wait until the transfer is done. +* +* @dev: The DMA device +* @direction: direction of data transfer (should be one from +* enum dma_direction) +* @dst: The destination pointer. +* @src: The source pointer. +* @len: Length of the data to be copied (number of bytes). +* @return zero on success, or -ve error code. +*/ +int (*transfer)(struct udevice *dev,int direction,void *dst, +void *src,size_t len); +}; + +#endif /* _DMA_UCLASS_H */
include/dma.h +0 -22
@@ -28,28 +28,6 @@ enum dma_direction {#define DMA_SUPPORTS_DEV_TO_DEV BIT(3)/* -* struct dma_ops - Driver model DMA operations -* -* The uclass interface is implemented by all DMA devices which use -* driver model. -*/ -struct dma_ops { -/* -* Get the current timer count -* -* @dev: The DMA device -* @direction: direction of data transfer should be one from -enum dma_direction -* @dst: Destination pointer -* @src: Source pointer -* @len: Length of the data to be copied. -* @return: 0 if OK, -ve on error -*/ -int (*transfer)(struct udevice *dev,int direction,void *dst, -void *src,size_t len); -}; - -/* * struct dma_dev_priv - information about a device used by the uclass * * @supported: mode of transfers that DMA can support, should be
Signature · 1 line
2.11.0
RFC v3 1/15 dma: move dma_ops to dma-uclass.h
Quoted 9 lines · Álvaro Fernández Rojas
Move
dma_opsto a separate header file, following other uclass implementations. While doing so, this patch also improvesdma_opsdocumentation.Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v3: Introduce changes reported by Simon Glass:
- Improvedma-uclass.hdocumentation.
- Switch to live tree API.
Quoted 5 lines
drivers/dma/dma-uclass.c | 3 ++- include/dma-uclass.h | 39 +++++++++++++++++++++++++++++++++++++++ include/dma.h | 22 ---------------------- 3 files changed, 41 insertions(+), 23 deletions(-) create mode 100644 include/dma-uclass.h
RFC v3 1/15 dma: move dma_ops to dma-uclass.h
Quoted 10 lines · Simon Glass
Quoted 9 lines · Álvaro Fernández Rojas
Move
dma_opsto a separate header file, following other uclass implementations. While doing so, this patch also improvesdma_opsdocumentation.Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v3: Introduce changes reported by Simon Glass:
- Improvedma-uclass.hdocumentation.
- Switch to live tree API.
Quoted 7 lines
Quoted 5 lines
drivers/dma/dma-uclass.c | 3 ++- include/dma-uclass.h | 39 +++++++++++++++++++++++++++++++++++++++ include/dma.h | 22 ---------------------- 3 files changed, 41 insertions(+), 23 deletions(-)create mode 100644
include/dma-uclass.hReviewed-by Simon Glass <[email protected]>
this patch will break build of existing DMA drivers, as the do not have #include <dma-uclass.h>.
drivers/dma/ti-edma3.c:563:21: error: variable 'ti_edma3_ops' has initializer but incomplete type
static const struct dma_ops ti_edma3_ops = {
^~~~~~~drivers/dma/ti-edma3.c:564:2: error: unknown field 'transfer' specified in initializer
.transfer = ti_edma3_transfer,
^drivers/dma/ti-edma3.c:564:14: warning: excess elements in struct initializer
.transfer = ti_edma3_transfer,
^~~~~~~~~~~~~~~~~
drivers/dma/ti-edma3.c:564:14: note: (near initialization for 'ti_edma3_ops')
drivers/dma/ti-edma3.c:563:29: error: storage size of 'ti_edma3_ops' isn't known
static const struct dma_ops ti_edma3_ops = {
^~~~~~~~~~~~make[1]: *** [drivers/dma/ti-edma3.o] Error 1
Signature · 2 lines
regards, -grygorii
RFC v3 1/15 dma: move dma_ops to dma-uclass.h
Hi Grygorii,
Thanks for reporting that, it should be fixed on v5.
Regards,
Álvaro.
Quoted 37 lines · Grygorii Strashko
Quoted 10 lines · Simon Glass
Quoted 9 lines · Álvaro Fernández Rojas
Move
dma_opsto a separate header file, following other uclass implementations. While doing so, this patch also improvesdma_opsdocumentation.Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v3: Introduce changes reported by Simon Glass:
- Improvedma-uclass.hdocumentation.
- Switch to live tree API.Quoted 6 lines
Quoted 5 lines
drivers/dma/dma-uclass.c | 3 ++- include/dma-uclass.h | 39 +++++++++++++++++++++++++++++++++++++++ include/dma.h | 22 ---------------------- 3 files changed, 41 insertions(+), 23 deletions(-)create mode 100644
include/dma-uclass.hReviewed-by Simon Glass <[email protected]>this patch will break build of existing DMA drivers, as the do not have #include <
dma-uclass.h>.
drivers/dma/ti-edma3.c:563:21: error: variable 'ti_edma3_ops' has initializer but incomplete typestatic const struct dma_ops ti_edma3_ops = { ^~~~~~~
drivers/dma/ti-edma3.c:564:2: error: unknown field 'transfer' specified in initializer
.transfer =ti_edma3_transfer,
^drivers/dma/ti-edma3.c:564:14: warning: excess elements in struct initializer
.transfer =ti_edma3_transfer,^~~~~~~~~~~~~~~~~ drivers/dma/ti-edma3.c:564:14: note: (near initialization for 'ti_edma3_ops') drivers/dma/ti-edma3.c:563:29: error: storage size of 'ti_edma3_ops' isn't known static const struct dma_ops ti_edma3_ops = { ^~~~~~~~~~~~make[1]: *** [
drivers/dma/ti-edma3.o] Error 1
RFC v3 2/15 dma: add channels support
In reply to Álvaro Fernández RojasThis adds channels support for dma controllers that have multiple channels which can transfer data to/from different devices (enet, usb...).
---
v3: Introduce changes reported by Simon Glass:
- Improve dma-uclass.h documentation.
- Switch to live tree API.
drivers/dma/Kconfig | 7 ++ drivers/dma/dma-uclass.c | 188 +++++++++++++++++++++++++++++++++++++++++++++-- include/dma-uclass.h | 78 ++++++++++++++++++++ include/dma.h | 174 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 439 insertions(+), 8 deletions(-)
drivers/dma/Kconfig +7 -0
@@ -12,6 +12,13 @@ config DMA buses that is used to transfer data to and from memory. The uclass interface is defined in include/dma.h. +config DMA_CHANNELS + bool "Enable DMA channels support" + depends on DMA + help + Enable channels support for DMA. Some DMA controllers have multiple + channels which can either transfer data to/from different devices. + config TI_EDMA3 bool "TI EDMA3 driver" help
drivers/dma/dma-uclass.c +182 -6
206 lines not on this page · raw message
include/dma-uclass.h +78 -0
90 lines not on this page · raw message
include/dma.h +172 -2
190 lines not on this page · raw message
Signature · 1 line
2.11.0
RFC v3 2/15 dma: add channels support
Quoted 9 lines · Álvaro Fernández Rojas
This adds channels support for dma controllers that have multiple channels which can transfer data to/from different devices (enet, usb...).
Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v3: Introduce changes reported by Simon Glass:
- Improvedma-uclass.hdocumentation.
- Switch to live tree API.
Quoted 6 lines
drivers/dma/Kconfig | 7 ++ drivers/dma/dma-uclass.c | 188 +++++++++++++++++++++++++++++++++++++++++++++-- include/dma-uclass.h | 78 ++++++++++++++++++++ include/dma.h | 174 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 439 insertions(+), 8 deletions(-)
Re moving the code into ofdata_to_platdata(), I suppose what you have here is OK.
Regards,
Simon
RFC v3 3/15 dma: add bcm6348-iudma support
In reply to Álvaro Fernández RojasBCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
---
v3: no changes
v2: Fix dma rx burst config and select DMA_CHANNELS.
drivers/dma/Kconfig | 9 + drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 505 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 515 insertions(+) create mode 100644 drivers/dma/bcm6348-iudma.c
drivers/dma/Kconfig +9 -0
@@ -19,6 +19,15 @@ config DMA_CHANNELS Enable channels support for DMA. Some DMA controllers have multiple channels which can either transfer data to/from different devices. +config BCM6348_IUDMA + bool "BCM6348 IUDMA driver" + depends on ARCH_BMIPS + select DMA_CHANNELS + help + Enable the BCM6348 IUDMA driver. + This driver support data transfer from devices to + memory and from memory to devices. + config TI_EDMA3 bool "TI EDMA3 driver" help
drivers/dma/Makefile +1 -0
@@ -9,6 +9,7 @@ obj-$(CONFIG_DMA) += dma-uclass.o obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o obj-$(CONFIG_APBH_DMA) += apbh_dma.o +obj-$(CONFIG_BCM6348_IUDMA) += bcm6348-iudma.o obj-$(CONFIG_FSL_DMA) += fsl_dma.o obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o obj-$(CONFIG_TI_EDMA3) += ti-edma3.o
drivers/dma/bcm6348-iudma.c new file +505 -0
505 lines not on this page · raw message
Signature · 1 line
2.11.0
RFC v3 3/15 dma: add bcm6348-iudma support
Hi
I'd appreciated if you can clarify few points below.
Quoted 13 lines · Álvaro Fernández Rojas
BCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v3: no changes
v2: Fix dma rx burst config and selectDMA_CHANNELS.drivers/dma/Kconfig | 9 + drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 505 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 515 insertions(+)create mode 100644
drivers/dma/bcm6348-iudma.c
[...]
Quoted 5 lines
drivers/dma/bcm6348-iudma.c new file +4
-0+static int bcm6348_iudma_enable (struct dma *dma) +{ +struct bcm6348_iudma_priv *priv =dev_get_priv (dma->dev); +struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
drivers/dma/bcm6348-iudma.c line 200
Quoted 10 lines
drivers/dma/bcm6348-iudma.c new file +10
-0+struct bcm6348_dma_desc *dma_desc; +uint8_t i; + +/* init dma rings */ + dma_desc = ch_priv->dma_ring; +for (i =0 ; i < ch_priv->dma_ring_size; i++) { +if (bcm6348_iudma_chan_is_rx (dma->id)) { + dma_desc->status =DMAD_ST_OWN_MASK ; + dma_desc->length =PKTSIZE_ALIGN ; + dma_desc->address =virt_to_phys (net_rx_packets[i]);
You are filling RX queue/ring with buffers defined in Net core. Does it mean that this DMA driver will not be usable for other purposes, as Net can be compiled out?
Wouldn't it be reasonable to have some sort of .receive_prepare() callback in DMA dma_ops, so DMA user can control which buffers to push in RX DMA channel? And it also can be used in eth_ops.free_pkt() callback (see below).
Quoted 59 lines
drivers/dma/bcm6348-iudma.c new file +59
-0+ }else { + dma_desc->status =0 ; + dma_desc->length =0 ; + dma_desc->address =0 ; + } + +if (i == ch_priv->dma_ring_size -1 ) + dma_desc->status |=DMAD_ST_WRAP_MASK ; + +if (bcm6348_iudma_chan_is_rx (dma->id)) +writel_be (1 , + priv->base +DMA_FLOWC_ALLOC_REG (dma->id)); + + dma_desc++; + } + +/* init to first descriptor */ + ch_priv->desc_id =0 ; + +/* force cache writeback */ +flush_dcache_range ((ulong )ch_priv->dma_ring, + ALIGN_END_ADDR(struct bcm6348_dma_desc, ch_priv->dma_ring, + ch_priv->dma_ring_size)); + +/* clear sram */ +writel_be (0 , priv->sram +DMAS_STATE_DATA_REG (dma->id)); +writel_be (0 , priv->sram +DMAS_DESC_LEN_STATUS_REG (dma->id)); +writel_be (0 , priv->sram +DMAS_DESC_BASE_BUFPTR_REG (dma->id)); + +/* set dma ring start */ +writel_be (virt_to_phys (ch_priv->dma_ring), + priv->sram +DMAS_RSTART_REG (dma->id)); + +/* set flow control */ +if (bcm6348_iudma_chan_is_rx (dma->id)) { +u32 val; + +setbits_be32 (priv->base +DMA_CFG_REG , +DMA_CFG_FLOWC_ENABLE (dma->id)); + + val = ch_priv->dma_ring_size /3 ; +writel_be (val, priv->base +DMA_FLOWC_THR_LO_REG (dma->id)); + + val = (ch_priv->dma_ring_size *2 ) /3 ; +writel_be (val, priv->base +DMA_FLOWC_THR_HI_REG (dma->id)); + } + +/* set dma max burst */ +writel_be (ch_priv->dma_ring_size, + priv->chan +DMAC_BURST_REG (dma->id)); + +/* clear interrupts */ +writel_be (DMAC_IR_DONE_MASK , priv->chan +DMAC_IR_ST_REG (dma->id)); +writel_be (0 , priv->chan +DMAC_IR_EN_REG (dma->id)); + +setbits_be32 (priv->chan +DMAC_CFG_REG (dma->id),DMAC_CFG_ENABLE_MASK ); + +return 0 ; +}
[...]
Quoted 37 lines
drivers/dma/bcm6348-iudma.c new file +37
-0+ +static int bcm6348_iudma_receive (struct dma *dma,void **dst) +{ +struct bcm6348_iudma_priv *priv =dev_get_priv (dma->dev); +struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id]; +struct bcm6348_dma_desc *dma_desc; +void __iomem *dma_buff; +uint16_t status; +int ret; + +/* get dma ring descriptor address */ + dma_desc = ch_priv->dma_ring; + dma_desc += ch_priv->desc_id; + +/* invalidate cache data */ +invalidate_dcache_range ((ulong )dma_desc, + ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1)); + +/* check dma own */ +if (dma_desc->status &DMAD_ST_OWN_MASK ) +return 0 ; + +/* check dma end */ +if (!(dma_desc->status &DMAD_ST_EOP_MASK )) +return -EINVAL ; + +/* get dma buff descriptor address */ + dma_buff =phys_to_virt (dma_desc->address); + +/* invalidate cache data */ +invalidate_dcache_range ((ulong )dma_buff, + (ulong)(dma_buff +PKTSIZE_ALIGN )); + +/* get dma data */ + *dst = dma_buff; + ret = dma_desc->length; +
drivers/dma/bcm6348-iudma.c line 335
Quoted 10 lines
drivers/dma/bcm6348-iudma.c new file +10
-0+/* reinit dma descriptor */ + status = dma_desc->status &DMAD_ST_WRAP_MASK ; + status |=DMAD_ST_OWN_MASK ; + + dma_desc->length =PKTSIZE_ALIGN ; + dma_desc->status = status; + +/* flush cache */ +flush_dcache_range ((ulong )dma_desc, + ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1));
Could you clarify pls, if you do return dma_desc to RX ring here or not?
if yes, wouldn't it cause potential problem on Net RX path
ret = eth_get_ops(current)->recv(current, flags, &packet);
^^ (1) here buffer will be received from DMA ( and pushed back to RX ring ?? )
flags = 0; if (ret > 0) net_process_received_packet(packet, ret);
^^ (2) here it will be passed in Net stack
if (ret >= 0 && eth_get_ops(current)->free_pkt) eth_get_ops(current)->free_pkt(current, packet, ret);
^^ at this point it should be safe to return buffer in DMA RX ring.
if (ret <= 0) break;
Can DMA overwrite packet after point (1) while packet is still processed (2)?
Quoted 16 lines
drivers/dma/bcm6348-iudma.c new file +16
-0+ +/* set flow control buffer alloc */ +writel_be (1 , priv->base +DMA_FLOWC_ALLOC_REG (dma->id)); + +/* enable dma */ +setbits_be32 (priv->chan +DMAC_CFG_REG (dma->id),DMAC_CFG_ENABLE_MASK ); + +/* set interrupt */ +writel_be (DMAC_IR_DONE_MASK , priv->chan +DMAC_IR_EN_REG (dma->id)); + +/* increment dma descriptor */ + ch_priv->desc_id = (ch_priv->desc_id +1 ) % ch_priv->dma_ring_size; + +return ret -4 ; +} +
Signature · 2 lines
regards, -grygorii
RFC v3 3/15 dma: add bcm6348-iudma support
Hi Grygori,
Quoted 29 lines · Grygorii Strashko
Hi
I'd appreciated if you can clarify few points below.
Quoted 13 lines · Álvaro Fernández Rojas
BCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v3: no changes
v2: Fix dma rx burst config and selectDMA_CHANNELS.drivers/dma/Kconfig | 9 + drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 505 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 515 insertions(+)create mode 100644
drivers/dma/bcm6348-iudma.c[...]
Quoted 9 lines
drivers/dma/bcm6348-iudma.c new file +9
-0+static int bcm6348_iudma_enable (struct dma *dma) +{ +struct bcm6348_iudma_priv *priv =dev_get_priv (dma->dev); +struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id]; +struct bcm6348_dma_desc *dma_desc; +uint8_t i; + +/* init dma rings */ + dma_desc = ch_priv->dma_ring;
Quoted 8 lines
drivers/dma/bcm6348-iudma.c line 200
Quoted 5 lines
drivers/dma/bcm6348-iudma.c new file +5
-0+for (i =0 ; i < ch_priv->dma_ring_size; i++) { +if (bcm6348_iudma_chan_is_rx (dma->id)) { + dma_desc->status =DMAD_ST_OWN_MASK ; + dma_desc->length =PKTSIZE_ALIGN ; + dma_desc->address =virt_to_phys (net_rx_packets[i]);You are filling RX queue/ring with buffers defined in Net core. Does it mean that this DMA driver will not be usable for other purposes, as Net can be compiled out?
As far as I know, and depending on the specific SoC, BCM63xx IUDMA is used for Ethernet, USB (device only) and xDSL.
So yes, in u-boot it will be used for ethernet only.
BTW, my first attempt didn't use net_rx_packets, but I saw that in pic32_eth implementation and dropped the dma specific buffers. I will add them again ;).
Quoted 4 lines
Wouldn't it be reasonable to have some sort of .receive_prepare() callback in DMA
dma_ops, so DMA user can control which buffers to push in RX DMA channel? And it also can be used ineth_ops.free_pkt()callback (see below).
Yes, probably, but maybe we can achieve that without adding another call.
Quoted 102 lines
Quoted 60 lines
drivers/dma/bcm6348-iudma.c new file +59
-0+ }else { + dma_desc->status =0 ; + dma_desc->length =0 ; + dma_desc->address =0 ; + } + +if (i == ch_priv->dma_ring_size -1 ) + dma_desc->status |=DMAD_ST_WRAP_MASK ; + +if (bcm6348_iudma_chan_is_rx (dma->id)) +writel_be (1 , + priv->base +DMA_FLOWC_ALLOC_REG (dma->id)); + + dma_desc++; + } + +/* init to first descriptor */ + ch_priv->desc_id =0 ; + +/* force cache writeback */ +flush_dcache_range ((ulong )ch_priv->dma_ring, + ALIGN_END_ADDR(struct bcm6348_dma_desc, ch_priv->dma_ring, + ch_priv->dma_ring_size)); + +/* clear sram */ +writel_be (0 , priv->sram +DMAS_STATE_DATA_REG (dma->id)); +writel_be (0 , priv->sram +DMAS_DESC_LEN_STATUS_REG (dma->id)); +writel_be (0 , priv->sram +DMAS_DESC_BASE_BUFPTR_REG (dma->id)); + +/* set dma ring start */ +writel_be (virt_to_phys (ch_priv->dma_ring), + priv->sram +DMAS_RSTART_REG (dma->id)); + +/* set flow control */ +if (bcm6348_iudma_chan_is_rx (dma->id)) { +u32 val; + +setbits_be32 (priv->base +DMA_CFG_REG , +DMA_CFG_FLOWC_ENABLE (dma->id)); + + val = ch_priv->dma_ring_size /3 ; +writel_be (val, priv->base +DMA_FLOWC_THR_LO_REG (dma->id)); + + val = (ch_priv->dma_ring_size *2 ) /3 ; +writel_be (val, priv->base +DMA_FLOWC_THR_HI_REG (dma->id)); + } + +/* set dma max burst */ +writel_be (ch_priv->dma_ring_size, + priv->chan +DMAC_BURST_REG (dma->id)); + +/* clear interrupts */ +writel_be (DMAC_IR_DONE_MASK , priv->chan +DMAC_IR_ST_REG (dma->id)); +writel_be (0 , priv->chan +DMAC_IR_EN_REG (dma->id)); + +setbits_be32 (priv->chan +DMAC_CFG_REG (dma->id),DMAC_CFG_ENABLE_MASK ); + +return 0 ; +}[...]
Quoted 40 lines
drivers/dma/bcm6348-iudma.c new file +40
-0+ +static int bcm6348_iudma_receive (struct dma *dma,void **dst) +{ +struct bcm6348_iudma_priv *priv =dev_get_priv (dma->dev); +struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id]; +struct bcm6348_dma_desc *dma_desc; +void __iomem *dma_buff; +uint16_t status; +int ret; + +/* get dma ring descriptor address */ + dma_desc = ch_priv->dma_ring; + dma_desc += ch_priv->desc_id; + +/* invalidate cache data */ +invalidate_dcache_range ((ulong )dma_desc, + ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1)); + +/* check dma own */ +if (dma_desc->status &DMAD_ST_OWN_MASK ) +return 0 ; + +/* check dma end */ +if (!(dma_desc->status &DMAD_ST_EOP_MASK )) +return -EINVAL ; + +/* get dma buff descriptor address */ + dma_buff =phys_to_virt (dma_desc->address); + +/* invalidate cache data */ +invalidate_dcache_range ((ulong )dma_buff, + (ulong)(dma_buff +PKTSIZE_ALIGN )); + +/* get dma data */ + *dst = dma_buff; + ret = dma_desc->length; + +/* reinit dma descriptor */ + status = dma_desc->status &DMAD_ST_WRAP_MASK ; + status |=DMAD_ST_OWN_MASK ;
Quoted 8 lines
drivers/dma/bcm6348-iudma.c line 335
Quoted 7 lines
drivers/dma/bcm6348-iudma.c new file +7
-0+ + dma_desc->length =PKTSIZE_ALIGN ; + dma_desc->status = status; + +/* flush cache */ +flush_dcache_range ((ulong )dma_desc, + ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1));Could you clarify pls, if you do return
dma_descto RX ring here or not?
Yes.
Quoted 10 lines
if yes, wouldn't it cause potential problem on Net RX path
ret = eth_get_ops(current)->recv(current, flags, &packet);^^ (1) here buffer will be received from DMA ( and pushed back to RX ring ?? )
flags = 0; if (ret > 0) net_process_received_packet(packet, ret);^^ (2) here it will be passed in Net stack
Quoted 8 lines
if (ret >= 0 && eth_get_ops(current)->free_pkt) eth_get_ops(current)->free_pkt(current, packet, ret);^^ at this point it should be safe to return buffer in DMA RX ring.
if (ret <= 0) break;Can DMA overwrite packet after point (1) while packet is still processed (2)?
I don't think so, because as far as I know u-boot is not processing more than one packet at once, is it?
But yeah, I see your point and if it does process more than one packet at once this is not the proper way to do that.
I will use free_pkt in next version and lock the packet until it's processed.
Quoted 19 lines
Quoted 7 lines
drivers/dma/bcm6348-iudma.c new file +6
-0+ +/* set flow control buffer alloc */ +writel_be (1 , priv->base +DMA_FLOWC_ALLOC_REG (dma->id)); + +/* enable dma */ +setbits_be32 (priv->chan +DMAC_CFG_REG (dma->id),DMAC_CFG_ENABLE_MASK );drivers/dma/bcm6348-iudma.c line 351
Quoted 10 lines
drivers/dma/bcm6348-iudma.c new file +10
-0+ +/* set interrupt */ +writel_be (DMAC_IR_DONE_MASK , priv->chan +DMAC_IR_EN_REG (dma->id)); + +/* increment dma descriptor */ + ch_priv->desc_id = (ch_priv->desc_id +1 ) % ch_priv->dma_ring_size; + +return ret -4 ; +} +
Regards,
Álvaro.
RFC v3 3/15 dma: add bcm6348-iudma support
Hi
thanks for your comments.
Quoted 35 lines · Álvaro Fernández Rojas
Quoted 26 lines · Grygorii Strashko
Quoted 14 lines · Álvaro Fernández Rojas
BCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v3: no changes
v2: Fix dma rx burst config and selectDMA_CHANNELS.drivers/dma/Kconfig | 9 +
drivers/dma/Makefile | 1 +
drivers/dma/bcm6348-iudma.c| 505
++++++++++++++++++++++++++++++++++++++++++++3 files changed, 515 insertions(+)create mode 100644
drivers/dma/bcm6348-iudma.c[...]
Quoted 10 lines
drivers/dma/bcm6348-iudma.c new file +10
-0+static int bcm6348_iudma_enable (struct dma *dma) +{ + struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev); + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id]; + struct bcm6348_dma_desc *dma_desc; + uint8_t i; + + /* init dma rings */ + dma_desc = ch_priv->dma_ring; + for (i = 0; i < ch_priv->dma_ring_size; i++) {Quoted 8 lines
Quoted 4 lines
+ if (
bcm6348_iudma_chan_is_rx(dma->id)) {
+dma_desc->status=DMAD_ST_OWN_MASK;
+dma_desc->length=PKTSIZE_ALIGN;
+dma_desc->address=virt_to_phys(net_rx_packets[i]);You are filling RX queue/ring with buffers defined in Net core. Does it mean that this DMA driver will not be usable for other purposes, as
Net can be compiled out?
Quoted 6 lines
As far as I know, and depending on the specific SoC, BCM63xx IUDMA is used for Ethernet, USB (device only) and xDSL.
So yes, in u-boot it will be used for ethernet only.
BTW, my first attempt didn't usenet_rx_packets, but I saw that inpic32_ethimplementation and dropped the dma specific buffers. I will add them again ;).
it is really net specific :)
Quoted 8 lines
Quoted 6 lines
Wouldn't it be reasonable to have some sort of .receive_prepare() callback in
DMAdma_ops, so DMA user can control which buffers to push in RX DMA channel?
And it also can be used ineth_ops.free_pkt()callback (see below).Yes, probably, but maybe we can achieve that without adding another call.
Quoted 1 line
I'm looking at this patch set from our HW point of view. In my case, DMA channel can be used with different IPs (not only networking), so it would be really great if DMA user can pass RX buffers in DMA driver - network driver can use net_rx_packets, other drivers might use own buffers. So hard-codding RX buffers in DMA driver looks like not a good choice.
Quoted 21 lines
Quoted 5 lines
Quoted 4 lines
+
+ /* flush cache */
+ flush_dcache_range((ulong)dma_desc,
+ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1));Could you clarify pls, if you do return
dma_descto RX ring here or not?Yes.
Quoted 15 lines
if yes, wouldn't it cause potential problem on Net RX path ret = eth_get_ops(current)->recv(current, flags, &packet); ^^ (1) here buffer will be received from DMA ( and pushed back to RX ring ?? )
flags = 0;
if (ret > 0)net_process_received_packet(packet, ret); ^^ (2) here it will be passed in Net stackif (ret >= 0 && eth_get_ops(current)->free_pkt) eth_get_ops(current)->free_pkt(current, packet, ret); ^^ at this point it should be safe to return buffer in DMA RX ring.
Quoted 7 lines
Quoted 5 lines
if (ret <= 0)
break;Can DMA overwrite packet after point (1) while packet is still processed (2)?
I don't think so, because as far as I know u-boot is not processing more than one packet at once, is it?
u-boot can't process more than one packet, but dma does. if buffer returned to DMA and there are some traffic on the line - DMA can potentially refill all buffers in its RX ring while u-boot still processing one packet.
Quoted 4 lines
But yeah, I see your point and if it does process more than one packet at once this is not the proper way to do that.
I will usefree_pktin next version and lock the packet until it's processed.
Signature · 2 lines
regards, -grygorii
RFC v3 3/15 dma: add bcm6348-iudma support
Hi Grygorii,
Quoted 83 lines · Grygorii Strashko
Hi
thanks for your comments.
Quoted 35 lines · Álvaro Fernández Rojas
Quoted 26 lines · Grygorii Strashko
Quoted 14 lines · Álvaro Fernández Rojas
BCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v3: no changes
v2: Fix dma rx burst config and selectDMA_CHANNELS.drivers/dma/Kconfig | 9 + drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 505 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 515 insertions(+)create mode 100644
drivers/dma/bcm6348-iudma.c[...]
Quoted 10 lines
drivers/dma/bcm6348-iudma.c new file +10
-0+static int bcm6348_iudma_enable (struct dma *dma) +{ + struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev); + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id]; + struct bcm6348_dma_desc *dma_desc; + uint8_t i; + + /* init dma rings */ + dma_desc = ch_priv->dma_ring; + for (i = 0; i < ch_priv->dma_ring_size; i++) {Quoted 8 lines
Quoted 4 lines
+ if (
bcm6348_iudma_chan_is_rx(dma->id)) {
+dma_desc->status=DMAD_ST_OWN_MASK;
+dma_desc->length=PKTSIZE_ALIGN;
+dma_desc->address=virt_to_phys(net_rx_packets[i]);You are filling RX queue/ring with buffers defined in Net core. Does it mean that this DMA driver will not be usable for other purposes, as
Net can be compiled out?Quoted 6 lines
As far as I know, and depending on the specific SoC, BCM63xx IUDMA is used for Ethernet, USB (device only) and xDSL.
So yes, in u-boot it will be used for ethernet only.
BTW, my first attempt didn't usenet_rx_packets, but I saw that inpic32_ethimplementation and dropped the dma specific buffers. I will add them again ;).it is really net specific :)
Quoted 6 lines
Quoted 5 lines
Wouldn't it be reasonable to have some sort of .receive_prepare() callback in
DMAdma_ops, so DMA user can control which buffers to push in RX DMA channel?
And it also can be used ineth_ops.free_pkt()callback (see below).Yes, probably, but maybe we can achieve that without adding another call.
I'm looking at this patch set from our HW point of view. In my case, DMA channel can be used with different IPs (not only networking), so it would be really great if DMA user can pass RX buffers in DMA driver - network driver can use
net_rx_packets, other drivers might use own buffers. So hard-codding RX buffers in DMA driver looks like not a good choice.Quoted 23 lines
Quoted 5 lines
Quoted 4 lines
+
+ /* flush cache */
+ flush_dcache_range((ulong)dma_desc,
+ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1));Could you clarify pls, if you do return
dma_descto RX ring here or not?Yes.
Quoted 17 lines
if yes, wouldn't it cause potential problem on Net RX path
ret = eth_get_ops(current)->recv(current, flags, &packet);
^^ (1) here buffer will be received from DMA ( and pushed back to RX ring ?? )flags = 0;
if (ret > 0)net_process_received_packet(packet, ret);
^^ (2) here it will be passed in Net stackif (ret >= 0 && eth_get_ops(current)->free_pkt) eth_get_ops(current)->free_pkt(current, packet, ret);
^^ at this point it should be safe to return buffer in DMA RX ring.if (ret <= 0)
break;
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Can DMA overwrite packet after point (1) while packet is still processed (2)?
I don't think so, because as far as I know u-boot is not processing more than one packet at once, is it?
u-boot can't process more than one packet, but dma does. if buffer returned to DMA and there are some traffic on the line - DMA can potentially refill all buffers in its RX ring while u-boot still processing one packet.
I just sent a new version of the patches which doesn't use net_rx_packets in bcm6348-iudma.
However, after several tests it turns out that dma received buffers must be processed as soon as possible in order to avoid flow control issues. Considering that, releasing the buffer by using free_pkt after the packet is processed isn't a valid option, since it makes ethernet unusable. That's why I decided to allocate a dynamic buffer on bcm6348-iudma, saving the received packets on net_rx_packets and immediately returning the dma descriptor to the RX ring.
However, you can still add dma_receive_prepare to dma ops if you need it for your HW.
Quoted 7 lines
Quoted 6 lines
But yeah, I see your point and if it does process more than one packet at once this is not the proper way to do that.
I will usefree_pktin next version and lock the packet until it's processed.
Regards,
Álvaro.
RFC v3 4/15 bmips: bcm6338: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas---
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6338.dtsi | 14 ++++++++++++++ include/dt-bindings/dma/bcm6338-dma.h | 15 +++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6338-dma.h
arch/mips/dts/brcm,bcm6338.dtsi +14 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6338-clock.h> +#include <dt-bindings/dma/bcm6338-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6338-reset.h> #include "skeleton.dtsi"
@@ -131,5 +132,18 @@ reg = <0xfffe3100 0x38>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller at fffe2400 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe2400 0x1c>, + <0xfffe2500 0x60>, + <0xfffe2600 0x60>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <6>; + resets = <&periph_rst BCM6338_RST_DMAMEM>; + }; }; };
include/dt-bindings/dma/bcm6338-dma.h new file +15 -0
@@ -0,0 +1,15 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6338_H +#define __DT_BINDINGS_DMA_BCM6338_H + +#define BCM6338_DMA_ENET_RX 0 +#define BCM6338_DMA_ENET_TX 1 + +#endif /* __DT_BINDINGS_DMA_BCM6338_H */
Signature · 1 line
2.11.0
RFC v3 5/15 bmips: bcm6348: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas---
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6348.dtsi | 16 ++++++++++++++++ include/dt-bindings/dma/bcm6348-dma.h | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6348-dma.h
arch/mips/dts/brcm,bcm6348.dtsi +16 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6348-clock.h> +#include <dt-bindings/dma/bcm6348-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6348-reset.h> #include "skeleton.dtsi"
@@ -160,5 +161,20 @@ reg = <0xfffe2300 0x38>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller at fffe7000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe7000 0x1c>, + <0xfffe7100 0x40>, + <0xfffe7200 0x40>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <4>; + clocks = <&periph_clk BCM6348_CLK_ENET>; + resets = <&periph_rst BCM6348_RST_ENET>, + <&periph_rst BCM6348_RST_DMAMEM>; + }; }; };
include/dt-bindings/dma/bcm6348-dma.h new file +17 -0
@@ -0,0 +1,17 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6348_H +#define __DT_BINDINGS_DMA_BCM6348_H + +#define BCM6348_DMA_ENET0_RX 0 +#define BCM6348_DMA_ENET0_TX 1 +#define BCM6348_DMA_ENET1_RX 2 +#define BCM6348_DMA_ENET1_TX 3 + +#endif /* __DT_BINDINGS_DMA_BCM6348_H */
Signature · 1 line
2.11.0
RFC v3 6/15 bmips: bcm6358: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas---
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6358.dtsi | 18 ++++++++++++++++++ include/dt-bindings/dma/bcm6358-dma.h | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6358-dma.h
arch/mips/dts/brcm,bcm6358.dtsi +18 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6358-clock.h> +#include <dt-bindings/dma/bcm6358-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6358-reset.h> #include "skeleton.dtsi"
@@ -191,5 +192,22 @@ status = "disabled"; }; + + iudma: dma-controller at fffe5000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe5000 0x24>, + <0xfffe5100 0x80>, + <0xfffe5200 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + clocks = <&periph_clk BCM6358_CLK_EMUSB>, + <&periph_clk BCM6358_CLK_USBSU>, + <&periph_clk BCM6358_CLK_EPHY>; + resets = <&periph_rst BCM6358_RST_ENET>, + <&periph_rst BCM6358_RST_EPHY>; + }; }; };
include/dt-bindings/dma/bcm6358-dma.h new file +17 -0
@@ -0,0 +1,17 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6358_H +#define __DT_BINDINGS_DMA_BCM6358_H + +#define BCM6358_DMA_ENET0_RX 0 +#define BCM6358_DMA_ENET0_TX 1 +#define BCM6358_DMA_ENET1_RX 2 +#define BCM6358_DMA_ENET1_TX 3 + +#endif /* __DT_BINDINGS_DMA_BCM6358_H */
Signature · 1 line
2.11.0
RFC v3 7/15 phy: add support for internal phys
In reply to Álvaro Fernández Rojas---
v3: no changes
v2: no changes
include/phy.h | 2 ++ 1 file changed, 2 insertions(+)
include/phy.h +2 -0
@@ -50,6 +50,7 @@ typedef enum { + PHY_INTERFACE_MODE_INTERNAL, PHY_INTERFACE_MODE_MII, PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_SGMII,
@@ -72,6 +73,7 @@ typedef enum { } phy_interface_t;static const char *phy_interface_strings[] = { + [PHY_INTERFACE_MODE_INTERNAL ] ="internal" , [PHY_INTERFACE_MODE_MII ] ="mii" , [PHY_INTERFACE_MODE_GMII ] ="gmii" , [PHY_INTERFACE_MODE_SGMII ] ="sgmii" ,
Signature · 1 line
2.11.0
RFC v3 8/15 net: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v3: no changes
v2: select DMA_CHANNELS.
drivers/net/Kconfig | 10 + drivers/net/Makefile | 1 + drivers/net/bcm6348-eth.c | 517 +++++++++++++++++++++++++++++++++++++++++ include/configs/bmips_common.h | 5 +- 4 files changed, 532 insertions(+), 1 deletion(-) create mode 100644 drivers/net/bcm6348-eth.c
drivers/net/Kconfig +10 -0
@@ -71,6 +71,16 @@ config BCM_SF2_ETH_GMAC by the BCM_SF2_ETH driver. Say Y to any bcmcygnus based platforms. +config BCM6348_ETH + bool "BCM6348 EMAC support" + depends on DM_ETH && ARCH_BMIPS + select DMA + select DMA_CHANNELS + select MII + select PHYLIB + help + This driver supports the BCM6348 Ethernet MAC. + config DWC_ETH_QOS bool "Synopsys DWC Ethernet QOS device support" depends on DM_ETH
drivers/net/Makefile +1 -0
@@ -8,6 +8,7 @@ obj-$(CONFIG_ALTERA_TSE) += altera_tse.o obj-$(CONFIG_AG7XXX) += ag7xxx.o obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o +obj-$(CONFIG_BCM6348_ETH) += bcm6348-eth.o obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o obj-$(CONFIG_DRIVER_AX88180) += ax88180.o obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
drivers/net/bcm6348-eth.c new file +517 -0
517 lines not on this page · raw message
include/configs/bmips_common.h +4 -1
@@ -7,6 +7,9 @@#ifndef __CONFIG_BMIPS_COMMON_H#define __CONFIG_BMIPS_COMMON_H +/* ETH */ +#define CONFIG_PHY_RESET_DELAY 20 +/* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ 230400, 500000, 1500000 }
@@ -17,7 +20,7 @@/* Memory usage */ #define CONFIG_SYS_MAXARGS 24 -#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) +#define CONFIG_SYS_MALLOC_LEN (2 * 1024 * 1024)#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)#define CONFIG_SYS_CBSIZE 512
Signature · 1 line
2.11.0
RFC v3 9/15 bmips: bcm6338: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6338.dtsi | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
arch/mips/dts/brcm,bcm6338.dtsi +15 -0
@@ -145,5 +145,20 @@ dma-channels = <6>; resets = <&periph_rst BCM6338_RST_DMAMEM>; }; + + enet: ethernet at fffe2800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe2800 0x2dc>; + clocks = <&periph_clk BCM6338_CLK_ENET>; + resets = <&periph_rst BCM6338_RST_ENET>; + dmas = <&iudma BCM6338_DMA_ENET_RX>, + <&iudma BCM6338_DMA_ENET_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; }; };
Signature · 1 line
2.11.0
RFC v3 10/15 bmips: enable f@st1704 enet support
In reply to Álvaro Fernández Rojas---
v3: no changes
v2: no changes
arch/mips/dts/sagem,f at st1704.dts | 12 ++++++++++++ configs/sagem_f at st1704_ram_defconfig | 9 ++++++++- 2 files changed, 20 insertions(+), 1 deletion(-)
arch/mips/dts/sagem,f at st1704.dts +12 -0
@@ -40,6 +40,18 @@ }; }; +&enet { + status = "okay"; + phy = <&enetphy>; + phy-mode = "mii"; + + enetphy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio { status = "okay"; };
configs/sagem_f at st1704_ram_defconfig +8 -1
@@ -28,11 +28,15 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_SF=y CONFIG_CMD_SPI=y -# CONFIG_CMD_NET is not set +CONFIG_CMD_DHCP=y # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -41,6 +45,9 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_DM_RESET=y CONFIG_RESET_BCM6345=y # CONFIG_SPL_SERIAL_PRESENT is not set
Signature · 1 line
2.11.0
RFC v3 11/15 bmips: bcm6348: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6348.dtsi | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
arch/mips/dts/brcm,bcm6348.dtsi +26 -0
@@ -162,6 +162,32 @@ u-boot,dm-pre-reloc; }; + enet0: ethernet at fffe6000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6000 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET0_RX>, + <&iudma BCM6348_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet at fffe6800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6800 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET1_RX>, + <&iudma BCM6348_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + iudma: dma-controller at fffe7000 { compatible = "brcm,bcm6348-iudma"; reg = <0xfffe7000 0x1c>,
Signature · 1 line
2.11.0
RFC v3 12/15 bmips: enable ct-5361 enet support
In reply to Álvaro Fernández Rojas---
v3: no changes
v2: no changes
arch/mips/dts/comtrend,ct-5361.dts | 12 ++++++++++++ configs/comtrend_ct5361_ram_defconfig | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
arch/mips/dts/comtrend,ct-5361.dts +12 -0
@@ -35,6 +35,18 @@ }; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/comtrend_ct5361_ram_defconfig +7 -1
@@ -26,11 +26,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -38,6 +41,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6348_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
RFC v3 13/15 bmips: bcm6358: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6358.dtsi | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
arch/mips/dts/brcm,bcm6358.dtsi +28 -0
@@ -193,6 +193,34 @@ status = "disabled"; }; + enet0: ethernet at fffe4000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4000 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET0>; + dmas = <&iudma BCM6358_DMA_ENET0_RX>, + <&iudma BCM6358_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet at fffe4800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4800 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET1>; + dmas = <&iudma BCM6358_DMA_ENET1_RX>, + <&iudma BCM6358_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + iudma: dma-controller at fffe5000 { compatible = "brcm,bcm6348-iudma"; reg = <0xfffe5000 0x24>,
Signature · 1 line
2.11.0
RFC v3 14/15 bmips: enable hg556a enet support
In reply to Álvaro Fernández Rojas---
v3: no changes
v2: no changes
arch/mips/dts/huawei,hg556a.dts | 12 ++++++++++++ configs/huawei_hg556a_ram_defconfig | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
arch/mips/dts/huawei,hg556a.dts +12 -0
@@ -94,6 +94,18 @@ status = "okay"; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/huawei_hg556a_ram_defconfig +7 -1
@@ -26,11 +26,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -38,6 +41,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6358_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
RFC v3 15/15 bmips: enable nb4-ser enet support
In reply to Álvaro Fernández Rojas---
v3: no changes
v2: no changes
arch/mips/dts/sfr,nb4-ser.dts | 24 ++++++++++++++++++++++++ configs/sfr_nb4-ser_ram_defconfig | 8 +++++++- 2 files changed, 31 insertions(+), 1 deletion(-)
arch/mips/dts/sfr,nb4-ser.dts +24 -0
@@ -54,6 +54,30 @@ status = "okay"; }; +&enet0 { + status = "okay"; + phy = <&enet0phy>; + phy-mode = "internal"; + + enet0phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/sfr_nb4-ser_ram_defconfig +7 -1
@@ -27,11 +27,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -40,6 +43,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6358_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
v4 cover bmips: add bcm6348-enet support
In reply to Álvaro Fernández RojasIn order to add bcm6348-enet support, dma-uclass must be extended to support dma channels and reworked to operate like the other dm uclass (clk, reset...).
This is a RFC, so please give you feedback on the things that I should fix or rework.
v4: Fix issues reported by Grygorii Strashko and other fixes:
- Remove usage of net_rx_packets as buffer from bcm6348-iudma.
- Allocate dynamic rx buffer on bcm6348-iudma.
- Copy received dma buffer to net_rx_packets in order to avoid possible dma overwrites.
- Check dma errors and discard invalid packets.
- Reset dma rx channel when sending a new packet to prevent flow control issues.
- Fix packet casting on bcm6348_eth_recv/send.
v3: Introduce changes reported by Simon Glass:
- Improve dma-uclass.h documentation.
- Switch to live tree API.
v2: Introduce changes reported by Vignesh:
- Respect current dma implementation.
- Let dma_memcpy find a compatible dma device.
Other changes:
- Fix bcm6348-iudma rx burst config.
Álvaro Fernández Rojas (15):
dma: move dma_ops to dma-uclass.h
dma: add channels support
dma: add bcm6348-iudma support
bmips: bcm6338: add bcm6348-iudma support
bmips: bcm6348: add bcm6348-iudma support
bmips: bcm6358: add bcm6348-iudma support
phy: add support for internal phys
net: add support for bcm6348-enet
bmips: bcm6338: add support for bcm6348-enet
bmips: enable f at st1704 enet support
bmips: bcm6348: add support for bcm6348-enet
bmips: enable ct-5361 enet support
bmips: bcm6358: add support for bcm6348-enet
bmips: enable hg556a enet support
bmips: enable nb4-ser enet support
arch/mips/dts/brcm,bcm6338.dtsi | 29 ++ arch/mips/dts/brcm,bcm6348.dtsi | 42 +++ arch/mips/dts/brcm,bcm6358.dtsi | 46 +++ arch/mips/dts/comtrend,ct-5361.dts | 12 + arch/mips/dts/huawei,hg556a.dts | 12 + arch/mips/dts/sagem,f at st1704.dts | 12 + arch/mips/dts/sfr,nb4-ser.dts | 24 ++ configs/comtrend_ct5361_ram_defconfig | 8 +- configs/huawei_hg556a_ram_defconfig | 8 +- configs/sagem_f at st1704_ram_defconfig | 9 +- configs/sfr_nb4-ser_ram_defconfig | 8 +- drivers/dma/Kconfig | 16 + drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 545 ++++++++++++++++++++++++++++++++++ drivers/dma/dma-uclass.c | 191 +++++++++++- drivers/net/Kconfig | 10 + drivers/net/Makefile | 1 + drivers/net/bcm6348-eth.c | 530 +++++++++++++++++++++++++++++++++ include/configs/bmips_common.h | 5 +- include/dma-uclass.h | 117 ++++++++ include/dma.h | 196 ++++++++++-- include/dt-bindings/dma/bcm6338-dma.h | 15 + include/dt-bindings/dma/bcm6348-dma.h | 17 ++ include/dt-bindings/dma/bcm6358-dma.h | 17 ++ include/phy.h | 2 + 25 files changed, 1837 insertions(+), 36 deletions(-) create mode 100644 drivers/dma/bcm6348-iudma.c create mode 100644 drivers/net/bcm6348-eth.c create mode 100644 include/dma-uclass.h create mode 100644 include/dt-bindings/dma/bcm6338-dma.h create mode 100644 include/dt-bindings/dma/bcm6348-dma.h create mode 100644 include/dt-bindings/dma/bcm6358-dma.h
Signature · 1 line
2.11.0
RFC v4 1/15 dma: move dma_ops to dma-uclass.h
Move dma_ops to a separate header file, following other uclass implementations. While doing so, this patch also improves dma_ops documentation.
---
v4: no changes
v3: Introduce changes reported by Simon Glass:
- Improve dma-uclass.h documentation.
- Switch to live tree API.
drivers/dma/dma-uclass.c | 3 ++- include/dma-uclass.h | 39 +++++++++++++++++++++++++++++++++++++++ include/dma.h | 22 ---------------------- 3 files changed, 41 insertions(+), 23 deletions(-) create mode 100644 include/dma-uclass.h
drivers/dma/dma-uclass.c +2 -1
@@ -10,10 +10,11 @@*/ #include <common.h> -#include <dma.h> #include <dm.h> #include <dm/uclass-internal.h> #include <dm/device-internal.h> +#include <dma.h> +#include <dma-uclass.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ;
include/dma-uclass.h new file +39 -0
@@ -0,0 +1,39 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com> +* Written by Mugunthan V N <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _DMA_UCLASS_H +#define _DMA_UCLASS_H + +/* See dma.h for background documentation. */ + +#include <dma.h> + +/* +* struct dma_ops - Driver model DMA operations +* +* The uclass interface is implemented by all DMA devices which use +* driver model. +*/ +struct dma_ops { +/** +* transfer() - Issue a DMA transfer. The implementation must +* wait until the transfer is done. +* +* @dev: The DMA device +* @direction: direction of data transfer (should be one from +* enum dma_direction) +* @dst: The destination pointer. +* @src: The source pointer. +* @len: Length of the data to be copied (number of bytes). +* @return zero on success, or -ve error code. +*/ +int (*transfer)(struct udevice *dev,int direction,void *dst, +void *src,size_t len); +}; + +#endif /* _DMA_UCLASS_H */
include/dma.h +0 -22
@@ -28,28 +28,6 @@ enum dma_direction {#define DMA_SUPPORTS_DEV_TO_DEV BIT(3)/* -* struct dma_ops - Driver model DMA operations -* -* The uclass interface is implemented by all DMA devices which use -* driver model. -*/ -struct dma_ops { -/* -* Get the current timer count -* -* @dev: The DMA device -* @direction: direction of data transfer should be one from -enum dma_direction -* @dst: Destination pointer -* @src: Source pointer -* @len: Length of the data to be copied. -* @return: 0 if OK, -ve on error -*/ -int (*transfer)(struct udevice *dev,int direction,void *dst, -void *src,size_t len); -}; - -/* * struct dma_dev_priv - information about a device used by the uclass * * @supported: mode of transfers that DMA can support, should be
Signature · 1 line
2.11.0
RFC v4 1/15 dma: move dma_ops to dma-uclass.h
Hi
Quoted 11 lines · Álvaro Fernández Rojas
Move
dma_opsto a separate header file, following other uclass implementations. While doing so, this patch also improvesdma_opsdocumentation.Signed-off-by Álvaro Fernández Rojas <[email protected]>Reviewed-by Simon Glass <[email protected]>---
v4: no changes
v3: Introduce changes reported by Simon Glass:
- Improvedma-uclass.hdocumentation.
- Switch to live tree API.
Quoted 6 lines
drivers/dma/dma-uclass.c | 3 ++- include/dma-uclass.h | 39 +++++++++++++++++++++++++++++++++++++++ include/dma.h | 22 ---------------------- 3 files changed, 41 insertions(+), 23 deletions(-)create mode 100644
include/dma-uclass.h
I've sent the same comment for prev patch version also.
this patch will break build of existing DMA drivers, as the do not have #include <dma-uclass.h>.
drivers/dma/ti-edma3.c:563:21: error: variable 'ti_edma3_ops' has initializer but incomplete type
static const struct dma_ops ti_edma3_ops = {
^~~~~~~drivers/dma/ti-edma3.c:564:2: error: unknown field 'transfer' specified in initializer
.transfer = ti_edma3_transfer,
^drivers/dma/ti-edma3.c:564:14: warning: excess elements in struct initializer
.transfer = ti_edma3_transfer,
^~~~~~~~~~~~~~~~~
drivers/dma/ti-edma3.c:564:14: note: (near initialization for 'ti_edma3_ops')
drivers/dma/ti-edma3.c:563:29: error: storage size of 'ti_edma3_ops' isn't known
static const struct dma_ops ti_edma3_ops = {
^~~~~~~~~~~~make[1]: *** [drivers/dma/ti-edma3.o] Error 1
Signature · 2 lines
regards, -grygorii
RFC v4 2/15 dma: add channels support
In reply to Álvaro Fernández RojasThis adds channels support for dma controllers that have multiple channels which can transfer data to/from different devices (enet, usb...).
---
v4: no changes
v3: Introduce changes reported by Simon Glass:
- Improve dma-uclass.h documentation.
- Switch to live tree API.
drivers/dma/Kconfig | 7 ++ drivers/dma/dma-uclass.c | 188 +++++++++++++++++++++++++++++++++++++++++++++-- include/dma-uclass.h | 78 ++++++++++++++++++++ include/dma.h | 174 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 439 insertions(+), 8 deletions(-)
drivers/dma/Kconfig +7 -0
@@ -12,6 +12,13 @@ config DMA buses that is used to transfer data to and from memory. The uclass interface is defined in include/dma.h. +config DMA_CHANNELS + bool "Enable DMA channels support" + depends on DMA + help + Enable channels support for DMA. Some DMA controllers have multiple + channels which can either transfer data to/from different devices. + config TI_EDMA3 bool "TI EDMA3 driver" help
drivers/dma/dma-uclass.c +182 -6
206 lines not on this page · raw message
include/dma-uclass.h +78 -0
90 lines not on this page · raw message
include/dma.h +172 -2
190 lines not on this page · raw message
Signature · 1 line
2.11.0
RFC v4 3/15 dma: add bcm6348-iudma support
In reply to Álvaro Fernández RojasBCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
---
v4: Fix issues reported by Grygorii Strashko and other fixes:
- Remove usage of net_rx_packets as buffer.
- Allocate dynamic rx buffer.
- Check dma errors and discard invalid packets.
v3: no changes
v2: Fix dma rx burst config and select DMA_CHANNELS.
drivers/dma/Kconfig | 9 + drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 545 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 555 insertions(+) create mode 100644 drivers/dma/bcm6348-iudma.c
drivers/dma/Kconfig +9 -0
@@ -19,6 +19,15 @@ config DMA_CHANNELS Enable channels support for DMA. Some DMA controllers have multiple channels which can either transfer data to/from different devices. +config BCM6348_IUDMA + bool "BCM6348 IUDMA driver" + depends on ARCH_BMIPS + select DMA_CHANNELS + help + Enable the BCM6348 IUDMA driver. + This driver support data transfer from devices to + memory and from memory to devices. + config TI_EDMA3 bool "TI EDMA3 driver" help
drivers/dma/Makefile +1 -0
@@ -9,6 +9,7 @@ obj-$(CONFIG_DMA) += dma-uclass.o obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o obj-$(CONFIG_APBH_DMA) += apbh_dma.o +obj-$(CONFIG_BCM6348_IUDMA) += bcm6348-iudma.o obj-$(CONFIG_FSL_DMA) += fsl_dma.o obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o obj-$(CONFIG_TI_EDMA3) += ti-edma3.o
drivers/dma/bcm6348-iudma.c new file +545 -0
545 lines not on this page · raw message
Signature · 1 line
2.11.0
RFC v4 4/15 bmips: bcm6338: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas---
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6338.dtsi | 14 ++++++++++++++ include/dt-bindings/dma/bcm6338-dma.h | 15 +++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6338-dma.h
arch/mips/dts/brcm,bcm6338.dtsi +14 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6338-clock.h> +#include <dt-bindings/dma/bcm6338-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6338-reset.h> #include "skeleton.dtsi"
@@ -131,5 +132,18 @@ reg = <0xfffe3100 0x38>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller at fffe2400 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe2400 0x1c>, + <0xfffe2500 0x60>, + <0xfffe2600 0x60>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <6>; + resets = <&periph_rst BCM6338_RST_DMAMEM>; + }; }; };
include/dt-bindings/dma/bcm6338-dma.h new file +15 -0
@@ -0,0 +1,15 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6338_H +#define __DT_BINDINGS_DMA_BCM6338_H + +#define BCM6338_DMA_ENET_RX 0 +#define BCM6338_DMA_ENET_TX 1 + +#endif /* __DT_BINDINGS_DMA_BCM6338_H */
Signature · 1 line
2.11.0
RFC v4 5/15 bmips: bcm6348: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas---
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6348.dtsi | 16 ++++++++++++++++ include/dt-bindings/dma/bcm6348-dma.h | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6348-dma.h
arch/mips/dts/brcm,bcm6348.dtsi +16 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6348-clock.h> +#include <dt-bindings/dma/bcm6348-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6348-reset.h> #include "skeleton.dtsi"
@@ -160,5 +161,20 @@ reg = <0xfffe2300 0x38>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller at fffe7000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe7000 0x1c>, + <0xfffe7100 0x40>, + <0xfffe7200 0x40>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <4>; + clocks = <&periph_clk BCM6348_CLK_ENET>; + resets = <&periph_rst BCM6348_RST_ENET>, + <&periph_rst BCM6348_RST_DMAMEM>; + }; }; };
include/dt-bindings/dma/bcm6348-dma.h new file +17 -0
@@ -0,0 +1,17 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6348_H +#define __DT_BINDINGS_DMA_BCM6348_H + +#define BCM6348_DMA_ENET0_RX 0 +#define BCM6348_DMA_ENET0_TX 1 +#define BCM6348_DMA_ENET1_RX 2 +#define BCM6348_DMA_ENET1_TX 3 + +#endif /* __DT_BINDINGS_DMA_BCM6348_H */
Signature · 1 line
2.11.0
RFC v4 6/15 bmips: bcm6358: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas---
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6358.dtsi | 18 ++++++++++++++++++ include/dt-bindings/dma/bcm6358-dma.h | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6358-dma.h
arch/mips/dts/brcm,bcm6358.dtsi +18 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6358-clock.h> +#include <dt-bindings/dma/bcm6358-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6358-reset.h> #include "skeleton.dtsi"
@@ -191,5 +192,22 @@ status = "disabled"; }; + + iudma: dma-controller at fffe5000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe5000 0x24>, + <0xfffe5100 0x80>, + <0xfffe5200 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + clocks = <&periph_clk BCM6358_CLK_EMUSB>, + <&periph_clk BCM6358_CLK_USBSU>, + <&periph_clk BCM6358_CLK_EPHY>; + resets = <&periph_rst BCM6358_RST_ENET>, + <&periph_rst BCM6358_RST_EPHY>; + }; }; };
include/dt-bindings/dma/bcm6358-dma.h new file +17 -0
@@ -0,0 +1,17 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6358_H +#define __DT_BINDINGS_DMA_BCM6358_H + +#define BCM6358_DMA_ENET0_RX 0 +#define BCM6358_DMA_ENET0_TX 1 +#define BCM6358_DMA_ENET1_RX 2 +#define BCM6358_DMA_ENET1_TX 3 + +#endif /* __DT_BINDINGS_DMA_BCM6358_H */
Signature · 1 line
2.11.0
RFC v4 7/15 phy: add support for internal phys
In reply to Álvaro Fernández Rojas---
v4: no changes
v3: no changes
v2: no changes
include/phy.h | 2 ++ 1 file changed, 2 insertions(+)
include/phy.h +2 -0
@@ -50,6 +50,7 @@ typedef enum { + PHY_INTERFACE_MODE_INTERNAL, PHY_INTERFACE_MODE_MII, PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_SGMII,
@@ -72,6 +73,7 @@ typedef enum { } phy_interface_t;static const char *phy_interface_strings[] = { + [PHY_INTERFACE_MODE_INTERNAL ] ="internal" , [PHY_INTERFACE_MODE_MII ] ="mii" , [PHY_INTERFACE_MODE_GMII ] ="gmii" , [PHY_INTERFACE_MODE_SGMII ] ="sgmii" ,
Signature · 1 line
2.11.0
RFC v4 8/15 net: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v4: Fix issues reported by Grygorii Strashko and other fixes:
- Copy received dma buffer to net_rx_packets in order to avoid possible dma overwrites.
- Reset dma rx channel when sending a new packet to prevent flow control issues.
- Fix packet casting on bcm6348_eth_recv/send.
v3: no changes
v2: select DMA_CHANNELS.
drivers/net/Kconfig | 10 + drivers/net/Makefile | 1 + drivers/net/bcm6348-eth.c | 530 +++++++++++++++++++++++++++++++++++++++++ include/configs/bmips_common.h | 5 +- 4 files changed, 545 insertions(+), 1 deletion(-) create mode 100644 drivers/net/bcm6348-eth.c
drivers/net/Kconfig +10 -0
@@ -71,6 +71,16 @@ config BCM_SF2_ETH_GMAC by the BCM_SF2_ETH driver. Say Y to any bcmcygnus based platforms. +config BCM6348_ETH + bool "BCM6348 EMAC support" + depends on DM_ETH && ARCH_BMIPS + select DMA + select DMA_CHANNELS + select MII + select PHYLIB + help + This driver supports the BCM6348 Ethernet MAC. + config DWC_ETH_QOS bool "Synopsys DWC Ethernet QOS device support" depends on DM_ETH
drivers/net/Makefile +1 -0
@@ -8,6 +8,7 @@ obj-$(CONFIG_ALTERA_TSE) += altera_tse.o obj-$(CONFIG_AG7XXX) += ag7xxx.o obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o +obj-$(CONFIG_BCM6348_ETH) += bcm6348-eth.o obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o obj-$(CONFIG_DRIVER_AX88180) += ax88180.o obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
drivers/net/bcm6348-eth.c new file +530 -0
530 lines not on this page · raw message
include/configs/bmips_common.h +4 -1
@@ -7,6 +7,9 @@#ifndef __CONFIG_BMIPS_COMMON_H#define __CONFIG_BMIPS_COMMON_H +/* ETH */ +#define CONFIG_PHY_RESET_DELAY 20 +/* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ 230400, 500000, 1500000 }
@@ -17,7 +20,7 @@/* Memory usage */ #define CONFIG_SYS_MAXARGS 24 -#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) +#define CONFIG_SYS_MALLOC_LEN (2 * 1024 * 1024)#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)#define CONFIG_SYS_CBSIZE 512
Signature · 1 line
2.11.0
RFC v4 9/15 bmips: bcm6338: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6338.dtsi | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
arch/mips/dts/brcm,bcm6338.dtsi +15 -0
@@ -145,5 +145,20 @@ dma-channels = <6>; resets = <&periph_rst BCM6338_RST_DMAMEM>; }; + + enet: ethernet at fffe2800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe2800 0x2dc>; + clocks = <&periph_clk BCM6338_CLK_ENET>; + resets = <&periph_rst BCM6338_RST_ENET>; + dmas = <&iudma BCM6338_DMA_ENET_RX>, + <&iudma BCM6338_DMA_ENET_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; }; };
Signature · 1 line
2.11.0
RFC v4 10/15 bmips: enable f@st1704 enet support
In reply to Álvaro Fernández Rojas---
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/sagem,f at st1704.dts | 12 ++++++++++++ configs/sagem_f at st1704_ram_defconfig | 9 ++++++++- 2 files changed, 20 insertions(+), 1 deletion(-)
arch/mips/dts/sagem,f at st1704.dts +12 -0
@@ -40,6 +40,18 @@ }; }; +&enet { + status = "okay"; + phy = <&enetphy>; + phy-mode = "mii"; + + enetphy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio { status = "okay"; };
configs/sagem_f at st1704_ram_defconfig +8 -1
@@ -28,11 +28,15 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_SF=y CONFIG_CMD_SPI=y -# CONFIG_CMD_NET is not set +CONFIG_CMD_DHCP=y # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -41,6 +45,9 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_DM_RESET=y CONFIG_RESET_BCM6345=y # CONFIG_SPL_SERIAL_PRESENT is not set
Signature · 1 line
2.11.0
RFC v4 11/15 bmips: bcm6348: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6348.dtsi | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
arch/mips/dts/brcm,bcm6348.dtsi +26 -0
@@ -162,6 +162,32 @@ u-boot,dm-pre-reloc; }; + enet0: ethernet at fffe6000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6000 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET0_RX>, + <&iudma BCM6348_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet at fffe6800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6800 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET1_RX>, + <&iudma BCM6348_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + iudma: dma-controller at fffe7000 { compatible = "brcm,bcm6348-iudma"; reg = <0xfffe7000 0x1c>,
Signature · 1 line
2.11.0
RFC v4 12/15 bmips: enable ct-5361 enet support
In reply to Álvaro Fernández Rojas---
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/comtrend,ct-5361.dts | 12 ++++++++++++ configs/comtrend_ct5361_ram_defconfig | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
arch/mips/dts/comtrend,ct-5361.dts +12 -0
@@ -35,6 +35,18 @@ }; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/comtrend_ct5361_ram_defconfig +7 -1
@@ -26,11 +26,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -38,6 +41,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6348_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
RFC v4 13/15 bmips: bcm6358: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6358.dtsi | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
arch/mips/dts/brcm,bcm6358.dtsi +28 -0
@@ -193,6 +193,34 @@ status = "disabled"; }; + enet0: ethernet at fffe4000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4000 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET0>; + dmas = <&iudma BCM6358_DMA_ENET0_RX>, + <&iudma BCM6358_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet at fffe4800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4800 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET1>; + dmas = <&iudma BCM6358_DMA_ENET1_RX>, + <&iudma BCM6358_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + iudma: dma-controller at fffe5000 { compatible = "brcm,bcm6348-iudma"; reg = <0xfffe5000 0x24>,
Signature · 1 line
2.11.0
RFC v4 14/15 bmips: enable hg556a enet support
In reply to Álvaro Fernández Rojas---
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/huawei,hg556a.dts | 12 ++++++++++++ configs/huawei_hg556a_ram_defconfig | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
arch/mips/dts/huawei,hg556a.dts +12 -0
@@ -94,6 +94,18 @@ status = "okay"; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/huawei_hg556a_ram_defconfig +7 -1
@@ -26,11 +26,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -38,6 +41,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6358_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
RFC v4 15/15 bmips: enable nb4-ser enet support
In reply to Álvaro Fernández Rojas---
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/sfr,nb4-ser.dts | 24 ++++++++++++++++++++++++ configs/sfr_nb4-ser_ram_defconfig | 8 +++++++- 2 files changed, 31 insertions(+), 1 deletion(-)
arch/mips/dts/sfr,nb4-ser.dts +24 -0
@@ -54,6 +54,30 @@ status = "okay"; }; +&enet0 { + status = "okay"; + phy = <&enet0phy>; + phy-mode = "internal"; + + enet0phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/sfr_nb4-ser_ram_defconfig +7 -1
@@ -27,11 +27,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -40,6 +43,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6358_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
v5 cover bmips: add bcm6348-enet support
In reply to Álvaro Fernández RojasIn order to add bcm6348-enet support, dma-uclass must be extended to support dma channels and reworked to operate like the other dm uclass (clk, reset...).
v5: Fix issues reported by Grygorii Strashko and other fixes:
- Fix build of ti-edma3.
- Remove unused bcm6348-iudma defines.
- Increment bcm6348-iudma rx descriptors.
- Fix bcm6348-iudma flow control issues.
- bcm6348-iudma error checking now depends on hw.
- Remove unneeded bcm6348-iudma interrupts.
- Receive as much packets as possible from bcm6348-eth and cache them in net_rx_packets. This is needed in order to fix flow control issues.
v4: Fix issues reported by Grygorii Strashko and other fixes:
- Remove usage of net_rx_packets as buffer from bcm6348-iudma.
- Allocate dynamic rx buffer on bcm6348-iudma.
- Copy received dma buffer to net_rx_packets in order to avoid possible dma overwrites.
- Check dma errors and discard invalid packets.
- Reset dma rx channel when sending a new packet to prevent flow control issues.
- Fix packet casting on bcm6348_eth_recv/send.
v3: Introduce changes reported by Simon Glass:
- Improve dma-uclass.h documentation.
- Switch to live tree API.
v2: Introduce changes reported by Vignesh:
- Respect current dma implementation.
- Let dma_memcpy find a compatible dma device.
Other changes:
- Fix bcm6348-iudma rx burst config.
Álvaro Fernández Rojas (15):
dma: move dma_ops to dma-uclass.h
dma: add channels support
dma: add bcm6348-iudma support
bmips: bcm6338: add bcm6348-iudma support
bmips: bcm6348: add bcm6348-iudma support
bmips: bcm6358: add bcm6348-iudma support
phy: add support for internal phys
net: add support for bcm6348-enet
bmips: bcm6338: add support for bcm6348-enet
bmips: enable f at st1704 enet support
bmips: bcm6348: add support for bcm6348-enet
bmips: enable ct-5361 enet support
bmips: bcm6358: add support for bcm6348-enet
bmips: enable hg556a enet support
bmips: enable nb4-ser enet support
arch/mips/dts/brcm,bcm6338.dtsi | 29 ++ arch/mips/dts/brcm,bcm6348.dtsi | 42 +++ arch/mips/dts/brcm,bcm6358.dtsi | 46 +++ arch/mips/dts/comtrend,ct-5361.dts | 12 + arch/mips/dts/huawei,hg556a.dts | 12 + arch/mips/dts/sagem,f at st1704.dts | 12 + arch/mips/dts/sfr,nb4-ser.dts | 24 ++ configs/comtrend_ct5361_ram_defconfig | 8 +- configs/huawei_hg556a_ram_defconfig | 8 +- configs/sagem_f at st1704_ram_defconfig | 9 +- configs/sfr_nb4-ser_ram_defconfig | 8 +- drivers/dma/Kconfig | 16 + drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 532 +++++++++++++++++++++++++++++++ drivers/dma/dma-uclass.c | 190 ++++++++++- drivers/dma/ti-edma3.c | 2 +- drivers/net/Kconfig | 10 + drivers/net/Makefile | 1 + drivers/net/bcm6348-eth.c | 575 ++++++++++++++++++++++++++++++++++ include/configs/bmips_common.h | 5 +- include/dma-uclass.h | 117 +++++++ include/dma.h | 196 ++++++++++-- include/dt-bindings/dma/bcm6338-dma.h | 15 + include/dt-bindings/dma/bcm6348-dma.h | 17 + include/dt-bindings/dma/bcm6358-dma.h | 17 + include/phy.h | 2 + 26 files changed, 1869 insertions(+), 37 deletions(-) create mode 100644 drivers/dma/bcm6348-iudma.c create mode 100644 drivers/net/bcm6348-eth.c create mode 100644 include/dma-uclass.h create mode 100644 include/dt-bindings/dma/bcm6338-dma.h create mode 100644 include/dt-bindings/dma/bcm6348-dma.h create mode 100644 include/dt-bindings/dma/bcm6358-dma.h
Signature · 1 line
2.11.0
PATCH v5 1/15 dma: move dma_ops to dma-uclass.h
Move dma_ops to a separate header file, following other uclass implementations. While doing so, this patch also improves dma_ops documentation.
---
v5: fix build of ti-edma3 (reported by Grygorii Strashko) and remove unneeded dma.h include
v4: no changes
v3: Introduce changes reported by Simon Glass:
- Improve dma-uclass.h documentation.
- Switch to live tree API.
drivers/dma/dma-uclass.c | 2 +- drivers/dma/ti-edma3.c | 2 +- include/dma-uclass.h | 39 +++++++++++++++++++++++++++++++++++++++ include/dma.h | 22 ---------------------- 4 files changed, 41 insertions(+), 24 deletions(-) create mode 100644 include/dma-uclass.h
drivers/dma/dma-uclass.c +1 -1
@@ -10,10 +10,10 @@*/ #include <common.h> -#include <dma.h> #include <dm.h> #include <dm/uclass-internal.h> #include <dm/device-internal.h> +#include <dma-uclass.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ;
drivers/dma/ti-edma3.c +1 -1
@@ -12,7 +12,7 @@#include <asm/io.h> #include <common.h> #include <dm.h> -#include <dma.h> +#include <dma-uclass.h> #include <asm/omap_common.h> #include <asm/ti-common/ti-edma3.h>
include/dma-uclass.h new file +39 -0
@@ -0,0 +1,39 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com> +* Written by Mugunthan V N <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _DMA_UCLASS_H +#define _DMA_UCLASS_H + +/* See dma.h for background documentation. */ + +#include <dma.h> + +/* +* struct dma_ops - Driver model DMA operations +* +* The uclass interface is implemented by all DMA devices which use +* driver model. +*/ +struct dma_ops { +/** +* transfer() - Issue a DMA transfer. The implementation must +* wait until the transfer is done. +* +* @dev: The DMA device +* @direction: direction of data transfer (should be one from +* enum dma_direction) +* @dst: The destination pointer. +* @src: The source pointer. +* @len: Length of the data to be copied (number of bytes). +* @return zero on success, or -ve error code. +*/ +int (*transfer)(struct udevice *dev,int direction,void *dst, +void *src,size_t len); +}; + +#endif /* _DMA_UCLASS_H */
include/dma.h +0 -22
@@ -28,28 +28,6 @@ enum dma_direction {#define DMA_SUPPORTS_DEV_TO_DEV BIT(3)/* -* struct dma_ops - Driver model DMA operations -* -* The uclass interface is implemented by all DMA devices which use -* driver model. -*/ -struct dma_ops { -/* -* Get the current timer count -* -* @dev: The DMA device -* @direction: direction of data transfer should be one from -enum dma_direction -* @dst: Destination pointer -* @src: Source pointer -* @len: Length of the data to be copied. -* @return: 0 if OK, -ve on error -*/ -int (*transfer)(struct udevice *dev,int direction,void *dst, -void *src,size_t len); -}; - -/* * struct dma_dev_priv - information about a device used by the uclass * * @supported: mode of transfers that DMA can support, should be
Signature · 1 line
2.11.0
PATCH v5 1/15 dma: move dma_ops to dma-uclass.h
Quoted 13 lines · Álvaro Fernández Rojas
Move
dma_opsto a separate header file, following other uclass implementations. While doing so, this patch also improvesdma_opsdocumentation.Signed-off-by Álvaro Fernández Rojas <[email protected]>Reviewed-by Simon Glass <[email protected]>---
v5: fix build of ti-edma3 (reported by Grygorii Strashko) and remove unneededdma.hinclude
v4: no changes
v3: Introduce changes reported by Simon Glass:
- Improvedma-uclass.hdocumentation.
- Switch to live tree API.
Quoted 6 lines
drivers/dma/dma-uclass.c | 2 +- drivers/dma/ti-edma3.c | 2 +- include/dma-uclass.h | 39 +++++++++++++++++++++++++++++++++++++++ include/dma.h | 22 ---------------------- 4 files changed, 41 insertions(+), 24 deletions(-)create mode 100644
include/dma-uclass.h
Signature · 2 lines
regards, -grygorii
PATCH v5 2/15 dma: add channels support
In reply to Álvaro Fernández RojasThis adds channels support for dma controllers that have multiple channels which can transfer data to/from different devices (enet, usb...).
---
v5: remove unneeded dma.h include
v4: no changes
v3: Introduce changes reported by Simon Glass:
- Improve dma-uclass.h documentation.
- Switch to live tree API.
drivers/dma/Kconfig | 7 ++ drivers/dma/dma-uclass.c | 188 +++++++++++++++++++++++++++++++++++++++++++++-- include/dma-uclass.h | 78 ++++++++++++++++++++ include/dma.h | 174 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 439 insertions(+), 8 deletions(-)
drivers/dma/Kconfig +7 -0
@@ -12,6 +12,13 @@ config DMA buses that is used to transfer data to and from memory. The uclass interface is defined in include/dma.h. +config DMA_CHANNELS + bool "Enable DMA channels support" + depends on DMA + help + Enable channels support for DMA. Some DMA controllers have multiple + channels which can either transfer data to/from different devices. + config TI_EDMA3 bool "TI EDMA3 driver" help
drivers/dma/dma-uclass.c +182 -6
205 lines not on this page · raw message
include/dma-uclass.h +78 -0
90 lines not on this page · raw message
include/dma.h +172 -2
190 lines not on this page · raw message
Signature · 1 line
2.11.0
PATCH v5 2/15 dma: add channels support
Quoted 216 lines · Álvaro Fernández Rojas
This adds channels support for dma controllers that have multiple channels which can transfer data to/from different devices (enet, usb...).
Signed-off-by Álvaro Fernández Rojas <[email protected]>Reviewed-by Simon Glass <[email protected]>---
v5: remove unneededdma.hinclude
v4: no changes
v3: Introduce changes reported by Simon Glass:
- Improvedma-uclass.hdocumentation.
- Switch to live tree API.drivers/dma/Kconfig | 7 ++ drivers/dma/dma-uclass.c | 188 +++++++++++++++++++++++++++++++++++++++++++++-- include/dma-uclass.h | 78 ++++++++++++++++++++ include/dma.h | 174 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 439 insertions(+), 8 deletions(-)drivers/dma/Kconfig +7
-0@@ -12,6 +12,13 @@ config DMA buses that is used to transfer data to and from memory. The uclass interface is defined in include/dma.h. +config DMA_CHANNELS + bool "Enable DMA channels support" + depends on DMA + help + Enable channels support for DMA. Some DMA controllers have multiple + channels which can either transfer data to/from different devices. + config TI_EDMA3 bool "TI EDMA3 driver" helpdrivers/dma/dma-uclass.c +155
-6@@ -1,23 +1,199 @@/* * Direct Memory Access U-Class driver * -* (C) Copyright 2015 -* Texas Instruments Incorporated, <www.ti.com> -* -* Author: Mugunthan V N <[email protected]> +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com> +* Written by Mugunthan V N <[email protected]> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> #include <dm.h> -#include <dm/uclass-internal.h> -#include <dm/device-internal.h> +#include <dm/read.h> #include <dma-uclass.h> +#include <dt-structs.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ; +#ifdef CONFIG_DMA_CHANNELS +static inline struct dma_ops *dma_dev_ops (struct udevice *dev) +{ +return (struct dma_ops *)dev->driver->ops; +} + +# if CONFIG_IS_ENABLED (OF_CONTROL ) +# if CONFIG_IS_ENABLED (OF_PLATDATA ) +int dma_get_by_index_platdata (struct udevice *dev,int index, +struct phandle_1_arg *cells,struct dma *dma) +{ +int ret; + +if (index !=0 ) +return -ENOSYS ; + ret =uclass_get_device (UCLASS_DMA ,0 , &dma->dev); +if (ret) +return ret; + dma->id = cells[0 ].id; + +return 0 ; +} +# else +static int dma_of_xlate_default (struct dma *dma, +struct ofnode_phandle_args *args) +{ +debug ("%s(dma=%p)\n" , __func__, dma); + +if (args->args_count >1 ) { +pr_err ("Invaild args_count: %d\n" , args->args_count); +return -EINVAL ; + } + +if (args->args_count) + dma->id = args->args[0 ]; +else + dma->id =0 ; + +return 0 ; +} + +int dma_get_by_index (struct udevice *dev,int index,struct dma *dma) +{ +int ret; +struct ofnode_phandle_args args; +struct udevice *dev_dma; +const struct dma_ops *ops; + +debug ("%s(dev=%p, index=%d, dma=%p)\n" , __func__, dev, index, dma); + +assert (dma); + dma->dev =NULL ; + + ret =dev_read_phandle_with_args (dev,"dmas" ,"#dma-cells" ,0 , index, + &args); +if (ret) { +pr_err ("%s: dev_read_phandle_with_args failed: err=%d\n" , + __func__, ret); +return ret; + } + + ret =uclass_get_device_by_ofnode (UCLASS_DMA , args.node, &dev_dma); +if (ret) { +pr_err ("%s: uclass_get_device_by_ofnode failed: err=%d\n" , + __func__, ret); +return ret; + } + + dma->dev = dev_dma; + + ops =dma_dev_ops (dev_dma); + +if (ops->of_xlate) + ret = ops->of_xlate (dma, &args); +else + ret =dma_of_xlate_default (dma, &args); +if (ret) { +pr_err ("of_xlate() failed: %d\n" , ret); +return ret; + } + +return dma_request (dev_dma, dma); +} +# endif /* OF_PLATDATA */ + +int dma_get_by_name (struct udevice *dev,const char *name,struct dma *dma) +{ +int index; + +debug ("%s(dev=%p, name=%s, dma=%p)\n" , __func__, dev, name, dma); + dma->dev =NULL ; + + index =dev_read_stringlist_search (dev,"dma-names" , name); +if (index <0 ) { +pr_err ("dev_read_stringlist_search() failed: %d\n" , index); +return index; + } + +return dma_get_by_index (dev, index, dma); +} +# endif /* OF_CONTROL */ + +int dma_request (struct udevice *dev,struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dev); + +debug ("%s(dev=%p, dma=%p)\n" , __func__, dev, dma); + + dma->dev = dev; + +if (!ops->request) +return 0 ; + +return ops->request (dma); +} + +int dma_free (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->free) +return 0 ; + +return ops->free (dma); +} + +int dma_enable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->enable) +return -ENOSYS ; + +return ops->enable (dma); +} + +int dma_disable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->disable) +return -ENOSYS ; + +return ops->disable (dma);
drivers/dma/dma-uclass.c line 179
Quoted 10 lines
drivers/dma/dma-uclass.c +10
-0+} + +int dma_receive (struct dma *dma,void **dst) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->receive) +return -1 ;
Isn't there a better error code you could return? Such as -ENOSYS like above?
drivers/dma/dma-uclass.c line 191
Quoted 12 lines
drivers/dma/dma-uclass.c +12
-0+ +return ops->receive (dma, dst); +} + +int dma_send (struct dma *dma,void *src,size_t len) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->send) +return -1 ;
Same here.
Quoted 80 lines
drivers/dma/dma-uclass.c +5
-0+ + return ops->send(dma, src, len); +} +#endif /* CONFIG_DMA_CHANNELS */ +int dma_get_device (u32 transfer_type,struct udevice **devp) {struct udevice *dev;include/dma-uclass.h +57
-0@@ -13,6 +13,8 @@#include <dma.h> +struct ofnode_phandle_args ; +/* * struct dma_ops - Driver model DMA operations * @@ -20,6 +22,82 @@* driver model. */ struct dma_ops { +#ifdef CONFIG_DMA_CHANNELS +/** +* of_xlate - Translate a client's device-tree (OF) DMA specifier. +* +* The DMA core calls this function as the first step in implementing +* a client's dma_get_by_*() call. +* +* If this function pointer is set to NULL, the DMA core will use a +* default implementation, which assumes #dma-cells = <1>, and that +* the DT cell contains a simple integer DMA Channel. +* +* At present, the DMA API solely supports device-tree. If this +* changes, other xxx_xlate() functions may be added to support those +* other mechanisms. +* +* @dma: The dma struct to hold the translation result. +* @args: The dma specifier values from device tree. +* @return 0 if OK, or a negative error code. +*/ +int (*of_xlate)(struct dma *dma, +struct ofnode_phandle_args *args); +/** +* request - Request a translated DMA. +* +* The DMA core calls this function as the second step in +* implementing a client's dma_get_by_*() call, following a successful +* xxx_xlate() call, or as the only step in implementing a client's +* dma_request() call. +* +* @dma: The DMA struct to request; this has been filled in by +* a previoux xxx_xlate() function call, or by the caller of +* dma_request(). +* @return 0 if OK, or a negative error code. +*/ +int (*request)(struct dma *dma); +/** +* free - Free a previously requested dma. +* +* This is the implementation of the client dma_free() API. +* +* @dma: The DMA to free. +* @return 0 if OK, or a negative error code. +*/ +int (*free)(struct dma *dma); +/** +* enable() - Enable a DMA Channel. +* +* @dma: The DMA Channel to manipulate. +* @return zero on success, or -ve error code. +*/ +int (*enable)(struct dma *dma); +/** +* disable() - Disable a DMA Channel. +* +* @dma: The DMA Channel to manipulate.
include/dma-uclass.h line 89
Quoted 10 lines
include/dma-uclass.h +10
-0+* @return zero on success, or -ve error code. +*/ +int (*disable)(struct dma *dma); +/** +* receive() - Receive a DMA transfer. +* +* @dma: The DMA Channel to manipulate. +* @dst: The destination pointer. +* @return zero on success, or -ve error code. +*/
I haven't seen any implementation of this. Will it return -EAGAIN in the case where the packet isn't available?
Quoted 218 lines
include/dma-uclass.h +11
-0+int (*receive)(struct dma *dma,void **dst); +/** +* send() - Send a DMA transfer. +* +* @dma: The DMA Channel to manipulate. +* @src: The source pointer. +* @len: Length of the data to be sent (number of bytes). +* @return zero on success, or -ve error code. +*/ +int (*send)(struct dma *dma,void *src,size_t len); +#endif /* CONFIG_DMA_CHANNELS */ /** * transfer() - Issue a DMA transfer. The implementation must * wait until the transfer is done. include/dma.h +172
-3@@ -1,6 +1,7 @@/* -* (C) Copyright 2015 -* Texas Instruments Incorporated, <www.ti.com> +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com> +* Written by Mugunthan V N <[email protected]> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -8,6 +9,9 @@#ifndef _DMA_H_#define _DMA_H_ +#include <linux/errno.h> +#include <linux/types.h> +/* * enum dma_direction - dma transfer direction indicator * @DMA_MEM_TO_MEM: Memcpy mode @@ -37,6 +41,172 @@ struct dma_dev_priv {u32 supported; }; +#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. +*/ + +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 ) +struct phandle_1_arg ; +int dma_get_by_index_platdata (struct udevice *dev,int index, +struct phandle_1_arg *cells,struct dma *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_receive() - Receive a DMA transfer. +* +* @dma: A DMA struct that was previously successfully requested by +* dma_request/get_by_*(). +* @dst: The destination pointer. +* @return zero on success, or -ve error code. +*/ +int dma_receive (struct dma *dma,void **dst); + +/** +* 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). +* @return zero on success, or -ve error code. +*/ +int dma_send (struct dma *dma,void *src,size_t len); +#endif /* CONFIG_DMA_CHANNELS */ +/* * dma_get_device - get a DMA device which supports transfer * type of transfer_type -- 2.11.0
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
https://lists.denx.de/listinfo/u-boot
PATCH v5 2/15 dma: add channels support
Hi Joe,
Quoted 221 lines · Joe Hershberger
Quoted 219 lines · Álvaro Fernández Rojas
This adds channels support for dma controllers that have multiple channels which can transfer data to/from different devices (enet, usb...).
Signed-off-by Álvaro Fernández Rojas <[email protected]>Reviewed-by Simon Glass <[email protected]>---
v5: remove unneededdma.hinclude
v4: no changes
v3: Introduce changes reported by Simon Glass:
- Improvedma-uclass.hdocumentation.
- Switch to live tree API.drivers/dma/Kconfig | 7 ++ drivers/dma/dma-uclass.c | 188 +++++++++++++++++++++++++++++++++++++++++++++-- include/dma-uclass.h | 78 ++++++++++++++++++++ include/dma.h | 174 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 439 insertions(+), 8 deletions(-)drivers/dma/Kconfig +7
-0@@ -12,6 +12,13 @@ config DMA buses that is used to transfer data to and from memory. The uclass interface is defined in include/dma.h. +config DMA_CHANNELS + bool "Enable DMA channels support" + depends on DMA + help + Enable channels support for DMA. Some DMA controllers have multiple + channels which can either transfer data to/from different devices. + config TI_EDMA3 bool "TI EDMA3 driver" helpdrivers/dma/dma-uclass.c +158
-6@@ -1,23 +1,199 @@/* * Direct Memory Access U-Class driver * -* (C) Copyright 2015 -* Texas Instruments Incorporated, <www.ti.com> -* -* Author: Mugunthan V N <[email protected]> +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com> +* Written by Mugunthan V N <[email protected]> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> #include <dm.h> -#include <dm/uclass-internal.h> -#include <dm/device-internal.h> +#include <dm/read.h> #include <dma-uclass.h> +#include <dt-structs.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ; +#ifdef CONFIG_DMA_CHANNELS +static inline struct dma_ops *dma_dev_ops (struct udevice *dev) +{ +return (struct dma_ops *)dev->driver->ops; +} + +# if CONFIG_IS_ENABLED (OF_CONTROL ) +# if CONFIG_IS_ENABLED (OF_PLATDATA ) +int dma_get_by_index_platdata (struct udevice *dev,int index, +struct phandle_1_arg *cells,struct dma *dma) +{ +int ret; + +if (index !=0 ) +return -ENOSYS ; + ret =uclass_get_device (UCLASS_DMA ,0 , &dma->dev); +if (ret) +return ret; + dma->id = cells[0 ].id; + +return 0 ; +} +# else +static int dma_of_xlate_default (struct dma *dma, +struct ofnode_phandle_args *args) +{ +debug ("%s(dma=%p)\n" , __func__, dma); + +if (args->args_count >1 ) { +pr_err ("Invaild args_count: %d\n" , args->args_count); +return -EINVAL ; + } + +if (args->args_count) + dma->id = args->args[0 ]; +else + dma->id =0 ; + +return 0 ; +} + +int dma_get_by_index (struct udevice *dev,int index,struct dma *dma) +{ +int ret; +struct ofnode_phandle_args args; +struct udevice *dev_dma; +const struct dma_ops *ops; + +debug ("%s(dev=%p, index=%d, dma=%p)\n" , __func__, dev, index, dma); + +assert (dma); + dma->dev =NULL ; + + ret =dev_read_phandle_with_args (dev,"dmas" ,"#dma-cells" ,0 , index, + &args); +if (ret) { +pr_err ("%s: dev_read_phandle_with_args failed: err=%d\n" , + __func__, ret); +return ret; + } + + ret =uclass_get_device_by_ofnode (UCLASS_DMA , args.node, &dev_dma); +if (ret) { +pr_err ("%s: uclass_get_device_by_ofnode failed: err=%d\n" , + __func__, ret); +return ret; + } + + dma->dev = dev_dma; + + ops =dma_dev_ops (dev_dma); + +if (ops->of_xlate) + ret = ops->of_xlate (dma, &args); +else + ret =dma_of_xlate_default (dma, &args); +if (ret) { +pr_err ("of_xlate() failed: %d\n" , ret); +return ret; + } + +return dma_request (dev_dma, dma); +} +# endif /* OF_PLATDATA */ + +int dma_get_by_name (struct udevice *dev,const char *name,struct dma *dma) +{ +int index; + +debug ("%s(dev=%p, name=%s, dma=%p)\n" , __func__, dev, name, dma); + dma->dev =NULL ; + + index =dev_read_stringlist_search (dev,"dma-names" , name); +if (index <0 ) { +pr_err ("dev_read_stringlist_search() failed: %d\n" , index); +return index; + } + +return dma_get_by_index (dev, index, dma); +} +# endif /* OF_CONTROL */ + +int dma_request (struct udevice *dev,struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dev); + +debug ("%s(dev=%p, dma=%p)\n" , __func__, dev, dma); + + dma->dev = dev; + +if (!ops->request) +return 0 ; + +return ops->request (dma); +} + +int dma_free (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->free) +return 0 ; + +return ops->free (dma); +} + +int dma_enable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->enable) +return -ENOSYS ; + +return ops->enable (dma); +} + +int dma_disable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->disable) +return -ENOSYS ; + +return ops->disable (dma); +} + +int dma_receive (struct dma *dma,void **dst)
Quoted 8 lines
drivers/dma/dma-uclass.c line 179
Quoted 7 lines
drivers/dma/dma-uclass.c +7
-0+{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->receive) +return -1 ;Isn't there a better error code you could return? Such as
-ENOSYSlike above?
Ok, I will fix that in the next version.
Quoted 14 lines
drivers/dma/dma-uclass.c line 191
Quoted 13 lines
drivers/dma/dma-uclass.c +12
-0+ +return ops->receive (dma, dst); +} + +int dma_send (struct dma *dma,void *src,size_t len) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->send) +return -1 ;Same here.
Ok, I will fix that in the next version.
Quoted 85 lines
Quoted 85 lines
drivers/dma/dma-uclass.c +5
-0+ + return ops->send(dma, src, len); +} +#endif /* CONFIG_DMA_CHANNELS */ +int dma_get_device (u32 transfer_type,struct udevice **devp) {struct udevice *dev;include/dma-uclass.h +61
-0@@ -13,6 +13,8 @@#include <dma.h> +struct ofnode_phandle_args ; +/* * struct dma_ops - Driver model DMA operations * @@ -20,6 +22,82 @@* driver model. */ struct dma_ops { +#ifdef CONFIG_DMA_CHANNELS +/** +* of_xlate - Translate a client's device-tree (OF) DMA specifier. +* +* The DMA core calls this function as the first step in implementing +* a client's dma_get_by_*() call. +* +* If this function pointer is set to NULL, the DMA core will use a +* default implementation, which assumes #dma-cells = <1>, and that +* the DT cell contains a simple integer DMA Channel. +* +* At present, the DMA API solely supports device-tree. If this +* changes, other xxx_xlate() functions may be added to support those +* other mechanisms. +* +* @dma: The dma struct to hold the translation result. +* @args: The dma specifier values from device tree. +* @return 0 if OK, or a negative error code. +*/ +int (*of_xlate)(struct dma *dma, +struct ofnode_phandle_args *args); +/** +* request - Request a translated DMA. +* +* The DMA core calls this function as the second step in +* implementing a client's dma_get_by_*() call, following a successful +* xxx_xlate() call, or as the only step in implementing a client's +* dma_request() call. +* +* @dma: The DMA struct to request; this has been filled in by +* a previoux xxx_xlate() function call, or by the caller of +* dma_request(). +* @return 0 if OK, or a negative error code. +*/ +int (*request)(struct dma *dma); +/** +* free - Free a previously requested dma. +* +* This is the implementation of the client dma_free() API. +* +* @dma: The DMA to free. +* @return 0 if OK, or a negative error code. +*/ +int (*free)(struct dma *dma); +/** +* enable() - Enable a DMA Channel. +* +* @dma: The DMA Channel to manipulate. +* @return zero on success, or -ve error code. +*/ +int (*enable)(struct dma *dma); +/** +* disable() - Disable a DMA Channel. +* +* @dma: The DMA Channel to manipulate. +* @return zero on success, or -ve error code. +*/ +int (*disable)(struct dma *dma); +/**
Quoted 8 lines
include/dma-uclass.h line 89
Quoted 6 lines
include/dma-uclass.h +6
-0+* receive() - Receive a DMA transfer. +* +* @dma: The DMA Channel to manipulate. +* @dst: The destination pointer. +* @return zero on success, or -ve error code. +*/ I haven't seen any implementation of this. Will it return
-EAGAINin the case where the packet isn't available?
First of all, this documentation is wrong, because it doesn't return zero on success, but the received packet length, and it returns -EAGAIN when packet is not available in order to facilitate enet implementations, but it can return something different and handle it from enet drivers.
I will fix that in the next version.
Quoted 219 lines
Quoted 219 lines
include/dma-uclass.h +11
-0+int (*receive)(struct dma *dma,void **dst); +/** +* send() - Send a DMA transfer. +* +* @dma: The DMA Channel to manipulate. +* @src: The source pointer. +* @len: Length of the data to be sent (number of bytes). +* @return zero on success, or -ve error code. +*/ +int (*send)(struct dma *dma,void *src,size_t len); +#endif /* CONFIG_DMA_CHANNELS */ /** * transfer() - Issue a DMA transfer. The implementation must * wait until the transfer is done. include/dma.h +172
-3@@ -1,6 +1,7 @@/* -* (C) Copyright 2015 -* Texas Instruments Incorporated, <www.ti.com> +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com> +* Written by Mugunthan V N <[email protected]> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -8,6 +9,9 @@#ifndef _DMA_H_#define _DMA_H_ +#include <linux/errno.h> +#include <linux/types.h> +/* * enum dma_direction - dma transfer direction indicator * @DMA_MEM_TO_MEM: Memcpy mode @@ -37,6 +41,172 @@ struct dma_dev_priv {u32 supported; }; +#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. +*/ + +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 ) +struct phandle_1_arg ; +int dma_get_by_index_platdata (struct udevice *dev,int index, +struct phandle_1_arg *cells,struct dma *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_receive() - Receive a DMA transfer. +* +* @dma: A DMA struct that was previously successfully requested by +* dma_request/get_by_*(). +* @dst: The destination pointer. +* @return zero on success, or -ve error code. +*/ +int dma_receive (struct dma *dma,void **dst); + +/** +* 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). +* @return zero on success, or -ve error code. +*/ +int dma_send (struct dma *dma,void *src,size_t len); +#endif /* CONFIG_DMA_CHANNELS */ +/* * dma_get_device - get a DMA device which supports transfer * type of transfer_type -- 2.11.0
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
https://lists.denx.de/listinfo/u-boot
PATCH v5 2/15 dma: add channels support
In reply to Álvaro Fernández RojasHi Álvaro,
Quoted 12 lines · Álvaro Fernández Rojas
This adds channels support for dma controllers that have multiple channels which can transfer data to/from different devices (enet, usb...).
Signed-off-by Álvaro Fernández Rojas <[email protected]>Reviewed-by Simon Glass <[email protected]>---
v5: remove unneededdma.hinclude
v4: no changes
v3: Introduce changes reported by Simon Glass:
- Improvedma-uclass.hdocumentation.
- Switch to live tree API.
Quoted 5 lines
drivers/dma/Kconfig | 7 ++ drivers/dma/dma-uclass.c | 188 +++++++++++++++++++++++++++++++++++++++++++++-- include/dma-uclass.h | 78 ++++++++++++++++++++ include/dma.h | 174 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 439 insertions(+), 8 deletions(-)
Small note first. I don't know if this is common practice for u-boot -
but Isn't it preferable to send new version of the series *not as reply* to the old one?
I've tried this and, in general, it works for me (unfortunately I can't post code yet). Thanks a lot for you work.
But... (it's always but ;)
[...]
Quoted 7 lines
include/dma-uclass.h +7
-0+/** +* receive() - Receive a DMA transfer. +* +* @dma: The DMA Channel to manipulate. +* @dst: The destination pointer. +* @return zero on success, or -ve error code. +*/
include/dma-uclass.h line 99
Quoted 10 lines
include/dma-uclass.h +10
-0+int (*receive)(struct dma *dma,void **dst); +/** +* send() - Send a DMA transfer. +* +* @dma: The DMA Channel to manipulate. +* @src: The source pointer. +* @len: Length of the data to be sent (number of bytes). +* @return zero on success, or -ve error code. +*/ +int (*send)(struct dma *dma,void *src,size_t len);
Can we have additional *optional* parameter in above two callbacks and in dma_receive/dma_send() API? Like:
int (*send)(struct dma *dma, void *src, size_t len, void *metadata)
int (*receive)(struct dma *dma, void **dst, void **metadata);
Reason:
It's not a common practice to implement Networking DMA using generic DMA frameworks, simply because Networking DMA HW is terribly different between different SoCs :(, so it's mostly impossible to fit all of them in any generic DMA framework (at least this has never ever worked for Linux kernel):
- totally different HW rings/queues impl, multi-queues & multi DMA channels
- special requirements for IRQ handling
- necessity to pass additional information within each Net DMA descriptor
- availability and support of different Net traffic HW acceleration features
But in case of u-boot, it, theoretically, might work because most of Net drivers have much more simplified implementation comparing to Linux kernel
- UP, polling, one RX/TX channel and disabled Net traffic HW acceleration features.
As result, Proposed here interface can be used with much more different HW and drivers (and especially Net drivers), but only if it will be possible to pass additional DMA driver's specific information from DMA user to DMA driver per each send/rsv request.
For example, two TI driver cpsw.c and keystone_net.c required to pass minimum one additional parameter with each sending packet - Destination Port number, which must be passed to DMA in DMA descriptor. And Source Port number has to be passed back with each received packet.
! I'm not insisting here ! and be happy to hear third opinion.
(if proposition will not be accepted - .. :( I'll just need to do the same later,
but there might be hight number of active users of this interface in u-boot already)
Quoted 202 lines
include/dma-uclass.h +1
-0+#endif /* CONFIG_DMA_CHANNELS */ /** * transfer() - Issue a DMA transfer. The implementation must * wait until the transfer is done. include/dma.h +172
-2@@ -1,6 +1,7 @@/* -* (C) Copyright 2015 -* Texas Instruments Incorporated, <www.ti.com> +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com> +* Written by Mugunthan V N <[email protected]> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -8,6 +9,9 @@#ifndef _DMA_H_#define _DMA_H_ +#include <linux/errno.h> +#include <linux/types.h> +/* * enum dma_direction - dma transfer direction indicator * @DMA_MEM_TO_MEM: Memcpy mode @@ -37,6 +41,172 @@ struct dma_dev_priv {u32 supported; }; +#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. +*/ + +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 ) +struct phandle_1_arg ; +int dma_get_by_index_platdata (struct udevice *dev,int index, +struct phandle_1_arg *cells,struct dma *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_receive() - Receive a DMA transfer. +* +* @dma: A DMA struct that was previously successfully requested by +* dma_request/get_by_*(). +* @dst: The destination pointer. +* @return zero on success, or -ve error code. +*/ +int dma_receive (struct dma *dma,void **dst); + +/** +* 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). +* @return zero on success, or -ve error code. +*/ +int dma_send (struct dma *dma,void *src,size_t len); +#endif /* CONFIG_DMA_CHANNELS */ +/* * dma_get_device - get a DMA device which supports transfer * type of transfer_type
Signature · 2 lines
regards, -grygorii
PATCH v5 2/15 dma: add channels support
Hi Grygorii,
Quoted 15 lines · Grygorii Strashko
Hi Álvaro,
Quoted 12 lines · Álvaro Fernández Rojas
This adds channels support for dma controllers that have multiple channels which can transfer data to/from different devices (enet, usb...).
Signed-off-by Álvaro Fernández Rojas <[email protected]>Reviewed-by Simon Glass <[email protected]>---
v5: remove unneededdma.hinclude
v4: no changes
v3: Introduce changes reported by Simon Glass:
- Improvedma-uclass.hdocumentation.
- Switch to live tree API.
Quoted 7 lines
Quoted 5 lines
drivers/dma/Kconfig | 7 ++ drivers/dma/dma-uclass.c | 188 +++++++++++++++++++++++++++++++++++++++++++++-- include/dma-uclass.h | 78 ++++++++++++++++++++ include/dma.h | 174 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 439 insertions(+), 8 deletions(-)Small note first. I don't know if this is common practice for u-boot -
but Isn't it preferable to send new version of the series *not as reply* to the old one?
I was sending it as a reply to the first version, not the last one, but I will do that from now on.
Quoted 3 lines
I've tried this and, in general, it works for me (unfortunately I can't post code yet). Thanks a lot for you work.
Thanks to you for testing :).
Quoted 2 lines
But... (it's always but ;)
¯\_(ツ)_/¯
Quoted 45 lines
[...]
Quoted 7 lines
include/dma-uclass.h +7
-0+/** +* receive() - Receive a DMA transfer. +* +* @dma: The DMA Channel to manipulate. +* @dst: The destination pointer. +* @return zero on success, or -ve error code. +*/ include/dma-uclass.h line 99
Quoted 10 lines
include/dma-uclass.h +10
-0+int (*receive)(struct dma *dma,void **dst); +/** +* send() - Send a DMA transfer. +* +* @dma: The DMA Channel to manipulate. +* @src: The source pointer. +* @len: Length of the data to be sent (number of bytes). +* @return zero on success, or -ve error code. +*/ +int (*send)(struct dma *dma,void *src,size_t len);Can we have additional *optional* parameter in above two callbacks and in dma_receive/dma_send() API? Like:
int (*send)(struct dma *dma, void *src,size_tlen, void *metadata)
int (*receive)(struct dma *dma, void **dst, void **metadata);Reason:
It's not a common practice to implement Networking DMA using generic DMA frameworks, simply because Networking DMA HW is terribly different between different SoCs :(, so it's mostly impossible to fit all of them in any generic DMA framework (at least this has never ever worked for Linux kernel):
- totally different HW rings/queues impl, multi-queues & multi DMA channels
- special requirements for IRQ handling
- necessity to pass additional information within each Net DMA descriptor
- availability and support of different Net traffic HW acceleration featuresBut in case of u-boot, it, theoretically, might work because most of Net drivers have much more simplified implementation comparing to Linux kernel
- UP, polling, one RX/TX channel and disabled Net traffic HW acceleration features.As result, Proposed here interface can be used with much more different HW and drivers (and especially Net drivers), but only if it will be possible to pass additional DMA driver's specific information from DMA user to DMA driver per each send/rsv request.
For example, two TI drivercpsw.candkeystone_net.crequired to pass minimum one additional parameter with each sending packet - Destination Port number, which must be passed to DMA in DMA descriptor. And Source Port number has to be passed back with each received packet.
Quoted 4 lines
! I'm not insisting here ! and be happy to hear third opinion.
(if proposition will not be accepted - .. :( I'll just need to do the same later,
but there might be hight number of active users of this interface in u-boot already)
If everyone else agrees I can add those two parameters in the next version even though my implementation doesn't need them.
Quoted 195 lines
Quoted 195 lines
include/dma-uclass.h +1
-0+#endif /* CONFIG_DMA_CHANNELS */ /** * transfer() - Issue a DMA transfer. The implementation must * wait until the transfer is done. include/dma.h +168
-2@@ -1,6 +1,7 @@/* -* (C) Copyright 2015 -* Texas Instruments Incorporated, <www.ti.com> +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com> +* Written by Mugunthan V N <[email protected]> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -8,6 +9,9 @@#ifndef _DMA_H_#define _DMA_H_ +#include <linux/errno.h> +#include <linux/types.h> +/* * enum dma_direction - dma transfer direction indicator * @DMA_MEM_TO_MEM: Memcpy mode @@ -37,6 +41,172 @@ struct dma_dev_priv {u32 supported; }; +#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. +*/ + +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 ) +struct phandle_1_arg ; +int dma_get_by_index_platdata (struct udevice *dev,int index, +struct phandle_1_arg *cells,struct dma *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_receive() - Receive a DMA transfer. +* +* @dma: A DMA struct that was previously successfully requested by +* dma_request/get_by_*(). +* @dst: The destination pointer. +* @return zero on success, or -ve error code. +*/ +int dma_receive (struct dma *dma,void **dst); + +/** +* 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). +* @return zero on success, or -ve error code.
Quoted 8 lines
include/dma.h struct dma_dev_priv { · line 212
Quoted 8 lines
include/dma.h +4
-0+*/ +int dma_send (struct dma *dma,void *src,size_t len); +#endif /* CONFIG_DMA_CHANNELS */ +/* * dma_get_device - get a DMA device which supports transfer * type of transfer_type
~Álvaro.
PATCH v5 2/15 dma: add channels support
In reply to Álvaro Fernández RojasHi Álvaro,
sorry for the late response.
Quoted 329 lines · Álvaro Fernández Rojas
This adds channels support for dma controllers that have multiple channels which can transfer data to/from different devices (enet, usb...).
Signed-off-by Álvaro Fernández Rojas <[email protected]>Reviewed-by Simon Glass <[email protected]>---
v5: remove unneededdma.hinclude
v4: no changes
v3: Introduce changes reported by Simon Glass:
- Improvedma-uclass.hdocumentation.
- Switch to live tree API.drivers/dma/Kconfig | 7 ++ drivers/dma/dma-uclass.c | 188 +++++++++++++++++++++++++++++++++++++++++++++-- include/dma-uclass.h | 78 ++++++++++++++++++++ include/dma.h | 174 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 439 insertions(+), 8 deletions(-)drivers/dma/Kconfig +7
-0@@ -12,6 +12,13 @@ config DMA buses that is used to transfer data to and from memory. The uclass interface is defined in include/dma.h. +config DMA_CHANNELS + bool "Enable DMA channels support" + depends on DMA + help + Enable channels support for DMA. Some DMA controllers have multiple + channels which can either transfer data to/from different devices. + config TI_EDMA3 bool "TI EDMA3 driver" helpdrivers/dma/dma-uclass.c +182
-6@@ -1,23 +1,199 @@/* * Direct Memory Access U-Class driver * -* (C) Copyright 2015 -* Texas Instruments Incorporated, <www.ti.com> -* -* Author: Mugunthan V N <[email protected]> +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com> +* Written by Mugunthan V N <[email protected]> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> #include <dm.h> -#include <dm/uclass-internal.h> -#include <dm/device-internal.h> +#include <dm/read.h> #include <dma-uclass.h> +#include <dt-structs.h> #include <errno.h> DECLARE_GLOBAL_DATA_PTR ; +#ifdef CONFIG_DMA_CHANNELS +static inline struct dma_ops *dma_dev_ops (struct udevice *dev) +{ +return (struct dma_ops *)dev->driver->ops; +} + +# if CONFIG_IS_ENABLED (OF_CONTROL ) +# if CONFIG_IS_ENABLED (OF_PLATDATA ) +int dma_get_by_index_platdata (struct udevice *dev,int index, +struct phandle_1_arg *cells,struct dma *dma) +{ +int ret; + +if (index !=0 ) +return -ENOSYS ; + ret =uclass_get_device (UCLASS_DMA ,0 , &dma->dev); +if (ret) +return ret; + dma->id = cells[0 ].id; + +return 0 ; +} +# else +static int dma_of_xlate_default (struct dma *dma, +struct ofnode_phandle_args *args) +{ +debug ("%s(dma=%p)\n" , __func__, dma); + +if (args->args_count >1 ) { +pr_err ("Invaild args_count: %d\n" , args->args_count); +return -EINVAL ; + } + +if (args->args_count) + dma->id = args->args[0 ]; +else + dma->id =0 ; + +return 0 ; +} + +int dma_get_by_index (struct udevice *dev,int index,struct dma *dma) +{ +int ret; +struct ofnode_phandle_args args; +struct udevice *dev_dma; +const struct dma_ops *ops; + +debug ("%s(dev=%p, index=%d, dma=%p)\n" , __func__, dev, index, dma); + +assert (dma); + dma->dev =NULL ; + + ret =dev_read_phandle_with_args (dev,"dmas" ,"#dma-cells" ,0 , index, + &args); +if (ret) { +pr_err ("%s: dev_read_phandle_with_args failed: err=%d\n" , + __func__, ret); +return ret; + } + + ret =uclass_get_device_by_ofnode (UCLASS_DMA , args.node, &dev_dma); +if (ret) { +pr_err ("%s: uclass_get_device_by_ofnode failed: err=%d\n" , + __func__, ret); +return ret; + } + + dma->dev = dev_dma; + + ops =dma_dev_ops (dev_dma); + +if (ops->of_xlate) + ret = ops->of_xlate (dma, &args); +else + ret =dma_of_xlate_default (dma, &args); +if (ret) { +pr_err ("of_xlate() failed: %d\n" , ret); +return ret; + } + +return dma_request (dev_dma, dma); +} +# endif /* OF_PLATDATA */ + +int dma_get_by_name (struct udevice *dev,const char *name,struct dma *dma) +{ +int index; + +debug ("%s(dev=%p, name=%s, dma=%p)\n" , __func__, dev, name, dma); + dma->dev =NULL ; + + index =dev_read_stringlist_search (dev,"dma-names" , name); +if (index <0 ) { +pr_err ("dev_read_stringlist_search() failed: %d\n" , index); +return index; + } + +return dma_get_by_index (dev, index, dma); +} +# endif /* OF_CONTROL */ + +int dma_request (struct udevice *dev,struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dev); + +debug ("%s(dev=%p, dma=%p)\n" , __func__, dev, dma); + + dma->dev = dev; + +if (!ops->request) +return 0 ; + +return ops->request (dma); +} + +int dma_free (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->free) +return 0 ; + +return ops->free (dma); +} + +int dma_enable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->enable) +return -ENOSYS ; + +return ops->enable (dma); +} + +int dma_disable (struct dma *dma) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->disable) +return -ENOSYS ; + +return ops->disable (dma); +} + +int dma_receive (struct dma *dma,void **dst) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->receive) +return -1 ; + +return ops->receive (dma, dst); +} + +int dma_send (struct dma *dma,void *src,size_t len) +{ +struct dma_ops *ops =dma_dev_ops (dma->dev); + +debug ("%s(dma=%p)\n" , __func__, dma); + +if (!ops->send) +return -1 ; + +return ops->send (dma, src, len); +} +#endif /* CONFIG_DMA_CHANNELS */ +int dma_get_device (u32 transfer_type,struct udevice **devp) {struct udevice *dev;include/dma-uclass.h +68
-0@@ -13,6 +13,8 @@#include <dma.h> +struct ofnode_phandle_args ; +/* * struct dma_ops - Driver model DMA operations * @@ -20,6 +22,82 @@* driver model. */ struct dma_ops { +#ifdef CONFIG_DMA_CHANNELS +/** +* of_xlate - Translate a client's device-tree (OF) DMA specifier. +* +* The DMA core calls this function as the first step in implementing +* a client's dma_get_by_*() call. +* +* If this function pointer is set to NULL, the DMA core will use a +* default implementation, which assumes #dma-cells = <1>, and that +* the DT cell contains a simple integer DMA Channel. +* +* At present, the DMA API solely supports device-tree. If this +* changes, other xxx_xlate() functions may be added to support those +* other mechanisms. +* +* @dma: The dma struct to hold the translation result. +* @args: The dma specifier values from device tree. +* @return 0 if OK, or a negative error code. +*/ +int (*of_xlate)(struct dma *dma, +struct ofnode_phandle_args *args); +/** +* request - Request a translated DMA. +* +* The DMA core calls this function as the second step in +* implementing a client's dma_get_by_*() call, following a successful +* xxx_xlate() call, or as the only step in implementing a client's +* dma_request() call. +* +* @dma: The DMA struct to request; this has been filled in by +* a previoux xxx_xlate() function call, or by the caller of +* dma_request(). +* @return 0 if OK, or a negative error code. +*/ +int (*request)(struct dma *dma); +/** +* free - Free a previously requested dma. +* +* This is the implementation of the client dma_free() API. +* +* @dma: The DMA to free. +* @return 0 if OK, or a negative error code. +*/ +int (*free)(struct dma *dma); +/** +* enable() - Enable a DMA Channel. +* +* @dma: The DMA Channel to manipulate. +* @return zero on success, or -ve error code. +*/ +int (*enable)(struct dma *dma); +/** +* disable() - Disable a DMA Channel. +* +* @dma: The DMA Channel to manipulate. +* @return zero on success, or -ve error code. +*/ +int (*disable)(struct dma *dma); +/** +* receive() - Receive a DMA transfer. +* +* @dma: The DMA Channel to manipulate. +* @dst: The destination pointer. +* @return zero on success, or -ve error code. +*/ +int (*receive)(struct dma *dma,void **dst);
include/dma-uclass.h line 100
Quoted 10 lines
include/dma-uclass.h +10
-0+/** +* send() - Send a DMA transfer. +* +* @dma: The DMA Channel to manipulate. +* @src: The source pointer. +* @len: Length of the data to be sent (number of bytes). +* @return zero on success, or -ve error code. +*/ +int (*send)(struct dma *dma,void *src,size_t len); +#endif /* CONFIG_DMA_CHANNELS */
IMHO a DMA driver should not implement receive() and send() directly as this involves generic code like flushing/invalidating caches, synchronous waiting on descriptor status etc. This could be better handled by dma-uclass code than repeating it in each driver.
I think a heavily simplified design of Linux's dmaengine would help. For instance the driver interface could be modelled with prepare_cyclic(), prepare_memcpy() and status(). The dma-uclass can then provide an interface for those functions as well as additional wrapper functions like dma_is_complete(), dma_sync_wait(), dma_receive() or dma_send().
Regardless of the design, I'd like to have at least separate functions for preparing the buffers and polling the descriptor. For instance I have a DMA-capable NAND controller, where the DMA transfer is only started by writing some HW registers. This must happen between preparing the buffers and DMA descriptors and polling the descriptors until the transaction has finished.
Could you do that?
Quoted 201 lines
include/dma-uclass.h +0
-0/** * transfer() - Issue a DMA transfer. The implementation must * wait until the transfer is done. include/dma.h +172
-2@@ -1,6 +1,7 @@/* -* (C) Copyright 2015 -* Texas Instruments Incorporated, <www.ti.com> +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com> +* Written by Mugunthan V N <[email protected]> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -8,6 +9,9 @@#ifndef _DMA_H_#define _DMA_H_ +#include <linux/errno.h> +#include <linux/types.h> +/* * enum dma_direction - dma transfer direction indicator * @DMA_MEM_TO_MEM: Memcpy mode @@ -37,6 +41,172 @@ struct dma_dev_priv {u32 supported; }; +#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. +*/ + +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 ) +struct phandle_1_arg ; +int dma_get_by_index_platdata (struct udevice *dev,int index, +struct phandle_1_arg *cells,struct dma *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_receive() - Receive a DMA transfer. +* +* @dma: A DMA struct that was previously successfully requested by +* dma_request/get_by_*(). +* @dst: The destination pointer. +* @return zero on success, or -ve error code. +*/ +int dma_receive (struct dma *dma,void **dst); + +/** +* 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). +* @return zero on success, or -ve error code. +*/ +int dma_send (struct dma *dma,void *src,size_t len); +#endif /* CONFIG_DMA_CHANNELS */ +/* * dma_get_device - get a DMA device which supports transfer * type of transfer_type
Signature · 9 lines
- Daniel -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180311/5111c25b/attachment.sig>
PATCH v5 3/15 dma: add bcm6348-iudma support
In reply to Álvaro Fernández RojasBCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
---
v5: Several fixes and improvements:
- Remove unused defines.
- Increment rx descriptors.
- Fix flow control issues.
- Error checking now depends on hw.
- Remove unneeded interrupts.
v4: Fix issues reported by Grygorii Strashko and other fixes:
- Remove usage of net_rx_packets as buffer.
- Allocate dynamic rx buffer.
- Check dma errors and discard invalid packets.
v3: no changes
v2: Fix dma rx burst config and select DMA_CHANNELS.
drivers/dma/Kconfig | 9 + drivers/dma/Makefile | 1 + drivers/dma/bcm6348-iudma.c | 532 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 542 insertions(+) create mode 100644 drivers/dma/bcm6348-iudma.c
drivers/dma/Kconfig +9 -0
@@ -19,6 +19,15 @@ config DMA_CHANNELS Enable channels support for DMA. Some DMA controllers have multiple channels which can either transfer data to/from different devices. +config BCM6348_IUDMA + bool "BCM6348 IUDMA driver" + depends on ARCH_BMIPS + select DMA_CHANNELS + help + Enable the BCM6348 IUDMA driver. + This driver support data transfer from devices to + memory and from memory to devices. + config TI_EDMA3 bool "TI EDMA3 driver" help
drivers/dma/Makefile +1 -0
@@ -9,6 +9,7 @@ obj-$(CONFIG_DMA) += dma-uclass.o obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o obj-$(CONFIG_APBH_DMA) += apbh_dma.o +obj-$(CONFIG_BCM6348_IUDMA) += bcm6348-iudma.o obj-$(CONFIG_FSL_DMA) += fsl_dma.o obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o obj-$(CONFIG_TI_EDMA3) += ti-edma3.o
drivers/dma/bcm6348-iudma.c new file +532 -0
532 lines not on this page · raw message
Signature · 1 line
2.11.0
PATCH v5 4/15 bmips: bcm6338: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas---
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6338.dtsi | 14 ++++++++++++++ include/dt-bindings/dma/bcm6338-dma.h | 15 +++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6338-dma.h
arch/mips/dts/brcm,bcm6338.dtsi +14 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6338-clock.h> +#include <dt-bindings/dma/bcm6338-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6338-reset.h> #include "skeleton.dtsi"
@@ -131,5 +132,18 @@ reg = <0xfffe3100 0x38>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller at fffe2400 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe2400 0x1c>, + <0xfffe2500 0x60>, + <0xfffe2600 0x60>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <6>; + resets = <&periph_rst BCM6338_RST_DMAMEM>; + }; }; };
include/dt-bindings/dma/bcm6338-dma.h new file +15 -0
@@ -0,0 +1,15 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6338_H +#define __DT_BINDINGS_DMA_BCM6338_H + +#define BCM6338_DMA_ENET_RX 0 +#define BCM6338_DMA_ENET_TX 1 + +#endif /* __DT_BINDINGS_DMA_BCM6338_H */
Signature · 1 line
2.11.0
PATCH v5 5/15 bmips: bcm6348: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas---
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6348.dtsi | 16 ++++++++++++++++ include/dt-bindings/dma/bcm6348-dma.h | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6348-dma.h
arch/mips/dts/brcm,bcm6348.dtsi +16 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6348-clock.h> +#include <dt-bindings/dma/bcm6348-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6348-reset.h> #include "skeleton.dtsi"
@@ -160,5 +161,20 @@ reg = <0xfffe2300 0x38>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller at fffe7000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe7000 0x1c>, + <0xfffe7100 0x40>, + <0xfffe7200 0x40>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <4>; + clocks = <&periph_clk BCM6348_CLK_ENET>; + resets = <&periph_rst BCM6348_RST_ENET>, + <&periph_rst BCM6348_RST_DMAMEM>; + }; }; };
include/dt-bindings/dma/bcm6348-dma.h new file +17 -0
@@ -0,0 +1,17 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6348_H +#define __DT_BINDINGS_DMA_BCM6348_H + +#define BCM6348_DMA_ENET0_RX 0 +#define BCM6348_DMA_ENET0_TX 1 +#define BCM6348_DMA_ENET1_RX 2 +#define BCM6348_DMA_ENET1_TX 3 + +#endif /* __DT_BINDINGS_DMA_BCM6348_H */
Signature · 1 line
2.11.0
PATCH v5 6/15 bmips: bcm6358: add bcm6348-iudma support
In reply to Álvaro Fernández Rojas---
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6358.dtsi | 18 ++++++++++++++++++ include/dt-bindings/dma/bcm6358-dma.h | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 include/dt-bindings/dma/bcm6358-dma.h
arch/mips/dts/brcm,bcm6358.dtsi +18 -0
@@ -5,6 +5,7 @@ */ #include <dt-bindings/clock/bcm6358-clock.h> +#include <dt-bindings/dma/bcm6358-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6358-reset.h> #include "skeleton.dtsi"
@@ -191,5 +192,22 @@ status = "disabled"; }; + + iudma: dma-controller at fffe5000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe5000 0x24>, + <0xfffe5100 0x80>, + <0xfffe5200 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + clocks = <&periph_clk BCM6358_CLK_EMUSB>, + <&periph_clk BCM6358_CLK_USBSU>, + <&periph_clk BCM6358_CLK_EPHY>; + resets = <&periph_rst BCM6358_RST_ENET>, + <&periph_rst BCM6358_RST_EPHY>; + }; }; };
include/dt-bindings/dma/bcm6358-dma.h new file +17 -0
@@ -0,0 +1,17 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __DT_BINDINGS_DMA_BCM6358_H +#define __DT_BINDINGS_DMA_BCM6358_H + +#define BCM6358_DMA_ENET0_RX 0 +#define BCM6358_DMA_ENET0_TX 1 +#define BCM6358_DMA_ENET1_RX 2 +#define BCM6358_DMA_ENET1_TX 3 + +#endif /* __DT_BINDINGS_DMA_BCM6358_H */
Signature · 1 line
2.11.0
PATCH v5 7/15 phy: add support for internal phys
In reply to Álvaro Fernández Rojas---
v5: no changes
v4: no changes
v3: no changes
v2: no changes
include/phy.h | 2 ++ 1 file changed, 2 insertions(+)
include/phy.h +2 -0
@@ -50,6 +50,7 @@ typedef enum { + PHY_INTERFACE_MODE_INTERNAL, PHY_INTERFACE_MODE_MII, PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_SGMII,
@@ -72,6 +73,7 @@ typedef enum { } phy_interface_t;static const char *phy_interface_strings[] = { + [PHY_INTERFACE_MODE_INTERNAL ] ="internal" , [PHY_INTERFACE_MODE_MII ] ="mii" , [PHY_INTERFACE_MODE_GMII ] ="gmii" , [PHY_INTERFACE_MODE_SGMII ] ="sgmii" ,
Signature · 1 line
2.11.0
PATCH v5 7/15 phy: add support for internal phys
Quoted 15 lines · Álvaro Fernández Rojas
Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v5: no changes
v4: no changes
v3: no changes
v2: no changesinclude/phy.h | 2 ++ 1 file changed, 2 insertions(+)include/phy.h +0
-0
include/phy.h line 53
Quoted 4 lines
include/phy.h +1
-0@@ -50,6 +50,7 @@ typedef enum { + PHY_INTERFACE_MODE_INTERNAL,
In Linux this is handled as a flag instead of a different mode. It seems we should do it the same way.
Quoted 18 lines
include/phy.h +1
-1PHY_INTERFACE_MODE_MII ,PHY_INTERFACE_MODE_GMII , PHY_INTERFACE_MODE_SGMII,@@ -72,6 +73,7 @@ typedef enum { } phy_interface_t;static const char *phy_interface_strings[] = { + [PHY_INTERFACE_MODE_INTERNAL ] ="internal" , [PHY_INTERFACE_MODE_MII ] ="mii" , [PHY_INTERFACE_MODE_GMII ] ="gmii" , [PHY_INTERFACE_MODE_SGMII ] ="sgmii" , --2.11.0
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
https://lists.denx.de/listinfo/u-boot
PATCH v5 7/15 phy: add support for internal phys
Hi Joe,
Quoted 19 lines · Joe Hershberger
Quoted 17 lines · Álvaro Fernández Rojas
Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v5: no changes
v4: no changes
v3: no changes
v2: no changesinclude/phy.h | 2 ++ 1 file changed, 2 insertions(+)include/phy.h +0
-0@@ -50,6 +50,7 @@
Quoted 4 lines
include/phy.h line 53
Quoted 2 lines
include/phy.h +1
-0typedef enum { + PHY_INTERFACE_MODE_INTERNAL,In Linux this is handled as a flag instead of a different mode. It seems we should do it the same way.
Not really, in Linux this is handled as both:
- As a flag (https://elixir.bootlin.com/linux/latest/ident/PHY_IS_INTERNAL):
https://github.com/torvalds/linux/blob/master/include/linux/phy.h#L61
https://github.com/torvalds/linux/blob/master/drivers/net/phy/phy_device.c#L1792
https://github.com/torvalds/linux/blob/master/include/linux/phy.h#L832
- As a mode
(https://elixir.bootlin.com/linux/latest/ident/PHY_INTERFACE_MODE_INTERNAL):
https://github.com/torvalds/linux/blob/master/include/linux/phy.h#L68
https://github.com/torvalds/linux/blob/master/include/linux/phy.h#L119
Quoted 15 lines
Quoted 15 lines
include/phy.h +1
-1PHY_INTERFACE_MODE_MII ,PHY_INTERFACE_MODE_GMII , PHY_INTERFACE_MODE_SGMII,@@ -72,6 +73,7 @@ typedef enum { } phy_interface_t;static const char *phy_interface_strings[] = { + [PHY_INTERFACE_MODE_INTERNAL ] ="internal" , [PHY_INTERFACE_MODE_MII ] ="mii" , [PHY_INTERFACE_MODE_GMII ] ="gmii" , [PHY_INTERFACE_MODE_SGMII ] ="sgmii" , --2.11.0
Quoted 4 lines
Quoted 4 lines
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
https://lists.denx.de/listinfo/u-boot
~Álvaro.
PATCH v5 7/15 phy: add support for internal phys
Quoted 30 lines · Álvaro Fernández Rojas
Hi Joe,
Quoted 21 lines · Joe Hershberger
Quoted 18 lines · Álvaro Fernández Rojas
Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v5: no changes
v4: no changes
v3: no changes
v2: no changesinclude/phy.h | 2 ++ 1 file changed, 2 insertions(+)include/phy.h +0
-0@@ -50,6 +50,7 @@Quoted 5 lines
include/phy.h line 53
Quoted 2 lines
include/phy.h +1
-0typedef enum { + PHY_INTERFACE_MODE_INTERNAL,In Linux this is handled as a flag instead of a different mode. It seems we should do it the same way.
Quoted 10 lines
Not really, in Linux this is handled as both:
- As a flag (https://elixir.bootlin.com/linux/latest/ident/PHY_IS_INTERNAL):
https://github.com/torvalds/linux/blob/master/include/linux/phy.h#L61
https://github.com/torvalds/linux/blob/master/drivers/net/phy/phy_device.c#L1792
https://github.com/torvalds/linux/blob/master/include/linux/phy.h#L832
- As a mode
(https://elixir.bootlin.com/linux/latest/ident/PHY_INTERFACE_MODE_INTERNAL):
https://github.com/torvalds/linux/blob/master/include/linux/phy.h#L68
https://github.com/torvalds/linux/blob/master/include/linux/phy.h#L119
OK, I was looking at an older kernel where there was only the flag.
Quoted 26 lines
Quoted 15 lines
Quoted 15 lines
include/phy.h +1
-1PHY_INTERFACE_MODE_MII ,PHY_INTERFACE_MODE_GMII , PHY_INTERFACE_MODE_SGMII,@@ -72,6 +73,7 @@ typedef enum { } phy_interface_t;static const char *phy_interface_strings[] = { + [PHY_INTERFACE_MODE_INTERNAL ] ="internal" , [PHY_INTERFACE_MODE_MII ] ="mii" , [PHY_INTERFACE_MODE_GMII ] ="gmii" , [PHY_INTERFACE_MODE_SGMII ] ="sgmii" , --2.11.0
Quoted 4 lines
Quoted 4 lines
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
https://lists.denx.de/listinfo/u-boot~Álvaro.
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
https://lists.denx.de/listinfo/u-boot
PATCH v5 8/15 net: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v5: Receive as much packets as possible from bcm6348-eth and cache them in net_rx_packets. This is needed in order to fix flow control issues.
v4: Fix issues reported by Grygorii Strashko and other fixes:
- Copy received dma buffer to net_rx_packets in order to avoid possible dma overwrites.
- Reset dma rx channel when sending a new packet to prevent flow control issues.
- Fix packet casting on bcm6348_eth_recv/send.
v3: no changes
v2: select DMA_CHANNELS.
drivers/net/Kconfig | 10 + drivers/net/Makefile | 1 + drivers/net/bcm6348-eth.c | 575 +++++++++++++++++++++++++++++++++++++++++ include/configs/bmips_common.h | 5 +- 4 files changed, 590 insertions(+), 1 deletion(-) create mode 100644 drivers/net/bcm6348-eth.c
drivers/net/Kconfig +10 -0
@@ -71,6 +71,16 @@ config BCM_SF2_ETH_GMAC by the BCM_SF2_ETH driver. Say Y to any bcmcygnus based platforms. +config BCM6348_ETH + bool "BCM6348 EMAC support" + depends on DM_ETH && ARCH_BMIPS + select DMA + select DMA_CHANNELS + select MII + select PHYLIB + help + This driver supports the BCM6348 Ethernet MAC. + config DWC_ETH_QOS bool "Synopsys DWC Ethernet QOS device support" depends on DM_ETH
drivers/net/Makefile +1 -0
@@ -8,6 +8,7 @@ obj-$(CONFIG_ALTERA_TSE) += altera_tse.o obj-$(CONFIG_AG7XXX) += ag7xxx.o obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o +obj-$(CONFIG_BCM6348_ETH) += bcm6348-eth.o obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o obj-$(CONFIG_DRIVER_AX88180) += ax88180.o obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
drivers/net/bcm6348-eth.c new file +575 -0
575 lines not on this page · raw message
include/configs/bmips_common.h +4 -1
@@ -7,6 +7,9 @@#ifndef __CONFIG_BMIPS_COMMON_H#define __CONFIG_BMIPS_COMMON_H +/* ETH */ +#define CONFIG_PHY_RESET_DELAY 20 +/* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ 230400, 500000, 1500000 }
@@ -17,7 +20,7 @@/* Memory usage */ #define CONFIG_SYS_MAXARGS 24 -#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) +#define CONFIG_SYS_MALLOC_LEN (2 * 1024 * 1024)#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)#define CONFIG_SYS_CBSIZE 512
Signature · 1 line
2.11.0
PATCH v5 8/15 net: add support for bcm6348-enet
Quoted 265 lines · Álvaro Fernández Rojas
Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v5: Receive as much packets as possible from bcm6348-eth and cache them innet_rx_packets. This is needed in order to fix flow control issues.
v4: Fix issues reported by Grygorii Strashko and other fixes:
- Copy received dma buffer tonet_rx_packetsin order to avoid possible dma overwrites.
- Reset dma rx channel when sending a new packet to prevent flow control issues.
- Fix packet casting on bcm6348_eth_recv/send.
v3: no changes
v2: selectDMA_CHANNELS.drivers/net/Kconfig | 10 + drivers/net/Makefile | 1 + drivers/net/bcm6348-eth.c | 575 +++++++++++++++++++++++++++++++++++++++++ include/configs/bmips_common.h | 5 +- 4 files changed, 590 insertions(+), 1 deletion(-) create mode 100644 drivers/net/bcm6348-eth.cdrivers/net/Kconfig +10
-0@@ -71,6 +71,16 @@ config BCM_SF2_ETH_GMAC by the BCM_SF2_ETH driver. Say Y to any bcmcygnus based platforms. +config BCM6348_ETH + bool "BCM6348 EMAC support" + depends on DM_ETH && ARCH_BMIPS + select DMA + select DMA_CHANNELS + select MII + select PHYLIB + help + This driver supports the BCM6348 Ethernet MAC. + config DWC_ETH_QOS bool "Synopsys DWC Ethernet QOS device support" depends on DM_ETHdrivers/net/Makefile +1
-0@@ -8,6 +8,7 @@ obj-$(CONFIG_ALTERA_TSE) += altera_tse.o obj-$(CONFIG_AG7XXX) += ag7xxx.o obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o +obj-$(CONFIG_BCM6348_ETH) += bcm6348-eth.o obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o obj-$(CONFIG_DRIVER_AX88180) += ax88180.o obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.odrivers/net/bcm6348-eth.c new file +206
-0@@ -0,0 +1,575 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c: +* Copyright (C) 2008 Maxime Bizon <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <dma.h> +#include <miiphy.h> +#include <net.h> +#include <phy.h> +#include <reset.h> +#include <wait_bit.h> +#include <asm/io.h> + +#define ETH_RX_DESC PKTBUFSRX +#define ETH_MAX_MTU_SIZE 1518 +#define ETH_TIMEOUT 100 +#define ETH_TX_WATERMARK 32 + +/* ETH Receiver Configuration register */ +#define ETH_RXCFG_REG 0x00 +#define ETH_RXCFG_ENFLOW_SHIFT 5 +#define ETH_RXCFG_ENFLOW_MASK (1 << ETH_RXCFG_ENFLOW_SHIFT) + +/* ETH Receive Maximum Length register */ +#define ETH_RXMAXLEN_REG 0x04 +#define ETH_RXMAXLEN_SHIFT 0 +#define ETH_RXMAXLEN_MASK (0x7ff << ETH_RXMAXLEN_SHIFT) + +/* ETH Transmit Maximum Length register */ +#define ETH_TXMAXLEN_REG 0x08 +#define ETH_TXMAXLEN_SHIFT 0 +#define ETH_TXMAXLEN_MASK (0x7ff << ETH_TXMAXLEN_SHIFT) + +/* MII Status/Control register */ +#define MII_SC_REG 0x10 +#define MII_SC_MDCFREQDIV_SHIFT 0 +#define MII_SC_MDCFREQDIV_MASK (0x7f << MII_SC_MDCFREQDIV_SHIFT) +#define MII_SC_PREAMBLE_EN_SHIFT 7 +#define MII_SC_PREAMBLE_EN_MASK (1 << MII_SC_PREAMBLE_EN_SHIFT) + +/* MII Data register */ +#define MII_DAT_REG 0x14 +#define MII_DAT_DATA_SHIFT 0 +#define MII_DAT_DATA_MASK (0xffff << MII_DAT_DATA_SHIFT) +#define MII_DAT_TA_SHIFT 16 +#define MII_DAT_TA_MASK (0x3 << MII_DAT_TA_SHIFT) +#define MII_DAT_REG_SHIFT 18 +#define MII_DAT_REG_MASK (0x1f << MII_DAT_REG_SHIFT) +#define MII_DAT_PHY_SHIFT 23 +#define MII_DAT_PHY_MASK (0x1f << MII_DAT_PHY_SHIFT) +#define MII_DAT_OP_SHIFT 28 +#define MII_DAT_OP_WRITE (0x5 << MII_DAT_OP_SHIFT) +#define MII_DAT_OP_READ (0x6 << MII_DAT_OP_SHIFT) + +/* ETH Interrupts Mask register */ +#define ETH_IRMASK_REG 0x18 + +/* ETH Interrupts register */ +#define ETH_IR_REG 0x1c +#define ETH_IR_MII_SHIFT 0 +#define ETH_IR_MII_MASK (1 << ETH_IR_MII_SHIFT) + +/* ETH Control register */ +#define ETH_CTL_REG 0x2c +#define ETH_CTL_ENABLE_SHIFT 0 +#define ETH_CTL_ENABLE_MASK (1 << ETH_CTL_ENABLE_SHIFT) +#define ETH_CTL_DISABLE_SHIFT 1 +#define ETH_CTL_DISABLE_MASK (1 << ETH_CTL_DISABLE_SHIFT) +#define ETH_CTL_RESET_SHIFT 2 +#define ETH_CTL_RESET_MASK (1 << ETH_CTL_RESET_SHIFT) +#define ETH_CTL_EPHY_SHIFT 3 +#define ETH_CTL_EPHY_MASK (1 << ETH_CTL_EPHY_SHIFT) + +/* ETH Transmit Control register */ +#define ETH_TXCTL_REG 0x30 +#define ETH_TXCTL_FD_SHIFT 0 +#define ETH_TXCTL_FD_MASK (1 << ETH_TXCTL_FD_SHIFT) + +/* ETH Transmit Watermask register */ +#define ETH_TXWMARK_REG 0x34 +#define ETH_TXWMARK_WM_SHIFT 0 +#define ETH_TXWMARK_WM_MASK (0x3f << ETH_TXWMARK_WM_SHIFT) + +/* MIB Control register */ +#define MIB_CTL_REG 0x38 +#define MIB_CTL_RDCLEAR_SHIFT 0 +#define MIB_CTL_RDCLEAR_MASK (1 << MIB_CTL_RDCLEAR_SHIFT) + +/* ETH Perfect Match registers */ +#define ETH_PM_CNT 4 +#define ETH_PML_REG (x) (0x58 + (x) * 0x8) +#define ETH_PMH_REG (x) (0x5c + (x) * 0x8) +#define ETH_PMH_VALID_SHIFT 16 +#define ETH_PMH_VALID_MASK (1 << ETH_PMH_VALID_SHIFT) + +/* MIB Counters registers */ +#define MIB_REG_CNT 55 +#define MIB_REG (x) (0x200 + (x) * 4) + +/* ETH data */ +struct bcm6348_eth_priv { +void __iomem *base; +/* RX */ +uint8_t rx_desc; +uint8_t rx_pend; +int rx_ret[ETH_RX_DESC ]; +/* DMA */ +struct dma rx_dma; +struct dma tx_dma; +/* PHY */ +int phy_id; +struct phy_device *phy_dev; +}; + +DECLARE_GLOBAL_DATA_PTR ; + +static void bcm6348_eth_mac_disable (struct bcm6348_eth_priv *priv) +{ +/* disable emac */ +clrsetbits_be32 (priv->base +ETH_CTL_REG ,ETH_CTL_ENABLE_MASK , +ETH_CTL_DISABLE_MASK ); + +/* wait until emac is disabled */ +if (wait_for_bit_be32 (priv->base +ETH_CTL_REG , +ETH_CTL_DISABLE_MASK , false, +ETH_TIMEOUT , false)) +pr_err ("error disabling emac\n" ); +} + +static void bcm6348_eth_mac_enable (struct bcm6348_eth_priv *priv) +{ +setbits_be32 (priv->base +ETH_CTL_REG ,ETH_CTL_ENABLE_MASK ); +} + +static void bcm6348_eth_mac_reset (struct bcm6348_eth_priv *priv) +{ +/* reset emac */ +writel_be (ETH_CTL_RESET_MASK , priv->base +ETH_CTL_REG ); +wmb (); + +/* wait until emac is reset */ +if (wait_for_bit_be32 (priv->base +ETH_CTL_REG , +ETH_CTL_RESET_MASK , false, +ETH_TIMEOUT , false)) +pr_err ("error resetting emac\n" ); +} + +static int bcm6348_eth_free_pkt (struct udevice *dev,uchar *packet,int len) +{ +struct bcm6348_eth_priv *priv =dev_get_priv (dev); + +/* sanity check */ +if (packet != net_rx_packets[priv->rx_pend]) { +pr_err ("rx_pend %d: packet is not matched,\n" , priv->rx_pend); +return -EAGAIN ; + } + +/* free pending packet */ + priv->rx_ret[priv->rx_pend] =0 ; + priv->rx_pend = (priv->rx_pend +1 ) %ETH_RX_DESC ; + +return 0 ; +} + +static int _bcm6348_eth_recv (struct bcm6348_eth_priv *priv) +{ +uint8_t pkt = priv->rx_desc; + +/* check if packet is free */ +if (priv->rx_ret[pkt] >0 ) +return -EAGAIN ; + +/* try to receive a new packet */ + priv->rx_ret[pkt] =dma_receive (&priv->rx_dma, + (void **)&net_rx_packets[pkt]); +if (priv->rx_ret[pkt] >0 ) + priv->rx_desc = (priv->rx_desc +1 ) %ETH_RX_DESC ; + +return priv->rx_ret[pkt]; +} + +static int bcm6348_eth_recv (struct udevice *dev,int flags,uchar **packetp) +{ +struct bcm6348_eth_priv *priv =dev_get_priv (dev); +uint8_t pkt_cnt =0 ; +int ret; + +/* try to receive packets */ +while (_bcm6348_eth_recv (priv) >0 ) + pkt_cnt++; + +if (pkt_cnt) +debug ("%s: received %u packet(s)\n" , __func__, pkt_cnt); + +/* return current packet */ + ret = priv->rx_ret[priv->rx_pend]; +if (ret >0 ) + *packetp = net_rx_packets[priv->rx_pend]; +
drivers/net/bcm6348-eth.c line 216
Quoted 10 lines
drivers/net/bcm6348-eth.c new file +10
-0+return ret; +} + +static int bcm6348_eth_send (struct udevice *dev,void *packet,int length) +{ +struct bcm6348_eth_priv *priv =dev_get_priv (dev); + +/* reset dma rx channel */ +dma_disable (&priv->rx_dma); +dma_enable (&priv->rx_dma);
Why. Please include reasoning in the comment.
Quoted 389 lines
drivers/net/bcm6348-eth.c new file +359
-0+ +return dma_send (&priv->tx_dma, (void *)packet, length); +} + +static int bcm6348_eth_adjust_link (struct udevice *dev, +struct phy_device *phydev) +{ +struct bcm6348_eth_priv *priv =dev_get_priv (dev); + +/* mac duplex parameters */ +if (phydev->duplex) +setbits_be32 (priv->base +ETH_TXCTL_REG ,ETH_TXCTL_FD_MASK ); +else +clrbits_be32 (priv->base +ETH_TXCTL_REG ,ETH_TXCTL_FD_MASK ); + +/* rx flow control (pause frame handling) */ +if (phydev->pause) +setbits_be32 (priv->base +ETH_RXCFG_REG , +ETH_RXCFG_ENFLOW_MASK ); +else +clrbits_be32 (priv->base +ETH_RXCFG_REG , +ETH_RXCFG_ENFLOW_MASK ); + +return 0 ; +} + +static int bcm6348_eth_start (struct udevice *dev) +{ +struct bcm6348_eth_priv *priv =dev_get_priv (dev); +int ret, i; + + priv->rx_desc =0 ; + priv->rx_pend =0 ; +for (i =0 ; i <ETH_RX_DESC ; i++) + priv->rx_ret[i] =0 ; + +/* enable dma rx channel */ +dma_enable (&priv->rx_dma); + +/* enable dma tx channel */ +dma_enable (&priv->tx_dma); + + ret =phy_startup (priv->phy_dev); +if (ret) { +pr_err ("could not initialize phy\n" ); +return ret; + } + +if (!priv->phy_dev->link) { +pr_err ("no phy link\n" ); +return -EIO ; + } + +bcm6348_eth_adjust_link (dev, priv->phy_dev); + +/* zero mib counters */ +for (i =0 ; i <MIB_REG_CNT ; i++) +writel_be (0 ,MIB_REG (i)); + +/* enable rx flow control */ +setbits_be32 (priv->base +ETH_RXCFG_REG ,ETH_RXCFG_ENFLOW_MASK ); + +/* set max rx/tx length */ +writel_be ((ETH_MAX_MTU_SIZE <<ETH_RXMAXLEN_SHIFT ) & +ETH_RXMAXLEN_MASK , priv->base +ETH_RXMAXLEN_REG ); +writel_be ((ETH_MAX_MTU_SIZE <<ETH_TXMAXLEN_SHIFT ) & +ETH_TXMAXLEN_MASK , priv->base +ETH_TXMAXLEN_REG ); + +/* set correct transmit fifo watermark */ +writel_be ((ETH_TX_WATERMARK <<ETH_TXWMARK_WM_SHIFT ) & +ETH_TXWMARK_WM_MASK , priv->base +ETH_TXWMARK_REG ); + +/* enable emac */ +bcm6348_eth_mac_enable (priv); + +/* clear interrupts */ +writel_be (0 , priv->base +ETH_IRMASK_REG ); + +return 0 ; +} + +static void bcm6348_eth_stop (struct udevice *dev) +{ +struct bcm6348_eth_priv *priv =dev_get_priv (dev); + +/* disable dma rx channel */ +dma_disable (&priv->rx_dma); + +/* disable dma tx channel */ +dma_disable (&priv->tx_dma); + +/* disable emac */ +bcm6348_eth_mac_disable (priv); +} + +static int bcm6348_eth_write_hwaddr (struct udevice *dev) +{ +struct eth_pdata *pdata =dev_get_platdata (dev); +struct bcm6348_eth_priv *priv =dev_get_priv (dev); +bool running = false; + +/* check if emac is running */ +if (readl_be (priv->base +ETH_CTL_REG ) Ð_CTL_ENABLE_MASK ) + running = true; + +/* disable emac */ +if (running) +bcm6348_eth_mac_disable (priv); + +/* set mac address */ +writel_be ((pdata->enetaddr[2 ] <<24 ) | (pdata->enetaddr[3 ]) <<16 | + (pdata->enetaddr[4 ]) <<8 | (pdata->enetaddr[5 ]), + priv->base +ETH_PML_REG (0 )); +writel_be ((pdata->enetaddr[1 ]) | (pdata->enetaddr[0 ] <<8 ) | +ETH_PMH_VALID_MASK , priv->base +ETH_PMH_REG (0 )); + +/* enable emac */ +if (running) +bcm6348_eth_mac_enable (priv); + +return 0 ; +} + +static const struct eth_ops bcm6348_eth_ops = { + .free_pkt = bcm6348_eth_free_pkt, + .recv = bcm6348_eth_recv, + .send = bcm6348_eth_send, + .start = bcm6348_eth_start, + .stop = bcm6348_eth_stop, + .write_hwaddr = bcm6348_eth_write_hwaddr, +}; + +static const struct udevice_id bcm6348_eth_ids[] = { + { .compatible ="brcm,bcm6348-enet" , }, + {/* sentinel */ } +}; + +static int bcm6348_mdio_op (void __iomem *base,uint32_t data) +{ +/* make sure mii interrupt status is cleared */ +writel_be (ETH_IR_MII_MASK , base +ETH_IR_REG ); + +/* issue mii op */ +writel_be (data, base +MII_DAT_REG ); + +/* wait until emac is disabled */ +return wait_for_bit_be32 (base +ETH_IR_REG , +ETH_IR_MII_MASK , true, +ETH_TIMEOUT , false); +} + +static int bcm6348_mdio_read (struct mii_dev *bus,int addr,int devaddr, +int reg) +{ +void __iomem *base = bus->priv; +uint32_t val; + + val =MII_DAT_OP_READ ; + val |= (reg <<MII_DAT_REG_SHIFT ) &MII_DAT_REG_MASK ; + val |= (0x2 <<MII_DAT_TA_SHIFT ) &MII_DAT_TA_MASK ; + val |= (addr <<MII_DAT_PHY_SHIFT ) &MII_DAT_PHY_MASK ; + +if (bcm6348_mdio_op (base, val)) { +pr_err ("%s: timeout\n" , __func__); +return -EINVAL ; + } + + val =readl_be (base +MII_DAT_REG ) &MII_DAT_DATA_MASK ; + val >>=MII_DAT_DATA_SHIFT ; + +return val; +} + +static int bcm6348_mdio_write (struct mii_dev *bus,int addr,int dev_addr, +int reg,u16 value) +{ +void __iomem *base = bus->priv; +uint32_t val; + + val =MII_DAT_OP_WRITE ; + val |= (reg <<MII_DAT_REG_SHIFT ) &MII_DAT_REG_MASK ; + val |= (0x2 <<MII_DAT_TA_SHIFT ) &MII_DAT_TA_MASK ; + val |= (addr <<MII_DAT_PHY_SHIFT ) &MII_DAT_PHY_MASK ; + val |= (value <<MII_DAT_DATA_SHIFT ) &MII_DAT_DATA_MASK ; + +if (bcm6348_mdio_op (base, val)) { +pr_err ("%s: timeout\n" , __func__); +return -EINVAL ; + } + +return 0 ; +} + +static int bcm6348_mdio_init (const char *name,void __iomem *base) +{ +struct mii_dev *bus; + + bus =mdio_alloc (); +if (!bus) { +pr_err ("%s: failed to allocate MDIO bus\n" , __func__); +return -ENOMEM ; + } + + bus->read = bcm6348_mdio_read; + bus->write = bcm6348_mdio_write; + bus->priv = base; +snprintf (bus->name,sizeof (bus->name),"%s" , name); + +return mdio_register (bus); +} + +static int bcm6348_phy_init (struct udevice *dev) +{ +struct eth_pdata *pdata =dev_get_platdata (dev); +struct bcm6348_eth_priv *priv =dev_get_priv (dev); +struct mii_dev *bus; + +/* get mii bus */ + bus =miiphy_get_dev_by_name (dev->name); + +/* phy connect */ + priv->phy_dev =phy_connect (bus, priv->phy_id, dev, + pdata->phy_interface); +if (!priv->phy_dev) { +pr_err ("%s: no phy device\n" , __func__); +return -ENODEV ; + } + + priv->phy_dev->supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_Pause | +SUPPORTED_MII ); + priv->phy_dev->advertising = priv->phy_dev->supported; + +/* phy config */ +phy_config (priv->phy_dev); + +return 0 ; +} + +static int bcm6348_eth_probe (struct udevice *dev) +{ +struct eth_pdata *pdata =dev_get_platdata (dev); +struct bcm6348_eth_priv *priv =dev_get_priv (dev); +void *blob = (void *)gd->fdt_blob; +int node =dev_of_offset (dev); +const char *phy_mode; +fdt_addr_t addr; +int phy_node, ret, i; + +/* get base address */ + addr =devfdt_get_addr (dev); +if (addr ==FDT_ADDR_T_NONE ) +return -EINVAL ; + +/* get phy mode */ + pdata->phy_interface =PHY_INTERFACE_MODE_NONE ; + phy_mode =fdt_getprop (blob, node,"phy-mode" ,NULL ); +if (phy_mode) + pdata->phy_interface =phy_get_interface_by_name (phy_mode); +if (pdata->phy_interface ==PHY_INTERFACE_MODE_NONE ) +return -ENODEV ; + +/* get phy */ + phy_node =fdtdec_lookup_phandle (blob, node,"phy" ); +if (phy_node >=0 ) + priv->phy_id =fdtdec_get_int (blob, phy_node,"reg" ,-1 ); +else +return -EINVAL ; + +/* get dma channels */ + ret =dma_get_by_name (dev,"tx" , &priv->tx_dma); +if (ret) +return -EINVAL ; + + ret =dma_get_by_name (dev,"rx" , &priv->rx_dma); +if (ret) +return -EINVAL ; + +/* try to enable clocks */ +for (i =0 ; ; i++) { +struct clk clk; +int ret; + + ret =clk_get_by_index (dev, i, &clk); +if (ret <0 ) +break ; +if (clk_enable (&clk)) +pr_err ("failed to enable clock %d\n" , i); +clk_free (&clk); + } + +/* try to perform resets */ +for (i =0 ; ; i++) { +struct reset_ctl reset; +int ret; + + ret =reset_get_by_index (dev, i, &reset); +if (ret <0 ) +break ; +if (reset_deassert (&reset)) +pr_err ("failed to deassert reset %d\n" , i); +reset_free (&reset); + } + +/* get base addr */ + priv->base =ioremap (addr,0 ); + pdata->iobase = (phys_addr_t ) priv->base; + +/* disable emac */ +bcm6348_eth_mac_disable (priv); + +/* reset emac */ +bcm6348_eth_mac_reset (priv); + +/* select correct mii interface */ +if (pdata->phy_interface ==PHY_INTERFACE_MODE_INTERNAL ) +clrbits_be32 (priv->base +ETH_CTL_REG ,ETH_CTL_EPHY_MASK ); +else +setbits_be32 (priv->base +ETH_CTL_REG ,ETH_CTL_EPHY_MASK ); + +/* turn on mdc clock */ +writel_be ((0x1f <<MII_SC_MDCFREQDIV_SHIFT ) | +MII_SC_PREAMBLE_EN_MASK , priv->base +MII_SC_REG ); + +/* set mib counters to not clear when read */ +clrbits_be32 (priv->base +MIB_CTL_REG ,MIB_CTL_RDCLEAR_MASK ); + +/* initialize perfect match registers */ +for (i =0 ; i <ETH_PM_CNT ; i++) { +writel_be (0 , priv->base +ETH_PML_REG (i)); +writel_be (0 , priv->base +ETH_PMH_REG (i)); + } + +/* init mii bus */ + ret =bcm6348_mdio_init (dev->name, priv->base); +if (ret) +return ret; + +/* init phy */ + ret =bcm6348_phy_init (dev); +if (ret) +return ret; + +return 0 ; +} + +U_BOOT_DRIVER (bcm6348_eth) = { + .name ="bcm6348_eth" , + .id =UCLASS_ETH , + .of_match = bcm6348_eth_ids, + .ops = &bcm6348_eth_ops, + .platdata_auto_alloc_size =sizeof (struct eth_pdata ), + .priv_auto_alloc_size =sizeof (struct bcm6348_eth_priv ), + .probe = bcm6348_eth_probe, +};include/configs/bmips_common.h +4
-2@@ -7,6 +7,9 @@#ifndef __CONFIG_BMIPS_COMMON_H#define __CONFIG_BMIPS_COMMON_H +/* ETH */ +#define CONFIG_PHY_RESET_DELAY 20 +/* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ 230400, 500000, 1500000 }@@ -17,7 +20,7 @@/* Memory usage */ #define CONFIG_SYS_MAXARGS 24 -#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) +#define CONFIG_SYS_MALLOC_LEN (2 * 1024 * 1024)#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)#define CONFIG_SYS_CBSIZE 512 --2.11.0
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
https://lists.denx.de/listinfo/u-boot
PATCH v5 8/15 net: add support for bcm6348-enet
Hi Joe,
Quoted 270 lines · Joe Hershberger
Quoted 268 lines · Álvaro Fernández Rojas
Signed-off-by Álvaro Fernández Rojas <[email protected]>---
v5: Receive as much packets as possible from bcm6348-eth and cache them innet_rx_packets. This is needed in order to fix flow control issues.
v4: Fix issues reported by Grygorii Strashko and other fixes:
- Copy received dma buffer tonet_rx_packetsin order to avoid possible dma overwrites.
- Reset dma rx channel when sending a new packet to prevent flow control issues.
- Fix packet casting on bcm6348_eth_recv/send.
v3: no changes
v2: selectDMA_CHANNELS.drivers/net/Kconfig | 10 + drivers/net/Makefile | 1 + drivers/net/bcm6348-eth.c | 575 +++++++++++++++++++++++++++++++++++++++++ include/configs/bmips_common.h | 5 +- 4 files changed, 590 insertions(+), 1 deletion(-)create mode 100644
drivers/net/bcm6348-eth.cdrivers/net/Kconfig +10
-0@@ -71,6 +71,16 @@ config BCM_SF2_ETH_GMAC by the BCM_SF2_ETH driver. Say Y to any bcmcygnus based platforms. +config BCM6348_ETH + bool "BCM6348 EMAC support" + depends on DM_ETH && ARCH_BMIPS + select DMA + select DMA_CHANNELS + select MII + select PHYLIB + help + This driver supports the BCM6348 Ethernet MAC. + config DWC_ETH_QOS bool "Synopsys DWC Ethernet QOS device support" depends on DM_ETHdrivers/net/Makefile +1
-0@@ -8,6 +8,7 @@ obj-$(CONFIG_ALTERA_TSE) += altera_tse.o obj-$(CONFIG_AG7XXX) += ag7xxx.o obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o +obj-$(CONFIG_BCM6348_ETH) += bcm6348-eth.o obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o obj-$(CONFIG_DRIVER_AX88180) += ax88180.o obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.odrivers/net/bcm6348-eth.c new file +209
-0@@ -0,0 +1,575 @@ +/* +* Copyright (C) 2018 Álvaro Fernández Rojas <[email protected]> +* +* Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c: +* Copyright (C) 2008 Maxime Bizon <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <dma.h> +#include <miiphy.h> +#include <net.h> +#include <phy.h> +#include <reset.h> +#include <wait_bit.h> +#include <asm/io.h> + +#define ETH_RX_DESC PKTBUFSRX +#define ETH_MAX_MTU_SIZE 1518 +#define ETH_TIMEOUT 100 +#define ETH_TX_WATERMARK 32 + +/* ETH Receiver Configuration register */ +#define ETH_RXCFG_REG 0x00 +#define ETH_RXCFG_ENFLOW_SHIFT 5 +#define ETH_RXCFG_ENFLOW_MASK (1 << ETH_RXCFG_ENFLOW_SHIFT) + +/* ETH Receive Maximum Length register */ +#define ETH_RXMAXLEN_REG 0x04 +#define ETH_RXMAXLEN_SHIFT 0 +#define ETH_RXMAXLEN_MASK (0x7ff << ETH_RXMAXLEN_SHIFT) + +/* ETH Transmit Maximum Length register */ +#define ETH_TXMAXLEN_REG 0x08 +#define ETH_TXMAXLEN_SHIFT 0 +#define ETH_TXMAXLEN_MASK (0x7ff << ETH_TXMAXLEN_SHIFT) + +/* MII Status/Control register */ +#define MII_SC_REG 0x10 +#define MII_SC_MDCFREQDIV_SHIFT 0 +#define MII_SC_MDCFREQDIV_MASK (0x7f << MII_SC_MDCFREQDIV_SHIFT) +#define MII_SC_PREAMBLE_EN_SHIFT 7 +#define MII_SC_PREAMBLE_EN_MASK (1 << MII_SC_PREAMBLE_EN_SHIFT) + +/* MII Data register */ +#define MII_DAT_REG 0x14 +#define MII_DAT_DATA_SHIFT 0 +#define MII_DAT_DATA_MASK (0xffff << MII_DAT_DATA_SHIFT) +#define MII_DAT_TA_SHIFT 16 +#define MII_DAT_TA_MASK (0x3 << MII_DAT_TA_SHIFT) +#define MII_DAT_REG_SHIFT 18 +#define MII_DAT_REG_MASK (0x1f << MII_DAT_REG_SHIFT) +#define MII_DAT_PHY_SHIFT 23 +#define MII_DAT_PHY_MASK (0x1f << MII_DAT_PHY_SHIFT) +#define MII_DAT_OP_SHIFT 28 +#define MII_DAT_OP_WRITE (0x5 << MII_DAT_OP_SHIFT) +#define MII_DAT_OP_READ (0x6 << MII_DAT_OP_SHIFT) + +/* ETH Interrupts Mask register */ +#define ETH_IRMASK_REG 0x18 + +/* ETH Interrupts register */ +#define ETH_IR_REG 0x1c +#define ETH_IR_MII_SHIFT 0 +#define ETH_IR_MII_MASK (1 << ETH_IR_MII_SHIFT) + +/* ETH Control register */ +#define ETH_CTL_REG 0x2c +#define ETH_CTL_ENABLE_SHIFT 0 +#define ETH_CTL_ENABLE_MASK (1 << ETH_CTL_ENABLE_SHIFT) +#define ETH_CTL_DISABLE_SHIFT 1 +#define ETH_CTL_DISABLE_MASK (1 << ETH_CTL_DISABLE_SHIFT) +#define ETH_CTL_RESET_SHIFT 2 +#define ETH_CTL_RESET_MASK (1 << ETH_CTL_RESET_SHIFT) +#define ETH_CTL_EPHY_SHIFT 3 +#define ETH_CTL_EPHY_MASK (1 << ETH_CTL_EPHY_SHIFT) + +/* ETH Transmit Control register */ +#define ETH_TXCTL_REG 0x30 +#define ETH_TXCTL_FD_SHIFT 0 +#define ETH_TXCTL_FD_MASK (1 << ETH_TXCTL_FD_SHIFT) + +/* ETH Transmit Watermask register */ +#define ETH_TXWMARK_REG 0x34 +#define ETH_TXWMARK_WM_SHIFT 0 +#define ETH_TXWMARK_WM_MASK (0x3f << ETH_TXWMARK_WM_SHIFT) + +/* MIB Control register */ +#define MIB_CTL_REG 0x38 +#define MIB_CTL_RDCLEAR_SHIFT 0 +#define MIB_CTL_RDCLEAR_MASK (1 << MIB_CTL_RDCLEAR_SHIFT) + +/* ETH Perfect Match registers */ +#define ETH_PM_CNT 4 +#define ETH_PML_REG (x) (0x58 + (x) * 0x8) +#define ETH_PMH_REG (x) (0x5c + (x) * 0x8) +#define ETH_PMH_VALID_SHIFT 16 +#define ETH_PMH_VALID_MASK (1 << ETH_PMH_VALID_SHIFT) + +/* MIB Counters registers */ +#define MIB_REG_CNT 55 +#define MIB_REG (x) (0x200 + (x) * 4) + +/* ETH data */ +struct bcm6348_eth_priv { +void __iomem *base; +/* RX */ +uint8_t rx_desc; +uint8_t rx_pend; +int rx_ret[ETH_RX_DESC ]; +/* DMA */ +struct dma rx_dma; +struct dma tx_dma; +/* PHY */ +int phy_id; +struct phy_device *phy_dev; +}; + +DECLARE_GLOBAL_DATA_PTR ; + +static void bcm6348_eth_mac_disable (struct bcm6348_eth_priv *priv) +{ +/* disable emac */ +clrsetbits_be32 (priv->base +ETH_CTL_REG ,ETH_CTL_ENABLE_MASK , +ETH_CTL_DISABLE_MASK ); + +/* wait until emac is disabled */ +if (wait_for_bit_be32 (priv->base +ETH_CTL_REG , +ETH_CTL_DISABLE_MASK , false, +ETH_TIMEOUT , false)) +pr_err ("error disabling emac\n" ); +} + +static void bcm6348_eth_mac_enable (struct bcm6348_eth_priv *priv) +{ +setbits_be32 (priv->base +ETH_CTL_REG ,ETH_CTL_ENABLE_MASK ); +} + +static void bcm6348_eth_mac_reset (struct bcm6348_eth_priv *priv) +{ +/* reset emac */ +writel_be (ETH_CTL_RESET_MASK , priv->base +ETH_CTL_REG ); +wmb (); + +/* wait until emac is reset */ +if (wait_for_bit_be32 (priv->base +ETH_CTL_REG , +ETH_CTL_RESET_MASK , false, +ETH_TIMEOUT , false)) +pr_err ("error resetting emac\n" ); +} + +static int bcm6348_eth_free_pkt (struct udevice *dev,uchar *packet,int len) +{ +struct bcm6348_eth_priv *priv =dev_get_priv (dev); + +/* sanity check */ +if (packet != net_rx_packets[priv->rx_pend]) { +pr_err ("rx_pend %d: packet is not matched,\n" , priv->rx_pend); +return -EAGAIN ; + } + +/* free pending packet */ + priv->rx_ret[priv->rx_pend] =0 ; + priv->rx_pend = (priv->rx_pend +1 ) %ETH_RX_DESC ; + +return 0 ; +} + +static int _bcm6348_eth_recv (struct bcm6348_eth_priv *priv) +{ +uint8_t pkt = priv->rx_desc; + +/* check if packet is free */ +if (priv->rx_ret[pkt] >0 ) +return -EAGAIN ; + +/* try to receive a new packet */ + priv->rx_ret[pkt] =dma_receive (&priv->rx_dma, + (void **)&net_rx_packets[pkt]); +if (priv->rx_ret[pkt] >0 ) + priv->rx_desc = (priv->rx_desc +1 ) %ETH_RX_DESC ; + +return priv->rx_ret[pkt]; +} + +static int bcm6348_eth_recv (struct udevice *dev,int flags,uchar **packetp) +{ +struct bcm6348_eth_priv *priv =dev_get_priv (dev); +uint8_t pkt_cnt =0 ; +int ret; + +/* try to receive packets */ +while (_bcm6348_eth_recv (priv) >0 ) + pkt_cnt++; + +if (pkt_cnt) +debug ("%s: received %u packet(s)\n" , __func__, pkt_cnt); + +/* return current packet */ + ret = priv->rx_ret[priv->rx_pend]; +if (ret >0 ) + *packetp = net_rx_packets[priv->rx_pend]; + +return ret; +} +
Quoted 8 lines
drivers/net/bcm6348-eth.c line 216
Quoted 7 lines
drivers/net/bcm6348-eth.c new file +7
-0+static int bcm6348_eth_send (struct udevice *dev,void *packet,int length) +{ +struct bcm6348_eth_priv *priv =dev_get_priv (dev); + +/* reset dma rx channel */ +dma_disable (&priv->rx_dma); +dma_enable (&priv->rx_dma);Why. Please include reasoning in the comment.
For what I've seen flow control is a bit tricky on this dma controller and when you don't process a received packet in a short period of time, it may get into a an state where no new packets are correctly received. However, resetting the dma channel here prevents that from hapenning.
Quoted 383 lines
Quoted 383 lines
drivers/net/bcm6348-eth.c new file +359
-0+ +return dma_send (&priv->tx_dma, (void *)packet, length); +} + +static int bcm6348_eth_adjust_link (struct udevice *dev, +struct phy_device *phydev) +{ +struct bcm6348_eth_priv *priv =dev_get_priv (dev); + +/* mac duplex parameters */ +if (phydev->duplex) +setbits_be32 (priv->base +ETH_TXCTL_REG ,ETH_TXCTL_FD_MASK ); +else +clrbits_be32 (priv->base +ETH_TXCTL_REG ,ETH_TXCTL_FD_MASK ); + +/* rx flow control (pause frame handling) */ +if (phydev->pause) +setbits_be32 (priv->base +ETH_RXCFG_REG , +ETH_RXCFG_ENFLOW_MASK ); +else +clrbits_be32 (priv->base +ETH_RXCFG_REG , +ETH_RXCFG_ENFLOW_MASK ); + +return 0 ; +} + +static int bcm6348_eth_start (struct udevice *dev) +{ +struct bcm6348_eth_priv *priv =dev_get_priv (dev); +int ret, i; + + priv->rx_desc =0 ; + priv->rx_pend =0 ; +for (i =0 ; i <ETH_RX_DESC ; i++) + priv->rx_ret[i] =0 ; + +/* enable dma rx channel */ +dma_enable (&priv->rx_dma); + +/* enable dma tx channel */ +dma_enable (&priv->tx_dma); + + ret =phy_startup (priv->phy_dev); +if (ret) { +pr_err ("could not initialize phy\n" ); +return ret; + } + +if (!priv->phy_dev->link) { +pr_err ("no phy link\n" ); +return -EIO ; + } + +bcm6348_eth_adjust_link (dev, priv->phy_dev); + +/* zero mib counters */ +for (i =0 ; i <MIB_REG_CNT ; i++) +writel_be (0 ,MIB_REG (i)); + +/* enable rx flow control */ +setbits_be32 (priv->base +ETH_RXCFG_REG ,ETH_RXCFG_ENFLOW_MASK ); + +/* set max rx/tx length */ +writel_be ((ETH_MAX_MTU_SIZE <<ETH_RXMAXLEN_SHIFT ) & +ETH_RXMAXLEN_MASK , priv->base +ETH_RXMAXLEN_REG ); +writel_be ((ETH_MAX_MTU_SIZE <<ETH_TXMAXLEN_SHIFT ) & +ETH_TXMAXLEN_MASK , priv->base +ETH_TXMAXLEN_REG ); + +/* set correct transmit fifo watermark */ +writel_be ((ETH_TX_WATERMARK <<ETH_TXWMARK_WM_SHIFT ) & +ETH_TXWMARK_WM_MASK , priv->base +ETH_TXWMARK_REG ); + +/* enable emac */ +bcm6348_eth_mac_enable (priv); + +/* clear interrupts */ +writel_be (0 , priv->base +ETH_IRMASK_REG ); + +return 0 ; +} + +static void bcm6348_eth_stop (struct udevice *dev) +{ +struct bcm6348_eth_priv *priv =dev_get_priv (dev); + +/* disable dma rx channel */ +dma_disable (&priv->rx_dma); + +/* disable dma tx channel */ +dma_disable (&priv->tx_dma); + +/* disable emac */ +bcm6348_eth_mac_disable (priv); +} + +static int bcm6348_eth_write_hwaddr (struct udevice *dev) +{ +struct eth_pdata *pdata =dev_get_platdata (dev); +struct bcm6348_eth_priv *priv =dev_get_priv (dev); +bool running = false; + +/* check if emac is running */ +if (readl_be (priv->base +ETH_CTL_REG ) Ð_CTL_ENABLE_MASK ) + running = true; + +/* disable emac */ +if (running) +bcm6348_eth_mac_disable (priv); + +/* set mac address */ +writel_be ((pdata->enetaddr[2 ] <<24 ) | (pdata->enetaddr[3 ]) <<16 | + (pdata->enetaddr[4 ]) <<8 | (pdata->enetaddr[5 ]), + priv->base +ETH_PML_REG (0 )); +writel_be ((pdata->enetaddr[1 ]) | (pdata->enetaddr[0 ] <<8 ) | +ETH_PMH_VALID_MASK , priv->base +ETH_PMH_REG (0 )); + +/* enable emac */ +if (running) +bcm6348_eth_mac_enable (priv); + +return 0 ; +} + +static const struct eth_ops bcm6348_eth_ops = { + .free_pkt = bcm6348_eth_free_pkt, + .recv = bcm6348_eth_recv, + .send = bcm6348_eth_send, + .start = bcm6348_eth_start, + .stop = bcm6348_eth_stop, + .write_hwaddr = bcm6348_eth_write_hwaddr, +}; + +static const struct udevice_id bcm6348_eth_ids[] = { + { .compatible ="brcm,bcm6348-enet" , }, + {/* sentinel */ } +}; + +static int bcm6348_mdio_op (void __iomem *base,uint32_t data) +{ +/* make sure mii interrupt status is cleared */ +writel_be (ETH_IR_MII_MASK , base +ETH_IR_REG ); + +/* issue mii op */ +writel_be (data, base +MII_DAT_REG ); + +/* wait until emac is disabled */ +return wait_for_bit_be32 (base +ETH_IR_REG , +ETH_IR_MII_MASK , true, +ETH_TIMEOUT , false); +} + +static int bcm6348_mdio_read (struct mii_dev *bus,int addr,int devaddr, +int reg) +{ +void __iomem *base = bus->priv; +uint32_t val; + + val =MII_DAT_OP_READ ; + val |= (reg <<MII_DAT_REG_SHIFT ) &MII_DAT_REG_MASK ; + val |= (0x2 <<MII_DAT_TA_SHIFT ) &MII_DAT_TA_MASK ; + val |= (addr <<MII_DAT_PHY_SHIFT ) &MII_DAT_PHY_MASK ; + +if (bcm6348_mdio_op (base, val)) { +pr_err ("%s: timeout\n" , __func__); +return -EINVAL ; + } + + val =readl_be (base +MII_DAT_REG ) &MII_DAT_DATA_MASK ; + val >>=MII_DAT_DATA_SHIFT ; + +return val; +} + +static int bcm6348_mdio_write (struct mii_dev *bus,int addr,int dev_addr, +int reg,u16 value) +{ +void __iomem *base = bus->priv; +uint32_t val; + + val =MII_DAT_OP_WRITE ; + val |= (reg <<MII_DAT_REG_SHIFT ) &MII_DAT_REG_MASK ; + val |= (0x2 <<MII_DAT_TA_SHIFT ) &MII_DAT_TA_MASK ; + val |= (addr <<MII_DAT_PHY_SHIFT ) &MII_DAT_PHY_MASK ; + val |= (value <<MII_DAT_DATA_SHIFT ) &MII_DAT_DATA_MASK ; + +if (bcm6348_mdio_op (base, val)) { +pr_err ("%s: timeout\n" , __func__); +return -EINVAL ; + } + +return 0 ; +} + +static int bcm6348_mdio_init (const char *name,void __iomem *base) +{ +struct mii_dev *bus; + + bus =mdio_alloc (); +if (!bus) { +pr_err ("%s: failed to allocate MDIO bus\n" , __func__); +return -ENOMEM ; + } + + bus->read = bcm6348_mdio_read; + bus->write = bcm6348_mdio_write; + bus->priv = base; +snprintf (bus->name,sizeof (bus->name),"%s" , name); + +return mdio_register (bus); +} + +static int bcm6348_phy_init (struct udevice *dev) +{ +struct eth_pdata *pdata =dev_get_platdata (dev); +struct bcm6348_eth_priv *priv =dev_get_priv (dev); +struct mii_dev *bus; + +/* get mii bus */ + bus =miiphy_get_dev_by_name (dev->name); + +/* phy connect */ + priv->phy_dev =phy_connect (bus, priv->phy_id, dev, + pdata->phy_interface); +if (!priv->phy_dev) { +pr_err ("%s: no phy device\n" , __func__); +return -ENODEV ; + } + + priv->phy_dev->supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_Pause | +SUPPORTED_MII ); + priv->phy_dev->advertising = priv->phy_dev->supported; + +/* phy config */ +phy_config (priv->phy_dev); + +return 0 ; +} + +static int bcm6348_eth_probe (struct udevice *dev) +{ +struct eth_pdata *pdata =dev_get_platdata (dev); +struct bcm6348_eth_priv *priv =dev_get_priv (dev); +void *blob = (void *)gd->fdt_blob; +int node =dev_of_offset (dev); +const char *phy_mode; +fdt_addr_t addr; +int phy_node, ret, i; + +/* get base address */ + addr =devfdt_get_addr (dev); +if (addr ==FDT_ADDR_T_NONE ) +return -EINVAL ; + +/* get phy mode */ + pdata->phy_interface =PHY_INTERFACE_MODE_NONE ; + phy_mode =fdt_getprop (blob, node,"phy-mode" ,NULL ); +if (phy_mode) + pdata->phy_interface =phy_get_interface_by_name (phy_mode); +if (pdata->phy_interface ==PHY_INTERFACE_MODE_NONE ) +return -ENODEV ; + +/* get phy */ + phy_node =fdtdec_lookup_phandle (blob, node,"phy" ); +if (phy_node >=0 ) + priv->phy_id =fdtdec_get_int (blob, phy_node,"reg" ,-1 ); +else +return -EINVAL ; + +/* get dma channels */ + ret =dma_get_by_name (dev,"tx" , &priv->tx_dma); +if (ret) +return -EINVAL ; + + ret =dma_get_by_name (dev,"rx" , &priv->rx_dma); +if (ret) +return -EINVAL ; + +/* try to enable clocks */ +for (i =0 ; ; i++) { +struct clk clk; +int ret; + + ret =clk_get_by_index (dev, i, &clk); +if (ret <0 ) +break ; +if (clk_enable (&clk)) +pr_err ("failed to enable clock %d\n" , i); +clk_free (&clk); + } + +/* try to perform resets */ +for (i =0 ; ; i++) { +struct reset_ctl reset; +int ret; + + ret =reset_get_by_index (dev, i, &reset); +if (ret <0 ) +break ; +if (reset_deassert (&reset)) +pr_err ("failed to deassert reset %d\n" , i); +reset_free (&reset); + } + +/* get base addr */ + priv->base =ioremap (addr,0 ); + pdata->iobase = (phys_addr_t ) priv->base; + +/* disable emac */ +bcm6348_eth_mac_disable (priv); + +/* reset emac */ +bcm6348_eth_mac_reset (priv); + +/* select correct mii interface */ +if (pdata->phy_interface ==PHY_INTERFACE_MODE_INTERNAL ) +clrbits_be32 (priv->base +ETH_CTL_REG ,ETH_CTL_EPHY_MASK ); +else +setbits_be32 (priv->base +ETH_CTL_REG ,ETH_CTL_EPHY_MASK ); + +/* turn on mdc clock */ +writel_be ((0x1f <<MII_SC_MDCFREQDIV_SHIFT ) | +MII_SC_PREAMBLE_EN_MASK , priv->base +MII_SC_REG ); + +/* set mib counters to not clear when read */ +clrbits_be32 (priv->base +MIB_CTL_REG ,MIB_CTL_RDCLEAR_MASK ); + +/* initialize perfect match registers */ +for (i =0 ; i <ETH_PM_CNT ; i++) { +writel_be (0 , priv->base +ETH_PML_REG (i)); +writel_be (0 , priv->base +ETH_PMH_REG (i)); + } + +/* init mii bus */ + ret =bcm6348_mdio_init (dev->name, priv->base); +if (ret) +return ret; + +/* init phy */ + ret =bcm6348_phy_init (dev); +if (ret) +return ret; + +return 0 ; +} + +U_BOOT_DRIVER (bcm6348_eth) = { + .name ="bcm6348_eth" , + .id =UCLASS_ETH , + .of_match = bcm6348_eth_ids, + .ops = &bcm6348_eth_ops, + .platdata_auto_alloc_size =sizeof (struct eth_pdata ), + .priv_auto_alloc_size =sizeof (struct bcm6348_eth_priv ), + .probe = bcm6348_eth_probe, +};include/configs/bmips_common.h +4
-1@@ -7,6 +7,9 @@#ifndef __CONFIG_BMIPS_COMMON_H#define __CONFIG_BMIPS_COMMON_H +/* ETH */ +#define CONFIG_PHY_RESET_DELAY 20 +/* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ 230400, 500000, 1500000 }@@ -17,7 +20,7 @@/* Memory usage */ #define CONFIG_SYS_MAXARGS 24 -#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) +#define CONFIG_SYS_MALLOC_LEN (2 * 1024 * 1024)#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)#define CONFIG_SYS_CBSIZE 512
Quoted 7 lines
Quoted 7 lines
--
2.11.0_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
https://lists.denx.de/listinfo/u-boot
~Álvaro.
PATCH v5 9/15 bmips: bcm6338: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6338.dtsi | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
arch/mips/dts/brcm,bcm6338.dtsi +15 -0
@@ -145,5 +145,20 @@ dma-channels = <6>; resets = <&periph_rst BCM6338_RST_DMAMEM>; }; + + enet: ethernet at fffe2800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe2800 0x2dc>; + clocks = <&periph_clk BCM6338_CLK_ENET>; + resets = <&periph_rst BCM6338_RST_ENET>; + dmas = <&iudma BCM6338_DMA_ENET_RX>, + <&iudma BCM6338_DMA_ENET_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; }; };
Signature · 1 line
2.11.0
PATCH v5 10/15 bmips: enable f@st1704 enet support
In reply to Álvaro Fernández Rojas---
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/sagem,f at st1704.dts | 12 ++++++++++++ configs/sagem_f at st1704_ram_defconfig | 9 ++++++++- 2 files changed, 20 insertions(+), 1 deletion(-)
arch/mips/dts/sagem,f at st1704.dts +12 -0
@@ -40,6 +40,18 @@ }; }; +&enet { + status = "okay"; + phy = <&enetphy>; + phy-mode = "mii"; + + enetphy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio { status = "okay"; };
configs/sagem_f at st1704_ram_defconfig +8 -1
@@ -28,11 +28,15 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_SF=y CONFIG_CMD_SPI=y -# CONFIG_CMD_NET is not set +CONFIG_CMD_DHCP=y # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -41,6 +45,9 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_DM_RESET=y CONFIG_RESET_BCM6345=y # CONFIG_SPL_SERIAL_PRESENT is not set
Signature · 1 line
2.11.0
PATCH v5 11/15 bmips: bcm6348: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6348.dtsi | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
arch/mips/dts/brcm,bcm6348.dtsi +26 -0
@@ -162,6 +162,32 @@ u-boot,dm-pre-reloc; }; + enet0: ethernet at fffe6000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6000 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET0_RX>, + <&iudma BCM6348_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet at fffe6800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6800 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET1_RX>, + <&iudma BCM6348_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + iudma: dma-controller at fffe7000 { compatible = "brcm,bcm6348-iudma"; reg = <0xfffe7000 0x1c>,
Signature · 1 line
2.11.0
PATCH v5 12/15 bmips: enable ct-5361 enet support
In reply to Álvaro Fernández Rojas---
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/comtrend,ct-5361.dts | 12 ++++++++++++ configs/comtrend_ct5361_ram_defconfig | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
arch/mips/dts/comtrend,ct-5361.dts +12 -0
@@ -35,6 +35,18 @@ }; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/comtrend_ct5361_ram_defconfig +7 -1
@@ -26,11 +26,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -38,6 +41,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6348_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
PATCH v5 13/15 bmips: bcm6358: add support for bcm6348-enet
In reply to Álvaro Fernández Rojas---
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6358.dtsi | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
arch/mips/dts/brcm,bcm6358.dtsi +28 -0
@@ -193,6 +193,34 @@ status = "disabled"; }; + enet0: ethernet at fffe4000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4000 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET0>; + dmas = <&iudma BCM6358_DMA_ENET0_RX>, + <&iudma BCM6358_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet at fffe4800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4800 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET1>; + dmas = <&iudma BCM6358_DMA_ENET1_RX>, + <&iudma BCM6358_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + iudma: dma-controller at fffe5000 { compatible = "brcm,bcm6348-iudma"; reg = <0xfffe5000 0x24>,
Signature · 1 line
2.11.0
PATCH v5 14/15 bmips: enable hg556a enet support
In reply to Álvaro Fernández Rojas---
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/huawei,hg556a.dts | 12 ++++++++++++ configs/huawei_hg556a_ram_defconfig | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
arch/mips/dts/huawei,hg556a.dts +12 -0
@@ -94,6 +94,18 @@ status = "okay"; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/huawei_hg556a_ram_defconfig +7 -1
@@ -26,11 +26,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -38,6 +41,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6358_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0
PATCH v5 15/15 bmips: enable nb4-ser enet support
In reply to Álvaro Fernández Rojas---
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/sfr,nb4-ser.dts | 24 ++++++++++++++++++++++++ configs/sfr_nb4-ser_ram_defconfig | 8 +++++++- 2 files changed, 31 insertions(+), 1 deletion(-)
arch/mips/dts/sfr,nb4-ser.dts +24 -0
@@ -54,6 +54,30 @@ status = "okay"; }; +&enet0 { + status = "okay"; + phy = <&enet0phy>; + phy-mode = "internal"; + + enet0phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; };
configs/sfr_nb4-ser_ram_defconfig +7 -1
@@ -27,11 +27,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FPGA is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y
@@ -40,6 +43,9 @@ CONFIG_LED_GPIO=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_CFI_FLASH=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6358_USBH_PHY=y CONFIG_DM_RESET=y
Signature · 1 line
2.11.0