diff options
author | Tom Rini <trini@konsulko.com> | 2016-05-27 19:48:53 (GMT) |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2016-05-27 19:48:53 (GMT) |
commit | 378f9134eba4665ea94a63653393d25418665fda (patch) | |
tree | e273a03c52e8261c0f6c401914d44a9eff442684 /drivers/net | |
parent | 9b77b19178446393fce2e74554815c17454f8da8 (diff) | |
parent | 2ed6dc83380ea2f49ec09556c14c6eddd3f5c27a (diff) | |
download | u-boot-378f9134eba4665ea94a63653393d25418665fda.tar.xz |
Merge git://git.denx.de/u-boot-rockchip
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/designware.c | 76 | ||||
-rw-r--r-- | drivers/net/designware.h | 10 |
2 files changed, 80 insertions, 6 deletions
diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 1673167..8858f07 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -24,7 +24,12 @@ DECLARE_GLOBAL_DATA_PTR; 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; +#endif ulong start; u16 miiaddr; 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, 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; +#endif ulong start; u16 miiaddr; 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; } -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(); @@ -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->write = dw_mdio_write; 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); } @@ -611,7 +658,7 @@ static int designware_eth_probe(struct udevice *dev) priv->interface = pdata->phy_interface; 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); ret = dw_phy_init(priv, dev); @@ -642,9 +689,13 @@ static const struct eth_ops designware_eth_ops = { 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 fdt32_t *cell; + int reset_flags = GPIOD_IS_OUT; + int ret = 0; pdata->iobase = dev_get_addr(dev); pdata->phy_interface = -1; @@ -661,7 +712,20 @@ static int designware_eth_ofdata_to_platdata(struct udevice *dev) if (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[] = { @@ -680,7 +744,7 @@ U_BOOT_DRIVER(eth_designware) = { .remove = designware_eth_remove, .ops = &designware_eth_ops, .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, }; diff --git a/drivers/net/designware.h b/drivers/net/designware.h index d48df7b..51ba769 100644 --- a/drivers/net/designware.h +++ b/drivers/net/designware.h @@ -8,6 +8,8 @@ #ifndef _DW_ETH_H #define _DW_ETH_H +#include <asm/gpio.h> + #define CONFIG_TX_DESCR_NUM 16 #define CONFIG_RX_DESCR_NUM 16 #define CONFIG_ETH_BUFSIZE 2048 @@ -232,8 +234,16 @@ struct dw_eth_dev { #ifndef CONFIG_DM_ETH struct eth_device *dev; #endif + struct gpio_desc reset_gpio; struct phy_device *phydev; struct mii_dev *bus; }; +#ifdef CONFIG_DM_ETH +struct dw_eth_pdata { + struct eth_pdata eth_pdata; + u32 reset_delays[3]; +}; +#endif + #endif |