Merge branch 'next_net/phy_connect_dev' of https://source.denx.de/u-boot/custodians/u-boot-sh into next

This commit is contained in:
Tom Rini 2023-06-10 14:08:00 -04:00
commit 5b589e1396
14 changed files with 60 additions and 93 deletions

View file

@ -126,6 +126,8 @@
phy-handle = <&phy0>; phy-handle = <&phy0>;
phy0: ethernet-phy@0 { phy0: ethernet-phy@0 {
compatible = "ethernet-phy-id0007.c0f0",
"ethernet-phy-ieee802.3-c22";
reg = <0>; reg = <0>;
reset-gpios = <&port4 2 GPIO_ACTIVE_LOW>; reset-gpios = <&port4 2 GPIO_ACTIVE_LOW>;

View file

@ -52,6 +52,9 @@ CONFIG_SPI_FLASH_MACRONIX=y
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
CONFIG_BITBANGMII=y CONFIG_BITBANGMII=y
CONFIG_BITBANGMII_MULTI=y CONFIG_BITBANGMII_MULTI=y
CONFIG_PHY_SMSC=y
CONFIG_PHY_ETHERNET_ID=y
CONFIG_DM_ETH_PHY=y
CONFIG_SH_ETHER=y CONFIG_SH_ETHER=y
CONFIG_PINCTRL=y CONFIG_PINCTRL=y
CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR=y

View file

@ -695,6 +695,7 @@ config SUN8I_EMAC
config SH_ETHER config SH_ETHER
bool "Renesas SH Ethernet MAC" bool "Renesas SH Ethernet MAC"
select PHYLIB select PHYLIB
select PHY_ETHERNET_ID
help help
This driver supports the Ethernet for Renesas SH and ARM SoCs. This driver supports the Ethernet for Renesas SH and ARM SoCs.
@ -764,6 +765,7 @@ config RENESAS_RAVB
bool "Renesas Ethernet AVB MAC" bool "Renesas Ethernet AVB MAC"
depends on RCAR_64 depends on RCAR_64
select PHYLIB select PHYLIB
select PHY_ETHERNET_ID
help help
This driver implements support for the Ethernet AVB block in This driver implements support for the Ethernet AVB block in
Renesas M3 and H3 SoCs. Renesas M3 and H3 SoCs.

View file

@ -430,17 +430,11 @@ static int tse_mdio_init(const char *name, struct altera_tse_priv *priv)
static int tse_phy_init(struct altera_tse_priv *priv, void *dev) static int tse_phy_init(struct altera_tse_priv *priv, void *dev)
{ {
struct phy_device *phydev; struct phy_device *phydev;
unsigned int mask = 0xffffffff;
if (priv->phyaddr) phydev = phy_connect(priv->bus, -1, dev, priv->interface);
mask = 1 << priv->phyaddr;
phydev = phy_find_by_mask(priv->bus, mask);
if (!phydev) if (!phydev)
return -ENODEV; return -ENODEV;
phy_connect_dev(phydev, dev, priv->interface);
phydev->supported &= PHY_GBIT_FEATURES; phydev->supported &= PHY_GBIT_FEATURES;
phydev->advertising = phydev->supported; phydev->advertising = phydev->supported;

View file

@ -144,10 +144,18 @@ static int eth_phy_of_to_plat(struct udevice *dev)
uc_priv->reset_assert_delay = dev_read_u32_default(dev, "reset-assert-us", 0); uc_priv->reset_assert_delay = dev_read_u32_default(dev, "reset-assert-us", 0);
uc_priv->reset_deassert_delay = dev_read_u32_default(dev, "reset-deassert-us", 0); uc_priv->reset_deassert_delay = dev_read_u32_default(dev, "reset-deassert-us", 0);
/* These are used by some DTs, try these as a fallback. */
if (!uc_priv->reset_assert_delay && !uc_priv->reset_deassert_delay) {
uc_priv->reset_assert_delay =
dev_read_u32_default(dev, "reset-delay-us", 0);
uc_priv->reset_deassert_delay =
dev_read_u32_default(dev, "reset-post-delay-us", 0);
}
return 0; return 0;
} }
void eth_phy_reset(struct udevice *dev, int value) static void eth_phy_reset(struct udevice *dev, int value)
{ {
struct eth_phy_device_priv *uc_priv = dev_get_uclass_priv(dev); struct eth_phy_device_priv *uc_priv = dev_get_uclass_priv(dev);
u32 delay; u32 delay;

View file

@ -608,18 +608,16 @@ static int ethoc_mdio_init(const char *name, struct ethoc *priv)
static int ethoc_phy_init(struct ethoc *priv, void *dev) static int ethoc_phy_init(struct ethoc *priv, void *dev)
{ {
struct phy_device *phydev; struct phy_device *phydev;
int mask = 0xffffffff; int mask = -1;
#ifdef CONFIG_PHY_ADDR #ifdef CONFIG_PHY_ADDR
mask = 1 << CONFIG_PHY_ADDR; mask = CONFIG_PHY_ADDR;
#endif #endif
phydev = phy_find_by_mask(priv->bus, mask); phydev = phy_connect(priv->bus, mask, dev, PHY_INTERFACE_MODE_MII);
if (!phydev) if (!phydev)
return -ENODEV; return -ENODEV;
phy_connect_dev(phydev, dev, PHY_INTERFACE_MODE_MII);
phydev->supported &= PHY_BASIC_FEATURES; phydev->supported &= PHY_BASIC_FEATURES;
phydev->advertising = phydev->supported; phydev->advertising = phydev->supported;

View file

@ -414,16 +414,13 @@ static int pch_gbe_phy_init(struct udevice *dev)
struct pch_gbe_priv *priv = dev_get_priv(dev); struct pch_gbe_priv *priv = dev_get_priv(dev);
struct eth_pdata *plat = dev_get_plat(dev); struct eth_pdata *plat = dev_get_plat(dev);
struct phy_device *phydev; struct phy_device *phydev;
int mask = 0xffffffff;
phydev = phy_find_by_mask(priv->bus, mask); phydev = phy_connect(priv->bus, -1, dev, plat->phy_interface);
if (!phydev) { if (!phydev) {
printf("pch_gbe: cannot find the phy\n"); printf("pch_gbe: cannot find the phy\n");
return -1; return -1;
} }
phy_connect_dev(phydev, dev, plat->phy_interface);
phydev->supported &= PHY_GBIT_FEATURES; phydev->supported &= PHY_GBIT_FEATURES;
phydev->advertising = phydev->supported; phydev->advertising = phydev->supported;

View file

@ -7,6 +7,8 @@
#include <common.h> #include <common.h>
#include <dm/device_compat.h> #include <dm/device_compat.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <phy.h> #include <phy.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <asm/gpio.h> #include <asm/gpio.h>
@ -17,6 +19,8 @@ struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev,
struct phy_device *phydev; struct phy_device *phydev;
struct ofnode_phandle_args phandle_args; struct ofnode_phandle_args phandle_args;
struct gpio_desc gpio; struct gpio_desc gpio;
const char *node_name;
struct udevice *pdev;
ofnode node; ofnode node;
u32 id, assert, deassert; u32 id, assert, deassert;
u16 vendor, device; u16 vendor, device;
@ -72,5 +76,18 @@ struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev,
if (phydev) if (phydev)
phydev->node = node; phydev->node = node;
if (IS_ENABLED(CONFIG_DM_ETH_PHY) && ofnode_valid(node)) {
node_name = ofnode_get_name(node);
ret = device_bind_driver_to_node(dev, "eth_phy_generic_drv",
node_name, node,
&pdev);
if (ret)
return NULL;
ret = device_probe(pdev);
if (ret)
return NULL;
}
return phydev; return phydev;
} }

View file

@ -812,8 +812,8 @@ struct phy_device *phy_find_by_mask(struct mii_dev *bus, uint phy_mask)
return get_phy_device_by_mask(bus, phy_mask); return get_phy_device_by_mask(bus, phy_mask);
} }
void phy_connect_dev(struct phy_device *phydev, struct udevice *dev, static void phy_connect_dev(struct phy_device *phydev, struct udevice *dev,
phy_interface_t interface) phy_interface_t interface)
{ {
/* Soft Reset the PHY */ /* Soft Reset the PHY */
phy_reset(phydev); phy_reset(phydev);

View file

@ -131,7 +131,6 @@ struct ravb_priv {
struct mii_dev *bus; struct mii_dev *bus;
void __iomem *iobase; void __iomem *iobase;
struct clk_bulk clks; struct clk_bulk clks;
struct gpio_desc reset_gpio;
}; };
static inline void ravb_flush_dcache(u32 addr, u32 len) static inline void ravb_flush_dcache(u32 addr, u32 len)
@ -312,13 +311,6 @@ static int ravb_phy_config(struct udevice *dev)
struct phy_device *phydev; struct phy_device *phydev;
int reg; int reg;
if (dm_gpio_is_valid(&eth->reset_gpio)) {
dm_gpio_set_value(&eth->reset_gpio, 1);
mdelay(20);
dm_gpio_set_value(&eth->reset_gpio, 0);
mdelay(1);
}
phydev = phy_connect(eth->bus, -1, dev, pdata->phy_interface); phydev = phy_connect(eth->bus, -1, dev, pdata->phy_interface);
if (!phydev) if (!phydev)
return -ENODEV; return -ENODEV;
@ -503,7 +495,6 @@ static int ravb_probe(struct udevice *dev)
{ {
struct eth_pdata *pdata = dev_get_plat(dev); struct eth_pdata *pdata = dev_get_plat(dev);
struct ravb_priv *eth = dev_get_priv(dev); struct ravb_priv *eth = dev_get_priv(dev);
struct ofnode_phandle_args phandle_args;
struct mii_dev *mdiodev; struct mii_dev *mdiodev;
void __iomem *iobase; void __iomem *iobase;
int ret; int ret;
@ -515,17 +506,6 @@ static int ravb_probe(struct udevice *dev)
if (ret < 0) if (ret < 0)
goto err_mdio_alloc; goto err_mdio_alloc;
ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, &phandle_args);
if (!ret) {
gpio_request_by_name_nodev(phandle_args.node, "reset-gpios", 0,
&eth->reset_gpio, GPIOD_IS_OUT);
}
if (!dm_gpio_is_valid(&eth->reset_gpio)) {
gpio_request_by_name(dev, "reset-gpios", 0, &eth->reset_gpio,
GPIOD_IS_OUT);
}
mdiodev = mdio_alloc(); mdiodev = mdio_alloc();
if (!mdiodev) { if (!mdiodev) {
ret = -ENOMEM; ret = -ENOMEM;
@ -576,8 +556,6 @@ static int ravb_remove(struct udevice *dev)
free(eth->phydev); free(eth->phydev);
mdio_unregister(eth->bus); mdio_unregister(eth->bus);
mdio_free(eth->bus); mdio_free(eth->bus);
if (dm_gpio_is_valid(&eth->reset_gpio))
dm_gpio_free(dev, &eth->reset_gpio);
unmap_physmem(eth->iobase, MAP_NOCACHE); unmap_physmem(eth->iobase, MAP_NOCACHE);
return 0; return 0;

View file

@ -129,11 +129,11 @@ static int sh_eth_recv_start(struct sh_eth_dev *eth)
/* Check if the rx descriptor is ready */ /* Check if the rx descriptor is ready */
invalidate_cache(port_info->rx_desc_cur, sizeof(struct rx_desc_s)); invalidate_cache(port_info->rx_desc_cur, sizeof(struct rx_desc_s));
if (port_info->rx_desc_cur->rd0 & RD_RACT) if (port_info->rx_desc_cur->rd0 & RD_RACT)
return -EINVAL; return -EAGAIN;
/* Check for errors */ /* Check for errors */
if (port_info->rx_desc_cur->rd0 & RD_RFE) if (port_info->rx_desc_cur->rd0 & RD_RFE)
return -EINVAL; return 0;
return port_info->rx_desc_cur->rd1 & 0xffff; return port_info->rx_desc_cur->rd1 & 0xffff;
} }
@ -142,6 +142,8 @@ static void sh_eth_recv_finish(struct sh_eth_dev *eth)
{ {
struct sh_eth_info *port_info = &eth->port_info[eth->port]; struct sh_eth_info *port_info = &eth->port_info[eth->port];
invalidate_cache(ADDR_TO_P2(port_info->rx_desc_cur->rd2), MAX_BUF_SIZE);
/* Make current descriptor available again */ /* Make current descriptor available again */
if (port_info->rx_desc_cur->rd0 & RD_RDLE) if (port_info->rx_desc_cur->rd0 & RD_RDLE)
port_info->rx_desc_cur->rd0 = RD_RACT | RD_RDLE; port_info->rx_desc_cur->rd0 = RD_RACT | RD_RDLE;
@ -210,8 +212,6 @@ static int sh_eth_tx_desc_init(struct sh_eth_dev *eth)
goto err; goto err;
} }
flush_cache_wback(port_info->tx_desc_alloc, alloc_desc_size);
/* Make sure we use a P2 address (non-cacheable) */ /* Make sure we use a P2 address (non-cacheable) */
port_info->tx_desc_base = port_info->tx_desc_base =
(struct tx_desc_s *)ADDR_TO_P2((uintptr_t)port_info->tx_desc_alloc); (struct tx_desc_s *)ADDR_TO_P2((uintptr_t)port_info->tx_desc_alloc);
@ -229,6 +229,7 @@ static int sh_eth_tx_desc_init(struct sh_eth_dev *eth)
cur_tx_desc--; cur_tx_desc--;
cur_tx_desc->td0 |= TD_TDLE; cur_tx_desc->td0 |= TD_TDLE;
flush_cache_wback(port_info->tx_desc_alloc, alloc_desc_size);
/* /*
* Point the controller to the tx descriptor list. Must use physical * Point the controller to the tx descriptor list. Must use physical
* addresses * addresses
@ -264,8 +265,6 @@ static int sh_eth_rx_desc_init(struct sh_eth_dev *eth)
goto err; goto err;
} }
flush_cache_wback(port_info->rx_desc_alloc, alloc_desc_size);
/* Make sure we use a P2 address (non-cacheable) */ /* Make sure we use a P2 address (non-cacheable) */
port_info->rx_desc_base = port_info->rx_desc_base =
(struct rx_desc_s *)ADDR_TO_P2((uintptr_t)port_info->rx_desc_alloc); (struct rx_desc_s *)ADDR_TO_P2((uintptr_t)port_info->rx_desc_alloc);
@ -299,6 +298,9 @@ static int sh_eth_rx_desc_init(struct sh_eth_dev *eth)
cur_rx_desc--; cur_rx_desc--;
cur_rx_desc->rd0 |= RD_RDLE; cur_rx_desc->rd0 |= RD_RDLE;
invalidate_cache(port_info->rx_buf_alloc, NUM_RX_DESC * MAX_BUF_SIZE);
flush_cache_wback(port_info->rx_desc_alloc, alloc_desc_size);
/* Point the controller to the rx descriptor list */ /* Point the controller to the rx descriptor list */
sh_eth_write(port_info, ADDR_TO_PHY(port_info->rx_desc_base), RDLAR); sh_eth_write(port_info, ADDR_TO_PHY(port_info->rx_desc_base), RDLAR);
#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ) #if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
@ -530,7 +532,6 @@ struct sh_ether_priv {
struct mii_dev *bus; struct mii_dev *bus;
phys_addr_t iobase; phys_addr_t iobase;
struct clk clk; struct clk clk;
struct gpio_desc reset_gpio;
}; };
static int sh_ether_send(struct udevice *dev, void *packet, int len) static int sh_ether_send(struct udevice *dev, void *packet, int len)
@ -555,15 +556,13 @@ static int sh_ether_recv(struct udevice *dev, int flags, uchar **packetp)
*packetp = packet; *packetp = packet;
return len; return len;
} else {
len = 0;
/* Restart the receiver if disabled */
if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
sh_eth_write(port_info, EDRRR_R, EDRRR);
return -EAGAIN;
} }
/* Restart the receiver if disabled */
if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
sh_eth_write(port_info, EDRRR_R, EDRRR);
return len;
} }
static int sh_ether_free_pkt(struct udevice *dev, uchar *packet, int length) static int sh_ether_free_pkt(struct udevice *dev, uchar *packet, int length)
@ -601,14 +600,11 @@ static int sh_eth_phy_config(struct udevice *dev)
int ret = 0; int ret = 0;
struct sh_eth_info *port_info = &eth->port_info[eth->port]; struct sh_eth_info *port_info = &eth->port_info[eth->port];
struct phy_device *phydev; struct phy_device *phydev;
int mask = 0xffffffff;
phydev = phy_find_by_mask(priv->bus, mask); phydev = phy_connect(priv->bus, -1, dev, pdata->phy_interface);
if (!phydev) if (!phydev)
return -ENODEV; return -ENODEV;
phy_connect_dev(phydev, dev, pdata->phy_interface);
port_info->phydev = phydev; port_info->phydev = phydev;
phy_config(phydev); phy_config(phydev);
@ -653,7 +649,6 @@ static int sh_ether_probe(struct udevice *udev)
struct eth_pdata *pdata = dev_get_plat(udev); struct eth_pdata *pdata = dev_get_plat(udev);
struct sh_ether_priv *priv = dev_get_priv(udev); struct sh_ether_priv *priv = dev_get_priv(udev);
struct sh_eth_dev *eth = &priv->shdev; struct sh_eth_dev *eth = &priv->shdev;
struct ofnode_phandle_args phandle_args;
struct mii_dev *mdiodev; struct mii_dev *mdiodev;
int ret; int ret;
@ -664,18 +659,6 @@ static int sh_ether_probe(struct udevice *udev)
if (ret < 0) if (ret < 0)
return ret; return ret;
#endif #endif
ret = dev_read_phandle_with_args(udev, "phy-handle", NULL, 0, 0, &phandle_args);
if (!ret) {
gpio_request_by_name_nodev(phandle_args.node, "reset-gpios", 0,
&priv->reset_gpio, GPIOD_IS_OUT);
}
if (!dm_gpio_is_valid(&priv->reset_gpio)) {
gpio_request_by_name(udev, "reset-gpios", 0, &priv->reset_gpio,
GPIOD_IS_OUT);
}
mdiodev = mdio_alloc(); mdiodev = mdio_alloc();
if (!mdiodev) { if (!mdiodev) {
ret = -ENOMEM; ret = -ENOMEM;
@ -738,9 +721,6 @@ static int sh_ether_remove(struct udevice *udev)
mdio_unregister(priv->bus); mdio_unregister(priv->bus);
mdio_free(priv->bus); mdio_free(priv->bus);
if (dm_gpio_is_valid(&priv->reset_gpio))
dm_gpio_free(udev, &priv->reset_gpio);
return 0; return 0;
} }

