2020-10-21 06:48:00

by Dan Murphy

[permalink] [raw]
Subject: [PATCH net-next v2 0/3] DP83TD510 Single Pair 10Mbps Ethernet PHY

Hello

The DP83TD510 is an Ethernet PHY supporting single pair of twisted wires. The
PHY is capable of 10Mbps communication over long distances and exceeds the
IEEE 802.3cg 10BASE-T1L single-pair Ethernet specification. The PHY supports
various voltage level signalling and can be forced to support a specific
voltage or allowed to perfrom auto negotiation on the voltage level. The
default for the PHY is auto negotiation but if the PHY is forced to a specific
voltage then the LP must also support the same voltage.

Add the 10BASE-T1L linkmodes for ethtool to properly advertise the PHY's
capability.

Dan

Dan Murphy (3):
ethtool: Add 10base-T1L link mode entries
dt-bindings: dp83td510: Add binding for DP83TD510 Ethernet PHY
net: phy: dp83td510: Add support for the DP83TD510 Ethernet PHY

.../devicetree/bindings/net/ti,dp83td510.yaml | 72 +++
drivers/net/phy/Kconfig | 6 +
drivers/net/phy/Makefile | 1 +
drivers/net/phy/dp83td510.c | 600 ++++++++++++++++++
drivers/net/phy/phy-core.c | 4 +-
include/uapi/linux/ethtool.h | 2 +
net/ethtool/common.c | 2 +
net/ethtool/linkmodes.c | 2 +
8 files changed, 688 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/net/ti,dp83td510.yaml
create mode 100644 drivers/net/phy/dp83td510.c

--
2.28.0.585.ge1cfff676549


2020-10-21 06:50:25

by Dan Murphy

[permalink] [raw]
Subject: [PATCH net-next v2 1/3] ethtool: Add 10base-T1L link mode entries

Add entries for the 10base-T1L full and half duplex supported modes.

$ ethtool eth0
Supported ports: [ TP MII ]
Supported link modes: 10baseT1L/Half 10baseT1L/Full
Supported pause frame use: Symmetric Receive-only
Supports auto-negotiation: Yes
Supported FEC modes: Not reported
Advertised link modes: 10baseT1L/Half 10baseT1L/Full
Advertised pause frame use: No
Advertised auto-negotiation: No
Advertised FEC modes: Not reported
Speed: 10Mb/s
Duplex: Full
Auto-negotiation: on
Port: MII
PHYAD: 1
Transceiver: external
Supports Wake-on: gs
Wake-on: d
SecureOn password: 00:00:00:00:00:00
Current message level: 0x00000000 (0)

Link detected: yes

Signed-off-by: Dan Murphy <[email protected]>
---
drivers/net/phy/phy-core.c | 4 +++-
include/uapi/linux/ethtool.h | 2 ++
net/ethtool/common.c | 2 ++
net/ethtool/linkmodes.c | 2 ++
4 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
index 8d333d3084ed..616fae7f0c86 100644
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -13,7 +13,7 @@
*/
const char *phy_speed_to_str(int speed)
{
- BUILD_BUG_ON_MSG(__ETHTOOL_LINK_MODE_MASK_NBITS != 92,
+ BUILD_BUG_ON_MSG(__ETHTOOL_LINK_MODE_MASK_NBITS != 94,
"Enum ethtool_link_mode_bit_indices and phylib are out of sync. "
"If a speed or mode has been added please update phy_speed_to_str "
"and the PHY settings array.\n");
@@ -175,6 +175,8 @@ static const struct phy_setting settings[] = {
/* 10M */
PHY_SETTING( 10, FULL, 10baseT_Full ),
PHY_SETTING( 10, HALF, 10baseT_Half ),
+ PHY_SETTING( 10, FULL, 10baseT1L_Full ),
+ PHY_SETTING( 10, HALF, 10baseT1L_Half ),
};
#undef PHY_SETTING

diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 9ca87bc73c44..16b6ea7548d3 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -1619,6 +1619,8 @@ enum ethtool_link_mode_bit_indices {
ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT = 89,
ETHTOOL_LINK_MODE_100baseFX_Half_BIT = 90,
ETHTOOL_LINK_MODE_100baseFX_Full_BIT = 91,
+ ETHTOOL_LINK_MODE_10baseT1L_Half_BIT = 92,
+ ETHTOOL_LINK_MODE_10baseT1L_Full_BIT = 93,
/* must be last entry */
__ETHTOOL_LINK_MODE_MASK_NBITS
};
diff --git a/net/ethtool/common.c b/net/ethtool/common.c
index 24036e3055a1..95f87febc742 100644
--- a/net/ethtool/common.c
+++ b/net/ethtool/common.c
@@ -194,6 +194,8 @@ const char link_mode_names[][ETH_GSTRING_LEN] = {
__DEFINE_LINK_MODE_NAME(400000, CR4, Full),
__DEFINE_LINK_MODE_NAME(100, FX, Half),
__DEFINE_LINK_MODE_NAME(100, FX, Full),
+ __DEFINE_LINK_MODE_NAME(10, T1L, Half),
+ __DEFINE_LINK_MODE_NAME(10, T1L, Full),
};
static_assert(ARRAY_SIZE(link_mode_names) == __ETHTOOL_LINK_MODE_MASK_NBITS);

diff --git a/net/ethtool/linkmodes.c b/net/ethtool/linkmodes.c
index c5bcb9abc8b9..a8fab6fb1b30 100644
--- a/net/ethtool/linkmodes.c
+++ b/net/ethtool/linkmodes.c
@@ -264,6 +264,8 @@ static const struct link_mode_info link_mode_params[] = {
__DEFINE_LINK_MODE_PARAMS(400000, CR4, Full),
__DEFINE_LINK_MODE_PARAMS(100, FX, Half),
__DEFINE_LINK_MODE_PARAMS(100, FX, Full),
+ __DEFINE_LINK_MODE_PARAMS(10, T1L, Half),
+ __DEFINE_LINK_MODE_PARAMS(10, T1L, Full),
};

const struct nla_policy ethnl_linkmodes_set_policy[] = {
--
2.28.0.585.ge1cfff676549

2020-10-21 06:50:55

by Dan Murphy

[permalink] [raw]
Subject: [PATCH net-next v2 2/3] dt-bindings: dp83td510: Add binding for DP83TD510 Ethernet PHY

The DP83TD510 is a 10M single twisted pair Ethernet PHY

Signed-off-by: Dan Murphy <[email protected]>
---
.../devicetree/bindings/net/ti,dp83td510.yaml | 72 +++++++++++++++++++
1 file changed, 72 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/ti,dp83td510.yaml

diff --git a/Documentation/devicetree/bindings/net/ti,dp83td510.yaml b/Documentation/devicetree/bindings/net/ti,dp83td510.yaml
new file mode 100644
index 000000000000..171aed0f2503
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/ti,dp83td510.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2020 Texas Instruments Incorporated
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/net/ti,dp83td510.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: TI DP83TD510 ethernet PHY
+
+allOf:
+ - $ref: "ethernet-controller.yaml#"
+ - $ref: "ethernet-phy.yaml#"
+
+maintainers:
+ - Dan Murphy <[email protected]>
+
+description: |
+ The PHY is an twisted pair 10Mbps Ethernet PHY that support MII, RMII and
+ RGMII interfaces.
+
+ Specifications about the Ethernet PHY can be found at:
+ http://www.ti.com/lit/ds/symlink/dp83td510e.pdf
+
+properties:
+ reg:
+ maxItems: 1
+
+ tx-fifo-depth:
+ description: |
+ Transmitt FIFO depth for RMII mode. The PHY only exposes 4 nibble
+ depths. The valid nibble depths are 4, 5, 6 and 8.
+ default: 5
+
+ rx-internal-delay-ps:
+ description: |
+ Setting this property to a non-zero number sets the RX internal delay
+ for the PHY. The internal delay for the PHY is fixed to 30ns relative
+ to receive data.
+
+ tx-internal-delay-ps:
+ description: |
+ Setting this property to a non-zero number sets the TX internal delay
+ for the PHY. The internal delay for the PHY has a range of -4 to 4ns
+ relative to transmit data.
+
+ ti,master-slave-mode:
+ $ref: /schemas/types.yaml#definitions/uint32
+ default: 0
+ description: |
+ Force the PHY to be configured to a specific mode.
+ Force Auto Negotiation - 0
+ Force Master mode at 1v p2p - 1
+ Force Master mode at 2.4v p2p - 2
+ Force Slave mode at 1v p2p - 3
+ Force Slave mode at 2.4v p2p - 4
+ enum: [ 0, 1, 2, 3, 4 ]
+
+required:
+ - reg
+
+examples:
+ - |
+ mdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ tx-fifo-depth = <5>;
+ rx-internal-delay-ps = <1>;
+ tx-internal-delay-ps = <1>;
+ };
+ };
--
2.28.0.585.ge1cfff676549

2020-10-21 08:59:17

by Dan Murphy

[permalink] [raw]
Subject: [PATCH net-next v2 3/3] net: phy: dp83td510: Add support for the DP83TD510 Ethernet PHY

The DP83TD510E is an ultra-low power Ethernet physical layer transceiver
that supports 10M single pair cable.

The device supports both 2.4-V p2p and 1-V p2p output voltage as defined
by IEEE 802.3cg 10Base-T1L specfications. These modes can be forced via
the device tree or the device is defaulted to auto negotiation to
determine the proper p2p voltage.

Signed-off-by: Dan Murphy <[email protected]>
---
drivers/net/phy/Kconfig | 6 +
drivers/net/phy/Makefile | 1 +
drivers/net/phy/dp83td510.c | 600 ++++++++++++++++++++++++++++++++++++
3 files changed, 607 insertions(+)
create mode 100644 drivers/net/phy/dp83td510.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 698bea312adc..017252e1504c 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -302,6 +302,12 @@ config DP83869_PHY
Currently supports the DP83869 PHY. This PHY supports copper and
fiber connections.

+config DP83TD510_PHY
+ tristate "Texas Instruments DP83TD510 10M Single Pair Ethernet PHY"
+ help
+ Support for the DP83TD510 Ethernet PHY. This PHY supports a 10M single
+ pair Ethernet connection.
+
config VITESSE_PHY
tristate "Vitesse PHYs"
help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index a13e402074cf..bf62ce211eb4 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_DP83848_PHY) += dp83848.o
obj-$(CONFIG_DP83867_PHY) += dp83867.o
obj-$(CONFIG_DP83869_PHY) += dp83869.o
obj-$(CONFIG_DP83TC811_PHY) += dp83tc811.o
+obj-$(CONFIG_DP83TD510_PHY) += dp83td510.o
obj-$(CONFIG_FIXED_PHY) += fixed_phy.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
obj-$(CONFIG_INTEL_XWAY_PHY) += intel-xway.o
diff --git a/drivers/net/phy/dp83td510.c b/drivers/net/phy/dp83td510.c
new file mode 100644
index 000000000000..756497c592bc
--- /dev/null
+++ b/drivers/net/phy/dp83td510.c
@@ -0,0 +1,600 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Driver for the Texas Instruments DP83TD510 PHY
+ * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <linux/ethtool.h>
+#include <linux/etherdevice.h>
+#include <linux/kernel.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy.h>
+#include <linux/netdevice.h>
+
+#define DP83TD510E_PHY_ID 0x20000180
+#define DP83TD510_DEVADDR_AN 0x7
+#define DP83TD510_DEVADDR 0x1f
+
+#define DP83TD510_MII_REG 0x0
+#define DP83TD510_PHY_STAT 0x10
+#define DP83TD510_GEN_CFG 0x11
+#define DP83TD510_INT_REG1 0x12
+#define DP83TD510_INT_REG2 0x13
+#define DP83TD510_MAC_CFG_1 0x17
+
+#define DP83TD510_SOR_1 0x467
+
+#define DP83TD510_HW_RESET BIT(15)
+#define DP83TD510_SW_RESET BIT(14)
+
+/* GEN CFG bits */
+#define DP83TD510_INT_OE BIT(0)
+#define DP83TD510_INT_EN BIT(1)
+
+/* INT REG 1 bits */
+#define DP83TD510_INT1_ESD_EN BIT(3)
+#define DP83TD510_INT1_LINK_EN BIT(5)
+#define DP83TD510_INT1_RHF_EN BIT(7)
+#define DP83TD510_INT1_ESD BIT(11)
+#define DP83TD510_INT1_LINK BIT(13)
+#define DP83TD510_INT1_RHF BIT(15)
+
+/* INT REG 2 bits */
+#define DP83TD510_INT2_POR_EN BIT(0)
+#define DP83TD510_INT2_POL_EN BIT(1)
+#define DP83TD510_INT2_PAGE_EN BIT(5)
+#define DP83TD510_INT2_POR BIT(8)
+#define DP83TD510_INT2_POL BIT(9)
+#define DP83TD510_INT2_PAGE BIT(13)
+
+/* MAC CFG bits */
+#define DP83TD510_RX_CLK_SHIFT BIT(12)
+#define DP83TD510_TX_CLK_SHIFT BIT(11)
+
+#define DP83TD510_MASTER_MODE BIT(2)
+#define DP83TD510_2_4V BIT(7)
+#define DP83TD510_RGMII BIT(8)
+
+#define DP83TD510_FIFO_DEPTH_MASK GENMASK(6, 5)
+#define DP83TD510_FIFO_DEPTH_4_B_NIB 0
+#define DP83TD510_FIFO_DEPTH_5_B_NIB BIT(5)
+#define DP83TD510_FIFO_DEPTH_6_B_NIB BIT(6)
+#define DP83TD510_FIFO_DEPTH_8_B_NIB (BIT(5) | BIT(6))
+
+enum dp83td510_mode_config {
+ DP83TD510_AUTO_NEG = 0,
+ DP83TD510_MASTER_1 = 1,
+ DP83TD510_MASTER_24 = 2,
+ DP83TD510_SLAVE_1 = 3,
+ DP83TD510_SLAVE_24 = 4,
+};
+
+const int dp83td510_feature_array[3] = {
+ ETHTOOL_LINK_MODE_10baseT1L_Half_BIT,
+ ETHTOOL_LINK_MODE_10baseT1L_Full_BIT,
+ ETHTOOL_LINK_MODE_TP_BIT,
+};
+
+struct dp83td510_private {
+ u32 forced_mode;
+ u32 tx_fifo_depth;
+ u32 rgmii_delay;
+ bool is_rgmii;
+};
+
+struct dp83td510_init_reg {
+ int reg;
+ int val;
+};
+
+static struct dp83td510_init_reg dp83td510_master_1_0[] = {
+ { 0x000d, 0x0007 }, /* disable auto-neg */
+ { 0x000e, 0x0200 },
+ { 0x000d, 0x4007 },
+ { 0x000e, 0x0000 },
+ { 0x000d, 0x0001 }, /* force master mode */
+ { 0x000e, 0x0834 },
+ { 0x000d, 0x4001 },
+ { 0x000e, 0x4000 },
+ { 0x000d, 0x0001 }, /* force 1.0v swing */
+ { 0x000e, 0x08f6 },
+ { 0x000d, 0x4001 },
+ { 0x000e, 0x0000 },
+ { 0x0608, 0x003b }, /* disable_0_transition */
+ { 0x0862, 0x39f8 }, /* AGC Gain during Autoneg */
+ { 0x081a, 0x67c0 }, /* deq offset for 1V swing */
+ { 0x081c, 0xfb62 }, /* deq offset for 2.4V swing */
+ { 0x0830, 0x05a3 }, /* Enable energy lost fallback */
+ { 0x0855, 0x1b55 }, /* MSE Threshold change */
+ { 0x0831, 0x0403 }, /* energy detect threshold */
+ { 0x0856, 0x1800 }, /* good1 MSE threshold change */
+ { 0x0857, 0x8fa0 }, /* Enable fallback to phase 1 on watchdog trigger */
+ { 0x0871, 0x000c }, /* TED input changed to slicer_in without FFE */
+ { 0x0883, 0x022e }, /* Enable Rx Filter, Change PGA threshold for Short Cable detection */
+ { 0x0402, 0x1800 }, /* Adjusr LD swing */
+ { 0x0878, 0x2248 }, /* Change PI up/down polarity */
+ { 0x010c, 0x0008 }, /* tx filter coefficient */
+ { 0x0112, 0x1212 }, /* tx filter scaling factor */
+ { 0x0809, 0x5c80 }, /* AGC retrain */
+ { 0x0803, 0x1529 }, /* Master Ph1 Back-off */
+ { 0x0804, 0x1a33 }, /* Master Ph1 Back-off */
+ { 0x0805, 0x1f3d }, /* Master Ph1 Back-off */
+ { 0x0850, 0x045b }, /* hybrid gain & delay */
+ { 0x0874, 0x6967 }, /* kp step 0 for master */
+ { 0x0852, 0x7800 }, /* FAGC init gain */
+ { 0x0806, 0x1e1e }, /* Master/Slave Ph2 Back-off */
+ { 0x0807, 0x2525 }, /* Master/Slave Ph2 Back-off */
+ { 0x0808, 0x2c2c }, /* Master/Slave Ph2 Back-off */
+ { 0x0850, 0x0590 }, /* Hybrid Gain/Delay Code */
+ { 0x0827, 0x4000 }, /* Echo Fixed Delay */
+ { 0x0849, 0x0fe4 }, /* Hybrid Cal enable */
+ { 0x084b, 0x04b5 }, /* Echo Score Sel */
+ { 0x0018, 0x0043 }, /* Set CRS/RX_DV pin as RX_DV for RMII repeater mode */
+};
+
+static struct dp83td510_init_reg dp83td510_slave_1_0[] = {
+ { 0x000d, 0x0007 }, /* disable auto-neg */
+ { 0x000e, 0x0200 },
+ { 0x000d, 0x4007 },
+ { 0x000e, 0x0000 },
+ { 0x000d, 0x0001 }, /* force slave mode */
+ { 0x000e, 0x0834 },
+ { 0x000d, 0x4001 },
+ { 0x000e, 0x0000 },
+ { 0x000d, 0x0001 }, /* force 1.0v swing */
+ { 0x000d, 0x4001 },
+ { 0x000e, 0x0000 },
+ { 0x0608, 0x003b }, /* disable_0_transition */
+ { 0x0862, 0x39f8 }, /* AGC Gain during Autoneg */
+ { 0x081a, 0x67c0 }, /* deq offset for 1V swing */
+ { 0x081c, 0xfb62 }, /* deq offset for 2.4V swing */
+ { 0x0830, 0x05a3 }, /* Enable energy lost fallback */
+ { 0x0855, 0x1b55 }, /* MSE Threshold change */
+ { 0x0831, 0x0403 }, /* energy detect threshold */
+ { 0x0856, 0x1800 }, /* good1 MSE threshold change */
+ { 0x0857, 0x8fa0 }, /* Enable fallback to phase 1 on watchdog trigger */
+ { 0x0871, 0x000c }, /* TED input changed to slicer_in without FFE */
+ { 0x0883, 0x022e }, /* Enable Rx Filter, PGA threshold for Short Cable detection */
+ { 0x0402, 0x1800 }, /* Adjusr LD swing */
+ { 0x0878, 0x2248 }, /* Change PI up/down polarity */
+ { 0x010c, 0x0008 }, /* tx filter coefficient */
+ { 0x0112, 0x1212 }, /* tx filter scaling factor */
+ { 0x0809, 0x5c80 }, /* AGC retrain */
+ { 0x0803, 0x1529 }, /* Master Ph1 Back-off */
+ { 0x0804, 0x1a33 }, /* Master Ph1 Back-off */
+ { 0x0805, 0x1f3d }, /* Master Ph1 Back-off */
+ { 0x0850, 0x045b }, /* hybrid gain & delay */
+ { 0x0874, 0x6967 }, /* kp step 0 for master */
+ { 0x0852, 0x7800 }, /* FAGC init gain */
+ { 0x0806, 0x1e1e }, /* Master/Slave Ph2 Back-off */
+ { 0x0807, 0x2525 }, /* Master/Slave Ph2 Back-off */
+ { 0x0808, 0x2c2c }, /* Master/Slave Ph2 Back-off */
+ { 0x0850, 0x0590 }, /* Hybrid Gain/Delay Code */
+ { 0x0827, 0x4000 }, /* Echo Fixed Delay */
+ { 0x0849, 0x0fe4 }, /* Hybrid Cal enable */
+ { 0x084b, 0x04b5 }, /* Echo Score Sel */
+ { 0x0018, 0x0043 }, /* Set CRS/RX_DV pin as RX_DV for RMII repeater mode */
+};
+
+static struct dp83td510_init_reg dp83td510_master_2_4[] = {
+ { 0x000d, 0x0007 }, /* disable auto-neg */
+ { 0x000e, 0x0200 },
+ { 0x000d, 0x4007 },
+ { 0x000e, 0x0000 },
+ { 0x000d, 0x0001 }, /* force Master mode */
+ { 0x000e, 0x0834 },
+ { 0x000d, 0x4001 },
+ { 0x000e, 0x4000 },
+ { 0x000d, 0x0001 }, /* force 2.4v swing */
+ { 0x000e, 0x08f6 },
+ { 0x000d, 0x4001 },
+ { 0x000e, 0x1000 },
+ { 0x0608, 0x003b }, /* disable_0_transition */
+ { 0x0862, 0x39f8 }, /* AGC Gain during Autoneg */
+ { 0x081a, 0x67c0 }, /* deq offset for 1V swing */
+ { 0x081c, 0xfb62 }, /* deq offset for 2.4V swing */
+ { 0x0830, 0x05a3 }, /* Enable energy lost fallback */
+ { 0x0855, 0x1b55 }, /* MSE Threshold change */
+ { 0x0831, 0x0403 }, /* energy detect threshold */
+ { 0x0856, 0x1800 }, /* good1 MSE threshold change */
+ { 0x0857, 0x8fa0 }, /* Enable fallback to phase 1 on watchdog trigger */
+ { 0x0871, 0x000c }, /* TED input changed to slicer_in without FFE */
+ { 0x0883, 0x022e }, /* Enable Rx Filter, Change PGA threshold for Short Cable detection */
+ { 0x0402, 0x1800 }, /* Adjusr LD swing */
+ { 0x0878, 0x2248 }, /* Change PI up/down polarity */
+ { 0x010c, 0x0008 }, /* tx filter coefficient */
+ { 0x0112, 0x1212 }, /* tx filter scaling factor */
+ { 0x0809, 0x5c80 }, /* AGC retrain */
+ { 0x0803, 0x1529 }, /* Master Ph1 Back-off */
+ { 0x0804, 0x1a33 }, /* Master Ph1 Back-off */
+ { 0x0805, 0x1f3d }, /* Master Ph1 Back-off */
+ { 0x0850, 0x045b }, /* hybrid gain & delay */
+ { 0x0874, 0x6967 }, /* kp step 0 for master */
+ { 0x0852, 0x7800 }, /* FAGC init gain */
+ { 0x0806, 0x1e1e }, /* Master/Slave Ph2 Back-off */
+ { 0x0807, 0x2525 }, /* Master/Slave Ph2 Back-off */
+ { 0x0808, 0x2c2c }, /* Master/Slave Ph2 Back-off */
+ { 0x0850, 0x0590 }, /* Hybrid Gain/Delay Code */
+ { 0x0827, 0x4000 }, /* Echo Fixed Delay */
+ { 0x0849, 0x0fe4 }, /* Hybrid Cal enable */
+ { 0x084b, 0x04b5 }, /* Echo Score Sel */
+ { 0x0018, 0x0043 }, /* Set CRS/RX_DV pin as RX_DV for RMII repeater mode */
+};
+
+static struct dp83td510_init_reg dp83td510_slave_2_4[] = {
+ { 0x000d, 0x0007}, /* disable auto-neg */
+ { 0x000e, 0x0200},
+ { 0x000d, 0x4007},
+ { 0x000e, 0x0000},
+ { 0x000d, 0x0001}, /* force slave mode */
+ { 0x000e, 0x0834},
+ { 0x000d, 0x4001},
+ { 0x000e, 0x0000},
+ { 0x000d, 0x0001}, /* force 2.4v swing */
+ { 0x000e, 0x08f6},
+ { 0x000d, 0x4001},
+ { 0x000e, 0x1000},
+ { 0x0608, 0x003b}, /* disable_0_transition */
+ { 0x0862, 0x39f8}, /* AGC Gain during Autoneg */
+ { 0x081a, 0x67c0}, /* deq offset for 1V swing */
+ { 0x081c, 0xfb62}, /* deq offset for 2.4V swing */
+ { 0x0830, 0x05a3}, /* Enable energy lost fallback */
+ { 0x0855, 0x1b55}, /* MSE Threshold change */
+ { 0x0831, 0x0403}, /* energy detect threshold */
+ { 0x0856, 0x1800}, /* good1 MSE threshold change */
+ { 0x0857, 0x8fa0}, /* Enable fallback to phase 1 on watchdog trigger */
+ { 0x0871, 0x000c}, /* TED input changed to slicer_in without FFE */
+ { 0x0883, 0x022e}, /* Enable Rx Filter, Change PGA threshold for Short Cable detection */
+ { 0x0402, 0x1800}, /* Adjusr LD swing */
+ { 0x0878, 0x2248}, /* Change PI up/down polarity */
+ { 0x010c, 0x0008}, /* tx filter coefficient */
+ { 0x0112, 0x1212}, /* tx filter scaling factor */
+ { 0x0809, 0x5c80}, /* AGC retrain */
+ { 0x0803, 0x1529}, /* Master Ph1 Back-off */
+ { 0x0804, 0x1a33}, /* Master Ph1 Back-off */
+ { 0x0805, 0x1f3d}, /* Master Ph1 Back-off */
+ { 0x0850, 0x045b}, /* hybrid gain & delay */
+ { 0x0874, 0x6967}, /* kp step 0 for master */
+ { 0x0852, 0x7800}, /* FAGC init gain */
+ { 0x0806, 0x1e1e}, /* Master/Slave Ph2 Back-off */
+ { 0x0807, 0x2525}, /* Master/Slave Ph2 Back-off */
+ { 0x0808, 0x2c2c}, /* Master/Slave Ph2 Back-off */
+ { 0x0850, 0x0590}, /* Hybrid Gain/Delay Code */
+ { 0x0827, 0x4000}, /* Echo Fixed Delay */
+ { 0x0849, 0x0fe4}, /* Hybrid Cal enable */
+ { 0x084b, 0x04b5}, /* Echo Score Sel */
+ { 0x0018, 0x0043}, /* Set CRS/RX_DV pin as RX_DV for RMII repeater mode */
+};
+
+static struct dp83td510_init_reg dp83td510_auto_neg[] = {
+ { 0x608, 0x003b }, /* disable_0_transition */
+ { 0x862, 0x39f8 }, /* AGC Gain during Autoneg */
+ { 0x81a, 0x67c0 }, /* deq offset for 1V swing */
+ { 0x81c, 0xfb62 }, /* deq offset for 2.4V swing */
+ { 0x830, 0x05a3 }, /* Enable energy lost fallback */
+ { 0x855, 0x1b55 }, /* MSE Threshold change */
+ { 0x831, 0x0403 }, /* energy detect threshold */
+ { 0x856, 0x1800 }, /* good1 MSE threshold change */
+ { 0x857, 0x8fa0 }, /* Enable fallback to phase 1 on watchdog trigger */
+ { 0x871, 0x000c }, /* TED input changed to slicer_in without FFE */
+ { 0x883, 0x022e }, /* Enable Rx Filter Change PGA threshold for Short Cable detection */
+ { 0x402, 0x1800 }, /* Adjusr LD swing */
+ { 0x878, 0x2248 }, /* Change PI up/down polarity */
+ { 0x10c, 0x0008 }, /* tx filter coefficient */
+ { 0x112, 0x1212 }, /* tx filter scaling factor */
+ { 0x809, 0x5c80 }, /* AGC retrain */
+ { 0x803, 0x1529 }, /* Master Ph1 Back-off */
+ { 0x804, 0x1a33 }, /* Master Ph1 Back-off */
+ { 0x805, 0x1f3d }, /* Master Ph1 Back-off */
+ { 0x850, 0x045b }, /* hybrid gain & delay */
+ { 0x874, 0x6967 }, /* kp step 0 for master */
+ { 0x852, 0x7800 }, /* FAGC init gain */
+ { 0x806, 0x1e1e }, /* Master/Slave Ph2 Back-off */
+ { 0x807, 0x2525 }, /* Master/Slave Ph2 Back-off */
+ { 0x808, 0x2c2c }, /* Master/Slave Ph2 Back-off */
+ { 0x850, 0x0590 }, /* Hybrid Gain/Delay Code */
+ { 0x827, 0x4000 }, /* Echo Fixed Delay */
+ { 0x849, 0x0fe4 }, /* Hybrid Cal enable */
+ { 0x84b, 0x04b5 }, /* Echo Score Sel */
+ { 0x018, 0x0043 }, /* Set CRS/RX_DV pin as RX_DV for RMII repeater mode */
+};
+
+static int dp83td510_ack_interrupt(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = phy_read(phydev, DP83TD510_INT_REG1);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_read(phydev, DP83TD510_INT_REG2);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int dp83td510_config_intr(struct phy_device *phydev)
+{
+ int int_status;
+ int gen_cfg_val;
+ int ret;
+
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+ int_status = phy_read(phydev, DP83TD510_INT_REG1);
+ if (int_status < 0)
+ return int_status;
+
+ int_status = (DP83TD510_INT1_ESD_EN | DP83TD510_INT1_LINK_EN |
+ DP83TD510_INT1_RHF_EN);
+
+ ret = phy_write(phydev, DP83TD510_INT_REG1, int_status);
+ if (ret)
+ return ret;
+
+ int_status = phy_read(phydev, DP83TD510_INT_REG2);
+ if (int_status < 0)
+ return int_status;
+
+ int_status = (DP83TD510_INT2_POR | DP83TD510_INT2_POL |
+ DP83TD510_INT2_PAGE);
+
+ ret = phy_write(phydev, DP83TD510_INT_REG2, int_status);
+ if (ret)
+ return ret;
+
+ gen_cfg_val = phy_read(phydev, DP83TD510_GEN_CFG);
+ if (gen_cfg_val < 0)
+ return gen_cfg_val;
+
+ gen_cfg_val |= DP83TD510_INT_OE | DP83TD510_INT_EN;
+
+ } else {
+ ret = phy_write(phydev, DP83TD510_INT_REG1, 0);
+ if (ret)
+ return ret;
+
+ ret = phy_write(phydev, DP83TD510_INT_REG2, 0);
+ if (ret)
+ return ret;
+
+ gen_cfg_val = phy_read(phydev, DP83TD510_GEN_CFG);
+ if (gen_cfg_val < 0)
+ return gen_cfg_val;
+
+ gen_cfg_val &= ~DP83TD510_INT_EN;
+ }
+
+ return phy_write(phydev, DP83TD510_GEN_CFG, gen_cfg_val);
+}
+
+static int dp83td510_configure_mode(struct phy_device *phydev)
+{
+ struct dp83td510_private *dp83td510 = phydev->priv;
+ struct dp83td510_init_reg *init_data;
+ int size;
+ int ret;
+ int i;
+
+ ret = phy_set_bits(phydev, DP83TD510_MII_REG, DP83TD510_HW_RESET);
+ if (ret < 0)
+ return ret;
+
+ switch (dp83td510->forced_mode) {
+ case DP83TD510_MASTER_1:
+ size = ARRAY_SIZE(dp83td510_master_1_0);
+ init_data = dp83td510_master_1_0;
+ break;
+ case DP83TD510_MASTER_24:
+ size = ARRAY_SIZE(dp83td510_master_2_4);
+ init_data = dp83td510_master_2_4;
+ break;
+ case DP83TD510_SLAVE_1:
+ size = ARRAY_SIZE(dp83td510_slave_1_0);
+ init_data = dp83td510_slave_1_0;
+ break;
+ case DP83TD510_SLAVE_24:
+ size = ARRAY_SIZE(dp83td510_slave_2_4);
+ init_data = dp83td510_slave_2_4;
+ break;
+ case DP83TD510_AUTO_NEG:
+ default:
+ size = ARRAY_SIZE(dp83td510_auto_neg);
+ init_data = dp83td510_auto_neg;
+ break;
+ };
+
+ for (i = 0; i < size; i++) {
+ ret = phy_write_mmd(phydev, DP83TD510_DEVADDR, init_data[i].reg,
+ init_data[i].val);
+ if (ret)
+ return ret;
+ }
+
+ return phy_set_bits(phydev, DP83TD510_MII_REG, DP83TD510_SW_RESET);
+}
+
+static int dp83td510_get_features(struct phy_device *phydev)
+{
+ struct dp83td510_private *dp83td510 = phydev->priv;
+
+ linkmode_set_bit_array(dp83td510_feature_array,
+ ARRAY_SIZE(dp83td510_feature_array),
+ phydev->supported);
+
+ if (dp83td510->forced_mode == DP83TD510_AUTO_NEG)
+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
+
+ return 0;
+}
+
+static int dp83td510_config_init(struct phy_device *phydev)
+{
+ struct dp83td510_private *dp83td510 = phydev->priv;
+ int ret = 0;
+
+ if (phy_interface_is_rgmii(phydev)) {
+ if (dp83td510->rgmii_delay) {
+ ret = phy_set_bits_mmd(phydev, DP83TD510_DEVADDR,
+ DP83TD510_MAC_CFG_1, dp83td510->rgmii_delay);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RMII) {
+ ret = phy_modify(phydev, DP83TD510_GEN_CFG,
+ DP83TD510_FIFO_DEPTH_MASK,
+ dp83td510->tx_fifo_depth);
+ if (ret)
+ return ret;
+ }
+
+ return dp83td510_configure_mode(phydev);
+}
+
+static int dp83td510_phy_reset(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = phy_set_bits(phydev, DP83TD510_MII_REG, DP83TD510_SW_RESET);
+ if (ret < 0)
+ return ret;
+
+ usleep_range(10, 20);
+
+ return dp83td510_config_init(phydev);
+}
+
+static int dp83td510_read_straps(struct phy_device *phydev)
+{
+ struct dp83td510_private *dp83td510 = phydev->priv;
+ int strap;
+
+ strap = phy_read_mmd(phydev, DP83TD510_DEVADDR, DP83TD510_SOR_1);
+ if (strap < 0)
+ return strap;
+
+ if (strap & DP83TD510_RGMII)
+ dp83td510->is_rgmii = true;
+
+ return 0;
+};
+
+#if IS_ENABLED(CONFIG_OF_MDIO)
+static int dp83td510_of_init(struct phy_device *phydev)
+{
+ struct dp83td510_private *dp83td510 = phydev->priv;
+ struct device *dev = &phydev->mdio.dev;
+ struct device_node *of_node = dev->of_node;
+ s32 rx_int_delay;
+ s32 tx_int_delay;
+ int ret;
+
+ if (!of_node)
+ return -ENODEV;
+
+ ret = dp83td510_read_straps(phydev);
+ if (ret)
+ return ret;
+
+ ret = device_property_read_u32(&phydev->mdio.dev, "ti,master-slave-mode",
+ &dp83td510->forced_mode);
+ if (ret)
+ dp83td510->forced_mode = DP83TD510_AUTO_NEG;
+
+ if (dp83td510->forced_mode < DP83TD510_AUTO_NEG ||
+ dp83td510->forced_mode > DP83TD510_SLAVE_24)
+ return -EINVAL;
+
+ if (device_property_read_u32(&phydev->mdio.dev, "tx-fifo-depth",
+ &dp83td510->tx_fifo_depth))
+ dp83td510->tx_fifo_depth = DP83TD510_FIFO_DEPTH_5_B_NIB;
+
+ switch (dp83td510->tx_fifo_depth) {
+ case 4:
+ dp83td510->tx_fifo_depth = DP83TD510_FIFO_DEPTH_4_B_NIB;
+ break;
+ case 5:
+ dp83td510->tx_fifo_depth = DP83TD510_FIFO_DEPTH_5_B_NIB;
+ break;
+ case 6:
+ dp83td510->tx_fifo_depth = DP83TD510_FIFO_DEPTH_6_B_NIB;
+ break;
+ case 8:
+ dp83td510->tx_fifo_depth = DP83TD510_FIFO_DEPTH_8_B_NIB;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0, true);
+ if (rx_int_delay <= 0)
+ dp83td510->rgmii_delay = DP83TD510_RX_CLK_SHIFT;
+ else
+ dp83td510->rgmii_delay = 0;
+
+ tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0, false);
+ if (tx_int_delay <= 0)
+ dp83td510->rgmii_delay |= DP83TD510_TX_CLK_SHIFT;
+ else
+ dp83td510->rgmii_delay &= ~DP83TD510_TX_CLK_SHIFT;
+
+ return ret;
+}
+#else
+static int dp83869_of_init(struct phy_device *phydev)
+{
+ return dp83td510_read_straps(phydev);
+}
+#endif /* CONFIG_OF_MDIO */
+
+static int dp83td510_probe(struct phy_device *phydev)
+{
+ struct dp83td510_private *dp83td510;
+ int ret;
+
+ dp83td510 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83td510), GFP_KERNEL);
+ if (!dp83td510)
+ return -ENOMEM;
+
+ phydev->priv = dp83td510;
+
+ ret = dp83td510_of_init(phydev);
+ if (ret)
+ return ret;
+
+ return dp83td510_config_init(phydev);
+}
+
+static struct phy_driver dp83td510_driver[] = {
+ {
+ PHY_ID_MATCH_MODEL(DP83TD510E_PHY_ID),
+ .name = "TI DP83TD510E",
+ .probe = dp83td510_probe,
+ .config_init = dp83td510_config_init,
+ .soft_reset = dp83td510_phy_reset,
+
+ /* IRQ related */
+ .ack_interrupt = dp83td510_ack_interrupt,
+ .config_intr = dp83td510_config_intr,
+
+ .get_features = dp83td510_get_features,
+
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ },
+};
+module_phy_driver(dp83td510_driver);
+
+static struct mdio_device_id __maybe_unused dp83td510_tbl[] = {
+ { PHY_ID_MATCH_MODEL(DP83TD510E_PHY_ID) },
+ { }
+};
+MODULE_DEVICE_TABLE(mdio, dp83td510_tbl);
+
+MODULE_DESCRIPTION("Texas Instruments DP83TD510E PHY driver");
+MODULE_AUTHOR("Dan Murphy <[email protected]");
+MODULE_LICENSE("GPL v2");
+
--
2.28.0.585.ge1cfff676549

2020-10-21 09:24:07

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH net-next v2 2/3] dt-bindings: dp83td510: Add binding for DP83TD510 Ethernet PHY

> Humm. Are 1v and 2.4v advertised so it can be auto negotiated? Maybe a
> PHY tunable is not correct? Is this voltage selection actually more
> like pause and EEE?

[Goes and looks at the datasheet]

Register 0x20E, bit 13:

1 = Advertise that the 10BASE-T1L PHY has increased transmit/
receive level ability
0 = Do not advertise that the 10BASE-T1L PHY has increased
transmit/receive level ability (default)

So does this mean 2.4v?

Andrew

2020-10-21 16:26:32

by Dan Murphy

[permalink] [raw]
Subject: Re: [PATCH net-next v2 2/3] dt-bindings: dp83td510: Add binding for DP83TD510 Ethernet PHY

Andrew

On 10/20/20 2:07 PM, Andrew Lunn wrote:
>> Humm. Are 1v and 2.4v advertised so it can be auto negotiated? Maybe a
>> PHY tunable is not correct? Is this voltage selection actually more
>> like pause and EEE?
> [Goes and looks at the datasheet]
>
> Register 0x20E, bit 13:
>
> 1 = Advertise that the 10BASE-T1L PHY has increased transmit/
> receive level ability
> 0 = Do not advertise that the 10BASE-T1L PHY has increased
> transmit/receive level ability (default)
>
> So does this mean 2.4v?

This can also be strapped to a certain voltage level.  The device may
not have the regulators on board to drive a 2.4v signal. 1v signal AVDD
is 1.8v and 2.4v the AVDD needs to be at least 3.3v


This Strap defines the voltage level
requested by PHY during auto
negotiation. It is reflected in bit 12 of
0x20E. While using Force mode for
Linkup, the strap controls the output
voltage and reflects in bit 12 of 0x18F6

Bit 12

1 = Enable 2.4 Vpp operating mode
0 = Enable 1.0 Vpp operating mode

So maybe this is a hybrid of tunable for master/slave and a DT for
voltage level since the ability of the board to drive the signal can vary.

Dan


> Andrew

2020-10-21 17:02:35

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH net-next v2 2/3] dt-bindings: dp83td510: Add binding for DP83TD510 Ethernet PHY

> + ti,master-slave-mode:
> + $ref: /schemas/types.yaml#definitions/uint32
> + default: 0
> + description: |
> + Force the PHY to be configured to a specific mode.
> + Force Auto Negotiation - 0
> + Force Master mode at 1v p2p - 1
> + Force Master mode at 2.4v p2p - 2
> + Force Slave mode at 1v p2p - 3
> + Force Slave mode at 2.4v p2p - 4
> + enum: [ 0, 1, 2, 3, 4 ]

Is this a board hardware property? The fact value 0 means auto-neg
suggests not.

We already have ethtool configuration of master/slave for T1 PHYs:

ommit bdbdac7649fac05f88c9f7ab18121a17fb591687
Author: Oleksij Rempel <[email protected]>
Date: Tue May 5 08:35:05 2020 +0200

ethtool: provide UAPI for PHY master/slave configuration.

This UAPI is needed for BroadR-Reach 100BASE-T1 devices. Due to lack of
auto-negotiation support, we needed to be able to configure the
MASTER-SLAVE role of the port manually or from an application in user
space.

Please can you look at using that UAPI.

I assume that 1v p2p is the voltage of the signal put onto the twisted
pair? I know the Marvell 1000BaseT PHYs allow this to be configured as
well, but just downwards to save power. Maybe a PHY tunable would be
better?

Humm. Are 1v and 2.4v advertised so it can be auto negotiated? Maybe a
PHY tunable is not correct? Is this voltage selection actually more
like pause and EEE?

Andrew