diff options
author | Heiko Stuebner <heiko.stuebner@theobroma-systems.com> | 2020-06-09 15:37:39 +0200 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2020-09-30 16:48:18 -0400 |
commit | 9a499b2bfa684abe77033c76740a597da8f09f11 (patch) | |
tree | af1cb01c838be5172cf0feff7a19f6a64561d296 /drivers/net/phy | |
parent | 01114adfc1e0bf3cf5e2f3da858bb2c8e9810c1c (diff) | |
download | u-boot-9a499b2bfa684abe77033c76740a597da8f09f11.tar.gz u-boot-9a499b2bfa684abe77033c76740a597da8f09f11.tar.bz2 u-boot-9a499b2bfa684abe77033c76740a597da8f09f11.zip |
net: phy: mscc: make clock-output configurable on vsc85xx
The vsc8530/8531/8540/8541 phys have a configurable clock output that
can emit 25, 50 and 125 MHz rates, which in turn may be needed for
stable network connections.
This follows a similar change introduced into the Linux kernel at
https://lore.kernel.org/netdev/20200609133140.1421109-2-heiko@sntech.de
Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
Reviewed-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r-- | drivers/net/phy/mscc.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c index 709979f48c..64e9093827 100644 --- a/drivers/net/phy/mscc.c +++ b/drivers/net/phy/mscc.c @@ -157,6 +157,14 @@ #define INT_MEM_DATA_M GENMASK(7, 0) #define INT_MEM_DATA(x) (INT_MEM_DATA_M & (x)) +/* Extended page GPIO register 13G */ +#define MSCC_CLKOUT_CNTL 13 +#define CLKOUT_ENABLE BIT(15) +#define CLKOUT_FREQ_MASK GENMASK(14, 13) +#define CLKOUT_FREQ_25M (0x0 << 13) +#define CLKOUT_FREQ_50M (0x1 << 13) +#define CLKOUT_FREQ_125M (0x2 << 13) + /* Extended page GPIO register 18G */ #define MSCC_PHY_PROC_CMD 18 #define PROC_CMD_NCOMPLETED BIT(15) @@ -1210,6 +1218,47 @@ static int vsc8531_vsc8541_mac_config(struct phy_device *phydev) return 0; } +static int vsc8531_vsc8541_clkout_config(struct phy_device *phydev) +{ + struct ofnode_phandle_args phandle_args; + u32 clkout_rate = 0; + u16 reg_val; + int retval; + + retval = dev_read_phandle_with_args(phydev->dev, "phy-handle", NULL, + 0, 0, &phandle_args); + if (!retval) + clkout_rate = ofnode_read_u32_default(phandle_args.node, + "vsc8531,clk-out-frequency", 0); + + switch (clkout_rate) { + case 0: + reg_val = 0; + break; + case 25000000: + reg_val = CLKOUT_FREQ_25M | CLKOUT_ENABLE; + break; + case 50000000: + reg_val = CLKOUT_FREQ_50M | CLKOUT_ENABLE; + break; + case 125000000: + reg_val = CLKOUT_FREQ_125M | CLKOUT_ENABLE; + break; + default: + printf("PHY 8530/31 invalid clkout rate %u\n", + clkout_rate); + return -EINVAL; + } + + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_GPIO); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_CLKOUT_CNTL, reg_val); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_STD); + + return 0; +} + static int vsc8531_config(struct phy_device *phydev) { int retval = -EINVAL; @@ -1267,6 +1316,11 @@ static int vsc8531_config(struct phy_device *phydev) phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STD); + /* Configure the clk output */ + retval = vsc8531_vsc8541_clkout_config(phydev); + if (retval != 0) + return retval; + return genphy_config_aneg(phydev); } @@ -1327,6 +1381,11 @@ static int vsc8541_config(struct phy_device *phydev) phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STD); + /* Configure the clk output */ + retval = vsc8531_vsc8541_clkout_config(phydev); + if (retval != 0) + return retval; + return genphy_config_aneg(phydev); } |