View file

@ -391,14 +391,12 @@ static int ave_mdiobus_init(struct ave_private *priv, const char *name)
static int ave_phy_init(struct ave_private *priv, void *dev) static int ave_phy_init(struct ave_private *priv, void *dev)
{ {
struct phy_device *phydev; struct phy_device *phydev;
int mask = GENMASK(31, 0), ret; int ret;
phydev = phy_find_by_mask(priv->bus, mask); phydev = phy_connect(priv->bus, -1, dev, priv->phy_mode);
if (!phydev) if (!phydev)
return -ENODEV; return -ENODEV;
phy_connect_dev(phydev, dev, priv->phy_mode);
phydev->supported &= PHY_GBIT_FEATURES; phydev->supported &= PHY_GBIT_FEATURES;
if (priv->max_speed) { if (priv->max_speed) {
ret = phy_set_supported(phydev, priv->max_speed); ret = phy_set_supported(phydev, priv->max_speed);

View file

@ -248,10 +248,10 @@ static int emac_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
static int sunxi_emac_init_phy(struct emac_eth_dev *priv, void *dev) static int sunxi_emac_init_phy(struct emac_eth_dev *priv, void *dev)
{ {
int ret, mask = 0xffffffff; int ret, mask = -1;
#ifdef CONFIG_PHY_ADDR #ifdef CONFIG_PHY_ADDR
mask = 1 << CONFIG_PHY_ADDR; mask = CONFIG_PHY_ADDR;
#endif #endif
priv->bus = mdio_alloc(); priv->bus = mdio_alloc();
@ -269,11 +269,10 @@ static int sunxi_emac_init_phy(struct emac_eth_dev *priv, void *dev)
if (ret) if (ret)
return ret; return ret;
priv->phydev = phy_find_by_mask(priv->bus, mask); priv->phydev = phy_connect(priv->bus, mask, dev, PHY_INTERFACE_MODE_MII);
if (!priv->phydev) if (!priv->phydev)
return -ENODEV; return -ENODEV;
phy_connect_dev(priv->phydev, dev, PHY_INTERFACE_MODE_MII);
phy_config(priv->phydev); phy_config(priv->phydev);
return 0; return 0;

View file

@ -223,15 +223,6 @@ static inline struct phy_device *fixed_phy_create(ofnode node)
#endif #endif
/**
* phy_connect_dev() - Associates the given pair of PHY and Ethernet devices
* @phydev: PHY device
* @dev: Ethernet device
* @interface: type of MAC-PHY interface
*/
void phy_connect_dev(struct phy_device *phydev, struct udevice *dev,
phy_interface_t interface);
/** /**
* phy_connect() - Creates a PHY device for the Ethernet interface * phy_connect() - Creates a PHY device for the Ethernet interface
* Creates a PHY device for the PHY at the given address, if one doesn't exist * Creates a PHY device for the PHY at the given address, if one doesn't exist