summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/device-tree-bindings/net/ti,dp83867.txt3
-rw-r--r--drivers/net/phy/ti.c27
-rw-r--r--include/dt-bindings/net/ti-dp83867.h15
3 files changed, 45 insertions, 0 deletions
diff --git a/doc/device-tree-bindings/net/ti,dp83867.txt b/doc/device-tree-bindings/net/ti,dp83867.txt
index f31c2da902..034146f5f8 100644
--- a/doc/device-tree-bindings/net/ti,dp83867.txt
+++ b/doc/device-tree-bindings/net/ti,dp83867.txt
@@ -12,6 +12,8 @@ Required properties:
compensate for the board being designed with the lanes swapped.
- enet-phy-no-lane-swap - Indicates that PHY will disable swap of the
TX/RX lanes.
+ - ti,clk-output-sel - Clock output select - see dt-bindings/net/ti-dp83867.h
+ for applicable values
Default child nodes are standard Ethernet PHY device
nodes as described in doc/devicetree/bindings/net/ethernet.txt
@@ -24,6 +26,7 @@ Example:
ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
enet-phy-lane-no-swap;
+ ti,clk-output-sel = <DP83867_CLK_O_SEL_CHN_A_TCLK>;
};
Datasheet can be found:
diff --git a/drivers/net/phy/ti.c b/drivers/net/phy/ti.c
index e27ee32bd1..6db6edd0d0 100644
--- a/drivers/net/phy/ti.c
+++ b/drivers/net/phy/ti.c
@@ -93,6 +93,9 @@
#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_SHIFT 8
+#define DP83867_IO_MUX_CFG_CLK_O_SEL_MASK \
+ GENMASK(0x1f, DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT)
/* CFG4 bits */
#define DP83867_CFG4_PORT_MIRROR_EN BIT(0)
@@ -110,6 +113,7 @@ struct dp83867_private {
int io_impedance;
bool rxctrl_strap_quirk;
int port_mirroring;
+ int clk_output_sel;
};
/**
@@ -208,6 +212,18 @@ static int dp83867_of_init(struct phy_device *phydev)
{
struct dp83867_private *dp83867 = phydev->priv;
ofnode node;
+ u16 val;
+
+ /* Optional configuration */
+
+ /*
+ * Keep the default value if ti,clk-output-sel is not set
+ * or to high
+ */
+
+ dp83867->clk_output_sel =
+ ofnode_read_u32_default(node, "ti,clk-output-sel",
+ DP83867_CLK_O_SEL_REF_CLK);
node = phy_get_ofnode(phydev);
if (!ofnode_valid(node))
@@ -239,6 +255,17 @@ static int dp83867_of_init(struct phy_device *phydev)
dp83867->port_mirroring = DP83867_PORT_MIRRORING_DIS;
+ /* Clock output selection if muxing property is set */
+ if (dp83867->clk_output_sel != DP83867_CLK_O_SEL_REF_CLK) {
+ val = phy_read_mmd_indirect(phydev, DP83867_IO_MUX_CFG,
+ DP83867_DEVADDR, phydev->addr);
+ 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_indirect(phydev, DP83867_IO_MUX_CFG,
+ DP83867_DEVADDR, phydev->addr, val);
+ }
+
return 0;
}
#else
diff --git a/include/dt-bindings/net/ti-dp83867.h b/include/dt-bindings/net/ti-dp83867.h
index b8e5df615d..85d08f6974 100644
--- a/include/dt-bindings/net/ti-dp83867.h
+++ b/include/dt-bindings/net/ti-dp83867.h
@@ -31,4 +31,19 @@
#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