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

Joe Hershberger joe.hershberger at ni.com
Tue Jun 12 00:24:34 UTC 2018


Hi Ken,

Thanks for tackling this.

On Wed, Jun 6, 2018 at 9:08 PM,  <make at marvell.com> wrote:
> 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>
> ---
>
> 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 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
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot


More information about the U-Boot mailing list