
Hi Ken,
Thanks for tackling this.
On Wed, Jun 6, 2018 at 9:08 PM, make@marvell.com wrote:
From: Ken Ma make@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@marvell.com
Changes in v2: None
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 +++++++++++++++++++++++++++++
I think this should live in drivers/net. It will pretty much always be implemented by a NIC driver as a subset functionality.
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@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@12a200 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "marvell,orion-mdio";
reg = <0x12a200 0x10>;
mdio-name = "cp0-mdio";
};
cp0_xmdio: mdio@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@0 {
reg = <0>;
};
};
&cp0_xmdio {
phy0: ethernet-phy@0 {
reg = <0>;
};
phy8: ethernet-phy@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 Mamake@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 Mamake@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 Mamake@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
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot