[U-Boot] [PATCH 1/2] dm: mdio: add a uclass for MDIO

make at marvell.com make at marvell.com
Wed Jun 6 07:56:35 UTC 2018


From: Ken Ma <make at marvell.com>

Add a uclass which provides access to MDIO busses and includes
operations required by MDIO.
The implementation is based on the existing mii/phy/mdio data
structures and APIs.
This patch also adds evice tree binding for MDIO bus.

Signed-off-by: Ken Ma <make at marvell.com>
---

 MAINTAINERS                                |   1 +
 doc/device-tree-bindings/mdio/mdio-bus.txt |  54 +++++++++++++
 drivers/Kconfig                            |   2 +
 drivers/Makefile                           |   1 +
 drivers/mdio/Kconfig                       |  18 +++++
 drivers/mdio/Makefile                      |   6 ++
 drivers/mdio/mdio-uclass.c                 | 119 +++++++++++++++++++++++++++++
 include/dm/uclass-id.h                     |   1 +
 include/mdio.h                             |  62 +++++++++++++++
 9 files changed, 264 insertions(+)
 create mode 100644 doc/device-tree-bindings/mdio/mdio-bus.txt
 create mode 100644 drivers/mdio/Kconfig
 create mode 100644 drivers/mdio/Makefile
 create mode 100644 drivers/mdio/mdio-uclass.c
 create mode 100644 include/mdio.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 642c448..f66a904 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -335,6 +335,7 @@ M:	Simon Glass <sjg at chromium.org>
 S:	Maintained
 T:	git git://git.denx.de/u-boot-dm.git
 F:	drivers/core/
+F:	drivers/mdio/
 F:	include/dm/
 F:	test/dm/
 
diff --git a/doc/device-tree-bindings/mdio/mdio-bus.txt b/doc/device-tree-bindings/mdio/mdio-bus.txt
new file mode 100644
index 0000000..68d8b25
--- /dev/null
+++ b/doc/device-tree-bindings/mdio/mdio-bus.txt
@@ -0,0 +1,54 @@
+MDIO (Management Data Input/Output) busses
+
+MDIO busses can be described with a node for the MDIO master device
+and a set of child nodes for each phy on the bus.
+
+The MDIO node requires the following properties:
+- #address-cells  - number of cells required to define phy address on
+                    the MDIO bus.
+- #size-cells     - should be zero.
+- compatible      - name of MDIO bus controller following generic names
+                    recommended practice.
+- reg	          - address and length of the MDIO register.
+
+Optional property:
+- mdio-name       - MDIO bus name
+
+The child nodes of the MDIO driver are the individual PHY devices
+connected to this MDIO bus. They must have a "reg" property given the
+PHY address on the MDIO bus.
+- reg             - (required) phy address in MDIO bus.
+
+Example for cp110 MDIO node at the SoC level:
+	cp0_mdio: mdio at 12a200 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "marvell,orion-mdio";
+		reg = <0x12a200 0x10>;
+		mdio-name = "cp0-mdio";
+	};
+
+	cp0_xmdio: mdio at 12a600 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "marvell,xmdio";
+		reg = <0x12a600 0x200>;
+		mdio-name = "cp0-xmdio";
+	};
+
+And at the board level, example for armada-8040-mcbin board:
+	&cp0_mdio {
+		ge_phy: ethernet-phy at 0 {
+			reg = <0>;
+		};
+	};
+
+	&cp0_xmdio {
+		phy0: ethernet-phy at 0 {
+			reg = <0>;
+		};
+
+		phy8: ethernet-phy at 8 {
+			reg = <8>;
+		};
+	};
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 9e21b28..3fc0a90 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -44,6 +44,8 @@ source "drivers/led/Kconfig"
 
 source "drivers/mailbox/Kconfig"
 
+source "drivers/mdio/Kconfig"
+
 source "drivers/memory/Kconfig"
 
 source "drivers/misc/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index a213ea9..041a7bf 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -82,6 +82,7 @@ obj-y += dfu/
 obj-$(CONFIG_X86) += pch/
 obj-y += phy/allwinner/
 obj-y += phy/marvell/
+obj-y += mdio/
 obj-y += rtc/
 obj-y += scsi/
 obj-y += sound/
diff --git a/drivers/mdio/Kconfig b/drivers/mdio/Kconfig
new file mode 100644
index 0000000..76e3758
--- /dev/null
+++ b/drivers/mdio/Kconfig
@@ -0,0 +1,18 @@
+#
+# MDIO infrastructure and drivers
+#
+
+menu "MDIO Support"
+
+config DM_MDIO
+	bool "Enable Driver Model for MDIO drivers"
+	depends on DM
+	help
+	  Enable driver model for MDIO access.
+	  Drivers provide methods to management data
+	  Input/Output.
+	  MDIO uclass provides interfaces to get mdio
+	  udevice or mii bus from its child phy node or
+	  an ethernet udevice which the phy belongs to.
+
+endmenu
diff --git a/drivers/mdio/Makefile b/drivers/mdio/Makefile
new file mode 100644
index 0000000..9b290c0
--- /dev/null
+++ b/drivers/mdio/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018 Marvell International Ltd.
+# Author: Ken Ma<make at marvell.com>
+
+obj-$(CONFIG_DM_MDIO) += mdio-uclass.o
diff --git a/drivers/mdio/mdio-uclass.c b/drivers/mdio/mdio-uclass.c
new file mode 100644
index 0000000..251776b
--- /dev/null
+++ b/drivers/mdio/mdio-uclass.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ * Author: Ken Ma<make at marvell.com>
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <dm/uclass.h>
+#include <dm/uclass-internal.h>
+#include <miiphy.h>
+#include <mdio.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int mdio_mii_bus_get(struct udevice *mdio_dev, struct mii_dev **bus)
+{
+	*bus = *(struct mii_dev **)dev_get_uclass_platdata(mdio_dev);
+
+	return 0;
+}
+
+int mdio_device_get_from_phy(int phy_node, struct udevice **devp)
+{
+	int mdio_off;
+
+	mdio_off = fdt_parent_offset(gd->fdt_blob, phy_node);
+	return uclass_get_device_by_of_offset(UCLASS_MDIO, mdio_off,
+					      devp);
+}
+
+int mdio_mii_bus_get_from_phy(int phy_node, struct mii_dev **bus)
+{
+	struct udevice *mdio_dev;
+	int ret;
+
+	ret = mdio_device_get_from_phy(phy_node, &mdio_dev);
+	if (ret)
+		return ret;
+
+	*bus = *(struct mii_dev **)dev_get_uclass_platdata(mdio_dev);
+
+	return 0;
+}
+
+int mdio_device_get_from_eth(struct udevice *eth, struct udevice **devp)
+{
+	int dev_node = dev_of_offset(eth);
+	int phy_node;
+
+	phy_node = fdtdec_lookup_phandle(gd->fdt_blob, dev_node, "phy");
+	if (phy_node > 0)
+		return mdio_device_get_from_phy(phy_node, devp);
+
+	/*
+	 * If there is no phy reference under the ethernet fdt node,
+	 * it is not an error since the ethernet device may do not use
+	 * mode; so in this case, the output mdio device pointer is set
+	 * as NULL.
+	 */
+	*devp = NULL;
+	return 0;
+}
+
+int mdio_mii_bus_get_from_eth(struct udevice *eth, struct mii_dev **bus)
+{
+	struct udevice *mdio_dev;
+	int ret;
+
+	ret = mdio_device_get_from_eth(eth, &mdio_dev);
+	if (ret)
+		return ret;
+
+	if (mdio_dev)
+		*bus = *(struct mii_dev **)dev_get_uclass_platdata(mdio_dev);
+	else
+		*bus = NULL;
+
+	return 0;
+}
+
+static int mdio_uclass_pre_probe(struct udevice *dev)
+{
+	struct mii_dev **pbus = dev_get_uclass_platdata(dev);
+	struct mii_dev *bus;
+	const char *name;
+
+	bus = mdio_alloc();
+	if (!bus) {
+		printf("Failed to allocate MDIO bus @%p\n",
+		       devfdt_get_addr_ptr(dev));
+		return -1;
+	}
+
+	name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
+			   "mdio-name", NULL);
+	if (name)
+		strncpy(bus->name, name, MDIO_NAME_LEN);
+	*pbus = bus;
+
+	return 0;
+}
+
+static int mdio_uclass_post_probe(struct udevice *dev)
+{
+	struct mii_dev **pbus = dev_get_uclass_platdata(dev);
+
+	return mdio_register(*pbus);
+}
+
+UCLASS_DRIVER(mdio) = {
+	.id		= UCLASS_MDIO,
+	.name		= "mdio",
+	.pre_probe	= mdio_uclass_pre_probe,
+	.post_probe	= mdio_uclass_post_probe,
+	.per_device_platdata_auto_alloc_size = sizeof(struct mii_dev *),
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index d7f9df3..170a0cc 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -49,6 +49,7 @@ enum uclass_id {
 	UCLASS_LPC,		/* x86 'low pin count' interface */
 	UCLASS_MAILBOX,		/* Mailbox controller */
 	UCLASS_MASS_STORAGE,	/* Mass storage device */
+	UCLASS_MDIO,		/* MDIO device */
 	UCLASS_MISC,		/* Miscellaneous device */
 	UCLASS_MMC,		/* SD / MMC card or chip */
 	UCLASS_MOD_EXP,		/* RSA Mod Exp device */
diff --git a/include/mdio.h b/include/mdio.h
new file mode 100644
index 0000000..50458b1
--- /dev/null
+++ b/include/mdio.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ * Author: Ken Ma<make at marvell.com>
+ */
+
+#ifndef _MDIO_H_
+#define _MDIO_H_
+
+#include <dm.h>	/* Because we dereference struct udevice here */
+#include <phy.h>
+
+/**
+ * mdio_mii_bus_get() - Get mii bus from mdio udevice
+ *
+ * @mdio_dev:	mdio udevice
+ * @bus:	mii bus
+ * @returns 0 on success, error code otherwise.
+ */
+int mdio_mii_bus_get(struct udevice *mdio_dev, struct mii_dev **bus);
+
+/**
+ * mdio_device_get_from_phy() - Get the mdio udevice which the phy belongs to
+ *
+ * @phy_node:	phy node offset
+ * @devp:	mdio udevice
+ * @returns 0 on success, error code otherwise.
+ */
+int mdio_device_get_from_phy(int phy_node, struct udevice **devp);
+
+/**
+ * mdio_mii_bus_get_from_phy() - Get the mii bus which the phy belongs to
+ *
+ * @phy_node:	phy node offset
+ * @bus:	mii bus
+ * @returns 0 on success, error code otherwise.
+ */
+int mdio_mii_bus_get_from_phy(int phy_node, struct mii_dev **bus);
+
+/**
+ * mdio_device_get_from_eth() - When there is a phy reference of "phy = <&...>"
+ *                      under an ethernet udevice fdt node, this function can
+ *                      get the mdio udevice which the phy belongs to
+ *
+ * @dev:	the ethernet udevice which contains the phy reference
+ * @devp:	mdio udevice
+ * @returns 0 on success, error code otherwise.
+ */
+int mdio_device_get_from_eth(struct udevice *eth, struct udevice **devp);
+
+/**
+ * mdio_mii_bus_get_from_eth() - When there is a phy reference of
+ *                      "phy = <&...>" under an ethernet udevice fdt node, this
+ *                      function can get the mii bus which the phy belongs to
+ *
+ * @eth:	the ethernet udevice which contains the phy reference
+ * @bus:	mii bus
+ * @returns 0 on success, error code otherwise.
+ */
+int mdio_mii_bus_get_from_eth(struct udevice *eth, struct mii_dev **bus);
+
+#endif /* _MDIO_H_ */
-- 
1.9.1



More information about the U-Boot mailing list