diff mbox series

[4/5] net: phy: dp83tg720: Added OA script

Message ID c41bc533471bab570be58bca3eae057554a56389.1726263095.git.a-reyes1@ti.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series Extending features on DP83TG720 driver | expand

Checks

Context Check Description
netdev/series_format warning Target tree name not specified in the subject
netdev/tree_selection success Guessed tree name to be net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 16 this patch: 16
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 3 maintainers not CCed: pabeni@redhat.com kuba@kernel.org edumazet@google.com
netdev/build_clang success Errors and warnings before: 16 this patch: 16
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 16 this patch: 16
netdev/checkpatch fail CHECK: Alignment should match open parenthesis ERROR: trailing whitespace WARNING: line length of 113 exceeds 80 columns WARNING: line length of 82 exceeds 80 columns WARNING: line length of 83 exceeds 80 columns WARNING: line length of 84 exceeds 80 columns WARNING: line length of 85 exceeds 80 columns WARNING: line length of 86 exceeds 80 columns WARNING: line length of 87 exceeds 80 columns WARNING: line length of 88 exceeds 80 columns WARNING: line length of 89 exceeds 80 columns WARNING: line length of 94 exceeds 80 columns WARNING: please, no spaces at the start of a line WARNING: suspect code indent for conditional statements (24, 40) WARNING: suspect code indent for conditional statements (8, 24)
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Alvaro (Al-vuh-roe) Reyes Sept. 19, 2024, 9:01 p.m. UTC
For the DP83TG720 & DP83TG721 to function properly, both need an
initialization script to be run at boot up. The init script and a chip_init
function have been added to handle this condition. 

Signed-off-by: Alvaro (Al-vuh-roe) Reyes <a-reyes1@ti.com>
---
 drivers/net/phy/dp83tg720.c | 355 ++++++++++++++++++++++++++++++++----
 1 file changed, 324 insertions(+), 31 deletions(-)

Comments

Andrew Lunn Sept. 19, 2024, 9:44 p.m. UTC | #1
> +struct DP83TG720_init_reg {
> +	int MMD;
> +	int reg;
> +	int val;
> +};
> +
> +/*Refer to SNLA371 for more information*/
> +static const struct DP83TG720_init_reg DP83TG720_cs1_1_master_init[] = {
> +	{0x1F, 0x001F, 0X8000},
> +	{0x1F, 0x0573, 0x0101},
> +	{0x1, 0x0834, 0xC001},

MDIO_MMD_VEND2 etc.

Also 0x834 is BASE-T1 PMA/PMD control. Which is MDIO_PMA_PMD_BT1_CTRL

We also have:
#define MDIO_PMA_PMD_BT1_CTRL_STRAP_B1000 0x0001 /* Select 1000BASE-T1 */
#define MDIO_PMA_PMD_BT1_CTRL_CFG_MST		0x4000 /* MASTER-SLAVE config value */

802.3 says bit 15 is read only, so you don't need to set it.

The rest might be magic which nobody outside of TI will understand,
but you can fully document this.

> +static int dp83tg720_reset(struct phy_device *phydev, bool hw_reset)
> +{
> +	int ret;
> +
> +	if (hw_reset)
> +		ret = phy_write_mmd(phydev, MMD1F, DP83TG720_PHY_RESET_CTRL,
> +				DP83TG720_HW_RESET);
> +	else
> +		ret = phy_write_mmd(phydev, MMD1F, DP83TG720_PHY_RESET_CTRL,
> +				DP83TG720_SW_RESET);
> +	if (ret)
> +		return ret;
> +
> +	mdelay(100);

Does the bit not self clear when it has completed? That would be
common for a reset bit.

> +static int DP83TG720_write_seq(struct phy_device *phydev,
> +			     const struct DP83TG720_init_reg *init_data, int size)
> +{
> +	int ret;
> +	int i;
> +
> +	for (i = 0; i < size; i++) {
> +			ret = phy_write_mmd(phydev, init_data[i].MMD, init_data[i].reg,
> +				init_data[i].val);
> +			if (ret)
> +					return ret;
> +	}

More messed up indentation.

> +static int dp83tg720_chip_init(struct phy_device *phydev)
> +{
> +	struct DP83TG720_private *DP83TG720 = phydev->priv;
> +	int ret;
> +
> +	ret = dp83tg720_reset(phydev, true);
> +	if (ret)
> +		return ret;
> +	
> +	phydev->autoneg = AUTONEG_DISABLE;
> +    phydev->speed = SPEED_1000;
> +	phydev->duplex = DUPLEX_FULL;
> +    linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, phydev->supported);

This should not be needed. phylib should be able to figure this out
for itself from the registers. Please check that functions like
genphy_c45_pma_baset1_read_abilities() are doing.

> +
> +	switch (DP83TG720->chip) {
> +	case DP83TG720_CS1_1:
> +		if (DP83TG720->is_master)
> +			ret = DP83TG720_write_seq(phydev, DP83TG720_cs1_1_master_init,
> +						ARRAY_SIZE(DP83TG720_cs1_1_master_init));
> +		else
> +			ret = DP83TG720_write_seq(phydev, DP83TG720_cs1_1_slave_init,
> +						ARRAY_SIZE(DP83TG720_cs1_1_slave_init));
> +
> +		ret = dp83tg720_reset(phydev, false);
> +
> +		return 1;

0 on success, negative error code on error.

	Andrew
diff mbox series

Patch

diff --git a/drivers/net/phy/dp83tg720.c b/drivers/net/phy/dp83tg720.c
index b70802818f3c..4df6713c51e3 100644
--- a/drivers/net/phy/dp83tg720.c
+++ b/drivers/net/phy/dp83tg720.c
@@ -31,8 +31,9 @@ 
 /* 1b = TDR fail, 0b = TDR success */
 #define DP83TG720_TDR_FAIL				BIT(0)
 
-#define DP83TG720_PHY_RESET				0x1f
-#define DP83TG720_HW_RESET				BIT(15)
+#define DP83TG720_PHY_RESET_CTRL		0x1f
+#define DP83TG720_HW_RESET			    BIT(15)
+#define DP83TG720_SW_RESET              BIT(14)
 
 #define DP83TG720_LPS_CFG3				0x18c
 /* Power modes are documented as bit fields but used as values */
@@ -100,6 +101,221 @@  struct DP83TG720_private {
 	bool tx_shift;
 };
 
+struct DP83TG720_init_reg {
+	int MMD;
+	int reg;
+	int val;
+};
+
+/*Refer to SNLA371 for more information*/
+static const struct DP83TG720_init_reg DP83TG720_cs1_1_master_init[] = {
+	{0x1F, 0x001F, 0X8000},
+	{0x1F, 0x0573, 0x0101},
+	{0x1, 0x0834, 0xC001},
+	{0x1F, 0x0405, 0x5800},
+	{0x1F, 0x08AD, 0x3C51},
+	{0x1F, 0x0894, 0x5DF7},
+	{0x1F, 0x08A0, 0x09E7},
+	{0x1F, 0x08C0, 0x4000},
+	{0x1F, 0x0814, 0x4800},
+	{0x1F, 0x080D, 0x2EBF},
+	{0x1F, 0x08C1, 0x0B00},
+	{0x1F, 0x087D, 0x0001},
+	{0x1F, 0x082E, 0x0000},
+	{0x1F, 0x0837, 0x00F4},
+	{0x1F, 0x08BE, 0x0200},
+	{0x1F, 0x08C5, 0x4000},
+	{0x1F, 0x08C7, 0x2000},
+	{0x1F, 0x08B3, 0x005A},
+	{0x1F, 0x08B4, 0x005A},
+	{0x1F, 0x08B0, 0x0202},
+	{0x1F, 0x08B5, 0x00EA},
+	{0x1F, 0x08BA, 0x2828},
+	{0x1F, 0x08BB, 0x6828},
+	{0x1F, 0x08BC, 0x0028},
+	{0x1F, 0x08BF, 0x0000},
+	{0x1F, 0x08B1, 0x0014},
+	{0x1F, 0x08B2, 0x0008},
+	{0x1F, 0x08EC, 0x0000},
+	{0x1F, 0x08C8, 0x0003},
+	{0x1F, 0x08BE, 0x0201},
+	{0x1F, 0x018C, 0x0001},
+	{0x1F, 0x001F, 0x4000},
+	{0x1F, 0x0573, 0x0001},
+	{0x1F, 0x056A, 0x5F41},
+};
+
+/*Refer to SNLA371 for more information*/
+static const struct DP83TG720_init_reg DP83TG720_cs1_1_slave_init[] = {
+	{0x1F, 0x001F, 0x8000},
+	{0x1F, 0x0573, 0x0101},
+	{0x1, 0x0834, 0x8001},
+	{0x1F, 0x0894, 0x5DF7},
+	{0x1F, 0x056a, 0x5F40},
+	{0x1F, 0x0405, 0x5800},
+	{0x1F, 0x08AD, 0x3C51},
+	{0x1F, 0x0894, 0x5DF7},
+	{0x1F, 0x08A0, 0x09E7},
+	{0x1F, 0x08C0, 0x4000},
+	{0x1F, 0x0814, 0x4800},
+	{0x1F, 0x080D, 0x2EBF},
+	{0x1F, 0x08C1, 0x0B00},
+	{0x1F, 0x087d, 0x0001},
+	{0x1F, 0x082E, 0x0000},
+	{0x1F, 0x0837, 0x00f4},
+	{0x1F, 0x08BE, 0x0200},
+	{0x1F, 0x08C5, 0x4000},
+	{0x1F, 0x08C7, 0x2000},
+	{0x1F, 0x08B3, 0x005A},
+	{0x1F, 0x08B4, 0x005A},
+	{0x1F, 0x08B0, 0x0202},
+	{0x1F, 0x08B5, 0x00EA},
+	{0x1F, 0x08BA, 0x2828},
+	{0x1F, 0x08BB, 0x6828},
+	{0x1F, 0x08BC, 0x0028},
+	{0x1F, 0x08BF, 0x0000},
+	{0x1F, 0x08B1, 0x0014},
+	{0x1F, 0x08B2, 0x0008},
+	{0x1F, 0x08EC, 0x0000},
+	{0x1F, 0x08C8, 0x0003},
+	{0x1F, 0x08BE, 0x0201},
+	{0x1F, 0x056A, 0x5F40},
+	{0x1F, 0x018C, 0x0001},
+	{0x1F, 0x001F, 0x4000},
+	{0x1F, 0x0573, 0x0001},
+	{0x1F, 0x056A, 0X5F41},
+};
+
+/*Refer to SNLA371 for more information*/
+static const struct DP83TG720_init_reg DP83TG721_cs1_master_init[] = {
+	{0x1F, 0x001F, 0x8000},
+	{0x1F, 0x0573, 0x0801},
+	{0x1, 0x0834, 0xC001},
+	{0x1F, 0x0405, 0x6C00},
+	{0x1F, 0x08AD, 0x3C51},
+	{0x1F, 0x0894, 0x5DF7},
+	{0x1F, 0x08A0, 0x09E7},
+	{0x1F, 0x08C0, 0x4000},
+	{0x1F, 0x0814, 0x4800},
+	{0x1F, 0x080D, 0x2EBF},
+	{0x1F, 0x08C1, 0x0B00},
+	{0x1F, 0x087D, 0x0001},
+	{0x1F, 0x082E, 0x0000},
+	{0x1F, 0x0837, 0x00F8},
+	{0x1F, 0x08BE, 0x0200},
+	{0x1F, 0x08C5, 0x4000},
+	{0x1F, 0x08C7, 0x2000},
+	{0x1F, 0x08B3, 0x005A},
+	{0x1F, 0x08B4, 0x005A},
+	{0x1F, 0x08B0, 0x0202},
+	{0x1F, 0x08B5, 0x00EA},
+	{0x1F, 0x08BA, 0x2828},
+	{0x1F, 0x08BB, 0x6828},
+	{0x1F, 0x08BC, 0x0028},
+	{0x1F, 0x08BF, 0x0000},
+	{0x1F, 0x08B1, 0x0014},
+	{0x1F, 0x08B2, 0x0008},
+	{0x1F, 0x08EC, 0x0000},
+	{0x1F, 0x08FC, 0x0091},
+	{0x1F, 0x08BE, 0x0201},
+	{0x1F, 0x0335, 0x0010},
+	{0x1F, 0x0336, 0x0009},
+	{0x1F, 0x0337, 0x0208},
+	{0x1F, 0x0338, 0x0208},
+	{0x1F, 0x0339, 0x02CB},
+	{0x1F, 0x033A, 0x0208},
+	{0x1F, 0x033B, 0x0109},
+	{0x1F, 0x0418, 0x0380},
+	{0x1F, 0x0420, 0xFF10},
+	{0x1F, 0x0421, 0x4033},
+	{0x1F, 0x0422, 0x0800},
+	{0x1F, 0x0423, 0x0002},
+	{0x1F, 0x0484, 0x0003},
+	{0x1F, 0x055D, 0x0008},
+	{0x1F, 0x042B, 0x0018},
+	{0x1F, 0x087C, 0x0080},
+	{0x1F, 0x08C1, 0x0900},
+	{0x1F, 0x08fc, 0x4091},
+	{0x1F, 0x0881, 0x5146},
+	{0x1F, 0x08be, 0x02a1},
+	{0x1F, 0x0867, 0x9999},
+	{0x1F, 0x0869, 0x9666},
+	{0x1F, 0x086a, 0x0009},
+	{0x1F, 0x0822, 0x11e1},
+	{0x1F, 0x08f9, 0x1f11},
+	{0x1F, 0x08a3, 0x24e8},
+	{0x1F, 0x018C, 0x0001},
+	{0x1F, 0x001F, 0x4000},
+	{0x1F, 0x0573, 0x0001},
+	{0x1F, 0x056A, 0x5F41},
+};
+
+/*Refer to SNLA371 for more information*/
+static const struct DP83TG720_init_reg DP83TG721_cs1_slave_init[] = {
+	{0x1F, 0x001F, 0x8000},
+	{0x1F, 0x0573, 0x0801},
+	{0x1, 0x0834, 0x8001},
+	{0x1F, 0x0405, 0X6C00},
+	{0x1F, 0x08AD, 0x3C51},
+	{0x1F, 0x0894, 0x5DF7},
+	{0x1F, 0x08A0, 0x09E7},
+	{0x1F, 0x08C0, 0x4000},
+	{0x1F, 0x0814, 0x4800},
+	{0x1F, 0x080D, 0x2EBF},
+	{0x1F, 0x08C1, 0x0B00},
+	{0x1F, 0x087D, 0x0001},
+	{0x1F, 0x082E, 0x0000},
+	{0x1F, 0x0837, 0x00F8},
+	{0x1F, 0x08BE, 0x0200},
+	{0x1F, 0x08C5, 0x4000},
+	{0x1F, 0x08C7, 0x2000},
+	{0x1F, 0x08B3, 0x005A},
+	{0x1F, 0x08B4, 0x005A},
+	{0x1F, 0x08B0, 0x0202},
+	{0x1F, 0x08B5, 0x00EA},
+	{0x1F, 0x08BA, 0x2828},
+	{0x1F, 0x08BB, 0x6828},
+	{0x1F, 0x08BC, 0x0028},
+	{0x1F, 0x08BF, 0x0000},
+	{0x1F, 0x08B1, 0x0014},
+	{0x1F, 0x08B2, 0x0008},
+	{0x1F, 0x08EC, 0x0000},
+	{0x1F, 0x08FC, 0x0091},
+	{0x1F, 0x08BE, 0x0201},
+	{0x1F, 0x0456, 0x0160},
+	{0x1F, 0x0335, 0x0010},
+	{0x1F, 0x0336, 0x0009},
+	{0x1F, 0x0337, 0x0208},
+	{0x1F, 0x0338, 0x0208},
+	{0x1F, 0x0339, 0x02CB},
+	{0x1F, 0x033A, 0x0208},
+	{0x1F, 0x033B, 0x0109},
+	{0x1F, 0x0418, 0x0380},
+	{0x1F, 0x0420, 0xFF10},
+	{0x1F, 0x0421, 0x4033},
+	{0x1F, 0x0422, 0x0800},
+	{0x1F, 0x0423, 0x0002},
+	{0x1F, 0x0484, 0x0003},
+	{0x1F, 0x055D, 0x0008},
+	{0x1F, 0x042B, 0x0018},
+	{0x1F, 0x082D, 0x120F},
+	{0x1F, 0x0888, 0x0438},
+	{0x1F, 0x0824, 0x09E0},
+	{0x1F, 0x0883, 0x5146},
+	{0x1F, 0x08BE, 0x02A1},
+	{0x1F, 0x0822, 0x11E1},
+	{0x1F, 0x056A, 0x5F40},
+	{0x1F, 0x08C1, 0x0900},
+	{0x1F, 0x08FC, 0x4091},
+	{0x1F, 0x08F9, 0x1F11},
+	{0x1F, 0x084F, 0x290C},
+	{0x1F, 0x0850, 0x3D33},
+	{0x1F, 0x018C, 0x0001},
+	{0x1F, 0x001F, 0x4000},
+	{0x1F, 0x0573, 0x0001},
+	{0x1F, 0x056A, 0x5F41},
+};
+
 static int dp83tg720_read_straps(struct phy_device *phydev)
 {
 	struct DP83TG720_private *DP83TG720 = phydev->priv;
@@ -127,6 +343,55 @@  static int dp83tg720_read_straps(struct phy_device *phydev)
 	return 0;
 };
 
+static int dp83tg720_reset(struct phy_device *phydev, bool hw_reset)
+{
+	int ret;
+
+	if (hw_reset)
+		ret = phy_write_mmd(phydev, MMD1F, DP83TG720_PHY_RESET_CTRL,
+				DP83TG720_HW_RESET);
+	else
+		ret = phy_write_mmd(phydev, MMD1F, DP83TG720_PHY_RESET_CTRL,
+				DP83TG720_SW_RESET);
+	if (ret)
+		return ret;
+
+	mdelay(100);
+
+	return 0;
+}
+
+static int dp83tg720_phy_reset(struct phy_device *phydev)
+{
+	int ret;
+
+	ret = dp83tg720_reset(phydev, false);
+	if (ret)
+		return ret;
+
+	ret = dp83tg720_read_straps(phydev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int DP83TG720_write_seq(struct phy_device *phydev,
+			     const struct DP83TG720_init_reg *init_data, int size)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < size; i++) {
+			ret = phy_write_mmd(phydev, init_data[i].MMD, init_data[i].reg,
+				init_data[i].val);
+			if (ret)
+					return ret;
+	}
+
+	return 0;
+}
+
 /**
  * dp83tg720_cable_test_start - Start the cable test for the DP83TG720 PHY.
  * @phydev: Pointer to the phy_device structure.
@@ -362,6 +627,61 @@  static int dp83tg720_config_rgmii_delay(struct phy_device *phydev)
 			      rgmii_delay);
 }
 
+static int dp83tg720_chip_init(struct phy_device *phydev)
+{
+	struct DP83TG720_private *DP83TG720 = phydev->priv;
+	int ret;
+
+	ret = dp83tg720_reset(phydev, true);
+	if (ret)
+		return ret;
+	
+	phydev->autoneg = AUTONEG_DISABLE;
+    phydev->speed = SPEED_1000;
+	phydev->duplex = DUPLEX_FULL;
+    linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, phydev->supported);
+
+	switch (DP83TG720->chip) {
+	case DP83TG720_CS1_1:
+		if (DP83TG720->is_master)
+			ret = DP83TG720_write_seq(phydev, DP83TG720_cs1_1_master_init,
+						ARRAY_SIZE(DP83TG720_cs1_1_master_init));
+		else
+			ret = DP83TG720_write_seq(phydev, DP83TG720_cs1_1_slave_init,
+						ARRAY_SIZE(DP83TG720_cs1_1_slave_init));
+
+		ret = dp83tg720_reset(phydev, false);
+
+		return 1;
+	case DP83TG721_CS1:
+		if (DP83TG720->is_master)
+			ret = DP83TG720_write_seq(phydev, DP83TG721_cs1_master_init,
+						ARRAY_SIZE(DP83TG721_cs1_master_init));
+		else
+			ret = DP83TG720_write_seq(phydev, DP83TG721_cs1_slave_init,
+						ARRAY_SIZE(DP83TG721_cs1_slave_init));
+
+		ret = dp83tg720_reset(phydev, false);
+
+		return 1;
+	default:
+		return -EINVAL;
+	};
+
+	if (ret)
+		return ret;
+
+	/* Enable the PHY */
+	ret = phy_write_mmd(phydev, MMD1F, DP83TG720_LPS_CFG3, DP83TG720_LPS_CFG3_PWR_MODE_0);
+	if (ret)
+		return ret;
+
+	mdelay(10);
+
+	/* Do a software reset to restart the PHY with the updated values */
+	return dp83tg720_reset(phydev, false);
+}
+
 static int dp83tg720_config_init(struct phy_device *phydev)
 {
 	int value, ret;
@@ -369,9 +689,7 @@  static int dp83tg720_config_init(struct phy_device *phydev)
 	/* Software Restart is not enough to recover from a link failure.
 	 * Using Hardware Reset instead.
 	 */
-	ret = phy_write(phydev, DP83TG720_PHY_RESET, DP83TG720_HW_RESET);
-	if (ret)
-		return ret;
+	ret = dp83tg720_chip_init(phydev);
 
 	/* Wait until MDC can be used again.
 	 * The wait value of one 1ms is documented in "DP83TG720-Q1 1000BASE-T1
@@ -447,6 +765,7 @@  static int dp83tg720_probe(struct phy_device *phydev)
     PHY_ID_MATCH_EXACT(_id),                                            \
     .name                   = (_name),                                  \
     .probe                  = dp83tg720_probe,                          \
+	.soft_reset				= dp83tg720_phy_reset,						\
     .flags                  = PHY_POLL_CABLE_TEST,                      \
     .config_aneg            = dp83tg720_config_aneg,                    \
     .read_status            = dp83tg720_read_status,                    \
@@ -473,32 +792,6 @@  static struct mdio_device_id __maybe_unused dp83tg720_tbl[] = {
 };
 MODULE_DEVICE_TABLE(mdio, dp83tg720_tbl);
 
-// static struct phy_driver dp83tg720_driver[] = {
-// {
-// 	PHY_ID_MATCH_MODEL(DP83TG720_PHY_ID),
-// 	.name		= "TI DP83TG720",
-
-// 	.flags          = PHY_POLL_CABLE_TEST,
-// 	.config_aneg	= dp83tg720_config_aneg,
-// 	.read_status	= dp83tg720_read_status,
-// 	.get_features	= genphy_c45_pma_read_ext_abilities,
-// 	.config_init	= dp83tg720_config_init,
-// 	.get_sqi	= dp83tg720_get_sqi,
-// 	.get_sqi_max	= dp83tg720_get_sqi_max,
-// 	.cable_test_start = dp83tg720_cable_test_start,
-// 	.cable_test_get_status = dp83tg720_cable_test_get_status,
-
-// 	.suspend	= genphy_suspend,
-// 	.resume		= genphy_resume,
-// } };
-// module_phy_driver(dp83tg720_driver);
-
-// static struct mdio_device_id __maybe_unused dp83tg720_tbl[] = {
-// 	{ PHY_ID_MATCH_MODEL(DP83TG720_PHY_ID) },
-// 	{ }
-// };
-// MODULE_DEVICE_TABLE(mdio, dp83tg720_tbl);
-
 MODULE_DESCRIPTION("Texas Instruments DP83TG720 PHY driver");
 MODULE_AUTHOR("Oleksij Rempel <kernel@pengutronix.de>");
 MODULE_LICENSE("GPL");