diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/sun8i_emac.c | 7 | ||||
-rw-r--r-- | drivers/net/sunxi_emac.c | 38 |
2 files changed, 45 insertions, 0 deletions
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index 04c3274fbe1..4ba9ee1529e 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -29,6 +29,7 @@ #include <net.h> #include <reset.h> #include <wait_bit.h> +#include <power/regulator.h> #define MDIO_CMD_MII_BUSY BIT(0) #define MDIO_CMD_MII_WRITE BIT(1) @@ -170,6 +171,7 @@ struct emac_eth_dev { #if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc reset_gpio; #endif + struct udevice *phy_reg; }; @@ -720,6 +722,9 @@ static int sun8i_emac_eth_probe(struct udevice *dev) sun8i_emac_set_syscon(sun8i_pdata, priv); + if (priv->phy_reg) + regulator_set_enable(priv->phy_reg, true); + sun8i_mdio_init(dev->name, dev); priv->bus = miiphy_get_dev_by_name(dev->name); @@ -829,6 +834,8 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev) priv->sysctl_reg = (void *)syscon_base + priv->variant->syscon_offset; + device_get_supply_regulator(dev, "phy-supply", &priv->phy_reg); + pdata->phy_interface = -1; priv->phyaddr = -1; priv->use_internal_phy = false; diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c index 4c90d4b4981..f546ad1fe8d 100644 --- a/drivers/net/sunxi_emac.c +++ b/drivers/net/sunxi_emac.c @@ -17,6 +17,7 @@ #include <net.h> #include <asm/io.h> #include <asm/arch/clock.h> +#include <power/regulator.h> /* EMAC register */ struct emac_regs { @@ -165,6 +166,7 @@ struct emac_eth_dev { struct phy_device *phydev; int link_printed; uchar rx_buf[EMAC_RX_BUFSIZE]; + struct udevice *phy_reg; }; struct emac_rxhdr { @@ -572,6 +574,9 @@ static int sunxi_emac_eth_probe(struct udevice *dev) if (ret) return ret; + if (priv->phy_reg) + regulator_set_enable(priv->phy_reg, true); + return sunxi_emac_init_phy(priv, dev); } @@ -585,9 +590,42 @@ static const struct eth_ops sunxi_emac_eth_ops = { static int sunxi_emac_eth_of_to_plat(struct udevice *dev) { struct eth_pdata *pdata = dev_get_plat(dev); + struct emac_eth_dev *priv = dev_get_priv(dev); + struct ofnode_phandle_args args; + ofnode phy_node, mdio_node; + int ret; pdata->iobase = dev_read_addr(dev); + phy_node = dev_get_phy_node(dev); + if (!ofnode_valid(phy_node)) { + dev_err(dev, "failed to get PHY node\n"); + return -ENOENT; + } + /* + * The PHY regulator is in the MDIO node, not the EMAC or PHY node. + * U-Boot does not have (and does not need) a device driver for the + * MDIO device, so just "pass through" that DT node to get to the + * regulator phandle. + * The PHY regulator is optional, though: ignore if we cannot find + * a phy-supply property. + */ + mdio_node = ofnode_get_parent(phy_node); + ret= ofnode_parse_phandle_with_args(mdio_node, "phy-supply", NULL, 0, 0, + &args); + if (ret && ret != -ENOENT) { + dev_err(dev, "failed to get PHY supply node\n"); + return ret; + } + if (!ret) { + ret = uclass_get_device_by_ofnode(UCLASS_REGULATOR, args.node, + &priv->phy_reg); + if (ret) { + dev_err(dev, "failed to get PHY regulator node\n"); + return ret; + } + } + return 0; } |