X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fravb.c;h=3dab91b74b455f65ec268bb9aa68daa7712d473a;hb=c05ed00afb95fa5237f16962fccf5810437317bf;hp=dc7a52534e5c86ba23b0a3238086cfe132d77947;hpb=1b22c5ba496ffc9b0702919d58c410ed1527ab63;p=oweals%2Fu-boot.git diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c index dc7a52534e..3dab91b74b 100644 --- a/drivers/net/ravb.c +++ b/drivers/net/ravb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * drivers/net/ravb.c * This file is driver for Renesas Ethernet AVB. @@ -5,16 +6,18 @@ * Copyright (C) 2015-2017 Renesas Electronics Corporation * * Based on the SuperH Ethernet driver. - * - * SPDX-License-Identifier: GPL-2.0+ */ #include #include +#include #include #include +#include #include #include +#include +#include #include #include #include @@ -47,6 +50,8 @@ #define CSR_OPS 0x0000000F #define CSR_OPS_CONFIG BIT(1) +#define APSR_TDM BIT(14) + #define TCCR_TSRQ0 BIT(0) #define RFLR_RFL_MIN 0x05EE @@ -222,8 +227,8 @@ static int ravb_reset(struct udevice *dev) writel(CCC_OPC_CONFIG, eth->iobase + RAVB_REG_CCC); /* Check the operating mode is changed to the config mode. */ - return wait_for_bit(dev->name, (void *)eth->iobase + RAVB_REG_CSR, - CSR_OPS_CONFIG, true, 100, true); + return wait_for_bit_le32(eth->iobase + RAVB_REG_CSR, + CSR_OPS_CONFIG, true, 100, true); } static void ravb_base_desc_init(struct ravb_priv *eth) @@ -319,12 +324,13 @@ static int ravb_phy_config(struct udevice *dev) eth->phydev = phydev; - /* 10BASE is not supported for Ethernet AVB MAC */ - phydev->supported &= ~(SUPPORTED_10baseT_Full - | SUPPORTED_10baseT_Half); + phydev->supported &= SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | + SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_Pause | + SUPPORTED_Asym_Pause; + if (pdata->max_speed != 1000) { - phydev->supported &= ~(SUPPORTED_1000baseT_Half - | SUPPORTED_1000baseT_Full); + phydev->supported &= ~SUPPORTED_1000baseT_Full; reg = phy_read(phydev, -1, MII_CTRL1000); reg &= ~(BIT(9) | BIT(8)); phy_write(phydev, -1, MII_CTRL1000, reg); @@ -389,9 +395,14 @@ static int ravb_dmac_init(struct udevice *dev) /* FIFO size set */ writel(0x00222210, eth->iobase + RAVB_REG_TGC); - /* Delay CLK: 2ns */ - if (pdata->max_speed == 1000) - writel(BIT(14), eth->iobase + RAVB_REG_APSR); + /* Delay CLK: 2ns (not applicable on R-Car E3/D3) */ + if ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77990) || + (rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77995)) + return 0; + + if ((pdata->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) || + (pdata->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID)) + writel(APSR_TDM, eth->iobase + RAVB_REG_APSR); return 0; } @@ -399,7 +410,7 @@ static int ravb_dmac_init(struct udevice *dev) static int ravb_config(struct udevice *dev) { struct ravb_priv *eth = dev_get_priv(dev); - struct phy_device *phy; + struct phy_device *phy = eth->phydev; u32 mask = ECMR_CHG_DM | ECMR_RE | ECMR_TE; int ret; @@ -410,13 +421,6 @@ static int ravb_config(struct udevice *dev) ravb_mac_init(eth); ravb_write_hwaddr(dev); - /* Configure phy */ - ret = ravb_phy_config(dev); - if (ret) - return ret; - - phy = eth->phydev; - ret = phy_startup(phy); if (ret) return ret; @@ -438,18 +442,14 @@ static int ravb_config(struct udevice *dev) return 0; } -int ravb_start(struct udevice *dev) +static int ravb_start(struct udevice *dev) { struct ravb_priv *eth = dev_get_priv(dev); int ret; - ret = clk_enable(ð->clk); - if (ret) - return ret; - ret = ravb_reset(dev); if (ret) - goto err; + return ret; ravb_base_desc_init(eth); ravb_tx_desc_init(eth); @@ -457,30 +457,27 @@ int ravb_start(struct udevice *dev) ret = ravb_config(dev); if (ret) - goto err; + return ret; /* Setting the control will start the AVB-DMAC process. */ writel(CCC_OPC_OPERATION, eth->iobase + RAVB_REG_CCC); return 0; - -err: - clk_disable(ð->clk); - return ret; } static void ravb_stop(struct udevice *dev) { struct ravb_priv *eth = dev_get_priv(dev); + phy_shutdown(eth->phydev); ravb_reset(dev); - clk_disable(ð->clk); } static int ravb_probe(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct ravb_priv *eth = dev_get_priv(dev); + struct ofnode_phandle_args phandle_args; struct mii_dev *mdiodev; void __iomem *iobase; int ret; @@ -492,8 +489,16 @@ static int ravb_probe(struct udevice *dev) if (ret < 0) goto err_mdio_alloc; - gpio_request_by_name_nodev(dev_ofnode(dev), "reset-gpios", 0, - ð->reset_gpio, GPIOD_IS_OUT); + 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, + ð->reset_gpio, GPIOD_IS_OUT); + } + + if (!dm_gpio_is_valid(ð->reset_gpio)) { + gpio_request_by_name(dev, "reset-gpios", 0, ð->reset_gpio, + GPIOD_IS_OUT); + } mdiodev = mdio_alloc(); if (!mdiodev) { @@ -512,8 +517,23 @@ static int ravb_probe(struct udevice *dev) eth->bus = miiphy_get_dev_by_name(dev->name); + /* Bring up PHY */ + ret = clk_enable(ð->clk); + if (ret) + goto err_mdio_register; + + ret = ravb_reset(dev); + if (ret) + goto err_mdio_reset; + + ret = ravb_phy_config(dev); + if (ret) + goto err_mdio_reset; + return 0; +err_mdio_reset: + clk_disable(ð->clk); err_mdio_register: mdio_free(mdiodev); err_mdio_alloc: @@ -525,10 +545,13 @@ static int ravb_remove(struct udevice *dev) { struct ravb_priv *eth = dev_get_priv(dev); + clk_disable(ð->clk); + free(eth->phydev); mdio_unregister(eth->bus); mdio_free(eth->bus); - dm_gpio_free(dev, ð->reset_gpio); + if (dm_gpio_is_valid(ð->reset_gpio)) + dm_gpio_free(dev, ð->reset_gpio); unmap_physmem(eth->iobase, MAP_NOCACHE); return 0; @@ -651,6 +674,10 @@ int ravb_ofdata_to_platdata(struct udevice *dev) static const struct udevice_id ravb_ids[] = { { .compatible = "renesas,etheravb-r8a7795" }, { .compatible = "renesas,etheravb-r8a7796" }, + { .compatible = "renesas,etheravb-r8a77965" }, + { .compatible = "renesas,etheravb-r8a77970" }, + { .compatible = "renesas,etheravb-r8a77990" }, + { .compatible = "renesas,etheravb-r8a77995" }, { .compatible = "renesas,etheravb-rcar-gen3" }, { } };