* [U-Boot] [PATCH v8 01/31] dma: move dma_ops to dma-uclass.h
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 02/31] dma: add channels support Álvaro Fernández Rojas
` (32 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Move dma_ops to a separate header file, following other uclass
implementations. While doing so, this patch also improves dma_ops
documentation.
Reviewed-by: Tom Rini <trini@konsulko.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
v8: no changes
v7: From Grygorii Strashko:
- copyright fixed as suggested by Tom Rini
- added "Reviewed-by" tags
v6: no changes
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
diff --git a/drivers/dma/dma-uclass.c b/drivers/dma/dma-uclass.c
index a33f7d52da..6c3506c302 100644
--- a/drivers/dma/dma-uclass.c
+++ b/drivers/dma/dma-uclass.c
@@ -9,10 +9,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>
int dma_get_device(u32 transfer_type, struct udevice **devp)
diff --git a/drivers/dma/ti-edma3.c b/drivers/dma/ti-edma3.c
index 2131e10a40..7e11b13e45 100644
--- a/drivers/dma/ti-edma3.c
+++ b/drivers/dma/ti-edma3.c
@@ -11,7 +11,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>
diff --git a/include/dma-uclass.h b/include/dma-uclass.h
new file mode 100644
index 0000000000..7bec5d3399
--- /dev/null
+++ b/include/dma-uclass.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com>
+ * Written by Mugunthan V N <mugunthanvnm@ti.com>
+ *
+ */
+
+#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 */
diff --git a/include/dma.h b/include/dma.h
index 50e965241c..97fa0cf695 100644
--- a/include/dma.h
+++ b/include/dma.h
@@ -27,28 +27,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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 02/31] dma: add channels support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 01/31] dma: move dma_ops to dma-uclass.h Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 03/31] test: dma: add dma-uclass test Álvaro Fernández Rojas
` (31 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
This adds channels support for dma controllers that have multiple channels
which can transfer data to/from different devices (enet, usb...).
DMA channle API:
dma_get_by_index()
dma_get_by_name()
dma_request()
dma_free()
dma_enable()
dma_disable()
dma_prepare_rcv_buf()
dma_receive()
dma_send()
Reviewed-by: Tom Rini <trini@konsulko.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
[grygorii.strashko at ti.com: drop unused dma_get_by_index_platdata(),
add metadata to send/receive ops, add dma_prepare_rcv_buf(),
minor clean up]
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
v8: no changes
v7: From Grygorii Strashko:
- copyright fixed as suggested by Tom Rini
- added "Reviewed-by" tags
v6: From Grygorii Strashko:
- added possibility to pass DMA driver/channel's specific data per each
transfer using additional parameter "metadata" in dma_send/dma_receive() API.
For example, port number for network packets to be directed to the
specific port on multi port ethernet controllers.
- added new dma_prepare_rcv_buf() API which allows to implement zero-copy
DEV_TO_MEM transfer using DMA streaming channels which is usual case
for Networking.
- removed unused function dma_get_by_index_platdata()
- updated comments
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 | 181 ++++++++++++++++++++++++++++++++-
include/dma-uclass.h | 91 ++++++++++++++++-
include/dma.h | 260 ++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 532 insertions(+), 7 deletions(-)
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 4ee6afad35..b9b85c65fc 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -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
diff --git a/drivers/dma/dma-uclass.c b/drivers/dma/dma-uclass.c
index 6c3506c302..9c961cf1e2 100644
--- a/drivers/dma/dma-uclass.c
+++ b/drivers/dma/dma-uclass.c
@@ -2,19 +2,192 @@
/*
* Direct Memory Access U-Class driver
*
- * (C) Copyright 2015
- * Texas Instruments Incorporated, <www.ti.com>
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2015 - 2018 Texas Instruments Incorporated <www.ti.com>
+ * Written by Mugunthan V N <mugunthanvnm@ti.com>
*
* Author: Mugunthan V N <mugunthanvnm@ti.com>
*/
#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>
+#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)
+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);
+}
+
+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_prepare_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+ struct dma_ops *ops = dma_dev_ops(dma->dev);
+
+ debug("%s(dma=%p)\n", __func__, dma);
+
+ if (!ops->prepare_rcv_buf)
+ return -1;
+
+ return ops->prepare_rcv_buf(dma, dst, size);
+}
+
+int dma_receive(struct dma *dma, void **dst, void *metadata)
+{
+ struct dma_ops *ops = dma_dev_ops(dma->dev);
+
+ debug("%s(dma=%p)\n", __func__, dma);
+
+ if (!ops->receive)
+ return -ENOSYS;
+
+ return ops->receive(dma, dst, metadata);
+}
+
+int dma_send(struct dma *dma, void *src, size_t len, void *metadata)
+{
+ struct dma_ops *ops = dma_dev_ops(dma->dev);
+
+ debug("%s(dma=%p)\n", __func__, dma);
+
+ if (!ops->send)
+ return -ENOSYS;
+
+ return ops->send(dma, src, len, metadata);
+}
+#endif /* CONFIG_DMA_CHANNELS */
+
int dma_get_device(u32 transfer_type, struct udevice **devp)
{
struct udevice *dev;
diff --git a/include/dma-uclass.h b/include/dma-uclass.h
index 7bec5d3399..16fc879a5c 100644
--- a/include/dma-uclass.h
+++ b/include/dma-uclass.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
- * Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com>
+ * Copyright (C) 2015 - 2018 Texas Instruments Incorporated <www.ti.com>
* Written by Mugunthan V N <mugunthanvnm@ti.com>
*
*/
@@ -13,6 +13,8 @@
#include <dma.h>
+struct ofnode_phandle_args;
+
/*
* struct dma_ops - Driver model DMA operations
*
@@ -20,6 +22,93 @@
* 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);
+ /**
+ * add_rcv_buf() - Prepare/Add receive DMA buffer.
+ *
+ * @dma: The DMA Channel to manipulate.
+ * @dst: The receive buffer pointer.
+ * @size: The receive buffer size
+ * @return zero on success, or -ve error code.
+ */
+ int (*prepare_rcv_buf)(struct dma *dma, void *dst, size_t size);
+ /**
+ * receive() - Receive a DMA transfer.
+ *
+ * @dma: The DMA Channel to manipulate.
+ * @dst: The destination pointer.
+ * @metadata: DMA driver's specific data
+ * @return zero on success, or -ve error code.
+ */
+ int (*receive)(struct dma *dma, void **dst, void *metadata);
+ /**
+ * 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).
+ * @metadata: DMA driver's specific data
+ * @return zero on success, or -ve error code.
+ */
+ int (*send)(struct dma *dma, void *src, size_t len, void *metadata);
+#endif /* CONFIG_DMA_CHANNELS */
/**
* transfer() - Issue a DMA transfer. The implementation must
* wait until the transfer is done.
diff --git a/include/dma.h b/include/dma.h
index 97fa0cf695..d1c3d0df7d 100644
--- a/include/dma.h
+++ b/include/dma.h
@@ -1,12 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * (C) Copyright 2015
- * Texas Instruments Incorporated, <www.ti.com>
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2015 - 2018 Texas Instruments Incorporated <www.ti.com>
+ * Written by Mugunthan V N <mugunthanvnm@ti.com>
+ *
*/
#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
@@ -36,6 +41,257 @@ 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.
+ *
+ * DMA consumer DMA_MEM_TO_DEV (transmit) usage example (based on networking).
+ * Note. dma_send() is sync operation always - it'll start transfer and will
+ * poll for it to complete:
+ * - get/request dma channel
+ * struct dma dma_tx;
+ * ret = dma_get_by_name(common->dev, "tx0", &dma_tx);
+ * if (ret) ...
+ *
+ * - enable dma channel
+ * ret = dma_enable(&dma_tx);
+ * if (ret) ...
+ *
+ * - dma transmit DMA_MEM_TO_DEV.
+ * struct ti_drv_packet_data packet_data;
+ *
+ * packet_data.opt1 = val1;
+ * packet_data.opt2 = val2;
+ * ret = dma_send(&dma_tx, packet, length, &packet_data);
+ * if (ret) ..
+ *
+ * DMA consumer DMA_DEV_TO_MEM (receive) usage example (based on networking).
+ * Note. dma_receive() is sync operation always - it'll start transfer
+ * (if required) and will poll for it to complete (or for any previously
+ * configured dev2mem transfer to complete):
+ * - get/request dma channel
+ * struct dma dma_rx;
+ * ret = dma_get_by_name(common->dev, "rx0", &dma_rx);
+ * if (ret) ...
+ *
+ * - enable dma channel
+ * ret = dma_enable(&dma_rx);
+ * if (ret) ...
+ *
+ * - dma receive DMA_DEV_TO_MEM.
+ * struct ti_drv_packet_data packet_data;
+ *
+ * len = dma_receive(&dma_rx, (void **)packet, &packet_data);
+ * if (ret < 0) ...
+ *
+ * DMA consumer DMA_DEV_TO_MEM (receive) zero-copy usage example (based on
+ * networking). Networking subsystem allows to configure and use few receive
+ * buffers (dev2mem), as Networking RX DMA channels usually implemented
+ * as streaming interface
+ * - get/request dma channel
+ * struct dma dma_rx;
+ * ret = dma_get_by_name(common->dev, "rx0", &dma_rx);
+ * if (ret) ...
+ *
+ * for (i = 0; i < RX_DESC_NUM; i++) {
+ * ret = dma_prepare_rcv_buf(&dma_rx,
+ * net_rx_packets[i],
+ * RX_BUF_SIZE);
+ * if (ret) ...
+ * }
+ *
+ * - enable dma channel
+ * ret = dma_enable(&dma_rx);
+ * if (ret) ...
+ *
+ * - dma receive DMA_DEV_TO_MEM.
+ * struct ti_drv_packet_data packet_data;
+ *
+ * len = dma_receive(&dma_rx, (void **)packet, &packet_data);
+ * if (ret < 0) ..
+ *
+ * -- process packet --
+ *
+ * - return buffer back to DAM channel
+ * ret = dma_prepare_rcv_buf(&dma_rx,
+ * net_rx_packets[rx_next],
+ * RX_BUF_SIZE);
+ */
+
+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)
+/**
+ * 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_prepare_rcv_buf() - Prepare/add receive DMA buffer.
+ *
+ * It allows to implement zero-copy async DMA_DEV_TO_MEM (receive) transactions
+ * if supported by DMA providers.
+ *
+ * @dma: A DMA struct that was previously successfully requested by
+ * dma_request/get_by_*().
+ * @dst: The receive buffer pointer.
+ * @size: The receive buffer size
+ * @return zero on success, or -ve error code.
+ */
+int dma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size);
+
+/**
+ * dma_receive() - Receive a DMA transfer.
+ *
+ * @dma: A DMA struct that was previously successfully requested by
+ * dma_request/get_by_*().
+ * @dst: The destination pointer.
+ * @metadata: DMA driver's channel specific data
+ * @return length of received data on success, or zero - no data,
+ * or -ve error code.
+ */
+int dma_receive(struct dma *dma, void **dst, void *metadata);
+
+/**
+ * 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).
+ * @metadata: DMA driver's channel specific data
+ * @return zero on success, or -ve error code.
+ */
+int dma_send(struct dma *dma, void *src, size_t len, void *metadata);
+#endif /* CONFIG_DMA_CHANNELS */
+
/*
* dma_get_device - get a DMA device which supports transfer
* type of transfer_type
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 03/31] test: dma: add dma-uclass test
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 01/31] dma: move dma_ops to dma-uclass.h Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 02/31] dma: add channels support Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 04/31] dma: add bcm6348-iudma support Álvaro Fernández Rojas
` (30 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
From: Grygorii Strashko <grygorii.strashko@ti.com>
Add a sandbox DMA driver implementation (provider) and corresponding DM
test.
Reviewed-by: Tom Rini <trini@konsulko.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Acked-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: sync with latest u-boot
v7: From Grygorii Strashko:
- no changes
v6: From Grygorii Strashko:
- added dma-uclass test
arch/sandbox/dts/test.dts | 8 ++
configs/sandbox_defconfig | 3 +
drivers/dma/Kconfig | 7 +
drivers/dma/Makefile | 1 +
drivers/dma/sandbox-dma-test.c | 282 +++++++++++++++++++++++++++++++++++++++++
test/dm/Makefile | 1 +
test/dm/dma.c | 123 ++++++++++++++++++
7 files changed, 425 insertions(+)
create mode 100644 drivers/dma/sandbox-dma-test.c
create mode 100644 test/dm/dma.c
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 2c6b422312..e5932d5a34 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -731,6 +731,14 @@
pinctrl {
compatible = "sandbox,pinctrl";
};
+
+ dma: dma {
+ compatible = "sandbox,dma";
+ #dma-cells = <1>;
+
+ dmas = <&dma 0>, <&dma 1>, <&dma 2>;
+ dma-names = "m2m", "tx0", "rx0";
+ };
};
#include "sandbox_pmic.dtsi"
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 5a744f4791..0e5e6f687e 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -215,3 +215,6 @@ CONFIG_UT_TIME=y
CONFIG_UT_DM=y
CONFIG_UT_ENV=y
CONFIG_UT_OVERLAY=y
+CONFIG_DMA=y
+CONFIG_DMA_CHANNELS=y
+CONFIG_SANDBOX_DMA=y
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index b9b85c65fc..8a4162eccd 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -19,6 +19,13 @@ config DMA_CHANNELS
Enable channels support for DMA. Some DMA controllers have multiple
channels which can either transfer data to/from different devices.
+config SANDBOX_DMA
+ bool "Enable the sandbox DMA test driver"
+ depends on DMA && DMA_CHANNELS && SANDBOX
+ help
+ Enable support for a test DMA uclass implementation. It stimulates
+ DMA transfer by simple copying data between channels.
+
config TI_EDMA3
bool "TI EDMA3 driver"
help
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 4eaef8ac65..aff31f986a 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -8,6 +8,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_FSL_DMA) += fsl_dma.o
+obj-$(CONFIG_SANDBOX_DMA) += sandbox-dma-test.o
obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o
obj-$(CONFIG_TI_EDMA3) += ti-edma3.o
obj-$(CONFIG_DMA_LPC32XX) += lpc32xx_dma.o
diff --git a/drivers/dma/sandbox-dma-test.c b/drivers/dma/sandbox-dma-test.c
new file mode 100644
index 0000000000..b958ec4d23
--- /dev/null
+++ b/drivers/dma/sandbox-dma-test.c
@@ -0,0 +1,282 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Direct Memory Access U-Class Simulation driver
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated <www.ti.com>
+ *
+ * Author: Grygorii Strashko <grygorii.strashko@ti.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/read.h>
+#include <dma-uclass.h>
+#include <dt-structs.h>
+#include <errno.h>
+
+#define SANDBOX_DMA_CH_CNT 3
+#define SANDBOX_DMA_BUF_SIZE 1024
+
+struct sandbox_dma_chan {
+ struct sandbox_dma_dev *ud;
+ char name[20];
+ u32 id;
+ enum dma_direction dir;
+ bool in_use;
+ bool enabled;
+};
+
+struct sandbox_dma_dev {
+ struct device *dev;
+ u32 ch_count;
+ struct sandbox_dma_chan channels[SANDBOX_DMA_CH_CNT];
+ uchar buf[SANDBOX_DMA_BUF_SIZE];
+ uchar *buf_rx;
+ size_t data_len;
+ u32 meta;
+};
+
+static int sandbox_dma_transfer(struct udevice *dev, int direction,
+ void *dst, void *src, size_t len)
+{
+ memcpy(dst, src, len);
+
+ return 0;
+}
+
+static int sandbox_dma_of_xlate(struct dma *dma,
+ struct ofnode_phandle_args *args)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ debug("%s(dma id=%u)\n", __func__, args->args[0]);
+
+ if (args->args[0] >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+
+ dma->id = args->args[0];
+
+ uc = &ud->channels[dma->id];
+
+ if (dma->id == 1)
+ uc->dir = DMA_MEM_TO_DEV;
+ else if (dma->id == 2)
+ uc->dir = DMA_DEV_TO_MEM;
+ else
+ uc->dir = DMA_MEM_TO_MEM;
+ debug("%s(dma id=%lu dir=%d)\n", __func__, dma->id, uc->dir);
+
+ return 0;
+}
+
+static int sandbox_dma_request(struct dma *dma)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ if (dma->id >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+
+ uc = &ud->channels[dma->id];
+ if (uc->in_use)
+ return -EBUSY;
+
+ uc->in_use = true;
+ debug("%s(dma id=%lu in_use=%d)\n", __func__, dma->id, uc->in_use);
+
+ return 0;
+}
+
+static int sandbox_dma_free(struct dma *dma)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ if (dma->id >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+
+ uc = &ud->channels[dma->id];
+ if (!uc->in_use)
+ return -EINVAL;
+
+ uc->in_use = false;
+ ud->buf_rx = NULL;
+ ud->data_len = 0;
+ debug("%s(dma id=%lu in_use=%d)\n", __func__, dma->id, uc->in_use);
+
+ return 0;
+}
+
+static int sandbox_dma_enable(struct dma *dma)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ if (dma->id >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+
+ uc = &ud->channels[dma->id];
+ if (!uc->in_use)
+ return -EINVAL;
+ if (uc->enabled)
+ return -EINVAL;
+
+ uc->enabled = true;
+ debug("%s(dma id=%lu enabled=%d)\n", __func__, dma->id, uc->enabled);
+
+ return 0;
+}
+
+static int sandbox_dma_disable(struct dma *dma)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ if (dma->id >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+
+ uc = &ud->channels[dma->id];
+ if (!uc->in_use)
+ return -EINVAL;
+ if (!uc->enabled)
+ return -EINVAL;
+
+ uc->enabled = false;
+ debug("%s(dma id=%lu enabled=%d)\n", __func__, dma->id, uc->enabled);
+
+ return 0;
+}
+
+static int sandbox_dma_send(struct dma *dma,
+ void *src, size_t len, void *metadata)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ if (dma->id >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+ if (!src || !metadata)
+ return -EINVAL;
+
+ debug("%s(dma id=%lu)\n", __func__, dma->id);
+
+ uc = &ud->channels[dma->id];
+ if (uc->dir != DMA_MEM_TO_DEV)
+ return -EINVAL;
+ if (!uc->in_use)
+ return -EINVAL;
+ if (!uc->enabled)
+ return -EINVAL;
+ if (len >= SANDBOX_DMA_BUF_SIZE)
+ return -EINVAL;
+
+ memcpy(ud->buf, src, len);
+ ud->data_len = len;
+ ud->meta = *((u32 *)metadata);
+
+ debug("%s(dma id=%lu len=%zu meta=%08x)\n",
+ __func__, dma->id, len, ud->meta);
+
+ return 0;
+}
+
+static int sandbox_dma_receive(struct dma *dma, void **dst, void *metadata)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ if (dma->id >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+ if (!dst || !metadata)
+ return -EINVAL;
+
+ uc = &ud->channels[dma->id];
+ if (uc->dir != DMA_DEV_TO_MEM)
+ return -EINVAL;
+ if (!uc->in_use)
+ return -EINVAL;
+ if (!uc->enabled)
+ return -EINVAL;
+ if (!ud->data_len)
+ return 0;
+
+ if (ud->buf_rx) {
+ memcpy(ud->buf_rx, ud->buf, ud->data_len);
+ *dst = ud->buf_rx;
+ } else {
+ memcpy(*dst, ud->buf, ud->data_len);
+ }
+
+ *((u32 *)metadata) = ud->meta;
+
+ debug("%s(dma id=%lu len=%zu meta=%08x %p)\n",
+ __func__, dma->id, ud->data_len, ud->meta, *dst);
+
+ return ud->data_len;
+}
+
+static int sandbox_dma_add_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+
+ ud->buf_rx = dst;
+
+ return 0;
+}
+
+static const struct dma_ops sandbox_dma_ops = {
+ .transfer = sandbox_dma_transfer,
+ .of_xlate = sandbox_dma_of_xlate,
+ .request = sandbox_dma_request,
+ .free = sandbox_dma_free,
+ .enable = sandbox_dma_enable,
+ .disable = sandbox_dma_disable,
+ .send = sandbox_dma_send,
+ .receive = sandbox_dma_receive,
+ .add_rcv_buf = sandbox_dma_add_rcv_buf,
+};
+
+static int sandbox_dma_probe(struct udevice *dev)
+{
+ struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct sandbox_dma_dev *ud = dev_get_priv(dev);
+ int i, ret = 0;
+
+ uc_priv->supported = DMA_SUPPORTS_MEM_TO_MEM |
+ DMA_SUPPORTS_MEM_TO_DEV |
+ DMA_SUPPORTS_DEV_TO_MEM;
+
+ ud->ch_count = SANDBOX_DMA_CH_CNT;
+ ud->buf_rx = NULL;
+ ud->meta = 0;
+ ud->data_len = 0;
+
+ pr_err("Number of channels: %u\n", ud->ch_count);
+
+ for (i = 0; i < ud->ch_count; i++) {
+ struct sandbox_dma_chan *uc = &ud->channels[i];
+
+ uc->ud = ud;
+ uc->id = i;
+ sprintf(uc->name, "DMA chan%d\n", i);
+ uc->in_use = false;
+ uc->enabled = false;
+ }
+
+ return ret;
+}
+
+static const struct udevice_id sandbox_dma_ids[] = {
+ { .compatible = "sandbox,dma" },
+ { }
+};
+
+U_BOOT_DRIVER(sandbox_dma) = {
+ .name = "sandbox-dma",
+ .id = UCLASS_DMA,
+ .of_match = sandbox_dma_ids,
+ .ops = &sandbox_dma_ops,
+ .probe = sandbox_dma_probe,
+ .priv_auto_alloc_size = sizeof(struct sandbox_dma_dev),
+};
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 213e0fda94..757dd0c45b 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -54,4 +54,5 @@ obj-$(CONFIG_DM_SERIAL) += serial.o
obj-$(CONFIG_CPU) += cpu.o
obj-$(CONFIG_TEE) += tee.o
obj-$(CONFIG_VIRTIO_SANDBOX) += virtio.o
+obj-$(CONFIG_DMA) += dma.o
endif
diff --git a/test/dm/dma.c b/test/dm/dma.c
new file mode 100644
index 0000000000..6f19d6180c
--- /dev/null
+++ b/test/dm/dma.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Direct Memory Access U-Class tests
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated <www.ti.com>
+ * Grygorii Strashko <grygorii.strashko@ti.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/test.h>
+#include <dma.h>
+#include <test/ut.h>
+
+static int dm_test_dma_m2m(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ struct dma dma_m2m;
+ u8 src_buf[512];
+ u8 dst_buf[512];
+ size_t len = 512;
+ int i;
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_DMA, "dma", &dev));
+ ut_assertok(dma_get_by_name(dev, "m2m", &dma_m2m));
+
+ memset(dst_buf, 0, len);
+ for (i = 0; i < len; i++)
+ src_buf[i] = i;
+
+ ut_assertok(dma_memcpy(dst_buf, src_buf, len));
+
+ ut_assertok(memcmp(src_buf, dst_buf, len));
+ return 0;
+}
+DM_TEST(dm_test_dma_m2m, DM_TESTF_SCAN_FDT);
+
+static int dm_test_dma(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ struct dma dma_tx, dma_rx;
+ u8 src_buf[512];
+ u8 dst_buf[512];
+ void *dst_ptr;
+ size_t len = 512;
+ u32 meta1, meta2;
+ int i;
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_DMA, "dma", &dev));
+
+ ut_assertok(dma_get_by_name(dev, "tx0", &dma_tx));
+ ut_assertok(dma_get_by_name(dev, "rx0", &dma_rx));
+
+ ut_assertok(dma_enable(&dma_tx));
+ ut_assertok(dma_enable(&dma_rx));
+
+ memset(dst_buf, 0, len);
+ for (i = 0; i < len; i++)
+ src_buf[i] = i;
+ meta1 = 0xADADDEAD;
+ meta2 = 0;
+ dst_ptr = &dst_buf;
+
+ ut_assertok(dma_send(&dma_tx, src_buf, len, &meta1));
+
+ ut_asserteq(len, dma_receive(&dma_rx, &dst_ptr, &meta2));
+ ut_asserteq(0xADADDEAD, meta2);
+
+ ut_assertok(dma_disable(&dma_tx));
+ ut_assertok(dma_disable(&dma_rx));
+
+ ut_assertok(dma_free(&dma_tx));
+ ut_assertok(dma_free(&dma_rx));
+ ut_assertok(memcmp(src_buf, dst_buf, len));
+
+ return 0;
+}
+DM_TEST(dm_test_dma, DM_TESTF_SCAN_FDT);
+
+static int dm_test_dma_rx(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ struct dma dma_tx, dma_rx;
+ u8 src_buf[512];
+ u8 dst_buf[512];
+ void *dst_ptr;
+ size_t len = 512;
+ u32 meta1, meta2;
+ int i;
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_DMA, "dma", &dev));
+
+ ut_assertok(dma_get_by_name(dev, "tx0", &dma_tx));
+ ut_assertok(dma_get_by_name(dev, "rx0", &dma_rx));
+
+ ut_assertok(dma_enable(&dma_tx));
+ ut_assertok(dma_enable(&dma_rx));
+
+ memset(dst_buf, 0, len);
+ for (i = 0; i < len; i++)
+ src_buf[i] = i;
+ meta1 = 0xADADDEAD;
+ meta2 = 0;
+ dst_ptr = NULL;
+
+ ut_assertok(dma_add_rcv_buf(&dma_tx, dst_buf, len));
+
+ ut_assertok(dma_send(&dma_tx, src_buf, len, &meta1));
+
+ ut_asserteq(len, dma_receive(&dma_rx, &dst_ptr, &meta2));
+ ut_asserteq(0xADADDEAD, meta2);
+ ut_asserteq_ptr(dst_buf, dst_ptr);
+
+ ut_assertok(dma_disable(&dma_tx));
+ ut_assertok(dma_disable(&dma_rx));
+
+ ut_assertok(dma_free(&dma_tx));
+ ut_assertok(dma_free(&dma_rx));
+ ut_assertok(memcmp(src_buf, dst_buf, len));
+
+ return 0;
+}
+DM_TEST(dm_test_dma_rx, DM_TESTF_SCAN_FDT);
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 04/31] dma: add bcm6348-iudma support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (2 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 03/31] test: dma: add dma-uclass test Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 05/31] bmips: bcm6338: " Álvaro Fernández Rojas
` (29 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
BCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: Introduce changes from Grygorii Strashko
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 | 533 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 543 insertions(+)
create mode 100644 drivers/dma/bcm6348-iudma.c
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 8a4162eccd..1820676d7a 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -26,6 +26,15 @@ config SANDBOX_DMA
Enable support for a test DMA uclass implementation. It stimulates
DMA transfer by simple copying data between channels.
+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
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index aff31f986a..b5f9147e0a 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -7,6 +7,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_SANDBOX_DMA) += sandbox-dma-test.o
obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o
diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c
new file mode 100644
index 0000000000..ef938bc3cd
--- /dev/null
+++ b/drivers/dma/bcm6348-iudma.c
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/dma/bcm63xx-iudma.c:
+ * Copyright (C) 2015 Simon Arlott <simon@fire.lp0.eu>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h:
+ * Copyright (C) 2000-2010 Broadcom Corporation
+ *
+ * Derived from bcm963xx_4.12L.06B_consumer/bcmdrivers/opensource/net/enet/impl4/bcmenet.c:
+ * Copyright (C) 2010 Broadcom Corporation
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dma-uclass.h>
+#include <memalign.h>
+#include <reset.h>
+#include <asm/io.h>
+
+#define DMA_RX_DESC 6
+#define DMA_TX_DESC 1
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define ALIGN_END_ADDR(type, ptr, size) \
+ ((unsigned long)(ptr) + roundup((size) * sizeof(type), \
+ ARCH_DMA_MINALIGN))
+
+/* DMA Channels */
+#define DMA_CHAN_FLOWC(x) ((x) >> 1)
+#define DMA_CHAN_MAX 16
+#define DMA_CHAN_SIZE 0x10
+#define DMA_CHAN_TOUT 500
+
+/* DMA Global Configuration register */
+#define DMA_CFG_REG 0x00
+#define DMA_CFG_ENABLE_SHIFT 0
+#define DMA_CFG_ENABLE_MASK (1 << DMA_CFG_ENABLE_SHIFT)
+#define DMA_CFG_FLOWC_ENABLE(x) BIT(DMA_CHAN_FLOWC(x) + 1)
+#define DMA_CFG_NCHANS_SHIFT 24
+#define DMA_CFG_NCHANS_MASK (0xf << DMA_CFG_NCHANS_SHIFT)
+
+/* DMA Global Flow Control registers */
+#define DMA_FLOWC_THR_LO_REG(x) (0x04 + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_THR_HI_REG(x) (0x08 + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_ALLOC_REG(x) (0x0c + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_ALLOC_FORCE_SHIFT 31
+#define DMA_FLOWC_ALLOC_FORCE_MASK (1 << DMA_FLOWC_ALLOC_FORCE_SHIFT)
+
+/* DMA Global Reset register */
+#define DMA_RST_REG 0x34
+#define DMA_RST_CHAN_SHIFT 0
+#define DMA_RST_CHAN_MASK(x) (1 << x)
+
+/* DMA Channel Configuration register */
+#define DMAC_CFG_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
+#define DMAC_CFG_ENABLE_SHIFT 0
+#define DMAC_CFG_ENABLE_MASK (1 << DMAC_CFG_ENABLE_SHIFT)
+#define DMAC_CFG_PKT_HALT_SHIFT 1
+#define DMAC_CFG_PKT_HALT_MASK (1 << DMAC_CFG_PKT_HALT_SHIFT)
+#define DMAC_CFG_BRST_HALT_SHIFT 2
+#define DMAC_CFG_BRST_HALT_MASK (1 << DMAC_CFG_BRST_HALT_SHIFT)
+
+/* DMA Channel Max Burst Length register */
+#define DMAC_BURST_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
+
+/* DMA SRAM Descriptor Ring Start register */
+#define DMAS_RSTART_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
+
+/* DMA SRAM State/Bytes done/ring offset register */
+#define DMAS_STATE_DATA_REG(x) (DMA_CHAN_SIZE * (x) + 0x04)
+
+/* DMA SRAM Buffer Descriptor status and length register */
+#define DMAS_DESC_LEN_STATUS_REG(x) (DMA_CHAN_SIZE * (x) + 0x08)
+
+/* DMA SRAM Buffer Descriptor status and length register */
+#define DMAS_DESC_BASE_BUFPTR_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
+
+struct bcm6348_dma_desc {
+ uint16_t length;
+
+ uint16_t status;
+#define DMAD_ST_CRC_SHIFT 8
+#define DMAD_ST_CRC_MASK (1 << DMAD_ST_CRC_SHIFT)
+#define DMAD_ST_WRAP_SHIFT 12
+#define DMAD_ST_WRAP_MASK (1 << DMAD_ST_WRAP_SHIFT)
+#define DMAD_ST_SOP_SHIFT 13
+#define DMAD_ST_SOP_MASK (1 << DMAD_ST_SOP_SHIFT)
+#define DMAD_ST_EOP_SHIFT 14
+#define DMAD_ST_EOP_MASK (1 << DMAD_ST_EOP_SHIFT)
+#define DMAD_ST_OWN_SHIFT 15
+#define DMAD_ST_OWN_MASK (1 << DMAD_ST_OWN_SHIFT)
+
+#define DMAD6348_ST_OV_ERR_SHIFT 0
+#define DMAD6348_ST_OV_ERR_MASK (1 << DMAD6348_ST_OV_ERR_SHIFT)
+#define DMAD6348_ST_CRC_ERR_SHIFT 1
+#define DMAD6348_ST_CRC_ERR_MASK (1 << DMAD6348_ST_CRC_ERR_SHIFT)
+#define DMAD6348_ST_RX_ERR_SHIFT 2
+#define DMAD6348_ST_RX_ERR_MASK (1 << DMAD6348_ST_RX_ERR_SHIFT)
+#define DMAD6348_ST_OS_ERR_SHIFT 4
+#define DMAD6348_ST_OS_ERR_MASK (1 << DMAD6348_ST_OS_ERR_SHIFT)
+#define DMAD6348_ST_UN_ERR_SHIFT 9
+#define DMAD6348_ST_UN_ERR_MASK (1 << DMAD6348_ST_UN_ERR_SHIFT)
+
+ uint32_t address;
+} __attribute__((aligned(1)));
+
+struct bcm6348_chan_priv {
+ void __iomem *dma_buff;
+ void __iomem *dma_ring;
+ uint8_t dma_ring_size;
+ uint8_t desc_id;
+};
+
+struct bcm6348_iudma_hw {
+ uint16_t err_mask;
+};
+
+struct bcm6348_iudma_priv {
+ const struct bcm6348_iudma_hw *hw;
+ void __iomem *base;
+ void __iomem *chan;
+ void __iomem *sram;
+ struct bcm6348_chan_priv **ch_priv;
+ uint8_t n_channels;
+};
+
+static inline bool bcm6348_iudma_chan_is_rx(uint8_t ch)
+{
+ return !(ch & 1);
+}
+
+static void bcm6348_iudma_chan_stop(struct bcm6348_iudma_priv *priv,
+ uint8_t ch)
+{
+ unsigned int timeout = DMA_CHAN_TOUT;
+
+ do {
+ uint32_t cfg, halt;
+
+ if (timeout > DMA_CHAN_TOUT / 2)
+ halt = DMAC_CFG_PKT_HALT_MASK;
+ else
+ halt = DMAC_CFG_BRST_HALT_MASK;
+
+ /* try to stop dma channel */
+ writel_be(halt, priv->chan + DMAC_CFG_REG(ch));
+ mb();
+
+ /* check if channel was stopped */
+ cfg = readl_be(priv->chan + DMAC_CFG_REG(ch));
+ if (!(cfg & DMAC_CFG_ENABLE_MASK))
+ break;
+
+ udelay(1);
+ } while (--timeout);
+
+ if (!timeout)
+ pr_err("unable to stop channel %u\n", ch);
+
+ /* reset dma channel */
+ setbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
+ mb();
+ clrbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
+}
+
+static int bcm6348_iudma_disable(struct dma *dma)
+{
+ struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+
+ bcm6348_iudma_chan_stop(priv, dma->id);
+
+ if (bcm6348_iudma_chan_is_rx(dma->id))
+ writel_be(DMA_FLOWC_ALLOC_FORCE_MASK,
+ DMA_FLOWC_ALLOC_REG(dma->id));
+
+ return 0;
+}
+
+static int bcm6348_iudma_enable(struct dma *dma)
+{
+ const 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 = ch_priv->dma_buff;
+ 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(dma_buff);
+ dma_buff += PKTSIZE_ALIGN;
+ } 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;
+
+ 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));
+
+ writel_be(0, priv->base + DMA_FLOWC_ALLOC_REG(dma->id));
+ }
+
+ /* set dma max burst */
+ writel_be(ch_priv->dma_ring_size,
+ priv->chan + DMAC_BURST_REG(dma->id));
+
+ setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK);
+
+ return 0;
+}
+
+static int bcm6348_iudma_request(struct dma *dma)
+{
+ const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+ struct bcm6348_chan_priv *ch_priv;
+
+ /* check if channel is valid */
+ if (dma->id >= priv->n_channels)
+ return -ENODEV;
+
+ /* alloc channel private data */
+ priv->ch_priv[dma->id] = calloc(1, sizeof(struct bcm6348_chan_priv));
+ if (!priv->ch_priv[dma->id])
+ return -ENOMEM;
+ ch_priv = priv->ch_priv[dma->id];
+
+ /* alloc dma ring */
+ if (bcm6348_iudma_chan_is_rx(dma->id))
+ ch_priv->dma_ring_size = DMA_RX_DESC;
+ else
+ ch_priv->dma_ring_size = DMA_TX_DESC;
+
+ ch_priv->dma_ring =
+ malloc_cache_aligned(sizeof(struct bcm6348_dma_desc) *
+ ch_priv->dma_ring_size);
+ if (!ch_priv->dma_ring)
+ return -ENOMEM;
+
+ if (bcm6348_iudma_chan_is_rx(dma->id)) {
+ ch_priv->dma_buff =
+ malloc_cache_aligned(PKTSIZE_ALIGN *
+ ch_priv->dma_ring_size);
+ if (!ch_priv->dma_buff)
+ return -ENOMEM;
+ } else {
+ ch_priv->dma_buff = NULL;
+ }
+
+ return 0;
+}
+
+static int bcm6348_iudma_receive(struct dma *dma, void **dst, void *metadata)
+{
+ const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+ const struct bcm6348_iudma_hw *hw = priv->hw;
+ struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+ struct bcm6348_dma_desc *dma_desc;
+ void __iomem *dma_buff;
+ 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 -EAGAIN;
+
+ /* check pkt */
+ if (!(dma_desc->status & DMAD_ST_EOP_MASK) ||
+ !(dma_desc->status & DMAD_ST_SOP_MASK) ||
+ (dma_desc->status & hw->err_mask)) {
+ pr_err("invalid pkt received (ch=%ld) (st=%04x)\n",
+ dma->id, dma_desc->status);
+ ret = -EAGAIN;
+ } else {
+ uint16_t length;
+
+ /* 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));
+
+ /* remove crc */
+ length = dma_desc->length - 4;
+
+ /* copy data */
+ memcpy(*dst, dma_buff, length);
+
+ ret = length;
+ }
+
+ /* reinit dma descriptor */
+ dma_desc->length = PKTSIZE_ALIGN;
+ dma_desc->status = (dma_desc->status & DMAD_ST_WRAP_MASK) |
+ DMAD_ST_OWN_MASK;
+
+ /* flush cache */
+ flush_dcache_range((ulong)dma_desc,
+ ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1));
+
+ /* enable dma */
+ setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK);
+
+ /* increment dma descriptor */
+ ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->dma_ring_size;
+
+ return ret;
+}
+
+static int bcm6348_iudma_send(struct dma *dma, void *src, size_t len,
+ void *metadata)
+{
+ const 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;
+ uint16_t val;
+
+ /* get dma ring descriptor address */
+ dma_desc = ch_priv->dma_ring;
+ dma_desc += ch_priv->desc_id;
+
+ dma_desc->address = virt_to_phys(src);
+
+ /* config dma descriptor */
+ val = (DMAD_ST_OWN_MASK |
+ DMAD_ST_EOP_MASK |
+ DMAD_ST_CRC_MASK |
+ DMAD_ST_SOP_MASK);
+ if (ch_priv->desc_id == ch_priv->dma_ring_size - 1)
+ val |= DMAD_ST_WRAP_MASK;
+
+ dma_desc->length = len;
+ dma_desc->status = val;
+
+ /* flush cache */
+ flush_dcache_range((ulong)src, (ulong)src + PKTSIZE_ALIGN);
+
+ /* flush cache */
+ flush_dcache_range((ulong)dma_desc,
+ ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1));
+
+ /* enable dma */
+ setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK);
+
+ /* poll dma status */
+ do {
+ /* invalidate cache */
+ invalidate_dcache_range((ulong)dma_desc,
+ ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1));
+
+ if (!(dma_desc->status & DMAD_ST_OWN_MASK))
+ break;
+ } while(1);
+
+ /* increment dma descriptor */
+ ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->dma_ring_size;
+
+ return 0;
+}
+
+static const struct dma_ops bcm6348_iudma_ops = {
+ .disable = bcm6348_iudma_disable,
+ .enable = bcm6348_iudma_enable,
+ .request = bcm6348_iudma_request,
+ .receive = bcm6348_iudma_receive,
+ .send = bcm6348_iudma_send,
+};
+
+static const struct bcm6348_iudma_hw bcm6348_hw = {
+ .err_mask = (DMAD6348_ST_OV_ERR_MASK |
+ DMAD6348_ST_CRC_ERR_MASK |
+ DMAD6348_ST_RX_ERR_MASK |
+ DMAD6348_ST_OS_ERR_MASK |
+ DMAD6348_ST_UN_ERR_MASK),
+};
+
+static const struct bcm6348_iudma_hw bcm6368_hw = {
+ .err_mask = 0,
+};
+
+static const struct udevice_id bcm6348_iudma_ids[] = {
+ {
+ .compatible = "brcm,bcm6348-iudma",
+ .data = (ulong)&bcm6348_hw,
+ }, {
+ .compatible = "brcm,bcm6368-iudma",
+ .data = (ulong)&bcm6368_hw,
+ }, { /* sentinel */ }
+};
+
+static int bcm6348_iudma_probe(struct udevice *dev)
+{
+ struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct bcm6348_iudma_priv *priv = dev_get_priv(dev);
+ const struct bcm6348_iudma_hw *hw =
+ (const struct bcm6348_iudma_hw *)dev_get_driver_data(dev);
+ fdt_addr_t addr;
+ uint8_t ch;
+ int i;
+
+ uc_priv->supported = (DMA_SUPPORTS_DEV_TO_MEM |
+ DMA_SUPPORTS_MEM_TO_DEV);
+ priv->hw = hw;
+
+ /* 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);
+ }
+
+ /* dma global base address */
+ addr = devfdt_get_addr_name(dev, "dma");
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+ priv->base = ioremap(addr, 0);
+
+ /* dma channels base address */
+ addr = devfdt_get_addr_name(dev, "dma-channels");
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+ priv->chan = ioremap(addr, 0);
+
+ /* dma sram base address */
+ addr = devfdt_get_addr_name(dev, "dma-sram");
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+ priv->sram = ioremap(addr, 0);
+
+ /* disable dma controller */
+ clrbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
+
+ /* get number of channels */
+ priv->n_channels = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+ "dma-channels", 8);
+ if (priv->n_channels > DMA_CHAN_MAX)
+ return -EINVAL;
+
+ /* alloc channel private data pointers */
+ priv->ch_priv = calloc(priv->n_channels,
+ sizeof(struct bcm6348_chan_priv*));
+ if (!priv->ch_priv)
+ return -ENOMEM;
+
+ /* stop dma channels */
+ for (ch = 0; ch < priv->n_channels; ch++)
+ bcm6348_iudma_chan_stop(priv, ch);
+
+ /* enable dma controller */
+ setbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(bcm6348_iudma) = {
+ .name = "bcm6348_iudma",
+ .id = UCLASS_DMA,
+ .of_match = bcm6348_iudma_ids,
+ .ops = &bcm6348_iudma_ops,
+ .priv_auto_alloc_size = sizeof(struct bcm6348_iudma_priv),
+ .probe = bcm6348_iudma_probe,
+};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 05/31] bmips: bcm6338: add bcm6348-iudma support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (3 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 04/31] dma: add bcm6348-iudma support Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 06/31] bmips: bcm6348: " Álvaro Fernández Rojas
` (28 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: no changes
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
diff --git a/arch/mips/dts/brcm,bcm6338.dtsi b/arch/mips/dts/brcm,bcm6338.dtsi
index bbd58cf803..990355481c 100644
--- a/arch/mips/dts/brcm,bcm6338.dtsi
+++ b/arch/mips/dts/brcm,bcm6338.dtsi
@@ -4,6 +4,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"
@@ -130,5 +131,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>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6338-dma.h b/include/dt-bindings/dma/bcm6338-dma.h
new file mode 100644
index 0000000000..5dd66239b4
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6338-dma.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * 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 */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 06/31] bmips: bcm6348: add bcm6348-iudma support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (4 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 05/31] bmips: bcm6338: " Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 07/31] bmips: bcm6358: " Álvaro Fernández Rojas
` (27 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: no changes
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
diff --git a/arch/mips/dts/brcm,bcm6348.dtsi b/arch/mips/dts/brcm,bcm6348.dtsi
index cc80bbc808..875de232ca 100644
--- a/arch/mips/dts/brcm,bcm6348.dtsi
+++ b/arch/mips/dts/brcm,bcm6348.dtsi
@@ -4,6 +4,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"
@@ -159,5 +160,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>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6348-dma.h b/include/dt-bindings/dma/bcm6348-dma.h
new file mode 100644
index 0000000000..a1d3a6456d
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6348-dma.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * 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 */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 07/31] bmips: bcm6358: add bcm6348-iudma support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (5 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 06/31] bmips: bcm6348: " Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 08/31] bmips: bcm6368: " Álvaro Fernández Rojas
` (26 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: no changes
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
diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi
index 0617b46e92..5605723e83 100644
--- a/arch/mips/dts/brcm,bcm6358.dtsi
+++ b/arch/mips/dts/brcm,bcm6358.dtsi
@@ -4,6 +4,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"
@@ -190,5 +191,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>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6358-dma.h b/include/dt-bindings/dma/bcm6358-dma.h
new file mode 100644
index 0000000000..3b1fcf8540
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6358-dma.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * 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 */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 08/31] bmips: bcm6368: add bcm6348-iudma support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (6 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 07/31] bmips: bcm6358: " Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 09/31] bmips: bcm6328: " Álvaro Fernández Rojas
` (25 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6368.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm6368-dma.h | 15 +++++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6368-dma.h
diff --git a/arch/mips/dts/brcm,bcm6368.dtsi b/arch/mips/dts/brcm,bcm6368.dtsi
index 65d769ab4f..30047f6360 100644
--- a/arch/mips/dts/brcm,bcm6368.dtsi
+++ b/arch/mips/dts/brcm,bcm6368.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6368-clock.h>
+#include <dt-bindings/dma/bcm6368-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/reset/bcm6368-reset.h>
#include "skeleton.dtsi"
@@ -192,5 +193,17 @@
status = "disabled";
};
+
+ iudma: dma-controller at 10006800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x10006800 0x80>,
+ <0x10006a00 0x80>,
+ <0x10006c00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6368-dma.h b/include/dt-bindings/dma/bcm6368-dma.h
new file mode 100644
index 0000000000..45ffb89e0a
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6368-dma.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6368_H
+#define __DT_BINDINGS_DMA_BCM6368_H
+
+#define BCM6368_DMA_ENETSW_RX 0
+#define BCM6368_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6368_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 09/31] bmips: bcm6328: add bcm6348-iudma support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (7 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 08/31] bmips: bcm6368: " Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 10/31] bmips: bcm6362: " Álvaro Fernández Rojas
` (24 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6328.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm6328-dma.h | 15 +++++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6328-dma.h
diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi
index e00a2950e2..6fa49e22bb 100644
--- a/arch/mips/dts/brcm,bcm6328.dtsi
+++ b/arch/mips/dts/brcm,bcm6328.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6328-clock.h>
+#include <dt-bindings/dma/bcm6328-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm6328-power-domain.h>
#include <dt-bindings/reset/bcm6328-reset.h>
@@ -187,5 +188,17 @@
reg = <0x10003000 0x864>;
u-boot,dm-pre-reloc;
};
+
+ iudma: dma-controller at 1000d800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x1000d800 0x80>,
+ <0x1000da00 0x80>,
+ <0x1000dc00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6328-dma.h b/include/dt-bindings/dma/bcm6328-dma.h
new file mode 100644
index 0000000000..508a5dc523
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6328-dma.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6328_H
+#define __DT_BINDINGS_DMA_BCM6328_H
+
+#define BCM6328_DMA_ENETSW_RX 0
+#define BCM6328_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6328_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 10/31] bmips: bcm6362: add bcm6348-iudma support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (8 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 09/31] bmips: bcm6328: " Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 11/31] bmips: bcm63268: " Álvaro Fernández Rojas
` (23 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6362.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm6362-dma.h | 15 +++++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6362-dma.h
diff --git a/arch/mips/dts/brcm,bcm6362.dtsi b/arch/mips/dts/brcm,bcm6362.dtsi
index 3047b82b21..94e7de096d 100644
--- a/arch/mips/dts/brcm,bcm6362.dtsi
+++ b/arch/mips/dts/brcm,bcm6362.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6362-clock.h>
+#include <dt-bindings/dma/bcm6362-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm6362-power-domain.h>
#include <dt-bindings/reset/bcm6362-reset.h>
@@ -211,5 +212,17 @@
reg = <0x10003000 0x864>;
u-boot,dm-pre-reloc;
};
+
+ iudma: dma-controller at 1000d800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x1000d800 0x80>,
+ <0x1000da00 0x80>,
+ <0x1000dc00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6362-dma.h b/include/dt-bindings/dma/bcm6362-dma.h
new file mode 100644
index 0000000000..b90b3ffeb6
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6362-dma.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6362_H
+#define __DT_BINDINGS_DMA_BCM6362_H
+
+#define BCM6362_DMA_ENETSW_RX 0
+#define BCM6362_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6362_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 11/31] bmips: bcm63268: add bcm6348-iudma support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (9 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 10/31] bmips: bcm6362: " Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 12/31] bmips: bcm6318: " Álvaro Fernández Rojas
` (22 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm63268.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm63268-dma.h | 15 +++++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm63268-dma.h
diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi
index 62c440e675..c7ad83c306 100644
--- a/arch/mips/dts/brcm,bcm63268.dtsi
+++ b/arch/mips/dts/brcm,bcm63268.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm63268-clock.h>
+#include <dt-bindings/dma/bcm63268-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm63268-power-domain.h>
#include <dt-bindings/reset/bcm63268-reset.h>
@@ -217,5 +218,17 @@
reg = <0x10003000 0x894>;
u-boot,dm-pre-reloc;
};
+
+ iudma: dma-controller at 1000d800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x1000d800 0x80>,
+ <0x1000da00 0x80>,
+ <0x1000dc00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm63268-dma.h b/include/dt-bindings/dma/bcm63268-dma.h
new file mode 100644
index 0000000000..d5d7453be1
--- /dev/null
+++ b/include/dt-bindings/dma/bcm63268-dma.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM63268_H
+#define __DT_BINDINGS_DMA_BCM63268_H
+
+#define BCM63268_DMA_ENETSW_RX 0
+#define BCM63268_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM63268_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 12/31] bmips: bcm6318: add bcm6348-iudma support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (10 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 11/31] bmips: bcm63268: " Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 13/31] net: add support for bcm6348-enet Álvaro Fernández Rojas
` (21 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6318.dtsi | 19 +++++++++++++++++++
include/dt-bindings/dma/bcm6318-dma.h | 15 +++++++++++++++
2 files changed, 34 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6318-dma.h
diff --git a/arch/mips/dts/brcm,bcm6318.dtsi b/arch/mips/dts/brcm,bcm6318.dtsi
index f75988be12..d04b7cbb01 100644
--- a/arch/mips/dts/brcm,bcm6318.dtsi
+++ b/arch/mips/dts/brcm,bcm6318.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6318-clock.h>
+#include <dt-bindings/dma/bcm6318-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm6318-power-domain.h>
#include <dt-bindings/reset/bcm6318-reset.h>
@@ -54,6 +55,12 @@
reg = <0x10000004 0x4>;
#clock-cells = <1>;
};
+
+ ubus_clk: ubus-clk {
+ compatible = "brcm,bcm6345-clk";
+ reg = <0x10000008 0x4>;
+ #clock-cells = <1>;
+ };
};
ubus {
@@ -182,5 +189,17 @@
status = "disabled";
};
+
+ iudma: dma-controller at 10088000 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x10088000 0x80>,
+ <0x10088200 0x80>,
+ <0x10088400 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6318-dma.h b/include/dt-bindings/dma/bcm6318-dma.h
new file mode 100644
index 0000000000..c039391395
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6318-dma.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6318_H
+#define __DT_BINDINGS_DMA_BCM6318_H
+
+#define BCM6318_DMA_ENETSW_RX 0
+#define BCM6318_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6318_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 13/31] net: add support for bcm6348-enet
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (11 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 12/31] bmips: bcm6318: " Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 14/31] bmips: bcm6338: " Álvaro Fernández Rojas
` (20 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: Introduce changes from Grygorii Strashko
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 | 576 +++++++++++++++++++++++++++++++++++++++++
include/configs/bmips_common.h | 5 +-
4 files changed, 591 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/bcm6348-eth.c
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 8fb365fc5d..2b7cec8804 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -72,6 +72,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
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 99056aa041..2647d4dd23 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -6,6 +6,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
diff --git a/drivers/net/bcm6348-eth.c b/drivers/net/bcm6348-eth.c
new file mode 100644
index 0000000000..27c812ff4a
--- /dev/null
+++ b/drivers/net/bcm6348-eth.c
@@ -0,0 +1,576 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * 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],
+ NULL);
+ 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;
+}
+
+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);
+
+ return dma_send(&priv->tx_dma, (void *)packet, length, NULL);
+}
+
+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) & ETH_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,
+};
diff --git a/include/configs/bmips_common.h b/include/configs/bmips_common.h
index 39ca2e0bf3..65aa9c77cc 100644
--- a/include/configs/bmips_common.h
+++ b/include/configs/bmips_common.h
@@ -6,6 +6,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 }
@@ -16,7 +19,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
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 14/31] bmips: bcm6338: add support for bcm6348-enet
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (12 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 13/31] net: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 15/31] bmips: enable f@st1704 enet support Álvaro Fernández Rojas
` (19 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6338.dtsi | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6338.dtsi b/arch/mips/dts/brcm,bcm6338.dtsi
index 990355481c..c547e949dd 100644
--- a/arch/mips/dts/brcm,bcm6338.dtsi
+++ b/arch/mips/dts/brcm,bcm6338.dtsi
@@ -144,5 +144,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";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 15/31] bmips: enable f@st1704 enet support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (13 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 14/31] bmips: bcm6338: " Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 16/31] bmips: bcm6348: add support for bcm6348-enet Álvaro Fernández Rojas
` (18 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: no changes
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 | 8 +++++++-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/sagem,f at st1704.dts b/arch/mips/dts/sagem,f at st1704.dts
index 5300f8b6df..ec6846dd9f 100644
--- a/arch/mips/dts/sagem,f at st1704.dts
+++ b/arch/mips/dts/sagem,f at st1704.dts
@@ -39,6 +39,18 @@
};
};
+&enet {
+ status = "okay";
+ phy = <&enetphy>;
+ phy-mode = "mii";
+
+ enetphy: fixed-link {
+ reg = <1>;
+ speed = <100>;
+ full-duplex;
+ };
+};
+
&gpio {
status = "okay";
};
diff --git a/configs/sagem_f at st1704_ram_defconfig b/configs/sagem_f at st1704_ram_defconfig
index 91a966327a..8c36f5dbf8 100644
--- a/configs/sagem_f at st1704_ram_defconfig
+++ b/configs/sagem_f at st1704_ram_defconfig
@@ -27,11 +27,14 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="sagem,f at st1704"
-# CONFIG_NET is not set
+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_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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 16/31] bmips: bcm6348: add support for bcm6348-enet
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (14 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 15/31] bmips: enable f@st1704 enet support Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 17/31] bmips: enable ct-5361 enet support Álvaro Fernández Rojas
` (17 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6348.dtsi | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6348.dtsi b/arch/mips/dts/brcm,bcm6348.dtsi
index 875de232ca..79e7bd892b 100644
--- a/arch/mips/dts/brcm,bcm6348.dtsi
+++ b/arch/mips/dts/brcm,bcm6348.dtsi
@@ -161,6 +161,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>,
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 17/31] bmips: enable ct-5361 enet support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (15 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 16/31] bmips: bcm6348: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 18/31] bmips: bcm6358: add support for bcm6348-enet Álvaro Fernández Rojas
` (16 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: no changes
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(-)
diff --git a/arch/mips/dts/comtrend,ct-5361.dts b/arch/mips/dts/comtrend,ct-5361.dts
index 25747ca95d..f6b8a94e25 100644
--- a/arch/mips/dts/comtrend,ct-5361.dts
+++ b/arch/mips/dts/comtrend,ct-5361.dts
@@ -34,6 +34,18 @@
};
};
+&enet1 {
+ status = "okay";
+ phy = <&enet1phy>;
+ phy-mode = "mii";
+
+ enet1phy: fixed-link {
+ reg = <1>;
+ speed = <100>;
+ full-duplex;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/comtrend_ct5361_ram_defconfig b/configs/comtrend_ct5361_ram_defconfig
index 82f2070713..6297e78fd9 100644
--- a/configs/comtrend_ct5361_ram_defconfig
+++ b/configs/comtrend_ct5361_ram_defconfig
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,ct-5361"
-# CONFIG_NET is not set
+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_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 18/31] bmips: bcm6358: add support for bcm6348-enet
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (16 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 17/31] bmips: enable ct-5361 enet support Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 19/31] bmips: enable hg556a enet support Álvaro Fernández Rojas
` (15 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6358.dtsi | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi
index 5605723e83..5e9c9ad769 100644
--- a/arch/mips/dts/brcm,bcm6358.dtsi
+++ b/arch/mips/dts/brcm,bcm6358.dtsi
@@ -192,6 +192,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>,
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 19/31] bmips: enable hg556a enet support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (17 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 18/31] bmips: bcm6358: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 20/31] bmips: enable nb4-ser " Álvaro Fernández Rojas
` (14 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: no changes
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(-)
diff --git a/arch/mips/dts/huawei,hg556a.dts b/arch/mips/dts/huawei,hg556a.dts
index 60455c2ff8..6a7fc1df4b 100644
--- a/arch/mips/dts/huawei,hg556a.dts
+++ b/arch/mips/dts/huawei,hg556a.dts
@@ -93,6 +93,18 @@
status = "okay";
};
+&enet1 {
+ status = "okay";
+ phy = <&enet1phy>;
+ phy-mode = "mii";
+
+ enet1phy: fixed-link {
+ reg = <1>;
+ speed = <100>;
+ full-duplex;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/huawei_hg556a_ram_defconfig b/configs/huawei_hg556a_ram_defconfig
index 6bb14ba736..d4e6144319 100644
--- a/configs/huawei_hg556a_ram_defconfig
+++ b/configs/huawei_hg556a_ram_defconfig
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="huawei,hg556a"
-# CONFIG_NET is not set
+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_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 20/31] bmips: enable nb4-ser enet support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (18 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 19/31] bmips: enable hg556a enet support Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 21/31] net: add support for bcm6368-enet Álvaro Fernández Rojas
` (13 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: no changes
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(-)
diff --git a/arch/mips/dts/sfr,nb4-ser.dts b/arch/mips/dts/sfr,nb4-ser.dts
index bdc6f8ae45..dfbc4148dc 100644
--- a/arch/mips/dts/sfr,nb4-ser.dts
+++ b/arch/mips/dts/sfr,nb4-ser.dts
@@ -53,6 +53,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";
};
diff --git a/configs/sfr_nb4-ser_ram_defconfig b/configs/sfr_nb4-ser_ram_defconfig
index 12adfb01e7..39622875b1 100644
--- a/configs/sfr_nb4-ser_ram_defconfig
+++ b/configs/sfr_nb4-ser_ram_defconfig
@@ -26,11 +26,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="sfr,nb4-ser"
-# CONFIG_NET is not set
+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
@@ -42,6 +45,9 @@ CONFIG_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 21/31] net: add support for bcm6368-enet
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (19 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 20/31] bmips: enable nb4-ser " Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 22/31] bmips: bcm6368: " Álvaro Fernández Rojas
` (12 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
drivers/net/Kconfig | 8 +
drivers/net/Makefile | 1 +
drivers/net/bcm6368-eth.c | 604 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 613 insertions(+)
create mode 100644 drivers/net/bcm6368-eth.c
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2b7cec8804..7044c6adf3 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -82,6 +82,14 @@ config BCM6348_ETH
help
This driver supports the BCM6348 Ethernet MAC.
+config BCM6368_ETH
+ bool "BCM6368 EMAC support"
+ depends on DM_ETH && ARCH_BMIPS
+ select DMA
+ select MII
+ help
+ This driver supports the BCM6368 Ethernet MAC.
+
config DWC_ETH_QOS
bool "Synopsys DWC Ethernet QOS device support"
depends on DM_ETH
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 2647d4dd23..0dbfa03306 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -7,6 +7,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_BCM6368_ETH) += bcm6368-eth.o
obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
obj-$(CONFIG_DRIVER_AX88180) += ax88180.o
obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
diff --git a/drivers/net/bcm6368-eth.c b/drivers/net/bcm6368-eth.c
new file mode 100644
index 0000000000..ff2a8b1e78
--- /dev/null
+++ b/drivers/net/bcm6368-eth.c
@@ -0,0 +1,604 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * 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 <reset.h>
+#include <wait_bit.h>
+#include <asm/io.h>
+
+#define ETH_PORT_STR "brcm,enetsw-port"
+
+#define ETH_ZLEN 60
+#define ETH_TIMEOUT 100
+
+#define ETH_MAX_PORT 8
+#define ETH_RGMII_PORT0 4
+
+/* Port traffic control */
+#define ETH_PTCTRL_REG(x) (0x0 + (x))
+#define ETH_PTCTRL_RXDIS_SHIFT 0
+#define ETH_PTCTRL_RXDIS_MASK (1 << ETH_PTCTRL_RXDIS_SHIFT)
+#define ETH_PTCTRL_TXDIS_SHIFT 1
+#define ETH_PTCTRL_TXDIS_MASK (1 << ETH_PTCTRL_TXDIS_SHIFT)
+
+/* Switch mode register */
+#define ETH_SWMODE_REG 0xb
+#define ETH_SWMODE_FWD_EN_SHIFT 1
+#define ETH_SWMODE_FWD_EN_MASK (1 << ETH_SWMODE_FWD_EN_SHIFT)
+
+/* IMP override Register */
+#define ETH_IMPOV_REG 0xe
+#define ETH_IMPOV_LINKUP_SHIFT 0
+#define ETH_IMPOV_LINKUP_MASK (1 << ETH_IMPOV_LINKUP_SHIFT)
+#define ETH_IMPOV_FDX_SHIFT 1
+#define ETH_IMPOV_FDX_MASK (1 << ETH_IMPOV_FDX_SHIFT)
+#define ETH_IMPOV_100_SHIFT 2
+#define ETH_IMPOV_100_MASK (1 << ETH_IMPOV_100_SHIFT)
+#define ETH_IMPOV_1000_SHIFT 3
+#define ETH_IMPOV_1000_MASK (1 << ETH_IMPOV_1000_SHIFT)
+#define ETH_IMPOV_RXFLOW_SHIFT 4
+#define ETH_IMPOV_RXFLOW_MASK (1 << ETH_IMPOV_RXFLOW_SHIFT)
+#define ETH_IMPOV_TXFLOW_SHIFT 5
+#define ETH_IMPOV_TXFLOW_MASK (1 << ETH_IMPOV_TXFLOW_SHIFT)
+#define ETH_IMPOV_FORCE_SHIFT 7
+#define ETH_IMPOV_FORCE_MASK (1 << ETH_IMPOV_FORCE_SHIFT)
+
+/* Port override Register */
+#define ETH_PORTOV_REG(x) (0x58 + (x))
+#define ETH_PORTOV_LINKUP_SHIFT 0
+#define ETH_PORTOV_LINKUP_MASK (1 << ETH_PORTOV_LINKUP_SHIFT)
+#define ETH_PORTOV_FDX_SHIFT 1
+#define ETH_PORTOV_FDX_MASK (1 << ETH_PORTOV_FDX_SHIFT)
+#define ETH_PORTOV_100_SHIFT 2
+#define ETH_PORTOV_100_MASK (1 << ETH_PORTOV_100_SHIFT)
+#define ETH_PORTOV_1000_SHIFT 3
+#define ETH_PORTOV_1000_MASK (1 << ETH_PORTOV_1000_SHIFT)
+#define ETH_PORTOV_RXFLOW_SHIFT 4
+#define ETH_PORTOV_RXFLOW_MASK (1 << ETH_PORTOV_RXFLOW_SHIFT)
+#define ETH_PORTOV_TXFLOW_SHIFT 5
+#define ETH_PORTOV_TXFLOW_MASK (1 << ETH_PORTOV_TXFLOW_SHIFT)
+#define ETH_PORTOV_ENABLE_SHIFT 6
+#define ETH_PORTOV_ENABLE_MASK (1 << ETH_PORTOV_ENABLE_SHIFT)
+
+/* Port RGMII control register */
+#define ETH_RGMII_CTRL_REG(x) (0x60 + (x))
+#define ETH_RGMII_CTRL_GMII_CLK_EN (1 << 7)
+#define ETH_RGMII_CTRL_MII_OVERRIDE_EN (1 << 6)
+#define ETH_RGMII_CTRL_MII_MODE_MASK (3 << 4)
+#define ETH_RGMII_CTRL_RGMII_MODE (0 << 4)
+#define ETH_RGMII_CTRL_MII_MODE (1 << 4)
+#define ETH_RGMII_CTRL_RVMII_MODE (2 << 4)
+#define ETH_RGMII_CTRL_TIMING_SEL_EN (1 << 0)
+
+/* Port RGMII timing register */
+#define ENETSW_RGMII_TIMING_REG(x) (0x68 + (x))
+
+/* MDIO control register */
+#define MII_SC_REG 0xb0
+#define MII_SC_EXT_SHIFT 16
+#define MII_SC_EXT_MASK (1 << MII_SC_EXT_SHIFT)
+#define MII_SC_REG_SHIFT 20
+#define MII_SC_PHYID_SHIFT 25
+#define MII_SC_RD_SHIFT 30
+#define MII_SC_RD_MASK (1 << MII_SC_RD_SHIFT)
+#define MII_SC_WR_SHIFT 31
+#define MII_SC_WR_MASK (1 << MII_SC_WR_SHIFT)
+
+/* MDIO data register */
+#define MII_DAT_REG 0xb4
+
+/* Global Management Configuration Register */
+#define ETH_GMCR_REG 0x200
+#define ETH_GMCR_RST_MIB_SHIFT 0
+#define ETH_GMCR_RST_MIB_MASK (1 << ETH_GMCR_RST_MIB_SHIFT)
+
+/* Jumbo control register port mask register */
+#define ETH_JMBCTL_PORT_REG 0x4004
+
+/* Jumbo control mib good frame register */
+#define ETH_JMBCTL_MAXSIZE_REG 0x4008
+
+struct bcm_enetsw_port {
+ bool used;
+ int phy_id;
+
+ bool bypass_link;
+ int force_speed;
+ bool force_duplex_full;
+
+ const char *name;
+};
+
+/* ETH data */
+struct bcm6368_eth_priv {
+ struct udevice *dev;
+ void __iomem *base;
+ /* DMA */
+ struct dma rx_dma;
+ struct dma tx_dma;
+ /* Ports */
+ uint8_t num_ports;
+ struct bcm_enetsw_port used_ports[ETH_MAX_PORT];
+ int sw_port_link[ETH_MAX_PORT];
+ bool rgmii_override;
+ bool rgmii_timing;
+ /* PHY */
+ int phy_id;
+};
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static inline bool bcm_enet_port_is_rgmii(int portid)
+{
+ return portid >= ETH_RGMII_PORT0;
+}
+
+static int bcm6368_mdio_read(struct bcm6368_eth_priv *priv, uint8_t ext,
+ int phy_id, int reg)
+{
+ uint32_t val;
+
+ writel_be(0, priv->base + MII_SC_REG);
+
+ val = MII_SC_RD_MASK |
+ (phy_id << MII_SC_PHYID_SHIFT) |
+ (reg << MII_SC_REG_SHIFT);
+
+ if (ext)
+ val |= MII_SC_EXT_MASK;
+
+ writel_be(val, priv->base + MII_SC_REG);
+ udelay(50);
+
+ return readw_be(priv->base + MII_DAT_REG);
+}
+
+static int bcm6368_mdio_write(struct bcm6368_eth_priv *priv, uint8_t ext,
+ int phy_id, int reg, u16 data)
+{
+ uint32_t val;
+
+ writel_be(0, priv->base + MII_SC_REG);
+
+ val = MII_SC_WR_MASK |
+ (phy_id << MII_SC_PHYID_SHIFT) |
+ (reg << MII_SC_REG_SHIFT);
+
+ if (ext)
+ val |= MII_SC_EXT_MASK;
+
+ val |= data;
+
+ writel_be(val, priv->base + MII_SC_REG);
+ udelay(50);
+
+ return 0;
+}
+
+static int bcm6368_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+ return dma_receive(&priv->rx_dma, (void *)packetp, NULL);
+}
+
+static int bcm6368_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+ /* reset dma rx channel */
+ dma_disable(&priv->rx_dma);
+ dma_enable(&priv->rx_dma);
+
+ length = max(length, ETH_ZLEN);
+
+ return dma_send(&priv->tx_dma, (void **)packet, length, NULL);
+}
+
+static int bcm6368_eth_adjust_link(struct bcm6368_eth_priv *priv)
+{
+ unsigned int i;
+
+ for (i = 0; i < priv->num_ports; i++) {
+ struct bcm_enetsw_port *port;
+ int val, j, up, advertise, lpa, speed, duplex, media;
+ int external_phy = bcm_enet_port_is_rgmii(i);
+ u8 override;
+
+ port = &priv->used_ports[i];
+ if (!port->used)
+ continue;
+
+ if (port->bypass_link)
+ continue;
+
+ /* dummy read to clear */
+ for (j = 0; j < 2; j++)
+ val = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_BMSR);
+
+ if (val == 0xffff)
+ continue;
+
+ up = (val & BMSR_LSTATUS) ? 1 : 0;
+ if (!(up ^ priv->sw_port_link[i]))
+ continue;
+
+ priv->sw_port_link[i] = up;
+
+ /* link changed */
+ if (!up) {
+ dev_info(&priv->pdev->dev, "link DOWN on %s\n",
+ port->name);
+ writeb_be(ETH_PORTOV_ENABLE_MASK,
+ priv->base + ETH_PORTOV_REG(i));
+ writeb_be(ETH_PTCTRL_RXDIS_MASK |
+ ETH_PTCTRL_TXDIS_MASK,
+ priv->base + ETH_PTCTRL_REG(i));
+ continue;
+ }
+
+ advertise = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_ADVERTISE);
+
+ lpa = bcm6368_mdio_read(priv, external_phy, port->phy_id,
+ MII_LPA);
+
+ /* figure out media and duplex from advertise and LPA values */
+ media = mii_nway_result(lpa & advertise);
+ duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+
+ if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF))
+ speed = 100;
+ else
+ speed = 10;
+
+ if (val & BMSR_ESTATEN) {
+ advertise = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_CTRL1000);
+
+ lpa = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_STAT1000);
+
+ if (advertise & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)
+ && lpa & (LPA_1000FULL | LPA_1000HALF)) {
+ speed = 1000;
+ duplex = (lpa & LPA_1000FULL);
+ }
+ }
+
+ pr_alert("link UP on %s, %dMbps, %s-duplex\n",
+ port->name, speed, duplex ? "full" : "half");
+
+ override = ETH_PORTOV_ENABLE_MASK |
+ ETH_PORTOV_LINKUP_MASK;
+
+ if (speed == 1000)
+ override |= ETH_PORTOV_1000_MASK;
+ else if (speed == 100)
+ override |= ETH_PORTOV_100_MASK;
+ if (duplex)
+ override |= ETH_PORTOV_FDX_MASK;
+
+ writeb_be(override, priv->base + ETH_PORTOV_REG(i));
+ writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
+ }
+
+ return 0;
+}
+
+static int bcm6368_eth_start(struct udevice *dev)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+ int i;
+ u32 val;
+
+ /* disable all ports */
+ for (i = 0; i < priv->num_ports; i++) {
+ writeb_be(ETH_PORTOV_ENABLE_MASK,
+ priv->base + ETH_PORTOV_REG(i));
+ writeb_be(ETH_PTCTRL_RXDIS_MASK |
+ ETH_PTCTRL_TXDIS_MASK,
+ priv->base + ETH_PTCTRL_REG(i));
+
+ priv->sw_port_link[i] = 0;
+ }
+
+ /* enable external ports */
+ for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) {
+ u8 rgmii_ctrl;
+
+ if (!priv->used_ports[i].used)
+ continue;
+
+ rgmii_ctrl = readb_be(priv->base + ETH_RGMII_CTRL_REG(i));
+ rgmii_ctrl |= ETH_RGMII_CTRL_GMII_CLK_EN;
+ if (priv->rgmii_override)
+ rgmii_ctrl |= ETH_RGMII_CTRL_MII_OVERRIDE_EN;
+ if (priv->rgmii_timing)
+ rgmii_ctrl |= ETH_RGMII_CTRL_TIMING_SEL_EN;
+ writeb_be(rgmii_ctrl, priv->base + ETH_RGMII_CTRL_REG(i));
+ }
+
+ /* reset mib */
+ val = readb_be(priv->base + ETH_GMCR_REG);
+ val |= ETH_GMCR_RST_MIB_MASK;
+ writeb_be(val, priv->base + ETH_GMCR_REG);
+ mdelay(1);
+ val &= ~ETH_GMCR_RST_MIB_MASK;
+ writeb_be(val, priv->base + ETH_GMCR_REG);
+ mdelay(1);
+
+ /* force CPU port state */
+ val = readb_be(priv->base + ETH_IMPOV_REG);
+ val |= ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK;
+ writeb_be(val, priv->base + ETH_IMPOV_REG);
+
+ /* enable switch forward engine */
+ val = readb_be(priv->base + ETH_SWMODE_REG);
+ val |= ETH_SWMODE_FWD_EN_MASK;
+ writeb_be(val, priv->base + ETH_SWMODE_REG);
+
+ /* enable jumbo on all ports */
+ writel_be(0x1ff, priv->base + ETH_JMBCTL_PORT_REG);
+ writew_be(9728, priv->base + ETH_JMBCTL_MAXSIZE_REG);
+
+ /* enable dma rx channel */
+ dma_enable(&priv->rx_dma);
+
+ /* enable dma tx channel */
+ dma_enable(&priv->tx_dma);
+
+ /* apply override config for bypass_link ports here. */
+ for (i = 0; i < priv->num_ports; i++) {
+ struct bcm_enetsw_port *port;
+ u8 override;
+ port = &priv->used_ports[i];
+ if (!port->used)
+ continue;
+
+ if (!port->bypass_link)
+ continue;
+
+ override = ETH_PORTOV_ENABLE_MASK |
+ ETH_PORTOV_LINKUP_MASK;
+
+ switch (port->force_speed) {
+ case 1000:
+ override |= ETH_PORTOV_1000_MASK;
+ break;
+ case 100:
+ override |= ETH_PORTOV_100_MASK;
+ break;
+ case 10:
+ break;
+ default:
+ pr_warn("invalid forced speed on port %s: assume 10\n",
+ port->name);
+ break;
+ }
+
+ if (port->force_duplex_full)
+ override |= ETH_PORTOV_FDX_MASK;
+
+ writeb_be(override, priv->base + ETH_PORTOV_REG(i));
+ writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
+ }
+
+ bcm6368_eth_adjust_link(priv);
+
+ return 0;
+}
+
+static void bcm6368_eth_stop(struct udevice *dev)
+{
+ struct bcm6368_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);
+}
+
+static const struct eth_ops bcm6368_eth_ops = {
+ .recv = bcm6368_eth_recv,
+ .send = bcm6368_eth_send,
+ .start = bcm6368_eth_start,
+ .stop = bcm6368_eth_stop,
+};
+
+static const struct udevice_id bcm6368_eth_ids[] = {
+ { .compatible = "brcm,bcm6368-enet", },
+ { /* sentinel */ }
+};
+
+static bool bcm6368_phy_is_external(struct bcm6368_eth_priv *priv,
+ int phy_id)
+{
+ uint8_t i;
+
+ for (i = 0; i < priv->num_ports; ++i) {
+ if (!priv->used_ports[i].used)
+ continue;
+ if (priv->used_ports[i].phy_id == phy_id)
+ return bcm_enet_port_is_rgmii(i);
+ }
+
+ return true;
+}
+
+static int bcm6368_mii_mdio_read(struct mii_dev *bus, int addr, int devaddr,
+ int reg)
+{
+ struct bcm6368_eth_priv *priv = bus->priv;
+ bool ext = bcm6368_phy_is_external(priv, addr);
+
+ return bcm6368_mdio_read(priv, ext, addr, reg);
+}
+
+static int bcm6368_mii_mdio_write(struct mii_dev *bus, int addr, int devaddr,
+ int reg, u16 data)
+{
+ struct bcm6368_eth_priv *priv = bus->priv;
+ bool ext = bcm6368_phy_is_external(priv, addr);
+
+ return bcm6368_mdio_write(priv, ext, addr, reg, data);
+}
+
+static int bcm6368_mdio_init(const char *name, struct bcm6368_eth_priv *priv)
+{
+ struct mii_dev *bus;
+
+ bus = mdio_alloc();
+ if (!bus) {
+ pr_err("%s: failed to allocate MDIO bus\n", __func__);
+ return -ENOMEM;
+ }
+
+ bus->read = bcm6368_mii_mdio_read;
+ bus->write = bcm6368_mii_mdio_write;
+ bus->priv = priv;
+ snprintf(bus->name, sizeof(bus->name), "%s", name);
+
+ return mdio_register(bus);
+}
+
+static int bcm6368_eth_probe(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+ void *blob = (void *)gd->fdt_blob;
+ fdt_addr_t addr;
+ int node = dev_of_offset(dev);
+ int ret, i;
+ unsigned int num_ports;
+
+ /* get base address */
+ addr = devfdt_get_addr(dev);
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ /* get number of ports */
+ num_ports = fdtdec_get_uint(gd->fdt_blob, node, "brcm,num-ports",
+ ETH_MAX_PORT);
+ if (!num_ports || num_ports > ETH_MAX_PORT)
+ 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);
+ }
+
+ /* set priv data */
+ priv->dev = dev;
+
+ priv->base = ioremap(addr, 0);
+ pdata->iobase = (phys_addr_t) priv->base;
+
+ priv->num_ports = num_ports;
+
+ if (fdtdec_get_bool(gd->fdt_blob, i, "brcm,rgmii-override"))
+ priv->rgmii_override = true;
+ if (fdtdec_get_bool(gd->fdt_blob, i, "brcm,rgmii-timing"))
+ priv->rgmii_timing = true;
+
+ /* get ports */
+ for (i = fdt_first_subnode(blob, node);
+ i > 0;
+ i = fdt_next_subnode(blob, i)) {
+ const char *comp;
+ const char *label;
+ unsigned int p;
+ int phy_id;
+ int speed;
+
+ comp = fdt_getprop(blob, i, "compatible", NULL);
+ if (!comp || memcmp(comp, ETH_PORT_STR, sizeof(ETH_PORT_STR)))
+ continue;
+
+ p = fdtdec_get_uint(gd->fdt_blob, i, "reg",
+ ETH_MAX_PORT);
+ if (p >= num_ports)
+ return -EINVAL;
+
+ label = fdt_getprop(blob, i, "label", NULL);
+ if (!label) {
+ debug("%s: node %s has no label\n", __func__,
+ fdt_get_name(blob, i, NULL));
+ return -EINVAL;
+ }
+
+ phy_id = fdtdec_get_int(gd->fdt_blob, i, "brcm,phy-id", -1);
+
+ priv->used_ports[p].used = true;
+ priv->used_ports[p].name = label;
+ priv->used_ports[p].phy_id = phy_id;
+
+ if (fdtdec_get_bool(gd->fdt_blob, i, "full-duplex"))
+ priv->used_ports[p].force_duplex_full = true;
+ if (fdtdec_get_bool(gd->fdt_blob, i, "bypass-link"))
+ priv->used_ports[p].bypass_link = true;
+ speed = fdtdec_get_int(gd->fdt_blob, i, "speed", 0);
+ if (speed)
+ priv->used_ports[p].force_speed = speed;
+ }
+
+ /* init mii bus */
+ ret = bcm6368_mdio_init(dev->name, priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(bcm6368_eth) = {
+ .name = "bcm6368_eth",
+ .id = UCLASS_ETH,
+ .of_match = bcm6368_eth_ids,
+ .ops = &bcm6368_eth_ops,
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+ .priv_auto_alloc_size = sizeof(struct bcm6368_eth_priv),
+ .probe = bcm6368_eth_probe,
+};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 22/31] bmips: bcm6368: add support for bcm6368-enet
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (20 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 21/31] net: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 23/31] bmips: enable wap-5813n enet support Álvaro Fernández Rojas
` (11 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6368.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6368.dtsi b/arch/mips/dts/brcm,bcm6368.dtsi
index 30047f6360..89590d6ff9 100644
--- a/arch/mips/dts/brcm,bcm6368.dtsi
+++ b/arch/mips/dts/brcm,bcm6368.dtsi
@@ -205,5 +205,24 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10f00000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10f00000 0x10000>;
+ clocks = <&periph_clk BCM6368_CLK_SWPKT_USB>,
+ <&periph_clk BCM6368_CLK_SWPKT_SAR>,
+ <&periph_clk BCM6368_CLK_ROBOSW>;
+ resets = <&periph_rst BCM6368_RST_SWITCH>,
+ <&periph_rst BCM6368_RST_EPHY>;
+ dmas = <&iudma BCM6368_DMA_ENETSW_RX>,
+ <&iudma BCM6368_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <6>;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 23/31] bmips: enable wap-5813n enet support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (21 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 22/31] bmips: bcm6368: " Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 24/31] bmips: bcm6328: add support for bcm6368-enet Álvaro Fernández Rojas
` (10 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,wap-5813n.dts | 14 ++++++++++++++
configs/comtrend_wap5813n_ram_defconfig | 8 +++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,wap-5813n.dts b/arch/mips/dts/comtrend,wap-5813n.dts
index bd41dab9f8..7e835b28d2 100644
--- a/arch/mips/dts/comtrend,wap-5813n.dts
+++ b/arch/mips/dts/comtrend,wap-5813n.dts
@@ -54,6 +54,20 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 4 {
+ compatible = "brcm,enetsw-port";
+ reg = <4>;
+ label = "rgmii";
+ brcm,phy-id = <0xff>;
+ speed = <1000>;
+ full-duplex;
+ bypass-link;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/comtrend_wap5813n_ram_defconfig b/configs/comtrend_wap5813n_ram_defconfig
index 987e4c3fbc..fd5107bb7d 100644
--- a/configs/comtrend_wap5813n_ram_defconfig
+++ b/configs/comtrend_wap5813n_ram_defconfig
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,wap-5813n"
-# CONFIG_NET is not set
+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_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_DM_RESET=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 24/31] bmips: bcm6328: add support for bcm6368-enet
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (22 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 23/31] bmips: enable wap-5813n enet support Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 25/31] bmips: enable ar-5387un enet support Álvaro Fernández Rojas
` (9 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6328.dtsi | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi
index 6fa49e22bb..50beed4171 100644
--- a/arch/mips/dts/brcm,bcm6328.dtsi
+++ b/arch/mips/dts/brcm,bcm6328.dtsi
@@ -200,5 +200,22 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10e00000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10e00000 0x10000>;
+ clocks = <&periph_clk BCM6328_CLK_ROBOSW>;
+ resets = <&periph_rst BCM6328_RST_ENETSW>,
+ <&periph_rst BCM6328_RST_EPHY>;
+ dmas = <&iudma BCM6328_DMA_ENETSW_RX>,
+ <&iudma BCM6328_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <5>;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 25/31] bmips: enable ar-5387un enet support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (23 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 24/31] bmips: bcm6328: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 26/31] bmips: bcm6362: add support for bcm6368-enet Álvaro Fernández Rojas
` (8 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,ar-5387un.dts | 32 ++++++++++++++++++++++++++++++++
configs/comtrend_ar5387un_ram_defconfig | 7 ++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,ar-5387un.dts b/arch/mips/dts/comtrend,ar-5387un.dts
index e993b5cd89..03e3851ab1 100644
--- a/arch/mips/dts/comtrend,ar-5387un.dts
+++ b/arch/mips/dts/comtrend,ar-5387un.dts
@@ -24,6 +24,38 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 0 {
+ compatible = "brcm,enetsw-port";
+ reg = <0>;
+ label = "fe1";
+ brcm,phy-id = <1>;
+ };
+
+ port at 1 {
+ compatible = "brcm,enetsw-port";
+ reg = <1>;
+ label = "fe2";
+ brcm,phy-id = <2>;
+ };
+
+ port at 2 {
+ compatible = "brcm,enetsw-port";
+ reg = <2>;
+ label = "fe3";
+ brcm,phy-id = <3>;
+ };
+
+ port at 3 {
+ compatible = "brcm,enetsw-port";
+ reg = <3>;
+ label = "fe4";
+ brcm,phy-id = <4>;
+ };
+};
+
&leds {
status = "okay";
diff --git a/configs/comtrend_ar5387un_ram_defconfig b/configs/comtrend_ar5387un_ram_defconfig
index f129870ca0..5ba401a441 100644
--- a/configs/comtrend_ar5387un_ram_defconfig
+++ b/configs/comtrend_ar5387un_ram_defconfig
@@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5387un"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
CONFIG_DM_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
@@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 26/31] bmips: bcm6362: add support for bcm6368-enet
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (24 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 25/31] bmips: enable ar-5387un enet support Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 27/31] bmips: enable dgnd3700v2 enet support Álvaro Fernández Rojas
` (7 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6362.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6362.dtsi b/arch/mips/dts/brcm,bcm6362.dtsi
index 94e7de096d..c77b80a4cc 100644
--- a/arch/mips/dts/brcm,bcm6362.dtsi
+++ b/arch/mips/dts/brcm,bcm6362.dtsi
@@ -224,5 +224,24 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10e00000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10e00000 0x10000>;
+ clocks = <&periph_clk BCM6362_CLK_SWPKT_USB>,
+ <&periph_clk BCM6362_CLK_SWPKT_SAR>,
+ <&periph_clk BCM6362_CLK_ROBOSW>;
+ resets = <&periph_rst BCM6362_RST_ENETSW>,
+ <&periph_rst BCM6362_RST_EPHY>;
+ dmas = <&iudma BCM6362_DMA_ENETSW_RX>,
+ <&iudma BCM6362_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <6>;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 27/31] bmips: enable dgnd3700v2 enet support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (25 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 26/31] bmips: bcm6362: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 28/31] bmips: bcm63268: add support for bcm6368-enet Álvaro Fernández Rojas
` (6 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/netgear,dgnd3700v2.dts | 14 ++++++++++++++
configs/netgear_dgnd3700v2_ram_defconfig | 8 +++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/netgear,dgnd3700v2.dts b/arch/mips/dts/netgear,dgnd3700v2.dts
index 322d1567ff..2b72491f0b 100644
--- a/arch/mips/dts/netgear,dgnd3700v2.dts
+++ b/arch/mips/dts/netgear,dgnd3700v2.dts
@@ -43,6 +43,20 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 4 {
+ compatible = "brcm,enetsw-port";
+ reg = <4>;
+ label = "rgmii";
+ brcm,phy-id = <0xff>;
+ speed = <1000>;
+ full-duplex;
+ bypass-link;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/netgear_dgnd3700v2_ram_defconfig b/configs/netgear_dgnd3700v2_ram_defconfig
index 1abc869856..0f3914fe7e 100644
--- a/configs/netgear_dgnd3700v2_ram_defconfig
+++ b/configs/netgear_dgnd3700v2_ram_defconfig
@@ -27,17 +27,23 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
-# CONFIG_CMD_NET is not set
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="netgear,dgnd3700v2"
+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
CONFIG_LED_BCM6328=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 28/31] bmips: bcm63268: add support for bcm6368-enet
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (26 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 27/31] bmips: enable dgnd3700v2 enet support Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 29/31] bmips: enable vr-3032u enet support Álvaro Fernández Rojas
` (5 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm63268.dtsi | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi
index c7ad83c306..f8a72ef535 100644
--- a/arch/mips/dts/brcm,bcm63268.dtsi
+++ b/arch/mips/dts/brcm,bcm63268.dtsi
@@ -230,5 +230,30 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10700000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10700000 0x10000>;
+ clocks = <&periph_clk BCM63268_CLK_GMAC>,
+ <&periph_clk BCM63268_CLK_ROBOSW>,
+ <&periph_clk BCM63268_CLK_ROBOSW250>,
+ <&timer_clk BCM63268_TCLK_EPHY1>,
+ <&timer_clk BCM63268_TCLK_EPHY2>,
+ <&timer_clk BCM63268_TCLK_EPHY3>,
+ <&timer_clk BCM63268_TCLK_GPHY>;
+ resets = <&periph_rst BCM63268_RST_ENETSW>,
+ <&periph_rst BCM63268_RST_EPHY>,
+ <&periph_rst BCM63268_RST_GPHY>;
+ dmas = <&iudma BCM63268_DMA_ENETSW_RX>,
+ <&iudma BCM63268_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,rgmii-override;
+ brcm,rgmii-timing;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 29/31] bmips: enable vr-3032u enet support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (27 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 28/31] bmips: bcm63268: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 30/31] bmips: bcm6318: add support for bcm6368-enet Álvaro Fernández Rojas
` (4 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,vr-3032u.dts | 32 ++++++++++++++++++++++++++++++++
configs/comtrend_vr3032u_ram_defconfig | 7 ++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,vr-3032u.dts b/arch/mips/dts/comtrend,vr-3032u.dts
index 8c6a4a1eac..512cb52de3 100644
--- a/arch/mips/dts/comtrend,vr-3032u.dts
+++ b/arch/mips/dts/comtrend,vr-3032u.dts
@@ -24,6 +24,38 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 0 {
+ compatible = "brcm,enetsw-port";
+ reg = <0>;
+ label = "fe2";
+ brcm,phy-id = <1>;
+ };
+
+ port at 1 {
+ compatible = "brcm,enetsw-port";
+ reg = <1>;
+ label = "fe3";
+ brcm,phy-id = <2>;
+ };
+
+ port at 2 {
+ compatible = "brcm,enetsw-port";
+ reg = <2>;
+ label = "fe4";
+ brcm,phy-id = <3>;
+ };
+
+ port at 3 {
+ compatible = "brcm,enetsw-port";
+ reg = <3>;
+ label = "fe1";
+ brcm,phy-id = <4>;
+ };
+};
+
&leds {
status = "okay";
brcm,serial-leds;
diff --git a/configs/comtrend_vr3032u_ram_defconfig b/configs/comtrend_vr3032u_ram_defconfig
index 1689eecec1..47f53998e1 100644
--- a/configs/comtrend_vr3032u_ram_defconfig
+++ b/configs/comtrend_vr3032u_ram_defconfig
@@ -26,15 +26,20 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,vr-3032u"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
CONFIG_DM_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
CONFIG_LED_BLINK=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 30/31] bmips: bcm6318: add support for bcm6368-enet
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (28 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 29/31] bmips: enable vr-3032u enet support Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 18:00 ` [U-Boot] [PATCH v8 31/31] bmips: enable ar-5315u enet support Álvaro Fernández Rojas
` (3 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6318.dtsi | 19 +++++++++++++++++++
include/dt-bindings/clock/bcm6318-clock.h | 11 +++++++++++
2 files changed, 30 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6318.dtsi b/arch/mips/dts/brcm,bcm6318.dtsi
index d04b7cbb01..d678dab242 100644
--- a/arch/mips/dts/brcm,bcm6318.dtsi
+++ b/arch/mips/dts/brcm,bcm6318.dtsi
@@ -190,6 +190,25 @@
status = "disabled";
};
+ enet: ethernet at 10080000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10080000 0x8000>;
+ clocks = <&periph_clk BCM6318_CLK_ROBOSW250>,
+ <&periph_clk BCM6318_CLK_ROBOSW025>,
+ <&ubus_clk BCM6318_UCLK_ROBOSW>;
+ resets = <&periph_rst BCM6318_RST_ENETSW>,
+ <&periph_rst BCM6318_RST_EPHY>;
+ dmas = <&iudma BCM6318_DMA_ENETSW_RX>,
+ <&iudma BCM6318_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <5>;
+
+ status = "disabled";
+ };
+
iudma: dma-controller at 10088000 {
compatible = "brcm,bcm6368-iudma";
reg = <0x10088000 0x80>,
diff --git a/include/dt-bindings/clock/bcm6318-clock.h b/include/dt-bindings/clock/bcm6318-clock.h
index d5e13c5c2d..3f10448cef 100644
--- a/include/dt-bindings/clock/bcm6318-clock.h
+++ b/include/dt-bindings/clock/bcm6318-clock.h
@@ -33,4 +33,15 @@
#define BCM6318_CLK_AFE 29
#define BCM6318_CLK_QPROC 30
+#define BCM6318_UCLK_ADSL 0
+#define BCM6318_UCLK_ARB 1
+#define BCM6318_UCLK_MIPS 2
+#define BCM6318_UCLK_PCIE 3
+#define BCM6318_UCLK_PERIPH 4
+#define BCM6318_UCLK_PHYMIPS 5
+#define BCM6318_UCLK_ROBOSW 6
+#define BCM6318_UCLK_SAR 7
+#define BCM6318_UCLK_SDR 8
+#define BCM6318_UCLK_USB 9
+
#endif /* __DT_BINDINGS_CLOCK_BCM6318_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 31/31] bmips: enable ar-5315u enet support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (29 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 30/31] bmips: bcm6318: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-26 18:00 ` Álvaro Fernández Rojas
2018-11-26 23:15 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Tom Rini
` (2 subsequent siblings)
33 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-26 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,ar-5315u.dts | 32 ++++++++++++++++++++++++++++++++
configs/comtrend_ar5315u_ram_defconfig | 7 ++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,ar-5315u.dts b/arch/mips/dts/comtrend,ar-5315u.dts
index 45570189d0..eb60aaa8d5 100644
--- a/arch/mips/dts/comtrend,ar-5315u.dts
+++ b/arch/mips/dts/comtrend,ar-5315u.dts
@@ -24,6 +24,38 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 0 {
+ compatible = "brcm,enetsw-port";
+ reg = <0>;
+ label = "fe4";
+ brcm,phy-id = <1>;
+ };
+
+ port at 1 {
+ compatible = "brcm,enetsw-port";
+ reg = <1>;
+ label = "fe3";
+ brcm,phy-id = <2>;
+ };
+
+ port at 2 {
+ compatible = "brcm,enetsw-port";
+ reg = <2>;
+ label = "fe2";
+ brcm,phy-id = <3>;
+ };
+
+ port at 3 {
+ compatible = "brcm,enetsw-port";
+ reg = <3>;
+ label = "fe1";
+ brcm,phy-id = <4>;
+ };
+};
+
&leds {
status = "okay";
diff --git a/configs/comtrend_ar5315u_ram_defconfig b/configs/comtrend_ar5315u_ram_defconfig
index d9ef52e68d..1b8e4e43c4 100644
--- a/configs/comtrend_ar5315u_ram_defconfig
+++ b/configs/comtrend_ar5315u_ram_defconfig
@@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5315u"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
CONFIG_DM_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
@@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6318_USBH_PHY=y
CONFIG_BCM6328_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v8 00/31] dma: add channels support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (30 preceding siblings ...)
2018-11-26 18:00 ` [U-Boot] [PATCH v8 31/31] bmips: enable ar-5315u enet support Álvaro Fernández Rojas
@ 2018-11-26 23:15 ` Tom Rini
2018-11-28 18:17 ` [U-Boot] [PATCH v9 0/3] " Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
33 siblings, 0 replies; 145+ messages in thread
From: Tom Rini @ 2018-11-26 23:15 UTC (permalink / raw)
To: u-boot
On Mon, Nov 26, 2018 at 07:00:08PM +0100, Álvaro Fernández Rojas wrote:
> In 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...).
>
> ===
>
> 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.
>
> DMA channel API:
> dma_get_by_index()
> dma_get_by_name()
> dma_request()
> dma_free()
> dma_enable()
> dma_disable()
> dma_prepare_rcv_buf()
> dma_receive()
> dma_send()
>
> A driver that implements UCLASS_DMA is a DMA provider. A provider will
> often implement multiple separate DMAs channels, 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.
>
> DMA consumer DMA_MEM_TO_DEV (transmit) usage example (based on networking).
> Note. In u-boot dma_send() is sync operation always - it'll start transfer and
> will poll for it to complete:
> - get/request dma channel
> struct dma dma_tx;
> ret = dma_get_by_name(common->dev, "tx0", &dma_tx);
> if (ret) ...
>
> - enable dma channel
> ret = dma_enable(&dma_tx);
> if (ret) ...
>
> - dma transmit DMA_MEM_TO_DEV.
> struct ti_drv_packet_data packet_data;
>
> packet_data.opt1 = val1;
> packet_data.opt2 = val2;
> ret = dma_send(&dma_tx, packet, length, &packet_data);
> if (ret) ..
>
> DMA consumer DMA_DEV_TO_MEM (receive) usage example (based on networking).
> Note. dma_receive() is sync operation always - it'll start transfer
> (if required) and will poll for it to complete (or for any previously
> configured dev2mem transfer to complete):
> - get/request dma channel
> struct dma dma_rx;
> ret = dma_get_by_name(common->dev, "rx0", &dma_rx);
> if (ret) ...
>
> - enable dma channel
> ret = dma_enable(&dma_rx);
> if (ret) ...
>
> - dma receive DMA_DEV_TO_MEM.
> struct ti_drv_packet_data packet_data;
>
> len = dma_receive(&dma_rx, (void **)packet, &packet_data);
> if (ret < 0) ...
>
> DMA consumer DMA_DEV_TO_MEM (receive) zero-copy usage example (based on
> networking). Networking subsystem allows to configure and use few receive
> buffers (dev2mem), as Networking RX DMA channels usually implemented
> as streaming interface
> - get/request dma channel
> struct dma dma_rx;
> ret = dma_get_by_name(common->dev, "rx0", &dma_rx);
> if (ret) ...
>
> for (i = 0; i < RX_DESC_NUM; i++) {
> ret = dma_prepare_rcv_buf(&dma_rx,
> net_rx_packets[i],
> RX_BUF_SIZE);
> if (ret) ...
> }
>
> - enable dma channel
> ret = dma_enable(&dma_rx);
> if (ret) ...
>
> - dma receive DMA_DEV_TO_MEM.
> struct ti_drv_packet_data packet_data;
> void *packet;
>
> len = dma_receive(&dma_rx, &packet, &packet_data);
> if (ret < 0) ..
>
> /* packet - points on buffer prepared by dma_prepare_rcv_buf().
> process packet*/
>
> - return buffer back to DAM channel
> ret = dma_prepare_rcv_buf(&dma_rx,
> net_rx_packets[rx_next],
> RX_BUF_SIZE);
>
Can you please split this into 2 parts, the generic DMA portion, and the
bcm6368-enet/etc part? Thanks!
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181126/ad0bf55c/attachment.sig>
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 0/3] dma: add channels support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (31 preceding siblings ...)
2018-11-26 23:15 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Tom Rini
@ 2018-11-28 18:17 ` Álvaro Fernández Rojas
2018-11-28 18:17 ` [U-Boot] [PATCH v9 1/3] dma: move dma_ops to dma-uclass.h Álvaro Fernández Rojas
` (3 more replies)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
33 siblings, 4 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:17 UTC (permalink / raw)
To: u-boot
In 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...).
===
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.
DMA channel API:
dma_get_by_index()
dma_get_by_name()
dma_request()
dma_free()
dma_enable()
dma_disable()
dma_prepare_rcv_buf()
dma_receive()
dma_send()
A driver that implements UCLASS_DMA is a DMA provider. A provider will
often implement multiple separate DMAs channels, 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.
DMA consumer DMA_MEM_TO_DEV (transmit) usage example (based on networking).
Note. In u-boot dma_send() is sync operation always - it'll start transfer and
will poll for it to complete:
- get/request dma channel
struct dma dma_tx;
ret = dma_get_by_name(common->dev, "tx0", &dma_tx);
if (ret) ...
- enable dma channel
ret = dma_enable(&dma_tx);
if (ret) ...
- dma transmit DMA_MEM_TO_DEV.
struct ti_drv_packet_data packet_data;
packet_data.opt1 = val1;
packet_data.opt2 = val2;
ret = dma_send(&dma_tx, packet, length, &packet_data);
if (ret) ..
DMA consumer DMA_DEV_TO_MEM (receive) usage example (based on networking).
Note. dma_receive() is sync operation always - it'll start transfer
(if required) and will poll for it to complete (or for any previously
configured dev2mem transfer to complete):
- get/request dma channel
struct dma dma_rx;
ret = dma_get_by_name(common->dev, "rx0", &dma_rx);
if (ret) ...
- enable dma channel
ret = dma_enable(&dma_rx);
if (ret) ...
- dma receive DMA_DEV_TO_MEM.
struct ti_drv_packet_data packet_data;
len = dma_receive(&dma_rx, (void **)packet, &packet_data);
if (ret < 0) ...
DMA consumer DMA_DEV_TO_MEM (receive) zero-copy usage example (based on
networking). Networking subsystem allows to configure and use few receive
buffers (dev2mem), as Networking RX DMA channels usually implemented
as streaming interface
- get/request dma channel
struct dma dma_rx;
ret = dma_get_by_name(common->dev, "rx0", &dma_rx);
if (ret) ...
for (i = 0; i < RX_DESC_NUM; i++) {
ret = dma_prepare_rcv_buf(&dma_rx,
net_rx_packets[i],
RX_BUF_SIZE);
if (ret) ...
}
- enable dma channel
ret = dma_enable(&dma_rx);
if (ret) ...
- dma receive DMA_DEV_TO_MEM.
struct ti_drv_packet_data packet_data;
void *packet;
len = dma_receive(&dma_rx, &packet, &packet_data);
if (ret < 0) ..
/* packet - points on buffer prepared by dma_prepare_rcv_buf().
process packet*/
- return buffer back to DAM channel
ret = dma_prepare_rcv_buf(&dma_rx,
net_rx_packets[rx_next],
RX_BUF_SIZE);
===
v9: Separate generic dma channels support from bmips enet support
v8: Sync with latest u-boot.
v7: From Grygorii Strashko:
- copyright fixed as suggested by Tom Rini
- added "Reviewed-by" tags
v6: From Grygorii Strashko:
- added possibility to pass DMA driver/channel's specific data per each
transfer using additional parameter "metadata" in dma_send/dma_receive() API.
For example, port number for network packets to be directed to the
specific port on multi port ethernet controllers.
- added new dma_prepare_rcv_buf() API which allows to implement zero-copy
DEV_TO_MEM transfer using DMA streaming channels which is usual case
for Networking.
- added dma-uclass test
- removed unused function dma_get_by_index_platdata()
- updated comments
v5: Fix build of ti-edma3.
v4: No changes
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.
Grygorii Strashko (1):
test: dma: add dma-uclass test
Álvaro Fernández Rojas (2):
dma: move dma_ops to dma-uclass.h
dma: add channels support
arch/sandbox/dts/test.dts | 8 ++
configs/sandbox_defconfig | 3 +
drivers/dma/Kconfig | 14 ++
drivers/dma/Makefile | 1 +
drivers/dma/dma-uclass.c | 183 +++++++++++++++++++++++++-
drivers/dma/sandbox-dma-test.c | 282 +++++++++++++++++++++++++++++++++++++++++
drivers/dma/ti-edma3.c | 2 +-
include/dma-uclass.h | 128 +++++++++++++++++++
include/dma.h | 282 +++++++++++++++++++++++++++++++++++++----
test/dm/Makefile | 1 +
test/dm/dma.c | 123 ++++++++++++++++++
11 files changed, 997 insertions(+), 30 deletions(-)
create mode 100644 drivers/dma/sandbox-dma-test.c
create mode 100644 include/dma-uclass.h
create mode 100644 test/dm/dma.c
--
2.11.0
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 1/3] dma: move dma_ops to dma-uclass.h
2018-11-28 18:17 ` [U-Boot] [PATCH v9 0/3] " Álvaro Fernández Rojas
@ 2018-11-28 18:17 ` Álvaro Fernández Rojas
2018-12-07 20:33 ` [U-Boot] [U-Boot,v9,1/3] " Tom Rini
2018-11-28 18:17 ` [U-Boot] [PATCH v9 2/3] dma: add channels support Álvaro Fernández Rojas
` (2 subsequent siblings)
3 siblings, 1 reply; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:17 UTC (permalink / raw)
To: u-boot
Move dma_ops to a separate header file, following other uclass
implementations. While doing so, this patch also improves dma_ops
documentation.
Reviewed-by: Tom Rini <trini@konsulko.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
v9: no changes
v8: no changes
v7: From Grygorii Strashko:
- copyright fixed as suggested by Tom Rini
- added "Reviewed-by" tags
v6: no changes
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
diff --git a/drivers/dma/dma-uclass.c b/drivers/dma/dma-uclass.c
index a33f7d52da..6c3506c302 100644
--- a/drivers/dma/dma-uclass.c
+++ b/drivers/dma/dma-uclass.c
@@ -9,10 +9,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>
int dma_get_device(u32 transfer_type, struct udevice **devp)
diff --git a/drivers/dma/ti-edma3.c b/drivers/dma/ti-edma3.c
index 2131e10a40..7e11b13e45 100644
--- a/drivers/dma/ti-edma3.c
+++ b/drivers/dma/ti-edma3.c
@@ -11,7 +11,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>
diff --git a/include/dma-uclass.h b/include/dma-uclass.h
new file mode 100644
index 0000000000..7bec5d3399
--- /dev/null
+++ b/include/dma-uclass.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com>
+ * Written by Mugunthan V N <mugunthanvnm@ti.com>
+ *
+ */
+
+#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 */
diff --git a/include/dma.h b/include/dma.h
index 50e965241c..97fa0cf695 100644
--- a/include/dma.h
+++ b/include/dma.h
@@ -27,28 +27,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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 2/3] dma: add channels support
2018-11-28 18:17 ` [U-Boot] [PATCH v9 0/3] " Álvaro Fernández Rojas
2018-11-28 18:17 ` [U-Boot] [PATCH v9 1/3] dma: move dma_ops to dma-uclass.h Álvaro Fernández Rojas
@ 2018-11-28 18:17 ` Álvaro Fernández Rojas
2018-12-07 20:33 ` [U-Boot] [U-Boot,v9,2/3] " Tom Rini
2018-11-28 18:17 ` [U-Boot] [PATCH v9 3/3] test: dma: add dma-uclass test Álvaro Fernández Rojas
2018-11-30 23:56 ` [U-Boot] [PATCH v9 0/3] dma: add channels support Grygorii Strashko
3 siblings, 1 reply; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:17 UTC (permalink / raw)
To: u-boot
This adds channels support for dma controllers that have multiple channels
which can transfer data to/from different devices (enet, usb...).
DMA channle API:
dma_get_by_index()
dma_get_by_name()
dma_request()
dma_free()
dma_enable()
dma_disable()
dma_prepare_rcv_buf()
dma_receive()
dma_send()
Reviewed-by: Tom Rini <trini@konsulko.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
[grygorii.strashko at ti.com: drop unused dma_get_by_index_platdata(),
add metadata to send/receive ops, add dma_prepare_rcv_buf(),
minor clean up]
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
v9: no changes
v8: no changes
v7: From Grygorii Strashko:
- copyright fixed as suggested by Tom Rini
- added "Reviewed-by" tags
v6: From Grygorii Strashko:
- added possibility to pass DMA driver/channel's specific data per each
transfer using additional parameter "metadata" in dma_send/dma_receive() API.
For example, port number for network packets to be directed to the
specific port on multi port ethernet controllers.
- added new dma_prepare_rcv_buf() API which allows to implement zero-copy
DEV_TO_MEM transfer using DMA streaming channels which is usual case
for Networking.
- removed unused function dma_get_by_index_platdata()
- updated comments
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 | 181 ++++++++++++++++++++++++++++++++-
include/dma-uclass.h | 91 ++++++++++++++++-
include/dma.h | 260 ++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 532 insertions(+), 7 deletions(-)
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 4ee6afad35..b9b85c65fc 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -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
diff --git a/drivers/dma/dma-uclass.c b/drivers/dma/dma-uclass.c
index 6c3506c302..9c961cf1e2 100644
--- a/drivers/dma/dma-uclass.c
+++ b/drivers/dma/dma-uclass.c
@@ -2,19 +2,192 @@
/*
* Direct Memory Access U-Class driver
*
- * (C) Copyright 2015
- * Texas Instruments Incorporated, <www.ti.com>
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2015 - 2018 Texas Instruments Incorporated <www.ti.com>
+ * Written by Mugunthan V N <mugunthanvnm@ti.com>
*
* Author: Mugunthan V N <mugunthanvnm@ti.com>
*/
#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>
+#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)
+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);
+}
+
+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_prepare_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+ struct dma_ops *ops = dma_dev_ops(dma->dev);
+
+ debug("%s(dma=%p)\n", __func__, dma);
+
+ if (!ops->prepare_rcv_buf)
+ return -1;
+
+ return ops->prepare_rcv_buf(dma, dst, size);
+}
+
+int dma_receive(struct dma *dma, void **dst, void *metadata)
+{
+ struct dma_ops *ops = dma_dev_ops(dma->dev);
+
+ debug("%s(dma=%p)\n", __func__, dma);
+
+ if (!ops->receive)
+ return -ENOSYS;
+
+ return ops->receive(dma, dst, metadata);
+}
+
+int dma_send(struct dma *dma, void *src, size_t len, void *metadata)
+{
+ struct dma_ops *ops = dma_dev_ops(dma->dev);
+
+ debug("%s(dma=%p)\n", __func__, dma);
+
+ if (!ops->send)
+ return -ENOSYS;
+
+ return ops->send(dma, src, len, metadata);
+}
+#endif /* CONFIG_DMA_CHANNELS */
+
int dma_get_device(u32 transfer_type, struct udevice **devp)
{
struct udevice *dev;
diff --git a/include/dma-uclass.h b/include/dma-uclass.h
index 7bec5d3399..16fc879a5c 100644
--- a/include/dma-uclass.h
+++ b/include/dma-uclass.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
- * Copyright (C) 2015 Texas Instruments Incorporated <www.ti.com>
+ * Copyright (C) 2015 - 2018 Texas Instruments Incorporated <www.ti.com>
* Written by Mugunthan V N <mugunthanvnm@ti.com>
*
*/
@@ -13,6 +13,8 @@
#include <dma.h>
+struct ofnode_phandle_args;
+
/*
* struct dma_ops - Driver model DMA operations
*
@@ -20,6 +22,93 @@
* 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);
+ /**
+ * add_rcv_buf() - Prepare/Add receive DMA buffer.
+ *
+ * @dma: The DMA Channel to manipulate.
+ * @dst: The receive buffer pointer.
+ * @size: The receive buffer size
+ * @return zero on success, or -ve error code.
+ */
+ int (*prepare_rcv_buf)(struct dma *dma, void *dst, size_t size);
+ /**
+ * receive() - Receive a DMA transfer.
+ *
+ * @dma: The DMA Channel to manipulate.
+ * @dst: The destination pointer.
+ * @metadata: DMA driver's specific data
+ * @return zero on success, or -ve error code.
+ */
+ int (*receive)(struct dma *dma, void **dst, void *metadata);
+ /**
+ * 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).
+ * @metadata: DMA driver's specific data
+ * @return zero on success, or -ve error code.
+ */
+ int (*send)(struct dma *dma, void *src, size_t len, void *metadata);
+#endif /* CONFIG_DMA_CHANNELS */
/**
* transfer() - Issue a DMA transfer. The implementation must
* wait until the transfer is done.
diff --git a/include/dma.h b/include/dma.h
index 97fa0cf695..d1c3d0df7d 100644
--- a/include/dma.h
+++ b/include/dma.h
@@ -1,12 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * (C) Copyright 2015
- * Texas Instruments Incorporated, <www.ti.com>
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ * Copyright (C) 2015 - 2018 Texas Instruments Incorporated <www.ti.com>
+ * Written by Mugunthan V N <mugunthanvnm@ti.com>
+ *
*/
#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
@@ -36,6 +41,257 @@ 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.
+ *
+ * DMA consumer DMA_MEM_TO_DEV (transmit) usage example (based on networking).
+ * Note. dma_send() is sync operation always - it'll start transfer and will
+ * poll for it to complete:
+ * - get/request dma channel
+ * struct dma dma_tx;
+ * ret = dma_get_by_name(common->dev, "tx0", &dma_tx);
+ * if (ret) ...
+ *
+ * - enable dma channel
+ * ret = dma_enable(&dma_tx);
+ * if (ret) ...
+ *
+ * - dma transmit DMA_MEM_TO_DEV.
+ * struct ti_drv_packet_data packet_data;
+ *
+ * packet_data.opt1 = val1;
+ * packet_data.opt2 = val2;
+ * ret = dma_send(&dma_tx, packet, length, &packet_data);
+ * if (ret) ..
+ *
+ * DMA consumer DMA_DEV_TO_MEM (receive) usage example (based on networking).
+ * Note. dma_receive() is sync operation always - it'll start transfer
+ * (if required) and will poll for it to complete (or for any previously
+ * configured dev2mem transfer to complete):
+ * - get/request dma channel
+ * struct dma dma_rx;
+ * ret = dma_get_by_name(common->dev, "rx0", &dma_rx);
+ * if (ret) ...
+ *
+ * - enable dma channel
+ * ret = dma_enable(&dma_rx);
+ * if (ret) ...
+ *
+ * - dma receive DMA_DEV_TO_MEM.
+ * struct ti_drv_packet_data packet_data;
+ *
+ * len = dma_receive(&dma_rx, (void **)packet, &packet_data);
+ * if (ret < 0) ...
+ *
+ * DMA consumer DMA_DEV_TO_MEM (receive) zero-copy usage example (based on
+ * networking). Networking subsystem allows to configure and use few receive
+ * buffers (dev2mem), as Networking RX DMA channels usually implemented
+ * as streaming interface
+ * - get/request dma channel
+ * struct dma dma_rx;
+ * ret = dma_get_by_name(common->dev, "rx0", &dma_rx);
+ * if (ret) ...
+ *
+ * for (i = 0; i < RX_DESC_NUM; i++) {
+ * ret = dma_prepare_rcv_buf(&dma_rx,
+ * net_rx_packets[i],
+ * RX_BUF_SIZE);
+ * if (ret) ...
+ * }
+ *
+ * - enable dma channel
+ * ret = dma_enable(&dma_rx);
+ * if (ret) ...
+ *
+ * - dma receive DMA_DEV_TO_MEM.
+ * struct ti_drv_packet_data packet_data;
+ *
+ * len = dma_receive(&dma_rx, (void **)packet, &packet_data);
+ * if (ret < 0) ..
+ *
+ * -- process packet --
+ *
+ * - return buffer back to DAM channel
+ * ret = dma_prepare_rcv_buf(&dma_rx,
+ * net_rx_packets[rx_next],
+ * RX_BUF_SIZE);
+ */
+
+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)
+/**
+ * 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_prepare_rcv_buf() - Prepare/add receive DMA buffer.
+ *
+ * It allows to implement zero-copy async DMA_DEV_TO_MEM (receive) transactions
+ * if supported by DMA providers.
+ *
+ * @dma: A DMA struct that was previously successfully requested by
+ * dma_request/get_by_*().
+ * @dst: The receive buffer pointer.
+ * @size: The receive buffer size
+ * @return zero on success, or -ve error code.
+ */
+int dma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size);
+
+/**
+ * dma_receive() - Receive a DMA transfer.
+ *
+ * @dma: A DMA struct that was previously successfully requested by
+ * dma_request/get_by_*().
+ * @dst: The destination pointer.
+ * @metadata: DMA driver's channel specific data
+ * @return length of received data on success, or zero - no data,
+ * or -ve error code.
+ */
+int dma_receive(struct dma *dma, void **dst, void *metadata);
+
+/**
+ * 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).
+ * @metadata: DMA driver's channel specific data
+ * @return zero on success, or -ve error code.
+ */
+int dma_send(struct dma *dma, void *src, size_t len, void *metadata);
+#endif /* CONFIG_DMA_CHANNELS */
+
/*
* dma_get_device - get a DMA device which supports transfer
* type of transfer_type
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [U-Boot,v9,2/3] dma: add channels support
2018-11-28 18:17 ` [U-Boot] [PATCH v9 2/3] dma: add channels support Álvaro Fernández Rojas
@ 2018-12-07 20:33 ` Tom Rini
0 siblings, 0 replies; 145+ messages in thread
From: Tom Rini @ 2018-12-07 20:33 UTC (permalink / raw)
To: u-boot
On Wed, Nov 28, 2018 at 07:17:50PM +0100, Álvaro Fernández Rojas wrote:
> This adds channels support for dma controllers that have multiple channels
> which can transfer data to/from different devices (enet, usb...).
>
> DMA channle API:
> dma_get_by_index()
> dma_get_by_name()
> dma_request()
> dma_free()
> dma_enable()
> dma_disable()
> dma_prepare_rcv_buf()
> dma_receive()
> dma_send()
>
> Reviewed-by: Tom Rini <trini@konsulko.com>
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> [grygorii.strashko at ti.com: drop unused dma_get_by_index_platdata(),
> add metadata to send/receive ops, add dma_prepare_rcv_buf(),
> minor clean up]
> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
Applied to u-boot/master, thanks!
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181207/7e554157/attachment.sig>
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 3/3] test: dma: add dma-uclass test
2018-11-28 18:17 ` [U-Boot] [PATCH v9 0/3] " Álvaro Fernández Rojas
2018-11-28 18:17 ` [U-Boot] [PATCH v9 1/3] dma: move dma_ops to dma-uclass.h Álvaro Fernández Rojas
2018-11-28 18:17 ` [U-Boot] [PATCH v9 2/3] dma: add channels support Álvaro Fernández Rojas
@ 2018-11-28 18:17 ` Álvaro Fernández Rojas
2018-12-07 20:33 ` [U-Boot] [U-Boot,v9,3/3] " Tom Rini
2018-11-30 23:56 ` [U-Boot] [PATCH v9 0/3] dma: add channels support Grygorii Strashko
3 siblings, 1 reply; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:17 UTC (permalink / raw)
To: u-boot
From: Grygorii Strashko <grygorii.strashko@ti.com>
Add a sandbox DMA driver implementation (provider) and corresponding DM
test.
Reviewed-by: Tom Rini <trini@konsulko.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Acked-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: sync with latest u-boot
v7: no changes
v6: From Grygorii Strashko:
- added dma-uclass test
arch/sandbox/dts/test.dts | 8 ++
configs/sandbox_defconfig | 3 +
drivers/dma/Kconfig | 7 +
drivers/dma/Makefile | 1 +
drivers/dma/sandbox-dma-test.c | 282 +++++++++++++++++++++++++++++++++++++++++
test/dm/Makefile | 1 +
test/dm/dma.c | 123 ++++++++++++++++++
7 files changed, 425 insertions(+)
create mode 100644 drivers/dma/sandbox-dma-test.c
create mode 100644 test/dm/dma.c
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 2c6b422312..e5932d5a34 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -731,6 +731,14 @@
pinctrl {
compatible = "sandbox,pinctrl";
};
+
+ dma: dma {
+ compatible = "sandbox,dma";
+ #dma-cells = <1>;
+
+ dmas = <&dma 0>, <&dma 1>, <&dma 2>;
+ dma-names = "m2m", "tx0", "rx0";
+ };
};
#include "sandbox_pmic.dtsi"
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 5a744f4791..0e5e6f687e 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -215,3 +215,6 @@ CONFIG_UT_TIME=y
CONFIG_UT_DM=y
CONFIG_UT_ENV=y
CONFIG_UT_OVERLAY=y
+CONFIG_DMA=y
+CONFIG_DMA_CHANNELS=y
+CONFIG_SANDBOX_DMA=y
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index b9b85c65fc..8a4162eccd 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -19,6 +19,13 @@ config DMA_CHANNELS
Enable channels support for DMA. Some DMA controllers have multiple
channels which can either transfer data to/from different devices.
+config SANDBOX_DMA
+ bool "Enable the sandbox DMA test driver"
+ depends on DMA && DMA_CHANNELS && SANDBOX
+ help
+ Enable support for a test DMA uclass implementation. It stimulates
+ DMA transfer by simple copying data between channels.
+
config TI_EDMA3
bool "TI EDMA3 driver"
help
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 4eaef8ac65..aff31f986a 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -8,6 +8,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_FSL_DMA) += fsl_dma.o
+obj-$(CONFIG_SANDBOX_DMA) += sandbox-dma-test.o
obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o
obj-$(CONFIG_TI_EDMA3) += ti-edma3.o
obj-$(CONFIG_DMA_LPC32XX) += lpc32xx_dma.o
diff --git a/drivers/dma/sandbox-dma-test.c b/drivers/dma/sandbox-dma-test.c
new file mode 100644
index 0000000000..b958ec4d23
--- /dev/null
+++ b/drivers/dma/sandbox-dma-test.c
@@ -0,0 +1,282 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Direct Memory Access U-Class Simulation driver
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated <www.ti.com>
+ *
+ * Author: Grygorii Strashko <grygorii.strashko@ti.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/read.h>
+#include <dma-uclass.h>
+#include <dt-structs.h>
+#include <errno.h>
+
+#define SANDBOX_DMA_CH_CNT 3
+#define SANDBOX_DMA_BUF_SIZE 1024
+
+struct sandbox_dma_chan {
+ struct sandbox_dma_dev *ud;
+ char name[20];
+ u32 id;
+ enum dma_direction dir;
+ bool in_use;
+ bool enabled;
+};
+
+struct sandbox_dma_dev {
+ struct device *dev;
+ u32 ch_count;
+ struct sandbox_dma_chan channels[SANDBOX_DMA_CH_CNT];
+ uchar buf[SANDBOX_DMA_BUF_SIZE];
+ uchar *buf_rx;
+ size_t data_len;
+ u32 meta;
+};
+
+static int sandbox_dma_transfer(struct udevice *dev, int direction,
+ void *dst, void *src, size_t len)
+{
+ memcpy(dst, src, len);
+
+ return 0;
+}
+
+static int sandbox_dma_of_xlate(struct dma *dma,
+ struct ofnode_phandle_args *args)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ debug("%s(dma id=%u)\n", __func__, args->args[0]);
+
+ if (args->args[0] >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+
+ dma->id = args->args[0];
+
+ uc = &ud->channels[dma->id];
+
+ if (dma->id == 1)
+ uc->dir = DMA_MEM_TO_DEV;
+ else if (dma->id == 2)
+ uc->dir = DMA_DEV_TO_MEM;
+ else
+ uc->dir = DMA_MEM_TO_MEM;
+ debug("%s(dma id=%lu dir=%d)\n", __func__, dma->id, uc->dir);
+
+ return 0;
+}
+
+static int sandbox_dma_request(struct dma *dma)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ if (dma->id >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+
+ uc = &ud->channels[dma->id];
+ if (uc->in_use)
+ return -EBUSY;
+
+ uc->in_use = true;
+ debug("%s(dma id=%lu in_use=%d)\n", __func__, dma->id, uc->in_use);
+
+ return 0;
+}
+
+static int sandbox_dma_free(struct dma *dma)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ if (dma->id >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+
+ uc = &ud->channels[dma->id];
+ if (!uc->in_use)
+ return -EINVAL;
+
+ uc->in_use = false;
+ ud->buf_rx = NULL;
+ ud->data_len = 0;
+ debug("%s(dma id=%lu in_use=%d)\n", __func__, dma->id, uc->in_use);
+
+ return 0;
+}
+
+static int sandbox_dma_enable(struct dma *dma)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ if (dma->id >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+
+ uc = &ud->channels[dma->id];
+ if (!uc->in_use)
+ return -EINVAL;
+ if (uc->enabled)
+ return -EINVAL;
+
+ uc->enabled = true;
+ debug("%s(dma id=%lu enabled=%d)\n", __func__, dma->id, uc->enabled);
+
+ return 0;
+}
+
+static int sandbox_dma_disable(struct dma *dma)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ if (dma->id >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+
+ uc = &ud->channels[dma->id];
+ if (!uc->in_use)
+ return -EINVAL;
+ if (!uc->enabled)
+ return -EINVAL;
+
+ uc->enabled = false;
+ debug("%s(dma id=%lu enabled=%d)\n", __func__, dma->id, uc->enabled);
+
+ return 0;
+}
+
+static int sandbox_dma_send(struct dma *dma,
+ void *src, size_t len, void *metadata)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ if (dma->id >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+ if (!src || !metadata)
+ return -EINVAL;
+
+ debug("%s(dma id=%lu)\n", __func__, dma->id);
+
+ uc = &ud->channels[dma->id];
+ if (uc->dir != DMA_MEM_TO_DEV)
+ return -EINVAL;
+ if (!uc->in_use)
+ return -EINVAL;
+ if (!uc->enabled)
+ return -EINVAL;
+ if (len >= SANDBOX_DMA_BUF_SIZE)
+ return -EINVAL;
+
+ memcpy(ud->buf, src, len);
+ ud->data_len = len;
+ ud->meta = *((u32 *)metadata);
+
+ debug("%s(dma id=%lu len=%zu meta=%08x)\n",
+ __func__, dma->id, len, ud->meta);
+
+ return 0;
+}
+
+static int sandbox_dma_receive(struct dma *dma, void **dst, void *metadata)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+ struct sandbox_dma_chan *uc;
+
+ if (dma->id >= SANDBOX_DMA_CH_CNT)
+ return -EINVAL;
+ if (!dst || !metadata)
+ return -EINVAL;
+
+ uc = &ud->channels[dma->id];
+ if (uc->dir != DMA_DEV_TO_MEM)
+ return -EINVAL;
+ if (!uc->in_use)
+ return -EINVAL;
+ if (!uc->enabled)
+ return -EINVAL;
+ if (!ud->data_len)
+ return 0;
+
+ if (ud->buf_rx) {
+ memcpy(ud->buf_rx, ud->buf, ud->data_len);
+ *dst = ud->buf_rx;
+ } else {
+ memcpy(*dst, ud->buf, ud->data_len);
+ }
+
+ *((u32 *)metadata) = ud->meta;
+
+ debug("%s(dma id=%lu len=%zu meta=%08x %p)\n",
+ __func__, dma->id, ud->data_len, ud->meta, *dst);
+
+ return ud->data_len;
+}
+
+static int sandbox_dma_add_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+ struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
+
+ ud->buf_rx = dst;
+
+ return 0;
+}
+
+static const struct dma_ops sandbox_dma_ops = {
+ .transfer = sandbox_dma_transfer,
+ .of_xlate = sandbox_dma_of_xlate,
+ .request = sandbox_dma_request,
+ .free = sandbox_dma_free,
+ .enable = sandbox_dma_enable,
+ .disable = sandbox_dma_disable,
+ .send = sandbox_dma_send,
+ .receive = sandbox_dma_receive,
+ .add_rcv_buf = sandbox_dma_add_rcv_buf,
+};
+
+static int sandbox_dma_probe(struct udevice *dev)
+{
+ struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct sandbox_dma_dev *ud = dev_get_priv(dev);
+ int i, ret = 0;
+
+ uc_priv->supported = DMA_SUPPORTS_MEM_TO_MEM |
+ DMA_SUPPORTS_MEM_TO_DEV |
+ DMA_SUPPORTS_DEV_TO_MEM;
+
+ ud->ch_count = SANDBOX_DMA_CH_CNT;
+ ud->buf_rx = NULL;
+ ud->meta = 0;
+ ud->data_len = 0;
+
+ pr_err("Number of channels: %u\n", ud->ch_count);
+
+ for (i = 0; i < ud->ch_count; i++) {
+ struct sandbox_dma_chan *uc = &ud->channels[i];
+
+ uc->ud = ud;
+ uc->id = i;
+ sprintf(uc->name, "DMA chan%d\n", i);
+ uc->in_use = false;
+ uc->enabled = false;
+ }
+
+ return ret;
+}
+
+static const struct udevice_id sandbox_dma_ids[] = {
+ { .compatible = "sandbox,dma" },
+ { }
+};
+
+U_BOOT_DRIVER(sandbox_dma) = {
+ .name = "sandbox-dma",
+ .id = UCLASS_DMA,
+ .of_match = sandbox_dma_ids,
+ .ops = &sandbox_dma_ops,
+ .probe = sandbox_dma_probe,
+ .priv_auto_alloc_size = sizeof(struct sandbox_dma_dev),
+};
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 213e0fda94..757dd0c45b 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -54,4 +54,5 @@ obj-$(CONFIG_DM_SERIAL) += serial.o
obj-$(CONFIG_CPU) += cpu.o
obj-$(CONFIG_TEE) += tee.o
obj-$(CONFIG_VIRTIO_SANDBOX) += virtio.o
+obj-$(CONFIG_DMA) += dma.o
endif
diff --git a/test/dm/dma.c b/test/dm/dma.c
new file mode 100644
index 0000000000..6f19d6180c
--- /dev/null
+++ b/test/dm/dma.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Direct Memory Access U-Class tests
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated <www.ti.com>
+ * Grygorii Strashko <grygorii.strashko@ti.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/test.h>
+#include <dma.h>
+#include <test/ut.h>
+
+static int dm_test_dma_m2m(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ struct dma dma_m2m;
+ u8 src_buf[512];
+ u8 dst_buf[512];
+ size_t len = 512;
+ int i;
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_DMA, "dma", &dev));
+ ut_assertok(dma_get_by_name(dev, "m2m", &dma_m2m));
+
+ memset(dst_buf, 0, len);
+ for (i = 0; i < len; i++)
+ src_buf[i] = i;
+
+ ut_assertok(dma_memcpy(dst_buf, src_buf, len));
+
+ ut_assertok(memcmp(src_buf, dst_buf, len));
+ return 0;
+}
+DM_TEST(dm_test_dma_m2m, DM_TESTF_SCAN_FDT);
+
+static int dm_test_dma(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ struct dma dma_tx, dma_rx;
+ u8 src_buf[512];
+ u8 dst_buf[512];
+ void *dst_ptr;
+ size_t len = 512;
+ u32 meta1, meta2;
+ int i;
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_DMA, "dma", &dev));
+
+ ut_assertok(dma_get_by_name(dev, "tx0", &dma_tx));
+ ut_assertok(dma_get_by_name(dev, "rx0", &dma_rx));
+
+ ut_assertok(dma_enable(&dma_tx));
+ ut_assertok(dma_enable(&dma_rx));
+
+ memset(dst_buf, 0, len);
+ for (i = 0; i < len; i++)
+ src_buf[i] = i;
+ meta1 = 0xADADDEAD;
+ meta2 = 0;
+ dst_ptr = &dst_buf;
+
+ ut_assertok(dma_send(&dma_tx, src_buf, len, &meta1));
+
+ ut_asserteq(len, dma_receive(&dma_rx, &dst_ptr, &meta2));
+ ut_asserteq(0xADADDEAD, meta2);
+
+ ut_assertok(dma_disable(&dma_tx));
+ ut_assertok(dma_disable(&dma_rx));
+
+ ut_assertok(dma_free(&dma_tx));
+ ut_assertok(dma_free(&dma_rx));
+ ut_assertok(memcmp(src_buf, dst_buf, len));
+
+ return 0;
+}
+DM_TEST(dm_test_dma, DM_TESTF_SCAN_FDT);
+
+static int dm_test_dma_rx(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ struct dma dma_tx, dma_rx;
+ u8 src_buf[512];
+ u8 dst_buf[512];
+ void *dst_ptr;
+ size_t len = 512;
+ u32 meta1, meta2;
+ int i;
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_DMA, "dma", &dev));
+
+ ut_assertok(dma_get_by_name(dev, "tx0", &dma_tx));
+ ut_assertok(dma_get_by_name(dev, "rx0", &dma_rx));
+
+ ut_assertok(dma_enable(&dma_tx));
+ ut_assertok(dma_enable(&dma_rx));
+
+ memset(dst_buf, 0, len);
+ for (i = 0; i < len; i++)
+ src_buf[i] = i;
+ meta1 = 0xADADDEAD;
+ meta2 = 0;
+ dst_ptr = NULL;
+
+ ut_assertok(dma_add_rcv_buf(&dma_tx, dst_buf, len));
+
+ ut_assertok(dma_send(&dma_tx, src_buf, len, &meta1));
+
+ ut_asserteq(len, dma_receive(&dma_rx, &dst_ptr, &meta2));
+ ut_asserteq(0xADADDEAD, meta2);
+ ut_asserteq_ptr(dst_buf, dst_ptr);
+
+ ut_assertok(dma_disable(&dma_tx));
+ ut_assertok(dma_disable(&dma_rx));
+
+ ut_assertok(dma_free(&dma_tx));
+ ut_assertok(dma_free(&dma_rx));
+ ut_assertok(memcmp(src_buf, dst_buf, len));
+
+ return 0;
+}
+DM_TEST(dm_test_dma_rx, DM_TESTF_SCAN_FDT);
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 0/3] dma: add channels support
2018-11-28 18:17 ` [U-Boot] [PATCH v9 0/3] " Álvaro Fernández Rojas
` (2 preceding siblings ...)
2018-11-28 18:17 ` [U-Boot] [PATCH v9 3/3] test: dma: add dma-uclass test Álvaro Fernández Rojas
@ 2018-11-30 23:56 ` Grygorii Strashko
3 siblings, 0 replies; 145+ messages in thread
From: Grygorii Strashko @ 2018-11-30 23:56 UTC (permalink / raw)
To: u-boot
Hi Álvaro,
On 11/28/18 12:17 PM, Álvaro Fernández Rojas wrote:
> In 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...).
>
> ===
Thank you for picking this up.
I, unfortunately, will be out unresponsive next few month due to personal reasons,
but hope this will be moved forward eventually.
>
> ===
>
> v9: Separate generic dma channels support from bmips enet support
> v8: Sync with latest u-boot.
> v7: From Grygorii Strashko:
> - copyright fixed as suggested by Tom Rini
> - added "Reviewed-by" tags
> v6: From Grygorii Strashko:
> - added possibility to pass DMA driver/channel's specific data per each
> transfer using additional parameter "metadata" in dma_send/dma_receive() API.
> For example, port number for network packets to be directed to the
> specific port on multi port ethernet controllers.
> - added new dma_prepare_rcv_buf() API which allows to implement zero-copy
> DEV_TO_MEM transfer using DMA streaming channels which is usual case
> for Networking.
> - added dma-uclass test
> - removed unused function dma_get_by_index_platdata()
> - updated comments
> v5: Fix build of ti-edma3.
> v4: No changes
> 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.
>
> Grygorii Strashko (1):
> test: dma: add dma-uclass test
>
> Álvaro Fernández Rojas (2):
> dma: move dma_ops to dma-uclass.h
> dma: add channels support
>
> arch/sandbox/dts/test.dts | 8 ++
> configs/sandbox_defconfig | 3 +
> drivers/dma/Kconfig | 14 ++
> drivers/dma/Makefile | 1 +
> drivers/dma/dma-uclass.c | 183 +++++++++++++++++++++++++-
> drivers/dma/sandbox-dma-test.c | 282 +++++++++++++++++++++++++++++++++++++++++
> drivers/dma/ti-edma3.c | 2 +-
> include/dma-uclass.h | 128 +++++++++++++++++++
> include/dma.h | 282 +++++++++++++++++++++++++++++++++++++----
> test/dm/Makefile | 1 +
> test/dm/dma.c | 123 ++++++++++++++++++
> 11 files changed, 997 insertions(+), 30 deletions(-)
> create mode 100644 drivers/dma/sandbox-dma-test.c
> create mode 100644 include/dma-uclass.h
> create mode 100644 test/dm/dma.c
>
--
regards,
-grygorii
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support
2018-11-26 18:00 ` [U-Boot] [PATCH v8 00/31] dma: add channels support Álvaro Fernández Rojas
` (32 preceding siblings ...)
2018-11-28 18:17 ` [U-Boot] [PATCH v9 0/3] " Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 01/28] dma: add bcm6348-iudma support Álvaro Fernández Rojas
` (28 more replies)
33 siblings, 29 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
In 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...).
v9: Separate generic dma channels support from bmips enet support
bcm6348-iudma:
- bcm6348_iudma_chan_stop: switch to mdelay when resetting channel.
- bcm6348_iudma_receive: track dirty dma descriptors and no longer trigger
dma rx channel.
- bcm6348_iudma_send: reorder to properly flush cache and set dma descriptor
config.
- bcm6348_iudma_prepare_rcv_buf: implemented to clear dirty dma descriptors.
bcm6348-enet:
- bcm6348_eth_recv: clear dirty dma descriptors only when packets are copied
from rx dma.
- bcm6348_eth_send: remove dma rx channel reset when sending packet.
bcm6368-enet:
- introduce rx packets caching functionality from bcm6348-eth to fix flow
control issues.
- code style fixes.
v8: Introduce bcm6368-enet driver support.
v5: Fix issues reported by Grygorii Strashko and other fixes:
- 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: Switch to live tree API.
v2: Fix bcm6348-iudma rx burst config.
Álvaro Fernández Rojas (28):
dma: add bcm6348-iudma support
bmips: bcm6338: add bcm6348-iudma support
bmips: bcm6348: add bcm6348-iudma support
bmips: bcm6358: add bcm6348-iudma support
bmips: bcm6368: add bcm6348-iudma support
bmips: bcm6328: add bcm6348-iudma support
bmips: bcm6362: add bcm6348-iudma support
bmips: bcm63268: add bcm6348-iudma support
bmips: bcm6318: add bcm6348-iudma support
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
net: add support for bcm6368-enet
bmips: bcm6368: add support for bcm6368-enet
bmips: enable wap-5813n enet support
bmips: bcm6328: add support for bcm6368-enet
bmips: enable ar-5387un enet support
bmips: bcm6362: add support for bcm6368-enet
bmips: enable dgnd3700v2 enet support
bmips: bcm63268: add support for bcm6368-enet
bmips: enable vr-3032u enet support
bmips: bcm6318: add support for bcm6368-enet
bmips: enable ar-5315u enet support
arch/mips/dts/brcm,bcm6318.dtsi | 38 ++
arch/mips/dts/brcm,bcm63268.dtsi | 38 ++
arch/mips/dts/brcm,bcm6328.dtsi | 30 ++
arch/mips/dts/brcm,bcm6338.dtsi | 29 ++
arch/mips/dts/brcm,bcm6348.dtsi | 42 ++
arch/mips/dts/brcm,bcm6358.dtsi | 46 ++
arch/mips/dts/brcm,bcm6362.dtsi | 32 ++
arch/mips/dts/brcm,bcm6368.dtsi | 32 ++
arch/mips/dts/comtrend,ar-5315u.dts | 32 ++
arch/mips/dts/comtrend,ar-5387un.dts | 32 ++
arch/mips/dts/comtrend,ct-5361.dts | 12 +
arch/mips/dts/comtrend,vr-3032u.dts | 32 ++
arch/mips/dts/comtrend,wap-5813n.dts | 14 +
arch/mips/dts/huawei,hg556a.dts | 12 +
arch/mips/dts/netgear,dgnd3700v2.dts | 14 +
arch/mips/dts/sagem,f at st1704.dts | 12 +
arch/mips/dts/sfr,nb4-ser.dts | 24 ++
configs/comtrend_ar5315u_ram_defconfig | 7 +-
configs/comtrend_ar5387un_ram_defconfig | 7 +-
configs/comtrend_ct5361_ram_defconfig | 8 +-
configs/comtrend_vr3032u_ram_defconfig | 7 +-
configs/comtrend_wap5813n_ram_defconfig | 8 +-
configs/huawei_hg556a_ram_defconfig | 8 +-
configs/netgear_dgnd3700v2_ram_defconfig | 8 +-
configs/sagem_f at st1704_ram_defconfig | 8 +-
configs/sfr_nb4-ser_ram_defconfig | 8 +-
drivers/dma/Kconfig | 9 +
drivers/dma/Makefile | 1 +
drivers/dma/bcm6348-iudma.c | 576 +++++++++++++++++++++++++
drivers/net/Kconfig | 18 +
drivers/net/Makefile | 2 +
drivers/net/bcm6348-eth.c | 576 +++++++++++++++++++++++++
drivers/net/bcm6368-eth.c | 670 ++++++++++++++++++++++++++++++
include/configs/bmips_common.h | 5 +-
include/dt-bindings/clock/bcm6318-clock.h | 11 +
include/dt-bindings/dma/bcm6318-dma.h | 15 +
include/dt-bindings/dma/bcm63268-dma.h | 15 +
include/dt-bindings/dma/bcm6328-dma.h | 15 +
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/dt-bindings/dma/bcm6362-dma.h | 15 +
include/dt-bindings/dma/bcm6368-dma.h | 15 +
43 files changed, 2522 insertions(+), 10 deletions(-)
create mode 100644 drivers/dma/bcm6348-iudma.c
create mode 100644 drivers/net/bcm6348-eth.c
create mode 100644 drivers/net/bcm6368-eth.c
create mode 100644 include/dt-bindings/dma/bcm6318-dma.h
create mode 100644 include/dt-bindings/dma/bcm63268-dma.h
create mode 100644 include/dt-bindings/dma/bcm6328-dma.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
create mode 100644 include/dt-bindings/dma/bcm6362-dma.h
create mode 100644 include/dt-bindings/dma/bcm6368-dma.h
--
2.11.0
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 01/28] dma: add bcm6348-iudma support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 23:44 ` Daniel Schwierzeck
2018-11-28 18:23 ` [U-Boot] [PATCH v9 02/28] bmips: bcm6338: " Álvaro Fernández Rojas
` (27 subsequent siblings)
28 siblings, 1 reply; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
BCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: introduce dma_prepare_rcv_buf dma op:
- bcm6348_iudma_chan_stop: switch to mdelay when resetting channel.
- bcm6348_iudma_receive: track dirty dma descriptors and no longer trigger
dma rx channel.
- bcm6348_iudma_send: reorder to properly flush cache and set dma descriptor
config.
- bcm6348_iudma_prepare_rcv_buf: implemented to clear dirty dma descriptors.
v8: Introduce changes from Grygorii Strashko
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 | 576 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 586 insertions(+)
create mode 100644 drivers/dma/bcm6348-iudma.c
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 8a4162eccd..1820676d7a 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -26,6 +26,15 @@ config SANDBOX_DMA
Enable support for a test DMA uclass implementation. It stimulates
DMA transfer by simple copying data between channels.
+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
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index aff31f986a..b5f9147e0a 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -7,6 +7,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_SANDBOX_DMA) += sandbox-dma-test.o
obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o
diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c
new file mode 100644
index 0000000000..284735fff3
--- /dev/null
+++ b/drivers/dma/bcm6348-iudma.c
@@ -0,0 +1,576 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/dma/bcm63xx-iudma.c:
+ * Copyright (C) 2015 Simon Arlott <simon@fire.lp0.eu>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h:
+ * Copyright (C) 2000-2010 Broadcom Corporation
+ *
+ * Derived from bcm963xx_4.12L.06B_consumer/bcmdrivers/opensource/net/enet/impl4/bcmenet.c:
+ * Copyright (C) 2010 Broadcom Corporation
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dma-uclass.h>
+#include <memalign.h>
+#include <reset.h>
+#include <asm/io.h>
+
+#define DMA_RX_DESC 6
+#define DMA_TX_DESC 1
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define ALIGN_END_ADDR(type, ptr, size) \
+ ((unsigned long)(ptr) + roundup((size) * sizeof(type), \
+ ARCH_DMA_MINALIGN))
+
+/* DMA Channels */
+#define DMA_CHAN_FLOWC(x) ((x) >> 1)
+#define DMA_CHAN_MAX 16
+#define DMA_CHAN_SIZE 0x10
+#define DMA_CHAN_TOUT 500
+
+/* DMA Global Configuration register */
+#define DMA_CFG_REG 0x00
+#define DMA_CFG_ENABLE_SHIFT 0
+#define DMA_CFG_ENABLE_MASK (1 << DMA_CFG_ENABLE_SHIFT)
+#define DMA_CFG_FLOWC_ENABLE(x) BIT(DMA_CHAN_FLOWC(x) + 1)
+#define DMA_CFG_NCHANS_SHIFT 24
+#define DMA_CFG_NCHANS_MASK (0xf << DMA_CFG_NCHANS_SHIFT)
+
+/* DMA Global Flow Control registers */
+#define DMA_FLOWC_THR_LO_REG(x) (0x04 + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_THR_HI_REG(x) (0x08 + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_ALLOC_REG(x) (0x0c + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_ALLOC_FORCE_SHIFT 31
+#define DMA_FLOWC_ALLOC_FORCE_MASK (1 << DMA_FLOWC_ALLOC_FORCE_SHIFT)
+
+/* DMA Global Reset register */
+#define DMA_RST_REG 0x34
+#define DMA_RST_CHAN_SHIFT 0
+#define DMA_RST_CHAN_MASK(x) (1 << x)
+
+/* DMA Channel Configuration register */
+#define DMAC_CFG_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
+#define DMAC_CFG_ENABLE_SHIFT 0
+#define DMAC_CFG_ENABLE_MASK (1 << DMAC_CFG_ENABLE_SHIFT)
+#define DMAC_CFG_PKT_HALT_SHIFT 1
+#define DMAC_CFG_PKT_HALT_MASK (1 << DMAC_CFG_PKT_HALT_SHIFT)
+#define DMAC_CFG_BRST_HALT_SHIFT 2
+#define DMAC_CFG_BRST_HALT_MASK (1 << DMAC_CFG_BRST_HALT_SHIFT)
+
+/* DMA Channel Max Burst Length register */
+#define DMAC_BURST_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
+
+/* DMA SRAM Descriptor Ring Start register */
+#define DMAS_RSTART_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
+
+/* DMA SRAM State/Bytes done/ring offset register */
+#define DMAS_STATE_DATA_REG(x) (DMA_CHAN_SIZE * (x) + 0x04)
+
+/* DMA SRAM Buffer Descriptor status and length register */
+#define DMAS_DESC_LEN_STATUS_REG(x) (DMA_CHAN_SIZE * (x) + 0x08)
+
+/* DMA SRAM Buffer Descriptor status and length register */
+#define DMAS_DESC_BASE_BUFPTR_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
+
+struct bcm6348_dma_desc {
+ uint16_t length;
+
+ uint16_t status;
+#define DMAD_ST_CRC_SHIFT 8
+#define DMAD_ST_CRC_MASK (1 << DMAD_ST_CRC_SHIFT)
+#define DMAD_ST_WRAP_SHIFT 12
+#define DMAD_ST_WRAP_MASK (1 << DMAD_ST_WRAP_SHIFT)
+#define DMAD_ST_SOP_SHIFT 13
+#define DMAD_ST_SOP_MASK (1 << DMAD_ST_SOP_SHIFT)
+#define DMAD_ST_EOP_SHIFT 14
+#define DMAD_ST_EOP_MASK (1 << DMAD_ST_EOP_SHIFT)
+#define DMAD_ST_OWN_SHIFT 15
+#define DMAD_ST_OWN_MASK (1 << DMAD_ST_OWN_SHIFT)
+
+#define DMAD6348_ST_OV_ERR_SHIFT 0
+#define DMAD6348_ST_OV_ERR_MASK (1 << DMAD6348_ST_OV_ERR_SHIFT)
+#define DMAD6348_ST_CRC_ERR_SHIFT 1
+#define DMAD6348_ST_CRC_ERR_MASK (1 << DMAD6348_ST_CRC_ERR_SHIFT)
+#define DMAD6348_ST_RX_ERR_SHIFT 2
+#define DMAD6348_ST_RX_ERR_MASK (1 << DMAD6348_ST_RX_ERR_SHIFT)
+#define DMAD6348_ST_OS_ERR_SHIFT 4
+#define DMAD6348_ST_OS_ERR_MASK (1 << DMAD6348_ST_OS_ERR_SHIFT)
+#define DMAD6348_ST_UN_ERR_SHIFT 9
+#define DMAD6348_ST_UN_ERR_MASK (1 << DMAD6348_ST_UN_ERR_SHIFT)
+
+ uint32_t address;
+} __attribute__((aligned(1)));
+
+struct bcm6348_chan_priv {
+ void __iomem *dma_buff;
+ void __iomem *dma_ring;
+ uint8_t dma_ring_size;
+ uint8_t desc_id;
+ uint8_t dirty_cnt;
+ uint8_t dirty_desc;
+};
+
+struct bcm6348_iudma_hw {
+ uint16_t err_mask;
+};
+
+struct bcm6348_iudma_priv {
+ const struct bcm6348_iudma_hw *hw;
+ void __iomem *base;
+ void __iomem *chan;
+ void __iomem *sram;
+ struct bcm6348_chan_priv **ch_priv;
+ uint8_t n_channels;
+};
+
+static inline bool bcm6348_iudma_chan_is_rx(uint8_t ch)
+{
+ return !(ch & 1);
+}
+
+static void bcm6348_iudma_chan_stop(struct bcm6348_iudma_priv *priv,
+ uint8_t ch)
+{
+ unsigned int timeout = DMA_CHAN_TOUT;
+
+ do {
+ uint32_t cfg, halt;
+
+ if (timeout > DMA_CHAN_TOUT / 2)
+ halt = DMAC_CFG_PKT_HALT_MASK;
+ else
+ halt = DMAC_CFG_BRST_HALT_MASK;
+
+ /* try to stop dma channel */
+ writel_be(halt, priv->chan + DMAC_CFG_REG(ch));
+ mb();
+
+ /* check if channel was stopped */
+ cfg = readl_be(priv->chan + DMAC_CFG_REG(ch));
+ if (!(cfg & DMAC_CFG_ENABLE_MASK))
+ break;
+
+ udelay(1);
+ } while (--timeout);
+
+ if (!timeout)
+ pr_err("unable to stop channel %u\n", ch);
+
+ /* reset dma channel */
+ setbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
+ mdelay(1);
+ clrbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
+}
+
+static int bcm6348_iudma_disable(struct dma *dma)
+{
+ struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+
+ bcm6348_iudma_chan_stop(priv, dma->id);
+
+ if (bcm6348_iudma_chan_is_rx(dma->id))
+ writel_be(DMA_FLOWC_ALLOC_FORCE_MASK,
+ DMA_FLOWC_ALLOC_REG(dma->id));
+
+ return 0;
+}
+
+static int bcm6348_iudma_enable(struct dma *dma)
+{
+ const 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 = ch_priv->dma_buff;
+ uint8_t i;
+
+ /* init dma rings */
+ dma_desc = ch_priv->dma_ring;
+ for (i = 0; i < ch_priv->dma_ring_size; i++) {
+ uint16_t status;
+
+ if (bcm6348_iudma_chan_is_rx(dma->id)) {
+ status = DMAD_ST_OWN_MASK;
+ dma_desc->length = PKTSIZE_ALIGN;
+ dma_desc->address = virt_to_phys(dma_buff);
+ dma_buff += PKTSIZE_ALIGN;
+ } else {
+ status = 0;
+ dma_desc->length = 0;
+ dma_desc->address = 0;
+ }
+
+ if (i == ch_priv->dma_ring_size - 1)
+ status |= DMAD_ST_WRAP_MASK;
+
+ dma_desc->status = status;
+
+ dma_desc++;
+ }
+
+ /* init to first descriptor */
+ ch_priv->desc_id = 0;
+ ch_priv->dirty_desc = 0;
+ ch_priv->dirty_cnt = 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));
+
+ writel_be(0, priv->base + DMA_FLOWC_ALLOC_REG(dma->id));
+ }
+
+ /* set dma max burst */
+ writel_be(ch_priv->dma_ring_size,
+ priv->chan + DMAC_BURST_REG(dma->id));
+
+ /* kick dma channel */
+ setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK);
+
+ return 0;
+}
+
+static int bcm6348_iudma_request(struct dma *dma)
+{
+ const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+ struct bcm6348_chan_priv *ch_priv;
+
+ /* check if channel is valid */
+ if (dma->id >= priv->n_channels)
+ return -ENODEV;
+
+ /* alloc channel private data */
+ priv->ch_priv[dma->id] = calloc(1, sizeof(struct bcm6348_chan_priv));
+ if (!priv->ch_priv[dma->id])
+ return -ENOMEM;
+ ch_priv = priv->ch_priv[dma->id];
+
+ /* alloc dma ring */
+ if (bcm6348_iudma_chan_is_rx(dma->id))
+ ch_priv->dma_ring_size = DMA_RX_DESC;
+ else
+ ch_priv->dma_ring_size = DMA_TX_DESC;
+
+ ch_priv->dma_ring =
+ malloc_cache_aligned(sizeof(struct bcm6348_dma_desc) *
+ ch_priv->dma_ring_size);
+ if (!ch_priv->dma_ring)
+ return -ENOMEM;
+
+ if (bcm6348_iudma_chan_is_rx(dma->id)) {
+ ch_priv->dma_buff =
+ malloc_cache_aligned(PKTSIZE_ALIGN *
+ ch_priv->dma_ring_size);
+ if (!ch_priv->dma_buff)
+ return -ENOMEM;
+ } else {
+ ch_priv->dma_buff = NULL;
+ }
+
+ return 0;
+}
+
+static int bcm6348_iudma_receive(struct dma *dma, void **dst, void *metadata)
+{
+ const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+ const struct bcm6348_iudma_hw *hw = priv->hw;
+ struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+ struct bcm6348_dma_desc *dma_desc;
+ void __iomem *dma_buff;
+ int ret;
+
+ if (ch_priv->dirty_cnt == ch_priv->dma_ring_size) {
+ pr_err("dma rx ring full of dirty descriptors\n");
+ return -EAGAIN;
+ }
+
+ /* 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 -EAGAIN;
+
+ /* check pkt */
+ if (!(dma_desc->status & DMAD_ST_EOP_MASK) ||
+ !(dma_desc->status & DMAD_ST_SOP_MASK) ||
+ (dma_desc->status & hw->err_mask)) {
+ pr_err("invalid pkt received (ch=%ld) (st=%04x)\n",
+ dma->id, dma_desc->status);
+ ret = -EAGAIN;
+ } else {
+ uint16_t length;
+
+ /* 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));
+
+ /* remove crc */
+ length = dma_desc->length - 4;
+
+ /* copy data */
+ memcpy(*dst, dma_buff, length);
+
+ ret = length;
+ }
+
+ /* increment dma descriptor */
+ ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->dma_ring_size;
+ ch_priv->dirty_cnt++;
+
+ return ret;
+}
+
+static int bcm6348_iudma_send(struct dma *dma, void *src, size_t len,
+ void *metadata)
+{
+ const 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;
+ uint16_t status;
+
+ /* flush cache */
+ flush_dcache_range((ulong)src, (ulong)src + PKTSIZE_ALIGN);
+
+ /* get dma ring descriptor address */
+ dma_desc = ch_priv->dma_ring;
+ dma_desc += ch_priv->desc_id;
+
+ /* config dma descriptor */
+ status = (DMAD_ST_OWN_MASK |
+ DMAD_ST_EOP_MASK |
+ DMAD_ST_CRC_MASK |
+ DMAD_ST_SOP_MASK);
+ if (ch_priv->desc_id == ch_priv->dma_ring_size - 1)
+ status |= DMAD_ST_WRAP_MASK;
+
+ dma_desc->address = virt_to_phys(src);
+ dma_desc->length = len;
+ dma_desc->status = status;
+
+ /* flush cache */
+ flush_dcache_range((ulong)dma_desc,
+ ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1));
+
+ /* kick tx dma channel */
+ setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK);
+
+ /* poll dma status */
+ do {
+ /* invalidate cache */
+ invalidate_dcache_range((ulong)dma_desc,
+ ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1));
+
+ if (!(dma_desc->status & DMAD_ST_OWN_MASK))
+ break;
+ } while(1);
+
+ /* increment dma descriptor */
+ ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->dma_ring_size;
+
+ return 0;
+}
+
+int bcm6348_iudma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+ const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+ struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+
+ /* init dma rings */
+ while (ch_priv->dirty_cnt) {
+ struct bcm6348_dma_desc *dma_desc = ch_priv->dma_ring;
+ uint16_t status = DMAD_ST_OWN_MASK;
+
+ /* get dirty dma descriptor */
+ dma_desc += ch_priv->dirty_desc;
+
+ /* reinit dirty dma descriptor */
+ if (ch_priv->dirty_desc == ch_priv->dma_ring_size - 1)
+ status |= DMAD_ST_WRAP_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));
+
+ /* tell dma engine we allocated one buffer */
+ writel_be(1, DMA_FLOWC_ALLOC_REG(dma->id));
+
+ /* bump dirty dma descriptor */
+ ch_priv->dirty_desc = (ch_priv->dirty_desc + 1) %
+ ch_priv->dma_ring_size;
+
+ /* kick rx dma channel */
+ ch_priv->dirty_cnt--;
+ if (!ch_priv->dirty_cnt)
+ setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
+ DMAC_CFG_ENABLE_MASK);
+ }
+
+ return 0;
+}
+
+static const struct dma_ops bcm6348_iudma_ops = {
+ .disable = bcm6348_iudma_disable,
+ .enable = bcm6348_iudma_enable,
+ .prepare_rcv_buf = bcm6348_iudma_prepare_rcv_buf,
+ .request = bcm6348_iudma_request,
+ .receive = bcm6348_iudma_receive,
+ .send = bcm6348_iudma_send,
+};
+
+static const struct bcm6348_iudma_hw bcm6348_hw = {
+ .err_mask = (DMAD6348_ST_OV_ERR_MASK |
+ DMAD6348_ST_CRC_ERR_MASK |
+ DMAD6348_ST_RX_ERR_MASK |
+ DMAD6348_ST_OS_ERR_MASK |
+ DMAD6348_ST_UN_ERR_MASK),
+};
+
+static const struct bcm6348_iudma_hw bcm6368_hw = {
+ .err_mask = 0,
+};
+
+static const struct udevice_id bcm6348_iudma_ids[] = {
+ {
+ .compatible = "brcm,bcm6348-iudma",
+ .data = (ulong)&bcm6348_hw,
+ }, {
+ .compatible = "brcm,bcm6368-iudma",
+ .data = (ulong)&bcm6368_hw,
+ }, { /* sentinel */ }
+};
+
+static int bcm6348_iudma_probe(struct udevice *dev)
+{
+ struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct bcm6348_iudma_priv *priv = dev_get_priv(dev);
+ const struct bcm6348_iudma_hw *hw =
+ (const struct bcm6348_iudma_hw *)dev_get_driver_data(dev);
+ fdt_addr_t addr;
+ uint8_t ch;
+ int i;
+
+ uc_priv->supported = (DMA_SUPPORTS_DEV_TO_MEM |
+ DMA_SUPPORTS_MEM_TO_DEV);
+ priv->hw = hw;
+
+ /* 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);
+ }
+
+ /* dma global base address */
+ addr = devfdt_get_addr_name(dev, "dma");
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+ priv->base = ioremap(addr, 0);
+
+ /* dma channels base address */
+ addr = devfdt_get_addr_name(dev, "dma-channels");
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+ priv->chan = ioremap(addr, 0);
+
+ /* dma sram base address */
+ addr = devfdt_get_addr_name(dev, "dma-sram");
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+ priv->sram = ioremap(addr, 0);
+
+ /* disable dma controller */
+ clrbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
+
+ /* get number of channels */
+ priv->n_channels = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+ "dma-channels", 8);
+ if (priv->n_channels > DMA_CHAN_MAX)
+ return -EINVAL;
+
+ /* alloc channel private data pointers */
+ priv->ch_priv = calloc(priv->n_channels,
+ sizeof(struct bcm6348_chan_priv*));
+ if (!priv->ch_priv)
+ return -ENOMEM;
+
+ /* stop dma channels */
+ for (ch = 0; ch < priv->n_channels; ch++)
+ bcm6348_iudma_chan_stop(priv, ch);
+
+ /* enable dma controller */
+ setbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(bcm6348_iudma) = {
+ .name = "bcm6348_iudma",
+ .id = UCLASS_DMA,
+ .of_match = bcm6348_iudma_ids,
+ .ops = &bcm6348_iudma_ops,
+ .priv_auto_alloc_size = sizeof(struct bcm6348_iudma_priv),
+ .probe = bcm6348_iudma_probe,
+};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 01/28] dma: add bcm6348-iudma support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 01/28] dma: add bcm6348-iudma support Álvaro Fernández Rojas
@ 2018-11-28 23:44 ` Daniel Schwierzeck
0 siblings, 0 replies; 145+ messages in thread
From: Daniel Schwierzeck @ 2018-11-28 23:44 UTC (permalink / raw)
To: u-boot
Am 28.11.18 um 19:23 schrieb Álvaro Fernández Rojas:
> BCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
>
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
> v9: introduce dma_prepare_rcv_buf dma op:
> - bcm6348_iudma_chan_stop: switch to mdelay when resetting channel.
> - bcm6348_iudma_receive: track dirty dma descriptors and no longer trigger
> dma rx channel.
> - bcm6348_iudma_send: reorder to properly flush cache and set dma descriptor
> config.
> - bcm6348_iudma_prepare_rcv_buf: implemented to clear dirty dma descriptors.
> v8: Introduce changes from Grygorii Strashko
> 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 | 576 ++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 586 insertions(+)
> create mode 100644 drivers/dma/bcm6348-iudma.c
>
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 8a4162eccd..1820676d7a 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -26,6 +26,15 @@ config SANDBOX_DMA
> Enable support for a test DMA uclass implementation. It stimulates
> DMA transfer by simple copying data between channels.
>
> +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
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index aff31f986a..b5f9147e0a 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -7,6 +7,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_SANDBOX_DMA) += sandbox-dma-test.o
> obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o
> diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c
> new file mode 100644
> index 0000000000..284735fff3
> --- /dev/null
> +++ b/drivers/dma/bcm6348-iudma.c
> @@ -0,0 +1,576 @@
> +/*
> + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
> + *
> + * Derived from linux/drivers/dma/bcm63xx-iudma.c:
> + * Copyright (C) 2015 Simon Arlott <simon@fire.lp0.eu>
> + *
> + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
> + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
> + *
> + * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h:
> + * Copyright (C) 2000-2010 Broadcom Corporation
> + *
> + * Derived from bcm963xx_4.12L.06B_consumer/bcmdrivers/opensource/net/enet/impl4/bcmenet.c:
> + * Copyright (C) 2010 Broadcom Corporation
> + *
> + * SPDX-License-Identifier: GPL-2.0+
// SPDX-License-Identifier: GPL-2.0+
must be the first line of the file
> + */
> +
> +#include <common.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <dma-uclass.h>
> +#include <memalign.h>
> +#include <reset.h>
> +#include <asm/io.h>
> +
> +#define DMA_RX_DESC 6
> +#define DMA_TX_DESC 1
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define ALIGN_END_ADDR(type, ptr, size) \
> + ((unsigned long)(ptr) + roundup((size) * sizeof(type), \
> + ARCH_DMA_MINALIGN))
> +
> +/* DMA Channels */
> +#define DMA_CHAN_FLOWC(x) ((x) >> 1)
> +#define DMA_CHAN_MAX 16
> +#define DMA_CHAN_SIZE 0x10
> +#define DMA_CHAN_TOUT 500
> +
> +/* DMA Global Configuration register */
> +#define DMA_CFG_REG 0x00
> +#define DMA_CFG_ENABLE_SHIFT 0
> +#define DMA_CFG_ENABLE_MASK (1 << DMA_CFG_ENABLE_SHIFT)
> +#define DMA_CFG_FLOWC_ENABLE(x) BIT(DMA_CHAN_FLOWC(x) + 1)
> +#define DMA_CFG_NCHANS_SHIFT 24
> +#define DMA_CFG_NCHANS_MASK (0xf << DMA_CFG_NCHANS_SHIFT)
> +
> +/* DMA Global Flow Control registers */
> +#define DMA_FLOWC_THR_LO_REG(x) (0x04 + DMA_CHAN_FLOWC(x) * 0x0c)
> +#define DMA_FLOWC_THR_HI_REG(x) (0x08 + DMA_CHAN_FLOWC(x) * 0x0c)
> +#define DMA_FLOWC_ALLOC_REG(x) (0x0c + DMA_CHAN_FLOWC(x) * 0x0c)
> +#define DMA_FLOWC_ALLOC_FORCE_SHIFT 31
> +#define DMA_FLOWC_ALLOC_FORCE_MASK (1 << DMA_FLOWC_ALLOC_FORCE_SHIFT)
> +
> +/* DMA Global Reset register */
> +#define DMA_RST_REG 0x34
> +#define DMA_RST_CHAN_SHIFT 0
> +#define DMA_RST_CHAN_MASK(x) (1 << x)
> +
> +/* DMA Channel Configuration register */
> +#define DMAC_CFG_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
> +#define DMAC_CFG_ENABLE_SHIFT 0
> +#define DMAC_CFG_ENABLE_MASK (1 << DMAC_CFG_ENABLE_SHIFT)
> +#define DMAC_CFG_PKT_HALT_SHIFT 1
> +#define DMAC_CFG_PKT_HALT_MASK (1 << DMAC_CFG_PKT_HALT_SHIFT)
> +#define DMAC_CFG_BRST_HALT_SHIFT 2
> +#define DMAC_CFG_BRST_HALT_MASK (1 << DMAC_CFG_BRST_HALT_SHIFT)
> +
> +/* DMA Channel Max Burst Length register */
> +#define DMAC_BURST_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
> +
> +/* DMA SRAM Descriptor Ring Start register */
> +#define DMAS_RSTART_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
> +
> +/* DMA SRAM State/Bytes done/ring offset register */
> +#define DMAS_STATE_DATA_REG(x) (DMA_CHAN_SIZE * (x) + 0x04)
> +
> +/* DMA SRAM Buffer Descriptor status and length register */
> +#define DMAS_DESC_LEN_STATUS_REG(x) (DMA_CHAN_SIZE * (x) + 0x08)
> +
> +/* DMA SRAM Buffer Descriptor status and length register */
> +#define DMAS_DESC_BASE_BUFPTR_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
> +
> +struct bcm6348_dma_desc {
> + uint16_t length;
> +
> + uint16_t status;
> +#define DMAD_ST_CRC_SHIFT 8
> +#define DMAD_ST_CRC_MASK (1 << DMAD_ST_CRC_SHIFT)
> +#define DMAD_ST_WRAP_SHIFT 12
> +#define DMAD_ST_WRAP_MASK (1 << DMAD_ST_WRAP_SHIFT)
> +#define DMAD_ST_SOP_SHIFT 13
> +#define DMAD_ST_SOP_MASK (1 << DMAD_ST_SOP_SHIFT)
> +#define DMAD_ST_EOP_SHIFT 14
> +#define DMAD_ST_EOP_MASK (1 << DMAD_ST_EOP_SHIFT)
> +#define DMAD_ST_OWN_SHIFT 15
> +#define DMAD_ST_OWN_MASK (1 << DMAD_ST_OWN_SHIFT)
> +
> +#define DMAD6348_ST_OV_ERR_SHIFT 0
> +#define DMAD6348_ST_OV_ERR_MASK (1 << DMAD6348_ST_OV_ERR_SHIFT)
> +#define DMAD6348_ST_CRC_ERR_SHIFT 1
> +#define DMAD6348_ST_CRC_ERR_MASK (1 << DMAD6348_ST_CRC_ERR_SHIFT)
> +#define DMAD6348_ST_RX_ERR_SHIFT 2
> +#define DMAD6348_ST_RX_ERR_MASK (1 << DMAD6348_ST_RX_ERR_SHIFT)
> +#define DMAD6348_ST_OS_ERR_SHIFT 4
> +#define DMAD6348_ST_OS_ERR_MASK (1 << DMAD6348_ST_OS_ERR_SHIFT)
> +#define DMAD6348_ST_UN_ERR_SHIFT 9
> +#define DMAD6348_ST_UN_ERR_MASK (1 << DMAD6348_ST_UN_ERR_SHIFT)
I would move this out of the struct definition
> +
> + uint32_t address;
> +} __attribute__((aligned(1)));
__aligned(1)? But what's the sense of aligning to 1 byte?
> +
> +struct bcm6348_chan_priv {
> + void __iomem *dma_buff;
> + void __iomem *dma_ring;
> + uint8_t dma_ring_size;
> + uint8_t desc_id;
> + uint8_t dirty_cnt;
> + uint8_t dirty_desc;
> +};
> +
> +struct bcm6348_iudma_hw {
> + uint16_t err_mask;
> +};
> +
> +struct bcm6348_iudma_priv {
> + const struct bcm6348_iudma_hw *hw;
> + void __iomem *base;
> + void __iomem *chan;
> + void __iomem *sram;
> + struct bcm6348_chan_priv **ch_priv;
> + uint8_t n_channels;
> +};
> +
> +static inline bool bcm6348_iudma_chan_is_rx(uint8_t ch)
> +{
> + return !(ch & 1);
> +}
> +
> +static void bcm6348_iudma_chan_stop(struct bcm6348_iudma_priv *priv,
> + uint8_t ch)
> +{
> + unsigned int timeout = DMA_CHAN_TOUT;
> +
> + do {
> + uint32_t cfg, halt;
> +
> + if (timeout > DMA_CHAN_TOUT / 2)
> + halt = DMAC_CFG_PKT_HALT_MASK;
> + else
> + halt = DMAC_CFG_BRST_HALT_MASK;
> +
> + /* try to stop dma channel */
> + writel_be(halt, priv->chan + DMAC_CFG_REG(ch));
> + mb();
> +
> + /* check if channel was stopped */
> + cfg = readl_be(priv->chan + DMAC_CFG_REG(ch));
> + if (!(cfg & DMAC_CFG_ENABLE_MASK))
> + break;
> +
> + udelay(1);
> + } while (--timeout);
> +
> + if (!timeout)
> + pr_err("unable to stop channel %u\n", ch);
> +
> + /* reset dma channel */
> + setbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
> + mdelay(1);
> + clrbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
> +}
> +
> +static int bcm6348_iudma_disable(struct dma *dma)
> +{
> + struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
> +
> + bcm6348_iudma_chan_stop(priv, dma->id);
> +
> + if (bcm6348_iudma_chan_is_rx(dma->id))
> + writel_be(DMA_FLOWC_ALLOC_FORCE_MASK,
> + DMA_FLOWC_ALLOC_REG(dma->id));
> +
> + return 0;
> +}
> +
> +static int bcm6348_iudma_enable(struct dma *dma)
> +{
> + const 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 = ch_priv->dma_buff;
> + uint8_t i;
> +
> + /* init dma rings */
> + dma_desc = ch_priv->dma_ring;
> + for (i = 0; i < ch_priv->dma_ring_size; i++) {
> + uint16_t status;
> +
> + if (bcm6348_iudma_chan_is_rx(dma->id)) {
> + status = DMAD_ST_OWN_MASK;
> + dma_desc->length = PKTSIZE_ALIGN;
> + dma_desc->address = virt_to_phys(dma_buff);
> + dma_buff += PKTSIZE_ALIGN;
shouldn't this be somehow set by a consumer driver instead of
hard-coding the size of a network packet?
> + } else {
> + status = 0;
> + dma_desc->length = 0;
> + dma_desc->address = 0;
> + }
> +
> + if (i == ch_priv->dma_ring_size - 1)
> + status |= DMAD_ST_WRAP_MASK;
> +
> + dma_desc->status = status;
> +
> + dma_desc++;
> + }
> +
> + /* init to first descriptor */
> + ch_priv->desc_id = 0;
> + ch_priv->dirty_desc = 0;
> + ch_priv->dirty_cnt = 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));
> +
> + writel_be(0, priv->base + DMA_FLOWC_ALLOC_REG(dma->id));
> + }
> +
> + /* set dma max burst */
> + writel_be(ch_priv->dma_ring_size,
> + priv->chan + DMAC_BURST_REG(dma->id));
> +
> + /* kick dma channel */
> + setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK);
> +
> + return 0;
> +}
> +
> +static int bcm6348_iudma_request(struct dma *dma)
> +{
> + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
> + struct bcm6348_chan_priv *ch_priv;
> +
> + /* check if channel is valid */
> + if (dma->id >= priv->n_channels)
> + return -ENODEV;
> +
> + /* alloc channel private data */
> + priv->ch_priv[dma->id] = calloc(1, sizeof(struct bcm6348_chan_priv));
> + if (!priv->ch_priv[dma->id])
> + return -ENOMEM;
> + ch_priv = priv->ch_priv[dma->id];
> +
> + /* alloc dma ring */
> + if (bcm6348_iudma_chan_is_rx(dma->id))
> + ch_priv->dma_ring_size = DMA_RX_DESC;
> + else
> + ch_priv->dma_ring_size = DMA_TX_DESC;
> +
> + ch_priv->dma_ring =
> + malloc_cache_aligned(sizeof(struct bcm6348_dma_desc) *
> + ch_priv->dma_ring_size);
> + if (!ch_priv->dma_ring)
> + return -ENOMEM;
> +
> + if (bcm6348_iudma_chan_is_rx(dma->id)) {
> + ch_priv->dma_buff =
> + malloc_cache_aligned(PKTSIZE_ALIGN *
> + ch_priv->dma_ring_size);
> + if (!ch_priv->dma_buff)
> + return -ENOMEM;
> + } else {
> + ch_priv->dma_buff = NULL;
> + }
> +
> + return 0;
> +}
> +
> +static int bcm6348_iudma_receive(struct dma *dma, void **dst, void *metadata)
> +{
> + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
> + const struct bcm6348_iudma_hw *hw = priv->hw;
> + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
> + struct bcm6348_dma_desc *dma_desc;
> + void __iomem *dma_buff;
> + int ret;
> +
> + if (ch_priv->dirty_cnt == ch_priv->dma_ring_size) {
> + pr_err("dma rx ring full of dirty descriptors\n");
> + return -EAGAIN;
> + }
> +
> + /* 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 -EAGAIN;
> +
> + /* check pkt */
> + if (!(dma_desc->status & DMAD_ST_EOP_MASK) ||
> + !(dma_desc->status & DMAD_ST_SOP_MASK) ||
> + (dma_desc->status & hw->err_mask)) {
> + pr_err("invalid pkt received (ch=%ld) (st=%04x)\n",
> + dma->id, dma_desc->status);
> + ret = -EAGAIN;
> + } else {
> + uint16_t length;
> +
> + /* 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));
> +
> + /* remove crc */
> + length = dma_desc->length - 4;
> +
> + /* copy data */
> + memcpy(*dst, dma_buff, length);
why not returning the buffer address where the DMA transfered the data
to instead of making a copy?
> +
> + ret = length;
> + }
> +
> + /* increment dma descriptor */
> + ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->dma_ring_size;
> + ch_priv->dirty_cnt++;
> +
> + return ret;
> +}
> +
> +static int bcm6348_iudma_send(struct dma *dma, void *src, size_t len,
> + void *metadata)
> +{
> + const 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;
> + uint16_t status;
> +
> + /* flush cache */
> + flush_dcache_range((ulong)src, (ulong)src + PKTSIZE_ALIGN);
you pass a 'size_t len' but still use the hard-coded buffer size?
> +
> + /* get dma ring descriptor address */
> + dma_desc = ch_priv->dma_ring;
> + dma_desc += ch_priv->desc_id;
> +
> + /* config dma descriptor */
> + status = (DMAD_ST_OWN_MASK |
> + DMAD_ST_EOP_MASK |
> + DMAD_ST_CRC_MASK |
> + DMAD_ST_SOP_MASK);
> + if (ch_priv->desc_id == ch_priv->dma_ring_size - 1)
> + status |= DMAD_ST_WRAP_MASK;
> +
> + dma_desc->address = virt_to_phys(src);
> + dma_desc->length = len;
> + dma_desc->status = status;
> +
> + /* flush cache */
> + flush_dcache_range((ulong)dma_desc,
> + ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1));
> +
> + /* kick tx dma channel */
> + setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK);
> +
> + /* poll dma status */
> + do {
> + /* invalidate cache */
> + invalidate_dcache_range((ulong)dma_desc,
> + ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1));
> +
> + if (!(dma_desc->status & DMAD_ST_OWN_MASK))
> + break;
> + } while(1);
> +
> + /* increment dma descriptor */
> + ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->dma_ring_size;
> +
> + return 0;
> +}
> +
> +int bcm6348_iudma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size)
> +{
> + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
> + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
> +
> + /* init dma rings */
> + while (ch_priv->dirty_cnt) {
> + struct bcm6348_dma_desc *dma_desc = ch_priv->dma_ring;
> + uint16_t status = DMAD_ST_OWN_MASK;
> +
> + /* get dirty dma descriptor */
> + dma_desc += ch_priv->dirty_desc;
> +
> + /* reinit dirty dma descriptor */
> + if (ch_priv->dirty_desc == ch_priv->dma_ring_size - 1)
> + status |= DMAD_ST_WRAP_MASK;
> + dma_desc->length = PKTSIZE_ALIGN;
you pass a 'size_t size' but still use the hard-coded buffer size?
> + dma_desc->status = status;
> +
> + /* flush cache */
> + flush_dcache_range((ulong)dma_desc,
> + ALIGN_END_ADDR(struct bcm6348_dma_desc, dma_desc, 1));
> +
> + /* tell dma engine we allocated one buffer */
> + writel_be(1, DMA_FLOWC_ALLOC_REG(dma->id));
> +
> + /* bump dirty dma descriptor */
> + ch_priv->dirty_desc = (ch_priv->dirty_desc + 1) %
> + ch_priv->dma_ring_size;
> +
> + /* kick rx dma channel */
> + ch_priv->dirty_cnt--;
> + if (!ch_priv->dirty_cnt)
> + setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
> + DMAC_CFG_ENABLE_MASK);
> + }
> +
> + return 0;
> +}
> +
> +static const struct dma_ops bcm6348_iudma_ops = {
> + .disable = bcm6348_iudma_disable,
> + .enable = bcm6348_iudma_enable,
> + .prepare_rcv_buf = bcm6348_iudma_prepare_rcv_buf,
> + .request = bcm6348_iudma_request,
> + .receive = bcm6348_iudma_receive,
> + .send = bcm6348_iudma_send,
> +};
> +
> +static const struct bcm6348_iudma_hw bcm6348_hw = {
> + .err_mask = (DMAD6348_ST_OV_ERR_MASK |
> + DMAD6348_ST_CRC_ERR_MASK |
> + DMAD6348_ST_RX_ERR_MASK |
> + DMAD6348_ST_OS_ERR_MASK |
> + DMAD6348_ST_UN_ERR_MASK),
> +};
> +
> +static const struct bcm6348_iudma_hw bcm6368_hw = {
> + .err_mask = 0,
> +};
> +
> +static const struct udevice_id bcm6348_iudma_ids[] = {
> + {
> + .compatible = "brcm,bcm6348-iudma",
> + .data = (ulong)&bcm6348_hw,
> + }, {
> + .compatible = "brcm,bcm6368-iudma",
> + .data = (ulong)&bcm6368_hw,
> + }, { /* sentinel */ }
> +};
> +
> +static int bcm6348_iudma_probe(struct udevice *dev)
> +{
> + struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> + struct bcm6348_iudma_priv *priv = dev_get_priv(dev);
> + const struct bcm6348_iudma_hw *hw =
> + (const struct bcm6348_iudma_hw *)dev_get_driver_data(dev);
> + fdt_addr_t addr;
> + uint8_t ch;
> + int i;
> +
> + uc_priv->supported = (DMA_SUPPORTS_DEV_TO_MEM |
> + DMA_SUPPORTS_MEM_TO_DEV);
> + priv->hw = hw;
> +
> + /* 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;
why not getting the reference once and do appropiate error handling.
Although it's only probing but this looks very inefficient
> + if (clk_enable(&clk))
> + pr_err("failed to enable clock %d\n", i);
> + clk_free(&clk);
> + }
> +
> + /* try to perform resets */
no error handling for clk_get_by_index()? I guess it doesn't make sense
to continue without enabled clocks?
> + 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);
> + }
same here
> +
> + /* dma global base address */
> + addr = devfdt_get_addr_name(dev, "dma");
> + if (addr == FDT_ADDR_T_NONE)
> + return -EINVAL;
> + priv->base = ioremap(addr, 0);
this is not compatible with DM live tree which you already enabled for
BMIPS platform. You should use dev_remap_addr_index() or you should add
a generic dev_remap_addr_name().
> +
> + /* dma channels base address */
> + addr = devfdt_get_addr_name(dev, "dma-channels");
> + if (addr == FDT_ADDR_T_NONE)
> + return -EINVAL;
> + priv->chan = ioremap(addr, 0);
> +
> + /* dma sram base address */
> + addr = devfdt_get_addr_name(dev, "dma-sram");
> + if (addr == FDT_ADDR_T_NONE)
> + return -EINVAL;
> + priv->sram = ioremap(addr, 0);
> +
> + /* disable dma controller */
> + clrbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
> +
> + /* get number of channels */
> + priv->n_channels = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
> + "dma-channels", 8);
dev_read_u32() ?
> + if (priv->n_channels > DMA_CHAN_MAX)
> + return -EINVAL;
> +
> + /* alloc channel private data pointers */
> + priv->ch_priv = calloc(priv->n_channels,
> + sizeof(struct bcm6348_chan_priv*));
> + if (!priv->ch_priv)
> + return -ENOMEM;
> +
> + /* stop dma channels */
> + for (ch = 0; ch < priv->n_channels; ch++)
> + bcm6348_iudma_chan_stop(priv, ch);
> +
> + /* enable dma controller */
> + setbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
> +
> + return 0;
> +}
> +
> +U_BOOT_DRIVER(bcm6348_iudma) = {
> + .name = "bcm6348_iudma",
> + .id = UCLASS_DMA,
> + .of_match = bcm6348_iudma_ids,
> + .ops = &bcm6348_iudma_ops,
> + .priv_auto_alloc_size = sizeof(struct bcm6348_iudma_priv),
> + .probe = bcm6348_iudma_probe,
> +};
>
--
- Daniel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181129/a1bd05ee/attachment.sig>
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 02/28] bmips: bcm6338: add bcm6348-iudma support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 01/28] dma: add bcm6348-iudma support Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 23:48 ` Daniel Schwierzeck
2018-11-28 18:23 ` [U-Boot] [PATCH v9 03/28] bmips: bcm6348: " Álvaro Fernández Rojas
` (26 subsequent siblings)
28 siblings, 1 reply; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: no changes
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
diff --git a/arch/mips/dts/brcm,bcm6338.dtsi b/arch/mips/dts/brcm,bcm6338.dtsi
index bbd58cf803..990355481c 100644
--- a/arch/mips/dts/brcm,bcm6338.dtsi
+++ b/arch/mips/dts/brcm,bcm6338.dtsi
@@ -4,6 +4,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"
@@ -130,5 +131,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>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6338-dma.h b/include/dt-bindings/dma/bcm6338-dma.h
new file mode 100644
index 0000000000..5dd66239b4
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6338-dma.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * 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 */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 02/28] bmips: bcm6338: add bcm6348-iudma support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 02/28] bmips: bcm6338: " Álvaro Fernández Rojas
@ 2018-11-28 23:48 ` Daniel Schwierzeck
0 siblings, 0 replies; 145+ messages in thread
From: Daniel Schwierzeck @ 2018-11-28 23:48 UTC (permalink / raw)
To: u-boot
Am 28.11.18 um 19:23 schrieb Álvaro Fernández Rojas:
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
> v9: no changes
> v8: no changes
> 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
>
> diff --git a/arch/mips/dts/brcm,bcm6338.dtsi b/arch/mips/dts/brcm,bcm6338.dtsi
> index bbd58cf803..990355481c 100644
> --- a/arch/mips/dts/brcm,bcm6338.dtsi
> +++ b/arch/mips/dts/brcm,bcm6338.dtsi
> @@ -4,6 +4,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"
> @@ -130,5 +131,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>;
> + };
> };
> };
> diff --git a/include/dt-bindings/dma/bcm6338-dma.h b/include/dt-bindings/dma/bcm6338-dma.h
> new file mode 100644
> index 0000000000..5dd66239b4
> --- /dev/null
> +++ b/include/dt-bindings/dma/bcm6338-dma.h
> @@ -0,0 +1,15 @@
> +/*
> + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
> + *
> + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
> + *
> + * SPDX-License-Identifier: GPL-2.0+
// SPDX-License-Identifier: GPL-2.0+
need to be fixed in all patches
> + */
> +
> +#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 */
>
--
- Daniel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181129/58dff1b6/attachment.sig>
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 03/28] bmips: bcm6348: add bcm6348-iudma support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 01/28] dma: add bcm6348-iudma support Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 02/28] bmips: bcm6338: " Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 04/28] bmips: bcm6358: " Álvaro Fernández Rojas
` (25 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: no changes
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
diff --git a/arch/mips/dts/brcm,bcm6348.dtsi b/arch/mips/dts/brcm,bcm6348.dtsi
index cc80bbc808..875de232ca 100644
--- a/arch/mips/dts/brcm,bcm6348.dtsi
+++ b/arch/mips/dts/brcm,bcm6348.dtsi
@@ -4,6 +4,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"
@@ -159,5 +160,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>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6348-dma.h b/include/dt-bindings/dma/bcm6348-dma.h
new file mode 100644
index 0000000000..a1d3a6456d
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6348-dma.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * 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 */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 04/28] bmips: bcm6358: add bcm6348-iudma support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (2 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 03/28] bmips: bcm6348: " Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 05/28] bmips: bcm6368: " Álvaro Fernández Rojas
` (24 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: no changes
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
diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi
index 0617b46e92..5605723e83 100644
--- a/arch/mips/dts/brcm,bcm6358.dtsi
+++ b/arch/mips/dts/brcm,bcm6358.dtsi
@@ -4,6 +4,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"
@@ -190,5 +191,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>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6358-dma.h b/include/dt-bindings/dma/bcm6358-dma.h
new file mode 100644
index 0000000000..3b1fcf8540
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6358-dma.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * 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 */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 05/28] bmips: bcm6368: add bcm6348-iudma support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (3 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 04/28] bmips: bcm6358: " Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 06/28] bmips: bcm6328: " Álvaro Fernández Rojas
` (23 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6368.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm6368-dma.h | 15 +++++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6368-dma.h
diff --git a/arch/mips/dts/brcm,bcm6368.dtsi b/arch/mips/dts/brcm,bcm6368.dtsi
index 65d769ab4f..30047f6360 100644
--- a/arch/mips/dts/brcm,bcm6368.dtsi
+++ b/arch/mips/dts/brcm,bcm6368.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6368-clock.h>
+#include <dt-bindings/dma/bcm6368-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/reset/bcm6368-reset.h>
#include "skeleton.dtsi"
@@ -192,5 +193,17 @@
status = "disabled";
};
+
+ iudma: dma-controller at 10006800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x10006800 0x80>,
+ <0x10006a00 0x80>,
+ <0x10006c00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6368-dma.h b/include/dt-bindings/dma/bcm6368-dma.h
new file mode 100644
index 0000000000..45ffb89e0a
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6368-dma.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6368_H
+#define __DT_BINDINGS_DMA_BCM6368_H
+
+#define BCM6368_DMA_ENETSW_RX 0
+#define BCM6368_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6368_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 06/28] bmips: bcm6328: add bcm6348-iudma support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (4 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 05/28] bmips: bcm6368: " Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 07/28] bmips: bcm6362: " Álvaro Fernández Rojas
` (22 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6328.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm6328-dma.h | 15 +++++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6328-dma.h
diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi
index e00a2950e2..6fa49e22bb 100644
--- a/arch/mips/dts/brcm,bcm6328.dtsi
+++ b/arch/mips/dts/brcm,bcm6328.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6328-clock.h>
+#include <dt-bindings/dma/bcm6328-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm6328-power-domain.h>
#include <dt-bindings/reset/bcm6328-reset.h>
@@ -187,5 +188,17 @@
reg = <0x10003000 0x864>;
u-boot,dm-pre-reloc;
};
+
+ iudma: dma-controller at 1000d800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x1000d800 0x80>,
+ <0x1000da00 0x80>,
+ <0x1000dc00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6328-dma.h b/include/dt-bindings/dma/bcm6328-dma.h
new file mode 100644
index 0000000000..508a5dc523
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6328-dma.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6328_H
+#define __DT_BINDINGS_DMA_BCM6328_H
+
+#define BCM6328_DMA_ENETSW_RX 0
+#define BCM6328_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6328_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 07/28] bmips: bcm6362: add bcm6348-iudma support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (5 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 06/28] bmips: bcm6328: " Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 08/28] bmips: bcm63268: " Álvaro Fernández Rojas
` (21 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6362.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm6362-dma.h | 15 +++++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6362-dma.h
diff --git a/arch/mips/dts/brcm,bcm6362.dtsi b/arch/mips/dts/brcm,bcm6362.dtsi
index 3047b82b21..94e7de096d 100644
--- a/arch/mips/dts/brcm,bcm6362.dtsi
+++ b/arch/mips/dts/brcm,bcm6362.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6362-clock.h>
+#include <dt-bindings/dma/bcm6362-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm6362-power-domain.h>
#include <dt-bindings/reset/bcm6362-reset.h>
@@ -211,5 +212,17 @@
reg = <0x10003000 0x864>;
u-boot,dm-pre-reloc;
};
+
+ iudma: dma-controller at 1000d800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x1000d800 0x80>,
+ <0x1000da00 0x80>,
+ <0x1000dc00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6362-dma.h b/include/dt-bindings/dma/bcm6362-dma.h
new file mode 100644
index 0000000000..b90b3ffeb6
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6362-dma.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6362_H
+#define __DT_BINDINGS_DMA_BCM6362_H
+
+#define BCM6362_DMA_ENETSW_RX 0
+#define BCM6362_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6362_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 08/28] bmips: bcm63268: add bcm6348-iudma support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (6 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 07/28] bmips: bcm6362: " Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 09/28] bmips: bcm6318: " Álvaro Fernández Rojas
` (20 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm63268.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm63268-dma.h | 15 +++++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm63268-dma.h
diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi
index 62c440e675..c7ad83c306 100644
--- a/arch/mips/dts/brcm,bcm63268.dtsi
+++ b/arch/mips/dts/brcm,bcm63268.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm63268-clock.h>
+#include <dt-bindings/dma/bcm63268-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm63268-power-domain.h>
#include <dt-bindings/reset/bcm63268-reset.h>
@@ -217,5 +218,17 @@
reg = <0x10003000 0x894>;
u-boot,dm-pre-reloc;
};
+
+ iudma: dma-controller at 1000d800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x1000d800 0x80>,
+ <0x1000da00 0x80>,
+ <0x1000dc00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm63268-dma.h b/include/dt-bindings/dma/bcm63268-dma.h
new file mode 100644
index 0000000000..d5d7453be1
--- /dev/null
+++ b/include/dt-bindings/dma/bcm63268-dma.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM63268_H
+#define __DT_BINDINGS_DMA_BCM63268_H
+
+#define BCM63268_DMA_ENETSW_RX 0
+#define BCM63268_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM63268_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 09/28] bmips: bcm6318: add bcm6348-iudma support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (7 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 08/28] bmips: bcm63268: " Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 10/28] net: add support for bcm6348-enet Álvaro Fernández Rojas
` (19 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6318.dtsi | 19 +++++++++++++++++++
include/dt-bindings/dma/bcm6318-dma.h | 15 +++++++++++++++
2 files changed, 34 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6318-dma.h
diff --git a/arch/mips/dts/brcm,bcm6318.dtsi b/arch/mips/dts/brcm,bcm6318.dtsi
index f75988be12..d04b7cbb01 100644
--- a/arch/mips/dts/brcm,bcm6318.dtsi
+++ b/arch/mips/dts/brcm,bcm6318.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6318-clock.h>
+#include <dt-bindings/dma/bcm6318-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm6318-power-domain.h>
#include <dt-bindings/reset/bcm6318-reset.h>
@@ -54,6 +55,12 @@
reg = <0x10000004 0x4>;
#clock-cells = <1>;
};
+
+ ubus_clk: ubus-clk {
+ compatible = "brcm,bcm6345-clk";
+ reg = <0x10000008 0x4>;
+ #clock-cells = <1>;
+ };
};
ubus {
@@ -182,5 +189,17 @@
status = "disabled";
};
+
+ iudma: dma-controller at 10088000 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x10088000 0x80>,
+ <0x10088200 0x80>,
+ <0x10088400 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6318-dma.h b/include/dt-bindings/dma/bcm6318-dma.h
new file mode 100644
index 0000000000..c039391395
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6318-dma.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6318_H
+#define __DT_BINDINGS_DMA_BCM6318_H
+
+#define BCM6318_DMA_ENETSW_RX 0
+#define BCM6318_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6318_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 10/28] net: add support for bcm6348-enet
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (8 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 09/28] bmips: bcm6318: " Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 23:58 ` Daniel Schwierzeck
2018-11-28 18:23 ` [U-Boot] [PATCH v9 11/28] bmips: bcm6338: " Álvaro Fernández Rojas
` (18 subsequent siblings)
28 siblings, 1 reply; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: use dma_prepare_rcv_buf and remove dma rx channel reset:
- bcm6348_eth_recv: clear dirty dma descriptors only when packets are copied
from rx dma.
- bcm6348_eth_send: remove dma rx channel reset when sending packet.
v8: Introduce changes from Grygorii Strashko
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 | 576 +++++++++++++++++++++++++++++++++++++++++
include/configs/bmips_common.h | 5 +-
4 files changed, 591 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/bcm6348-eth.c
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 8fb365fc5d..2b7cec8804 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -72,6 +72,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
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 99056aa041..2647d4dd23 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -6,6 +6,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
diff --git a/drivers/net/bcm6348-eth.c b/drivers/net/bcm6348-eth.c
new file mode 100644
index 0000000000..24a44d83cb
--- /dev/null
+++ b/drivers/net/bcm6348-eth.c
@@ -0,0 +1,576 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * 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],
+ NULL);
+ 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);
+
+ /* receive packets if queue is empty */
+ if (priv->rx_ret[priv->rx_pend] <= 0) {
+ uint8_t pkt_cnt = 0;
+
+ /* try to receive packets */
+ while (_bcm6348_eth_recv(priv) > 0)
+ pkt_cnt++;
+
+ dma_prepare_rcv_buf(&priv->rx_dma, NULL, 0);
+
+ if (pkt_cnt)
+ debug("%s: received %u packet(s)\n", __func__, pkt_cnt);
+ }
+
+ /* return current packet */
+ if (priv->rx_ret[priv->rx_pend] > 0)
+ *packetp = net_rx_packets[priv->rx_pend];
+
+ return priv->rx_ret[priv->rx_pend];
+}
+
+static int bcm6348_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+
+ return dma_send(&priv->tx_dma, packet, length, NULL);
+}
+
+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) & ETH_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,
+};
diff --git a/include/configs/bmips_common.h b/include/configs/bmips_common.h
index 39ca2e0bf3..65aa9c77cc 100644
--- a/include/configs/bmips_common.h
+++ b/include/configs/bmips_common.h
@@ -6,6 +6,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 }
@@ -16,7 +19,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
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 10/28] net: add support for bcm6348-enet
2018-11-28 18:23 ` [U-Boot] [PATCH v9 10/28] net: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-11-28 23:58 ` Daniel Schwierzeck
0 siblings, 0 replies; 145+ messages in thread
From: Daniel Schwierzeck @ 2018-11-28 23:58 UTC (permalink / raw)
To: u-boot
Am 28.11.18 um 19:23 schrieb Álvaro Fernández Rojas:
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
> v9: use dma_prepare_rcv_buf and remove dma rx channel reset:
> - bcm6348_eth_recv: clear dirty dma descriptors only when packets are copied
> from rx dma.
> - bcm6348_eth_send: remove dma rx channel reset when sending packet.
> v8: Introduce changes from Grygorii Strashko
> 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 | 576 +++++++++++++++++++++++++++++++++++++++++
> include/configs/bmips_common.h | 5 +-
> 4 files changed, 591 insertions(+), 1 deletion(-)
> create mode 100644 drivers/net/bcm6348-eth.c
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 8fb365fc5d..2b7cec8804 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -72,6 +72,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
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 99056aa041..2647d4dd23 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -6,6 +6,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
> diff --git a/drivers/net/bcm6348-eth.c b/drivers/net/bcm6348-eth.c
> new file mode 100644
> index 0000000000..24a44d83cb
> --- /dev/null
> +++ b/drivers/net/bcm6348-eth.c
> @@ -0,0 +1,576 @@
> +/*
> + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
> + *
> + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
> + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
> + *
> + * 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],
> + NULL);
> + 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);
> +
> + /* receive packets if queue is empty */
> + if (priv->rx_ret[priv->rx_pend] <= 0) {
> + uint8_t pkt_cnt = 0;
> +
> + /* try to receive packets */
> + while (_bcm6348_eth_recv(priv) > 0)
> + pkt_cnt++;
> +
> + dma_prepare_rcv_buf(&priv->rx_dma, NULL, 0);
> +
> + if (pkt_cnt)
> + debug("%s: received %u packet(s)\n", __func__, pkt_cnt);
> + }
> +
> + /* return current packet */
> + if (priv->rx_ret[priv->rx_pend] > 0)
> + *packetp = net_rx_packets[priv->rx_pend];
> +
> + return priv->rx_ret[priv->rx_pend];
> +}
> +
> +static int bcm6348_eth_send(struct udevice *dev, void *packet, int length)
> +{
> + struct bcm6348_eth_priv *priv = dev_get_priv(dev);
> +
> + return dma_send(&priv->tx_dma, packet, length, NULL);
> +}
> +
> +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) & ETH_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;
dev_remap_addr() ?
> +
> + /* get phy mode */
> + pdata->phy_interface = PHY_INTERFACE_MODE_NONE;
> + phy_mode = fdt_getprop(blob, node, "phy-mode", NULL);
dev_read_string() ?
> + 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;
dev_read_phandle_with_args() ?
> +
> + /* 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,
> +};
> diff --git a/include/configs/bmips_common.h b/include/configs/bmips_common.h
> index 39ca2e0bf3..65aa9c77cc 100644
> --- a/include/configs/bmips_common.h
> +++ b/include/configs/bmips_common.h
> @@ -6,6 +6,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 }
> @@ -16,7 +19,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
>
>
--
- Daniel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181129/563550e3/attachment.sig>
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 11/28] bmips: bcm6338: add support for bcm6348-enet
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (9 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 10/28] net: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 12/28] bmips: enable f@st1704 enet support Álvaro Fernández Rojas
` (17 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6338.dtsi | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6338.dtsi b/arch/mips/dts/brcm,bcm6338.dtsi
index 990355481c..c547e949dd 100644
--- a/arch/mips/dts/brcm,bcm6338.dtsi
+++ b/arch/mips/dts/brcm,bcm6338.dtsi
@@ -144,5 +144,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";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 12/28] bmips: enable f@st1704 enet support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (10 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 11/28] bmips: bcm6338: " Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 13/28] bmips: bcm6348: add support for bcm6348-enet Álvaro Fernández Rojas
` (16 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: no changes
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 | 8 +++++++-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/sagem,f at st1704.dts b/arch/mips/dts/sagem,f at st1704.dts
index 5300f8b6df..ec6846dd9f 100644
--- a/arch/mips/dts/sagem,f at st1704.dts
+++ b/arch/mips/dts/sagem,f at st1704.dts
@@ -39,6 +39,18 @@
};
};
+&enet {
+ status = "okay";
+ phy = <&enetphy>;
+ phy-mode = "mii";
+
+ enetphy: fixed-link {
+ reg = <1>;
+ speed = <100>;
+ full-duplex;
+ };
+};
+
&gpio {
status = "okay";
};
diff --git a/configs/sagem_f at st1704_ram_defconfig b/configs/sagem_f at st1704_ram_defconfig
index 91a966327a..8c36f5dbf8 100644
--- a/configs/sagem_f at st1704_ram_defconfig
+++ b/configs/sagem_f at st1704_ram_defconfig
@@ -27,11 +27,14 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="sagem,f at st1704"
-# CONFIG_NET is not set
+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_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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 13/28] bmips: bcm6348: add support for bcm6348-enet
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (11 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 12/28] bmips: enable f@st1704 enet support Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 14/28] bmips: enable ct-5361 enet support Álvaro Fernández Rojas
` (15 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6348.dtsi | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6348.dtsi b/arch/mips/dts/brcm,bcm6348.dtsi
index 875de232ca..79e7bd892b 100644
--- a/arch/mips/dts/brcm,bcm6348.dtsi
+++ b/arch/mips/dts/brcm,bcm6348.dtsi
@@ -161,6 +161,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>,
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 14/28] bmips: enable ct-5361 enet support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (12 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 13/28] bmips: bcm6348: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 15/28] bmips: bcm6358: add support for bcm6348-enet Álvaro Fernández Rojas
` (14 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: no changes
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(-)
diff --git a/arch/mips/dts/comtrend,ct-5361.dts b/arch/mips/dts/comtrend,ct-5361.dts
index 25747ca95d..f6b8a94e25 100644
--- a/arch/mips/dts/comtrend,ct-5361.dts
+++ b/arch/mips/dts/comtrend,ct-5361.dts
@@ -34,6 +34,18 @@
};
};
+&enet1 {
+ status = "okay";
+ phy = <&enet1phy>;
+ phy-mode = "mii";
+
+ enet1phy: fixed-link {
+ reg = <1>;
+ speed = <100>;
+ full-duplex;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/comtrend_ct5361_ram_defconfig b/configs/comtrend_ct5361_ram_defconfig
index 82f2070713..6297e78fd9 100644
--- a/configs/comtrend_ct5361_ram_defconfig
+++ b/configs/comtrend_ct5361_ram_defconfig
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,ct-5361"
-# CONFIG_NET is not set
+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_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 15/28] bmips: bcm6358: add support for bcm6348-enet
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (13 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 14/28] bmips: enable ct-5361 enet support Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 16/28] bmips: enable hg556a enet support Álvaro Fernández Rojas
` (13 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6358.dtsi | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi
index 5605723e83..5e9c9ad769 100644
--- a/arch/mips/dts/brcm,bcm6358.dtsi
+++ b/arch/mips/dts/brcm,bcm6358.dtsi
@@ -192,6 +192,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>,
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 16/28] bmips: enable hg556a enet support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (14 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 15/28] bmips: bcm6358: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 17/28] bmips: enable nb4-ser " Álvaro Fernández Rojas
` (12 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: no changes
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(-)
diff --git a/arch/mips/dts/huawei,hg556a.dts b/arch/mips/dts/huawei,hg556a.dts
index 60455c2ff8..6a7fc1df4b 100644
--- a/arch/mips/dts/huawei,hg556a.dts
+++ b/arch/mips/dts/huawei,hg556a.dts
@@ -93,6 +93,18 @@
status = "okay";
};
+&enet1 {
+ status = "okay";
+ phy = <&enet1phy>;
+ phy-mode = "mii";
+
+ enet1phy: fixed-link {
+ reg = <1>;
+ speed = <100>;
+ full-duplex;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/huawei_hg556a_ram_defconfig b/configs/huawei_hg556a_ram_defconfig
index 6bb14ba736..d4e6144319 100644
--- a/configs/huawei_hg556a_ram_defconfig
+++ b/configs/huawei_hg556a_ram_defconfig
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="huawei,hg556a"
-# CONFIG_NET is not set
+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_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 17/28] bmips: enable nb4-ser enet support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (15 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 16/28] bmips: enable hg556a enet support Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 18/28] net: add support for bcm6368-enet Álvaro Fernández Rojas
` (11 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: no changes
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(-)
diff --git a/arch/mips/dts/sfr,nb4-ser.dts b/arch/mips/dts/sfr,nb4-ser.dts
index bdc6f8ae45..dfbc4148dc 100644
--- a/arch/mips/dts/sfr,nb4-ser.dts
+++ b/arch/mips/dts/sfr,nb4-ser.dts
@@ -53,6 +53,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";
};
diff --git a/configs/sfr_nb4-ser_ram_defconfig b/configs/sfr_nb4-ser_ram_defconfig
index 12adfb01e7..39622875b1 100644
--- a/configs/sfr_nb4-ser_ram_defconfig
+++ b/configs/sfr_nb4-ser_ram_defconfig
@@ -26,11 +26,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="sfr,nb4-ser"
-# CONFIG_NET is not set
+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
@@ -42,6 +45,9 @@ CONFIG_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 18/28] net: add support for bcm6368-enet
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (16 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 17/28] bmips: enable nb4-ser " Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-29 0:44 ` Daniel Schwierzeck
2018-11-28 18:23 ` [U-Boot] [PATCH v9 19/28] bmips: bcm6368: " Álvaro Fernández Rojas
` (10 subsequent siblings)
28 siblings, 1 reply; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: introduce flow control improvements from bcm6348-eth:
- introduce rx packets caching functionality from bcm6348-eth to fix flow
control issues.
- code style fixes.
v8: introduce bcm6368-enet driver
drivers/net/Kconfig | 8 +
drivers/net/Makefile | 1 +
drivers/net/bcm6368-eth.c | 670 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 679 insertions(+)
create mode 100644 drivers/net/bcm6368-eth.c
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2b7cec8804..7044c6adf3 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -82,6 +82,14 @@ config BCM6348_ETH
help
This driver supports the BCM6348 Ethernet MAC.
+config BCM6368_ETH
+ bool "BCM6368 EMAC support"
+ depends on DM_ETH && ARCH_BMIPS
+ select DMA
+ select MII
+ help
+ This driver supports the BCM6368 Ethernet MAC.
+
config DWC_ETH_QOS
bool "Synopsys DWC Ethernet QOS device support"
depends on DM_ETH
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 2647d4dd23..0dbfa03306 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -7,6 +7,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_BCM6368_ETH) += bcm6368-eth.o
obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
obj-$(CONFIG_DRIVER_AX88180) += ax88180.o
obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
diff --git a/drivers/net/bcm6368-eth.c b/drivers/net/bcm6368-eth.c
new file mode 100644
index 0000000000..f0c2ada3e2
--- /dev/null
+++ b/drivers/net/bcm6368-eth.c
@@ -0,0 +1,670 @@
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * 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 <reset.h>
+#include <wait_bit.h>
+#include <asm/io.h>
+
+#define ETH_PORT_STR "brcm,enetsw-port"
+
+#define ETH_RX_DESC PKTBUFSRX
+#define ETH_ZLEN 60
+#define ETH_TIMEOUT 100
+
+#define ETH_MAX_PORT 8
+#define ETH_RGMII_PORT0 4
+
+/* Port traffic control */
+#define ETH_PTCTRL_REG(x) (0x0 + (x))
+#define ETH_PTCTRL_RXDIS_SHIFT 0
+#define ETH_PTCTRL_RXDIS_MASK (1 << ETH_PTCTRL_RXDIS_SHIFT)
+#define ETH_PTCTRL_TXDIS_SHIFT 1
+#define ETH_PTCTRL_TXDIS_MASK (1 << ETH_PTCTRL_TXDIS_SHIFT)
+
+/* Switch mode register */
+#define ETH_SWMODE_REG 0xb
+#define ETH_SWMODE_FWD_EN_SHIFT 1
+#define ETH_SWMODE_FWD_EN_MASK (1 << ETH_SWMODE_FWD_EN_SHIFT)
+
+/* IMP override Register */
+#define ETH_IMPOV_REG 0xe
+#define ETH_IMPOV_LINKUP_SHIFT 0
+#define ETH_IMPOV_LINKUP_MASK (1 << ETH_IMPOV_LINKUP_SHIFT)
+#define ETH_IMPOV_FDX_SHIFT 1
+#define ETH_IMPOV_FDX_MASK (1 << ETH_IMPOV_FDX_SHIFT)
+#define ETH_IMPOV_100_SHIFT 2
+#define ETH_IMPOV_100_MASK (1 << ETH_IMPOV_100_SHIFT)
+#define ETH_IMPOV_1000_SHIFT 3
+#define ETH_IMPOV_1000_MASK (1 << ETH_IMPOV_1000_SHIFT)
+#define ETH_IMPOV_RXFLOW_SHIFT 4
+#define ETH_IMPOV_RXFLOW_MASK (1 << ETH_IMPOV_RXFLOW_SHIFT)
+#define ETH_IMPOV_TXFLOW_SHIFT 5
+#define ETH_IMPOV_TXFLOW_MASK (1 << ETH_IMPOV_TXFLOW_SHIFT)
+#define ETH_IMPOV_FORCE_SHIFT 7
+#define ETH_IMPOV_FORCE_MASK (1 << ETH_IMPOV_FORCE_SHIFT)
+
+/* Port override Register */
+#define ETH_PORTOV_REG(x) (0x58 + (x))
+#define ETH_PORTOV_LINKUP_SHIFT 0
+#define ETH_PORTOV_LINKUP_MASK (1 << ETH_PORTOV_LINKUP_SHIFT)
+#define ETH_PORTOV_FDX_SHIFT 1
+#define ETH_PORTOV_FDX_MASK (1 << ETH_PORTOV_FDX_SHIFT)
+#define ETH_PORTOV_100_SHIFT 2
+#define ETH_PORTOV_100_MASK (1 << ETH_PORTOV_100_SHIFT)
+#define ETH_PORTOV_1000_SHIFT 3
+#define ETH_PORTOV_1000_MASK (1 << ETH_PORTOV_1000_SHIFT)
+#define ETH_PORTOV_RXFLOW_SHIFT 4
+#define ETH_PORTOV_RXFLOW_MASK (1 << ETH_PORTOV_RXFLOW_SHIFT)
+#define ETH_PORTOV_TXFLOW_SHIFT 5
+#define ETH_PORTOV_TXFLOW_MASK (1 << ETH_PORTOV_TXFLOW_SHIFT)
+#define ETH_PORTOV_ENABLE_SHIFT 6
+#define ETH_PORTOV_ENABLE_MASK (1 << ETH_PORTOV_ENABLE_SHIFT)
+
+/* Port RGMII control register */
+#define ETH_RGMII_CTRL_REG(x) (0x60 + (x))
+#define ETH_RGMII_CTRL_GMII_CLK_EN (1 << 7)
+#define ETH_RGMII_CTRL_MII_OVERRIDE_EN (1 << 6)
+#define ETH_RGMII_CTRL_MII_MODE_MASK (3 << 4)
+#define ETH_RGMII_CTRL_RGMII_MODE (0 << 4)
+#define ETH_RGMII_CTRL_MII_MODE (1 << 4)
+#define ETH_RGMII_CTRL_RVMII_MODE (2 << 4)
+#define ETH_RGMII_CTRL_TIMING_SEL_EN (1 << 0)
+
+/* Port RGMII timing register */
+#define ENETSW_RGMII_TIMING_REG(x) (0x68 + (x))
+
+/* MDIO control register */
+#define MII_SC_REG 0xb0
+#define MII_SC_EXT_SHIFT 16
+#define MII_SC_EXT_MASK (1 << MII_SC_EXT_SHIFT)
+#define MII_SC_REG_SHIFT 20
+#define MII_SC_PHYID_SHIFT 25
+#define MII_SC_RD_SHIFT 30
+#define MII_SC_RD_MASK (1 << MII_SC_RD_SHIFT)
+#define MII_SC_WR_SHIFT 31
+#define MII_SC_WR_MASK (1 << MII_SC_WR_SHIFT)
+
+/* MDIO data register */
+#define MII_DAT_REG 0xb4
+
+/* MDIO 1000BASE-T control/status */
+#define MII_ADVERTISE_1000 (ADVERTISE_1000HALF |\
+ ADVERTISE_1000FULL)
+#define MII_LPA_1000 (LPA_1000HALF | LPA_1000FULL)
+
+/* Global Management Configuration Register */
+#define ETH_GMCR_REG 0x200
+#define ETH_GMCR_RST_MIB_SHIFT 0
+#define ETH_GMCR_RST_MIB_MASK (1 << ETH_GMCR_RST_MIB_SHIFT)
+
+/* Jumbo control register port mask register */
+#define ETH_JMBCTL_PORT_REG 0x4004
+
+/* Jumbo control mib good frame register */
+#define ETH_JMBCTL_MAXSIZE_REG 0x4008
+
+/* ETH port data */
+struct bcm_enetsw_port {
+ bool used;
+ const char *name;
+ /* Config */
+ bool bypass_link;
+ int force_speed;
+ bool force_duplex_full;
+ /* PHY */
+ int phy_id;
+};
+
+/* ETH data */
+struct bcm6368_eth_priv {
+ struct udevice *dev;
+ 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;
+ /* Ports */
+ uint8_t num_ports;
+ struct bcm_enetsw_port used_ports[ETH_MAX_PORT];
+ int sw_port_link[ETH_MAX_PORT];
+ bool rgmii_override;
+ bool rgmii_timing;
+ /* PHY */
+ int phy_id;
+};
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static inline bool bcm_enet_port_is_rgmii(int portid)
+{
+ return portid >= ETH_RGMII_PORT0;
+}
+
+static int bcm6368_mdio_read(struct bcm6368_eth_priv *priv, uint8_t ext,
+ int phy_id, int reg)
+{
+ uint32_t val;
+
+ writel_be(0, priv->base + MII_SC_REG);
+
+ val = MII_SC_RD_MASK |
+ (phy_id << MII_SC_PHYID_SHIFT) |
+ (reg << MII_SC_REG_SHIFT);
+
+ if (ext)
+ val |= MII_SC_EXT_MASK;
+
+ writel_be(val, priv->base + MII_SC_REG);
+ udelay(50);
+
+ return readw_be(priv->base + MII_DAT_REG);
+}
+
+static int bcm6368_mdio_write(struct bcm6368_eth_priv *priv, uint8_t ext,
+ int phy_id, int reg, u16 data)
+{
+ uint32_t val;
+
+ writel_be(0, priv->base + MII_SC_REG);
+
+ val = MII_SC_WR_MASK |
+ (phy_id << MII_SC_PHYID_SHIFT) |
+ (reg << MII_SC_REG_SHIFT);
+
+ if (ext)
+ val |= MII_SC_EXT_MASK;
+
+ val |= data;
+
+ writel_be(val, priv->base + MII_SC_REG);
+ udelay(50);
+
+ return 0;
+}
+
+static int bcm6368_eth_free_pkt(struct udevice *dev, uchar *packet, int len)
+{
+ struct bcm6368_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 _bcm6368_eth_recv(struct bcm6368_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],
+ NULL);
+ if (priv->rx_ret[pkt] > 0)
+ priv->rx_desc = (priv->rx_desc + 1) % ETH_RX_DESC;
+
+ return priv->rx_ret[pkt];
+}
+
+static int bcm6368_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+ /* receive packets if queue is empty */
+ if (priv->rx_ret[priv->rx_pend] <= 0) {
+ uint8_t pkt_cnt = 0;
+
+ /* try to receive packets */
+ while (_bcm6368_eth_recv(priv) > 0)
+ pkt_cnt++;
+
+ dma_prepare_rcv_buf(&priv->rx_dma, NULL, 0);
+
+ if (pkt_cnt)
+ debug("%s: received %u packet(s)\n", __func__, pkt_cnt);
+ }
+
+ /* return current packet */
+ if (priv->rx_ret[priv->rx_pend] > 0)
+ *packetp = net_rx_packets[priv->rx_pend];
+
+ return priv->rx_ret[priv->rx_pend];
+}
+
+static int bcm6368_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+ length = max(length, ETH_ZLEN);
+
+ return dma_send(&priv->tx_dma, packet, length, NULL);
+}
+
+static int bcm6368_eth_adjust_link(struct bcm6368_eth_priv *priv)
+{
+ unsigned int i;
+
+ for (i = 0; i < priv->num_ports; i++) {
+ struct bcm_enetsw_port *port;
+ int val, j, up, advertise, lpa, speed, duplex, media;
+ int external_phy = bcm_enet_port_is_rgmii(i);
+ u8 override;
+
+ port = &priv->used_ports[i];
+ if (!port->used)
+ continue;
+
+ if (port->bypass_link)
+ continue;
+
+ /* dummy read to clear */
+ for (j = 0; j < 2; j++)
+ val = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_BMSR);
+
+ if (val == 0xffff)
+ continue;
+
+ up = (val & BMSR_LSTATUS) ? 1 : 0;
+ if (!(up ^ priv->sw_port_link[i]))
+ continue;
+
+ priv->sw_port_link[i] = up;
+
+ /* link changed */
+ if (!up) {
+ dev_info(&priv->pdev->dev, "link DOWN on %s\n",
+ port->name);
+ writeb_be(ETH_PORTOV_ENABLE_MASK,
+ priv->base + ETH_PORTOV_REG(i));
+ writeb_be(ETH_PTCTRL_RXDIS_MASK |
+ ETH_PTCTRL_TXDIS_MASK,
+ priv->base + ETH_PTCTRL_REG(i));
+ continue;
+ }
+
+ advertise = bcm6368_mdio_read(priv, external_phy, port->phy_id,
+ MII_ADVERTISE);
+
+ lpa = bcm6368_mdio_read(priv, external_phy, port->phy_id,
+ MII_LPA);
+
+ /* figure out media and duplex from advertise and LPA values */
+ media = mii_nway_result(lpa & advertise);
+ duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+
+ if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF))
+ speed = 100;
+ else
+ speed = 10;
+
+ if (val & BMSR_ESTATEN) {
+ advertise = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_CTRL1000);
+
+ lpa = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_STAT1000);
+
+ if ((advertise & MII_ADVERTISE_1000) &&
+ (lpa & MII_LPA_1000)) {
+ speed = 1000;
+ duplex = (lpa & LPA_1000FULL);
+ }
+ }
+
+ pr_alert("link UP on %s, %dMbps, %s-duplex\n",
+ port->name, speed, duplex ? "full" : "half");
+
+ override = ETH_PORTOV_ENABLE_MASK |
+ ETH_PORTOV_LINKUP_MASK;
+
+ if (speed == 1000)
+ override |= ETH_PORTOV_1000_MASK;
+ else if (speed == 100)
+ override |= ETH_PORTOV_100_MASK;
+ if (duplex)
+ override |= ETH_PORTOV_FDX_MASK;
+
+ writeb_be(override, priv->base + ETH_PORTOV_REG(i));
+ writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
+ }
+
+ return 0;
+}
+
+static int bcm6368_eth_start(struct udevice *dev)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+ int i;
+ u32 val;
+
+ priv->rx_desc = 0;
+ priv->rx_pend = 0;
+ for (i = 0; i < ETH_RX_DESC; i++)
+ priv->rx_ret[i] = 0;
+
+ /* disable all ports */
+ for (i = 0; i < priv->num_ports; i++) {
+ writeb_be(ETH_PORTOV_ENABLE_MASK,
+ priv->base + ETH_PORTOV_REG(i));
+ writeb_be(ETH_PTCTRL_RXDIS_MASK |
+ ETH_PTCTRL_TXDIS_MASK,
+ priv->base + ETH_PTCTRL_REG(i));
+
+ priv->sw_port_link[i] = 0;
+ }
+
+ /* enable external ports */
+ for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) {
+ u8 rgmii_ctrl;
+
+ if (!priv->used_ports[i].used)
+ continue;
+
+ rgmii_ctrl = readb_be(priv->base + ETH_RGMII_CTRL_REG(i));
+ rgmii_ctrl |= ETH_RGMII_CTRL_GMII_CLK_EN;
+ if (priv->rgmii_override)
+ rgmii_ctrl |= ETH_RGMII_CTRL_MII_OVERRIDE_EN;
+ if (priv->rgmii_timing)
+ rgmii_ctrl |= ETH_RGMII_CTRL_TIMING_SEL_EN;
+ writeb_be(rgmii_ctrl, priv->base + ETH_RGMII_CTRL_REG(i));
+ }
+
+ /* reset mib */
+ val = readb_be(priv->base + ETH_GMCR_REG);
+ val |= ETH_GMCR_RST_MIB_MASK;
+ writeb_be(val, priv->base + ETH_GMCR_REG);
+ mdelay(1);
+ val &= ~ETH_GMCR_RST_MIB_MASK;
+ writeb_be(val, priv->base + ETH_GMCR_REG);
+ mdelay(1);
+
+ /* force CPU port state */
+ val = readb_be(priv->base + ETH_IMPOV_REG);
+ val |= ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK;
+ writeb_be(val, priv->base + ETH_IMPOV_REG);
+
+ /* enable switch forward engine */
+ val = readb_be(priv->base + ETH_SWMODE_REG);
+ val |= ETH_SWMODE_FWD_EN_MASK;
+ writeb_be(val, priv->base + ETH_SWMODE_REG);
+
+ /* enable jumbo on all ports */
+ writel_be(0x1ff, priv->base + ETH_JMBCTL_PORT_REG);
+ writew_be(9728, priv->base + ETH_JMBCTL_MAXSIZE_REG);
+
+ /* enable dma rx channel */
+ dma_enable(&priv->rx_dma);
+
+ /* enable dma tx channel */
+ dma_enable(&priv->tx_dma);
+
+ /* apply override config for bypass_link ports here. */
+ for (i = 0; i < priv->num_ports; i++) {
+ struct bcm_enetsw_port *port;
+ u8 override;
+ port = &priv->used_ports[i];
+ if (!port->used)
+ continue;
+
+ if (!port->bypass_link)
+ continue;
+
+ override = ETH_PORTOV_ENABLE_MASK |
+ ETH_PORTOV_LINKUP_MASK;
+
+ switch (port->force_speed) {
+ case 1000:
+ override |= ETH_PORTOV_1000_MASK;
+ break;
+ case 100:
+ override |= ETH_PORTOV_100_MASK;
+ break;
+ case 10:
+ break;
+ default:
+ pr_warn("invalid forced speed on port %s: assume 10\n",
+ port->name);
+ break;
+ }
+
+ if (port->force_duplex_full)
+ override |= ETH_PORTOV_FDX_MASK;
+
+ writeb_be(override, priv->base + ETH_PORTOV_REG(i));
+ writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
+ }
+
+ bcm6368_eth_adjust_link(priv);
+
+ return 0;
+}
+
+static void bcm6368_eth_stop(struct udevice *dev)
+{
+ struct bcm6368_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);
+}
+
+static const struct eth_ops bcm6368_eth_ops = {
+ .free_pkt = bcm6368_eth_free_pkt,
+ .recv = bcm6368_eth_recv,
+ .send = bcm6368_eth_send,
+ .start = bcm6368_eth_start,
+ .stop = bcm6368_eth_stop,
+};
+
+static const struct udevice_id bcm6368_eth_ids[] = {
+ { .compatible = "brcm,bcm6368-enet", },
+ { /* sentinel */ }
+};
+
+static bool bcm6368_phy_is_external(struct bcm6368_eth_priv *priv,
+ int phy_id)
+{
+ uint8_t i;
+
+ for (i = 0; i < priv->num_ports; ++i) {
+ if (!priv->used_ports[i].used)
+ continue;
+ if (priv->used_ports[i].phy_id == phy_id)
+ return bcm_enet_port_is_rgmii(i);
+ }
+
+ return true;
+}
+
+static int bcm6368_mii_mdio_read(struct mii_dev *bus, int addr, int devaddr,
+ int reg)
+{
+ struct bcm6368_eth_priv *priv = bus->priv;
+ bool ext = bcm6368_phy_is_external(priv, addr);
+
+ return bcm6368_mdio_read(priv, ext, addr, reg);
+}
+
+static int bcm6368_mii_mdio_write(struct mii_dev *bus, int addr, int devaddr,
+ int reg, u16 data)
+{
+ struct bcm6368_eth_priv *priv = bus->priv;
+ bool ext = bcm6368_phy_is_external(priv, addr);
+
+ return bcm6368_mdio_write(priv, ext, addr, reg, data);
+}
+
+static int bcm6368_mdio_init(const char *name, struct bcm6368_eth_priv *priv)
+{
+ struct mii_dev *bus;
+
+ bus = mdio_alloc();
+ if (!bus) {
+ pr_err("%s: failed to allocate MDIO bus\n", __func__);
+ return -ENOMEM;
+ }
+
+ bus->read = bcm6368_mii_mdio_read;
+ bus->write = bcm6368_mii_mdio_write;
+ bus->priv = priv;
+ snprintf(bus->name, sizeof(bus->name), "%s", name);
+
+ return mdio_register(bus);
+}
+
+static int bcm6368_eth_probe(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+ void *blob = (void *)gd->fdt_blob;
+ fdt_addr_t addr;
+ int node = dev_of_offset(dev);
+ int ret, i;
+ unsigned int num_ports;
+
+ /* get base address */
+ addr = devfdt_get_addr(dev);
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ /* get number of ports */
+ num_ports = fdtdec_get_uint(gd->fdt_blob, node, "brcm,num-ports",
+ ETH_MAX_PORT);
+ if (!num_ports || num_ports > ETH_MAX_PORT)
+ 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);
+ }
+
+ /* set priv data */
+ priv->dev = dev;
+
+ priv->base = ioremap(addr, 0);
+ pdata->iobase = (phys_addr_t) priv->base;
+
+ priv->num_ports = num_ports;
+
+ if (fdtdec_get_bool(gd->fdt_blob, i, "brcm,rgmii-override"))
+ priv->rgmii_override = true;
+ if (fdtdec_get_bool(gd->fdt_blob, i, "brcm,rgmii-timing"))
+ priv->rgmii_timing = true;
+
+ /* get ports */
+ for (i = fdt_first_subnode(blob, node);
+ i > 0;
+ i = fdt_next_subnode(blob, i)) {
+ const char *comp;
+ const char *label;
+ unsigned int p;
+ int phy_id;
+ int speed;
+
+ comp = fdt_getprop(blob, i, "compatible", NULL);
+ if (!comp || memcmp(comp, ETH_PORT_STR, sizeof(ETH_PORT_STR)))
+ continue;
+
+ p = fdtdec_get_uint(gd->fdt_blob, i, "reg",
+ ETH_MAX_PORT);
+ if (p >= num_ports)
+ return -EINVAL;
+
+ label = fdt_getprop(blob, i, "label", NULL);
+ if (!label) {
+ debug("%s: node %s has no label\n", __func__,
+ fdt_get_name(blob, i, NULL));
+ return -EINVAL;
+ }
+
+ phy_id = fdtdec_get_int(gd->fdt_blob, i, "brcm,phy-id", -1);
+
+ priv->used_ports[p].used = true;
+ priv->used_ports[p].name = label;
+ priv->used_ports[p].phy_id = phy_id;
+
+ if (fdtdec_get_bool(gd->fdt_blob, i, "full-duplex"))
+ priv->used_ports[p].force_duplex_full = true;
+ if (fdtdec_get_bool(gd->fdt_blob, i, "bypass-link"))
+ priv->used_ports[p].bypass_link = true;
+ speed = fdtdec_get_int(gd->fdt_blob, i, "speed", 0);
+ if (speed)
+ priv->used_ports[p].force_speed = speed;
+ }
+
+ /* init mii bus */
+ ret = bcm6368_mdio_init(dev->name, priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(bcm6368_eth) = {
+ .name = "bcm6368_eth",
+ .id = UCLASS_ETH,
+ .of_match = bcm6368_eth_ids,
+ .ops = &bcm6368_eth_ops,
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+ .priv_auto_alloc_size = sizeof(struct bcm6368_eth_priv),
+ .probe = bcm6368_eth_probe,
+};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 18/28] net: add support for bcm6368-enet
2018-11-28 18:23 ` [U-Boot] [PATCH v9 18/28] net: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-29 0:44 ` Daniel Schwierzeck
0 siblings, 0 replies; 145+ messages in thread
From: Daniel Schwierzeck @ 2018-11-29 0:44 UTC (permalink / raw)
To: u-boot
Am 28.11.18 um 19:23 schrieb Álvaro Fernández Rojas:
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
> v9: introduce flow control improvements from bcm6348-eth:
> - introduce rx packets caching functionality from bcm6348-eth to fix flow
> control issues.
> - code style fixes.
> v8: introduce bcm6368-enet driver
>
> drivers/net/Kconfig | 8 +
> drivers/net/Makefile | 1 +
> drivers/net/bcm6368-eth.c | 670 ++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 679 insertions(+)
> create mode 100644 drivers/net/bcm6368-eth.c
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 2b7cec8804..7044c6adf3 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -82,6 +82,14 @@ config BCM6348_ETH
> help
> This driver supports the BCM6348 Ethernet MAC.
>
> +config BCM6368_ETH
> + bool "BCM6368 EMAC support"
> + depends on DM_ETH && ARCH_BMIPS
> + select DMA
> + select MII
> + help
> + This driver supports the BCM6368 Ethernet MAC.
> +
> config DWC_ETH_QOS
> bool "Synopsys DWC Ethernet QOS device support"
> depends on DM_ETH
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 2647d4dd23..0dbfa03306 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -7,6 +7,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_BCM6368_ETH) += bcm6368-eth.o
> obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
> obj-$(CONFIG_DRIVER_AX88180) += ax88180.o
> obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
> diff --git a/drivers/net/bcm6368-eth.c b/drivers/net/bcm6368-eth.c
> new file mode 100644
> index 0000000000..f0c2ada3e2
> --- /dev/null
> +++ b/drivers/net/bcm6368-eth.c
> @@ -0,0 +1,670 @@
> +/*
> + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
> + *
> + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
> + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
> + *
> + * 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 <reset.h>
> +#include <wait_bit.h>
> +#include <asm/io.h>
> +
> +#define ETH_PORT_STR "brcm,enetsw-port"
> +
> +#define ETH_RX_DESC PKTBUFSRX
> +#define ETH_ZLEN 60
> +#define ETH_TIMEOUT 100
> +
> +#define ETH_MAX_PORT 8
> +#define ETH_RGMII_PORT0 4
> +
> +/* Port traffic control */
> +#define ETH_PTCTRL_REG(x) (0x0 + (x))
> +#define ETH_PTCTRL_RXDIS_SHIFT 0
> +#define ETH_PTCTRL_RXDIS_MASK (1 << ETH_PTCTRL_RXDIS_SHIFT)
> +#define ETH_PTCTRL_TXDIS_SHIFT 1
> +#define ETH_PTCTRL_TXDIS_MASK (1 << ETH_PTCTRL_TXDIS_SHIFT)
> +
> +/* Switch mode register */
> +#define ETH_SWMODE_REG 0xb
> +#define ETH_SWMODE_FWD_EN_SHIFT 1
> +#define ETH_SWMODE_FWD_EN_MASK (1 << ETH_SWMODE_FWD_EN_SHIFT)
> +
> +/* IMP override Register */
> +#define ETH_IMPOV_REG 0xe
> +#define ETH_IMPOV_LINKUP_SHIFT 0
> +#define ETH_IMPOV_LINKUP_MASK (1 << ETH_IMPOV_LINKUP_SHIFT)
> +#define ETH_IMPOV_FDX_SHIFT 1
> +#define ETH_IMPOV_FDX_MASK (1 << ETH_IMPOV_FDX_SHIFT)
> +#define ETH_IMPOV_100_SHIFT 2
> +#define ETH_IMPOV_100_MASK (1 << ETH_IMPOV_100_SHIFT)
> +#define ETH_IMPOV_1000_SHIFT 3
> +#define ETH_IMPOV_1000_MASK (1 << ETH_IMPOV_1000_SHIFT)
> +#define ETH_IMPOV_RXFLOW_SHIFT 4
> +#define ETH_IMPOV_RXFLOW_MASK (1 << ETH_IMPOV_RXFLOW_SHIFT)
> +#define ETH_IMPOV_TXFLOW_SHIFT 5
> +#define ETH_IMPOV_TXFLOW_MASK (1 << ETH_IMPOV_TXFLOW_SHIFT)
> +#define ETH_IMPOV_FORCE_SHIFT 7
> +#define ETH_IMPOV_FORCE_MASK (1 << ETH_IMPOV_FORCE_SHIFT)
> +
> +/* Port override Register */
> +#define ETH_PORTOV_REG(x) (0x58 + (x))
> +#define ETH_PORTOV_LINKUP_SHIFT 0
> +#define ETH_PORTOV_LINKUP_MASK (1 << ETH_PORTOV_LINKUP_SHIFT)
> +#define ETH_PORTOV_FDX_SHIFT 1
> +#define ETH_PORTOV_FDX_MASK (1 << ETH_PORTOV_FDX_SHIFT)
> +#define ETH_PORTOV_100_SHIFT 2
> +#define ETH_PORTOV_100_MASK (1 << ETH_PORTOV_100_SHIFT)
> +#define ETH_PORTOV_1000_SHIFT 3
> +#define ETH_PORTOV_1000_MASK (1 << ETH_PORTOV_1000_SHIFT)
> +#define ETH_PORTOV_RXFLOW_SHIFT 4
> +#define ETH_PORTOV_RXFLOW_MASK (1 << ETH_PORTOV_RXFLOW_SHIFT)
> +#define ETH_PORTOV_TXFLOW_SHIFT 5
> +#define ETH_PORTOV_TXFLOW_MASK (1 << ETH_PORTOV_TXFLOW_SHIFT)
> +#define ETH_PORTOV_ENABLE_SHIFT 6
> +#define ETH_PORTOV_ENABLE_MASK (1 << ETH_PORTOV_ENABLE_SHIFT)
> +
> +/* Port RGMII control register */
> +#define ETH_RGMII_CTRL_REG(x) (0x60 + (x))
> +#define ETH_RGMII_CTRL_GMII_CLK_EN (1 << 7)
> +#define ETH_RGMII_CTRL_MII_OVERRIDE_EN (1 << 6)
> +#define ETH_RGMII_CTRL_MII_MODE_MASK (3 << 4)
> +#define ETH_RGMII_CTRL_RGMII_MODE (0 << 4)
> +#define ETH_RGMII_CTRL_MII_MODE (1 << 4)
> +#define ETH_RGMII_CTRL_RVMII_MODE (2 << 4)
> +#define ETH_RGMII_CTRL_TIMING_SEL_EN (1 << 0)
> +
> +/* Port RGMII timing register */
> +#define ENETSW_RGMII_TIMING_REG(x) (0x68 + (x))
> +
> +/* MDIO control register */
> +#define MII_SC_REG 0xb0
> +#define MII_SC_EXT_SHIFT 16
> +#define MII_SC_EXT_MASK (1 << MII_SC_EXT_SHIFT)
> +#define MII_SC_REG_SHIFT 20
> +#define MII_SC_PHYID_SHIFT 25
> +#define MII_SC_RD_SHIFT 30
> +#define MII_SC_RD_MASK (1 << MII_SC_RD_SHIFT)
> +#define MII_SC_WR_SHIFT 31
> +#define MII_SC_WR_MASK (1 << MII_SC_WR_SHIFT)
> +
> +/* MDIO data register */
> +#define MII_DAT_REG 0xb4
> +
> +/* MDIO 1000BASE-T control/status */
> +#define MII_ADVERTISE_1000 (ADVERTISE_1000HALF |\
> + ADVERTISE_1000FULL)
> +#define MII_LPA_1000 (LPA_1000HALF | LPA_1000FULL)
> +
> +/* Global Management Configuration Register */
> +#define ETH_GMCR_REG 0x200
> +#define ETH_GMCR_RST_MIB_SHIFT 0
> +#define ETH_GMCR_RST_MIB_MASK (1 << ETH_GMCR_RST_MIB_SHIFT)
> +
> +/* Jumbo control register port mask register */
> +#define ETH_JMBCTL_PORT_REG 0x4004
> +
> +/* Jumbo control mib good frame register */
> +#define ETH_JMBCTL_MAXSIZE_REG 0x4008
> +
> +/* ETH port data */
> +struct bcm_enetsw_port {
> + bool used;
> + const char *name;
> + /* Config */
> + bool bypass_link;
> + int force_speed;
> + bool force_duplex_full;
> + /* PHY */
> + int phy_id;
> +};
> +
> +/* ETH data */
> +struct bcm6368_eth_priv {
> + struct udevice *dev;
> + 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;
> + /* Ports */
> + uint8_t num_ports;
> + struct bcm_enetsw_port used_ports[ETH_MAX_PORT];
> + int sw_port_link[ETH_MAX_PORT];
> + bool rgmii_override;
> + bool rgmii_timing;
> + /* PHY */
> + int phy_id;
> +};
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static inline bool bcm_enet_port_is_rgmii(int portid)
> +{
> + return portid >= ETH_RGMII_PORT0;
> +}
> +
> +static int bcm6368_mdio_read(struct bcm6368_eth_priv *priv, uint8_t ext,
> + int phy_id, int reg)
> +{
> + uint32_t val;
> +
> + writel_be(0, priv->base + MII_SC_REG);
> +
> + val = MII_SC_RD_MASK |
> + (phy_id << MII_SC_PHYID_SHIFT) |
> + (reg << MII_SC_REG_SHIFT);
> +
> + if (ext)
> + val |= MII_SC_EXT_MASK;
> +
> + writel_be(val, priv->base + MII_SC_REG);
> + udelay(50);
> +
> + return readw_be(priv->base + MII_DAT_REG);
> +}
> +
> +static int bcm6368_mdio_write(struct bcm6368_eth_priv *priv, uint8_t ext,
> + int phy_id, int reg, u16 data)
> +{
> + uint32_t val;
> +
> + writel_be(0, priv->base + MII_SC_REG);
> +
> + val = MII_SC_WR_MASK |
> + (phy_id << MII_SC_PHYID_SHIFT) |
> + (reg << MII_SC_REG_SHIFT);
> +
> + if (ext)
> + val |= MII_SC_EXT_MASK;
> +
> + val |= data;
> +
> + writel_be(val, priv->base + MII_SC_REG);
> + udelay(50);
> +
> + return 0;
> +}
> +
> +static int bcm6368_eth_free_pkt(struct udevice *dev, uchar *packet, int len)
> +{
> + struct bcm6368_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 _bcm6368_eth_recv(struct bcm6368_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],
> + NULL);
> + if (priv->rx_ret[pkt] > 0)
> + priv->rx_desc = (priv->rx_desc + 1) % ETH_RX_DESC;
> +
> + return priv->rx_ret[pkt];
> +}
> +
> +static int bcm6368_eth_recv(struct udevice *dev, int flags, uchar **packetp)
> +{
> + struct bcm6368_eth_priv *priv = dev_get_priv(dev);
> +
> + /* receive packets if queue is empty */
> + if (priv->rx_ret[priv->rx_pend] <= 0) {
> + uint8_t pkt_cnt = 0;
> +
> + /* try to receive packets */
> + while (_bcm6368_eth_recv(priv) > 0)
> + pkt_cnt++;
> +
> + dma_prepare_rcv_buf(&priv->rx_dma, NULL, 0);
I forgot to mention this in your other ethernet driver but why do you
have your own packet queue? eth_recv() is supposed to receive one packet
from HW or return -EAGAIN. Also I think dma_prepare_rcv_buf should go to
eth_free_pkt() and pass net_rx_packets[]. eth_recv should only call
dma_receive() to check if packets are available.
> +
> + if (pkt_cnt)
> + debug("%s: received %u packet(s)\n", __func__, pkt_cnt);
> + }
> +
> + /* return current packet */
> + if (priv->rx_ret[priv->rx_pend] > 0)
> + *packetp = net_rx_packets[priv->rx_pend];
> +
> + return priv->rx_ret[priv->rx_pend];
> +}
> +
> +static int bcm6368_eth_send(struct udevice *dev, void *packet, int length)
> +{
> + struct bcm6368_eth_priv *priv = dev_get_priv(dev);
> +
> + length = max(length, ETH_ZLEN);
> +
> + return dma_send(&priv->tx_dma, packet, length, NULL);
does the HW do the actual padding? Otherwise you should set the padding
bytes to zero to avoid sending random memory content on the wire.
> +}
> +
> +static int bcm6368_eth_adjust_link(struct bcm6368_eth_priv *priv)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < priv->num_ports; i++) {
> + struct bcm_enetsw_port *port;
> + int val, j, up, advertise, lpa, speed, duplex, media;
> + int external_phy = bcm_enet_port_is_rgmii(i);
> + u8 override;
> +
> + port = &priv->used_ports[i];
> + if (!port->used)
> + continue;
> +
> + if (port->bypass_link)
> + continue;
> +
> + /* dummy read to clear */
> + for (j = 0; j < 2; j++)
> + val = bcm6368_mdio_read(priv, external_phy,
> + port->phy_id, MII_BMSR);
> +
> + if (val == 0xffff)
> + continue;
> +
> + up = (val & BMSR_LSTATUS) ? 1 : 0;
> + if (!(up ^ priv->sw_port_link[i]))
> + continue;
> +
> + priv->sw_port_link[i] = up;
> +
> + /* link changed */
> + if (!up) {
> + dev_info(&priv->pdev->dev, "link DOWN on %s\n",
> + port->name);
> + writeb_be(ETH_PORTOV_ENABLE_MASK,
> + priv->base + ETH_PORTOV_REG(i));
> + writeb_be(ETH_PTCTRL_RXDIS_MASK |
> + ETH_PTCTRL_TXDIS_MASK,
> + priv->base + ETH_PTCTRL_REG(i));
> + continue;
> + }
> +
> + advertise = bcm6368_mdio_read(priv, external_phy, port->phy_id,
> + MII_ADVERTISE);
> +
> + lpa = bcm6368_mdio_read(priv, external_phy, port->phy_id,
> + MII_LPA);
> +
> + /* figure out media and duplex from advertise and LPA values */
> + media = mii_nway_result(lpa & advertise);
> + duplex = (media & ADVERTISE_FULL) ? 1 : 0;
> +
> + if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF))
> + speed = 100;
> + else
> + speed = 10;
> +
> + if (val & BMSR_ESTATEN) {
> + advertise = bcm6368_mdio_read(priv, external_phy,
> + port->phy_id, MII_CTRL1000);
> +
> + lpa = bcm6368_mdio_read(priv, external_phy,
> + port->phy_id, MII_STAT1000);
> +
> + if ((advertise & MII_ADVERTISE_1000) &&
> + (lpa & MII_LPA_1000)) {
> + speed = 1000;
> + duplex = (lpa & LPA_1000FULL);
> + }
> + }
> +
> + pr_alert("link UP on %s, %dMbps, %s-duplex\n",
> + port->name, speed, duplex ? "full" : "half");
> +
> + override = ETH_PORTOV_ENABLE_MASK |
> + ETH_PORTOV_LINKUP_MASK;
> +
> + if (speed == 1000)
> + override |= ETH_PORTOV_1000_MASK;
> + else if (speed == 100)
> + override |= ETH_PORTOV_100_MASK;
> + if (duplex)
> + override |= ETH_PORTOV_FDX_MASK;
> +
> + writeb_be(override, priv->base + ETH_PORTOV_REG(i));
> + writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
> + }
> +
> + return 0;
> +}
> +
> +static int bcm6368_eth_start(struct udevice *dev)
> +{
> + struct bcm6368_eth_priv *priv = dev_get_priv(dev);
> + int i;
> + u32 val;
> +
> + priv->rx_desc = 0;
> + priv->rx_pend = 0;
> + for (i = 0; i < ETH_RX_DESC; i++)
> + priv->rx_ret[i] = 0;
> +
> + /* disable all ports */
> + for (i = 0; i < priv->num_ports; i++) {
> + writeb_be(ETH_PORTOV_ENABLE_MASK,
> + priv->base + ETH_PORTOV_REG(i));
> + writeb_be(ETH_PTCTRL_RXDIS_MASK |
> + ETH_PTCTRL_TXDIS_MASK,
> + priv->base + ETH_PTCTRL_REG(i));
> +
> + priv->sw_port_link[i] = 0;
> + }
> +
> + /* enable external ports */
> + for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) {
> + u8 rgmii_ctrl;
> +
> + if (!priv->used_ports[i].used)
> + continue;
> +
> + rgmii_ctrl = readb_be(priv->base + ETH_RGMII_CTRL_REG(i));
> + rgmii_ctrl |= ETH_RGMII_CTRL_GMII_CLK_EN;
> + if (priv->rgmii_override)
> + rgmii_ctrl |= ETH_RGMII_CTRL_MII_OVERRIDE_EN;
> + if (priv->rgmii_timing)
> + rgmii_ctrl |= ETH_RGMII_CTRL_TIMING_SEL_EN;
> + writeb_be(rgmii_ctrl, priv->base + ETH_RGMII_CTRL_REG(i));
> + }
> +
> + /* reset mib */
> + val = readb_be(priv->base + ETH_GMCR_REG);
> + val |= ETH_GMCR_RST_MIB_MASK;
> + writeb_be(val, priv->base + ETH_GMCR_REG);
> + mdelay(1);
> + val &= ~ETH_GMCR_RST_MIB_MASK;
> + writeb_be(val, priv->base + ETH_GMCR_REG);
> + mdelay(1);
> +
> + /* force CPU port state */
> + val = readb_be(priv->base + ETH_IMPOV_REG);
> + val |= ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK;
> + writeb_be(val, priv->base + ETH_IMPOV_REG);
> +
> + /* enable switch forward engine */
> + val = readb_be(priv->base + ETH_SWMODE_REG);
> + val |= ETH_SWMODE_FWD_EN_MASK;
> + writeb_be(val, priv->base + ETH_SWMODE_REG);
> +
> + /* enable jumbo on all ports */
> + writel_be(0x1ff, priv->base + ETH_JMBCTL_PORT_REG);
> + writew_be(9728, priv->base + ETH_JMBCTL_MAXSIZE_REG);
> +
> + /* enable dma rx channel */
> + dma_enable(&priv->rx_dma);
> +
> + /* enable dma tx channel */
> + dma_enable(&priv->tx_dma);
> +
> + /* apply override config for bypass_link ports here. */
> + for (i = 0; i < priv->num_ports; i++) {
> + struct bcm_enetsw_port *port;
> + u8 override;
> + port = &priv->used_ports[i];
> + if (!port->used)
> + continue;
> +
> + if (!port->bypass_link)
> + continue;
> +
> + override = ETH_PORTOV_ENABLE_MASK |
> + ETH_PORTOV_LINKUP_MASK;
> +
> + switch (port->force_speed) {
> + case 1000:
> + override |= ETH_PORTOV_1000_MASK;
> + break;
> + case 100:
> + override |= ETH_PORTOV_100_MASK;
> + break;
> + case 10:
> + break;
> + default:
> + pr_warn("invalid forced speed on port %s: assume 10\n",
> + port->name);
> + break;
> + }
> +
> + if (port->force_duplex_full)
> + override |= ETH_PORTOV_FDX_MASK;
> +
> + writeb_be(override, priv->base + ETH_PORTOV_REG(i));
> + writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
> + }
> +
> + bcm6368_eth_adjust_link(priv);
> +
> + return 0;
> +}
> +
> +static void bcm6368_eth_stop(struct udevice *dev)
> +{
> + struct bcm6368_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);
> +}
> +
> +static const struct eth_ops bcm6368_eth_ops = {
> + .free_pkt = bcm6368_eth_free_pkt,
> + .recv = bcm6368_eth_recv,
> + .send = bcm6368_eth_send,
> + .start = bcm6368_eth_start,
> + .stop = bcm6368_eth_stop,
> +};
> +
> +static const struct udevice_id bcm6368_eth_ids[] = {
> + { .compatible = "brcm,bcm6368-enet", },
> + { /* sentinel */ }
> +};
> +
> +static bool bcm6368_phy_is_external(struct bcm6368_eth_priv *priv,
> + int phy_id)
> +{
> + uint8_t i;
> +
> + for (i = 0; i < priv->num_ports; ++i) {
> + if (!priv->used_ports[i].used)
> + continue;
> + if (priv->used_ports[i].phy_id == phy_id)
> + return bcm_enet_port_is_rgmii(i);
> + }
> +
> + return true;
> +}
> +
> +static int bcm6368_mii_mdio_read(struct mii_dev *bus, int addr, int devaddr,
> + int reg)
> +{
> + struct bcm6368_eth_priv *priv = bus->priv;
> + bool ext = bcm6368_phy_is_external(priv, addr);
> +
> + return bcm6368_mdio_read(priv, ext, addr, reg);
> +}
> +
> +static int bcm6368_mii_mdio_write(struct mii_dev *bus, int addr, int devaddr,
> + int reg, u16 data)
> +{
> + struct bcm6368_eth_priv *priv = bus->priv;
> + bool ext = bcm6368_phy_is_external(priv, addr);
> +
> + return bcm6368_mdio_write(priv, ext, addr, reg, data);
> +}
> +
> +static int bcm6368_mdio_init(const char *name, struct bcm6368_eth_priv *priv)
> +{
> + struct mii_dev *bus;
> +
> + bus = mdio_alloc();
> + if (!bus) {
> + pr_err("%s: failed to allocate MDIO bus\n", __func__);
> + return -ENOMEM;
> + }
> +
> + bus->read = bcm6368_mii_mdio_read;
> + bus->write = bcm6368_mii_mdio_write;
> + bus->priv = priv;
> + snprintf(bus->name, sizeof(bus->name), "%s", name);
> +
> + return mdio_register(bus);
> +}
> +
> +static int bcm6368_eth_probe(struct udevice *dev)
> +{
> + struct eth_pdata *pdata = dev_get_platdata(dev);
> + struct bcm6368_eth_priv *priv = dev_get_priv(dev);
> + void *blob = (void *)gd->fdt_blob;
> + fdt_addr_t addr;
> + int node = dev_of_offset(dev);
> + int ret, i;
> + unsigned int num_ports;
> +
> + /* get base address */
> + addr = devfdt_get_addr(dev);
> + if (addr == FDT_ADDR_T_NONE)
> + return -EINVAL;
dev_remap_addr() ?
> +
> + /* get number of ports */
> + num_ports = fdtdec_get_uint(gd->fdt_blob, node, "brcm,num-ports",
> + ETH_MAX_PORT);
> + if (!num_ports || num_ports > ETH_MAX_PORT)
> + return -EINVAL;
dev_read_u32() ?
> +
> + /* 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);
> + }
> +
> + /* set priv data */
> + priv->dev = dev;
> +
> + priv->base = ioremap(addr, 0);
> + pdata->iobase = (phys_addr_t) priv->base;
> +
> + priv->num_ports = num_ports;
> +
> + if (fdtdec_get_bool(gd->fdt_blob, i, "brcm,rgmii-override"))
> + priv->rgmii_override = true;
> + if (fdtdec_get_bool(gd->fdt_blob, i, "brcm,rgmii-timing"))
> + priv->rgmii_timing = true;
dev_read_bool() ?
> +
> + /* get ports */
> + for (i = fdt_first_subnode(blob, node);
> + i > 0;
> + i = fdt_next_subnode(blob, i)) {
dev_read_first_subnode(), dev_read_next_subnode() and dev_read_*() in
the loop body?
> + const char *comp;
> + const char *label;
> + unsigned int p;
> + int phy_id;
> + int speed;
> +
> + comp = fdt_getprop(blob, i, "compatible", NULL);
> + if (!comp || memcmp(comp, ETH_PORT_STR, sizeof(ETH_PORT_STR)))
> + continue;
> +
> + p = fdtdec_get_uint(gd->fdt_blob, i, "reg",
> + ETH_MAX_PORT);
> + if (p >= num_ports)
> + return -EINVAL;
> +
> + label = fdt_getprop(blob, i, "label", NULL);
> + if (!label) {
> + debug("%s: node %s has no label\n", __func__,
> + fdt_get_name(blob, i, NULL));
> + return -EINVAL;
> + }
> +
> + phy_id = fdtdec_get_int(gd->fdt_blob, i, "brcm,phy-id", -1);
> +
> + priv->used_ports[p].used = true;
> + priv->used_ports[p].name = label;
> + priv->used_ports[p].phy_id = phy_id;
> +
> + if (fdtdec_get_bool(gd->fdt_blob, i, "full-duplex"))
> + priv->used_ports[p].force_duplex_full = true;
> + if (fdtdec_get_bool(gd->fdt_blob, i, "bypass-link"))
> + priv->used_ports[p].bypass_link = true;
> + speed = fdtdec_get_int(gd->fdt_blob, i, "speed", 0);
> + if (speed)
> + priv->used_ports[p].force_speed = speed;
> + }
> +
> + /* init mii bus */
> + ret = bcm6368_mdio_init(dev->name, priv);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> +U_BOOT_DRIVER(bcm6368_eth) = {
> + .name = "bcm6368_eth",
> + .id = UCLASS_ETH,
> + .of_match = bcm6368_eth_ids,
> + .ops = &bcm6368_eth_ops,
> + .platdata_auto_alloc_size = sizeof(struct eth_pdata),
> + .priv_auto_alloc_size = sizeof(struct bcm6368_eth_priv),
> + .probe = bcm6368_eth_probe,
> +};
>
--
- Daniel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181129/09cfab10/attachment.sig>
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 19/28] bmips: bcm6368: add support for bcm6368-enet
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (17 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 18/28] net: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 20/28] bmips: enable wap-5813n enet support Álvaro Fernández Rojas
` (9 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6368.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6368.dtsi b/arch/mips/dts/brcm,bcm6368.dtsi
index 30047f6360..89590d6ff9 100644
--- a/arch/mips/dts/brcm,bcm6368.dtsi
+++ b/arch/mips/dts/brcm,bcm6368.dtsi
@@ -205,5 +205,24 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10f00000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10f00000 0x10000>;
+ clocks = <&periph_clk BCM6368_CLK_SWPKT_USB>,
+ <&periph_clk BCM6368_CLK_SWPKT_SAR>,
+ <&periph_clk BCM6368_CLK_ROBOSW>;
+ resets = <&periph_rst BCM6368_RST_SWITCH>,
+ <&periph_rst BCM6368_RST_EPHY>;
+ dmas = <&iudma BCM6368_DMA_ENETSW_RX>,
+ <&iudma BCM6368_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <6>;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 20/28] bmips: enable wap-5813n enet support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (18 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 19/28] bmips: bcm6368: " Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 21/28] bmips: bcm6328: add support for bcm6368-enet Álvaro Fernández Rojas
` (8 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,wap-5813n.dts | 14 ++++++++++++++
configs/comtrend_wap5813n_ram_defconfig | 8 +++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,wap-5813n.dts b/arch/mips/dts/comtrend,wap-5813n.dts
index bd41dab9f8..7e835b28d2 100644
--- a/arch/mips/dts/comtrend,wap-5813n.dts
+++ b/arch/mips/dts/comtrend,wap-5813n.dts
@@ -54,6 +54,20 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 4 {
+ compatible = "brcm,enetsw-port";
+ reg = <4>;
+ label = "rgmii";
+ brcm,phy-id = <0xff>;
+ speed = <1000>;
+ full-duplex;
+ bypass-link;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/comtrend_wap5813n_ram_defconfig b/configs/comtrend_wap5813n_ram_defconfig
index 987e4c3fbc..fd5107bb7d 100644
--- a/configs/comtrend_wap5813n_ram_defconfig
+++ b/configs/comtrend_wap5813n_ram_defconfig
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,wap-5813n"
-# CONFIG_NET is not set
+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_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_DM_RESET=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 21/28] bmips: bcm6328: add support for bcm6368-enet
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (19 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 20/28] bmips: enable wap-5813n enet support Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 22/28] bmips: enable ar-5387un enet support Álvaro Fernández Rojas
` (7 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6328.dtsi | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi
index 6fa49e22bb..50beed4171 100644
--- a/arch/mips/dts/brcm,bcm6328.dtsi
+++ b/arch/mips/dts/brcm,bcm6328.dtsi
@@ -200,5 +200,22 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10e00000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10e00000 0x10000>;
+ clocks = <&periph_clk BCM6328_CLK_ROBOSW>;
+ resets = <&periph_rst BCM6328_RST_ENETSW>,
+ <&periph_rst BCM6328_RST_EPHY>;
+ dmas = <&iudma BCM6328_DMA_ENETSW_RX>,
+ <&iudma BCM6328_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <5>;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 22/28] bmips: enable ar-5387un enet support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (20 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 21/28] bmips: bcm6328: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 23/28] bmips: bcm6362: add support for bcm6368-enet Álvaro Fernández Rojas
` (6 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,ar-5387un.dts | 32 ++++++++++++++++++++++++++++++++
configs/comtrend_ar5387un_ram_defconfig | 7 ++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,ar-5387un.dts b/arch/mips/dts/comtrend,ar-5387un.dts
index e993b5cd89..03e3851ab1 100644
--- a/arch/mips/dts/comtrend,ar-5387un.dts
+++ b/arch/mips/dts/comtrend,ar-5387un.dts
@@ -24,6 +24,38 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 0 {
+ compatible = "brcm,enetsw-port";
+ reg = <0>;
+ label = "fe1";
+ brcm,phy-id = <1>;
+ };
+
+ port at 1 {
+ compatible = "brcm,enetsw-port";
+ reg = <1>;
+ label = "fe2";
+ brcm,phy-id = <2>;
+ };
+
+ port at 2 {
+ compatible = "brcm,enetsw-port";
+ reg = <2>;
+ label = "fe3";
+ brcm,phy-id = <3>;
+ };
+
+ port at 3 {
+ compatible = "brcm,enetsw-port";
+ reg = <3>;
+ label = "fe4";
+ brcm,phy-id = <4>;
+ };
+};
+
&leds {
status = "okay";
diff --git a/configs/comtrend_ar5387un_ram_defconfig b/configs/comtrend_ar5387un_ram_defconfig
index f129870ca0..5ba401a441 100644
--- a/configs/comtrend_ar5387un_ram_defconfig
+++ b/configs/comtrend_ar5387un_ram_defconfig
@@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5387un"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
CONFIG_DM_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
@@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 23/28] bmips: bcm6362: add support for bcm6368-enet
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (21 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 22/28] bmips: enable ar-5387un enet support Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 24/28] bmips: enable dgnd3700v2 enet support Álvaro Fernández Rojas
` (5 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6362.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6362.dtsi b/arch/mips/dts/brcm,bcm6362.dtsi
index 94e7de096d..c77b80a4cc 100644
--- a/arch/mips/dts/brcm,bcm6362.dtsi
+++ b/arch/mips/dts/brcm,bcm6362.dtsi
@@ -224,5 +224,24 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10e00000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10e00000 0x10000>;
+ clocks = <&periph_clk BCM6362_CLK_SWPKT_USB>,
+ <&periph_clk BCM6362_CLK_SWPKT_SAR>,
+ <&periph_clk BCM6362_CLK_ROBOSW>;
+ resets = <&periph_rst BCM6362_RST_ENETSW>,
+ <&periph_rst BCM6362_RST_EPHY>;
+ dmas = <&iudma BCM6362_DMA_ENETSW_RX>,
+ <&iudma BCM6362_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <6>;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 24/28] bmips: enable dgnd3700v2 enet support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (22 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 23/28] bmips: bcm6362: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 25/28] bmips: bcm63268: add support for bcm6368-enet Álvaro Fernández Rojas
` (4 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/netgear,dgnd3700v2.dts | 14 ++++++++++++++
configs/netgear_dgnd3700v2_ram_defconfig | 8 +++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/netgear,dgnd3700v2.dts b/arch/mips/dts/netgear,dgnd3700v2.dts
index 322d1567ff..2b72491f0b 100644
--- a/arch/mips/dts/netgear,dgnd3700v2.dts
+++ b/arch/mips/dts/netgear,dgnd3700v2.dts
@@ -43,6 +43,20 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 4 {
+ compatible = "brcm,enetsw-port";
+ reg = <4>;
+ label = "rgmii";
+ brcm,phy-id = <0xff>;
+ speed = <1000>;
+ full-duplex;
+ bypass-link;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/netgear_dgnd3700v2_ram_defconfig b/configs/netgear_dgnd3700v2_ram_defconfig
index 1abc869856..0f3914fe7e 100644
--- a/configs/netgear_dgnd3700v2_ram_defconfig
+++ b/configs/netgear_dgnd3700v2_ram_defconfig
@@ -27,17 +27,23 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
-# CONFIG_CMD_NET is not set
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="netgear,dgnd3700v2"
+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
CONFIG_LED_BCM6328=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 25/28] bmips: bcm63268: add support for bcm6368-enet
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (23 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 24/28] bmips: enable dgnd3700v2 enet support Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 26/28] bmips: enable vr-3032u enet support Álvaro Fernández Rojas
` (3 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm63268.dtsi | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi
index c7ad83c306..f8a72ef535 100644
--- a/arch/mips/dts/brcm,bcm63268.dtsi
+++ b/arch/mips/dts/brcm,bcm63268.dtsi
@@ -230,5 +230,30 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10700000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10700000 0x10000>;
+ clocks = <&periph_clk BCM63268_CLK_GMAC>,
+ <&periph_clk BCM63268_CLK_ROBOSW>,
+ <&periph_clk BCM63268_CLK_ROBOSW250>,
+ <&timer_clk BCM63268_TCLK_EPHY1>,
+ <&timer_clk BCM63268_TCLK_EPHY2>,
+ <&timer_clk BCM63268_TCLK_EPHY3>,
+ <&timer_clk BCM63268_TCLK_GPHY>;
+ resets = <&periph_rst BCM63268_RST_ENETSW>,
+ <&periph_rst BCM63268_RST_EPHY>,
+ <&periph_rst BCM63268_RST_GPHY>;
+ dmas = <&iudma BCM63268_DMA_ENETSW_RX>,
+ <&iudma BCM63268_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,rgmii-override;
+ brcm,rgmii-timing;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 26/28] bmips: enable vr-3032u enet support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (24 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 25/28] bmips: bcm63268: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 27/28] bmips: bcm6318: add support for bcm6368-enet Álvaro Fernández Rojas
` (2 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,vr-3032u.dts | 32 ++++++++++++++++++++++++++++++++
configs/comtrend_vr3032u_ram_defconfig | 7 ++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,vr-3032u.dts b/arch/mips/dts/comtrend,vr-3032u.dts
index 8c6a4a1eac..512cb52de3 100644
--- a/arch/mips/dts/comtrend,vr-3032u.dts
+++ b/arch/mips/dts/comtrend,vr-3032u.dts
@@ -24,6 +24,38 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 0 {
+ compatible = "brcm,enetsw-port";
+ reg = <0>;
+ label = "fe2";
+ brcm,phy-id = <1>;
+ };
+
+ port at 1 {
+ compatible = "brcm,enetsw-port";
+ reg = <1>;
+ label = "fe3";
+ brcm,phy-id = <2>;
+ };
+
+ port at 2 {
+ compatible = "brcm,enetsw-port";
+ reg = <2>;
+ label = "fe4";
+ brcm,phy-id = <3>;
+ };
+
+ port at 3 {
+ compatible = "brcm,enetsw-port";
+ reg = <3>;
+ label = "fe1";
+ brcm,phy-id = <4>;
+ };
+};
+
&leds {
status = "okay";
brcm,serial-leds;
diff --git a/configs/comtrend_vr3032u_ram_defconfig b/configs/comtrend_vr3032u_ram_defconfig
index 1689eecec1..47f53998e1 100644
--- a/configs/comtrend_vr3032u_ram_defconfig
+++ b/configs/comtrend_vr3032u_ram_defconfig
@@ -26,15 +26,20 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,vr-3032u"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
CONFIG_DM_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
CONFIG_LED_BLINK=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 27/28] bmips: bcm6318: add support for bcm6368-enet
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (25 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 26/28] bmips: enable vr-3032u enet support Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-28 18:23 ` [U-Boot] [PATCH v9 28/28] bmips: enable ar-5315u enet support Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6318.dtsi | 19 +++++++++++++++++++
include/dt-bindings/clock/bcm6318-clock.h | 11 +++++++++++
2 files changed, 30 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6318.dtsi b/arch/mips/dts/brcm,bcm6318.dtsi
index d04b7cbb01..d678dab242 100644
--- a/arch/mips/dts/brcm,bcm6318.dtsi
+++ b/arch/mips/dts/brcm,bcm6318.dtsi
@@ -190,6 +190,25 @@
status = "disabled";
};
+ enet: ethernet at 10080000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10080000 0x8000>;
+ clocks = <&periph_clk BCM6318_CLK_ROBOSW250>,
+ <&periph_clk BCM6318_CLK_ROBOSW025>,
+ <&ubus_clk BCM6318_UCLK_ROBOSW>;
+ resets = <&periph_rst BCM6318_RST_ENETSW>,
+ <&periph_rst BCM6318_RST_EPHY>;
+ dmas = <&iudma BCM6318_DMA_ENETSW_RX>,
+ <&iudma BCM6318_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <5>;
+
+ status = "disabled";
+ };
+
iudma: dma-controller at 10088000 {
compatible = "brcm,bcm6368-iudma";
reg = <0x10088000 0x80>,
diff --git a/include/dt-bindings/clock/bcm6318-clock.h b/include/dt-bindings/clock/bcm6318-clock.h
index d5e13c5c2d..3f10448cef 100644
--- a/include/dt-bindings/clock/bcm6318-clock.h
+++ b/include/dt-bindings/clock/bcm6318-clock.h
@@ -33,4 +33,15 @@
#define BCM6318_CLK_AFE 29
#define BCM6318_CLK_QPROC 30
+#define BCM6318_UCLK_ADSL 0
+#define BCM6318_UCLK_ARB 1
+#define BCM6318_UCLK_MIPS 2
+#define BCM6318_UCLK_PCIE 3
+#define BCM6318_UCLK_PERIPH 4
+#define BCM6318_UCLK_PHYMIPS 5
+#define BCM6318_UCLK_ROBOSW 6
+#define BCM6318_UCLK_SAR 7
+#define BCM6318_UCLK_SDR 8
+#define BCM6318_UCLK_USB 9
+
#endif /* __DT_BINDINGS_CLOCK_BCM6318_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v9 28/28] bmips: enable ar-5315u enet support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (26 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 27/28] bmips: bcm6318: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-28 18:23 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-28 18:23 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,ar-5315u.dts | 32 ++++++++++++++++++++++++++++++++
configs/comtrend_ar5315u_ram_defconfig | 7 ++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,ar-5315u.dts b/arch/mips/dts/comtrend,ar-5315u.dts
index 45570189d0..eb60aaa8d5 100644
--- a/arch/mips/dts/comtrend,ar-5315u.dts
+++ b/arch/mips/dts/comtrend,ar-5315u.dts
@@ -24,6 +24,38 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 0 {
+ compatible = "brcm,enetsw-port";
+ reg = <0>;
+ label = "fe4";
+ brcm,phy-id = <1>;
+ };
+
+ port at 1 {
+ compatible = "brcm,enetsw-port";
+ reg = <1>;
+ label = "fe3";
+ brcm,phy-id = <2>;
+ };
+
+ port at 2 {
+ compatible = "brcm,enetsw-port";
+ reg = <2>;
+ label = "fe2";
+ brcm,phy-id = <3>;
+ };
+
+ port at 3 {
+ compatible = "brcm,enetsw-port";
+ reg = <3>;
+ label = "fe1";
+ brcm,phy-id = <4>;
+ };
+};
+
&leds {
status = "okay";
diff --git a/configs/comtrend_ar5315u_ram_defconfig b/configs/comtrend_ar5315u_ram_defconfig
index d9ef52e68d..1b8e4e43c4 100644
--- a/configs/comtrend_ar5315u_ram_defconfig
+++ b/configs/comtrend_ar5315u_ram_defconfig
@@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5315u"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
CONFIG_DM_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
@@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6318_USBH_PHY=y
CONFIG_BCM6328_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support
2018-11-28 18:23 ` [U-Boot] [PATCH v9 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (27 preceding siblings ...)
2018-11-28 18:23 ` [U-Boot] [PATCH v9 28/28] bmips: enable ar-5315u enet support Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 01/28] dma: add bcm6348-iudma support Álvaro Fernández Rojas
` (28 more replies)
28 siblings, 29 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
In 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...).
v10: Introduce changes suggested by Daniel Schwierzeck:
- Fix license identifiers.
bcm6348-iudma:
- Move DMAD_ST defines out of dma desc struct definition.
- Remove unneded aigned attribute from dma desc struct definition.
- Fill dma ring from consumer driver instead of allocating a new buffer.
- Correctly check clock/reset errors while probing.
- Switch to live DM live tree.
bcm6348-enet:
- Remove packet queue.
- Move dma_prepare_rcv_buf to free_pkt.
- Switch to live DM live tree.
bcm6368-enet:
- Remove packet queue.
- Move dma_prepare_rcv_buf to free_pkt.
- Pad packets smaller than ETH_ZLEN.
- Switch to live DM live tree.
v9: Separate generic dma channels support from bmips enet support
bcm6348-iudma:
- bcm6348_iudma_chan_stop: switch to mdelay when resetting channel.
- bcm6348_iudma_receive: track dirty dma descriptors and no longer trigger
dma rx channel.
- bcm6348_iudma_send: reorder to properly flush cache and set dma descriptor
config.
- bcm6348_iudma_prepare_rcv_buf: implemented to clear dirty dma descriptors.
bcm6348-enet:
- bcm6348_eth_recv: clear dirty dma descriptors only when packets are copied
from rx dma.
- bcm6348_eth_send: remove dma rx channel reset when sending packet.
bcm6368-enet:
- introduce rx packets caching functionality from bcm6348-eth to fix flow
control issues.
- code style fixes.
v8: Introduce bcm6368-enet driver support.
v5: Fix issues reported by Grygorii Strashko and other fixes:
- 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: Switch to live tree API.
v2: Fix bcm6348-iudma rx burst config.
Álvaro Fernández Rojas (28):
dma: add bcm6348-iudma support
bmips: bcm6338: add bcm6348-iudma support
bmips: bcm6348: add bcm6348-iudma support
bmips: bcm6358: add bcm6348-iudma support
bmips: bcm6368: add bcm6348-iudma support
bmips: bcm6328: add bcm6348-iudma support
bmips: bcm6362: add bcm6348-iudma support
bmips: bcm63268: add bcm6348-iudma support
bmips: bcm6318: add bcm6348-iudma support
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
net: add support for bcm6368-enet
bmips: bcm6368: add support for bcm6368-enet
bmips: enable wap-5813n enet support
bmips: bcm6328: add support for bcm6368-enet
bmips: enable ar-5387un enet support
bmips: bcm6362: add support for bcm6368-enet
bmips: enable dgnd3700v2 enet support
bmips: bcm63268: add support for bcm6368-enet
bmips: enable vr-3032u enet support
bmips: bcm6318: add support for bcm6368-enet
bmips: enable ar-5315u enet support
arch/mips/dts/brcm,bcm6318.dtsi | 38 ++
arch/mips/dts/brcm,bcm63268.dtsi | 38 ++
arch/mips/dts/brcm,bcm6328.dtsi | 30 ++
arch/mips/dts/brcm,bcm6338.dtsi | 29 ++
arch/mips/dts/brcm,bcm6348.dtsi | 42 ++
arch/mips/dts/brcm,bcm6358.dtsi | 46 +++
arch/mips/dts/brcm,bcm6362.dtsi | 32 ++
arch/mips/dts/brcm,bcm6368.dtsi | 32 ++
arch/mips/dts/comtrend,ar-5315u.dts | 32 ++
arch/mips/dts/comtrend,ar-5387un.dts | 32 ++
arch/mips/dts/comtrend,ct-5361.dts | 12 +
arch/mips/dts/comtrend,vr-3032u.dts | 32 ++
arch/mips/dts/comtrend,wap-5813n.dts | 14 +
arch/mips/dts/huawei,hg556a.dts | 12 +
arch/mips/dts/netgear,dgnd3700v2.dts | 14 +
arch/mips/dts/sagem,f at st1704.dts | 12 +
arch/mips/dts/sfr,nb4-ser.dts | 24 ++
configs/comtrend_ar5315u_ram_defconfig | 7 +-
configs/comtrend_ar5387un_ram_defconfig | 7 +-
configs/comtrend_ct5361_ram_defconfig | 8 +-
configs/comtrend_vr3032u_ram_defconfig | 7 +-
configs/comtrend_wap5813n_ram_defconfig | 8 +-
configs/huawei_hg556a_ram_defconfig | 8 +-
configs/netgear_dgnd3700v2_ram_defconfig | 8 +-
configs/sagem_f at st1704_ram_defconfig | 8 +-
configs/sfr_nb4-ser_ram_defconfig | 8 +-
drivers/dma/Kconfig | 9 +
drivers/dma/Makefile | 1 +
drivers/dma/bcm6348-iudma.c | 642 ++++++++++++++++++++++++++++++
drivers/net/Kconfig | 18 +
drivers/net/Makefile | 2 +
drivers/net/bcm6348-eth.c | 537 +++++++++++++++++++++++++
drivers/net/bcm6368-eth.c | 625 +++++++++++++++++++++++++++++
include/configs/bmips_common.h | 6 +-
include/dt-bindings/clock/bcm6318-clock.h | 11 +
include/dt-bindings/dma/bcm6318-dma.h | 14 +
include/dt-bindings/dma/bcm63268-dma.h | 14 +
include/dt-bindings/dma/bcm6328-dma.h | 14 +
include/dt-bindings/dma/bcm6338-dma.h | 14 +
include/dt-bindings/dma/bcm6348-dma.h | 16 +
include/dt-bindings/dma/bcm6358-dma.h | 16 +
include/dt-bindings/dma/bcm6362-dma.h | 14 +
include/dt-bindings/dma/bcm6368-dma.h | 14 +
43 files changed, 2497 insertions(+), 10 deletions(-)
create mode 100644 drivers/dma/bcm6348-iudma.c
create mode 100644 drivers/net/bcm6348-eth.c
create mode 100644 drivers/net/bcm6368-eth.c
create mode 100644 include/dt-bindings/dma/bcm6318-dma.h
create mode 100644 include/dt-bindings/dma/bcm63268-dma.h
create mode 100644 include/dt-bindings/dma/bcm6328-dma.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
create mode 100644 include/dt-bindings/dma/bcm6362-dma.h
create mode 100644 include/dt-bindings/dma/bcm6368-dma.h
--
2.11.0
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 01/28] dma: add bcm6348-iudma support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-30 13:46 ` Daniel Schwierzeck
2018-11-29 22:25 ` [U-Boot] [PATCH v10 02/28] bmips: bcm6338: " Álvaro Fernández Rojas
` (27 subsequent siblings)
28 siblings, 1 reply; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
BCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: Introduce changes suggested by Daniel Schwierzeck:
- Fix license identifiers.
- Move DMAD_ST defines out of dma desc struct definition.
- Remove unneded aigned attribute from dma desc struct definition.
- Fill dma ring from consumer driver instead of allocating a new buffer.
- Correctly check clock/reset errors while probing.
- Switch to live DM live tree.
v9: introduce dma_prepare_rcv_buf dma op:
- bcm6348_iudma_chan_stop: switch to mdelay when resetting channel.
- bcm6348_iudma_receive: track dirty dma descriptors and no longer trigger
dma rx channel.
- bcm6348_iudma_send: reorder to properly flush cache and set dma descriptor
config.
- bcm6348_iudma_prepare_rcv_buf: implemented to clear dirty dma descriptors.
v8: Introduce changes from Grygorii Strashko
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 | 642 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 652 insertions(+)
create mode 100644 drivers/dma/bcm6348-iudma.c
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 8a4162eccd..1820676d7a 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -26,6 +26,15 @@ config SANDBOX_DMA
Enable support for a test DMA uclass implementation. It stimulates
DMA transfer by simple copying data between channels.
+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
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index aff31f986a..b5f9147e0a 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -7,6 +7,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_SANDBOX_DMA) += sandbox-dma-test.o
obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o
diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c
new file mode 100644
index 0000000000..699f1a6754
--- /dev/null
+++ b/drivers/dma/bcm6348-iudma.c
@@ -0,0 +1,642 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/dma/bcm63xx-iudma.c:
+ * Copyright (C) 2015 Simon Arlott <simon@fire.lp0.eu>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h:
+ * Copyright (C) 2000-2010 Broadcom Corporation
+ *
+ * Derived from bcm963xx_4.12L.06B_consumer/bcmdrivers/opensource/net/enet/impl4/bcmenet.c:
+ * Copyright (C) 2010 Broadcom Corporation
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dma-uclass.h>
+#include <memalign.h>
+#include <reset.h>
+#include <asm/io.h>
+
+#define DMA_RX_DESC 6
+#define DMA_TX_DESC 1
+
+/* DMA Channels */
+#define DMA_CHAN_FLOWC(x) ((x) >> 1)
+#define DMA_CHAN_MAX 16
+#define DMA_CHAN_SIZE 0x10
+#define DMA_CHAN_TOUT 500
+
+/* DMA Global Configuration register */
+#define DMA_CFG_REG 0x00
+#define DMA_CFG_ENABLE_SHIFT 0
+#define DMA_CFG_ENABLE_MASK (1 << DMA_CFG_ENABLE_SHIFT)
+#define DMA_CFG_FLOWC_ENABLE(x) BIT(DMA_CHAN_FLOWC(x) + 1)
+#define DMA_CFG_NCHANS_SHIFT 24
+#define DMA_CFG_NCHANS_MASK (0xf << DMA_CFG_NCHANS_SHIFT)
+
+/* DMA Global Flow Control registers */
+#define DMA_FLOWC_THR_LO_REG(x) (0x04 + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_THR_HI_REG(x) (0x08 + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_ALLOC_REG(x) (0x0c + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_ALLOC_FORCE_SHIFT 31
+#define DMA_FLOWC_ALLOC_FORCE_MASK (1 << DMA_FLOWC_ALLOC_FORCE_SHIFT)
+
+/* DMA Global Reset register */
+#define DMA_RST_REG 0x34
+#define DMA_RST_CHAN_SHIFT 0
+#define DMA_RST_CHAN_MASK(x) (1 << x)
+
+/* DMA Channel Configuration register */
+#define DMAC_CFG_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
+#define DMAC_CFG_ENABLE_SHIFT 0
+#define DMAC_CFG_ENABLE_MASK (1 << DMAC_CFG_ENABLE_SHIFT)
+#define DMAC_CFG_PKT_HALT_SHIFT 1
+#define DMAC_CFG_PKT_HALT_MASK (1 << DMAC_CFG_PKT_HALT_SHIFT)
+#define DMAC_CFG_BRST_HALT_SHIFT 2
+#define DMAC_CFG_BRST_HALT_MASK (1 << DMAC_CFG_BRST_HALT_SHIFT)
+
+/* DMA Channel Max Burst Length register */
+#define DMAC_BURST_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
+
+/* DMA SRAM Descriptor Ring Start register */
+#define DMAS_RSTART_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
+
+/* DMA SRAM State/Bytes done/ring offset register */
+#define DMAS_STATE_DATA_REG(x) (DMA_CHAN_SIZE * (x) + 0x04)
+
+/* DMA SRAM Buffer Descriptor status and length register */
+#define DMAS_DESC_LEN_STATUS_REG(x) (DMA_CHAN_SIZE * (x) + 0x08)
+
+/* DMA SRAM Buffer Descriptor status and length register */
+#define DMAS_DESC_BASE_BUFPTR_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
+
+/* DMA Descriptor Status */
+#define DMAD_ST_CRC_SHIFT 8
+#define DMAD_ST_CRC_MASK (1 << DMAD_ST_CRC_SHIFT)
+#define DMAD_ST_WRAP_SHIFT 12
+#define DMAD_ST_WRAP_MASK (1 << DMAD_ST_WRAP_SHIFT)
+#define DMAD_ST_SOP_SHIFT 13
+#define DMAD_ST_SOP_MASK (1 << DMAD_ST_SOP_SHIFT)
+#define DMAD_ST_EOP_SHIFT 14
+#define DMAD_ST_EOP_MASK (1 << DMAD_ST_EOP_SHIFT)
+#define DMAD_ST_OWN_SHIFT 15
+#define DMAD_ST_OWN_MASK (1 << DMAD_ST_OWN_SHIFT)
+
+#define DMAD6348_ST_OV_ERR_SHIFT 0
+#define DMAD6348_ST_OV_ERR_MASK (1 << DMAD6348_ST_OV_ERR_SHIFT)
+#define DMAD6348_ST_CRC_ERR_SHIFT 1
+#define DMAD6348_ST_CRC_ERR_MASK (1 << DMAD6348_ST_CRC_ERR_SHIFT)
+#define DMAD6348_ST_RX_ERR_SHIFT 2
+#define DMAD6348_ST_RX_ERR_MASK (1 << DMAD6348_ST_RX_ERR_SHIFT)
+#define DMAD6348_ST_OS_ERR_SHIFT 4
+#define DMAD6348_ST_OS_ERR_MASK (1 << DMAD6348_ST_OS_ERR_SHIFT)
+#define DMAD6348_ST_UN_ERR_SHIFT 9
+#define DMAD6348_ST_UN_ERR_MASK (1 << DMAD6348_ST_UN_ERR_SHIFT)
+
+struct bcm6348_dma_desc {
+ uint16_t length;
+ uint16_t status;
+ uint32_t address;
+};
+
+struct bcm6348_chan_priv {
+ void __iomem *dma_ring;
+ uint8_t dma_ring_size;
+ uint8_t desc_id;
+ uint8_t desc_cnt;
+ bool *busy_desc;
+ bool running;
+};
+
+struct bcm6348_iudma_hw {
+ uint16_t err_mask;
+};
+
+struct bcm6348_iudma_priv {
+ const struct bcm6348_iudma_hw *hw;
+ void __iomem *base;
+ void __iomem *chan;
+ void __iomem *sram;
+ struct bcm6348_chan_priv **ch_priv;
+ uint8_t n_channels;
+};
+
+static inline bool bcm6348_iudma_chan_is_rx(uint8_t ch)
+{
+ return !(ch & 1);
+}
+
+static inline void bcm6348_iudma_fdc(void *ptr, ulong size)
+{
+ ulong start = (ulong) ptr;
+
+ flush_dcache_range(start, start + size);
+}
+
+static inline void bcm6348_iudma_idc(void *ptr, ulong size)
+{
+ ulong start = (ulong) ptr;
+
+ invalidate_dcache_range(start, start + size);
+}
+
+static void bcm6348_iudma_chan_stop(struct bcm6348_iudma_priv *priv,
+ uint8_t ch)
+{
+ unsigned int timeout = DMA_CHAN_TOUT;
+
+ do {
+ uint32_t cfg, halt;
+
+ if (timeout > DMA_CHAN_TOUT / 2)
+ halt = DMAC_CFG_PKT_HALT_MASK;
+ else
+ halt = DMAC_CFG_BRST_HALT_MASK;
+
+ /* try to stop dma channel */
+ writel_be(halt, priv->chan + DMAC_CFG_REG(ch));
+ mb();
+
+ /* check if channel was stopped */
+ cfg = readl_be(priv->chan + DMAC_CFG_REG(ch));
+ if (!(cfg & DMAC_CFG_ENABLE_MASK))
+ break;
+
+ udelay(1);
+ } while (--timeout);
+
+ if (!timeout)
+ pr_err("unable to stop channel %u\n", ch);
+
+ /* reset dma channel */
+ setbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
+ mb();
+ clrbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
+}
+
+static int bcm6348_iudma_disable(struct dma *dma)
+{
+ struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+ struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+
+ /* stop dma channel */
+ bcm6348_iudma_chan_stop(priv, dma->id);
+
+ /* dma flow control */
+ if (bcm6348_iudma_chan_is_rx(dma->id))
+ writel_be(DMA_FLOWC_ALLOC_FORCE_MASK,
+ DMA_FLOWC_ALLOC_REG(dma->id));
+
+ /* init channel config */
+ ch_priv->running = false;
+ ch_priv->desc_id = 0;
+ if (bcm6348_iudma_chan_is_rx(dma->id))
+ ch_priv->desc_cnt = 0;
+ else
+ ch_priv->desc_cnt = ch_priv->dma_ring_size;
+
+ return 0;
+}
+
+static int bcm6348_iudma_enable(struct dma *dma)
+{
+ const 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 = ch_priv->dma_ring;
+ uint8_t i;
+
+ /* dma ring init */
+ for (i = 0; i < ch_priv->desc_cnt; i++) {
+ if (bcm6348_iudma_chan_is_rx(dma->id)) {
+ ch_priv->busy_desc[i] = false;
+ dma_desc->status |= DMAD_ST_OWN_MASK;
+ } else {
+ dma_desc->status = 0;
+ dma_desc->length = 0;
+ dma_desc->address = 0;
+ }
+
+ if (i == ch_priv->desc_cnt - 1)
+ dma_desc->status |= DMAD_ST_WRAP_MASK;
+
+ dma_desc++;
+ }
+
+ /* init to first descriptor */
+ ch_priv->desc_id = 0;
+
+ /* force cache writeback */
+ bcm6348_iudma_fdc(ch_priv->dma_ring,
+ sizeof(*dma_desc) * ch_priv->desc_cnt);
+
+ /* 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->desc_cnt / 3;
+ writel_be(val, priv->base + DMA_FLOWC_THR_LO_REG(dma->id));
+
+ val = (ch_priv->desc_cnt * 2) / 3;
+ writel_be(val, priv->base + DMA_FLOWC_THR_HI_REG(dma->id));
+
+ writel_be(0, priv->base + DMA_FLOWC_ALLOC_REG(dma->id));
+ }
+
+ /* set dma max burst */
+ writel_be(ch_priv->desc_cnt,
+ priv->chan + DMAC_BURST_REG(dma->id));
+
+ /* kick rx dma channel */
+ if (bcm6348_iudma_chan_is_rx(dma->id))
+ setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
+ DMAC_CFG_ENABLE_MASK);
+
+ /* channel is now enabled */
+ ch_priv->running = true;
+
+ return 0;
+}
+
+static int bcm6348_iudma_request(struct dma *dma)
+{
+ const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+ struct bcm6348_chan_priv *ch_priv;
+
+ /* check if channel is valid */
+ if (dma->id >= priv->n_channels)
+ return -ENODEV;
+
+ /* alloc channel private data */
+ priv->ch_priv[dma->id] = calloc(1, sizeof(struct bcm6348_chan_priv));
+ if (!priv->ch_priv[dma->id])
+ return -ENOMEM;
+ ch_priv = priv->ch_priv[dma->id];
+
+ /* alloc dma ring */
+ if (bcm6348_iudma_chan_is_rx(dma->id))
+ ch_priv->dma_ring_size = DMA_RX_DESC;
+ else
+ ch_priv->dma_ring_size = DMA_TX_DESC;
+
+ ch_priv->dma_ring =
+ malloc_cache_aligned(sizeof(struct bcm6348_dma_desc) *
+ ch_priv->dma_ring_size);
+ if (!ch_priv->dma_ring)
+ return -ENOMEM;
+
+ /* init channel config */
+ ch_priv->running = false;
+ ch_priv->desc_id = 0;
+ if (bcm6348_iudma_chan_is_rx(dma->id)) {
+ ch_priv->desc_cnt = 0;
+ ch_priv->busy_desc = calloc(ch_priv->desc_cnt, sizeof(bool));
+ } else {
+ ch_priv->desc_cnt = ch_priv->dma_ring_size;
+ ch_priv->busy_desc = NULL;
+ }
+
+ return 0;
+}
+
+static int bcm6348_iudma_receive(struct dma *dma, void **dst, void *metadata)
+{
+ const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+ const struct bcm6348_iudma_hw *hw = priv->hw;
+ struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+ struct bcm6348_dma_desc *dma_desc = dma_desc = ch_priv->dma_ring;
+ int ret;
+
+ /* get dma ring descriptor address */
+ dma_desc += ch_priv->desc_id;
+
+ /* invalidate cache data */
+ bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc));
+
+ /* check dma own */
+ if (dma_desc->status & DMAD_ST_OWN_MASK)
+ return -EAGAIN;
+
+ /* check pkt */
+ if (!(dma_desc->status & DMAD_ST_EOP_MASK) ||
+ !(dma_desc->status & DMAD_ST_SOP_MASK) ||
+ (dma_desc->status & hw->err_mask)) {
+ pr_err("invalid pkt received (ch=%ld desc=%u) (st=%04x)\n",
+ dma->id, ch_priv->desc_id, dma_desc->status);
+ ret = -EAGAIN;
+ } else {
+ /* set dma buffer address */
+ *dst = phys_to_virt(dma_desc->address);
+
+ /* invalidate cache data */
+ bcm6348_iudma_idc(*dst, dma_desc->length);
+
+ /* remove crc */
+ ret = dma_desc->length - 4;
+ }
+
+ /* busy dma descriptor */
+ ch_priv->busy_desc[ch_priv->desc_id] = true;
+
+ /* increment dma descriptor */
+ ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt;
+
+ return ret;
+}
+
+static int bcm6348_iudma_send(struct dma *dma, void *src, size_t len,
+ void *metadata)
+{
+ const 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;
+ uint16_t status;
+
+ /* flush cache */
+ bcm6348_iudma_fdc(src, len);
+
+ /* get dma ring descriptor address */
+ dma_desc = ch_priv->dma_ring;
+ dma_desc += ch_priv->desc_id;
+
+ /* config dma descriptor */
+ status = (DMAD_ST_OWN_MASK |
+ DMAD_ST_EOP_MASK |
+ DMAD_ST_CRC_MASK |
+ DMAD_ST_SOP_MASK);
+ if (ch_priv->desc_id == ch_priv->desc_cnt - 1)
+ status |= DMAD_ST_WRAP_MASK;
+
+ /* set dma descriptor */
+ dma_desc->address = virt_to_phys(src);
+ dma_desc->length = len;
+ dma_desc->status = status;
+
+ /* flush cache */
+ bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc));
+
+ /* kick tx dma channel */
+ setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK);
+
+ /* poll dma status */
+ do {
+ /* invalidate cache */
+ bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc));
+
+ if (!(dma_desc->status & DMAD_ST_OWN_MASK))
+ break;
+ } while(1);
+
+ /* increment dma descriptor */
+ ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt;
+
+ return 0;
+}
+
+static int bcm6348_iudma_free_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+ const 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 = ch_priv->dma_ring;
+ uint16_t status;
+ uint8_t i;
+ u32 cfg;
+
+ /* get dirty dma descriptor */
+ for (i = 0; i < ch_priv->desc_cnt; i++) {
+ if (phys_to_virt(dma_desc->address) == dst)
+ break;
+
+ dma_desc++;
+ }
+
+ /* dma descriptor not found */
+ if (i == ch_priv->desc_cnt) {
+ pr_err("dirty dma descriptor not found\n");
+ return -ENOENT;
+ }
+
+ /* invalidate cache */
+ bcm6348_iudma_idc(ch_priv->dma_ring,
+ sizeof(*dma_desc) * ch_priv->desc_cnt);
+
+ /* free dma descriptor */
+ ch_priv->busy_desc[i] = false;
+
+ status = DMAD_ST_OWN_MASK;
+ if (i == ch_priv->desc_cnt - 1)
+ status |= DMAD_ST_WRAP_MASK;
+
+ dma_desc->status |= status;
+ dma_desc->length = PKTSIZE_ALIGN;
+
+ /* tell dma we allocated one buffer */
+ writel_be(1, DMA_FLOWC_ALLOC_REG(dma->id));
+
+ /* flush cache */
+ bcm6348_iudma_fdc(ch_priv->dma_ring,
+ sizeof(*dma_desc) * ch_priv->desc_cnt);
+
+ /* kick rx dma channel if disabled */
+ cfg = readl_be(priv->chan + DMAC_CFG_REG(dma->id));
+ if (!(cfg & DMAC_CFG_ENABLE_MASK))
+ setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
+ DMAC_CFG_ENABLE_MASK);
+
+ return 0;
+}
+
+static int bcm6348_iudma_add_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+ const 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 = ch_priv->dma_ring;
+
+ /* no more dma descriptors available */
+ if (ch_priv->desc_cnt == ch_priv->dma_ring_size) {
+ pr_err("max number of buffers reached\n");
+ return -EINVAL;
+ }
+
+ /* get next dma descriptor */
+ dma_desc += ch_priv->desc_cnt;
+
+ /* init dma descriptor */
+ dma_desc->address = virt_to_phys(dst);
+ dma_desc->length = size;
+ dma_desc->status = 0;
+
+ /* flush cache */
+ bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc));
+
+ /* increment dma descriptors */
+ ch_priv->desc_cnt++;
+
+ return 0;
+}
+
+static int bcm6348_iudma_prepare_rcv_buf(struct dma *dma, void *dst,
+ size_t size)
+{
+ const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+ struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+
+ /* only add new rx buffers if channel isn't running */
+ if (ch_priv->running)
+ return bcm6348_iudma_free_rcv_buf(dma, dst, size);
+ else
+ return bcm6348_iudma_add_rcv_buf(dma, dst, size);
+}
+
+static const struct dma_ops bcm6348_iudma_ops = {
+ .disable = bcm6348_iudma_disable,
+ .enable = bcm6348_iudma_enable,
+ .prepare_rcv_buf = bcm6348_iudma_prepare_rcv_buf,
+ .request = bcm6348_iudma_request,
+ .receive = bcm6348_iudma_receive,
+ .send = bcm6348_iudma_send,
+};
+
+static const struct bcm6348_iudma_hw bcm6348_hw = {
+ .err_mask = (DMAD6348_ST_OV_ERR_MASK |
+ DMAD6348_ST_CRC_ERR_MASK |
+ DMAD6348_ST_RX_ERR_MASK |
+ DMAD6348_ST_OS_ERR_MASK |
+ DMAD6348_ST_UN_ERR_MASK),
+};
+
+static const struct bcm6348_iudma_hw bcm6368_hw = {
+ .err_mask = 0,
+};
+
+static const struct udevice_id bcm6348_iudma_ids[] = {
+ {
+ .compatible = "brcm,bcm6348-iudma",
+ .data = (ulong)&bcm6348_hw,
+ }, {
+ .compatible = "brcm,bcm6368-iudma",
+ .data = (ulong)&bcm6368_hw,
+ }, { /* sentinel */ }
+};
+
+static int bcm6348_iudma_probe(struct udevice *dev)
+{
+ struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct bcm6348_iudma_priv *priv = dev_get_priv(dev);
+ const struct bcm6348_iudma_hw *hw =
+ (const struct bcm6348_iudma_hw *)dev_get_driver_data(dev);
+ uint8_t ch;
+ int i;
+
+ uc_priv->supported = (DMA_SUPPORTS_DEV_TO_MEM |
+ DMA_SUPPORTS_MEM_TO_DEV);
+ priv->hw = hw;
+
+ /* dma global base address */
+ priv->base = dev_remap_addr_name(dev, "dma");
+ if (!priv->base)
+ return -EINVAL;
+
+ /* dma channels base address */
+ priv->chan = dev_remap_addr_name(dev, "dma-channels");
+ if (!priv->chan)
+ return -EINVAL;
+
+ /* dma sram base address */
+ priv->sram = dev_remap_addr_name(dev, "dma-sram");
+ if (!priv->sram)
+ return -EINVAL;
+
+ /* get number of channels */
+ priv->n_channels = dev_read_u32_default(dev, "dma-channels", 8);
+ if (priv->n_channels > DMA_CHAN_MAX)
+ 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;
+
+ ret = clk_enable(&clk);
+ if (ret < 0) {
+ pr_err("error enabling clock %d\n", i);
+ return ret;
+ }
+
+ ret = clk_free(&clk);
+ if (ret < 0) {
+ pr_err("error freeing clock %d\n", i);
+ return ret;
+ }
+ }
+
+ /* 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;
+
+ ret = reset_deassert(&reset);
+ if (ret < 0) {
+ pr_err("error deasserting reset %d\n", i);
+ return ret;
+ }
+
+ ret = reset_free(&reset);
+ if (ret < 0) {
+ pr_err("error freeing reset %d\n", i);
+ return ret;
+ }
+ }
+
+ /* disable dma controller */
+ clrbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
+
+ /* alloc channel private data pointers */
+ priv->ch_priv = calloc(priv->n_channels,
+ sizeof(struct bcm6348_chan_priv*));
+ if (!priv->ch_priv)
+ return -ENOMEM;
+
+ /* stop dma channels */
+ for (ch = 0; ch < priv->n_channels; ch++)
+ bcm6348_iudma_chan_stop(priv, ch);
+
+ /* enable dma controller */
+ setbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(bcm6348_iudma) = {
+ .name = "bcm6348_iudma",
+ .id = UCLASS_DMA,
+ .of_match = bcm6348_iudma_ids,
+ .ops = &bcm6348_iudma_ops,
+ .priv_auto_alloc_size = sizeof(struct bcm6348_iudma_priv),
+ .probe = bcm6348_iudma_probe,
+};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 01/28] dma: add bcm6348-iudma support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 01/28] dma: add bcm6348-iudma support Álvaro Fernández Rojas
@ 2018-11-30 13:46 ` Daniel Schwierzeck
2018-11-30 17:13 ` Álvaro Fernández Rojas
0 siblings, 1 reply; 145+ messages in thread
From: Daniel Schwierzeck @ 2018-11-30 13:46 UTC (permalink / raw)
To: u-boot
Am 29.11.18 um 23:25 schrieb Álvaro Fernández Rojas:
> BCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
>
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
> v10: Introduce changes suggested by Daniel Schwierzeck:
> - Fix license identifiers.
> - Move DMAD_ST defines out of dma desc struct definition.
> - Remove unneded aigned attribute from dma desc struct definition.
> - Fill dma ring from consumer driver instead of allocating a new buffer.
> - Correctly check clock/reset errors while probing.
> - Switch to live DM live tree.
> v9: introduce dma_prepare_rcv_buf dma op:
> - bcm6348_iudma_chan_stop: switch to mdelay when resetting channel.
> - bcm6348_iudma_receive: track dirty dma descriptors and no longer trigger
> dma rx channel.
> - bcm6348_iudma_send: reorder to properly flush cache and set dma descriptor
> config.
> - bcm6348_iudma_prepare_rcv_buf: implemented to clear dirty dma descriptors.
> v8: Introduce changes from Grygorii Strashko
> 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 | 642 ++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 652 insertions(+)
> create mode 100644 drivers/dma/bcm6348-iudma.c
Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
only one nit left
>
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 8a4162eccd..1820676d7a 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -26,6 +26,15 @@ config SANDBOX_DMA
> Enable support for a test DMA uclass implementation. It stimulates
> DMA transfer by simple copying data between channels.
>
> +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
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index aff31f986a..b5f9147e0a 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -7,6 +7,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_SANDBOX_DMA) += sandbox-dma-test.o
> obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o
> diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c
> new file mode 100644
> index 0000000000..699f1a6754
> --- /dev/null
> +++ b/drivers/dma/bcm6348-iudma.c
> @@ -0,0 +1,642 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
> + *
> + * Derived from linux/drivers/dma/bcm63xx-iudma.c:
> + * Copyright (C) 2015 Simon Arlott <simon@fire.lp0.eu>
> + *
> + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
> + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
> + *
> + * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h:
> + * Copyright (C) 2000-2010 Broadcom Corporation
> + *
> + * Derived from bcm963xx_4.12L.06B_consumer/bcmdrivers/opensource/net/enet/impl4/bcmenet.c:
> + * Copyright (C) 2010 Broadcom Corporation
> + */
> +
> +#include <common.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <dma-uclass.h>
> +#include <memalign.h>
> +#include <reset.h>
> +#include <asm/io.h>
> +
> +#define DMA_RX_DESC 6
> +#define DMA_TX_DESC 1
> +
> +/* DMA Channels */
> +#define DMA_CHAN_FLOWC(x) ((x) >> 1)
> +#define DMA_CHAN_MAX 16
> +#define DMA_CHAN_SIZE 0x10
> +#define DMA_CHAN_TOUT 500
> +
> +/* DMA Global Configuration register */
> +#define DMA_CFG_REG 0x00
> +#define DMA_CFG_ENABLE_SHIFT 0
> +#define DMA_CFG_ENABLE_MASK (1 << DMA_CFG_ENABLE_SHIFT)
> +#define DMA_CFG_FLOWC_ENABLE(x) BIT(DMA_CHAN_FLOWC(x) + 1)
> +#define DMA_CFG_NCHANS_SHIFT 24
> +#define DMA_CFG_NCHANS_MASK (0xf << DMA_CFG_NCHANS_SHIFT)
> +
> +/* DMA Global Flow Control registers */
> +#define DMA_FLOWC_THR_LO_REG(x) (0x04 + DMA_CHAN_FLOWC(x) * 0x0c)
> +#define DMA_FLOWC_THR_HI_REG(x) (0x08 + DMA_CHAN_FLOWC(x) * 0x0c)
> +#define DMA_FLOWC_ALLOC_REG(x) (0x0c + DMA_CHAN_FLOWC(x) * 0x0c)
> +#define DMA_FLOWC_ALLOC_FORCE_SHIFT 31
> +#define DMA_FLOWC_ALLOC_FORCE_MASK (1 << DMA_FLOWC_ALLOC_FORCE_SHIFT)
> +
> +/* DMA Global Reset register */
> +#define DMA_RST_REG 0x34
> +#define DMA_RST_CHAN_SHIFT 0
> +#define DMA_RST_CHAN_MASK(x) (1 << x)
> +
> +/* DMA Channel Configuration register */
> +#define DMAC_CFG_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
> +#define DMAC_CFG_ENABLE_SHIFT 0
> +#define DMAC_CFG_ENABLE_MASK (1 << DMAC_CFG_ENABLE_SHIFT)
> +#define DMAC_CFG_PKT_HALT_SHIFT 1
> +#define DMAC_CFG_PKT_HALT_MASK (1 << DMAC_CFG_PKT_HALT_SHIFT)
> +#define DMAC_CFG_BRST_HALT_SHIFT 2
> +#define DMAC_CFG_BRST_HALT_MASK (1 << DMAC_CFG_BRST_HALT_SHIFT)
> +
> +/* DMA Channel Max Burst Length register */
> +#define DMAC_BURST_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
> +
> +/* DMA SRAM Descriptor Ring Start register */
> +#define DMAS_RSTART_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
> +
> +/* DMA SRAM State/Bytes done/ring offset register */
> +#define DMAS_STATE_DATA_REG(x) (DMA_CHAN_SIZE * (x) + 0x04)
> +
> +/* DMA SRAM Buffer Descriptor status and length register */
> +#define DMAS_DESC_LEN_STATUS_REG(x) (DMA_CHAN_SIZE * (x) + 0x08)
> +
> +/* DMA SRAM Buffer Descriptor status and length register */
> +#define DMAS_DESC_BASE_BUFPTR_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
> +
> +/* DMA Descriptor Status */
> +#define DMAD_ST_CRC_SHIFT 8
> +#define DMAD_ST_CRC_MASK (1 << DMAD_ST_CRC_SHIFT)
> +#define DMAD_ST_WRAP_SHIFT 12
> +#define DMAD_ST_WRAP_MASK (1 << DMAD_ST_WRAP_SHIFT)
> +#define DMAD_ST_SOP_SHIFT 13
> +#define DMAD_ST_SOP_MASK (1 << DMAD_ST_SOP_SHIFT)
> +#define DMAD_ST_EOP_SHIFT 14
> +#define DMAD_ST_EOP_MASK (1 << DMAD_ST_EOP_SHIFT)
> +#define DMAD_ST_OWN_SHIFT 15
> +#define DMAD_ST_OWN_MASK (1 << DMAD_ST_OWN_SHIFT)
> +
> +#define DMAD6348_ST_OV_ERR_SHIFT 0
> +#define DMAD6348_ST_OV_ERR_MASK (1 << DMAD6348_ST_OV_ERR_SHIFT)
> +#define DMAD6348_ST_CRC_ERR_SHIFT 1
> +#define DMAD6348_ST_CRC_ERR_MASK (1 << DMAD6348_ST_CRC_ERR_SHIFT)
> +#define DMAD6348_ST_RX_ERR_SHIFT 2
> +#define DMAD6348_ST_RX_ERR_MASK (1 << DMAD6348_ST_RX_ERR_SHIFT)
> +#define DMAD6348_ST_OS_ERR_SHIFT 4
> +#define DMAD6348_ST_OS_ERR_MASK (1 << DMAD6348_ST_OS_ERR_SHIFT)
> +#define DMAD6348_ST_UN_ERR_SHIFT 9
> +#define DMAD6348_ST_UN_ERR_MASK (1 << DMAD6348_ST_UN_ERR_SHIFT)
> +
> +struct bcm6348_dma_desc {
> + uint16_t length;
> + uint16_t status;
> + uint32_t address;
> +};
> +
> +struct bcm6348_chan_priv {
> + void __iomem *dma_ring;
> + uint8_t dma_ring_size;
> + uint8_t desc_id;
> + uint8_t desc_cnt;
> + bool *busy_desc;
> + bool running;
> +};
> +
> +struct bcm6348_iudma_hw {
> + uint16_t err_mask;
> +};
> +
> +struct bcm6348_iudma_priv {
> + const struct bcm6348_iudma_hw *hw;
> + void __iomem *base;
> + void __iomem *chan;
> + void __iomem *sram;
> + struct bcm6348_chan_priv **ch_priv;
> + uint8_t n_channels;
> +};
> +
> +static inline bool bcm6348_iudma_chan_is_rx(uint8_t ch)
> +{
> + return !(ch & 1);
> +}
> +
> +static inline void bcm6348_iudma_fdc(void *ptr, ulong size)
> +{
> + ulong start = (ulong) ptr;
> +
> + flush_dcache_range(start, start + size);
> +}
> +
> +static inline void bcm6348_iudma_idc(void *ptr, ulong size)
> +{
> + ulong start = (ulong) ptr;
> +
> + invalidate_dcache_range(start, start + size);
> +}
> +
> +static void bcm6348_iudma_chan_stop(struct bcm6348_iudma_priv *priv,
> + uint8_t ch)
> +{
> + unsigned int timeout = DMA_CHAN_TOUT;
> +
> + do {
> + uint32_t cfg, halt;
> +
> + if (timeout > DMA_CHAN_TOUT / 2)
> + halt = DMAC_CFG_PKT_HALT_MASK;
> + else
> + halt = DMAC_CFG_BRST_HALT_MASK;
> +
> + /* try to stop dma channel */
> + writel_be(halt, priv->chan + DMAC_CFG_REG(ch));
> + mb();
> +
> + /* check if channel was stopped */
> + cfg = readl_be(priv->chan + DMAC_CFG_REG(ch));
> + if (!(cfg & DMAC_CFG_ENABLE_MASK))
> + break;
> +
> + udelay(1);
> + } while (--timeout);
> +
> + if (!timeout)
> + pr_err("unable to stop channel %u\n", ch);
> +
> + /* reset dma channel */
> + setbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
> + mb();
> + clrbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
> +}
> +
> +static int bcm6348_iudma_disable(struct dma *dma)
> +{
> + struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
> + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
> +
> + /* stop dma channel */
> + bcm6348_iudma_chan_stop(priv, dma->id);
> +
> + /* dma flow control */
> + if (bcm6348_iudma_chan_is_rx(dma->id))
> + writel_be(DMA_FLOWC_ALLOC_FORCE_MASK,
> + DMA_FLOWC_ALLOC_REG(dma->id));
> +
> + /* init channel config */
> + ch_priv->running = false;
> + ch_priv->desc_id = 0;
> + if (bcm6348_iudma_chan_is_rx(dma->id))
> + ch_priv->desc_cnt = 0;
> + else
> + ch_priv->desc_cnt = ch_priv->dma_ring_size;
> +
> + return 0;
> +}
> +
> +static int bcm6348_iudma_enable(struct dma *dma)
> +{
> + const 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 = ch_priv->dma_ring;
> + uint8_t i;
> +
> + /* dma ring init */
> + for (i = 0; i < ch_priv->desc_cnt; i++) {
> + if (bcm6348_iudma_chan_is_rx(dma->id)) {
> + ch_priv->busy_desc[i] = false;
> + dma_desc->status |= DMAD_ST_OWN_MASK;
> + } else {
> + dma_desc->status = 0;
> + dma_desc->length = 0;
> + dma_desc->address = 0;
> + }
> +
> + if (i == ch_priv->desc_cnt - 1)
> + dma_desc->status |= DMAD_ST_WRAP_MASK;
> +
> + dma_desc++;
> + }
> +
> + /* init to first descriptor */
> + ch_priv->desc_id = 0;
> +
> + /* force cache writeback */
> + bcm6348_iudma_fdc(ch_priv->dma_ring,
> + sizeof(*dma_desc) * ch_priv->desc_cnt);
> +
> + /* 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->desc_cnt / 3;
> + writel_be(val, priv->base + DMA_FLOWC_THR_LO_REG(dma->id));
> +
> + val = (ch_priv->desc_cnt * 2) / 3;
> + writel_be(val, priv->base + DMA_FLOWC_THR_HI_REG(dma->id));
> +
> + writel_be(0, priv->base + DMA_FLOWC_ALLOC_REG(dma->id));
> + }
> +
> + /* set dma max burst */
> + writel_be(ch_priv->desc_cnt,
> + priv->chan + DMAC_BURST_REG(dma->id));
> +
> + /* kick rx dma channel */
> + if (bcm6348_iudma_chan_is_rx(dma->id))
> + setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
> + DMAC_CFG_ENABLE_MASK);
> +
> + /* channel is now enabled */
> + ch_priv->running = true;
> +
> + return 0;
> +}
> +
> +static int bcm6348_iudma_request(struct dma *dma)
> +{
> + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
> + struct bcm6348_chan_priv *ch_priv;
> +
> + /* check if channel is valid */
> + if (dma->id >= priv->n_channels)
> + return -ENODEV;
> +
> + /* alloc channel private data */
> + priv->ch_priv[dma->id] = calloc(1, sizeof(struct bcm6348_chan_priv));
> + if (!priv->ch_priv[dma->id])
> + return -ENOMEM;
> + ch_priv = priv->ch_priv[dma->id];
> +
> + /* alloc dma ring */
> + if (bcm6348_iudma_chan_is_rx(dma->id))
> + ch_priv->dma_ring_size = DMA_RX_DESC;
> + else
> + ch_priv->dma_ring_size = DMA_TX_DESC;
> +
> + ch_priv->dma_ring =
> + malloc_cache_aligned(sizeof(struct bcm6348_dma_desc) *
> + ch_priv->dma_ring_size);
> + if (!ch_priv->dma_ring)
> + return -ENOMEM;
> +
> + /* init channel config */
> + ch_priv->running = false;
> + ch_priv->desc_id = 0;
> + if (bcm6348_iudma_chan_is_rx(dma->id)) {
> + ch_priv->desc_cnt = 0;
> + ch_priv->busy_desc = calloc(ch_priv->desc_cnt, sizeof(bool));
> + } else {
> + ch_priv->desc_cnt = ch_priv->dma_ring_size;
> + ch_priv->busy_desc = NULL;
> + }
> +
> + return 0;
> +}
> +
> +static int bcm6348_iudma_receive(struct dma *dma, void **dst, void *metadata)
> +{
> + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
> + const struct bcm6348_iudma_hw *hw = priv->hw;
> + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
> + struct bcm6348_dma_desc *dma_desc = dma_desc = ch_priv->dma_ring;
> + int ret;
> +
> + /* get dma ring descriptor address */
> + dma_desc += ch_priv->desc_id;
> +
> + /* invalidate cache data */
> + bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc));
> +
> + /* check dma own */
> + if (dma_desc->status & DMAD_ST_OWN_MASK)
> + return -EAGAIN;
> +
> + /* check pkt */
> + if (!(dma_desc->status & DMAD_ST_EOP_MASK) ||
> + !(dma_desc->status & DMAD_ST_SOP_MASK) ||
> + (dma_desc->status & hw->err_mask)) {
> + pr_err("invalid pkt received (ch=%ld desc=%u) (st=%04x)\n",
> + dma->id, ch_priv->desc_id, dma_desc->status);
> + ret = -EAGAIN;
> + } else {
> + /* set dma buffer address */
> + *dst = phys_to_virt(dma_desc->address);
> +
> + /* invalidate cache data */
> + bcm6348_iudma_idc(*dst, dma_desc->length);
> +
> + /* remove crc */
> + ret = dma_desc->length - 4;
is CRC a feature of the DMA engine or does this belong to the ethernet
driver?
> + }
> +
> + /* busy dma descriptor */
> + ch_priv->busy_desc[ch_priv->desc_id] = true;
> +
> + /* increment dma descriptor */
> + ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt;
> +
> + return ret;
> +}
> +
> +static int bcm6348_iudma_send(struct dma *dma, void *src, size_t len,
> + void *metadata)
> +{
> + const 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;
> + uint16_t status;
> +
> + /* flush cache */
> + bcm6348_iudma_fdc(src, len);
> +
> + /* get dma ring descriptor address */
> + dma_desc = ch_priv->dma_ring;
> + dma_desc += ch_priv->desc_id;
> +
> + /* config dma descriptor */
> + status = (DMAD_ST_OWN_MASK |
> + DMAD_ST_EOP_MASK |
> + DMAD_ST_CRC_MASK |
> + DMAD_ST_SOP_MASK);
> + if (ch_priv->desc_id == ch_priv->desc_cnt - 1)
> + status |= DMAD_ST_WRAP_MASK;
> +
> + /* set dma descriptor */
> + dma_desc->address = virt_to_phys(src);
> + dma_desc->length = len;
> + dma_desc->status = status;
> +
> + /* flush cache */
> + bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc));
> +
> + /* kick tx dma channel */
> + setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK);
> +
> + /* poll dma status */
> + do {
> + /* invalidate cache */
> + bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc));
> +
> + if (!(dma_desc->status & DMAD_ST_OWN_MASK))
> + break;
> + } while(1);
> +
> + /* increment dma descriptor */
> + ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt;
> +
> + return 0;
> +}
> +
> +static int bcm6348_iudma_free_rcv_buf(struct dma *dma, void *dst, size_t size)
> +{
> + const 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 = ch_priv->dma_ring;
> + uint16_t status;
> + uint8_t i;
> + u32 cfg;
> +
> + /* get dirty dma descriptor */
> + for (i = 0; i < ch_priv->desc_cnt; i++) {
> + if (phys_to_virt(dma_desc->address) == dst)
> + break;
> +
> + dma_desc++;
> + }
> +
> + /* dma descriptor not found */
> + if (i == ch_priv->desc_cnt) {
> + pr_err("dirty dma descriptor not found\n");
> + return -ENOENT;
> + }
> +
> + /* invalidate cache */
> + bcm6348_iudma_idc(ch_priv->dma_ring,
> + sizeof(*dma_desc) * ch_priv->desc_cnt);
> +
> + /* free dma descriptor */
> + ch_priv->busy_desc[i] = false;
> +
> + status = DMAD_ST_OWN_MASK;
> + if (i == ch_priv->desc_cnt - 1)
> + status |= DMAD_ST_WRAP_MASK;
> +
> + dma_desc->status |= status;
> + dma_desc->length = PKTSIZE_ALIGN;
> +
> + /* tell dma we allocated one buffer */
> + writel_be(1, DMA_FLOWC_ALLOC_REG(dma->id));
> +
> + /* flush cache */
> + bcm6348_iudma_fdc(ch_priv->dma_ring,
> + sizeof(*dma_desc) * ch_priv->desc_cnt);
> +
> + /* kick rx dma channel if disabled */
> + cfg = readl_be(priv->chan + DMAC_CFG_REG(dma->id));
> + if (!(cfg & DMAC_CFG_ENABLE_MASK))
> + setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
> + DMAC_CFG_ENABLE_MASK);
> +
> + return 0;
> +}
> +
> +static int bcm6348_iudma_add_rcv_buf(struct dma *dma, void *dst, size_t size)
> +{
> + const 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 = ch_priv->dma_ring;
> +
> + /* no more dma descriptors available */
> + if (ch_priv->desc_cnt == ch_priv->dma_ring_size) {
> + pr_err("max number of buffers reached\n");
> + return -EINVAL;
> + }
> +
> + /* get next dma descriptor */
> + dma_desc += ch_priv->desc_cnt;
> +
> + /* init dma descriptor */
> + dma_desc->address = virt_to_phys(dst);
> + dma_desc->length = size;
> + dma_desc->status = 0;
> +
> + /* flush cache */
> + bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc));
> +
> + /* increment dma descriptors */
> + ch_priv->desc_cnt++;
> +
> + return 0;
> +}
> +
> +static int bcm6348_iudma_prepare_rcv_buf(struct dma *dma, void *dst,
> + size_t size)
> +{
> + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
> + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
> +
> + /* only add new rx buffers if channel isn't running */
> + if (ch_priv->running)
> + return bcm6348_iudma_free_rcv_buf(dma, dst, size);
> + else
> + return bcm6348_iudma_add_rcv_buf(dma, dst, size);
> +}
> +
> +static const struct dma_ops bcm6348_iudma_ops = {
> + .disable = bcm6348_iudma_disable,
> + .enable = bcm6348_iudma_enable,
> + .prepare_rcv_buf = bcm6348_iudma_prepare_rcv_buf,
> + .request = bcm6348_iudma_request,
> + .receive = bcm6348_iudma_receive,
> + .send = bcm6348_iudma_send,
> +};
> +
> +static const struct bcm6348_iudma_hw bcm6348_hw = {
> + .err_mask = (DMAD6348_ST_OV_ERR_MASK |
> + DMAD6348_ST_CRC_ERR_MASK |
> + DMAD6348_ST_RX_ERR_MASK |
> + DMAD6348_ST_OS_ERR_MASK |
> + DMAD6348_ST_UN_ERR_MASK),
> +};
> +
> +static const struct bcm6348_iudma_hw bcm6368_hw = {
> + .err_mask = 0,
> +};
> +
> +static const struct udevice_id bcm6348_iudma_ids[] = {
> + {
> + .compatible = "brcm,bcm6348-iudma",
> + .data = (ulong)&bcm6348_hw,
> + }, {
> + .compatible = "brcm,bcm6368-iudma",
> + .data = (ulong)&bcm6368_hw,
> + }, { /* sentinel */ }
> +};
> +
> +static int bcm6348_iudma_probe(struct udevice *dev)
> +{
> + struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> + struct bcm6348_iudma_priv *priv = dev_get_priv(dev);
> + const struct bcm6348_iudma_hw *hw =
> + (const struct bcm6348_iudma_hw *)dev_get_driver_data(dev);
> + uint8_t ch;
> + int i;
> +
> + uc_priv->supported = (DMA_SUPPORTS_DEV_TO_MEM |
> + DMA_SUPPORTS_MEM_TO_DEV);
> + priv->hw = hw;
> +
> + /* dma global base address */
> + priv->base = dev_remap_addr_name(dev, "dma");
> + if (!priv->base)
> + return -EINVAL;
> +
> + /* dma channels base address */
> + priv->chan = dev_remap_addr_name(dev, "dma-channels");
> + if (!priv->chan)
> + return -EINVAL;
> +
> + /* dma sram base address */
> + priv->sram = dev_remap_addr_name(dev, "dma-sram");
> + if (!priv->sram)
> + return -EINVAL;
> +
> + /* get number of channels */
> + priv->n_channels = dev_read_u32_default(dev, "dma-channels", 8);
> + if (priv->n_channels > DMA_CHAN_MAX)
> + 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;
> +
> + ret = clk_enable(&clk);
> + if (ret < 0) {
> + pr_err("error enabling clock %d\n", i);
> + return ret;
> + }
> +
> + ret = clk_free(&clk);
> + if (ret < 0) {
> + pr_err("error freeing clock %d\n", i);
> + return ret;
> + }
> + }
> +
> + /* 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;
> +
> + ret = reset_deassert(&reset);
> + if (ret < 0) {
> + pr_err("error deasserting reset %d\n", i);
> + return ret;
> + }
> +
> + ret = reset_free(&reset);
> + if (ret < 0) {
> + pr_err("error freeing reset %d\n", i);
> + return ret;
> + }
> + }
> +
> + /* disable dma controller */
> + clrbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
> +
> + /* alloc channel private data pointers */
> + priv->ch_priv = calloc(priv->n_channels,
> + sizeof(struct bcm6348_chan_priv*));
> + if (!priv->ch_priv)
> + return -ENOMEM;
> +
> + /* stop dma channels */
> + for (ch = 0; ch < priv->n_channels; ch++)
> + bcm6348_iudma_chan_stop(priv, ch);
> +
> + /* enable dma controller */
> + setbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
> +
> + return 0;
> +}
> +
> +U_BOOT_DRIVER(bcm6348_iudma) = {
> + .name = "bcm6348_iudma",
> + .id = UCLASS_DMA,
> + .of_match = bcm6348_iudma_ids,
> + .ops = &bcm6348_iudma_ops,
> + .priv_auto_alloc_size = sizeof(struct bcm6348_iudma_priv),
> + .probe = bcm6348_iudma_probe,
> +};
>
--
- Daniel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181130/584703df/attachment.sig>
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 01/28] dma: add bcm6348-iudma support
2018-11-30 13:46 ` Daniel Schwierzeck
@ 2018-11-30 17:13 ` Álvaro Fernández Rojas
0 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-30 17:13 UTC (permalink / raw)
To: u-boot
Hi Daniel,
El 30/11/2018 a las 14:46, Daniel Schwierzeck escribió:
>
> Am 29.11.18 um 23:25 schrieb Álvaro Fernández Rojas:
>> BCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
>>
>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
>> ---
>> v10: Introduce changes suggested by Daniel Schwierzeck:
>> - Fix license identifiers.
>> - Move DMAD_ST defines out of dma desc struct definition.
>> - Remove unneded aigned attribute from dma desc struct definition.
>> - Fill dma ring from consumer driver instead of allocating a new buffer.
>> - Correctly check clock/reset errors while probing.
>> - Switch to live DM live tree.
>> v9: introduce dma_prepare_rcv_buf dma op:
>> - bcm6348_iudma_chan_stop: switch to mdelay when resetting channel.
>> - bcm6348_iudma_receive: track dirty dma descriptors and no longer trigger
>> dma rx channel.
>> - bcm6348_iudma_send: reorder to properly flush cache and set dma descriptor
>> config.
>> - bcm6348_iudma_prepare_rcv_buf: implemented to clear dirty dma descriptors.
>> v8: Introduce changes from Grygorii Strashko
>> 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 | 642 ++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 652 insertions(+)
>> create mode 100644 drivers/dma/bcm6348-iudma.c
> Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
>
> only one nit left
>
>> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
>> index 8a4162eccd..1820676d7a 100644
>> --- a/drivers/dma/Kconfig
>> +++ b/drivers/dma/Kconfig
>> @@ -26,6 +26,15 @@ config SANDBOX_DMA
>> Enable support for a test DMA uclass implementation. It stimulates
>> DMA transfer by simple copying data between channels.
>>
>> +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
>> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
>> index aff31f986a..b5f9147e0a 100644
>> --- a/drivers/dma/Makefile
>> +++ b/drivers/dma/Makefile
>> @@ -7,6 +7,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_SANDBOX_DMA) += sandbox-dma-test.o
>> obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o
>> diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c
>> new file mode 100644
>> index 0000000000..699f1a6754
>> --- /dev/null
>> +++ b/drivers/dma/bcm6348-iudma.c
>> @@ -0,0 +1,642 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
>> + *
>> + * Derived from linux/drivers/dma/bcm63xx-iudma.c:
>> + * Copyright (C) 2015 Simon Arlott <simon@fire.lp0.eu>
>> + *
>> + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
>> + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
>> + *
>> + * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h:
>> + * Copyright (C) 2000-2010 Broadcom Corporation
>> + *
>> + * Derived from bcm963xx_4.12L.06B_consumer/bcmdrivers/opensource/net/enet/impl4/bcmenet.c:
>> + * Copyright (C) 2010 Broadcom Corporation
>> + */
>> +
>> +#include <common.h>
>> +#include <clk.h>
>> +#include <dm.h>
>> +#include <dma-uclass.h>
>> +#include <memalign.h>
>> +#include <reset.h>
>> +#include <asm/io.h>
>> +
>> +#define DMA_RX_DESC 6
>> +#define DMA_TX_DESC 1
>> +
>> +/* DMA Channels */
>> +#define DMA_CHAN_FLOWC(x) ((x) >> 1)
>> +#define DMA_CHAN_MAX 16
>> +#define DMA_CHAN_SIZE 0x10
>> +#define DMA_CHAN_TOUT 500
>> +
>> +/* DMA Global Configuration register */
>> +#define DMA_CFG_REG 0x00
>> +#define DMA_CFG_ENABLE_SHIFT 0
>> +#define DMA_CFG_ENABLE_MASK (1 << DMA_CFG_ENABLE_SHIFT)
>> +#define DMA_CFG_FLOWC_ENABLE(x) BIT(DMA_CHAN_FLOWC(x) + 1)
>> +#define DMA_CFG_NCHANS_SHIFT 24
>> +#define DMA_CFG_NCHANS_MASK (0xf << DMA_CFG_NCHANS_SHIFT)
>> +
>> +/* DMA Global Flow Control registers */
>> +#define DMA_FLOWC_THR_LO_REG(x) (0x04 + DMA_CHAN_FLOWC(x) * 0x0c)
>> +#define DMA_FLOWC_THR_HI_REG(x) (0x08 + DMA_CHAN_FLOWC(x) * 0x0c)
>> +#define DMA_FLOWC_ALLOC_REG(x) (0x0c + DMA_CHAN_FLOWC(x) * 0x0c)
>> +#define DMA_FLOWC_ALLOC_FORCE_SHIFT 31
>> +#define DMA_FLOWC_ALLOC_FORCE_MASK (1 << DMA_FLOWC_ALLOC_FORCE_SHIFT)
>> +
>> +/* DMA Global Reset register */
>> +#define DMA_RST_REG 0x34
>> +#define DMA_RST_CHAN_SHIFT 0
>> +#define DMA_RST_CHAN_MASK(x) (1 << x)
>> +
>> +/* DMA Channel Configuration register */
>> +#define DMAC_CFG_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
>> +#define DMAC_CFG_ENABLE_SHIFT 0
>> +#define DMAC_CFG_ENABLE_MASK (1 << DMAC_CFG_ENABLE_SHIFT)
>> +#define DMAC_CFG_PKT_HALT_SHIFT 1
>> +#define DMAC_CFG_PKT_HALT_MASK (1 << DMAC_CFG_PKT_HALT_SHIFT)
>> +#define DMAC_CFG_BRST_HALT_SHIFT 2
>> +#define DMAC_CFG_BRST_HALT_MASK (1 << DMAC_CFG_BRST_HALT_SHIFT)
>> +
>> +/* DMA Channel Max Burst Length register */
>> +#define DMAC_BURST_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
>> +
>> +/* DMA SRAM Descriptor Ring Start register */
>> +#define DMAS_RSTART_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
>> +
>> +/* DMA SRAM State/Bytes done/ring offset register */
>> +#define DMAS_STATE_DATA_REG(x) (DMA_CHAN_SIZE * (x) + 0x04)
>> +
>> +/* DMA SRAM Buffer Descriptor status and length register */
>> +#define DMAS_DESC_LEN_STATUS_REG(x) (DMA_CHAN_SIZE * (x) + 0x08)
>> +
>> +/* DMA SRAM Buffer Descriptor status and length register */
>> +#define DMAS_DESC_BASE_BUFPTR_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
>> +
>> +/* DMA Descriptor Status */
>> +#define DMAD_ST_CRC_SHIFT 8
>> +#define DMAD_ST_CRC_MASK (1 << DMAD_ST_CRC_SHIFT)
>> +#define DMAD_ST_WRAP_SHIFT 12
>> +#define DMAD_ST_WRAP_MASK (1 << DMAD_ST_WRAP_SHIFT)
>> +#define DMAD_ST_SOP_SHIFT 13
>> +#define DMAD_ST_SOP_MASK (1 << DMAD_ST_SOP_SHIFT)
>> +#define DMAD_ST_EOP_SHIFT 14
>> +#define DMAD_ST_EOP_MASK (1 << DMAD_ST_EOP_SHIFT)
>> +#define DMAD_ST_OWN_SHIFT 15
>> +#define DMAD_ST_OWN_MASK (1 << DMAD_ST_OWN_SHIFT)
>> +
>> +#define DMAD6348_ST_OV_ERR_SHIFT 0
>> +#define DMAD6348_ST_OV_ERR_MASK (1 << DMAD6348_ST_OV_ERR_SHIFT)
>> +#define DMAD6348_ST_CRC_ERR_SHIFT 1
>> +#define DMAD6348_ST_CRC_ERR_MASK (1 << DMAD6348_ST_CRC_ERR_SHIFT)
>> +#define DMAD6348_ST_RX_ERR_SHIFT 2
>> +#define DMAD6348_ST_RX_ERR_MASK (1 << DMAD6348_ST_RX_ERR_SHIFT)
>> +#define DMAD6348_ST_OS_ERR_SHIFT 4
>> +#define DMAD6348_ST_OS_ERR_MASK (1 << DMAD6348_ST_OS_ERR_SHIFT)
>> +#define DMAD6348_ST_UN_ERR_SHIFT 9
>> +#define DMAD6348_ST_UN_ERR_MASK (1 << DMAD6348_ST_UN_ERR_SHIFT)
>> +
>> +struct bcm6348_dma_desc {
>> + uint16_t length;
>> + uint16_t status;
>> + uint32_t address;
>> +};
>> +
>> +struct bcm6348_chan_priv {
>> + void __iomem *dma_ring;
>> + uint8_t dma_ring_size;
>> + uint8_t desc_id;
>> + uint8_t desc_cnt;
>> + bool *busy_desc;
>> + bool running;
>> +};
>> +
>> +struct bcm6348_iudma_hw {
>> + uint16_t err_mask;
>> +};
>> +
>> +struct bcm6348_iudma_priv {
>> + const struct bcm6348_iudma_hw *hw;
>> + void __iomem *base;
>> + void __iomem *chan;
>> + void __iomem *sram;
>> + struct bcm6348_chan_priv **ch_priv;
>> + uint8_t n_channels;
>> +};
>> +
>> +static inline bool bcm6348_iudma_chan_is_rx(uint8_t ch)
>> +{
>> + return !(ch & 1);
>> +}
>> +
>> +static inline void bcm6348_iudma_fdc(void *ptr, ulong size)
>> +{
>> + ulong start = (ulong) ptr;
>> +
>> + flush_dcache_range(start, start + size);
>> +}
>> +
>> +static inline void bcm6348_iudma_idc(void *ptr, ulong size)
>> +{
>> + ulong start = (ulong) ptr;
>> +
>> + invalidate_dcache_range(start, start + size);
>> +}
>> +
>> +static void bcm6348_iudma_chan_stop(struct bcm6348_iudma_priv *priv,
>> + uint8_t ch)
>> +{
>> + unsigned int timeout = DMA_CHAN_TOUT;
>> +
>> + do {
>> + uint32_t cfg, halt;
>> +
>> + if (timeout > DMA_CHAN_TOUT / 2)
>> + halt = DMAC_CFG_PKT_HALT_MASK;
>> + else
>> + halt = DMAC_CFG_BRST_HALT_MASK;
>> +
>> + /* try to stop dma channel */
>> + writel_be(halt, priv->chan + DMAC_CFG_REG(ch));
>> + mb();
>> +
>> + /* check if channel was stopped */
>> + cfg = readl_be(priv->chan + DMAC_CFG_REG(ch));
>> + if (!(cfg & DMAC_CFG_ENABLE_MASK))
>> + break;
>> +
>> + udelay(1);
>> + } while (--timeout);
>> +
>> + if (!timeout)
>> + pr_err("unable to stop channel %u\n", ch);
>> +
>> + /* reset dma channel */
>> + setbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
>> + mb();
>> + clrbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
>> +}
>> +
>> +static int bcm6348_iudma_disable(struct dma *dma)
>> +{
>> + struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
>> + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
>> +
>> + /* stop dma channel */
>> + bcm6348_iudma_chan_stop(priv, dma->id);
>> +
>> + /* dma flow control */
>> + if (bcm6348_iudma_chan_is_rx(dma->id))
>> + writel_be(DMA_FLOWC_ALLOC_FORCE_MASK,
>> + DMA_FLOWC_ALLOC_REG(dma->id));
>> +
>> + /* init channel config */
>> + ch_priv->running = false;
>> + ch_priv->desc_id = 0;
>> + if (bcm6348_iudma_chan_is_rx(dma->id))
>> + ch_priv->desc_cnt = 0;
>> + else
>> + ch_priv->desc_cnt = ch_priv->dma_ring_size;
>> +
>> + return 0;
>> +}
>> +
>> +static int bcm6348_iudma_enable(struct dma *dma)
>> +{
>> + const 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 = ch_priv->dma_ring;
>> + uint8_t i;
>> +
>> + /* dma ring init */
>> + for (i = 0; i < ch_priv->desc_cnt; i++) {
>> + if (bcm6348_iudma_chan_is_rx(dma->id)) {
>> + ch_priv->busy_desc[i] = false;
>> + dma_desc->status |= DMAD_ST_OWN_MASK;
>> + } else {
>> + dma_desc->status = 0;
>> + dma_desc->length = 0;
>> + dma_desc->address = 0;
>> + }
>> +
>> + if (i == ch_priv->desc_cnt - 1)
>> + dma_desc->status |= DMAD_ST_WRAP_MASK;
>> +
>> + dma_desc++;
>> + }
>> +
>> + /* init to first descriptor */
>> + ch_priv->desc_id = 0;
>> +
>> + /* force cache writeback */
>> + bcm6348_iudma_fdc(ch_priv->dma_ring,
>> + sizeof(*dma_desc) * ch_priv->desc_cnt);
>> +
>> + /* 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->desc_cnt / 3;
>> + writel_be(val, priv->base + DMA_FLOWC_THR_LO_REG(dma->id));
>> +
>> + val = (ch_priv->desc_cnt * 2) / 3;
>> + writel_be(val, priv->base + DMA_FLOWC_THR_HI_REG(dma->id));
>> +
>> + writel_be(0, priv->base + DMA_FLOWC_ALLOC_REG(dma->id));
>> + }
>> +
>> + /* set dma max burst */
>> + writel_be(ch_priv->desc_cnt,
>> + priv->chan + DMAC_BURST_REG(dma->id));
>> +
>> + /* kick rx dma channel */
>> + if (bcm6348_iudma_chan_is_rx(dma->id))
>> + setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
>> + DMAC_CFG_ENABLE_MASK);
>> +
>> + /* channel is now enabled */
>> + ch_priv->running = true;
>> +
>> + return 0;
>> +}
>> +
>> +static int bcm6348_iudma_request(struct dma *dma)
>> +{
>> + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
>> + struct bcm6348_chan_priv *ch_priv;
>> +
>> + /* check if channel is valid */
>> + if (dma->id >= priv->n_channels)
>> + return -ENODEV;
>> +
>> + /* alloc channel private data */
>> + priv->ch_priv[dma->id] = calloc(1, sizeof(struct bcm6348_chan_priv));
>> + if (!priv->ch_priv[dma->id])
>> + return -ENOMEM;
>> + ch_priv = priv->ch_priv[dma->id];
>> +
>> + /* alloc dma ring */
>> + if (bcm6348_iudma_chan_is_rx(dma->id))
>> + ch_priv->dma_ring_size = DMA_RX_DESC;
>> + else
>> + ch_priv->dma_ring_size = DMA_TX_DESC;
>> +
>> + ch_priv->dma_ring =
>> + malloc_cache_aligned(sizeof(struct bcm6348_dma_desc) *
>> + ch_priv->dma_ring_size);
>> + if (!ch_priv->dma_ring)
>> + return -ENOMEM;
>> +
>> + /* init channel config */
>> + ch_priv->running = false;
>> + ch_priv->desc_id = 0;
>> + if (bcm6348_iudma_chan_is_rx(dma->id)) {
>> + ch_priv->desc_cnt = 0;
>> + ch_priv->busy_desc = calloc(ch_priv->desc_cnt, sizeof(bool));
>> + } else {
>> + ch_priv->desc_cnt = ch_priv->dma_ring_size;
>> + ch_priv->busy_desc = NULL;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int bcm6348_iudma_receive(struct dma *dma, void **dst, void *metadata)
>> +{
>> + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
>> + const struct bcm6348_iudma_hw *hw = priv->hw;
>> + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
>> + struct bcm6348_dma_desc *dma_desc = dma_desc = ch_priv->dma_ring;
>> + int ret;
>> +
>> + /* get dma ring descriptor address */
>> + dma_desc += ch_priv->desc_id;
>> +
>> + /* invalidate cache data */
>> + bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc));
>> +
>> + /* check dma own */
>> + if (dma_desc->status & DMAD_ST_OWN_MASK)
>> + return -EAGAIN;
>> +
>> + /* check pkt */
>> + if (!(dma_desc->status & DMAD_ST_EOP_MASK) ||
>> + !(dma_desc->status & DMAD_ST_SOP_MASK) ||
>> + (dma_desc->status & hw->err_mask)) {
>> + pr_err("invalid pkt received (ch=%ld desc=%u) (st=%04x)\n",
>> + dma->id, ch_priv->desc_id, dma_desc->status);
>> + ret = -EAGAIN;
>> + } else {
>> + /* set dma buffer address */
>> + *dst = phys_to_virt(dma_desc->address);
>> +
>> + /* invalidate cache data */
>> + bcm6348_iudma_idc(*dst, dma_desc->length);
>> +
>> + /* remove crc */
>> + ret = dma_desc->length - 4;
> is CRC a feature of the DMA engine or does this belong to the ethernet
> driver?
I would say it belongs to ethernet, since I copied that from linux:
https://github.com/Noltari/linux/blob/master/drivers/net/ethernet/broadcom/bcm63xx_enet.c#L379
However, I just did one version without removing FCS and it worked, so I
will remove it in the next version.
>
>> + }
>> +
>> + /* busy dma descriptor */
>> + ch_priv->busy_desc[ch_priv->desc_id] = true;
>> +
>> + /* increment dma descriptor */
>> + ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt;
>> +
>> + return ret;
>> +}
>> +
>> +static int bcm6348_iudma_send(struct dma *dma, void *src, size_t len,
>> + void *metadata)
>> +{
>> + const 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;
>> + uint16_t status;
>> +
>> + /* flush cache */
>> + bcm6348_iudma_fdc(src, len);
>> +
>> + /* get dma ring descriptor address */
>> + dma_desc = ch_priv->dma_ring;
>> + dma_desc += ch_priv->desc_id;
>> +
>> + /* config dma descriptor */
>> + status = (DMAD_ST_OWN_MASK |
>> + DMAD_ST_EOP_MASK |
>> + DMAD_ST_CRC_MASK |
>> + DMAD_ST_SOP_MASK);
>> + if (ch_priv->desc_id == ch_priv->desc_cnt - 1)
>> + status |= DMAD_ST_WRAP_MASK;
>> +
>> + /* set dma descriptor */
>> + dma_desc->address = virt_to_phys(src);
>> + dma_desc->length = len;
>> + dma_desc->status = status;
>> +
>> + /* flush cache */
>> + bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc));
>> +
>> + /* kick tx dma channel */
>> + setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK);
>> +
>> + /* poll dma status */
>> + do {
>> + /* invalidate cache */
>> + bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc));
>> +
>> + if (!(dma_desc->status & DMAD_ST_OWN_MASK))
>> + break;
>> + } while(1);
>> +
>> + /* increment dma descriptor */
>> + ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt;
>> +
>> + return 0;
>> +}
>> +
>> +static int bcm6348_iudma_free_rcv_buf(struct dma *dma, void *dst, size_t size)
>> +{
>> + const 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 = ch_priv->dma_ring;
>> + uint16_t status;
>> + uint8_t i;
>> + u32 cfg;
>> +
>> + /* get dirty dma descriptor */
>> + for (i = 0; i < ch_priv->desc_cnt; i++) {
>> + if (phys_to_virt(dma_desc->address) == dst)
>> + break;
>> +
>> + dma_desc++;
>> + }
>> +
>> + /* dma descriptor not found */
>> + if (i == ch_priv->desc_cnt) {
>> + pr_err("dirty dma descriptor not found\n");
>> + return -ENOENT;
>> + }
>> +
>> + /* invalidate cache */
>> + bcm6348_iudma_idc(ch_priv->dma_ring,
>> + sizeof(*dma_desc) * ch_priv->desc_cnt);
>> +
>> + /* free dma descriptor */
>> + ch_priv->busy_desc[i] = false;
>> +
>> + status = DMAD_ST_OWN_MASK;
>> + if (i == ch_priv->desc_cnt - 1)
>> + status |= DMAD_ST_WRAP_MASK;
>> +
>> + dma_desc->status |= status;
>> + dma_desc->length = PKTSIZE_ALIGN;
>> +
>> + /* tell dma we allocated one buffer */
>> + writel_be(1, DMA_FLOWC_ALLOC_REG(dma->id));
>> +
>> + /* flush cache */
>> + bcm6348_iudma_fdc(ch_priv->dma_ring,
>> + sizeof(*dma_desc) * ch_priv->desc_cnt);
>> +
>> + /* kick rx dma channel if disabled */
>> + cfg = readl_be(priv->chan + DMAC_CFG_REG(dma->id));
>> + if (!(cfg & DMAC_CFG_ENABLE_MASK))
>> + setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
>> + DMAC_CFG_ENABLE_MASK);
>> +
>> + return 0;
>> +}
>> +
>> +static int bcm6348_iudma_add_rcv_buf(struct dma *dma, void *dst, size_t size)
>> +{
>> + const 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 = ch_priv->dma_ring;
>> +
>> + /* no more dma descriptors available */
>> + if (ch_priv->desc_cnt == ch_priv->dma_ring_size) {
>> + pr_err("max number of buffers reached\n");
>> + return -EINVAL;
>> + }
>> +
>> + /* get next dma descriptor */
>> + dma_desc += ch_priv->desc_cnt;
>> +
>> + /* init dma descriptor */
>> + dma_desc->address = virt_to_phys(dst);
>> + dma_desc->length = size;
>> + dma_desc->status = 0;
>> +
>> + /* flush cache */
>> + bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc));
>> +
>> + /* increment dma descriptors */
>> + ch_priv->desc_cnt++;
>> +
>> + return 0;
>> +}
>> +
>> +static int bcm6348_iudma_prepare_rcv_buf(struct dma *dma, void *dst,
>> + size_t size)
>> +{
>> + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
>> + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
>> +
>> + /* only add new rx buffers if channel isn't running */
>> + if (ch_priv->running)
>> + return bcm6348_iudma_free_rcv_buf(dma, dst, size);
>> + else
>> + return bcm6348_iudma_add_rcv_buf(dma, dst, size);
>> +}
>> +
>> +static const struct dma_ops bcm6348_iudma_ops = {
>> + .disable = bcm6348_iudma_disable,
>> + .enable = bcm6348_iudma_enable,
>> + .prepare_rcv_buf = bcm6348_iudma_prepare_rcv_buf,
>> + .request = bcm6348_iudma_request,
>> + .receive = bcm6348_iudma_receive,
>> + .send = bcm6348_iudma_send,
>> +};
>> +
>> +static const struct bcm6348_iudma_hw bcm6348_hw = {
>> + .err_mask = (DMAD6348_ST_OV_ERR_MASK |
>> + DMAD6348_ST_CRC_ERR_MASK |
>> + DMAD6348_ST_RX_ERR_MASK |
>> + DMAD6348_ST_OS_ERR_MASK |
>> + DMAD6348_ST_UN_ERR_MASK),
>> +};
>> +
>> +static const struct bcm6348_iudma_hw bcm6368_hw = {
>> + .err_mask = 0,
>> +};
>> +
>> +static const struct udevice_id bcm6348_iudma_ids[] = {
>> + {
>> + .compatible = "brcm,bcm6348-iudma",
>> + .data = (ulong)&bcm6348_hw,
>> + }, {
>> + .compatible = "brcm,bcm6368-iudma",
>> + .data = (ulong)&bcm6368_hw,
>> + }, { /* sentinel */ }
>> +};
>> +
>> +static int bcm6348_iudma_probe(struct udevice *dev)
>> +{
>> + struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
>> + struct bcm6348_iudma_priv *priv = dev_get_priv(dev);
>> + const struct bcm6348_iudma_hw *hw =
>> + (const struct bcm6348_iudma_hw *)dev_get_driver_data(dev);
>> + uint8_t ch;
>> + int i;
>> +
>> + uc_priv->supported = (DMA_SUPPORTS_DEV_TO_MEM |
>> + DMA_SUPPORTS_MEM_TO_DEV);
>> + priv->hw = hw;
>> +
>> + /* dma global base address */
>> + priv->base = dev_remap_addr_name(dev, "dma");
>> + if (!priv->base)
>> + return -EINVAL;
>> +
>> + /* dma channels base address */
>> + priv->chan = dev_remap_addr_name(dev, "dma-channels");
>> + if (!priv->chan)
>> + return -EINVAL;
>> +
>> + /* dma sram base address */
>> + priv->sram = dev_remap_addr_name(dev, "dma-sram");
>> + if (!priv->sram)
>> + return -EINVAL;
>> +
>> + /* get number of channels */
>> + priv->n_channels = dev_read_u32_default(dev, "dma-channels", 8);
>> + if (priv->n_channels > DMA_CHAN_MAX)
>> + 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;
>> +
>> + ret = clk_enable(&clk);
>> + if (ret < 0) {
>> + pr_err("error enabling clock %d\n", i);
>> + return ret;
>> + }
>> +
>> + ret = clk_free(&clk);
>> + if (ret < 0) {
>> + pr_err("error freeing clock %d\n", i);
>> + return ret;
>> + }
>> + }
>> +
>> + /* 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;
>> +
>> + ret = reset_deassert(&reset);
>> + if (ret < 0) {
>> + pr_err("error deasserting reset %d\n", i);
>> + return ret;
>> + }
>> +
>> + ret = reset_free(&reset);
>> + if (ret < 0) {
>> + pr_err("error freeing reset %d\n", i);
>> + return ret;
>> + }
>> + }
>> +
>> + /* disable dma controller */
>> + clrbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
>> +
>> + /* alloc channel private data pointers */
>> + priv->ch_priv = calloc(priv->n_channels,
>> + sizeof(struct bcm6348_chan_priv*));
>> + if (!priv->ch_priv)
>> + return -ENOMEM;
>> +
>> + /* stop dma channels */
>> + for (ch = 0; ch < priv->n_channels; ch++)
>> + bcm6348_iudma_chan_stop(priv, ch);
>> +
>> + /* enable dma controller */
>> + setbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
>> +
>> + return 0;
>> +}
>> +
>> +U_BOOT_DRIVER(bcm6348_iudma) = {
>> + .name = "bcm6348_iudma",
>> + .id = UCLASS_DMA,
>> + .of_match = bcm6348_iudma_ids,
>> + .ops = &bcm6348_iudma_ops,
>> + .priv_auto_alloc_size = sizeof(struct bcm6348_iudma_priv),
>> + .probe = bcm6348_iudma_probe,
>> +};
>>
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 02/28] bmips: bcm6338: add bcm6348-iudma support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 01/28] dma: add bcm6348-iudma support Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 03/28] bmips: bcm6348: " Álvaro Fernández Rojas
` (26 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: fix license identifiers
v9: no changes
v8: no changes
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 | 14 ++++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6338-dma.h
diff --git a/arch/mips/dts/brcm,bcm6338.dtsi b/arch/mips/dts/brcm,bcm6338.dtsi
index bbd58cf803..990355481c 100644
--- a/arch/mips/dts/brcm,bcm6338.dtsi
+++ b/arch/mips/dts/brcm,bcm6338.dtsi
@@ -4,6 +4,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"
@@ -130,5 +131,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>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6338-dma.h b/include/dt-bindings/dma/bcm6338-dma.h
new file mode 100644
index 0000000000..f2e0b20444
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6338-dma.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#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 */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 03/28] bmips: bcm6348: add bcm6348-iudma support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 01/28] dma: add bcm6348-iudma support Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 02/28] bmips: bcm6338: " Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 04/28] bmips: bcm6358: " Álvaro Fernández Rojas
` (25 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: fix license identifiers
v9: no changes
v8: no changes
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 | 16 ++++++++++++++++
2 files changed, 32 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6348-dma.h
diff --git a/arch/mips/dts/brcm,bcm6348.dtsi b/arch/mips/dts/brcm,bcm6348.dtsi
index cc80bbc808..875de232ca 100644
--- a/arch/mips/dts/brcm,bcm6348.dtsi
+++ b/arch/mips/dts/brcm,bcm6348.dtsi
@@ -4,6 +4,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"
@@ -159,5 +160,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>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6348-dma.h b/include/dt-bindings/dma/bcm6348-dma.h
new file mode 100644
index 0000000000..36c2ffd412
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6348-dma.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#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 */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 04/28] bmips: bcm6358: add bcm6348-iudma support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (2 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 03/28] bmips: bcm6348: " Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 05/28] bmips: bcm6368: " Álvaro Fernández Rojas
` (24 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: fix license identifiers
v9: no changes
v8: no changes
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 | 16 ++++++++++++++++
2 files changed, 34 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6358-dma.h
diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi
index 0617b46e92..5605723e83 100644
--- a/arch/mips/dts/brcm,bcm6358.dtsi
+++ b/arch/mips/dts/brcm,bcm6358.dtsi
@@ -4,6 +4,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"
@@ -190,5 +191,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>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6358-dma.h b/include/dt-bindings/dma/bcm6358-dma.h
new file mode 100644
index 0000000000..3118b9da0a
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6358-dma.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#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 */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 05/28] bmips: bcm6368: add bcm6348-iudma support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (3 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 04/28] bmips: bcm6358: " Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 06/28] bmips: bcm6328: " Álvaro Fernández Rojas
` (23 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: fix license identifiers
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6368.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm6368-dma.h | 14 ++++++++++++++
2 files changed, 27 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6368-dma.h
diff --git a/arch/mips/dts/brcm,bcm6368.dtsi b/arch/mips/dts/brcm,bcm6368.dtsi
index 65d769ab4f..30047f6360 100644
--- a/arch/mips/dts/brcm,bcm6368.dtsi
+++ b/arch/mips/dts/brcm,bcm6368.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6368-clock.h>
+#include <dt-bindings/dma/bcm6368-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/reset/bcm6368-reset.h>
#include "skeleton.dtsi"
@@ -192,5 +193,17 @@
status = "disabled";
};
+
+ iudma: dma-controller at 10006800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x10006800 0x80>,
+ <0x10006a00 0x80>,
+ <0x10006c00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6368-dma.h b/include/dt-bindings/dma/bcm6368-dma.h
new file mode 100644
index 0000000000..36c6caa0e1
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6368-dma.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6368_H
+#define __DT_BINDINGS_DMA_BCM6368_H
+
+#define BCM6368_DMA_ENETSW_RX 0
+#define BCM6368_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6368_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 06/28] bmips: bcm6328: add bcm6348-iudma support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (4 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 05/28] bmips: bcm6368: " Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 07/28] bmips: bcm6362: " Álvaro Fernández Rojas
` (22 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: fix license identifiers
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6328.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm6328-dma.h | 14 ++++++++++++++
2 files changed, 27 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6328-dma.h
diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi
index e00a2950e2..6fa49e22bb 100644
--- a/arch/mips/dts/brcm,bcm6328.dtsi
+++ b/arch/mips/dts/brcm,bcm6328.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6328-clock.h>
+#include <dt-bindings/dma/bcm6328-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm6328-power-domain.h>
#include <dt-bindings/reset/bcm6328-reset.h>
@@ -187,5 +188,17 @@
reg = <0x10003000 0x864>;
u-boot,dm-pre-reloc;
};
+
+ iudma: dma-controller at 1000d800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x1000d800 0x80>,
+ <0x1000da00 0x80>,
+ <0x1000dc00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6328-dma.h b/include/dt-bindings/dma/bcm6328-dma.h
new file mode 100644
index 0000000000..7494df2feb
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6328-dma.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6328_H
+#define __DT_BINDINGS_DMA_BCM6328_H
+
+#define BCM6328_DMA_ENETSW_RX 0
+#define BCM6328_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6328_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 07/28] bmips: bcm6362: add bcm6348-iudma support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (5 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 06/28] bmips: bcm6328: " Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 08/28] bmips: bcm63268: " Álvaro Fernández Rojas
` (21 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: fix license identifiers
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6362.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm6362-dma.h | 14 ++++++++++++++
2 files changed, 27 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6362-dma.h
diff --git a/arch/mips/dts/brcm,bcm6362.dtsi b/arch/mips/dts/brcm,bcm6362.dtsi
index 3047b82b21..94e7de096d 100644
--- a/arch/mips/dts/brcm,bcm6362.dtsi
+++ b/arch/mips/dts/brcm,bcm6362.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6362-clock.h>
+#include <dt-bindings/dma/bcm6362-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm6362-power-domain.h>
#include <dt-bindings/reset/bcm6362-reset.h>
@@ -211,5 +212,17 @@
reg = <0x10003000 0x864>;
u-boot,dm-pre-reloc;
};
+
+ iudma: dma-controller at 1000d800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x1000d800 0x80>,
+ <0x1000da00 0x80>,
+ <0x1000dc00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6362-dma.h b/include/dt-bindings/dma/bcm6362-dma.h
new file mode 100644
index 0000000000..1e62236daa
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6362-dma.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6362_H
+#define __DT_BINDINGS_DMA_BCM6362_H
+
+#define BCM6362_DMA_ENETSW_RX 0
+#define BCM6362_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6362_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 08/28] bmips: bcm63268: add bcm6348-iudma support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (6 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 07/28] bmips: bcm6362: " Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 09/28] bmips: bcm6318: " Álvaro Fernández Rojas
` (20 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: fix license identifiers
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm63268.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm63268-dma.h | 14 ++++++++++++++
2 files changed, 27 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm63268-dma.h
diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi
index 62c440e675..c7ad83c306 100644
--- a/arch/mips/dts/brcm,bcm63268.dtsi
+++ b/arch/mips/dts/brcm,bcm63268.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm63268-clock.h>
+#include <dt-bindings/dma/bcm63268-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm63268-power-domain.h>
#include <dt-bindings/reset/bcm63268-reset.h>
@@ -217,5 +218,17 @@
reg = <0x10003000 0x894>;
u-boot,dm-pre-reloc;
};
+
+ iudma: dma-controller at 1000d800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x1000d800 0x80>,
+ <0x1000da00 0x80>,
+ <0x1000dc00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm63268-dma.h b/include/dt-bindings/dma/bcm63268-dma.h
new file mode 100644
index 0000000000..7d027119e6
--- /dev/null
+++ b/include/dt-bindings/dma/bcm63268-dma.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM63268_H
+#define __DT_BINDINGS_DMA_BCM63268_H
+
+#define BCM63268_DMA_ENETSW_RX 0
+#define BCM63268_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM63268_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 09/28] bmips: bcm6318: add bcm6348-iudma support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (7 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 08/28] bmips: bcm63268: " Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 10/28] net: add support for bcm6348-enet Álvaro Fernández Rojas
` (19 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: fix license identifiers
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6318.dtsi | 19 +++++++++++++++++++
include/dt-bindings/dma/bcm6318-dma.h | 14 ++++++++++++++
2 files changed, 33 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6318-dma.h
diff --git a/arch/mips/dts/brcm,bcm6318.dtsi b/arch/mips/dts/brcm,bcm6318.dtsi
index f75988be12..d04b7cbb01 100644
--- a/arch/mips/dts/brcm,bcm6318.dtsi
+++ b/arch/mips/dts/brcm,bcm6318.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6318-clock.h>
+#include <dt-bindings/dma/bcm6318-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm6318-power-domain.h>
#include <dt-bindings/reset/bcm6318-reset.h>
@@ -54,6 +55,12 @@
reg = <0x10000004 0x4>;
#clock-cells = <1>;
};
+
+ ubus_clk: ubus-clk {
+ compatible = "brcm,bcm6345-clk";
+ reg = <0x10000008 0x4>;
+ #clock-cells = <1>;
+ };
};
ubus {
@@ -182,5 +189,17 @@
status = "disabled";
};
+
+ iudma: dma-controller at 10088000 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x10088000 0x80>,
+ <0x10088200 0x80>,
+ <0x10088400 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6318-dma.h b/include/dt-bindings/dma/bcm6318-dma.h
new file mode 100644
index 0000000000..ad7c5ac2df
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6318-dma.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6318_H
+#define __DT_BINDINGS_DMA_BCM6318_H
+
+#define BCM6318_DMA_ENETSW_RX 0
+#define BCM6318_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6318_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 10/28] net: add support for bcm6348-enet
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (8 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 09/28] bmips: bcm6318: " Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-30 16:54 ` Daniel Schwierzeck
2018-11-29 22:25 ` [U-Boot] [PATCH v10 11/28] bmips: bcm6338: " Álvaro Fernández Rojas
` (18 subsequent siblings)
28 siblings, 1 reply; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: Introduce changes suggested by Daniel Schwierzeck:
- Fix license identifiers.
- Remove packet queue.
- Move dma_prepare_rcv_buf to free_pkt.
- Switch to live DM live tree.
v9: use dma_prepare_rcv_buf and remove dma rx channel reset:
- bcm6348_eth_recv: clear dirty dma descriptors only when packets are copied
from rx dma.
- bcm6348_eth_send: remove dma rx channel reset when sending packet.
v8: Introduce changes from Grygorii Strashko
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 | 537 +++++++++++++++++++++++++++++++++++++++++
include/configs/bmips_common.h | 6 +-
4 files changed, 553 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/bcm6348-eth.c
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 8fb365fc5d..2b7cec8804 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -72,6 +72,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
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 99056aa041..2647d4dd23 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -6,6 +6,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
diff --git a/drivers/net/bcm6348-eth.c b/drivers/net/bcm6348-eth.c
new file mode 100644
index 0000000000..7100e68bd2
--- /dev/null
+++ b/drivers/net/bcm6348-eth.c
@@ -0,0 +1,537 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#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;
+ /* DMA */
+ struct dma rx_dma;
+ struct dma tx_dma;
+ /* PHY */
+ int phy_id;
+ struct phy_device *phy_dev;
+};
+
+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("%s: error disabling emac\n", __func__);
+}
+
+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("%s: error resetting emac\n", __func__);
+}
+
+static int bcm6348_eth_free_pkt(struct udevice *dev, uchar *packet, int len)
+{
+ struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+
+ return dma_prepare_rcv_buf(&priv->rx_dma, packet, len);
+}
+
+static int bcm6348_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+
+ return dma_receive(&priv->rx_dma, (void**)packetp, NULL);
+}
+
+static int bcm6348_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+
+ return dma_send(&priv->tx_dma, packet, length, NULL);
+}
+
+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;
+
+ /* prepare rx dma buffers */
+ for (i = 0; i < ETH_RX_DESC; i++) {
+ ret = dma_prepare_rcv_buf(&priv->rx_dma, net_rx_packets[i],
+ PKTSIZE_ALIGN);
+ if (ret < 0)
+ break;
+ }
+
+ /* 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("%s: could not initialize phy\n", __func__);
+ return ret;
+ }
+
+ if (!priv->phy_dev->link) {
+ pr_err("%s: no phy link\n", __func__);
+ 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) & ETH_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);
+ struct ofnode_phandle_args phy;
+ const char *phy_mode;
+ int ret, i;
+
+ /* get base address */
+ priv->base = dev_remap_addr(dev);
+ if (!priv->base)
+ return -EINVAL;
+ pdata->iobase = (phys_addr_t) priv->base;
+
+ /* get phy mode */
+ pdata->phy_interface = PHY_INTERFACE_MODE_NONE;
+ phy_mode = dev_read_string(dev, "phy-mode");
+ 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 */
+ if (dev_read_phandle_with_args(dev, "phy", NULL, 0, 0, &phy))
+ return -ENOENT;
+ priv->phy_id = ofnode_read_u32_default(phy.node, "reg", -1);
+
+ /* 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;
+
+ ret = clk_enable(&clk);
+ if (ret < 0) {
+ pr_err("%s: error enabling clock %d\n", __func__, i);
+ return ret;
+ }
+
+ ret = clk_free(&clk);
+ if (ret < 0) {
+ pr_err("%s: error freeing clock %d\n", __func__, i);
+ return ret;
+ }
+ }
+
+ /* 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;
+
+ ret = reset_deassert(&reset);
+ if (ret < 0) {
+ pr_err("%s: error deasserting reset %d\n", __func__, i);
+ return ret;
+ }
+
+ ret = reset_free(&reset);
+ if (ret < 0) {
+ pr_err("%s: error freeing reset %d\n", __func__, i);
+ return ret;
+ }
+ }
+
+ /* 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,
+};
diff --git a/include/configs/bmips_common.h b/include/configs/bmips_common.h
index 39ca2e0bf3..788f4af70d 100644
--- a/include/configs/bmips_common.h
+++ b/include/configs/bmips_common.h
@@ -6,6 +6,10 @@
#ifndef __CONFIG_BMIPS_COMMON_H
#define __CONFIG_BMIPS_COMMON_H
+/* ETH */
+#define CONFIG_PHY_RESET_DELAY 20
+#define CONFIG_SYS_RX_ETH_BUFFER 6
+
/* UART */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
230400, 500000, 1500000 }
@@ -16,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
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 10/28] net: add support for bcm6348-enet
2018-11-29 22:25 ` [U-Boot] [PATCH v10 10/28] net: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-11-30 16:54 ` Daniel Schwierzeck
0 siblings, 0 replies; 145+ messages in thread
From: Daniel Schwierzeck @ 2018-11-30 16:54 UTC (permalink / raw)
To: u-boot
Am 29.11.18 um 23:25 schrieb Álvaro Fernández Rojas:
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
> v10: Introduce changes suggested by Daniel Schwierzeck:
> - Fix license identifiers.
> - Remove packet queue.
> - Move dma_prepare_rcv_buf to free_pkt.
> - Switch to live DM live tree.
> v9: use dma_prepare_rcv_buf and remove dma rx channel reset:
> - bcm6348_eth_recv: clear dirty dma descriptors only when packets are copied
> from rx dma.
> - bcm6348_eth_send: remove dma rx channel reset when sending packet.
> v8: Introduce changes from Grygorii Strashko
> 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 | 537 +++++++++++++++++++++++++++++++++++++++++
> include/configs/bmips_common.h | 6 +-
> 4 files changed, 553 insertions(+), 1 deletion(-)
> create mode 100644 drivers/net/bcm6348-eth.c
>
Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
--
- Daniel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181130/0183de2e/attachment.sig>
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 11/28] bmips: bcm6338: add support for bcm6348-enet
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (9 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 10/28] net: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 12/28] bmips: enable f@st1704 enet support Álvaro Fernández Rojas
` (17 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
v10: no changes
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6338.dtsi | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6338.dtsi b/arch/mips/dts/brcm,bcm6338.dtsi
index 990355481c..c547e949dd 100644
--- a/arch/mips/dts/brcm,bcm6338.dtsi
+++ b/arch/mips/dts/brcm,bcm6338.dtsi
@@ -144,5 +144,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";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 12/28] bmips: enable f@st1704 enet support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (10 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 11/28] bmips: bcm6338: " Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 13/28] bmips: bcm6348: add support for bcm6348-enet Álvaro Fernández Rojas
` (16 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: no changes
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 | 8 +++++++-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/sagem,f at st1704.dts b/arch/mips/dts/sagem,f at st1704.dts
index 5300f8b6df..ec6846dd9f 100644
--- a/arch/mips/dts/sagem,f at st1704.dts
+++ b/arch/mips/dts/sagem,f at st1704.dts
@@ -39,6 +39,18 @@
};
};
+&enet {
+ status = "okay";
+ phy = <&enetphy>;
+ phy-mode = "mii";
+
+ enetphy: fixed-link {
+ reg = <1>;
+ speed = <100>;
+ full-duplex;
+ };
+};
+
&gpio {
status = "okay";
};
diff --git a/configs/sagem_f at st1704_ram_defconfig b/configs/sagem_f at st1704_ram_defconfig
index 91a966327a..8c36f5dbf8 100644
--- a/configs/sagem_f at st1704_ram_defconfig
+++ b/configs/sagem_f at st1704_ram_defconfig
@@ -27,11 +27,14 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="sagem,f at st1704"
-# CONFIG_NET is not set
+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_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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 13/28] bmips: bcm6348: add support for bcm6348-enet
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (11 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 12/28] bmips: enable f@st1704 enet support Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 14/28] bmips: enable ct-5361 enet support Álvaro Fernández Rojas
` (15 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6348.dtsi | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6348.dtsi b/arch/mips/dts/brcm,bcm6348.dtsi
index 875de232ca..79e7bd892b 100644
--- a/arch/mips/dts/brcm,bcm6348.dtsi
+++ b/arch/mips/dts/brcm,bcm6348.dtsi
@@ -161,6 +161,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>,
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 14/28] bmips: enable ct-5361 enet support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (12 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 13/28] bmips: bcm6348: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 15/28] bmips: bcm6358: add support for bcm6348-enet Álvaro Fernández Rojas
` (14 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: no changes
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(-)
diff --git a/arch/mips/dts/comtrend,ct-5361.dts b/arch/mips/dts/comtrend,ct-5361.dts
index 25747ca95d..f6b8a94e25 100644
--- a/arch/mips/dts/comtrend,ct-5361.dts
+++ b/arch/mips/dts/comtrend,ct-5361.dts
@@ -34,6 +34,18 @@
};
};
+&enet1 {
+ status = "okay";
+ phy = <&enet1phy>;
+ phy-mode = "mii";
+
+ enet1phy: fixed-link {
+ reg = <1>;
+ speed = <100>;
+ full-duplex;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/comtrend_ct5361_ram_defconfig b/configs/comtrend_ct5361_ram_defconfig
index 82f2070713..6297e78fd9 100644
--- a/configs/comtrend_ct5361_ram_defconfig
+++ b/configs/comtrend_ct5361_ram_defconfig
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,ct-5361"
-# CONFIG_NET is not set
+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_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 15/28] bmips: bcm6358: add support for bcm6348-enet
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (13 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 14/28] bmips: enable ct-5361 enet support Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 16/28] bmips: enable hg556a enet support Álvaro Fernández Rojas
` (13 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6358.dtsi | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi
index 5605723e83..5e9c9ad769 100644
--- a/arch/mips/dts/brcm,bcm6358.dtsi
+++ b/arch/mips/dts/brcm,bcm6358.dtsi
@@ -192,6 +192,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>,
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 16/28] bmips: enable hg556a enet support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (14 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 15/28] bmips: bcm6358: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 17/28] bmips: enable nb4-ser " Álvaro Fernández Rojas
` (12 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: no changes
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(-)
diff --git a/arch/mips/dts/huawei,hg556a.dts b/arch/mips/dts/huawei,hg556a.dts
index 60455c2ff8..6a7fc1df4b 100644
--- a/arch/mips/dts/huawei,hg556a.dts
+++ b/arch/mips/dts/huawei,hg556a.dts
@@ -93,6 +93,18 @@
status = "okay";
};
+&enet1 {
+ status = "okay";
+ phy = <&enet1phy>;
+ phy-mode = "mii";
+
+ enet1phy: fixed-link {
+ reg = <1>;
+ speed = <100>;
+ full-duplex;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/huawei_hg556a_ram_defconfig b/configs/huawei_hg556a_ram_defconfig
index 6bb14ba736..d4e6144319 100644
--- a/configs/huawei_hg556a_ram_defconfig
+++ b/configs/huawei_hg556a_ram_defconfig
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="huawei,hg556a"
-# CONFIG_NET is not set
+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_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 17/28] bmips: enable nb4-ser enet support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (15 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 16/28] bmips: enable hg556a enet support Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 18/28] net: add support for bcm6368-enet Álvaro Fernández Rojas
` (11 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: no changes
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(-)
diff --git a/arch/mips/dts/sfr,nb4-ser.dts b/arch/mips/dts/sfr,nb4-ser.dts
index bdc6f8ae45..dfbc4148dc 100644
--- a/arch/mips/dts/sfr,nb4-ser.dts
+++ b/arch/mips/dts/sfr,nb4-ser.dts
@@ -53,6 +53,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";
};
diff --git a/configs/sfr_nb4-ser_ram_defconfig b/configs/sfr_nb4-ser_ram_defconfig
index 12adfb01e7..39622875b1 100644
--- a/configs/sfr_nb4-ser_ram_defconfig
+++ b/configs/sfr_nb4-ser_ram_defconfig
@@ -26,11 +26,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="sfr,nb4-ser"
-# CONFIG_NET is not set
+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
@@ -42,6 +45,9 @@ CONFIG_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 18/28] net: add support for bcm6368-enet
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (16 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 17/28] bmips: enable nb4-ser " Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-30 16:58 ` Daniel Schwierzeck
2018-11-29 22:25 ` [U-Boot] [PATCH v10 19/28] bmips: bcm6368: " Álvaro Fernández Rojas
` (10 subsequent siblings)
28 siblings, 1 reply; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: Introduce changes suggested by Daniel Schwierzeck:
- Fix license identifiers.
- Remove packet queue.
- Move dma_prepare_rcv_buf to free_pkt.
- Pad packets smaller than ETH_ZLEN.
- Switch to live DM live tree.
v9: introduce flow control improvements from bcm6348-eth:
- introduce rx packets caching functionality from bcm6348-eth to fix flow
control issues.
- code style fixes.
v8: introduce bcm6368-enet driver
drivers/net/Kconfig | 8 +
drivers/net/Makefile | 1 +
drivers/net/bcm6368-eth.c | 625 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 634 insertions(+)
create mode 100644 drivers/net/bcm6368-eth.c
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2b7cec8804..7044c6adf3 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -82,6 +82,14 @@ config BCM6348_ETH
help
This driver supports the BCM6348 Ethernet MAC.
+config BCM6368_ETH
+ bool "BCM6368 EMAC support"
+ depends on DM_ETH && ARCH_BMIPS
+ select DMA
+ select MII
+ help
+ This driver supports the BCM6368 Ethernet MAC.
+
config DWC_ETH_QOS
bool "Synopsys DWC Ethernet QOS device support"
depends on DM_ETH
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 2647d4dd23..0dbfa03306 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -7,6 +7,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_BCM6368_ETH) += bcm6368-eth.o
obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
obj-$(CONFIG_DRIVER_AX88180) += ax88180.o
obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
diff --git a/drivers/net/bcm6368-eth.c b/drivers/net/bcm6368-eth.c
new file mode 100644
index 0000000000..a31efba9d1
--- /dev/null
+++ b/drivers/net/bcm6368-eth.c
@@ -0,0 +1,625 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dma.h>
+#include <miiphy.h>
+#include <net.h>
+#include <reset.h>
+#include <wait_bit.h>
+#include <asm/io.h>
+
+#define ETH_PORT_STR "brcm,enetsw-port"
+
+#define ETH_RX_DESC PKTBUFSRX
+#define ETH_ZLEN 60
+#define ETH_TIMEOUT 100
+
+#define ETH_MAX_PORT 8
+#define ETH_RGMII_PORT0 4
+
+/* Port traffic control */
+#define ETH_PTCTRL_REG(x) (0x0 + (x))
+#define ETH_PTCTRL_RXDIS_SHIFT 0
+#define ETH_PTCTRL_RXDIS_MASK (1 << ETH_PTCTRL_RXDIS_SHIFT)
+#define ETH_PTCTRL_TXDIS_SHIFT 1
+#define ETH_PTCTRL_TXDIS_MASK (1 << ETH_PTCTRL_TXDIS_SHIFT)
+
+/* Switch mode register */
+#define ETH_SWMODE_REG 0xb
+#define ETH_SWMODE_FWD_EN_SHIFT 1
+#define ETH_SWMODE_FWD_EN_MASK (1 << ETH_SWMODE_FWD_EN_SHIFT)
+
+/* IMP override Register */
+#define ETH_IMPOV_REG 0xe
+#define ETH_IMPOV_LINKUP_SHIFT 0
+#define ETH_IMPOV_LINKUP_MASK (1 << ETH_IMPOV_LINKUP_SHIFT)
+#define ETH_IMPOV_FDX_SHIFT 1
+#define ETH_IMPOV_FDX_MASK (1 << ETH_IMPOV_FDX_SHIFT)
+#define ETH_IMPOV_100_SHIFT 2
+#define ETH_IMPOV_100_MASK (1 << ETH_IMPOV_100_SHIFT)
+#define ETH_IMPOV_1000_SHIFT 3
+#define ETH_IMPOV_1000_MASK (1 << ETH_IMPOV_1000_SHIFT)
+#define ETH_IMPOV_RXFLOW_SHIFT 4
+#define ETH_IMPOV_RXFLOW_MASK (1 << ETH_IMPOV_RXFLOW_SHIFT)
+#define ETH_IMPOV_TXFLOW_SHIFT 5
+#define ETH_IMPOV_TXFLOW_MASK (1 << ETH_IMPOV_TXFLOW_SHIFT)
+#define ETH_IMPOV_FORCE_SHIFT 7
+#define ETH_IMPOV_FORCE_MASK (1 << ETH_IMPOV_FORCE_SHIFT)
+
+/* Port override Register */
+#define ETH_PORTOV_REG(x) (0x58 + (x))
+#define ETH_PORTOV_LINKUP_SHIFT 0
+#define ETH_PORTOV_LINKUP_MASK (1 << ETH_PORTOV_LINKUP_SHIFT)
+#define ETH_PORTOV_FDX_SHIFT 1
+#define ETH_PORTOV_FDX_MASK (1 << ETH_PORTOV_FDX_SHIFT)
+#define ETH_PORTOV_100_SHIFT 2
+#define ETH_PORTOV_100_MASK (1 << ETH_PORTOV_100_SHIFT)
+#define ETH_PORTOV_1000_SHIFT 3
+#define ETH_PORTOV_1000_MASK (1 << ETH_PORTOV_1000_SHIFT)
+#define ETH_PORTOV_RXFLOW_SHIFT 4
+#define ETH_PORTOV_RXFLOW_MASK (1 << ETH_PORTOV_RXFLOW_SHIFT)
+#define ETH_PORTOV_TXFLOW_SHIFT 5
+#define ETH_PORTOV_TXFLOW_MASK (1 << ETH_PORTOV_TXFLOW_SHIFT)
+#define ETH_PORTOV_ENABLE_SHIFT 6
+#define ETH_PORTOV_ENABLE_MASK (1 << ETH_PORTOV_ENABLE_SHIFT)
+
+/* Port RGMII control register */
+#define ETH_RGMII_CTRL_REG(x) (0x60 + (x))
+#define ETH_RGMII_CTRL_GMII_CLK_EN (1 << 7)
+#define ETH_RGMII_CTRL_MII_OVERRIDE_EN (1 << 6)
+#define ETH_RGMII_CTRL_MII_MODE_MASK (3 << 4)
+#define ETH_RGMII_CTRL_RGMII_MODE (0 << 4)
+#define ETH_RGMII_CTRL_MII_MODE (1 << 4)
+#define ETH_RGMII_CTRL_RVMII_MODE (2 << 4)
+#define ETH_RGMII_CTRL_TIMING_SEL_EN (1 << 0)
+
+/* Port RGMII timing register */
+#define ENETSW_RGMII_TIMING_REG(x) (0x68 + (x))
+
+/* MDIO control register */
+#define MII_SC_REG 0xb0
+#define MII_SC_EXT_SHIFT 16
+#define MII_SC_EXT_MASK (1 << MII_SC_EXT_SHIFT)
+#define MII_SC_REG_SHIFT 20
+#define MII_SC_PHYID_SHIFT 25
+#define MII_SC_RD_SHIFT 30
+#define MII_SC_RD_MASK (1 << MII_SC_RD_SHIFT)
+#define MII_SC_WR_SHIFT 31
+#define MII_SC_WR_MASK (1 << MII_SC_WR_SHIFT)
+
+/* MDIO data register */
+#define MII_DAT_REG 0xb4
+
+/* Global Management Configuration Register */
+#define ETH_GMCR_REG 0x200
+#define ETH_GMCR_RST_MIB_SHIFT 0
+#define ETH_GMCR_RST_MIB_MASK (1 << ETH_GMCR_RST_MIB_SHIFT)
+
+/* Jumbo control register port mask register */
+#define ETH_JMBCTL_PORT_REG 0x4004
+
+/* Jumbo control mib good frame register */
+#define ETH_JMBCTL_MAXSIZE_REG 0x4008
+
+/* ETH port data */
+struct bcm_enetsw_port {
+ bool used;
+ const char *name;
+ /* Config */
+ bool bypass_link;
+ int force_speed;
+ bool force_duplex_full;
+ /* PHY */
+ int phy_id;
+};
+
+/* ETH data */
+struct bcm6368_eth_priv {
+ void __iomem *base;
+ /* DMA */
+ struct dma rx_dma;
+ struct dma tx_dma;
+ /* Ports */
+ uint8_t num_ports;
+ struct bcm_enetsw_port used_ports[ETH_MAX_PORT];
+ int sw_port_link[ETH_MAX_PORT];
+ bool rgmii_override;
+ bool rgmii_timing;
+ /* PHY */
+ int phy_id;
+};
+
+static inline bool bcm_enet_port_is_rgmii(int portid)
+{
+ return portid >= ETH_RGMII_PORT0;
+}
+
+static int bcm6368_mdio_read(struct bcm6368_eth_priv *priv, uint8_t ext,
+ int phy_id, int reg)
+{
+ uint32_t val;
+
+ writel_be(0, priv->base + MII_SC_REG);
+
+ val = MII_SC_RD_MASK |
+ (phy_id << MII_SC_PHYID_SHIFT) |
+ (reg << MII_SC_REG_SHIFT);
+
+ if (ext)
+ val |= MII_SC_EXT_MASK;
+
+ writel_be(val, priv->base + MII_SC_REG);
+ udelay(50);
+
+ return readw_be(priv->base + MII_DAT_REG);
+}
+
+static int bcm6368_mdio_write(struct bcm6368_eth_priv *priv, uint8_t ext,
+ int phy_id, int reg, u16 data)
+{
+ uint32_t val;
+
+ writel_be(0, priv->base + MII_SC_REG);
+
+ val = MII_SC_WR_MASK |
+ (phy_id << MII_SC_PHYID_SHIFT) |
+ (reg << MII_SC_REG_SHIFT);
+
+ if (ext)
+ val |= MII_SC_EXT_MASK;
+
+ val |= data;
+
+ writel_be(val, priv->base + MII_SC_REG);
+ udelay(50);
+
+ return 0;
+}
+
+static int bcm6368_eth_free_pkt(struct udevice *dev, uchar *packet, int len)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+ return dma_prepare_rcv_buf(&priv->rx_dma, packet, len);
+}
+
+static int bcm6368_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+ return dma_receive(&priv->rx_dma, (void**)packetp, NULL);
+}
+
+static int bcm6368_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+ /* pad packets smaller than ETH_ZLEN */
+ if (length < ETH_ZLEN) {
+ memset(packet + length, 0, ETH_ZLEN - length);
+ length = ETH_ZLEN;
+ }
+
+ return dma_send(&priv->tx_dma, packet, length, NULL);
+}
+
+static int bcm6368_eth_adjust_link(struct udevice *dev)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+ unsigned int i;
+
+ for (i = 0; i < priv->num_ports; i++) {
+ struct bcm_enetsw_port *port;
+ int val, j, up, adv, lpa, speed, duplex, media;
+ int external_phy = bcm_enet_port_is_rgmii(i);
+ u8 override;
+
+ port = &priv->used_ports[i];
+ if (!port->used)
+ continue;
+
+ if (port->bypass_link)
+ continue;
+
+ /* dummy read to clear */
+ for (j = 0; j < 2; j++)
+ val = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_BMSR);
+
+ if (val == 0xffff)
+ continue;
+
+ up = (val & BMSR_LSTATUS) ? 1 : 0;
+ if (!(up ^ priv->sw_port_link[i]))
+ continue;
+
+ priv->sw_port_link[i] = up;
+
+ /* link changed */
+ if (!up) {
+ dev_info(&priv->pdev->dev, "link DOWN on %s\n",
+ port->name);
+ writeb_be(ETH_PORTOV_ENABLE_MASK,
+ priv->base + ETH_PORTOV_REG(i));
+ writeb_be(ETH_PTCTRL_RXDIS_MASK |
+ ETH_PTCTRL_TXDIS_MASK,
+ priv->base + ETH_PTCTRL_REG(i));
+ continue;
+ }
+
+ adv = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_ADVERTISE);
+
+ lpa = bcm6368_mdio_read(priv, external_phy, port->phy_id,
+ MII_LPA);
+
+ /* figure out media and duplex from advertise and LPA values */
+ media = mii_nway_result(lpa & adv);
+ duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+
+ if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF))
+ speed = 100;
+ else
+ speed = 10;
+
+ if (val & BMSR_ESTATEN) {
+ adv = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_CTRL1000);
+
+ lpa = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_STAT1000);
+
+ if ((adv & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
+ (lpa & (LPA_1000FULL | LPA_1000HALF))) {
+ speed = 1000;
+ duplex = (lpa & LPA_1000FULL);
+ }
+ }
+
+ pr_alert("link UP on %s, %dMbps, %s-duplex\n",
+ port->name, speed, duplex ? "full" : "half");
+
+ override = ETH_PORTOV_ENABLE_MASK |
+ ETH_PORTOV_LINKUP_MASK;
+
+ if (speed == 1000)
+ override |= ETH_PORTOV_1000_MASK;
+ else if (speed == 100)
+ override |= ETH_PORTOV_100_MASK;
+ if (duplex)
+ override |= ETH_PORTOV_FDX_MASK;
+
+ writeb_be(override, priv->base + ETH_PORTOV_REG(i));
+ writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
+ }
+
+ return 0;
+}
+
+static int bcm6368_eth_start(struct udevice *dev)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+ uint8_t i;
+
+ /* prepare rx dma buffers */
+ for (i = 0; i < ETH_RX_DESC; i++) {
+ int ret = dma_prepare_rcv_buf(&priv->rx_dma, net_rx_packets[i],
+ PKTSIZE_ALIGN);
+ if (ret < 0)
+ break;
+ }
+
+ /* enable dma rx channel */
+ dma_enable(&priv->rx_dma);
+
+ /* enable dma tx channel */
+ dma_enable(&priv->tx_dma);
+
+ /* apply override config for bypass_link ports here. */
+ for (i = 0; i < priv->num_ports; i++) {
+ struct bcm_enetsw_port *port;
+ u8 override;
+
+ port = &priv->used_ports[i];
+ if (!port->used)
+ continue;
+
+ if (!port->bypass_link)
+ continue;
+
+ override = ETH_PORTOV_ENABLE_MASK |
+ ETH_PORTOV_LINKUP_MASK;
+
+ switch (port->force_speed) {
+ case 1000:
+ override |= ETH_PORTOV_1000_MASK;
+ break;
+ case 100:
+ override |= ETH_PORTOV_100_MASK;
+ break;
+ case 10:
+ break;
+ default:
+ pr_warn("%s: invalid forced speed on port %s\n",
+ __func__, port->name);
+ break;
+ }
+
+ if (port->force_duplex_full)
+ override |= ETH_PORTOV_FDX_MASK;
+
+ writeb_be(override, priv->base + ETH_PORTOV_REG(i));
+ writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
+ }
+
+ bcm6368_eth_adjust_link(dev);
+
+ return 0;
+}
+
+static void bcm6368_eth_stop(struct udevice *dev)
+{
+ struct bcm6368_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);
+}
+
+static const struct eth_ops bcm6368_eth_ops = {
+ .free_pkt = bcm6368_eth_free_pkt,
+ .recv = bcm6368_eth_recv,
+ .send = bcm6368_eth_send,
+ .start = bcm6368_eth_start,
+ .stop = bcm6368_eth_stop,
+};
+
+static const struct udevice_id bcm6368_eth_ids[] = {
+ { .compatible = "brcm,bcm6368-enet", },
+ { /* sentinel */ }
+};
+
+static bool bcm6368_phy_is_external(struct bcm6368_eth_priv *priv, int phy_id)
+{
+ uint8_t i;
+
+ for (i = 0; i < priv->num_ports; ++i) {
+ if (!priv->used_ports[i].used)
+ continue;
+ if (priv->used_ports[i].phy_id == phy_id)
+ return bcm_enet_port_is_rgmii(i);
+ }
+
+ return true;
+}
+
+static int bcm6368_mii_mdio_read(struct mii_dev *bus, int addr, int devaddr,
+ int reg)
+{
+ struct bcm6368_eth_priv *priv = bus->priv;
+ bool ext = bcm6368_phy_is_external(priv, addr);
+
+ return bcm6368_mdio_read(priv, ext, addr, reg);
+}
+
+static int bcm6368_mii_mdio_write(struct mii_dev *bus, int addr, int devaddr,
+ int reg, u16 data)
+{
+ struct bcm6368_eth_priv *priv = bus->priv;
+ bool ext = bcm6368_phy_is_external(priv, addr);
+
+ return bcm6368_mdio_write(priv, ext, addr, reg, data);
+}
+
+static int bcm6368_mdio_init(const char *name, struct bcm6368_eth_priv *priv)
+{
+ struct mii_dev *bus;
+
+ bus = mdio_alloc();
+ if (!bus) {
+ pr_err("%s: failed to allocate MDIO bus\n", __func__);
+ return -ENOMEM;
+ }
+
+ bus->read = bcm6368_mii_mdio_read;
+ bus->write = bcm6368_mii_mdio_write;
+ bus->priv = priv;
+ snprintf(bus->name, sizeof(bus->name), "%s", name);
+
+ return mdio_register(bus);
+}
+
+static int bcm6368_eth_probe(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+ int num_ports, ret, i;
+ uint32_t val;
+ ofnode node;
+
+ /* get base address */
+ priv->base = dev_remap_addr(dev);
+ if (!priv->base)
+ return -EINVAL;
+ pdata->iobase = (phys_addr_t) priv->base;
+
+ /* get number of ports */
+ num_ports = dev_read_u32_default(dev, "brcm,num-ports", ETH_MAX_PORT);
+ if (!num_ports || num_ports > ETH_MAX_PORT)
+ 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;
+
+ ret = clk_enable(&clk);
+ if (ret < 0) {
+ pr_err("%s: error enabling clock %d\n", __func__, i);
+ return ret;
+ }
+
+ ret = clk_free(&clk);
+ if (ret < 0) {
+ pr_err("%s: error freeing clock %d\n", __func__, i);
+ return ret;
+ }
+ }
+
+ /* 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;
+
+ ret = reset_deassert(&reset);
+ if (ret < 0) {
+ pr_err("%s: error deasserting reset %d\n", __func__, i);
+ return ret;
+ }
+
+ ret = reset_free(&reset);
+ if (ret < 0) {
+ pr_err("%s: error freeing reset %d\n", __func__, i);
+ return ret;
+ }
+ }
+
+ /* set priv data */
+ priv->num_ports = num_ports;
+ if (dev_read_bool(dev, "brcm,rgmii-override"))
+ priv->rgmii_override = true;
+ if (dev_read_bool(dev, "brcm,rgmii-timing"))
+ priv->rgmii_timing = true;
+
+ /* get ports */
+ dev_for_each_subnode(node, dev) {
+ const char *comp;
+ const char *label;
+ unsigned int p;
+ int phy_id;
+ int speed;
+
+ comp = ofnode_read_string(node, "compatible");
+ if (!comp || memcmp(comp, ETH_PORT_STR, sizeof(ETH_PORT_STR)))
+ continue;
+
+ p = ofnode_read_u32_default(node, "reg", ETH_MAX_PORT);
+ if (p >= num_ports)
+ return -EINVAL;
+
+ label = ofnode_read_string(node, "label");
+ if (!label) {
+ debug("%s: node %s has no label\n", __func__,
+ ofnode_get_name(node));
+ return -EINVAL;
+ }
+
+ phy_id = ofnode_read_u32_default(node, "brcm,phy-id", -1);
+
+ priv->used_ports[p].used = true;
+ priv->used_ports[p].name = label;
+ priv->used_ports[p].phy_id = phy_id;
+
+ if (ofnode_read_bool(node, "full-duplex"))
+ priv->used_ports[p].force_duplex_full = true;
+ if (ofnode_read_bool(node, "bypass-link"))
+ priv->used_ports[p].bypass_link = true;
+ speed = ofnode_read_u32_default(node, "speed", 0);
+ if (speed)
+ priv->used_ports[p].force_speed = speed;
+ }
+
+ /* init mii bus */
+ ret = bcm6368_mdio_init(dev->name, priv);
+ if (ret)
+ return ret;
+
+ /* disable all ports */
+ for (i = 0; i < priv->num_ports; i++) {
+ writeb_be(ETH_PORTOV_ENABLE_MASK,
+ priv->base + ETH_PORTOV_REG(i));
+ writeb_be(ETH_PTCTRL_RXDIS_MASK |
+ ETH_PTCTRL_TXDIS_MASK,
+ priv->base + ETH_PTCTRL_REG(i));
+
+ priv->sw_port_link[i] = 0;
+ }
+
+ /* enable external ports */
+ for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) {
+ u8 rgmii_ctrl;
+
+ if (!priv->used_ports[i].used)
+ continue;
+
+ rgmii_ctrl = readb_be(priv->base + ETH_RGMII_CTRL_REG(i));
+ rgmii_ctrl |= ETH_RGMII_CTRL_GMII_CLK_EN;
+ if (priv->rgmii_override)
+ rgmii_ctrl |= ETH_RGMII_CTRL_MII_OVERRIDE_EN;
+ if (priv->rgmii_timing)
+ rgmii_ctrl |= ETH_RGMII_CTRL_TIMING_SEL_EN;
+ writeb_be(rgmii_ctrl, priv->base + ETH_RGMII_CTRL_REG(i));
+ }
+
+ /* reset mib */
+ val = readb_be(priv->base + ETH_GMCR_REG);
+ val |= ETH_GMCR_RST_MIB_MASK;
+ writeb_be(val, priv->base + ETH_GMCR_REG);
+ mdelay(1);
+ val &= ~ETH_GMCR_RST_MIB_MASK;
+ writeb_be(val, priv->base + ETH_GMCR_REG);
+ mdelay(1);
+
+ /* force CPU port state */
+ val = readb_be(priv->base + ETH_IMPOV_REG);
+ val |= ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK;
+ writeb_be(val, priv->base + ETH_IMPOV_REG);
+
+ /* enable switch forward engine */
+ val = readb_be(priv->base + ETH_SWMODE_REG);
+ val |= ETH_SWMODE_FWD_EN_MASK;
+ writeb_be(val, priv->base + ETH_SWMODE_REG);
+
+ /* enable jumbo on all ports */
+ writel_be(0x1ff, priv->base + ETH_JMBCTL_PORT_REG);
+ writew_be(9728, priv->base + ETH_JMBCTL_MAXSIZE_REG);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(bcm6368_eth) = {
+ .name = "bcm6368_eth",
+ .id = UCLASS_ETH,
+ .of_match = bcm6368_eth_ids,
+ .ops = &bcm6368_eth_ops,
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+ .priv_auto_alloc_size = sizeof(struct bcm6368_eth_priv),
+ .probe = bcm6368_eth_probe,
+};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 18/28] net: add support for bcm6368-enet
2018-11-29 22:25 ` [U-Boot] [PATCH v10 18/28] net: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-30 16:58 ` Daniel Schwierzeck
0 siblings, 0 replies; 145+ messages in thread
From: Daniel Schwierzeck @ 2018-11-30 16:58 UTC (permalink / raw)
To: u-boot
Am 29.11.18 um 23:25 schrieb Álvaro Fernández Rojas:
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
> v10: Introduce changes suggested by Daniel Schwierzeck:
> - Fix license identifiers.
> - Remove packet queue.
> - Move dma_prepare_rcv_buf to free_pkt.
> - Pad packets smaller than ETH_ZLEN.
> - Switch to live DM live tree.
> v9: introduce flow control improvements from bcm6348-eth:
> - introduce rx packets caching functionality from bcm6348-eth to fix flow
> control issues.
> - code style fixes.
> v8: introduce bcm6368-enet driver
>
> drivers/net/Kconfig | 8 +
> drivers/net/Makefile | 1 +
> drivers/net/bcm6368-eth.c | 625 ++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 634 insertions(+)
> create mode 100644 drivers/net/bcm6368-eth.c
>
Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
--
- Daniel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181130/7fff8b45/attachment.sig>
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 19/28] bmips: bcm6368: add support for bcm6368-enet
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (17 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 18/28] net: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 20/28] bmips: enable wap-5813n enet support Álvaro Fernández Rojas
` (9 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6368.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6368.dtsi b/arch/mips/dts/brcm,bcm6368.dtsi
index 30047f6360..89590d6ff9 100644
--- a/arch/mips/dts/brcm,bcm6368.dtsi
+++ b/arch/mips/dts/brcm,bcm6368.dtsi
@@ -205,5 +205,24 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10f00000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10f00000 0x10000>;
+ clocks = <&periph_clk BCM6368_CLK_SWPKT_USB>,
+ <&periph_clk BCM6368_CLK_SWPKT_SAR>,
+ <&periph_clk BCM6368_CLK_ROBOSW>;
+ resets = <&periph_rst BCM6368_RST_SWITCH>,
+ <&periph_rst BCM6368_RST_EPHY>;
+ dmas = <&iudma BCM6368_DMA_ENETSW_RX>,
+ <&iudma BCM6368_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <6>;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 20/28] bmips: enable wap-5813n enet support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (18 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 19/28] bmips: bcm6368: " Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 21/28] bmips: bcm6328: add support for bcm6368-enet Álvaro Fernández Rojas
` (8 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,wap-5813n.dts | 14 ++++++++++++++
configs/comtrend_wap5813n_ram_defconfig | 8 +++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,wap-5813n.dts b/arch/mips/dts/comtrend,wap-5813n.dts
index bd41dab9f8..7e835b28d2 100644
--- a/arch/mips/dts/comtrend,wap-5813n.dts
+++ b/arch/mips/dts/comtrend,wap-5813n.dts
@@ -54,6 +54,20 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 4 {
+ compatible = "brcm,enetsw-port";
+ reg = <4>;
+ label = "rgmii";
+ brcm,phy-id = <0xff>;
+ speed = <1000>;
+ full-duplex;
+ bypass-link;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/comtrend_wap5813n_ram_defconfig b/configs/comtrend_wap5813n_ram_defconfig
index 987e4c3fbc..fd5107bb7d 100644
--- a/configs/comtrend_wap5813n_ram_defconfig
+++ b/configs/comtrend_wap5813n_ram_defconfig
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,wap-5813n"
-# CONFIG_NET is not set
+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_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_DM_RESET=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 21/28] bmips: bcm6328: add support for bcm6368-enet
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (19 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 20/28] bmips: enable wap-5813n enet support Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 22/28] bmips: enable ar-5387un enet support Álvaro Fernández Rojas
` (7 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6328.dtsi | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi
index 6fa49e22bb..50beed4171 100644
--- a/arch/mips/dts/brcm,bcm6328.dtsi
+++ b/arch/mips/dts/brcm,bcm6328.dtsi
@@ -200,5 +200,22 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10e00000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10e00000 0x10000>;
+ clocks = <&periph_clk BCM6328_CLK_ROBOSW>;
+ resets = <&periph_rst BCM6328_RST_ENETSW>,
+ <&periph_rst BCM6328_RST_EPHY>;
+ dmas = <&iudma BCM6328_DMA_ENETSW_RX>,
+ <&iudma BCM6328_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <5>;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 22/28] bmips: enable ar-5387un enet support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (20 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 21/28] bmips: bcm6328: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 23/28] bmips: bcm6362: add support for bcm6368-enet Álvaro Fernández Rojas
` (6 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,ar-5387un.dts | 32 ++++++++++++++++++++++++++++++++
configs/comtrend_ar5387un_ram_defconfig | 7 ++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,ar-5387un.dts b/arch/mips/dts/comtrend,ar-5387un.dts
index e993b5cd89..03e3851ab1 100644
--- a/arch/mips/dts/comtrend,ar-5387un.dts
+++ b/arch/mips/dts/comtrend,ar-5387un.dts
@@ -24,6 +24,38 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 0 {
+ compatible = "brcm,enetsw-port";
+ reg = <0>;
+ label = "fe1";
+ brcm,phy-id = <1>;
+ };
+
+ port at 1 {
+ compatible = "brcm,enetsw-port";
+ reg = <1>;
+ label = "fe2";
+ brcm,phy-id = <2>;
+ };
+
+ port at 2 {
+ compatible = "brcm,enetsw-port";
+ reg = <2>;
+ label = "fe3";
+ brcm,phy-id = <3>;
+ };
+
+ port at 3 {
+ compatible = "brcm,enetsw-port";
+ reg = <3>;
+ label = "fe4";
+ brcm,phy-id = <4>;
+ };
+};
+
&leds {
status = "okay";
diff --git a/configs/comtrend_ar5387un_ram_defconfig b/configs/comtrend_ar5387un_ram_defconfig
index f129870ca0..5ba401a441 100644
--- a/configs/comtrend_ar5387un_ram_defconfig
+++ b/configs/comtrend_ar5387un_ram_defconfig
@@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5387un"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
CONFIG_DM_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
@@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 23/28] bmips: bcm6362: add support for bcm6368-enet
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (21 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 22/28] bmips: enable ar-5387un enet support Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 24/28] bmips: enable dgnd3700v2 enet support Álvaro Fernández Rojas
` (5 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6362.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6362.dtsi b/arch/mips/dts/brcm,bcm6362.dtsi
index 94e7de096d..c77b80a4cc 100644
--- a/arch/mips/dts/brcm,bcm6362.dtsi
+++ b/arch/mips/dts/brcm,bcm6362.dtsi
@@ -224,5 +224,24 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10e00000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10e00000 0x10000>;
+ clocks = <&periph_clk BCM6362_CLK_SWPKT_USB>,
+ <&periph_clk BCM6362_CLK_SWPKT_SAR>,
+ <&periph_clk BCM6362_CLK_ROBOSW>;
+ resets = <&periph_rst BCM6362_RST_ENETSW>,
+ <&periph_rst BCM6362_RST_EPHY>;
+ dmas = <&iudma BCM6362_DMA_ENETSW_RX>,
+ <&iudma BCM6362_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <6>;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 24/28] bmips: enable dgnd3700v2 enet support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (22 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 23/28] bmips: bcm6362: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 25/28] bmips: bcm63268: add support for bcm6368-enet Álvaro Fernández Rojas
` (4 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/netgear,dgnd3700v2.dts | 14 ++++++++++++++
configs/netgear_dgnd3700v2_ram_defconfig | 8 +++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/netgear,dgnd3700v2.dts b/arch/mips/dts/netgear,dgnd3700v2.dts
index 322d1567ff..2b72491f0b 100644
--- a/arch/mips/dts/netgear,dgnd3700v2.dts
+++ b/arch/mips/dts/netgear,dgnd3700v2.dts
@@ -43,6 +43,20 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 4 {
+ compatible = "brcm,enetsw-port";
+ reg = <4>;
+ label = "rgmii";
+ brcm,phy-id = <0xff>;
+ speed = <1000>;
+ full-duplex;
+ bypass-link;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/netgear_dgnd3700v2_ram_defconfig b/configs/netgear_dgnd3700v2_ram_defconfig
index 1abc869856..0f3914fe7e 100644
--- a/configs/netgear_dgnd3700v2_ram_defconfig
+++ b/configs/netgear_dgnd3700v2_ram_defconfig
@@ -27,17 +27,23 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
-# CONFIG_CMD_NET is not set
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="netgear,dgnd3700v2"
+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
CONFIG_LED_BCM6328=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 25/28] bmips: bcm63268: add support for bcm6368-enet
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (23 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 24/28] bmips: enable dgnd3700v2 enet support Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 26/28] bmips: enable vr-3032u enet support Álvaro Fernández Rojas
` (3 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm63268.dtsi | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi
index c7ad83c306..f8a72ef535 100644
--- a/arch/mips/dts/brcm,bcm63268.dtsi
+++ b/arch/mips/dts/brcm,bcm63268.dtsi
@@ -230,5 +230,30 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10700000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10700000 0x10000>;
+ clocks = <&periph_clk BCM63268_CLK_GMAC>,
+ <&periph_clk BCM63268_CLK_ROBOSW>,
+ <&periph_clk BCM63268_CLK_ROBOSW250>,
+ <&timer_clk BCM63268_TCLK_EPHY1>,
+ <&timer_clk BCM63268_TCLK_EPHY2>,
+ <&timer_clk BCM63268_TCLK_EPHY3>,
+ <&timer_clk BCM63268_TCLK_GPHY>;
+ resets = <&periph_rst BCM63268_RST_ENETSW>,
+ <&periph_rst BCM63268_RST_EPHY>,
+ <&periph_rst BCM63268_RST_GPHY>;
+ dmas = <&iudma BCM63268_DMA_ENETSW_RX>,
+ <&iudma BCM63268_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,rgmii-override;
+ brcm,rgmii-timing;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 26/28] bmips: enable vr-3032u enet support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (24 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 25/28] bmips: bcm63268: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 27/28] bmips: bcm6318: add support for bcm6368-enet Álvaro Fernández Rojas
` (2 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,vr-3032u.dts | 32 ++++++++++++++++++++++++++++++++
configs/comtrend_vr3032u_ram_defconfig | 7 ++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,vr-3032u.dts b/arch/mips/dts/comtrend,vr-3032u.dts
index 8c6a4a1eac..512cb52de3 100644
--- a/arch/mips/dts/comtrend,vr-3032u.dts
+++ b/arch/mips/dts/comtrend,vr-3032u.dts
@@ -24,6 +24,38 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 0 {
+ compatible = "brcm,enetsw-port";
+ reg = <0>;
+ label = "fe2";
+ brcm,phy-id = <1>;
+ };
+
+ port at 1 {
+ compatible = "brcm,enetsw-port";
+ reg = <1>;
+ label = "fe3";
+ brcm,phy-id = <2>;
+ };
+
+ port at 2 {
+ compatible = "brcm,enetsw-port";
+ reg = <2>;
+ label = "fe4";
+ brcm,phy-id = <3>;
+ };
+
+ port at 3 {
+ compatible = "brcm,enetsw-port";
+ reg = <3>;
+ label = "fe1";
+ brcm,phy-id = <4>;
+ };
+};
+
&leds {
status = "okay";
brcm,serial-leds;
diff --git a/configs/comtrend_vr3032u_ram_defconfig b/configs/comtrend_vr3032u_ram_defconfig
index 1689eecec1..47f53998e1 100644
--- a/configs/comtrend_vr3032u_ram_defconfig
+++ b/configs/comtrend_vr3032u_ram_defconfig
@@ -26,15 +26,20 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,vr-3032u"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
CONFIG_DM_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
CONFIG_LED_BLINK=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 27/28] bmips: bcm6318: add support for bcm6368-enet
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (25 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 26/28] bmips: enable vr-3032u enet support Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-11-29 22:25 ` [U-Boot] [PATCH v10 28/28] bmips: enable ar-5315u enet support Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6318.dtsi | 19 +++++++++++++++++++
include/dt-bindings/clock/bcm6318-clock.h | 11 +++++++++++
2 files changed, 30 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6318.dtsi b/arch/mips/dts/brcm,bcm6318.dtsi
index d04b7cbb01..d678dab242 100644
--- a/arch/mips/dts/brcm,bcm6318.dtsi
+++ b/arch/mips/dts/brcm,bcm6318.dtsi
@@ -190,6 +190,25 @@
status = "disabled";
};
+ enet: ethernet at 10080000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10080000 0x8000>;
+ clocks = <&periph_clk BCM6318_CLK_ROBOSW250>,
+ <&periph_clk BCM6318_CLK_ROBOSW025>,
+ <&ubus_clk BCM6318_UCLK_ROBOSW>;
+ resets = <&periph_rst BCM6318_RST_ENETSW>,
+ <&periph_rst BCM6318_RST_EPHY>;
+ dmas = <&iudma BCM6318_DMA_ENETSW_RX>,
+ <&iudma BCM6318_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <5>;
+
+ status = "disabled";
+ };
+
iudma: dma-controller at 10088000 {
compatible = "brcm,bcm6368-iudma";
reg = <0x10088000 0x80>,
diff --git a/include/dt-bindings/clock/bcm6318-clock.h b/include/dt-bindings/clock/bcm6318-clock.h
index d5e13c5c2d..3f10448cef 100644
--- a/include/dt-bindings/clock/bcm6318-clock.h
+++ b/include/dt-bindings/clock/bcm6318-clock.h
@@ -33,4 +33,15 @@
#define BCM6318_CLK_AFE 29
#define BCM6318_CLK_QPROC 30
+#define BCM6318_UCLK_ADSL 0
+#define BCM6318_UCLK_ARB 1
+#define BCM6318_UCLK_MIPS 2
+#define BCM6318_UCLK_PCIE 3
+#define BCM6318_UCLK_PERIPH 4
+#define BCM6318_UCLK_PHYMIPS 5
+#define BCM6318_UCLK_ROBOSW 6
+#define BCM6318_UCLK_SAR 7
+#define BCM6318_UCLK_SDR 8
+#define BCM6318_UCLK_USB 9
+
#endif /* __DT_BINDINGS_CLOCK_BCM6318_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v10 28/28] bmips: enable ar-5315u enet support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (26 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 27/28] bmips: bcm6318: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-11-29 22:25 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-11-29 22:25 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,ar-5315u.dts | 32 ++++++++++++++++++++++++++++++++
configs/comtrend_ar5315u_ram_defconfig | 7 ++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,ar-5315u.dts b/arch/mips/dts/comtrend,ar-5315u.dts
index 45570189d0..eb60aaa8d5 100644
--- a/arch/mips/dts/comtrend,ar-5315u.dts
+++ b/arch/mips/dts/comtrend,ar-5315u.dts
@@ -24,6 +24,38 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 0 {
+ compatible = "brcm,enetsw-port";
+ reg = <0>;
+ label = "fe4";
+ brcm,phy-id = <1>;
+ };
+
+ port at 1 {
+ compatible = "brcm,enetsw-port";
+ reg = <1>;
+ label = "fe3";
+ brcm,phy-id = <2>;
+ };
+
+ port at 2 {
+ compatible = "brcm,enetsw-port";
+ reg = <2>;
+ label = "fe2";
+ brcm,phy-id = <3>;
+ };
+
+ port at 3 {
+ compatible = "brcm,enetsw-port";
+ reg = <3>;
+ label = "fe1";
+ brcm,phy-id = <4>;
+ };
+};
+
&leds {
status = "okay";
diff --git a/configs/comtrend_ar5315u_ram_defconfig b/configs/comtrend_ar5315u_ram_defconfig
index d9ef52e68d..1b8e4e43c4 100644
--- a/configs/comtrend_ar5315u_ram_defconfig
+++ b/configs/comtrend_ar5315u_ram_defconfig
@@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5315u"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
CONFIG_DM_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
@@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6318_USBH_PHY=y
CONFIG_BCM6328_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support
2018-11-29 22:25 ` [U-Boot] [PATCH v10 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (27 preceding siblings ...)
2018-11-29 22:25 ` [U-Boot] [PATCH v10 28/28] bmips: enable ar-5315u enet support Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 01/28] dma: add bcm6348-iudma support Álvaro Fernández Rojas
` (28 more replies)
28 siblings, 29 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
In 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...).
v11: Introduce change suggested by Daniel Schwierzeck:
- Avoid trimming ethernet FCS from DMA driver.
v10: Introduce changes suggested by Daniel Schwierzeck:
- Fix license identifiers.
bcm6348-iudma:
- Move DMAD_ST defines out of dma desc struct definition.
- Remove unneded aigned attribute from dma desc struct definition.
- Fill dma ring from consumer driver instead of allocating a new buffer.
- Correctly check clock/reset errors while probing.
- Switch to live DM live tree.
bcm6348-enet:
- Remove packet queue.
- Move dma_prepare_rcv_buf to free_pkt.
- Switch to live DM live tree.
bcm6368-enet:
- Remove packet queue.
- Move dma_prepare_rcv_buf to free_pkt.
- Pad packets smaller than ETH_ZLEN.
- Switch to live DM live tree.
v9: Separate generic dma channels support from bmips enet support
bcm6348-iudma:
- bcm6348_iudma_chan_stop: switch to mdelay when resetting channel.
- bcm6348_iudma_receive: track dirty dma descriptors and no longer trigger
dma rx channel.
- bcm6348_iudma_send: reorder to properly flush cache and set dma descriptor
config.
- bcm6348_iudma_prepare_rcv_buf: implemented to clear dirty dma descriptors.
bcm6348-enet:
- bcm6348_eth_recv: clear dirty dma descriptors only when packets are copied
from rx dma.
- bcm6348_eth_send: remove dma rx channel reset when sending packet.
bcm6368-enet:
- introduce rx packets caching functionality from bcm6348-eth to fix flow
control issues.
- code style fixes.
v8: Introduce bcm6368-enet driver support.
v5: Fix issues reported by Grygorii Strashko and other fixes:
- 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: Switch to live tree API.
v2: Fix bcm6348-iudma rx burst config.
Álvaro Fernández Rojas (28):
dma: add bcm6348-iudma support
bmips: bcm6338: add bcm6348-iudma support
bmips: bcm6348: add bcm6348-iudma support
bmips: bcm6358: add bcm6348-iudma support
bmips: bcm6368: add bcm6348-iudma support
bmips: bcm6328: add bcm6348-iudma support
bmips: bcm6362: add bcm6348-iudma support
bmips: bcm63268: add bcm6348-iudma support
bmips: bcm6318: add bcm6348-iudma support
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
net: add support for bcm6368-enet
bmips: bcm6368: add support for bcm6368-enet
bmips: enable wap-5813n enet support
bmips: bcm6328: add support for bcm6368-enet
bmips: enable ar-5387un enet support
bmips: bcm6362: add support for bcm6368-enet
bmips: enable dgnd3700v2 enet support
bmips: bcm63268: add support for bcm6368-enet
bmips: enable vr-3032u enet support
bmips: bcm6318: add support for bcm6368-enet
bmips: enable ar-5315u enet support
arch/mips/dts/brcm,bcm6318.dtsi | 38 ++
arch/mips/dts/brcm,bcm63268.dtsi | 38 ++
arch/mips/dts/brcm,bcm6328.dtsi | 30 ++
arch/mips/dts/brcm,bcm6338.dtsi | 29 ++
arch/mips/dts/brcm,bcm6348.dtsi | 42 ++
arch/mips/dts/brcm,bcm6358.dtsi | 46 +++
arch/mips/dts/brcm,bcm6362.dtsi | 32 ++
arch/mips/dts/brcm,bcm6368.dtsi | 32 ++
arch/mips/dts/comtrend,ar-5315u.dts | 32 ++
arch/mips/dts/comtrend,ar-5387un.dts | 32 ++
arch/mips/dts/comtrend,ct-5361.dts | 12 +
arch/mips/dts/comtrend,vr-3032u.dts | 32 ++
arch/mips/dts/comtrend,wap-5813n.dts | 14 +
arch/mips/dts/huawei,hg556a.dts | 12 +
arch/mips/dts/netgear,dgnd3700v2.dts | 14 +
arch/mips/dts/sagem,f at st1704.dts | 12 +
arch/mips/dts/sfr,nb4-ser.dts | 24 ++
configs/comtrend_ar5315u_ram_defconfig | 7 +-
configs/comtrend_ar5387un_ram_defconfig | 7 +-
configs/comtrend_ct5361_ram_defconfig | 8 +-
configs/comtrend_vr3032u_ram_defconfig | 7 +-
configs/comtrend_wap5813n_ram_defconfig | 8 +-
configs/huawei_hg556a_ram_defconfig | 8 +-
configs/netgear_dgnd3700v2_ram_defconfig | 8 +-
configs/sagem_f at st1704_ram_defconfig | 8 +-
configs/sfr_nb4-ser_ram_defconfig | 8 +-
drivers/dma/Kconfig | 9 +
drivers/dma/Makefile | 1 +
drivers/dma/bcm6348-iudma.c | 642 ++++++++++++++++++++++++++++++
drivers/net/Kconfig | 18 +
drivers/net/Makefile | 2 +
drivers/net/bcm6348-eth.c | 537 +++++++++++++++++++++++++
drivers/net/bcm6368-eth.c | 625 +++++++++++++++++++++++++++++
include/configs/bmips_common.h | 6 +-
include/dt-bindings/clock/bcm6318-clock.h | 11 +
include/dt-bindings/dma/bcm6318-dma.h | 14 +
include/dt-bindings/dma/bcm63268-dma.h | 14 +
include/dt-bindings/dma/bcm6328-dma.h | 14 +
include/dt-bindings/dma/bcm6338-dma.h | 14 +
include/dt-bindings/dma/bcm6348-dma.h | 16 +
include/dt-bindings/dma/bcm6358-dma.h | 16 +
include/dt-bindings/dma/bcm6362-dma.h | 14 +
include/dt-bindings/dma/bcm6368-dma.h | 14 +
43 files changed, 2497 insertions(+), 10 deletions(-)
create mode 100644 drivers/dma/bcm6348-iudma.c
create mode 100644 drivers/net/bcm6348-eth.c
create mode 100644 drivers/net/bcm6368-eth.c
create mode 100644 include/dt-bindings/dma/bcm6318-dma.h
create mode 100644 include/dt-bindings/dma/bcm63268-dma.h
create mode 100644 include/dt-bindings/dma/bcm6328-dma.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
create mode 100644 include/dt-bindings/dma/bcm6362-dma.h
create mode 100644 include/dt-bindings/dma/bcm6368-dma.h
--
2.11.0
^ permalink raw reply [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 01/28] dma: add bcm6348-iudma support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 02/28] bmips: bcm6338: " Álvaro Fernández Rojas
` (27 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
BCM6348 IUDMA controller is present on multiple BMIPS (BCM63xx) SoCs.
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
---
v11: Introduce change suggested by Daniel Schwierzeck:
- Avoid trimming ethernet FCS from DMA driver.
v10: Introduce changes suggested by Daniel Schwierzeck:
- Fix license identifiers.
- Move DMAD_ST defines out of dma desc struct definition.
- Remove unneded aigned attribute from dma desc struct definition.
- Fill dma ring from consumer driver instead of allocating a new buffer.
- Correctly check clock/reset errors while probing.
- Switch to live DM live tree.
v9: introduce dma_prepare_rcv_buf dma op:
- bcm6348_iudma_chan_stop: switch to mdelay when resetting channel.
- bcm6348_iudma_receive: track dirty dma descriptors and no longer trigger
dma rx channel.
- bcm6348_iudma_send: reorder to properly flush cache and set dma descriptor
config.
- bcm6348_iudma_prepare_rcv_buf: implemented to clear dirty dma descriptors.
v8: Introduce changes from Grygorii Strashko
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 | 642 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 652 insertions(+)
create mode 100644 drivers/dma/bcm6348-iudma.c
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 8a4162eccd..1820676d7a 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -26,6 +26,15 @@ config SANDBOX_DMA
Enable support for a test DMA uclass implementation. It stimulates
DMA transfer by simple copying data between channels.
+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
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index aff31f986a..b5f9147e0a 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -7,6 +7,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_SANDBOX_DMA) += sandbox-dma-test.o
obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o
diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c
new file mode 100644
index 0000000000..1d3c192cfe
--- /dev/null
+++ b/drivers/dma/bcm6348-iudma.c
@@ -0,0 +1,642 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/dma/bcm63xx-iudma.c:
+ * Copyright (C) 2015 Simon Arlott <simon@fire.lp0.eu>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h:
+ * Copyright (C) 2000-2010 Broadcom Corporation
+ *
+ * Derived from bcm963xx_4.12L.06B_consumer/bcmdrivers/opensource/net/enet/impl4/bcmenet.c:
+ * Copyright (C) 2010 Broadcom Corporation
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dma-uclass.h>
+#include <memalign.h>
+#include <reset.h>
+#include <asm/io.h>
+
+#define DMA_RX_DESC 6
+#define DMA_TX_DESC 1
+
+/* DMA Channels */
+#define DMA_CHAN_FLOWC(x) ((x) >> 1)
+#define DMA_CHAN_MAX 16
+#define DMA_CHAN_SIZE 0x10
+#define DMA_CHAN_TOUT 500
+
+/* DMA Global Configuration register */
+#define DMA_CFG_REG 0x00
+#define DMA_CFG_ENABLE_SHIFT 0
+#define DMA_CFG_ENABLE_MASK (1 << DMA_CFG_ENABLE_SHIFT)
+#define DMA_CFG_FLOWC_ENABLE(x) BIT(DMA_CHAN_FLOWC(x) + 1)
+#define DMA_CFG_NCHANS_SHIFT 24
+#define DMA_CFG_NCHANS_MASK (0xf << DMA_CFG_NCHANS_SHIFT)
+
+/* DMA Global Flow Control registers */
+#define DMA_FLOWC_THR_LO_REG(x) (0x04 + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_THR_HI_REG(x) (0x08 + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_ALLOC_REG(x) (0x0c + DMA_CHAN_FLOWC(x) * 0x0c)
+#define DMA_FLOWC_ALLOC_FORCE_SHIFT 31
+#define DMA_FLOWC_ALLOC_FORCE_MASK (1 << DMA_FLOWC_ALLOC_FORCE_SHIFT)
+
+/* DMA Global Reset register */
+#define DMA_RST_REG 0x34
+#define DMA_RST_CHAN_SHIFT 0
+#define DMA_RST_CHAN_MASK(x) (1 << x)
+
+/* DMA Channel Configuration register */
+#define DMAC_CFG_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
+#define DMAC_CFG_ENABLE_SHIFT 0
+#define DMAC_CFG_ENABLE_MASK (1 << DMAC_CFG_ENABLE_SHIFT)
+#define DMAC_CFG_PKT_HALT_SHIFT 1
+#define DMAC_CFG_PKT_HALT_MASK (1 << DMAC_CFG_PKT_HALT_SHIFT)
+#define DMAC_CFG_BRST_HALT_SHIFT 2
+#define DMAC_CFG_BRST_HALT_MASK (1 << DMAC_CFG_BRST_HALT_SHIFT)
+
+/* DMA Channel Max Burst Length register */
+#define DMAC_BURST_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
+
+/* DMA SRAM Descriptor Ring Start register */
+#define DMAS_RSTART_REG(x) (DMA_CHAN_SIZE * (x) + 0x00)
+
+/* DMA SRAM State/Bytes done/ring offset register */
+#define DMAS_STATE_DATA_REG(x) (DMA_CHAN_SIZE * (x) + 0x04)
+
+/* DMA SRAM Buffer Descriptor status and length register */
+#define DMAS_DESC_LEN_STATUS_REG(x) (DMA_CHAN_SIZE * (x) + 0x08)
+
+/* DMA SRAM Buffer Descriptor status and length register */
+#define DMAS_DESC_BASE_BUFPTR_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c)
+
+/* DMA Descriptor Status */
+#define DMAD_ST_CRC_SHIFT 8
+#define DMAD_ST_CRC_MASK (1 << DMAD_ST_CRC_SHIFT)
+#define DMAD_ST_WRAP_SHIFT 12
+#define DMAD_ST_WRAP_MASK (1 << DMAD_ST_WRAP_SHIFT)
+#define DMAD_ST_SOP_SHIFT 13
+#define DMAD_ST_SOP_MASK (1 << DMAD_ST_SOP_SHIFT)
+#define DMAD_ST_EOP_SHIFT 14
+#define DMAD_ST_EOP_MASK (1 << DMAD_ST_EOP_SHIFT)
+#define DMAD_ST_OWN_SHIFT 15
+#define DMAD_ST_OWN_MASK (1 << DMAD_ST_OWN_SHIFT)
+
+#define DMAD6348_ST_OV_ERR_SHIFT 0
+#define DMAD6348_ST_OV_ERR_MASK (1 << DMAD6348_ST_OV_ERR_SHIFT)
+#define DMAD6348_ST_CRC_ERR_SHIFT 1
+#define DMAD6348_ST_CRC_ERR_MASK (1 << DMAD6348_ST_CRC_ERR_SHIFT)
+#define DMAD6348_ST_RX_ERR_SHIFT 2
+#define DMAD6348_ST_RX_ERR_MASK (1 << DMAD6348_ST_RX_ERR_SHIFT)
+#define DMAD6348_ST_OS_ERR_SHIFT 4
+#define DMAD6348_ST_OS_ERR_MASK (1 << DMAD6348_ST_OS_ERR_SHIFT)
+#define DMAD6348_ST_UN_ERR_SHIFT 9
+#define DMAD6348_ST_UN_ERR_MASK (1 << DMAD6348_ST_UN_ERR_SHIFT)
+
+struct bcm6348_dma_desc {
+ uint16_t length;
+ uint16_t status;
+ uint32_t address;
+};
+
+struct bcm6348_chan_priv {
+ void __iomem *dma_ring;
+ uint8_t dma_ring_size;
+ uint8_t desc_id;
+ uint8_t desc_cnt;
+ bool *busy_desc;
+ bool running;
+};
+
+struct bcm6348_iudma_hw {
+ uint16_t err_mask;
+};
+
+struct bcm6348_iudma_priv {
+ const struct bcm6348_iudma_hw *hw;
+ void __iomem *base;
+ void __iomem *chan;
+ void __iomem *sram;
+ struct bcm6348_chan_priv **ch_priv;
+ uint8_t n_channels;
+};
+
+static inline bool bcm6348_iudma_chan_is_rx(uint8_t ch)
+{
+ return !(ch & 1);
+}
+
+static inline void bcm6348_iudma_fdc(void *ptr, ulong size)
+{
+ ulong start = (ulong) ptr;
+
+ flush_dcache_range(start, start + size);
+}
+
+static inline void bcm6348_iudma_idc(void *ptr, ulong size)
+{
+ ulong start = (ulong) ptr;
+
+ invalidate_dcache_range(start, start + size);
+}
+
+static void bcm6348_iudma_chan_stop(struct bcm6348_iudma_priv *priv,
+ uint8_t ch)
+{
+ unsigned int timeout = DMA_CHAN_TOUT;
+
+ do {
+ uint32_t cfg, halt;
+
+ if (timeout > DMA_CHAN_TOUT / 2)
+ halt = DMAC_CFG_PKT_HALT_MASK;
+ else
+ halt = DMAC_CFG_BRST_HALT_MASK;
+
+ /* try to stop dma channel */
+ writel_be(halt, priv->chan + DMAC_CFG_REG(ch));
+ mb();
+
+ /* check if channel was stopped */
+ cfg = readl_be(priv->chan + DMAC_CFG_REG(ch));
+ if (!(cfg & DMAC_CFG_ENABLE_MASK))
+ break;
+
+ udelay(1);
+ } while (--timeout);
+
+ if (!timeout)
+ pr_err("unable to stop channel %u\n", ch);
+
+ /* reset dma channel */
+ setbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
+ mb();
+ clrbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch));
+}
+
+static int bcm6348_iudma_disable(struct dma *dma)
+{
+ struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+ struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+
+ /* stop dma channel */
+ bcm6348_iudma_chan_stop(priv, dma->id);
+
+ /* dma flow control */
+ if (bcm6348_iudma_chan_is_rx(dma->id))
+ writel_be(DMA_FLOWC_ALLOC_FORCE_MASK,
+ DMA_FLOWC_ALLOC_REG(dma->id));
+
+ /* init channel config */
+ ch_priv->running = false;
+ ch_priv->desc_id = 0;
+ if (bcm6348_iudma_chan_is_rx(dma->id))
+ ch_priv->desc_cnt = 0;
+ else
+ ch_priv->desc_cnt = ch_priv->dma_ring_size;
+
+ return 0;
+}
+
+static int bcm6348_iudma_enable(struct dma *dma)
+{
+ const 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 = ch_priv->dma_ring;
+ uint8_t i;
+
+ /* dma ring init */
+ for (i = 0; i < ch_priv->desc_cnt; i++) {
+ if (bcm6348_iudma_chan_is_rx(dma->id)) {
+ ch_priv->busy_desc[i] = false;
+ dma_desc->status |= DMAD_ST_OWN_MASK;
+ } else {
+ dma_desc->status = 0;
+ dma_desc->length = 0;
+ dma_desc->address = 0;
+ }
+
+ if (i == ch_priv->desc_cnt - 1)
+ dma_desc->status |= DMAD_ST_WRAP_MASK;
+
+ dma_desc++;
+ }
+
+ /* init to first descriptor */
+ ch_priv->desc_id = 0;
+
+ /* force cache writeback */
+ bcm6348_iudma_fdc(ch_priv->dma_ring,
+ sizeof(*dma_desc) * ch_priv->desc_cnt);
+
+ /* 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->desc_cnt / 3;
+ writel_be(val, priv->base + DMA_FLOWC_THR_LO_REG(dma->id));
+
+ val = (ch_priv->desc_cnt * 2) / 3;
+ writel_be(val, priv->base + DMA_FLOWC_THR_HI_REG(dma->id));
+
+ writel_be(0, priv->base + DMA_FLOWC_ALLOC_REG(dma->id));
+ }
+
+ /* set dma max burst */
+ writel_be(ch_priv->desc_cnt,
+ priv->chan + DMAC_BURST_REG(dma->id));
+
+ /* kick rx dma channel */
+ if (bcm6348_iudma_chan_is_rx(dma->id))
+ setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
+ DMAC_CFG_ENABLE_MASK);
+
+ /* channel is now enabled */
+ ch_priv->running = true;
+
+ return 0;
+}
+
+static int bcm6348_iudma_request(struct dma *dma)
+{
+ const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+ struct bcm6348_chan_priv *ch_priv;
+
+ /* check if channel is valid */
+ if (dma->id >= priv->n_channels)
+ return -ENODEV;
+
+ /* alloc channel private data */
+ priv->ch_priv[dma->id] = calloc(1, sizeof(struct bcm6348_chan_priv));
+ if (!priv->ch_priv[dma->id])
+ return -ENOMEM;
+ ch_priv = priv->ch_priv[dma->id];
+
+ /* alloc dma ring */
+ if (bcm6348_iudma_chan_is_rx(dma->id))
+ ch_priv->dma_ring_size = DMA_RX_DESC;
+ else
+ ch_priv->dma_ring_size = DMA_TX_DESC;
+
+ ch_priv->dma_ring =
+ malloc_cache_aligned(sizeof(struct bcm6348_dma_desc) *
+ ch_priv->dma_ring_size);
+ if (!ch_priv->dma_ring)
+ return -ENOMEM;
+
+ /* init channel config */
+ ch_priv->running = false;
+ ch_priv->desc_id = 0;
+ if (bcm6348_iudma_chan_is_rx(dma->id)) {
+ ch_priv->desc_cnt = 0;
+ ch_priv->busy_desc = calloc(ch_priv->desc_cnt, sizeof(bool));
+ } else {
+ ch_priv->desc_cnt = ch_priv->dma_ring_size;
+ ch_priv->busy_desc = NULL;
+ }
+
+ return 0;
+}
+
+static int bcm6348_iudma_receive(struct dma *dma, void **dst, void *metadata)
+{
+ const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+ const struct bcm6348_iudma_hw *hw = priv->hw;
+ struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+ struct bcm6348_dma_desc *dma_desc = dma_desc = ch_priv->dma_ring;
+ int ret;
+
+ /* get dma ring descriptor address */
+ dma_desc += ch_priv->desc_id;
+
+ /* invalidate cache data */
+ bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc));
+
+ /* check dma own */
+ if (dma_desc->status & DMAD_ST_OWN_MASK)
+ return -EAGAIN;
+
+ /* check pkt */
+ if (!(dma_desc->status & DMAD_ST_EOP_MASK) ||
+ !(dma_desc->status & DMAD_ST_SOP_MASK) ||
+ (dma_desc->status & hw->err_mask)) {
+ pr_err("invalid pkt received (ch=%ld desc=%u) (st=%04x)\n",
+ dma->id, ch_priv->desc_id, dma_desc->status);
+ ret = -EAGAIN;
+ } else {
+ /* set dma buffer address */
+ *dst = phys_to_virt(dma_desc->address);
+
+ /* invalidate cache data */
+ bcm6348_iudma_idc(*dst, dma_desc->length);
+
+ /* return packet length */
+ ret = dma_desc->length;
+ }
+
+ /* busy dma descriptor */
+ ch_priv->busy_desc[ch_priv->desc_id] = true;
+
+ /* increment dma descriptor */
+ ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt;
+
+ return ret;
+}
+
+static int bcm6348_iudma_send(struct dma *dma, void *src, size_t len,
+ void *metadata)
+{
+ const 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;
+ uint16_t status;
+
+ /* flush cache */
+ bcm6348_iudma_fdc(src, len);
+
+ /* get dma ring descriptor address */
+ dma_desc = ch_priv->dma_ring;
+ dma_desc += ch_priv->desc_id;
+
+ /* config dma descriptor */
+ status = (DMAD_ST_OWN_MASK |
+ DMAD_ST_EOP_MASK |
+ DMAD_ST_CRC_MASK |
+ DMAD_ST_SOP_MASK);
+ if (ch_priv->desc_id == ch_priv->desc_cnt - 1)
+ status |= DMAD_ST_WRAP_MASK;
+
+ /* set dma descriptor */
+ dma_desc->address = virt_to_phys(src);
+ dma_desc->length = len;
+ dma_desc->status = status;
+
+ /* flush cache */
+ bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc));
+
+ /* kick tx dma channel */
+ setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK);
+
+ /* poll dma status */
+ do {
+ /* invalidate cache */
+ bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc));
+
+ if (!(dma_desc->status & DMAD_ST_OWN_MASK))
+ break;
+ } while(1);
+
+ /* increment dma descriptor */
+ ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt;
+
+ return 0;
+}
+
+static int bcm6348_iudma_free_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+ const 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 = ch_priv->dma_ring;
+ uint16_t status;
+ uint8_t i;
+ u32 cfg;
+
+ /* get dirty dma descriptor */
+ for (i = 0; i < ch_priv->desc_cnt; i++) {
+ if (phys_to_virt(dma_desc->address) == dst)
+ break;
+
+ dma_desc++;
+ }
+
+ /* dma descriptor not found */
+ if (i == ch_priv->desc_cnt) {
+ pr_err("dirty dma descriptor not found\n");
+ return -ENOENT;
+ }
+
+ /* invalidate cache */
+ bcm6348_iudma_idc(ch_priv->dma_ring,
+ sizeof(*dma_desc) * ch_priv->desc_cnt);
+
+ /* free dma descriptor */
+ ch_priv->busy_desc[i] = false;
+
+ status = DMAD_ST_OWN_MASK;
+ if (i == ch_priv->desc_cnt - 1)
+ status |= DMAD_ST_WRAP_MASK;
+
+ dma_desc->status |= status;
+ dma_desc->length = PKTSIZE_ALIGN;
+
+ /* tell dma we allocated one buffer */
+ writel_be(1, DMA_FLOWC_ALLOC_REG(dma->id));
+
+ /* flush cache */
+ bcm6348_iudma_fdc(ch_priv->dma_ring,
+ sizeof(*dma_desc) * ch_priv->desc_cnt);
+
+ /* kick rx dma channel if disabled */
+ cfg = readl_be(priv->chan + DMAC_CFG_REG(dma->id));
+ if (!(cfg & DMAC_CFG_ENABLE_MASK))
+ setbits_be32(priv->chan + DMAC_CFG_REG(dma->id),
+ DMAC_CFG_ENABLE_MASK);
+
+ return 0;
+}
+
+static int bcm6348_iudma_add_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+ const 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 = ch_priv->dma_ring;
+
+ /* no more dma descriptors available */
+ if (ch_priv->desc_cnt == ch_priv->dma_ring_size) {
+ pr_err("max number of buffers reached\n");
+ return -EINVAL;
+ }
+
+ /* get next dma descriptor */
+ dma_desc += ch_priv->desc_cnt;
+
+ /* init dma descriptor */
+ dma_desc->address = virt_to_phys(dst);
+ dma_desc->length = size;
+ dma_desc->status = 0;
+
+ /* flush cache */
+ bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc));
+
+ /* increment dma descriptors */
+ ch_priv->desc_cnt++;
+
+ return 0;
+}
+
+static int bcm6348_iudma_prepare_rcv_buf(struct dma *dma, void *dst,
+ size_t size)
+{
+ const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev);
+ struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id];
+
+ /* only add new rx buffers if channel isn't running */
+ if (ch_priv->running)
+ return bcm6348_iudma_free_rcv_buf(dma, dst, size);
+ else
+ return bcm6348_iudma_add_rcv_buf(dma, dst, size);
+}
+
+static const struct dma_ops bcm6348_iudma_ops = {
+ .disable = bcm6348_iudma_disable,
+ .enable = bcm6348_iudma_enable,
+ .prepare_rcv_buf = bcm6348_iudma_prepare_rcv_buf,
+ .request = bcm6348_iudma_request,
+ .receive = bcm6348_iudma_receive,
+ .send = bcm6348_iudma_send,
+};
+
+static const struct bcm6348_iudma_hw bcm6348_hw = {
+ .err_mask = (DMAD6348_ST_OV_ERR_MASK |
+ DMAD6348_ST_CRC_ERR_MASK |
+ DMAD6348_ST_RX_ERR_MASK |
+ DMAD6348_ST_OS_ERR_MASK |
+ DMAD6348_ST_UN_ERR_MASK),
+};
+
+static const struct bcm6348_iudma_hw bcm6368_hw = {
+ .err_mask = 0,
+};
+
+static const struct udevice_id bcm6348_iudma_ids[] = {
+ {
+ .compatible = "brcm,bcm6348-iudma",
+ .data = (ulong)&bcm6348_hw,
+ }, {
+ .compatible = "brcm,bcm6368-iudma",
+ .data = (ulong)&bcm6368_hw,
+ }, { /* sentinel */ }
+};
+
+static int bcm6348_iudma_probe(struct udevice *dev)
+{
+ struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct bcm6348_iudma_priv *priv = dev_get_priv(dev);
+ const struct bcm6348_iudma_hw *hw =
+ (const struct bcm6348_iudma_hw *)dev_get_driver_data(dev);
+ uint8_t ch;
+ int i;
+
+ uc_priv->supported = (DMA_SUPPORTS_DEV_TO_MEM |
+ DMA_SUPPORTS_MEM_TO_DEV);
+ priv->hw = hw;
+
+ /* dma global base address */
+ priv->base = dev_remap_addr_name(dev, "dma");
+ if (!priv->base)
+ return -EINVAL;
+
+ /* dma channels base address */
+ priv->chan = dev_remap_addr_name(dev, "dma-channels");
+ if (!priv->chan)
+ return -EINVAL;
+
+ /* dma sram base address */
+ priv->sram = dev_remap_addr_name(dev, "dma-sram");
+ if (!priv->sram)
+ return -EINVAL;
+
+ /* get number of channels */
+ priv->n_channels = dev_read_u32_default(dev, "dma-channels", 8);
+ if (priv->n_channels > DMA_CHAN_MAX)
+ 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;
+
+ ret = clk_enable(&clk);
+ if (ret < 0) {
+ pr_err("error enabling clock %d\n", i);
+ return ret;
+ }
+
+ ret = clk_free(&clk);
+ if (ret < 0) {
+ pr_err("error freeing clock %d\n", i);
+ return ret;
+ }
+ }
+
+ /* 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;
+
+ ret = reset_deassert(&reset);
+ if (ret < 0) {
+ pr_err("error deasserting reset %d\n", i);
+ return ret;
+ }
+
+ ret = reset_free(&reset);
+ if (ret < 0) {
+ pr_err("error freeing reset %d\n", i);
+ return ret;
+ }
+ }
+
+ /* disable dma controller */
+ clrbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
+
+ /* alloc channel private data pointers */
+ priv->ch_priv = calloc(priv->n_channels,
+ sizeof(struct bcm6348_chan_priv*));
+ if (!priv->ch_priv)
+ return -ENOMEM;
+
+ /* stop dma channels */
+ for (ch = 0; ch < priv->n_channels; ch++)
+ bcm6348_iudma_chan_stop(priv, ch);
+
+ /* enable dma controller */
+ setbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(bcm6348_iudma) = {
+ .name = "bcm6348_iudma",
+ .id = UCLASS_DMA,
+ .of_match = bcm6348_iudma_ids,
+ .ops = &bcm6348_iudma_ops,
+ .priv_auto_alloc_size = sizeof(struct bcm6348_iudma_priv),
+ .probe = bcm6348_iudma_probe,
+};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 02/28] bmips: bcm6338: add bcm6348-iudma support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 01/28] dma: add bcm6348-iudma support Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 03/28] bmips: bcm6348: " Álvaro Fernández Rojas
` (26 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: fix license identifiers
v9: no changes
v8: no changes
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 | 14 ++++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6338-dma.h
diff --git a/arch/mips/dts/brcm,bcm6338.dtsi b/arch/mips/dts/brcm,bcm6338.dtsi
index bbd58cf803..990355481c 100644
--- a/arch/mips/dts/brcm,bcm6338.dtsi
+++ b/arch/mips/dts/brcm,bcm6338.dtsi
@@ -4,6 +4,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"
@@ -130,5 +131,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>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6338-dma.h b/include/dt-bindings/dma/bcm6338-dma.h
new file mode 100644
index 0000000000..f2e0b20444
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6338-dma.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#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 */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 03/28] bmips: bcm6348: add bcm6348-iudma support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 01/28] dma: add bcm6348-iudma support Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 02/28] bmips: bcm6338: " Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 04/28] bmips: bcm6358: " Álvaro Fernández Rojas
` (25 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: fix license identifiers
v9: no changes
v8: no changes
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 | 16 ++++++++++++++++
2 files changed, 32 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6348-dma.h
diff --git a/arch/mips/dts/brcm,bcm6348.dtsi b/arch/mips/dts/brcm,bcm6348.dtsi
index cc80bbc808..875de232ca 100644
--- a/arch/mips/dts/brcm,bcm6348.dtsi
+++ b/arch/mips/dts/brcm,bcm6348.dtsi
@@ -4,6 +4,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"
@@ -159,5 +160,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>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6348-dma.h b/include/dt-bindings/dma/bcm6348-dma.h
new file mode 100644
index 0000000000..36c2ffd412
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6348-dma.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#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 */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 04/28] bmips: bcm6358: add bcm6348-iudma support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (2 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 03/28] bmips: bcm6348: " Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 05/28] bmips: bcm6368: " Álvaro Fernández Rojas
` (24 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: fix license identifiers
v9: no changes
v8: no changes
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 | 16 ++++++++++++++++
2 files changed, 34 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6358-dma.h
diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi
index 0617b46e92..5605723e83 100644
--- a/arch/mips/dts/brcm,bcm6358.dtsi
+++ b/arch/mips/dts/brcm,bcm6358.dtsi
@@ -4,6 +4,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"
@@ -190,5 +191,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>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6358-dma.h b/include/dt-bindings/dma/bcm6358-dma.h
new file mode 100644
index 0000000000..3118b9da0a
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6358-dma.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#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 */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 05/28] bmips: bcm6368: add bcm6348-iudma support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (3 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 04/28] bmips: bcm6358: " Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 06/28] bmips: bcm6328: " Álvaro Fernández Rojas
` (23 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: fix license identifiers
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6368.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm6368-dma.h | 14 ++++++++++++++
2 files changed, 27 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6368-dma.h
diff --git a/arch/mips/dts/brcm,bcm6368.dtsi b/arch/mips/dts/brcm,bcm6368.dtsi
index 65d769ab4f..30047f6360 100644
--- a/arch/mips/dts/brcm,bcm6368.dtsi
+++ b/arch/mips/dts/brcm,bcm6368.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6368-clock.h>
+#include <dt-bindings/dma/bcm6368-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/reset/bcm6368-reset.h>
#include "skeleton.dtsi"
@@ -192,5 +193,17 @@
status = "disabled";
};
+
+ iudma: dma-controller at 10006800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x10006800 0x80>,
+ <0x10006a00 0x80>,
+ <0x10006c00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6368-dma.h b/include/dt-bindings/dma/bcm6368-dma.h
new file mode 100644
index 0000000000..36c6caa0e1
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6368-dma.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6368_H
+#define __DT_BINDINGS_DMA_BCM6368_H
+
+#define BCM6368_DMA_ENETSW_RX 0
+#define BCM6368_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6368_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 06/28] bmips: bcm6328: add bcm6348-iudma support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (4 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 05/28] bmips: bcm6368: " Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 07/28] bmips: bcm6362: " Álvaro Fernández Rojas
` (22 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: fix license identifiers
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6328.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm6328-dma.h | 14 ++++++++++++++
2 files changed, 27 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6328-dma.h
diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi
index e00a2950e2..6fa49e22bb 100644
--- a/arch/mips/dts/brcm,bcm6328.dtsi
+++ b/arch/mips/dts/brcm,bcm6328.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6328-clock.h>
+#include <dt-bindings/dma/bcm6328-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm6328-power-domain.h>
#include <dt-bindings/reset/bcm6328-reset.h>
@@ -187,5 +188,17 @@
reg = <0x10003000 0x864>;
u-boot,dm-pre-reloc;
};
+
+ iudma: dma-controller at 1000d800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x1000d800 0x80>,
+ <0x1000da00 0x80>,
+ <0x1000dc00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6328-dma.h b/include/dt-bindings/dma/bcm6328-dma.h
new file mode 100644
index 0000000000..7494df2feb
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6328-dma.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6328_H
+#define __DT_BINDINGS_DMA_BCM6328_H
+
+#define BCM6328_DMA_ENETSW_RX 0
+#define BCM6328_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6328_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 07/28] bmips: bcm6362: add bcm6348-iudma support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (5 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 06/28] bmips: bcm6328: " Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 08/28] bmips: bcm63268: " Álvaro Fernández Rojas
` (21 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: fix license identifiers
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6362.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm6362-dma.h | 14 ++++++++++++++
2 files changed, 27 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6362-dma.h
diff --git a/arch/mips/dts/brcm,bcm6362.dtsi b/arch/mips/dts/brcm,bcm6362.dtsi
index 3047b82b21..94e7de096d 100644
--- a/arch/mips/dts/brcm,bcm6362.dtsi
+++ b/arch/mips/dts/brcm,bcm6362.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6362-clock.h>
+#include <dt-bindings/dma/bcm6362-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm6362-power-domain.h>
#include <dt-bindings/reset/bcm6362-reset.h>
@@ -211,5 +212,17 @@
reg = <0x10003000 0x864>;
u-boot,dm-pre-reloc;
};
+
+ iudma: dma-controller at 1000d800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x1000d800 0x80>,
+ <0x1000da00 0x80>,
+ <0x1000dc00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6362-dma.h b/include/dt-bindings/dma/bcm6362-dma.h
new file mode 100644
index 0000000000..1e62236daa
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6362-dma.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6362_H
+#define __DT_BINDINGS_DMA_BCM6362_H
+
+#define BCM6362_DMA_ENETSW_RX 0
+#define BCM6362_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6362_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 08/28] bmips: bcm63268: add bcm6348-iudma support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (6 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 07/28] bmips: bcm6362: " Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 09/28] bmips: bcm6318: " Álvaro Fernández Rojas
` (20 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: fix license identifiers
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm63268.dtsi | 13 +++++++++++++
include/dt-bindings/dma/bcm63268-dma.h | 14 ++++++++++++++
2 files changed, 27 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm63268-dma.h
diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi
index 62c440e675..c7ad83c306 100644
--- a/arch/mips/dts/brcm,bcm63268.dtsi
+++ b/arch/mips/dts/brcm,bcm63268.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm63268-clock.h>
+#include <dt-bindings/dma/bcm63268-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm63268-power-domain.h>
#include <dt-bindings/reset/bcm63268-reset.h>
@@ -217,5 +218,17 @@
reg = <0x10003000 0x894>;
u-boot,dm-pre-reloc;
};
+
+ iudma: dma-controller at 1000d800 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x1000d800 0x80>,
+ <0x1000da00 0x80>,
+ <0x1000dc00 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm63268-dma.h b/include/dt-bindings/dma/bcm63268-dma.h
new file mode 100644
index 0000000000..7d027119e6
--- /dev/null
+++ b/include/dt-bindings/dma/bcm63268-dma.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM63268_H
+#define __DT_BINDINGS_DMA_BCM63268_H
+
+#define BCM63268_DMA_ENETSW_RX 0
+#define BCM63268_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM63268_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 09/28] bmips: bcm6318: add bcm6348-iudma support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (7 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 08/28] bmips: bcm63268: " Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 10/28] net: add support for bcm6348-enet Álvaro Fernández Rojas
` (19 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: fix license identifiers
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6318.dtsi | 19 +++++++++++++++++++
include/dt-bindings/dma/bcm6318-dma.h | 14 ++++++++++++++
2 files changed, 33 insertions(+)
create mode 100644 include/dt-bindings/dma/bcm6318-dma.h
diff --git a/arch/mips/dts/brcm,bcm6318.dtsi b/arch/mips/dts/brcm,bcm6318.dtsi
index f75988be12..d04b7cbb01 100644
--- a/arch/mips/dts/brcm,bcm6318.dtsi
+++ b/arch/mips/dts/brcm,bcm6318.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/bcm6318-clock.h>
+#include <dt-bindings/dma/bcm6318-dma.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/power-domain/bcm6318-power-domain.h>
#include <dt-bindings/reset/bcm6318-reset.h>
@@ -54,6 +55,12 @@
reg = <0x10000004 0x4>;
#clock-cells = <1>;
};
+
+ ubus_clk: ubus-clk {
+ compatible = "brcm,bcm6345-clk";
+ reg = <0x10000008 0x4>;
+ #clock-cells = <1>;
+ };
};
ubus {
@@ -182,5 +189,17 @@
status = "disabled";
};
+
+ iudma: dma-controller at 10088000 {
+ compatible = "brcm,bcm6368-iudma";
+ reg = <0x10088000 0x80>,
+ <0x10088200 0x80>,
+ <0x10088400 0x80>;
+ reg-names = "dma",
+ "dma-channels",
+ "dma-sram";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
};
};
diff --git a/include/dt-bindings/dma/bcm6318-dma.h b/include/dt-bindings/dma/bcm6318-dma.h
new file mode 100644
index 0000000000..ad7c5ac2df
--- /dev/null
+++ b/include/dt-bindings/dma/bcm6318-dma.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+ */
+
+#ifndef __DT_BINDINGS_DMA_BCM6318_H
+#define __DT_BINDINGS_DMA_BCM6318_H
+
+#define BCM6318_DMA_ENETSW_RX 0
+#define BCM6318_DMA_ENETSW_TX 1
+
+#endif /* __DT_BINDINGS_DMA_BCM6318_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 10/28] net: add support for bcm6348-enet
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (8 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 09/28] bmips: bcm6318: " Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 11/28] bmips: bcm6338: " Álvaro Fernández Rojas
` (18 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
---
v11: no changes
v10: Introduce changes suggested by Daniel Schwierzeck:
- Fix license identifiers.
- Remove packet queue.
- Move dma_prepare_rcv_buf to free_pkt.
- Switch to live DM live tree.
v9: use dma_prepare_rcv_buf and remove dma rx channel reset:
- bcm6348_eth_recv: clear dirty dma descriptors only when packets are copied
from rx dma.
- bcm6348_eth_send: remove dma rx channel reset when sending packet.
v8: Introduce changes from Grygorii Strashko
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 | 537 +++++++++++++++++++++++++++++++++++++++++
include/configs/bmips_common.h | 6 +-
4 files changed, 553 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/bcm6348-eth.c
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 8fb365fc5d..2b7cec8804 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -72,6 +72,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
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 99056aa041..2647d4dd23 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -6,6 +6,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
diff --git a/drivers/net/bcm6348-eth.c b/drivers/net/bcm6348-eth.c
new file mode 100644
index 0000000000..7100e68bd2
--- /dev/null
+++ b/drivers/net/bcm6348-eth.c
@@ -0,0 +1,537 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#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;
+ /* DMA */
+ struct dma rx_dma;
+ struct dma tx_dma;
+ /* PHY */
+ int phy_id;
+ struct phy_device *phy_dev;
+};
+
+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("%s: error disabling emac\n", __func__);
+}
+
+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("%s: error resetting emac\n", __func__);
+}
+
+static int bcm6348_eth_free_pkt(struct udevice *dev, uchar *packet, int len)
+{
+ struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+
+ return dma_prepare_rcv_buf(&priv->rx_dma, packet, len);
+}
+
+static int bcm6348_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+
+ return dma_receive(&priv->rx_dma, (void**)packetp, NULL);
+}
+
+static int bcm6348_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct bcm6348_eth_priv *priv = dev_get_priv(dev);
+
+ return dma_send(&priv->tx_dma, packet, length, NULL);
+}
+
+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;
+
+ /* prepare rx dma buffers */
+ for (i = 0; i < ETH_RX_DESC; i++) {
+ ret = dma_prepare_rcv_buf(&priv->rx_dma, net_rx_packets[i],
+ PKTSIZE_ALIGN);
+ if (ret < 0)
+ break;
+ }
+
+ /* 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("%s: could not initialize phy\n", __func__);
+ return ret;
+ }
+
+ if (!priv->phy_dev->link) {
+ pr_err("%s: no phy link\n", __func__);
+ 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) & ETH_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);
+ struct ofnode_phandle_args phy;
+ const char *phy_mode;
+ int ret, i;
+
+ /* get base address */
+ priv->base = dev_remap_addr(dev);
+ if (!priv->base)
+ return -EINVAL;
+ pdata->iobase = (phys_addr_t) priv->base;
+
+ /* get phy mode */
+ pdata->phy_interface = PHY_INTERFACE_MODE_NONE;
+ phy_mode = dev_read_string(dev, "phy-mode");
+ 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 */
+ if (dev_read_phandle_with_args(dev, "phy", NULL, 0, 0, &phy))
+ return -ENOENT;
+ priv->phy_id = ofnode_read_u32_default(phy.node, "reg", -1);
+
+ /* 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;
+
+ ret = clk_enable(&clk);
+ if (ret < 0) {
+ pr_err("%s: error enabling clock %d\n", __func__, i);
+ return ret;
+ }
+
+ ret = clk_free(&clk);
+ if (ret < 0) {
+ pr_err("%s: error freeing clock %d\n", __func__, i);
+ return ret;
+ }
+ }
+
+ /* 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;
+
+ ret = reset_deassert(&reset);
+ if (ret < 0) {
+ pr_err("%s: error deasserting reset %d\n", __func__, i);
+ return ret;
+ }
+
+ ret = reset_free(&reset);
+ if (ret < 0) {
+ pr_err("%s: error freeing reset %d\n", __func__, i);
+ return ret;
+ }
+ }
+
+ /* 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,
+};
diff --git a/include/configs/bmips_common.h b/include/configs/bmips_common.h
index 39ca2e0bf3..788f4af70d 100644
--- a/include/configs/bmips_common.h
+++ b/include/configs/bmips_common.h
@@ -6,6 +6,10 @@
#ifndef __CONFIG_BMIPS_COMMON_H
#define __CONFIG_BMIPS_COMMON_H
+/* ETH */
+#define CONFIG_PHY_RESET_DELAY 20
+#define CONFIG_SYS_RX_ETH_BUFFER 6
+
/* UART */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
230400, 500000, 1500000 }
@@ -16,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
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 11/28] bmips: bcm6338: add support for bcm6348-enet
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (9 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 10/28] net: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 12/28] bmips: enable f@st1704 enet support Álvaro Fernández Rojas
` (17 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6338.dtsi | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6338.dtsi b/arch/mips/dts/brcm,bcm6338.dtsi
index 990355481c..c547e949dd 100644
--- a/arch/mips/dts/brcm,bcm6338.dtsi
+++ b/arch/mips/dts/brcm,bcm6338.dtsi
@@ -144,5 +144,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";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 12/28] bmips: enable f@st1704 enet support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (10 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 11/28] bmips: bcm6338: " Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 13/28] bmips: bcm6348: add support for bcm6348-enet Álvaro Fernández Rojas
` (16 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: no changes
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 | 8 +++++++-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/sagem,f at st1704.dts b/arch/mips/dts/sagem,f at st1704.dts
index 5300f8b6df..ec6846dd9f 100644
--- a/arch/mips/dts/sagem,f at st1704.dts
+++ b/arch/mips/dts/sagem,f at st1704.dts
@@ -39,6 +39,18 @@
};
};
+&enet {
+ status = "okay";
+ phy = <&enetphy>;
+ phy-mode = "mii";
+
+ enetphy: fixed-link {
+ reg = <1>;
+ speed = <100>;
+ full-duplex;
+ };
+};
+
&gpio {
status = "okay";
};
diff --git a/configs/sagem_f at st1704_ram_defconfig b/configs/sagem_f at st1704_ram_defconfig
index 91a966327a..8c36f5dbf8 100644
--- a/configs/sagem_f at st1704_ram_defconfig
+++ b/configs/sagem_f at st1704_ram_defconfig
@@ -27,11 +27,14 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="sagem,f at st1704"
-# CONFIG_NET is not set
+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_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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 13/28] bmips: bcm6348: add support for bcm6348-enet
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (11 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 12/28] bmips: enable f@st1704 enet support Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 14/28] bmips: enable ct-5361 enet support Álvaro Fernández Rojas
` (15 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6348.dtsi | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6348.dtsi b/arch/mips/dts/brcm,bcm6348.dtsi
index 875de232ca..79e7bd892b 100644
--- a/arch/mips/dts/brcm,bcm6348.dtsi
+++ b/arch/mips/dts/brcm,bcm6348.dtsi
@@ -161,6 +161,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>,
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 14/28] bmips: enable ct-5361 enet support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (12 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 13/28] bmips: bcm6348: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 15/28] bmips: bcm6358: add support for bcm6348-enet Álvaro Fernández Rojas
` (14 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: no changes
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(-)
diff --git a/arch/mips/dts/comtrend,ct-5361.dts b/arch/mips/dts/comtrend,ct-5361.dts
index 25747ca95d..f6b8a94e25 100644
--- a/arch/mips/dts/comtrend,ct-5361.dts
+++ b/arch/mips/dts/comtrend,ct-5361.dts
@@ -34,6 +34,18 @@
};
};
+&enet1 {
+ status = "okay";
+ phy = <&enet1phy>;
+ phy-mode = "mii";
+
+ enet1phy: fixed-link {
+ reg = <1>;
+ speed = <100>;
+ full-duplex;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/comtrend_ct5361_ram_defconfig b/configs/comtrend_ct5361_ram_defconfig
index 82f2070713..6297e78fd9 100644
--- a/configs/comtrend_ct5361_ram_defconfig
+++ b/configs/comtrend_ct5361_ram_defconfig
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,ct-5361"
-# CONFIG_NET is not set
+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_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 15/28] bmips: bcm6358: add support for bcm6348-enet
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (13 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 14/28] bmips: enable ct-5361 enet support Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 16/28] bmips: enable hg556a enet support Álvaro Fernández Rojas
` (13 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: no changes
v5: no changes
v4: no changes
v3: no changes
v2: no changes
arch/mips/dts/brcm,bcm6358.dtsi | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi
index 5605723e83..5e9c9ad769 100644
--- a/arch/mips/dts/brcm,bcm6358.dtsi
+++ b/arch/mips/dts/brcm,bcm6358.dtsi
@@ -192,6 +192,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>,
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 16/28] bmips: enable hg556a enet support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (14 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 15/28] bmips: bcm6358: add support for bcm6348-enet Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 17/28] bmips: enable nb4-ser " Álvaro Fernández Rojas
` (12 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: no changes
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(-)
diff --git a/arch/mips/dts/huawei,hg556a.dts b/arch/mips/dts/huawei,hg556a.dts
index 60455c2ff8..6a7fc1df4b 100644
--- a/arch/mips/dts/huawei,hg556a.dts
+++ b/arch/mips/dts/huawei,hg556a.dts
@@ -93,6 +93,18 @@
status = "okay";
};
+&enet1 {
+ status = "okay";
+ phy = <&enet1phy>;
+ phy-mode = "mii";
+
+ enet1phy: fixed-link {
+ reg = <1>;
+ speed = <100>;
+ full-duplex;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/huawei_hg556a_ram_defconfig b/configs/huawei_hg556a_ram_defconfig
index 6bb14ba736..d4e6144319 100644
--- a/configs/huawei_hg556a_ram_defconfig
+++ b/configs/huawei_hg556a_ram_defconfig
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="huawei,hg556a"
-# CONFIG_NET is not set
+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_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 17/28] bmips: enable nb4-ser enet support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (15 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 16/28] bmips: enable hg556a enet support Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 18/28] net: add support for bcm6368-enet Álvaro Fernández Rojas
` (11 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: no changes
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(-)
diff --git a/arch/mips/dts/sfr,nb4-ser.dts b/arch/mips/dts/sfr,nb4-ser.dts
index bdc6f8ae45..dfbc4148dc 100644
--- a/arch/mips/dts/sfr,nb4-ser.dts
+++ b/arch/mips/dts/sfr,nb4-ser.dts
@@ -53,6 +53,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";
};
diff --git a/configs/sfr_nb4-ser_ram_defconfig b/configs/sfr_nb4-ser_ram_defconfig
index 12adfb01e7..39622875b1 100644
--- a/configs/sfr_nb4-ser_ram_defconfig
+++ b/configs/sfr_nb4-ser_ram_defconfig
@@ -26,11 +26,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="sfr,nb4-ser"
-# CONFIG_NET is not set
+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
@@ -42,6 +45,9 @@ CONFIG_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=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
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 18/28] net: add support for bcm6368-enet
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (16 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 17/28] bmips: enable nb4-ser " Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 19/28] bmips: bcm6368: " Álvaro Fernández Rojas
` (10 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
---
v11: no changes
v10: Introduce changes suggested by Daniel Schwierzeck:
- Fix license identifiers.
- Remove packet queue.
- Move dma_prepare_rcv_buf to free_pkt.
- Pad packets smaller than ETH_ZLEN.
- Switch to live DM live tree.
v9: introduce flow control improvements from bcm6348-eth:
- introduce rx packets caching functionality from bcm6348-eth to fix flow
control issues.
- code style fixes.
v8: introduce bcm6368-enet driver
drivers/net/Kconfig | 8 +
drivers/net/Makefile | 1 +
drivers/net/bcm6368-eth.c | 625 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 634 insertions(+)
create mode 100644 drivers/net/bcm6368-eth.c
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2b7cec8804..7044c6adf3 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -82,6 +82,14 @@ config BCM6348_ETH
help
This driver supports the BCM6348 Ethernet MAC.
+config BCM6368_ETH
+ bool "BCM6368 EMAC support"
+ depends on DM_ETH && ARCH_BMIPS
+ select DMA
+ select MII
+ help
+ This driver supports the BCM6368 Ethernet MAC.
+
config DWC_ETH_QOS
bool "Synopsys DWC Ethernet QOS device support"
depends on DM_ETH
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 2647d4dd23..0dbfa03306 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -7,6 +7,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_BCM6368_ETH) += bcm6368-eth.o
obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
obj-$(CONFIG_DRIVER_AX88180) += ax88180.o
obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
diff --git a/drivers/net/bcm6368-eth.c b/drivers/net/bcm6368-eth.c
new file mode 100644
index 0000000000..a31efba9d1
--- /dev/null
+++ b/drivers/net/bcm6368-eth.c
@@ -0,0 +1,625 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dma.h>
+#include <miiphy.h>
+#include <net.h>
+#include <reset.h>
+#include <wait_bit.h>
+#include <asm/io.h>
+
+#define ETH_PORT_STR "brcm,enetsw-port"
+
+#define ETH_RX_DESC PKTBUFSRX
+#define ETH_ZLEN 60
+#define ETH_TIMEOUT 100
+
+#define ETH_MAX_PORT 8
+#define ETH_RGMII_PORT0 4
+
+/* Port traffic control */
+#define ETH_PTCTRL_REG(x) (0x0 + (x))
+#define ETH_PTCTRL_RXDIS_SHIFT 0
+#define ETH_PTCTRL_RXDIS_MASK (1 << ETH_PTCTRL_RXDIS_SHIFT)
+#define ETH_PTCTRL_TXDIS_SHIFT 1
+#define ETH_PTCTRL_TXDIS_MASK (1 << ETH_PTCTRL_TXDIS_SHIFT)
+
+/* Switch mode register */
+#define ETH_SWMODE_REG 0xb
+#define ETH_SWMODE_FWD_EN_SHIFT 1
+#define ETH_SWMODE_FWD_EN_MASK (1 << ETH_SWMODE_FWD_EN_SHIFT)
+
+/* IMP override Register */
+#define ETH_IMPOV_REG 0xe
+#define ETH_IMPOV_LINKUP_SHIFT 0
+#define ETH_IMPOV_LINKUP_MASK (1 << ETH_IMPOV_LINKUP_SHIFT)
+#define ETH_IMPOV_FDX_SHIFT 1
+#define ETH_IMPOV_FDX_MASK (1 << ETH_IMPOV_FDX_SHIFT)
+#define ETH_IMPOV_100_SHIFT 2
+#define ETH_IMPOV_100_MASK (1 << ETH_IMPOV_100_SHIFT)
+#define ETH_IMPOV_1000_SHIFT 3
+#define ETH_IMPOV_1000_MASK (1 << ETH_IMPOV_1000_SHIFT)
+#define ETH_IMPOV_RXFLOW_SHIFT 4
+#define ETH_IMPOV_RXFLOW_MASK (1 << ETH_IMPOV_RXFLOW_SHIFT)
+#define ETH_IMPOV_TXFLOW_SHIFT 5
+#define ETH_IMPOV_TXFLOW_MASK (1 << ETH_IMPOV_TXFLOW_SHIFT)
+#define ETH_IMPOV_FORCE_SHIFT 7
+#define ETH_IMPOV_FORCE_MASK (1 << ETH_IMPOV_FORCE_SHIFT)
+
+/* Port override Register */
+#define ETH_PORTOV_REG(x) (0x58 + (x))
+#define ETH_PORTOV_LINKUP_SHIFT 0
+#define ETH_PORTOV_LINKUP_MASK (1 << ETH_PORTOV_LINKUP_SHIFT)
+#define ETH_PORTOV_FDX_SHIFT 1
+#define ETH_PORTOV_FDX_MASK (1 << ETH_PORTOV_FDX_SHIFT)
+#define ETH_PORTOV_100_SHIFT 2
+#define ETH_PORTOV_100_MASK (1 << ETH_PORTOV_100_SHIFT)
+#define ETH_PORTOV_1000_SHIFT 3
+#define ETH_PORTOV_1000_MASK (1 << ETH_PORTOV_1000_SHIFT)
+#define ETH_PORTOV_RXFLOW_SHIFT 4
+#define ETH_PORTOV_RXFLOW_MASK (1 << ETH_PORTOV_RXFLOW_SHIFT)
+#define ETH_PORTOV_TXFLOW_SHIFT 5
+#define ETH_PORTOV_TXFLOW_MASK (1 << ETH_PORTOV_TXFLOW_SHIFT)
+#define ETH_PORTOV_ENABLE_SHIFT 6
+#define ETH_PORTOV_ENABLE_MASK (1 << ETH_PORTOV_ENABLE_SHIFT)
+
+/* Port RGMII control register */
+#define ETH_RGMII_CTRL_REG(x) (0x60 + (x))
+#define ETH_RGMII_CTRL_GMII_CLK_EN (1 << 7)
+#define ETH_RGMII_CTRL_MII_OVERRIDE_EN (1 << 6)
+#define ETH_RGMII_CTRL_MII_MODE_MASK (3 << 4)
+#define ETH_RGMII_CTRL_RGMII_MODE (0 << 4)
+#define ETH_RGMII_CTRL_MII_MODE (1 << 4)
+#define ETH_RGMII_CTRL_RVMII_MODE (2 << 4)
+#define ETH_RGMII_CTRL_TIMING_SEL_EN (1 << 0)
+
+/* Port RGMII timing register */
+#define ENETSW_RGMII_TIMING_REG(x) (0x68 + (x))
+
+/* MDIO control register */
+#define MII_SC_REG 0xb0
+#define MII_SC_EXT_SHIFT 16
+#define MII_SC_EXT_MASK (1 << MII_SC_EXT_SHIFT)
+#define MII_SC_REG_SHIFT 20
+#define MII_SC_PHYID_SHIFT 25
+#define MII_SC_RD_SHIFT 30
+#define MII_SC_RD_MASK (1 << MII_SC_RD_SHIFT)
+#define MII_SC_WR_SHIFT 31
+#define MII_SC_WR_MASK (1 << MII_SC_WR_SHIFT)
+
+/* MDIO data register */
+#define MII_DAT_REG 0xb4
+
+/* Global Management Configuration Register */
+#define ETH_GMCR_REG 0x200
+#define ETH_GMCR_RST_MIB_SHIFT 0
+#define ETH_GMCR_RST_MIB_MASK (1 << ETH_GMCR_RST_MIB_SHIFT)
+
+/* Jumbo control register port mask register */
+#define ETH_JMBCTL_PORT_REG 0x4004
+
+/* Jumbo control mib good frame register */
+#define ETH_JMBCTL_MAXSIZE_REG 0x4008
+
+/* ETH port data */
+struct bcm_enetsw_port {
+ bool used;
+ const char *name;
+ /* Config */
+ bool bypass_link;
+ int force_speed;
+ bool force_duplex_full;
+ /* PHY */
+ int phy_id;
+};
+
+/* ETH data */
+struct bcm6368_eth_priv {
+ void __iomem *base;
+ /* DMA */
+ struct dma rx_dma;
+ struct dma tx_dma;
+ /* Ports */
+ uint8_t num_ports;
+ struct bcm_enetsw_port used_ports[ETH_MAX_PORT];
+ int sw_port_link[ETH_MAX_PORT];
+ bool rgmii_override;
+ bool rgmii_timing;
+ /* PHY */
+ int phy_id;
+};
+
+static inline bool bcm_enet_port_is_rgmii(int portid)
+{
+ return portid >= ETH_RGMII_PORT0;
+}
+
+static int bcm6368_mdio_read(struct bcm6368_eth_priv *priv, uint8_t ext,
+ int phy_id, int reg)
+{
+ uint32_t val;
+
+ writel_be(0, priv->base + MII_SC_REG);
+
+ val = MII_SC_RD_MASK |
+ (phy_id << MII_SC_PHYID_SHIFT) |
+ (reg << MII_SC_REG_SHIFT);
+
+ if (ext)
+ val |= MII_SC_EXT_MASK;
+
+ writel_be(val, priv->base + MII_SC_REG);
+ udelay(50);
+
+ return readw_be(priv->base + MII_DAT_REG);
+}
+
+static int bcm6368_mdio_write(struct bcm6368_eth_priv *priv, uint8_t ext,
+ int phy_id, int reg, u16 data)
+{
+ uint32_t val;
+
+ writel_be(0, priv->base + MII_SC_REG);
+
+ val = MII_SC_WR_MASK |
+ (phy_id << MII_SC_PHYID_SHIFT) |
+ (reg << MII_SC_REG_SHIFT);
+
+ if (ext)
+ val |= MII_SC_EXT_MASK;
+
+ val |= data;
+
+ writel_be(val, priv->base + MII_SC_REG);
+ udelay(50);
+
+ return 0;
+}
+
+static int bcm6368_eth_free_pkt(struct udevice *dev, uchar *packet, int len)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+ return dma_prepare_rcv_buf(&priv->rx_dma, packet, len);
+}
+
+static int bcm6368_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+ return dma_receive(&priv->rx_dma, (void**)packetp, NULL);
+}
+
+static int bcm6368_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+
+ /* pad packets smaller than ETH_ZLEN */
+ if (length < ETH_ZLEN) {
+ memset(packet + length, 0, ETH_ZLEN - length);
+ length = ETH_ZLEN;
+ }
+
+ return dma_send(&priv->tx_dma, packet, length, NULL);
+}
+
+static int bcm6368_eth_adjust_link(struct udevice *dev)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+ unsigned int i;
+
+ for (i = 0; i < priv->num_ports; i++) {
+ struct bcm_enetsw_port *port;
+ int val, j, up, adv, lpa, speed, duplex, media;
+ int external_phy = bcm_enet_port_is_rgmii(i);
+ u8 override;
+
+ port = &priv->used_ports[i];
+ if (!port->used)
+ continue;
+
+ if (port->bypass_link)
+ continue;
+
+ /* dummy read to clear */
+ for (j = 0; j < 2; j++)
+ val = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_BMSR);
+
+ if (val == 0xffff)
+ continue;
+
+ up = (val & BMSR_LSTATUS) ? 1 : 0;
+ if (!(up ^ priv->sw_port_link[i]))
+ continue;
+
+ priv->sw_port_link[i] = up;
+
+ /* link changed */
+ if (!up) {
+ dev_info(&priv->pdev->dev, "link DOWN on %s\n",
+ port->name);
+ writeb_be(ETH_PORTOV_ENABLE_MASK,
+ priv->base + ETH_PORTOV_REG(i));
+ writeb_be(ETH_PTCTRL_RXDIS_MASK |
+ ETH_PTCTRL_TXDIS_MASK,
+ priv->base + ETH_PTCTRL_REG(i));
+ continue;
+ }
+
+ adv = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_ADVERTISE);
+
+ lpa = bcm6368_mdio_read(priv, external_phy, port->phy_id,
+ MII_LPA);
+
+ /* figure out media and duplex from advertise and LPA values */
+ media = mii_nway_result(lpa & adv);
+ duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+
+ if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF))
+ speed = 100;
+ else
+ speed = 10;
+
+ if (val & BMSR_ESTATEN) {
+ adv = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_CTRL1000);
+
+ lpa = bcm6368_mdio_read(priv, external_phy,
+ port->phy_id, MII_STAT1000);
+
+ if ((adv & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
+ (lpa & (LPA_1000FULL | LPA_1000HALF))) {
+ speed = 1000;
+ duplex = (lpa & LPA_1000FULL);
+ }
+ }
+
+ pr_alert("link UP on %s, %dMbps, %s-duplex\n",
+ port->name, speed, duplex ? "full" : "half");
+
+ override = ETH_PORTOV_ENABLE_MASK |
+ ETH_PORTOV_LINKUP_MASK;
+
+ if (speed == 1000)
+ override |= ETH_PORTOV_1000_MASK;
+ else if (speed == 100)
+ override |= ETH_PORTOV_100_MASK;
+ if (duplex)
+ override |= ETH_PORTOV_FDX_MASK;
+
+ writeb_be(override, priv->base + ETH_PORTOV_REG(i));
+ writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
+ }
+
+ return 0;
+}
+
+static int bcm6368_eth_start(struct udevice *dev)
+{
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+ uint8_t i;
+
+ /* prepare rx dma buffers */
+ for (i = 0; i < ETH_RX_DESC; i++) {
+ int ret = dma_prepare_rcv_buf(&priv->rx_dma, net_rx_packets[i],
+ PKTSIZE_ALIGN);
+ if (ret < 0)
+ break;
+ }
+
+ /* enable dma rx channel */
+ dma_enable(&priv->rx_dma);
+
+ /* enable dma tx channel */
+ dma_enable(&priv->tx_dma);
+
+ /* apply override config for bypass_link ports here. */
+ for (i = 0; i < priv->num_ports; i++) {
+ struct bcm_enetsw_port *port;
+ u8 override;
+
+ port = &priv->used_ports[i];
+ if (!port->used)
+ continue;
+
+ if (!port->bypass_link)
+ continue;
+
+ override = ETH_PORTOV_ENABLE_MASK |
+ ETH_PORTOV_LINKUP_MASK;
+
+ switch (port->force_speed) {
+ case 1000:
+ override |= ETH_PORTOV_1000_MASK;
+ break;
+ case 100:
+ override |= ETH_PORTOV_100_MASK;
+ break;
+ case 10:
+ break;
+ default:
+ pr_warn("%s: invalid forced speed on port %s\n",
+ __func__, port->name);
+ break;
+ }
+
+ if (port->force_duplex_full)
+ override |= ETH_PORTOV_FDX_MASK;
+
+ writeb_be(override, priv->base + ETH_PORTOV_REG(i));
+ writeb_be(0, priv->base + ETH_PTCTRL_REG(i));
+ }
+
+ bcm6368_eth_adjust_link(dev);
+
+ return 0;
+}
+
+static void bcm6368_eth_stop(struct udevice *dev)
+{
+ struct bcm6368_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);
+}
+
+static const struct eth_ops bcm6368_eth_ops = {
+ .free_pkt = bcm6368_eth_free_pkt,
+ .recv = bcm6368_eth_recv,
+ .send = bcm6368_eth_send,
+ .start = bcm6368_eth_start,
+ .stop = bcm6368_eth_stop,
+};
+
+static const struct udevice_id bcm6368_eth_ids[] = {
+ { .compatible = "brcm,bcm6368-enet", },
+ { /* sentinel */ }
+};
+
+static bool bcm6368_phy_is_external(struct bcm6368_eth_priv *priv, int phy_id)
+{
+ uint8_t i;
+
+ for (i = 0; i < priv->num_ports; ++i) {
+ if (!priv->used_ports[i].used)
+ continue;
+ if (priv->used_ports[i].phy_id == phy_id)
+ return bcm_enet_port_is_rgmii(i);
+ }
+
+ return true;
+}
+
+static int bcm6368_mii_mdio_read(struct mii_dev *bus, int addr, int devaddr,
+ int reg)
+{
+ struct bcm6368_eth_priv *priv = bus->priv;
+ bool ext = bcm6368_phy_is_external(priv, addr);
+
+ return bcm6368_mdio_read(priv, ext, addr, reg);
+}
+
+static int bcm6368_mii_mdio_write(struct mii_dev *bus, int addr, int devaddr,
+ int reg, u16 data)
+{
+ struct bcm6368_eth_priv *priv = bus->priv;
+ bool ext = bcm6368_phy_is_external(priv, addr);
+
+ return bcm6368_mdio_write(priv, ext, addr, reg, data);
+}
+
+static int bcm6368_mdio_init(const char *name, struct bcm6368_eth_priv *priv)
+{
+ struct mii_dev *bus;
+
+ bus = mdio_alloc();
+ if (!bus) {
+ pr_err("%s: failed to allocate MDIO bus\n", __func__);
+ return -ENOMEM;
+ }
+
+ bus->read = bcm6368_mii_mdio_read;
+ bus->write = bcm6368_mii_mdio_write;
+ bus->priv = priv;
+ snprintf(bus->name, sizeof(bus->name), "%s", name);
+
+ return mdio_register(bus);
+}
+
+static int bcm6368_eth_probe(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct bcm6368_eth_priv *priv = dev_get_priv(dev);
+ int num_ports, ret, i;
+ uint32_t val;
+ ofnode node;
+
+ /* get base address */
+ priv->base = dev_remap_addr(dev);
+ if (!priv->base)
+ return -EINVAL;
+ pdata->iobase = (phys_addr_t) priv->base;
+
+ /* get number of ports */
+ num_ports = dev_read_u32_default(dev, "brcm,num-ports", ETH_MAX_PORT);
+ if (!num_ports || num_ports > ETH_MAX_PORT)
+ 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;
+
+ ret = clk_enable(&clk);
+ if (ret < 0) {
+ pr_err("%s: error enabling clock %d\n", __func__, i);
+ return ret;
+ }
+
+ ret = clk_free(&clk);
+ if (ret < 0) {
+ pr_err("%s: error freeing clock %d\n", __func__, i);
+ return ret;
+ }
+ }
+
+ /* 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;
+
+ ret = reset_deassert(&reset);
+ if (ret < 0) {
+ pr_err("%s: error deasserting reset %d\n", __func__, i);
+ return ret;
+ }
+
+ ret = reset_free(&reset);
+ if (ret < 0) {
+ pr_err("%s: error freeing reset %d\n", __func__, i);
+ return ret;
+ }
+ }
+
+ /* set priv data */
+ priv->num_ports = num_ports;
+ if (dev_read_bool(dev, "brcm,rgmii-override"))
+ priv->rgmii_override = true;
+ if (dev_read_bool(dev, "brcm,rgmii-timing"))
+ priv->rgmii_timing = true;
+
+ /* get ports */
+ dev_for_each_subnode(node, dev) {
+ const char *comp;
+ const char *label;
+ unsigned int p;
+ int phy_id;
+ int speed;
+
+ comp = ofnode_read_string(node, "compatible");
+ if (!comp || memcmp(comp, ETH_PORT_STR, sizeof(ETH_PORT_STR)))
+ continue;
+
+ p = ofnode_read_u32_default(node, "reg", ETH_MAX_PORT);
+ if (p >= num_ports)
+ return -EINVAL;
+
+ label = ofnode_read_string(node, "label");
+ if (!label) {
+ debug("%s: node %s has no label\n", __func__,
+ ofnode_get_name(node));
+ return -EINVAL;
+ }
+
+ phy_id = ofnode_read_u32_default(node, "brcm,phy-id", -1);
+
+ priv->used_ports[p].used = true;
+ priv->used_ports[p].name = label;
+ priv->used_ports[p].phy_id = phy_id;
+
+ if (ofnode_read_bool(node, "full-duplex"))
+ priv->used_ports[p].force_duplex_full = true;
+ if (ofnode_read_bool(node, "bypass-link"))
+ priv->used_ports[p].bypass_link = true;
+ speed = ofnode_read_u32_default(node, "speed", 0);
+ if (speed)
+ priv->used_ports[p].force_speed = speed;
+ }
+
+ /* init mii bus */
+ ret = bcm6368_mdio_init(dev->name, priv);
+ if (ret)
+ return ret;
+
+ /* disable all ports */
+ for (i = 0; i < priv->num_ports; i++) {
+ writeb_be(ETH_PORTOV_ENABLE_MASK,
+ priv->base + ETH_PORTOV_REG(i));
+ writeb_be(ETH_PTCTRL_RXDIS_MASK |
+ ETH_PTCTRL_TXDIS_MASK,
+ priv->base + ETH_PTCTRL_REG(i));
+
+ priv->sw_port_link[i] = 0;
+ }
+
+ /* enable external ports */
+ for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) {
+ u8 rgmii_ctrl;
+
+ if (!priv->used_ports[i].used)
+ continue;
+
+ rgmii_ctrl = readb_be(priv->base + ETH_RGMII_CTRL_REG(i));
+ rgmii_ctrl |= ETH_RGMII_CTRL_GMII_CLK_EN;
+ if (priv->rgmii_override)
+ rgmii_ctrl |= ETH_RGMII_CTRL_MII_OVERRIDE_EN;
+ if (priv->rgmii_timing)
+ rgmii_ctrl |= ETH_RGMII_CTRL_TIMING_SEL_EN;
+ writeb_be(rgmii_ctrl, priv->base + ETH_RGMII_CTRL_REG(i));
+ }
+
+ /* reset mib */
+ val = readb_be(priv->base + ETH_GMCR_REG);
+ val |= ETH_GMCR_RST_MIB_MASK;
+ writeb_be(val, priv->base + ETH_GMCR_REG);
+ mdelay(1);
+ val &= ~ETH_GMCR_RST_MIB_MASK;
+ writeb_be(val, priv->base + ETH_GMCR_REG);
+ mdelay(1);
+
+ /* force CPU port state */
+ val = readb_be(priv->base + ETH_IMPOV_REG);
+ val |= ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK;
+ writeb_be(val, priv->base + ETH_IMPOV_REG);
+
+ /* enable switch forward engine */
+ val = readb_be(priv->base + ETH_SWMODE_REG);
+ val |= ETH_SWMODE_FWD_EN_MASK;
+ writeb_be(val, priv->base + ETH_SWMODE_REG);
+
+ /* enable jumbo on all ports */
+ writel_be(0x1ff, priv->base + ETH_JMBCTL_PORT_REG);
+ writew_be(9728, priv->base + ETH_JMBCTL_MAXSIZE_REG);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(bcm6368_eth) = {
+ .name = "bcm6368_eth",
+ .id = UCLASS_ETH,
+ .of_match = bcm6368_eth_ids,
+ .ops = &bcm6368_eth_ops,
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+ .priv_auto_alloc_size = sizeof(struct bcm6368_eth_priv),
+ .probe = bcm6368_eth_probe,
+};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 19/28] bmips: bcm6368: add support for bcm6368-enet
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (17 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 18/28] net: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 20/28] bmips: enable wap-5813n enet support Álvaro Fernández Rojas
` (9 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6368.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6368.dtsi b/arch/mips/dts/brcm,bcm6368.dtsi
index 30047f6360..89590d6ff9 100644
--- a/arch/mips/dts/brcm,bcm6368.dtsi
+++ b/arch/mips/dts/brcm,bcm6368.dtsi
@@ -205,5 +205,24 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10f00000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10f00000 0x10000>;
+ clocks = <&periph_clk BCM6368_CLK_SWPKT_USB>,
+ <&periph_clk BCM6368_CLK_SWPKT_SAR>,
+ <&periph_clk BCM6368_CLK_ROBOSW>;
+ resets = <&periph_rst BCM6368_RST_SWITCH>,
+ <&periph_rst BCM6368_RST_EPHY>;
+ dmas = <&iudma BCM6368_DMA_ENETSW_RX>,
+ <&iudma BCM6368_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <6>;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 20/28] bmips: enable wap-5813n enet support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (18 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 19/28] bmips: bcm6368: " Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 21/28] bmips: bcm6328: add support for bcm6368-enet Álvaro Fernández Rojas
` (8 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,wap-5813n.dts | 14 ++++++++++++++
configs/comtrend_wap5813n_ram_defconfig | 8 +++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,wap-5813n.dts b/arch/mips/dts/comtrend,wap-5813n.dts
index bd41dab9f8..7e835b28d2 100644
--- a/arch/mips/dts/comtrend,wap-5813n.dts
+++ b/arch/mips/dts/comtrend,wap-5813n.dts
@@ -54,6 +54,20 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 4 {
+ compatible = "brcm,enetsw-port";
+ reg = <4>;
+ label = "rgmii";
+ brcm,phy-id = <0xff>;
+ speed = <1000>;
+ full-duplex;
+ bypass-link;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/comtrend_wap5813n_ram_defconfig b/configs/comtrend_wap5813n_ram_defconfig
index 987e4c3fbc..fd5107bb7d 100644
--- a/configs/comtrend_wap5813n_ram_defconfig
+++ b/configs/comtrend_wap5813n_ram_defconfig
@@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,wap-5813n"
-# CONFIG_NET is not set
+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_FLASH_CFI_DRIVER=y
CONFIG_CFI_FLASH=y
CONFIG_SYS_FLASH_PROTECTION=y
CONFIG_SYS_FLASH_CFI=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_DM_RESET=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 21/28] bmips: bcm6328: add support for bcm6368-enet
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (19 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 20/28] bmips: enable wap-5813n enet support Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 22/28] bmips: enable ar-5387un enet support Álvaro Fernández Rojas
` (7 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6328.dtsi | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi
index 6fa49e22bb..50beed4171 100644
--- a/arch/mips/dts/brcm,bcm6328.dtsi
+++ b/arch/mips/dts/brcm,bcm6328.dtsi
@@ -200,5 +200,22 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10e00000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10e00000 0x10000>;
+ clocks = <&periph_clk BCM6328_CLK_ROBOSW>;
+ resets = <&periph_rst BCM6328_RST_ENETSW>,
+ <&periph_rst BCM6328_RST_EPHY>;
+ dmas = <&iudma BCM6328_DMA_ENETSW_RX>,
+ <&iudma BCM6328_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <5>;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 22/28] bmips: enable ar-5387un enet support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (20 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 21/28] bmips: bcm6328: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 23/28] bmips: bcm6362: add support for bcm6368-enet Álvaro Fernández Rojas
` (6 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,ar-5387un.dts | 32 ++++++++++++++++++++++++++++++++
configs/comtrend_ar5387un_ram_defconfig | 7 ++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,ar-5387un.dts b/arch/mips/dts/comtrend,ar-5387un.dts
index e993b5cd89..03e3851ab1 100644
--- a/arch/mips/dts/comtrend,ar-5387un.dts
+++ b/arch/mips/dts/comtrend,ar-5387un.dts
@@ -24,6 +24,38 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 0 {
+ compatible = "brcm,enetsw-port";
+ reg = <0>;
+ label = "fe1";
+ brcm,phy-id = <1>;
+ };
+
+ port at 1 {
+ compatible = "brcm,enetsw-port";
+ reg = <1>;
+ label = "fe2";
+ brcm,phy-id = <2>;
+ };
+
+ port at 2 {
+ compatible = "brcm,enetsw-port";
+ reg = <2>;
+ label = "fe3";
+ brcm,phy-id = <3>;
+ };
+
+ port at 3 {
+ compatible = "brcm,enetsw-port";
+ reg = <3>;
+ label = "fe4";
+ brcm,phy-id = <4>;
+ };
+};
+
&leds {
status = "okay";
diff --git a/configs/comtrend_ar5387un_ram_defconfig b/configs/comtrend_ar5387un_ram_defconfig
index f129870ca0..5ba401a441 100644
--- a/configs/comtrend_ar5387un_ram_defconfig
+++ b/configs/comtrend_ar5387un_ram_defconfig
@@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5387un"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
CONFIG_DM_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
@@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 23/28] bmips: bcm6362: add support for bcm6368-enet
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (21 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 22/28] bmips: enable ar-5387un enet support Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 24/28] bmips: enable dgnd3700v2 enet support Álvaro Fernández Rojas
` (5 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6362.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6362.dtsi b/arch/mips/dts/brcm,bcm6362.dtsi
index 94e7de096d..c77b80a4cc 100644
--- a/arch/mips/dts/brcm,bcm6362.dtsi
+++ b/arch/mips/dts/brcm,bcm6362.dtsi
@@ -224,5 +224,24 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10e00000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10e00000 0x10000>;
+ clocks = <&periph_clk BCM6362_CLK_SWPKT_USB>,
+ <&periph_clk BCM6362_CLK_SWPKT_SAR>,
+ <&periph_clk BCM6362_CLK_ROBOSW>;
+ resets = <&periph_rst BCM6362_RST_ENETSW>,
+ <&periph_rst BCM6362_RST_EPHY>;
+ dmas = <&iudma BCM6362_DMA_ENETSW_RX>,
+ <&iudma BCM6362_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <6>;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 24/28] bmips: enable dgnd3700v2 enet support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (22 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 23/28] bmips: bcm6362: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 25/28] bmips: bcm63268: add support for bcm6368-enet Álvaro Fernández Rojas
` (4 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/netgear,dgnd3700v2.dts | 14 ++++++++++++++
configs/netgear_dgnd3700v2_ram_defconfig | 8 +++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/netgear,dgnd3700v2.dts b/arch/mips/dts/netgear,dgnd3700v2.dts
index 322d1567ff..2b72491f0b 100644
--- a/arch/mips/dts/netgear,dgnd3700v2.dts
+++ b/arch/mips/dts/netgear,dgnd3700v2.dts
@@ -43,6 +43,20 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 4 {
+ compatible = "brcm,enetsw-port";
+ reg = <4>;
+ label = "rgmii";
+ brcm,phy-id = <0xff>;
+ speed = <1000>;
+ full-duplex;
+ bypass-link;
+ };
+};
+
&gpio0 {
status = "okay";
};
diff --git a/configs/netgear_dgnd3700v2_ram_defconfig b/configs/netgear_dgnd3700v2_ram_defconfig
index 1abc869856..0f3914fe7e 100644
--- a/configs/netgear_dgnd3700v2_ram_defconfig
+++ b/configs/netgear_dgnd3700v2_ram_defconfig
@@ -27,17 +27,23 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
-# CONFIG_CMD_NET is not set
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="netgear,dgnd3700v2"
+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
CONFIG_LED_BCM6328=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
+CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 25/28] bmips: bcm63268: add support for bcm6368-enet
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (23 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 24/28] bmips: enable dgnd3700v2 enet support Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 26/28] bmips: enable vr-3032u enet support Álvaro Fernández Rojas
` (3 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm63268.dtsi | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi
index c7ad83c306..f8a72ef535 100644
--- a/arch/mips/dts/brcm,bcm63268.dtsi
+++ b/arch/mips/dts/brcm,bcm63268.dtsi
@@ -230,5 +230,30 @@
#dma-cells = <1>;
dma-channels = <8>;
};
+
+ enet: ethernet at 10700000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10700000 0x10000>;
+ clocks = <&periph_clk BCM63268_CLK_GMAC>,
+ <&periph_clk BCM63268_CLK_ROBOSW>,
+ <&periph_clk BCM63268_CLK_ROBOSW250>,
+ <&timer_clk BCM63268_TCLK_EPHY1>,
+ <&timer_clk BCM63268_TCLK_EPHY2>,
+ <&timer_clk BCM63268_TCLK_EPHY3>,
+ <&timer_clk BCM63268_TCLK_GPHY>;
+ resets = <&periph_rst BCM63268_RST_ENETSW>,
+ <&periph_rst BCM63268_RST_EPHY>,
+ <&periph_rst BCM63268_RST_GPHY>;
+ dmas = <&iudma BCM63268_DMA_ENETSW_RX>,
+ <&iudma BCM63268_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,rgmii-override;
+ brcm,rgmii-timing;
+
+ status = "disabled";
+ };
};
};
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 26/28] bmips: enable vr-3032u enet support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (24 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 25/28] bmips: bcm63268: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 27/28] bmips: bcm6318: add support for bcm6368-enet Álvaro Fernández Rojas
` (2 subsequent siblings)
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,vr-3032u.dts | 32 ++++++++++++++++++++++++++++++++
configs/comtrend_vr3032u_ram_defconfig | 7 ++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,vr-3032u.dts b/arch/mips/dts/comtrend,vr-3032u.dts
index 8c6a4a1eac..512cb52de3 100644
--- a/arch/mips/dts/comtrend,vr-3032u.dts
+++ b/arch/mips/dts/comtrend,vr-3032u.dts
@@ -24,6 +24,38 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 0 {
+ compatible = "brcm,enetsw-port";
+ reg = <0>;
+ label = "fe2";
+ brcm,phy-id = <1>;
+ };
+
+ port at 1 {
+ compatible = "brcm,enetsw-port";
+ reg = <1>;
+ label = "fe3";
+ brcm,phy-id = <2>;
+ };
+
+ port at 2 {
+ compatible = "brcm,enetsw-port";
+ reg = <2>;
+ label = "fe4";
+ brcm,phy-id = <3>;
+ };
+
+ port at 3 {
+ compatible = "brcm,enetsw-port";
+ reg = <3>;
+ label = "fe1";
+ brcm,phy-id = <4>;
+ };
+};
+
&leds {
status = "okay";
brcm,serial-leds;
diff --git a/configs/comtrend_vr3032u_ram_defconfig b/configs/comtrend_vr3032u_ram_defconfig
index 1689eecec1..47f53998e1 100644
--- a/configs/comtrend_vr3032u_ram_defconfig
+++ b/configs/comtrend_vr3032u_ram_defconfig
@@ -26,15 +26,20 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,vr-3032u"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
CONFIG_DM_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
CONFIG_LED_BLINK=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6368_USBH_PHY=y
CONFIG_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 27/28] bmips: bcm6318: add support for bcm6368-enet
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (25 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 26/28] bmips: enable vr-3032u enet support Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-01 18:00 ` [U-Boot] [PATCH v11 28/28] bmips: enable ar-5315u enet support Álvaro Fernández Rojas
2018-12-10 15:36 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Daniel Schwierzeck
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/brcm,bcm6318.dtsi | 19 +++++++++++++++++++
include/dt-bindings/clock/bcm6318-clock.h | 11 +++++++++++
2 files changed, 30 insertions(+)
diff --git a/arch/mips/dts/brcm,bcm6318.dtsi b/arch/mips/dts/brcm,bcm6318.dtsi
index d04b7cbb01..d678dab242 100644
--- a/arch/mips/dts/brcm,bcm6318.dtsi
+++ b/arch/mips/dts/brcm,bcm6318.dtsi
@@ -190,6 +190,25 @@
status = "disabled";
};
+ enet: ethernet at 10080000 {
+ compatible = "brcm,bcm6368-enet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x10080000 0x8000>;
+ clocks = <&periph_clk BCM6318_CLK_ROBOSW250>,
+ <&periph_clk BCM6318_CLK_ROBOSW025>,
+ <&ubus_clk BCM6318_UCLK_ROBOSW>;
+ resets = <&periph_rst BCM6318_RST_ENETSW>,
+ <&periph_rst BCM6318_RST_EPHY>;
+ dmas = <&iudma BCM6318_DMA_ENETSW_RX>,
+ <&iudma BCM6318_DMA_ENETSW_TX>;
+ dma-names = "rx",
+ "tx";
+ brcm,num-ports = <5>;
+
+ status = "disabled";
+ };
+
iudma: dma-controller at 10088000 {
compatible = "brcm,bcm6368-iudma";
reg = <0x10088000 0x80>,
diff --git a/include/dt-bindings/clock/bcm6318-clock.h b/include/dt-bindings/clock/bcm6318-clock.h
index d5e13c5c2d..3f10448cef 100644
--- a/include/dt-bindings/clock/bcm6318-clock.h
+++ b/include/dt-bindings/clock/bcm6318-clock.h
@@ -33,4 +33,15 @@
#define BCM6318_CLK_AFE 29
#define BCM6318_CLK_QPROC 30
+#define BCM6318_UCLK_ADSL 0
+#define BCM6318_UCLK_ARB 1
+#define BCM6318_UCLK_MIPS 2
+#define BCM6318_UCLK_PCIE 3
+#define BCM6318_UCLK_PERIPH 4
+#define BCM6318_UCLK_PHYMIPS 5
+#define BCM6318_UCLK_ROBOSW 6
+#define BCM6318_UCLK_SAR 7
+#define BCM6318_UCLK_SDR 8
+#define BCM6318_UCLK_USB 9
+
#endif /* __DT_BINDINGS_CLOCK_BCM6318_H */
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 28/28] bmips: enable ar-5315u enet support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (26 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 27/28] bmips: bcm6318: add support for bcm6368-enet Álvaro Fernández Rojas
@ 2018-12-01 18:00 ` Álvaro Fernández Rojas
2018-12-10 15:36 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Daniel Schwierzeck
28 siblings, 0 replies; 145+ messages in thread
From: Álvaro Fernández Rojas @ 2018-12-01 18:00 UTC (permalink / raw)
To: u-boot
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
---
v11: no changes
v10: no changes
v9: no changes
v8: introduce bcm6368-enet driver
arch/mips/dts/comtrend,ar-5315u.dts | 32 ++++++++++++++++++++++++++++++++
configs/comtrend_ar5315u_ram_defconfig | 7 ++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/mips/dts/comtrend,ar-5315u.dts b/arch/mips/dts/comtrend,ar-5315u.dts
index 45570189d0..eb60aaa8d5 100644
--- a/arch/mips/dts/comtrend,ar-5315u.dts
+++ b/arch/mips/dts/comtrend,ar-5315u.dts
@@ -24,6 +24,38 @@
status = "okay";
};
+&enet {
+ status = "okay";
+
+ port at 0 {
+ compatible = "brcm,enetsw-port";
+ reg = <0>;
+ label = "fe4";
+ brcm,phy-id = <1>;
+ };
+
+ port at 1 {
+ compatible = "brcm,enetsw-port";
+ reg = <1>;
+ label = "fe3";
+ brcm,phy-id = <2>;
+ };
+
+ port at 2 {
+ compatible = "brcm,enetsw-port";
+ reg = <2>;
+ label = "fe2";
+ brcm,phy-id = <3>;
+ };
+
+ port at 3 {
+ compatible = "brcm,enetsw-port";
+ reg = <3>;
+ label = "fe1";
+ brcm,phy-id = <4>;
+ };
+};
+
&leds {
status = "okay";
diff --git a/configs/comtrend_ar5315u_ram_defconfig b/configs/comtrend_ar5315u_ram_defconfig
index d9ef52e68d..1b8e4e43c4 100644
--- a/configs/comtrend_ar5315u_ram_defconfig
+++ b/configs/comtrend_ar5315u_ram_defconfig
@@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
# CONFIG_CMD_MISC is not set
CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5315u"
-# CONFIG_NET is not set
+CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BCM6348_IUDMA=y
CONFIG_DM_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
@@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_ETH=y
+CONFIG_BCM6368_ETH=y
CONFIG_PHY=y
CONFIG_BCM6318_USBH_PHY=y
CONFIG_BCM6328_POWER_DOMAIN=y
--
2.11.0
^ permalink raw reply related [flat|nested] 145+ messages in thread
* [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support
2018-12-01 18:00 ` [U-Boot] [PATCH v11 00/28] bmips: add iudma/enet support Álvaro Fernández Rojas
` (27 preceding siblings ...)
2018-12-01 18:00 ` [U-Boot] [PATCH v11 28/28] bmips: enable ar-5315u enet support Álvaro Fernández Rojas
@ 2018-12-10 15:36 ` Daniel Schwierzeck
28 siblings, 0 replies; 145+ messages in thread
From: Daniel Schwierzeck @ 2018-12-10 15:36 UTC (permalink / raw)
To: u-boot
Am 01.12.18 um 19:00 schrieb Álvaro Fernández Rojas:
> In 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...).
>
> v11: Introduce change suggested by Daniel Schwierzeck:
> - Avoid trimming ethernet FCS from DMA driver.
> v10: Introduce changes suggested by Daniel Schwierzeck:
> - Fix license identifiers.
> bcm6348-iudma:
> - Move DMAD_ST defines out of dma desc struct definition.
> - Remove unneded aigned attribute from dma desc struct definition.
> - Fill dma ring from consumer driver instead of allocating a new buffer.
> - Correctly check clock/reset errors while probing.
> - Switch to live DM live tree.
> bcm6348-enet:
> - Remove packet queue.
> - Move dma_prepare_rcv_buf to free_pkt.
> - Switch to live DM live tree.
> bcm6368-enet:
> - Remove packet queue.
> - Move dma_prepare_rcv_buf to free_pkt.
> - Pad packets smaller than ETH_ZLEN.
> - Switch to live DM live tree.
> v9: Separate generic dma channels support from bmips enet support
> bcm6348-iudma:
> - bcm6348_iudma_chan_stop: switch to mdelay when resetting channel.
> - bcm6348_iudma_receive: track dirty dma descriptors and no longer trigger
> dma rx channel.
> - bcm6348_iudma_send: reorder to properly flush cache and set dma descriptor
> config.
> - bcm6348_iudma_prepare_rcv_buf: implemented to clear dirty dma descriptors.
> bcm6348-enet:
> - bcm6348_eth_recv: clear dirty dma descriptors only when packets are copied
> from rx dma.
> - bcm6348_eth_send: remove dma rx channel reset when sending packet.
> bcm6368-enet:
> - introduce rx packets caching functionality from bcm6348-eth to fix flow
> control issues.
> - code style fixes.
> v8: Introduce bcm6368-enet driver support.
> v5: Fix issues reported by Grygorii Strashko and other fixes:
> - 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: Switch to live tree API.
> v2: Fix bcm6348-iudma rx burst config.
>
> Álvaro Fernández Rojas (28):
> dma: add bcm6348-iudma support
> bmips: bcm6338: add bcm6348-iudma support
> bmips: bcm6348: add bcm6348-iudma support
> bmips: bcm6358: add bcm6348-iudma support
> bmips: bcm6368: add bcm6348-iudma support
> bmips: bcm6328: add bcm6348-iudma support
> bmips: bcm6362: add bcm6348-iudma support
> bmips: bcm63268: add bcm6348-iudma support
> bmips: bcm6318: add bcm6348-iudma support
> 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
> net: add support for bcm6368-enet
> bmips: bcm6368: add support for bcm6368-enet
> bmips: enable wap-5813n enet support
> bmips: bcm6328: add support for bcm6368-enet
> bmips: enable ar-5387un enet support
> bmips: bcm6362: add support for bcm6368-enet
> bmips: enable dgnd3700v2 enet support
> bmips: bcm63268: add support for bcm6368-enet
> bmips: enable vr-3032u enet support
> bmips: bcm6318: add support for bcm6368-enet
> bmips: enable ar-5315u enet support
>
> arch/mips/dts/brcm,bcm6318.dtsi | 38 ++
> arch/mips/dts/brcm,bcm63268.dtsi | 38 ++
> arch/mips/dts/brcm,bcm6328.dtsi | 30 ++
> arch/mips/dts/brcm,bcm6338.dtsi | 29 ++
> arch/mips/dts/brcm,bcm6348.dtsi | 42 ++
> arch/mips/dts/brcm,bcm6358.dtsi | 46 +++
> arch/mips/dts/brcm,bcm6362.dtsi | 32 ++
> arch/mips/dts/brcm,bcm6368.dtsi | 32 ++
> arch/mips/dts/comtrend,ar-5315u.dts | 32 ++
> arch/mips/dts/comtrend,ar-5387un.dts | 32 ++
> arch/mips/dts/comtrend,ct-5361.dts | 12 +
> arch/mips/dts/comtrend,vr-3032u.dts | 32 ++
> arch/mips/dts/comtrend,wap-5813n.dts | 14 +
> arch/mips/dts/huawei,hg556a.dts | 12 +
> arch/mips/dts/netgear,dgnd3700v2.dts | 14 +
> arch/mips/dts/sagem,f at st1704.dts | 12 +
> arch/mips/dts/sfr,nb4-ser.dts | 24 ++
> configs/comtrend_ar5315u_ram_defconfig | 7 +-
> configs/comtrend_ar5387un_ram_defconfig | 7 +-
> configs/comtrend_ct5361_ram_defconfig | 8 +-
> configs/comtrend_vr3032u_ram_defconfig | 7 +-
> configs/comtrend_wap5813n_ram_defconfig | 8 +-
> configs/huawei_hg556a_ram_defconfig | 8 +-
> configs/netgear_dgnd3700v2_ram_defconfig | 8 +-
> configs/sagem_f at st1704_ram_defconfig | 8 +-
> configs/sfr_nb4-ser_ram_defconfig | 8 +-
> drivers/dma/Kconfig | 9 +
> drivers/dma/Makefile | 1 +
> drivers/dma/bcm6348-iudma.c | 642 ++++++++++++++++++++++++++++++
> drivers/net/Kconfig | 18 +
> drivers/net/Makefile | 2 +
> drivers/net/bcm6348-eth.c | 537 +++++++++++++++++++++++++
> drivers/net/bcm6368-eth.c | 625 +++++++++++++++++++++++++++++
> include/configs/bmips_common.h | 6 +-
> include/dt-bindings/clock/bcm6318-clock.h | 11 +
> include/dt-bindings/dma/bcm6318-dma.h | 14 +
> include/dt-bindings/dma/bcm63268-dma.h | 14 +
> include/dt-bindings/dma/bcm6328-dma.h | 14 +
> include/dt-bindings/dma/bcm6338-dma.h | 14 +
> include/dt-bindings/dma/bcm6348-dma.h | 16 +
> include/dt-bindings/dma/bcm6358-dma.h | 16 +
> include/dt-bindings/dma/bcm6362-dma.h | 14 +
> include/dt-bindings/dma/bcm6368-dma.h | 14 +
> 43 files changed, 2497 insertions(+), 10 deletions(-)
> create mode 100644 drivers/dma/bcm6348-iudma.c
> create mode 100644 drivers/net/bcm6348-eth.c
> create mode 100644 drivers/net/bcm6368-eth.c
> create mode 100644 include/dt-bindings/dma/bcm6318-dma.h
> create mode 100644 include/dt-bindings/dma/bcm63268-dma.h
> create mode 100644 include/dt-bindings/dma/bcm6328-dma.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
> create mode 100644 include/dt-bindings/dma/bcm6362-dma.h
> create mode 100644 include/dt-bindings/dma/bcm6368-dma.h
>
series applied to u-boot-mips/next, thanks.
Could you send a patch to fix this DTC warning?
w+arch/mips/dts/brcm,bcm968380gerg.dtb: Warning (avoid_unnecessary_addr_size): /clocks: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property
--
- Daniel
^ permalink raw reply [flat|nested] 145+ messages in thread