diff mbox series

[v2] net: phy: add driver for Motorcomm yt8511 phy

Message ID 20210511225913.2951922-1-pgwipeout@gmail.com (mailing list archive)
State New, archived
Headers show
Series [v2] net: phy: add driver for Motorcomm yt8511 phy | expand

Commit Message

Peter Geis May 11, 2021, 10:59 p.m. UTC
Add a driver for the Motorcomm yt8511 phy that will be used in the
production Pine64 rk3566-quartz64 development board.
It supports gigabit transfer speeds, rgmii, and 125mhz clk output.

Signed-off-by: Peter Geis <pgwipeout@gmail.com>
---
Changes v2:
- Change to __phy_modify
- Handle return errors
- Remove unnecessary &

 MAINTAINERS                 |  6 +++
 drivers/net/phy/Kconfig     |  6 +++
 drivers/net/phy/Makefile    |  1 +
 drivers/net/phy/motorcomm.c | 87 +++++++++++++++++++++++++++++++++++++
 4 files changed, 100 insertions(+)
 create mode 100644 drivers/net/phy/motorcomm.c

Comments

Andrew Lunn May 12, 2021, 12:48 a.m. UTC | #1
On Tue, May 11, 2021 at 06:59:13PM -0400, Peter Geis wrote:
> Add a driver for the Motorcomm yt8511 phy that will be used in the
> production Pine64 rk3566-quartz64 development board.
> It supports gigabit transfer speeds, rgmii, and 125mhz clk output.

Hi Peter

Please can you add minimal RGMII delay support. Trying to add it later
generally end up in backwards compatibility problems.

Do you know which one of the four RGMII modes your setup needs? Is the
PHY adding the Rx and Tx delays? So "rgmii-id"?

       Andrew
Peter Geis May 12, 2021, 1:45 a.m. UTC | #2
On Tue, May 11, 2021 at 8:48 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> On Tue, May 11, 2021 at 06:59:13PM -0400, Peter Geis wrote:
> > Add a driver for the Motorcomm yt8511 phy that will be used in the
> > production Pine64 rk3566-quartz64 development board.
> > It supports gigabit transfer speeds, rgmii, and 125mhz clk output.
>
> Hi Peter
>
> Please can you add minimal RGMII delay support. Trying to add it later
> generally end up in backwards compatibility problems.

It should be possible, yes.
I experimented a bit with it but it just broke things.
I'm still digging through the datasheet to find what is possible for this PHY.
A lot of items should be set up via the device tree, though it seems
this is a relatively unused concept in the net phy subsystem.
As I'm relatively new to this subsystem I'm still learning as well.

>
> Do you know which one of the four RGMII modes your setup needs? Is the
> PHY adding the Rx and Tx delays? So "rgmii-id"?

By default it implements a 500ps delay internally on the txd clock and
a 1.2 ns delay on the rx clock.
The controller is the snps,dwmac-4.20a, and it implements a default
delay as well.

I'd like to eventually support as much as possible.
For instance it seems to support cable testing.
What I've done so far has been through trial and error, but I'd prefer
a more scientific approach.
I need to be able to test that functions work and would need someone
who's experienced with network phys to assist.

>
>        Andrew
Andrew Lunn May 12, 2021, 12:38 p.m. UTC | #3
Hi Peter

> A lot of items should be set up via the device tree, though it seems
> this is a relatively unused concept in the net phy subsystem.

Very little should be set up via device tree, since it does not
describe the hardware. The interface mode does describe the hardware,
so that is expected to be in DT, but not too much else.

> > Do you know which one of the four RGMII modes your setup needs? Is the
> > PHY adding the Rx and Tx delays? So "rgmii-id"?
> 
> By default it implements a 500ps delay internally on the txd clock and
> a 1.2 ns delay on the rx clock.
> The controller is the snps,dwmac-4.20a, and it implements a default
> delay as well.

O.K, that is confusing. We generally recommend that the MAC does not
add delays, the PHY does it. So maybe you can implement "rgmii-id" in
the PHY, and return -EOPNOTSUP for the other three RGMII modes, as a
minimum. However dwmac is one of the oddball drivers which does
sometime add the delays, and always sets the PHY to "rgmii" so it does
not add delays. Either way, is O.K, but please avoid having some of
the delay on one side, and the rest on the other.

	Andrew
diff mbox series

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index 601b5ae0368a..2a2e406238fc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12388,6 +12388,12 @@  F:	Documentation/userspace-api/media/drivers/meye*
 F:	drivers/media/pci/meye/
 F:	include/uapi/linux/meye.h
 
+MOTORCOMM PHY DRIVER
+M:	Peter Geis <pgwipeout@gmail.com>
+L:	netdev@vger.kernel.org
+S:	Maintained
+F:	drivers/net/phy/motorcomm.c
+
 MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD
 S:	Orphan
 F:	Documentation/driver-api/serial/moxa-smartio.rst
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 288bf405ebdb..16db9f8037b5 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -229,6 +229,12 @@  config MICROSEMI_PHY
 	help
 	  Currently supports VSC8514, VSC8530, VSC8531, VSC8540 and VSC8541 PHYs
 
+config MOTORCOMM_PHY
+	tristate "Motorcomm PHYs"
+	help
+	  Enables support for Motorcomm network PHYs.
+	  Currently supports the YT8511 gigabit PHY.
+
 config NATIONAL_PHY
 	tristate "National Semiconductor PHYs"
 	help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index bcda7ed2455d..37ffbc6e3c87 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -70,6 +70,7 @@  obj-$(CONFIG_MICREL_PHY)	+= micrel.o
 obj-$(CONFIG_MICROCHIP_PHY)	+= microchip.o
 obj-$(CONFIG_MICROCHIP_T1_PHY)	+= microchip_t1.o
 obj-$(CONFIG_MICROSEMI_PHY)	+= mscc/
+obj-$(CONFIG_MOTORCOMM_PHY)	+= motorcomm.o
 obj-$(CONFIG_NATIONAL_PHY)	+= national.o
 obj-$(CONFIG_NXP_C45_TJA11XX_PHY)	+= nxp-c45-tja11xx.o
 obj-$(CONFIG_NXP_TJA11XX_PHY)	+= nxp-tja11xx.o
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
new file mode 100644
index 000000000000..580926f25dfc
--- /dev/null
+++ b/drivers/net/phy/motorcomm.c
@@ -0,0 +1,87 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for Motorcomm PHYs
+ *
+ * Author: Peter Geis <pgwipeout@gmail.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+
+#define PHY_ID_YT8511		0x0000010a
+
+#define YT8511_PAGE_SELECT	0x1e
+#define YT8511_PAGE		0x1f
+#define YT8511_EXT_CLK_GATE	0x0c
+#define YT8511_EXT_SLEEP_CTRL	0x27
+
+/* 2b00 25m from pll
+ * 2b01 25m from xtl *default*
+ * 2b10 62.m from pll
+ * 2b11 125m from pll
+ */
+#define YT8511_CLK_125M		(BIT(2) | BIT(1))
+
+static int yt8511_read_page(struct phy_device *phydev)
+{
+	return __phy_read(phydev, YT8511_PAGE_SELECT);
+};
+
+static int yt8511_write_page(struct phy_device *phydev, int page)
+{
+	return __phy_write(phydev, YT8511_PAGE_SELECT, page);
+};
+
+static int yt8511_config_init(struct phy_device *phydev)
+{
+	int ret, oldpage;
+
+	/* set clock mode to 125mhz */
+	oldpage = phy_select_page(phydev, YT8511_EXT_CLK_GATE);
+	if (oldpage < 0)
+		goto err_restore_page;
+
+	ret = __phy_modify(phydev, YT8511_PAGE, 0, YT8511_CLK_125M);
+	if (ret < 0)
+		goto err_restore_page;
+
+	/* disable auto sleep */
+	ret = __phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_SLEEP_CTRL);
+	if (ret < 0)
+		goto err_restore_page;
+	ret = __phy_modify(phydev, YT8511_PAGE, BIT(15), 0);
+	if (ret < 0)
+		goto err_restore_page;
+
+err_restore_page:
+	return phy_restore_page(phydev, oldpage, ret);
+}
+
+static struct phy_driver motorcomm_phy_drvs[] = {
+	{
+		PHY_ID_MATCH_EXACT(PHY_ID_YT8511),
+		.name		= "YT8511 Gigabit Ethernet",
+		.config_init	= yt8511_config_init,
+		.get_features	= genphy_read_abilities,
+		.config_aneg	= genphy_config_aneg,
+		.read_status	= genphy_read_status,
+		.suspend	= genphy_suspend,
+		.resume		= genphy_resume,
+		.read_page	= yt8511_read_page,
+		.write_page	= yt8511_write_page,
+	},
+};
+
+module_phy_driver(motorcomm_phy_drvs);
+
+MODULE_DESCRIPTION("Motorcomm PHY driver");
+MODULE_AUTHOR("Peter Geis");
+MODULE_LICENSE("GPL");
+
+static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = {
+	{ PHY_ID_MATCH_EXACT(PHY_ID_YT8511) },
+	{ /* sentinal */ }
+};
+
+MODULE_DEVICE_TABLE(mdio, motorcomm_tbl);