mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-21 14:41:31 +00:00
net: designware: support phy reset device-tree bindings
Add support for the snps,reset-gpio, snps,reset-active-low (optional) and snps,reset-delays-us device-tree bindings. The combination of these three define how the PHY should be reset to ensure it's in a sane state. Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
6523dbf7cc
commit
90b7fc924a
2 changed files with 80 additions and 6 deletions
|
@ -24,7 +24,12 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
|
static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_DM_ETH
|
||||||
|
struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv);
|
||||||
|
struct eth_mac_regs *mac_p = priv->mac_regs_p;
|
||||||
|
#else
|
||||||
struct eth_mac_regs *mac_p = bus->priv;
|
struct eth_mac_regs *mac_p = bus->priv;
|
||||||
|
#endif
|
||||||
ulong start;
|
ulong start;
|
||||||
u16 miiaddr;
|
u16 miiaddr;
|
||||||
int timeout = CONFIG_MDIO_TIMEOUT;
|
int timeout = CONFIG_MDIO_TIMEOUT;
|
||||||
|
@ -47,7 +52,12 @@ static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
|
||||||
static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
|
static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
|
||||||
u16 val)
|
u16 val)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_DM_ETH
|
||||||
|
struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv);
|
||||||
|
struct eth_mac_regs *mac_p = priv->mac_regs_p;
|
||||||
|
#else
|
||||||
struct eth_mac_regs *mac_p = bus->priv;
|
struct eth_mac_regs *mac_p = bus->priv;
|
||||||
|
#endif
|
||||||
ulong start;
|
ulong start;
|
||||||
u16 miiaddr;
|
u16 miiaddr;
|
||||||
int ret = -ETIMEDOUT, timeout = CONFIG_MDIO_TIMEOUT;
|
int ret = -ETIMEDOUT, timeout = CONFIG_MDIO_TIMEOUT;
|
||||||
|
@ -70,7 +80,41 @@ static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dw_mdio_init(const char *name, struct eth_mac_regs *mac_regs_p)
|
#if CONFIG_DM_ETH
|
||||||
|
static int dw_mdio_reset(struct mii_dev *bus)
|
||||||
|
{
|
||||||
|
struct udevice *dev = bus->priv;
|
||||||
|
struct dw_eth_dev *priv = dev_get_priv(dev);
|
||||||
|
struct dw_eth_pdata *pdata = dev_get_platdata(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!dm_gpio_is_valid(&priv->reset_gpio))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* reset the phy */
|
||||||
|
ret = dm_gpio_set_value(&priv->reset_gpio, 0);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
udelay(pdata->reset_delays[0]);
|
||||||
|
|
||||||
|
ret = dm_gpio_set_value(&priv->reset_gpio, 1);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
udelay(pdata->reset_delays[1]);
|
||||||
|
|
||||||
|
ret = dm_gpio_set_value(&priv->reset_gpio, 0);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
udelay(pdata->reset_delays[2]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int dw_mdio_init(const char *name, void *priv)
|
||||||
{
|
{
|
||||||
struct mii_dev *bus = mdio_alloc();
|
struct mii_dev *bus = mdio_alloc();
|
||||||
|
|
||||||
|
@ -82,8 +126,11 @@ static int dw_mdio_init(const char *name, struct eth_mac_regs *mac_regs_p)
|
||||||
bus->read = dw_mdio_read;
|
bus->read = dw_mdio_read;
|
||||||
bus->write = dw_mdio_write;
|
bus->write = dw_mdio_write;
|
||||||
snprintf(bus->name, sizeof(bus->name), "%s", name);
|
snprintf(bus->name, sizeof(bus->name), "%s", name);
|
||||||
|
#ifdef CONFIG_DM_ETH
|
||||||
|
bus->reset = dw_mdio_reset;
|
||||||
|
#endif
|
||||||
|
|
||||||
bus->priv = (void *)mac_regs_p;
|
bus->priv = priv;
|
||||||
|
|
||||||
return mdio_register(bus);
|
return mdio_register(bus);
|
||||||
}
|
}
|
||||||
|
@ -606,7 +653,7 @@ static int designware_eth_probe(struct udevice *dev)
|
||||||
priv->interface = pdata->phy_interface;
|
priv->interface = pdata->phy_interface;
|
||||||
priv->max_speed = pdata->max_speed;
|
priv->max_speed = pdata->max_speed;
|
||||||
|
|
||||||
dw_mdio_init(dev->name, priv->mac_regs_p);
|
dw_mdio_init(dev->name, dev);
|
||||||
priv->bus = miiphy_get_dev_by_name(dev->name);
|
priv->bus = miiphy_get_dev_by_name(dev->name);
|
||||||
|
|
||||||
ret = dw_phy_init(priv, dev);
|
ret = dw_phy_init(priv, dev);
|
||||||
|
@ -637,9 +684,13 @@ static const struct eth_ops designware_eth_ops = {
|
||||||
|
|
||||||
static int designware_eth_ofdata_to_platdata(struct udevice *dev)
|
static int designware_eth_ofdata_to_platdata(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct eth_pdata *pdata = dev_get_platdata(dev);
|
struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
|
||||||
|
struct dw_eth_dev *priv = dev_get_priv(dev);
|
||||||
|
struct eth_pdata *pdata = &dw_pdata->eth_pdata;
|
||||||
const char *phy_mode;
|
const char *phy_mode;
|
||||||
const fdt32_t *cell;
|
const fdt32_t *cell;
|
||||||
|
int reset_flags = GPIOD_IS_OUT;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
pdata->iobase = dev_get_addr(dev);
|
pdata->iobase = dev_get_addr(dev);
|
||||||
pdata->phy_interface = -1;
|
pdata->phy_interface = -1;
|
||||||
|
@ -656,7 +707,20 @@ static int designware_eth_ofdata_to_platdata(struct udevice *dev)
|
||||||
if (cell)
|
if (cell)
|
||||||
pdata->max_speed = fdt32_to_cpu(*cell);
|
pdata->max_speed = fdt32_to_cpu(*cell);
|
||||||
|
|
||||||
return 0;
|
if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
|
||||||
|
"snps,reset-active-low"))
|
||||||
|
reset_flags |= GPIOD_ACTIVE_LOW;
|
||||||
|
|
||||||
|
ret = gpio_request_by_name(dev, "snps,reset-gpio", 0,
|
||||||
|
&priv->reset_gpio, reset_flags);
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
|
||||||
|
"snps,reset-delays-us", dw_pdata->reset_delays, 3);
|
||||||
|
} else if (ret == -ENOENT) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct udevice_id designware_eth_ids[] = {
|
static const struct udevice_id designware_eth_ids[] = {
|
||||||
|
@ -675,7 +739,7 @@ U_BOOT_DRIVER(eth_designware) = {
|
||||||
.remove = designware_eth_remove,
|
.remove = designware_eth_remove,
|
||||||
.ops = &designware_eth_ops,
|
.ops = &designware_eth_ops,
|
||||||
.priv_auto_alloc_size = sizeof(struct dw_eth_dev),
|
.priv_auto_alloc_size = sizeof(struct dw_eth_dev),
|
||||||
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
|
.platdata_auto_alloc_size = sizeof(struct dw_eth_pdata),
|
||||||
.flags = DM_FLAG_ALLOC_PRIV_DMA,
|
.flags = DM_FLAG_ALLOC_PRIV_DMA,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#ifndef _DW_ETH_H
|
#ifndef _DW_ETH_H
|
||||||
#define _DW_ETH_H
|
#define _DW_ETH_H
|
||||||
|
|
||||||
|
#include <asm/gpio.h>
|
||||||
|
|
||||||
#define CONFIG_TX_DESCR_NUM 16
|
#define CONFIG_TX_DESCR_NUM 16
|
||||||
#define CONFIG_RX_DESCR_NUM 16
|
#define CONFIG_RX_DESCR_NUM 16
|
||||||
#define CONFIG_ETH_BUFSIZE 2048
|
#define CONFIG_ETH_BUFSIZE 2048
|
||||||
|
@ -232,8 +234,16 @@ struct dw_eth_dev {
|
||||||
#ifndef CONFIG_DM_ETH
|
#ifndef CONFIG_DM_ETH
|
||||||
struct eth_device *dev;
|
struct eth_device *dev;
|
||||||
#endif
|
#endif
|
||||||
|
struct gpio_desc reset_gpio;
|
||||||
struct phy_device *phydev;
|
struct phy_device *phydev;
|
||||||
struct mii_dev *bus;
|
struct mii_dev *bus;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_DM_ETH
|
||||||
|
struct dw_eth_pdata {
|
||||||
|
struct eth_pdata eth_pdata;
|
||||||
|
u32 reset_delays[3];
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue