diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2021-03-23 12:15:24 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2021-03-23 12:15:24 +0100 |
commit | 74ae57c86a39b8bd63b6c0130ce36040cd2db68a (patch) | |
tree | aa37033c69d2b095057e9bfb9c515314dbe81550 | |
parent | bb2873db3ef11e7b1299b1cca129f5d002e47f59 (diff) | |
parent | 3f09313f542be73ad9fb998076e284d66264838d (diff) | |
download | barebox-74ae57c86a39b8bd63b6c0130ce36040cd2db68a.tar.gz barebox-74ae57c86a39b8bd63b6c0130ce36040cd2db68a.tar.xz |
Merge branch 'for-next/net'
-rw-r--r-- | drivers/net/macb.c | 3 | ||||
-rw-r--r-- | drivers/net/phy/dp83867.c | 169 |
2 files changed, 93 insertions, 79 deletions
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 188dbf2d8c..14a0b45322 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -269,6 +269,9 @@ static int macb_set_tx_clk(struct macb_device *macb, int speed) } switch (speed) { + case SPEED_10: + rate = 2500000; + break; case SPEED_100: rate = 25000000; break; diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index 8131e8c9d6..05af83f076 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for the Texas Instruments DP83867 PHY * * Copyright (C) 2015 Texas Instruments Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <common.h> @@ -24,6 +16,7 @@ #define DP83867_DEVADDR MDIO_MMD_VEND2 #define MII_DP83867_PHYCTRL 0x10 +#define MII_DP83867_PHYSTS 0x11 #define MII_DP83867_MICR 0x12 #define MII_DP83867_ISR 0x13 #define MII_DP83867_CFG2 0x14 @@ -73,16 +66,21 @@ #define DP83867_PHYCTRL_TXFIFO_SHIFT 14 #define DP83867_PHYCR_RESERVED_MASK BIT(11) +/* PHY STS bits */ +#define DP83867_PHYSTS_SPEED_1000 BIT(15) +#define DP83867_PHYSTS_SPEED_100 BIT(14) +#define DP83867_PHYSTS_DUPLEX_FULL BIT(13) + /* RGMIIDCTL bits */ #define DP83867_RGMII_TX_CLK_DELAY_SHIFT 4 /* CFG2 bits */ -#define MII_DP83867_CFG2_SPEEDOPT_10EN 0x0040 -#define MII_DP83867_CFG2_SGMII_AUTONEGEN 0x0080 -#define MII_DP83867_CFG2_SPEEDOPT_ENH 0x0100 -#define MII_DP83867_CFG2_SPEEDOPT_CNT 0x0800 -#define MII_DP83867_CFG2_SPEEDOPT_INTLOW 0x2000 -#define MII_DP83867_CFG2_MASK 0x003F +#define DP83867_DOWNSHIFT_EN (BIT(8) | BIT(9)) +#define DP83867_DOWNSHIFT_ATTEMPT_MASK (BIT(10) | BIT(11)) +#define DP83867_DOWNSHIFT_1_COUNT_VAL 0 +#define DP83867_DOWNSHIFT_2_COUNT_VAL 1 +#define DP83867_DOWNSHIFT_4_COUNT_VAL 2 +#define DP83867_DOWNSHIFT_8_COUNT_VAL 3 /* CFG4 bits */ #define DP83867_CFG4_SGMII_AUTONEG_TIMER_MASK 0x60 @@ -117,9 +115,38 @@ struct dp83867_private { bool rxctrl_strap_quirk; }; +static int dp83867_read_status(struct phy_device *phydev) +{ + int status; + int ret; + + ret = genphy_update_link(phydev); + if (ret) + return ret; + + status = phy_read(phydev, MII_DP83867_PHYSTS); + if (status < 0) + return status; + + phydev->speed = SPEED_10; + phydev->duplex = DUPLEX_HALF; + + if (status & DP83867_PHYSTS_SPEED_1000) + phydev->speed = SPEED_1000; + else if (status & DP83867_PHYSTS_SPEED_100) + phydev->speed = SPEED_100; + + if (status & DP83867_PHYSTS_DUPLEX_FULL) + phydev->duplex = DUPLEX_FULL; + + phydev->pause = phydev->asym_pause = 0; + + return 0; +} + static int dp83867_config_port_mirroring(struct phy_device *phydev) { - struct dp83867_private *dp83867 = (struct dp83867_private *)phydev->priv; + struct dp83867_private *dp83867 = phydev->priv; u16 val; val = phy_read_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR); @@ -154,18 +181,18 @@ static int dp83867_of_init(struct phy_device *phydev) dp83867->rxctrl_strap_quirk = of_property_read_bool(of_node, - "ti,dp83867-rxctrl-strap-quirk"); + "ti,dp83867-rxctrl-strap-quirk"); ret = of_property_read_u32(of_node, "ti,rx-internal-delay", - &dp83867->rx_id_delay); + &dp83867->rx_id_delay); if (ret && (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || - phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)) + phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)) return ret; ret = of_property_read_u32(of_node, "ti,tx-internal-delay", - &dp83867->tx_id_delay); + &dp83867->tx_id_delay); if (ret && (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || - phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) + phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) return ret; if (of_property_read_bool(of_node, "enet-phy-lane-swap")) @@ -175,20 +202,20 @@ static int dp83867_of_init(struct phy_device *phydev) dp83867->port_mirroring = DP83867_PORT_MIRROING_DIS; return of_property_read_u32(of_node, "ti,fifo-depth", - &dp83867->fifo_depth); + &dp83867->fifo_depth); } static inline bool phy_interface_is_sgmii(struct phy_device *phydev) { return phydev->interface == PHY_INTERFACE_MODE_SGMII || - phydev->interface == PHY_INTERFACE_MODE_QSGMII; + phydev->interface == PHY_INTERFACE_MODE_QSGMII; } static int dp83867_config_init(struct phy_device *phydev) { struct dp83867_private *dp83867; int ret; - u16 val, delay, cfg2; + u16 val, delay; if (!phydev->priv) { dp83867 = kzalloc(sizeof(*dp83867), GFP_KERNEL); @@ -200,7 +227,7 @@ static int dp83867_config_init(struct phy_device *phydev) if (ret) return ret; } else { - dp83867 = (struct dp83867_private *)phydev->priv; + dp83867 = phydev->priv; } /* Restart the PHY. */ @@ -209,53 +236,26 @@ static int dp83867_config_init(struct phy_device *phydev) if (dp83867->rxctrl_strap_quirk) { val = phy_read_mmd_indirect(phydev, DP83867_CFG4, - DP83867_DEVADDR); + DP83867_DEVADDR); val &= ~BIT(7); - phy_write_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR, - val); + phy_write_mmd_indirect(phydev, DP83867_CFG4, + DP83867_DEVADDR, val); } if (phy_interface_is_rgmii(phydev)) { val = DP83867_MDI_CROSSOVER_AUTO << DP83867_MDI_CROSSOVER | - dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT; + dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT; ret = phy_write(phydev, MII_DP83867_PHYCTRL, val); if (ret) return ret; - } else if (phy_interface_is_sgmii(phydev)) { - phy_write(phydev, MII_BMCR, BMCR_ANENABLE | - BMCR_FULLDPLX | - BMCR_SPEED1000); - - cfg2 = phy_read(phydev, MII_DP83867_CFG2); - cfg2 &= MII_DP83867_CFG2_MASK; - cfg2 |= MII_DP83867_CFG2_SPEEDOPT_10EN | - MII_DP83867_CFG2_SGMII_AUTONEGEN | - MII_DP83867_CFG2_SPEEDOPT_ENH | - MII_DP83867_CFG2_SPEEDOPT_CNT | - MII_DP83867_CFG2_SPEEDOPT_INTLOW; - - phy_write(phydev, MII_DP83867_CFG2, cfg2); - phy_write_mmd_indirect(phydev, DP83867_RGMIICTL, - DP83867_DEVADDR, 0x0); - - val = DP83867_PHYCTRL_SGMIIEN | - DP83867_MDI_CROSSOVER_MDIX << DP83867_MDI_CROSSOVER | - dp83867->fifo_depth << DP83867_PHYCTRL_RXFIFO_SHIFT | - dp83867->fifo_depth << DP83867_PHYCTRL_TXFIFO_SHIFT; - - phy_write(phydev, MII_DP83867_PHYCTRL, val); - phy_write(phydev, MII_DP83867_BISCR, 0x0); - } - - if (phy_interface_is_rgmii(phydev)) { val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL, - DP83867_DEVADDR); + DP83867_DEVADDR); switch (phydev->interface) { case PHY_INTERFACE_MODE_RGMII_ID: - val |= (DP83867_RGMII_TX_CLK_DELAY_EN - | DP83867_RGMII_RX_CLK_DELAY_EN); + val |= DP83867_RGMII_TX_CLK_DELAY_EN | + DP83867_RGMII_RX_CLK_DELAY_EN; break; case PHY_INTERFACE_MODE_RGMII_TXID: val |= DP83867_RGMII_TX_CLK_DELAY_EN; @@ -267,48 +267,59 @@ static int dp83867_config_init(struct phy_device *phydev) break; } phy_write_mmd_indirect(phydev, DP83867_RGMIICTL, - DP83867_DEVADDR, val); + DP83867_DEVADDR, val); delay = (dp83867->rx_id_delay | (dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT)); phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL, - DP83867_DEVADDR, delay); + DP83867_DEVADDR, delay); if (dp83867->io_impedance >= 0) { val = phy_read_mmd_indirect(phydev, DP83867_IO_MUX_CFG, - DP83867_DEVADDR); + DP83867_DEVADDR); val &= ~DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL; - val |= dp83867->io_impedance - & DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL; + val |= (dp83867->io_impedance & + DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL); phy_write_mmd_indirect(phydev, DP83867_IO_MUX_CFG, - DP83867_DEVADDR, val); + DP83867_DEVADDR, val); } + } else if (phy_interface_is_sgmii(phydev)) { + phy_write(phydev, MII_BMCR, + BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000); + + phy_write_mmd_indirect(phydev, DP83867_RGMIICTL, + DP83867_DEVADDR, 0x0); + + val = DP83867_PHYCTRL_SGMIIEN | + DP83867_MDI_CROSSOVER_MDIX << DP83867_MDI_CROSSOVER | + dp83867->fifo_depth << DP83867_PHYCTRL_RXFIFO_SHIFT | + dp83867->fifo_depth << DP83867_PHYCTRL_TXFIFO_SHIFT; + + phy_write(phydev, MII_DP83867_PHYCTRL, val); + phy_write(phydev, MII_DP83867_BISCR, 0x0); } - genphy_config_aneg(phydev); + val = phy_read(phydev, MII_DP83867_CFG2); + val |= DP83867_DOWNSHIFT_EN; + phy_write(phydev, MII_DP83867_CFG2, val); if (dp83867->port_mirroring != DP83867_PORT_MIRROING_KEEP) dp83867_config_port_mirroring(phydev); - dev_info(&phydev->dev, "DP83867\n"); - return 0; } static struct phy_driver dp83867_driver[] = { - { - .phy_id = DP83867_PHY_ID, - .phy_id_mask = 0xfffffff0, - .drv.name = "TI DP83867", - .features = PHY_GBIT_FEATURES, - - .config_init = dp83867_config_init, - - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, - }, + { + .phy_id = DP83867_PHY_ID, + .phy_id_mask = 0xfffffff0, + .drv.name = "TI DP83867", + .features = PHY_GBIT_FEATURES, + .config_init = dp83867_config_init, + .read_status = dp83867_read_status, + }, }; device_phy_drivers(dp83867_driver); |