devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alexandru Ardelean <alexandru.ardelean@analog.com>
To: netdev@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org
Cc: davem@davemloft.net, robh+dt@kernel.org, mark.rutland@arm.com,
	f.fainelli@gmail.com, hkallweit1@gmail.com, andrew@lunn.ch,
	Alexandru Ardelean <alexandru.ardelean@analog.com>
Subject: [PATCH v2 11/15] net: phy: adin: implement PHY subsystem software reset
Date: Thu, 8 Aug 2019 15:30:22 +0300	[thread overview]
Message-ID: <20190808123026.17382-12-alexandru.ardelean@analog.com> (raw)
In-Reply-To: <20190808123026.17382-1-alexandru.ardelean@analog.com>

The ADIN PHYs supports 4 types of reset:
1. The standard PHY reset via BMCR_RESET bit in MII_BMCR reg
2. Reset via GPIO
3. Reset via reg GeSftRst (0xff0c) & reload previous pin configs
4. Reset via reg GeSftRst (0xff0c) & request new pin configs

Resets 2 & 4 are almost identical, with the exception that the crystal
oscillator is available during reset for 2.

As it turns out, phylib already supports GPIO reset.
In case this is configured, the PHY driver won't do anything. In case it
isn't specified the subsystem software reset will kick in.

Resetting via GeSftRst or via GPIO is useful when doing a warm reboot,
because this will reset the subsystem registers to default values.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
 drivers/net/phy/adin.c | 43 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
index c1cea1b6bd75..f276d692bdee 100644
--- a/drivers/net/phy/adin.c
+++ b/drivers/net/phy/adin.c
@@ -6,6 +6,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/bitfield.h>
+#include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -53,6 +54,9 @@
 #define ADIN1300_CLOCK_STOP_REG			0x9400
 #define ADIN1300_LPI_WAKE_ERR_CNT_REG		0xa000
 
+#define ADIN1300_GE_SOFT_RESET_REG		0xff0c
+#define   ADIN1300_GE_SOFT_RESET		BIT(0)
+
 #define ADIN1300_GE_RGMII_CFG_REG		0xff23
 #define   ADIN1300_GE_RGMII_RX_MSK		GENMASK(8, 6)
 #define   ADIN1300_GE_RGMII_RX_SEL(x)		\
@@ -457,11 +461,49 @@ static int adin_read_status(struct phy_device *phydev)
 	return genphy_read_status(phydev);
 }
 
