Re: [PATCH 1/7] net: davinci_mdio: separate driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello.

This patch caused a build conflict with ARCH_AM33XX.
Probably ARCH_OMAP3 should be replaced with ARCH_OMAP.

PATH=$PATH:/usr/local/usr5/bin CROSS_COMPILE=arm-buildroot-linux-gnueabihf- make
ARCH=arm mm_am335x_defconfig

WARNING: unmet direct dependencies detected for DRIVER_NET_TI_DAVINCI_MDIO
 Depends on [n]: NET [=y] && (ARCH_OMAP3 [=n] || ARCH_K3 [=n] || COMPILE_TEST [
=n])
 Selected by [y]:
 - DRIVER_NET_CPSW [=y] && NET [=y] && ARCH_OMAP [=y]

WARNING: unmet direct dependencies detected for DRIVER_NET_TI_DAVINCI_MDIO
 Depends on [n]: NET [=y] && (ARCH_OMAP3 [=n] || ARCH_K3 [=n] || COMPILE_TEST [
=n])
 Selected by [y]:
 - DRIVER_NET_CPSW [=y] && NET [=y] && ARCH_OMAP [=y]

пт, 8 нояб. 2024 г. в 16:15, Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>:
>
> The davinci MDIO driver can be reused for the CPSW found on TI K3 SoCs
> which needs a new ethernet driver. Separate the MDIO driver from the
> CPSW driver to make it usable with other ethernet drivers.
>
> Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
> ---
>  drivers/net/Kconfig        |   5 ++
>  drivers/net/Makefile       |   1 +
>  drivers/net/cpsw.c         | 178 ------------------------------------------
>  drivers/net/davinci_mdio.c | 188 +++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 194 insertions(+), 178 deletions(-)
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 13e9ff6924..7f0d277548 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -53,8 +53,13 @@ config DRIVER_NET_CS8900
>  config DRIVER_NET_CPSW
>         bool "CPSW ethernet driver"
>         depends on ARCH_OMAP
> +       select DRIVER_NET_TI_DAVINCI_MDIO
>         select PHYLIB
>
> +config DRIVER_NET_TI_DAVINCI_MDIO
> +       bool "TI Davinci MDIO driver"
> +       depends on ARCH_OMAP3 || COMPILE_TEST
> +
>  config DRIVER_NET_DAVINCI_EMAC
>         bool "TI Davinci/OMAP EMAC ethernet driver"
>         depends on ARCH_OMAP3
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 207345cfa3..b451813f7c 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -10,6 +10,7 @@ obj-$(CONFIG_DRIVER_NET_BCMGENET)     += bcmgenet.o
>  obj-$(CONFIG_DRIVER_NET_CS8900)                += cs8900.o
>  obj-$(CONFIG_DRIVER_NET_CPSW)          += cpsw.o
>  obj-$(CONFIG_DRIVER_NET_DAVINCI_EMAC)  += davinci_emac.o
> +obj-$(CONFIG_DRIVER_NET_TI_DAVINCI_MDIO) += davinci_mdio.o
>  obj-$(CONFIG_DRIVER_NET_DESIGNWARE)    += designware.o
>  obj-$(CONFIG_DRIVER_NET_DESIGNWARE_GENERIC) += designware_generic.o
>  obj-$(CONFIG_DRIVER_NET_DESIGNWARE_SOCFPGA) += designware_socfpga.o
> diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
> index 3e4f6502f9..b11930fdd0 100644
> --- a/drivers/net/cpsw.c
> +++ b/drivers/net/cpsw.c
> @@ -28,8 +28,6 @@
>  #define CPSW_VERSION_2         0x19010c
>
>  #define BITMASK(bits)          ((1 << (bits)) - 1)
> -#define PHY_REG_MASK           0x1f
> -#define PHY_ID_MASK            0x1f
>  #define NUM_DESCS              (PKTBUFSRX * 2)
>  #define PKT_MIN                        60
>  #define PKT_MAX                        (1500 + 14 + 4 + 4)
> @@ -60,34 +58,6 @@
>
>  #define SLIVER_SIZE            0x40
>
> -struct cpsw_mdio_regs {
> -       u32     version;
> -       u32     control;
> -#define CONTROL_IDLE           (1 << 31)
> -#define CONTROL_ENABLE         (1 << 30)
> -
> -       u32     alive;
> -       u32     link;
> -       u32     linkintraw;
> -       u32     linkintmasked;
> -       u32     __reserved_0[2];
> -       u32     userintraw;
> -       u32     userintmasked;
> -       u32     userintmaskset;
> -       u32     userintmaskclr;
> -       u32     __reserved_1[20];
> -
> -       struct {
> -               u32 access;
> -               u32 physel;
> -#define USERACCESS_GO          (1 << 31)
> -#define USERACCESS_WRITE       (1 << 30)
> -#define USERACCESS_ACK         (1 << 29)
> -#define USERACCESS_READ                (0)
> -#define USERACCESS_DATA                (0xffff)
> -       } user[0];
> -};
> -
>  struct cpsw_regs {
>         u32     id_ver;
>         u32     control;
> @@ -226,12 +196,6 @@ struct cpsw_priv {
>         struct cpsw_slave               *slaves;
>  };
>
> -struct cpsw_mdio_priv {
> -       struct device                   *dev;
> -       struct mii_bus                  miibus;
> -       struct cpsw_mdio_regs           *mdio_regs;
> -};
> -
>  static int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
>  {
>         int idx;
> @@ -524,148 +488,6 @@ static inline void cpsw_ale_port_state(struct cpsw_priv *priv, int port,
>         writel(tmp, priv->ale_regs + offset);
>  }
>
> -/* wait until hardware is ready for another user access */
> -static u32 wait_for_user_access(struct cpsw_mdio_priv *priv)
> -{
> -       struct cpsw_mdio_regs *mdio_regs = priv->mdio_regs;
> -       u32 tmp;
> -       uint64_t start = get_time_ns();
> -
> -       do {
> -               tmp = readl(&mdio_regs->user[0].access);
> -
> -               if (!(tmp & USERACCESS_GO))
> -                       break;
> -
> -               if (is_timeout(start, 100 * MSECOND)) {
> -                       dev_err(priv->dev, "timeout waiting for user access\n");
> -                       break;
> -               }
> -       } while (1);
> -
> -       return tmp;
> -}
> -
> -static int cpsw_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)
> -{
> -       struct cpsw_mdio_priv *priv = bus->priv;
> -       struct cpsw_mdio_regs *mdio_regs = priv->mdio_regs;
> -
> -       u32 tmp;
> -
> -       if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
> -               return -EINVAL;
> -
> -       wait_for_user_access(priv);
> -
> -       tmp = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) |
> -              (phy_id << 16));
> -       writel(tmp, &mdio_regs->user[0].access);
> -
> -       tmp = wait_for_user_access(priv);
> -
> -       return (tmp & USERACCESS_ACK) ? (tmp & USERACCESS_DATA) : -1;
> -}
> -
> -static int cpsw_mdio_write(struct mii_bus *bus, int phy_id, int phy_reg, u16 value)
> -{
> -       struct cpsw_mdio_priv *priv = bus->priv;
> -       struct cpsw_mdio_regs *mdio_regs = priv->mdio_regs;
> -       u32 tmp;
> -
> -       if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
> -               return -EINVAL;
> -
> -       wait_for_user_access(priv);
> -       tmp = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) |
> -                  (phy_id << 16) | (value & USERACCESS_DATA));
> -       writel(tmp, &mdio_regs->user[0].access);
> -       wait_for_user_access(priv);
> -
> -       return 0;
> -}
> -
> -static int cpsw_mdio_probe(struct device *dev)
> -{
> -       struct resource *iores;
> -       struct cpsw_mdio_priv *priv;
> -       uint64_t start;
> -       uint32_t phy_mask;
> -       int ret;
> -
> -       priv = xzalloc(sizeof(*priv));
> -
> -       /* If we can't request I/O memory region, we'll assume parent did
> -        * it for us
> -        */
> -       iores = dev_request_mem_resource(dev, 0);
> -       if (IS_ERR(iores) && PTR_ERR(iores) == -EBUSY)
> -               iores = dev_get_resource(dev, IORESOURCE_MEM, 0);
> -       if (IS_ERR(iores))
> -               return PTR_ERR(iores);
> -       priv->mdio_regs = IOMEM(iores->start);
> -       priv->miibus.read = cpsw_mdio_read;
> -       priv->miibus.write = cpsw_mdio_write;
> -       priv->miibus.priv = priv;
> -       priv->miibus.parent = dev;
> -
> -       /*
> -        * set enable and clock divider
> -        *
> -        * FIXME: Use a clock to calculate the divider
> -        */
> -       writel(0xff | CONTROL_ENABLE, &priv->mdio_regs->control);
> -
> -       /*
> -        * wait for scan logic to settle:
> -        * the scan time consists of (a) a large fixed component, and (b) a
> -        * small component that varies with the mii bus frequency.  These
> -        * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x
> -        * silicon.  Since the effect of (b) was found to be largely
> -        * negligible, we keep things simple here.
> -        */
> -       udelay(2000);
> -
> -       start = get_time_ns();
> -       while (1) {
> -               phy_mask = readl(&priv->mdio_regs->alive);
> -               if (phy_mask) {
> -                       dev_info(dev, "detected phy mask 0x%x\n", phy_mask);
> -                       phy_mask = ~phy_mask;
> -                       break;
> -               }
> -               if (is_timeout(start, 256 * MSECOND)) {
> -                       dev_err(dev, "no live phy, scanning all\n");
> -                       phy_mask = 0;
> -                       break;
> -               }
> -       }
> -
> -       priv->miibus.phy_mask = phy_mask;
> -
> -       ret = mdiobus_register(&priv->miibus);
> -       if (ret)
> -               return ret;
> -
> -       return 0;
> -}
> -
> -static __maybe_unused struct of_device_id cpsw_mdio_dt_ids[] = {
> -       {
> -               .compatible = "ti,cpsw-mdio",
> -       }, {
> -               /* sentinel */
> -       }
> -};
> -MODULE_DEVICE_TABLE(of, cpsw_mdio_dt_ids);
> -
> -static struct driver cpsw_mdio_driver = {
> -       .name   = "cpsw-mdio",
> -       .probe  = cpsw_mdio_probe,
> -       .of_compatible = DRV_OF_COMPAT(cpsw_mdio_dt_ids),
> -};
> -coredevice_platform_driver(cpsw_mdio_driver);
> -
>  static inline void soft_reset(struct cpsw_priv *priv, void *reg)
>  {
>         int ret;
> diff --git a/drivers/net/davinci_mdio.c b/drivers/net/davinci_mdio.c
> new file mode 100644
> index 0000000000..c5cd28fba4
> --- /dev/null
> +++ b/drivers/net/davinci_mdio.c
> @@ -0,0 +1,188 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * DaVinci MDIO Module driver
> + */
> +#include <driver.h>
> +#include <linux/phy.h>
> +#include <clock.h>
> +#include <xfuncs.h>
> +#include <io.h>
> +
> +#define PHY_REG_MASK           0x1f
> +#define PHY_ID_MASK            0x1f
> +
> +struct cpsw_mdio_regs {
> +       u32     version;
> +       u32     control;
> +#define CONTROL_IDLE           (1 << 31)
> +#define CONTROL_ENABLE         (1 << 30)
> +
> +       u32     alive;
> +       u32     link;
> +       u32     linkintraw;
> +       u32     linkintmasked;
> +       u32     __reserved_0[2];
> +       u32     userintraw;
> +       u32     userintmasked;
> +       u32     userintmaskset;
> +       u32     userintmaskclr;
> +       u32     __reserved_1[20];
> +
> +       struct {
> +               u32 access;
> +               u32 physel;
> +#define USERACCESS_GO          (1 << 31)
> +#define USERACCESS_WRITE       (1 << 30)
> +#define USERACCESS_ACK         (1 << 29)
> +#define USERACCESS_READ                (0)
> +#define USERACCESS_DATA                (0xffff)
> +       } user[0];
> +};
> +
> +struct cpsw_mdio_priv {
> +       struct device                   *dev;
> +       struct mii_bus                  miibus;
> +       struct cpsw_mdio_regs           *mdio_regs;
> +};
> +
> +/* wait until hardware is ready for another user access */
> +static u32 wait_for_user_access(struct cpsw_mdio_priv *priv)
> +{
> +       struct cpsw_mdio_regs *mdio_regs = priv->mdio_regs;
> +       u32 tmp;
> +       uint64_t start = get_time_ns();
> +
> +       do {
> +               tmp = readl(&mdio_regs->user[0].access);
> +
> +               if (!(tmp & USERACCESS_GO))
> +                       break;
> +
> +               if (is_timeout(start, 100 * MSECOND)) {
> +                       dev_err(priv->dev, "timeout waiting for user access\n");
> +                       break;
> +               }
> +       } while (1);
> +
> +       return tmp;
> +}
> +
> +static int cpsw_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)
> +{
> +       struct cpsw_mdio_priv *priv = bus->priv;
> +       struct cpsw_mdio_regs *mdio_regs = priv->mdio_regs;
> +
> +       u32 tmp;
> +
> +       if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
> +               return -EINVAL;
> +
> +       wait_for_user_access(priv);
> +
> +       tmp = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) |
> +              (phy_id << 16));
> +       writel(tmp, &mdio_regs->user[0].access);
> +
> +       tmp = wait_for_user_access(priv);
> +
> +       return (tmp & USERACCESS_ACK) ? (tmp & USERACCESS_DATA) : -1;
> +}
> +
> +static int cpsw_mdio_write(struct mii_bus *bus, int phy_id, int phy_reg, u16 value)
> +{
> +       struct cpsw_mdio_priv *priv = bus->priv;
> +       struct cpsw_mdio_regs *mdio_regs = priv->mdio_regs;
> +       u32 tmp;
> +
> +       if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
> +               return -EINVAL;
> +
> +       wait_for_user_access(priv);
> +       tmp = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) |
> +                  (phy_id << 16) | (value & USERACCESS_DATA));
> +       writel(tmp, &mdio_regs->user[0].access);
> +       wait_for_user_access(priv);
> +
> +       return 0;
> +}
> +
> +static int cpsw_mdio_probe(struct device *dev)
> +{
> +       struct resource *iores;
> +       struct cpsw_mdio_priv *priv;
> +       uint64_t start;
> +       uint32_t phy_mask;
> +       int ret;
> +
> +       priv = xzalloc(sizeof(*priv));
> +
> +       /* If we can't request I/O memory region, we'll assume parent did
> +        * it for us
> +        */
> +       iores = dev_request_mem_resource(dev, 0);
> +       if (IS_ERR(iores) && PTR_ERR(iores) == -EBUSY)
> +               iores = dev_get_resource(dev, IORESOURCE_MEM, 0);
> +       if (IS_ERR(iores))
> +               return PTR_ERR(iores);
> +       priv->mdio_regs = IOMEM(iores->start);
> +       priv->miibus.read = cpsw_mdio_read;
> +       priv->miibus.write = cpsw_mdio_write;
> +       priv->miibus.priv = priv;
> +       priv->miibus.parent = dev;
> +
> +       /*
> +        * set enable and clock divider
> +        *
> +        * FIXME: Use a clock to calculate the divider
> +        */
> +       writel(0xff | CONTROL_ENABLE, &priv->mdio_regs->control);
> +
> +       /*
> +        * wait for scan logic to settle:
> +        * the scan time consists of (a) a large fixed component, and (b) a
> +        * small component that varies with the mii bus frequency.  These
> +        * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x
> +        * silicon.  Since the effect of (b) was found to be largely
> +        * negligible, we keep things simple here.
> +        */
> +       udelay(2000);
> +
> +       start = get_time_ns();
> +       while (1) {
> +               phy_mask = readl(&priv->mdio_regs->alive);
> +               if (phy_mask) {
> +                       dev_info(dev, "detected phy mask 0x%x\n", phy_mask);
> +                       phy_mask = ~phy_mask;
> +                       break;
> +               }
> +               if (is_timeout(start, 256 * MSECOND)) {
> +                       dev_err(dev, "no live phy, scanning all\n");
> +                       phy_mask = 0;
> +                       break;
> +               }
> +       }
> +
> +       priv->miibus.phy_mask = phy_mask;
> +
> +       ret = mdiobus_register(&priv->miibus);
> +       if (ret)
> +               return ret;
> +
> +       return 0;
> +}
> +
> +static __maybe_unused struct of_device_id cpsw_mdio_dt_ids[] = {
> +       {
> +               .compatible = "ti,cpsw-mdio",
> +       }, {
> +               /* sentinel */
> +       }
> +};
> +MODULE_DEVICE_TABLE(of, cpsw_mdio_dt_ids);
> +
> +static struct driver cpsw_mdio_driver = {
> +       .name   = "cpsw-mdio",
> +       .probe  = cpsw_mdio_probe,
> +       .of_compatible = DRV_OF_COMPAT(cpsw_mdio_dt_ids),
> +};
> +coredevice_platform_driver(cpsw_mdio_driver);
>
> --
> 2.39.5
>
>





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux