[U-Boot] [PATCH v3 2/2] mdio: add marvell MDIO driver
Stefan Roese
sr at denx.de
Wed Jun 13 13:46:48 UTC 2018
On 13.06.2018 06:37, make at marvell.com wrote:
> From: Ken Ma <make at marvell.com>
>
> This patch adds a separate driver for the MDIO interface of the
> Marvell Ethernet controllers based on driver model. There are two
> reasons to have a separate driver rather than including it inside
> the MAC driver itself:
> *) The MDIO interface is shared by all Ethernet ports, so a driver
> must guarantee non-concurrent accesses to this MDIO interface. The
> most logical way is to have a separate driver that handles this
> single MDIO interface, used by all Ethernet ports.
> *) The MDIO interface is the same between the existing mv643xx_eth
> driver and the new mvneta/mvpp2 driver. Even though it is for now
> only used by the mvneta/mvpp2 driver, it will in the future be
> used by the mv643xx_eth driver as well.
>
> This driver supports SMI IEEE for 802.3 Clause 22 and XSMI for IEEE
> 802.3 Clause 45.
>
> This patch also adds device tree binding for marvell MDIO driver.
>
> Signed-off-by: Ken Ma <make at marvell.com>
> Reviewed-by: Chris Packham <judge.packham at gmail.com>
> ---
>
> Changes in v3:
> - Move marvell mdio driver to driver/net/mdio folder;
> - Update codes according to mdio uclass implementation updates.
>
> Changes in v2:
> - Fix error printing:
> - Change some debug to pr_err;
> - mii bus has no parent member and it is not a udevice, so dev_err
> is changed to pr_err for mii bus error printings.
>
> MAINTAINERS | 1 +
> arch/arm/Kconfig | 1 +
> doc/device-tree-bindings/net/marvell-mdio.txt | 18 ++
> drivers/net/mdio/Kconfig | 10 ++
> drivers/net/mdio/Makefile | 1 +
> drivers/net/mdio/mvmdio.c | 234 ++++++++++++++++++++++++++
> 6 files changed, 265 insertions(+)
> create mode 100644 doc/device-tree-bindings/net/marvell-mdio.txt
> create mode 100644 drivers/net/mdio/mvmdio.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9e1fc83..d8584f9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -137,6 +137,7 @@ T: git git://git.denx.de/u-boot-marvell.git
> F: arch/arm/mach-kirkwood/
> F: arch/arm/mach-mvebu/
> F: drivers/ata/ahci_mvebu.c
> +F: drivers/net/mdio/mvmdio.c
>
> ARM MARVELL PXA
> M: Marek Vasut <marex at denx.de>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index dde422b..e52b164 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -432,6 +432,7 @@ config ARCH_MVEBU
> select DM_SPI
> select DM_SPI_FLASH
> select SPI
> + select MDIO
>
> config TARGET_DEVKIT3250
> bool "Support devkit3250"
> diff --git a/doc/device-tree-bindings/net/marvell-mdio.txt b/doc/device-tree-bindings/net/marvell-mdio.txt
> new file mode 100644
> index 0000000..55db435
> --- /dev/null
> +++ b/doc/device-tree-bindings/net/marvell-mdio.txt
> @@ -0,0 +1,18 @@
> +* Marvell MDIO Ethernet Controller interface
> +
> +The Ethernet controllers of the Marvel Armada 3700 and Armada 7k/8k
> +have an identical unit that provides an interface with the MDIO bus.
> +This driver handles this MDIO interface.
> +
> +Mandatory properties:
> +SoC specific:
> + - #address-cells: Must be <1>.
> + - #size-cells: Must be <0>.
> + - compatible: Should be "marvell,orion-mdio" (for SMI)
> + "marvell,xmdio" (for XSMI)
> + - reg: Base address and size SMI/XMSI bus.
> +
> +Optional properties:
> + - mdio-name - MDIO bus name
> +
> +For example, please refer to "mdio-bus.txt".
> diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig
> index 533cc4a..d1a31e6 100644
> --- a/drivers/net/mdio/Kconfig
> +++ b/drivers/net/mdio/Kconfig
> @@ -15,4 +15,14 @@ config MDIO
> udevice or mii bus from its child phy node or
> an ethernet udevice which the phy belongs to.
>
> +config MVMDIO
> + bool "Marvell MDIO interface support"
> + depends on MDIO
> + select PHYLIB
> + help
> + This driver supports the MDIO interface found in the network
> + interface units of the Marvell EBU SoCs (Kirkwood, Orion5x,
> + Dove, Armada 370, Armada XP, Armada 37xx and Armada7K/8K/8KP).
> +
> + This driver is used by the MVPP2 and MVNETA drivers.
> endmenu
> diff --git a/drivers/net/mdio/Makefile b/drivers/net/mdio/Makefile
> index 45ae502..8b2e5a4 100644
> --- a/drivers/net/mdio/Makefile
> +++ b/drivers/net/mdio/Makefile
> @@ -4,3 +4,4 @@
> # Author: Ken Ma<make at marvell.com>
>
> obj-$(CONFIG_MDIO) += mdio-uclass.o
> +obj-$(CONFIG_MVMDIO) += mvmdio.o
> diff --git a/drivers/net/mdio/mvmdio.c b/drivers/net/mdio/mvmdio.c
> new file mode 100644
> index 0000000..0fb45ce
> --- /dev/null
> +++ b/drivers/net/mdio/mvmdio.c
> @@ -0,0 +1,234 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2018 Marvell International Ltd.
> + * Author: Ken Ma<make at marvell.com>
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <dm/device-internal.h>
> +#include <dm/lists.h>
> +#include <miiphy.h>
> +#include <phy.h>
> +#include <asm/io.h>
> +
> +#define MVMDIO_SMI_DATA_SHIFT 0
> +#define MVMDIO_SMI_PHY_ADDR_SHIFT 16
> +#define MVMDIO_SMI_PHY_REG_SHIFT 21
> +#define MVMDIO_SMI_READ_OPERATION BIT(26)
> +#define MVMDIO_SMI_WRITE_OPERATION 0
> +#define MVMDIO_SMI_READ_VALID BIT(27)
> +#define MVMDIO_SMI_BUSY BIT(28)
> +
> +#define MVMDIO_XSMI_MGNT_REG 0x0
> +#define MVMDIO_XSMI_PHYADDR_SHIFT 16
> +#define MVMDIO_XSMI_DEVADDR_SHIFT 21
> +#define MVMDIO_XSMI_WRITE_OPERATION (0x5 << 26)
> +#define MVMDIO_XSMI_READ_OPERATION (0x7 << 26)
> +#define MVMDIO_XSMI_READ_VALID BIT(29)
> +#define MVMDIO_XSMI_BUSY BIT(30)
> +#define MVMDIO_XSMI_ADDR_REG 0x8
> +
> +#define MVMDIO_TIMEOUT 10000
> +
> +struct mvmdio_priv {
> + void *mdio_base;
> +};
> +
> +enum mvmdio_bus_type {
> + BUS_TYPE_SMI,
> + BUS_TYPE_XSMI
> +};
> +
> +/* Wait for the SMI unit to be ready for another operation */
> +static int mvmdio_smi_wait_ready(struct mii_dev *bus)
> +{
> + u32 timeout = MVMDIO_TIMEOUT;
> + struct mvmdio_priv *priv = bus->priv;
> + u32 smi_reg;
> +
> + /* Wait till the SMI is not busy */
> + do {
> + /* Read smi register */
> + smi_reg = readl(priv->mdio_base);
> + if (timeout-- == 0) {
> + pr_err("Error: SMI busy timeout\n");
> + return -ETIME;
> + }
> + } while (smi_reg & MVMDIO_SMI_BUSY);
> +
> + return 0;
> +}
You could use wait_for_bit_le32() here instead of implementing your
own custom busy wait polling function (include/wait_bit.h). This also
adds more accurate timeout handling (via timer).
Other than this:
Reviewed-by: Stefan Roese <sr at denx.de>
> +
> +static int mvmdio_smi_read(struct mii_dev *bus, int addr,
> + int devad, int reg)
> +{
> + struct mvmdio_priv *priv = bus->priv;
> + u32 val;
> + int ret;
> +
> + if (devad != MDIO_DEVAD_NONE)
> + return -EOPNOTSUPP;
> +
> + ret = mvmdio_smi_wait_ready(bus);
> + if (ret < 0)
> + return ret;
> +
> + writel(((addr << MVMDIO_SMI_PHY_ADDR_SHIFT) |
> + (reg << MVMDIO_SMI_PHY_REG_SHIFT) |
> + MVMDIO_SMI_READ_OPERATION),
> + priv->mdio_base);
> +
> + ret = mvmdio_smi_wait_ready(bus);
> + if (ret < 0)
> + return ret;
> +
> + val = readl(priv->mdio_base);
> + if (!(val & MVMDIO_SMI_READ_VALID)) {
> + pr_err("SMI bus read not valid\n");
> + return -ENODEV;
> + }
> +
> + return val & GENMASK(15, 0);
> +}
> +
> +static int mvmdio_smi_write(struct mii_dev *bus, int addr, int devad,
> + int reg, u16 value)
> +{
> + struct mvmdio_priv *priv = bus->priv;
> + int ret;
> +
> + if (devad != MDIO_DEVAD_NONE)
> + return -EOPNOTSUPP;
> +
> + ret = mvmdio_smi_wait_ready(bus);
> + if (ret < 0)
> + return ret;
> +
> + writel(((addr << MVMDIO_SMI_PHY_ADDR_SHIFT) |
> + (reg << MVMDIO_SMI_PHY_REG_SHIFT) |
> + MVMDIO_SMI_WRITE_OPERATION |
> + (value << MVMDIO_SMI_DATA_SHIFT)),
> + priv->mdio_base);
> +
> + return 0;
> +}
> +
> +static int mvmdio_xsmi_wait_ready(struct mii_dev *bus)
> +{
> + u32 timeout = MVMDIO_TIMEOUT;
> + struct mvmdio_priv *priv = bus->priv;
> + u32 xsmi_reg;
> +
> + /* Wait till the xSMI is not busy */
> + do {
> + /* Read xSMI register */
> + xsmi_reg = readl(priv->mdio_base);
> + if (timeout-- == 0) {
> + pr_err("xSMI busy time-out\n");
> + return -ETIME;
> + }
> + } while (xsmi_reg & MVMDIO_XSMI_BUSY);
> +
> + return 0;
> +}
Again, please use the already available wait bit functions.
Other than this:
Reviewed-by: Stefan Roese <sr at denx.de>
Thanks,
Stefan
More information about the U-Boot
mailing list