+static int adin_subsytem_soft_reset(struct phy_device *phydev)
+{
+	int reg, rc, i;
+
+	rc = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+			      ADIN1300_GE_SOFT_RESET_REG,
+			      ADIN1300_GE_SOFT_RESET);
+	if (rc < 0)
+		return rc;
+
+	for (i = 0; i < 20; i++) {
+		usleep_range(500, 1000);
+		reg = phy_read_mmd(phydev, MDIO_MMD_VEND1,
+				   ADIN1300_GE_SOFT_RESET_REG);
+		if (reg < 0 || (reg & ADIN1300_GE_SOFT_RESET))
+			continue;
+		return 0;
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int adin_reset(struct phy_device *phydev)
+{
+	/* If there is a reset GPIO just exit */
+	if (!IS_ERR_OR_NULL(phydev->mdio.reset_gpio))
+		return 0;
+
+	/* Reset PHY core regs & subsystem regs */
+	return adin_subsytem_soft_reset(phydev);
+}
+
+static int adin_probe(struct phy_device *phydev)
+{
+	return adin_reset(phydev);
+}
+
 static struct phy_driver adin_driver[] = {
 	{
 		PHY_ID_MATCH_MODEL(PHY_ID_ADIN1200),
 		.name		= "ADIN1200",
 		.config_init	= adin_config_init,
+		.probe		= adin_probe,
 		.config_aneg	= adin_config_aneg,
 		.read_status	= adin_read_status,
 		.get_features	= genphy_read_abilities,
@@ -476,6 +518,7 @@ static struct phy_driver adin_driver[] = {
 		PHY_ID_MATCH_MODEL(PHY_ID_ADIN1300),
 		.name		= "ADIN1300",
 		.config_init	= adin_config_init,
+		.probe		= adin_probe,
 		.config_aneg	= adin_config_aneg,
 		.read_status	= adin_read_status,
 		.get_features	= genphy_read_abilities,
-- 
2.20.1

  parent reply	other threads:[~2019-08-08 12:30 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-08 12:30 [PATCH v2 00/15] net: phy: adin: add support for Analog Devices PHYs Alexandru Ardelean
2019-08-08 12:30 ` [PATCH v2 01/15] " Alexandru Ardelean
2019-08-08 15:13   ` Andrew Lunn
2019-08-08 12:30 ` [PATCH v2 02/15] net: phy: adin: hook genphy_read_abilities() to get_features Alexandru Ardelean
2019-08-08 15:24   ` Andrew Lunn
2019-08-08 19:32     ` Heiner Kallweit
2019-08-09 12:00       ` Ardelean, Alexandru
2019-08-08 12:30 ` [PATCH v2 03/15] net: phy: adin: hook genphy_{suspend,resume} into the driver Alexandru Ardelean
2019-08-08 15:24   ` Andrew Lunn
2019-08-08 12:30 ` [PATCH v2 04/15] net: phy: adin: add support for interrupts Alexandru Ardelean
2019-08-08 15:25   ` Andrew Lunn
2019-08-08 12:30 ` [PATCH v2 05/15] net: phy: adin: add {write,read}_mmd hooks Alexandru Ardelean
2019-08-08 15:35   ` Andrew Lunn
2019-08-09 12:05     ` Ardelean, Alexandru
2019-08-08 12:30 ` [PATCH v2 06/15] net: phy: adin: configure RGMII/RMII/MII modes on config Alexandru Ardelean
2019-08-08 15:38   ` Andrew Lunn
2019-08-08 12:30 ` [PATCH v2 07/15] net: phy: adin: make RGMII internal delays configurable Alexandru Ardelean
2019-08-08 15:40   ` Andrew Lunn
2019-08-08 12:30 ` [PATCH v2 08/15] net: phy: adin: make RMII fifo depth configurable Alexandru Ardelean
2019-08-08 15:42   ` Andrew Lunn
2019-08-08 12:30 ` [PATCH v2 09/15] net: phy: adin: add support MDI/MDIX/Auto-MDI selection Alexandru Ardelean
2019-08-08 12:30 ` [PATCH v2 10/15] net: phy: adin: add EEE translation layer from Clause 45 to Clause 22 Alexandru Ardelean
2019-08-08 12:30 ` Alexandru Ardelean [this message]
2019-08-08 12:30 ` [PATCH v2 12/15] net: phy: adin: implement Energy Detect Powerdown mode Alexandru Ardelean
2019-08-08 12:30 ` [PATCH v2 13/15] net: phy: adin: configure downshift on config_init Alexandru Ardelean
2019-08-08 19:38   ` Heiner Kallweit
2019-08-08 20:39     ` Andrew Lunn
2019-08-09 12:06       ` Ardelean, Alexandru
2019-08-08 12:30 ` [PATCH v2 14/15] net: phy: adin: add ethtool get_stats support Alexandru Ardelean
2019-08-08 12:30 ` [PATCH v2 15/15] dt-bindings: net: add bindings for ADIN PHY driver Alexandru Ardelean
2019-08-08 23:03   ` Rob Herring
2019-08-09 12:06     ` Ardelean, Alexandru
2019-08-08 18:24 ` [PATCH v2 00/15] net: phy: adin: add support for Analog Devices PHYs David Miller
2019-08-09 12:32   ` Ardelean, Alexandru

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190808123026.17382-12-alexandru.ardelean@analog.com \
    --to=alexandru.ardelean@analog.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=f.fainelli@gmail.com \
    --cc=hkallweit1@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=netdev@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).