From 9708fb630d19ee51ae3aeb3a533e3010da0e8570 Mon Sep 17 00:00:00 2001 From: Wadim Egorov Date: Wed, 14 Feb 2018 17:07:11 +0100 Subject: [PATCH] net: phy: dp83867: Add binding for the CLK_OUT pin muxing option The DP83867 has a muxing option for the CLK_OUT pin. It is possible to set CLK_OUT for different channels. Create a binding to select a specific clock for CLK_OUT pin. Signed-off-by: Wadim Egorov Signed-off-by: Daniel Schultz Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/dp83867.c | 19 +++++++++++++++++++ include/dt-bindings/net/ti-dp83867.h | 14 ++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index ab58224f897f..b3935778b19f 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -75,6 +75,8 @@ #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX 0x0 #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN 0x1f +#define DP83867_IO_MUX_CFG_CLK_O_SEL_MASK (0x1f << 8) +#define DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT 8 /* CFG4 bits */ #define DP83867_CFG4_PORT_MIRROR_EN BIT(0) @@ -92,6 +94,7 @@ struct dp83867_private { int io_impedance; int port_mirroring; bool rxctrl_strap_quirk; + int clk_output_sel; }; static int dp83867_ack_interrupt(struct phy_device *phydev) @@ -160,6 +163,14 @@ static int dp83867_of_init(struct phy_device *phydev) dp83867->io_impedance = -EINVAL; /* Optional configuration */ + ret = of_property_read_u32(of_node, "ti,clk-output-sel", + &dp83867->clk_output_sel); + if (ret || dp83867->clk_output_sel > DP83867_CLK_O_SEL_REF_CLK) + /* Keep the default value if ti,clk-output-sel is not set + * or too high + */ + dp83867->clk_output_sel = DP83867_CLK_O_SEL_REF_CLK; + if (of_property_read_bool(of_node, "ti,max-output-impedance")) dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX; else if (of_property_read_bool(of_node, "ti,min-output-impedance")) @@ -295,6 +306,14 @@ static int dp83867_config_init(struct phy_device *phydev) if (dp83867->port_mirroring != DP83867_PORT_MIRROING_KEEP) dp83867_config_port_mirroring(phydev); + /* Clock output selection if muxing property is set */ + if (dp83867->clk_output_sel != DP83867_CLK_O_SEL_REF_CLK) { + val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG); + val &= ~DP83867_IO_MUX_CFG_CLK_O_SEL_MASK; + val |= (dp83867->clk_output_sel << DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT); + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG, val); + } + return 0; } diff --git a/include/dt-bindings/net/ti-dp83867.h b/include/dt-bindings/net/ti-dp83867.h index 172744a72eb7..7b1656427cbe 100644 --- a/include/dt-bindings/net/ti-dp83867.h +++ b/include/dt-bindings/net/ti-dp83867.h @@ -42,4 +42,18 @@ #define DP83867_RGMIIDCTL_3_75_NS 0xe #define DP83867_RGMIIDCTL_4_00_NS 0xf +/* IO_MUX_CFG - Clock output selection */ +#define DP83867_CLK_O_SEL_CHN_A_RCLK 0x0 +#define DP83867_CLK_O_SEL_CHN_B_RCLK 0x1 +#define DP83867_CLK_O_SEL_CHN_C_RCLK 0x2 +#define DP83867_CLK_O_SEL_CHN_D_RCLK 0x3 +#define DP83867_CLK_O_SEL_CHN_A_RCLK_DIV5 0x4 +#define DP83867_CLK_O_SEL_CHN_B_RCLK_DIV5 0x5 +#define DP83867_CLK_O_SEL_CHN_C_RCLK_DIV5 0x6 +#define DP83867_CLK_O_SEL_CHN_D_RCLK_DIV5 0x7 +#define DP83867_CLK_O_SEL_CHN_A_TCLK 0x8 +#define DP83867_CLK_O_SEL_CHN_B_TCLK 0x9 +#define DP83867_CLK_O_SEL_CHN_C_TCLK 0xA +#define DP83867_CLK_O_SEL_CHN_D_TCLK 0xB +#define DP83867_CLK_O_SEL_REF_CLK 0xC #endif