2021-05-11 23:02:43

by Peter Geis

[permalink] [raw]
Subject: [PATCH v2] net: phy: add driver for Motorcomm yt8511 phy

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 <[email protected]>
---
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

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 <[email protected]>
+L: [email protected]
+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 <[email protected]>
+ */
+
+#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);
--
2.25.1


2021-05-12 00:50:15

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH v2] net: phy: add driver for Motorcomm yt8511 phy

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

2021-05-12 01:47:25

by Peter Geis

[permalink] [raw]
Subject: Re: [PATCH v2] net: phy: add driver for Motorcomm yt8511 phy

On Tue, May 11, 2021 at 8:48 PM Andrew Lunn <[email protected]> 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

2021-05-12 13:16:04

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH v2] net: phy: add driver for Motorcomm yt8511 phy

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