From: Oleksij Rempel <o.rempel@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Oleksij Rempel <o.rempel@pengutronix.de>
Subject: [PATCH v1 2/2] net: phy: micrel: port clock select support
Date: Tue, 12 Oct 2021 12:08:59 +0200 [thread overview]
Message-ID: <20211012100859.1409-2-o.rempel@pengutronix.de> (raw)
In-Reply-To: <20211012100859.1409-1-o.rempel@pengutronix.de>
Port devicetree based clock select support from kernel micrel driver (v5.15-rc1).
This support is needed to make netboot work on boards with PHY node and
"rmii-ref" property.
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
drivers/net/phy/micrel.c | 101 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 100 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index ea193c84a7..958abdd9d6 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -14,6 +14,7 @@
#include <common.h>
#include <init.h>
+#include <linux/clk.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
@@ -38,6 +39,10 @@
/* PHY Control 1 */
#define MII_KSZPHY_CTRL_1 0x1e
+/* PHY Control 2 / PHY Control (if no PHY Control 1) */
+#define MII_KSZPHY_CTRL_2 0x1f
+#define KSZPHY_RMII_REF_CLK_SEL BIT(7)
+
/* Write/read to/from extended registers */
#define MII_KSZPHY_EXTREG 0x0b
#define KSZPHY_EXTREG_WRITE 0x8000
@@ -52,6 +57,20 @@
#define PS_TO_REG 200
+struct kszphy_type {
+ bool has_rmii_ref_clk_sel;
+};
+
+struct kszphy_priv {
+ const struct kszphy_type *type;
+ bool rmii_ref_clk_sel;
+ bool rmii_ref_clk_sel_val;
+};
+
+static const struct kszphy_type ksz8081_type = {
+ .has_rmii_ref_clk_sel = true,
+};
+
static int kszphy_extended_write(struct phy_device *phydev,
u32 regnum, u16 val)
{
@@ -66,6 +85,22 @@ static int kszphy_extended_read(struct phy_device *phydev,
return phy_read(phydev, MII_KSZPHY_EXTREG_READ);
}
+static int kszphy_rmii_clk_sel(struct phy_device *phydev, bool val)
+{
+ int ctrl;
+
+ ctrl = phy_read(phydev, MII_KSZPHY_CTRL);
+ if (ctrl < 0)
+ return ctrl;
+
+ if (val)
+ ctrl |= KSZPHY_RMII_REF_CLK_SEL;
+ else
+ ctrl &= ~KSZPHY_RMII_REF_CLK_SEL;
+
+ return phy_write(phydev, MII_KSZPHY_CTRL, ctrl);
+}
+
/* Handle LED mode, shift = position of first led mode bit, usually 4 or 14 */
static int kszphy_led_mode(struct phy_device *phydev, int reg, int shift)
{
@@ -83,6 +118,24 @@ static int kszphy_led_mode(struct phy_device *phydev, int reg, int shift)
return 0;
}
+/* Some config bits need to be set again on resume, handle them here. */
+static int kszphy_config_reset(struct phy_device *phydev)
+{
+ struct kszphy_priv *priv = phydev->priv;
+ int ret;
+
+ if (priv->rmii_ref_clk_sel) {
+ ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val);
+ if (ret) {
+ dev_err(&phydev->dev,
+ "failed to set rmii reference clock\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
static int kszphy_config_init(struct phy_device *phydev)
{
kszphy_led_mode(phydev, MII_KSZPHY_CTRL_1, 14);
@@ -96,7 +149,7 @@ static int ksz8021_config_init(struct phy_device *phydev)
kszphy_led_mode(phydev, MII_KSZPHY_CTRL, 4);
- return 0;
+ return kszphy_config_reset(phydev);
}
static int ks8051_config_init(struct phy_device *phydev)
@@ -468,6 +521,50 @@ static int ksz8873mll_config_init(struct phy_device *phydev)
return 0;
}
+static int kszphy_probe(struct phy_device *phydev)
+{
+ struct device_d *dev = &phydev->dev;
+ struct device_node *np = dev->device_node;
+ struct phy_driver *drv = to_phy_driver(dev->driver);
+ const struct kszphy_type *type = drv->driver_data;
+ struct kszphy_priv *priv;
+ struct clk *clk;
+
+ priv = xzalloc(sizeof(*priv));
+
+ phydev->priv = priv;
+
+ priv->type = type;
+
+ clk = clk_get(dev, "rmii-ref");
+ /* NOTE: clk may be NULL if building without CONFIG_HAVE_CLK */
+ if (!IS_ERR_OR_NULL(clk)) {
+ unsigned long rate = clk_get_rate(clk);
+ bool rmii_ref_clk_sel_25_mhz;
+
+ priv->rmii_ref_clk_sel = type->has_rmii_ref_clk_sel;
+ rmii_ref_clk_sel_25_mhz = of_property_read_bool(np,
+ "micrel,rmii-reference-clock-select-25-mhz");
+
+ if (rate > 24500000 && rate < 25500000) {
+ priv->rmii_ref_clk_sel_val = rmii_ref_clk_sel_25_mhz;
+ } else if (rate > 49500000 && rate < 50500000) {
+ priv->rmii_ref_clk_sel_val = !rmii_ref_clk_sel_25_mhz;
+ } else {
+ dev_err(dev, "Clock rate out of range: %ld\n", rate);
+ return -EINVAL;
+ }
+ }
+
+ /* Support legacy board-file configuration */
+ if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) {
+ priv->rmii_ref_clk_sel = true;
+ priv->rmii_ref_clk_sel_val = true;
+ }
+
+ return 0;
+}
+
static struct phy_driver ksphy_driver[] = {
{
.phy_id = PHY_ID_KS8737,
@@ -517,7 +614,9 @@ static struct phy_driver ksphy_driver[] = {
.phy_id = PHY_ID_KSZ8081,
.phy_id_mask = MICREL_PHY_ID_MASK,
.drv.name = "Micrel KSZ8081/91",
+ .driver_data = &ksz8081_type,
.features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+ .probe = kszphy_probe,
.config_init = ksz8021_config_init,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
--
2.30.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2021-10-12 10:11 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-12 10:08 [PATCH v1 1/2] include/phy: add driver_data to resume more of kernel code Oleksij Rempel
2021-10-12 10:08 ` Oleksij Rempel [this message]
2021-10-12 17:12 ` [PATCH v1 2/2] net: phy: micrel: port clock select support Trent Piepho
2021-10-13 7:28 ` Oleksij Rempel
2021-10-13 8:48 ` Trent Piepho
2021-10-13 10:23 ` Oleksij Rempel
2021-10-13 10:43 ` Trent Piepho
2021-10-13 11:02 ` Oleksij Rempel
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=20211012100859.1409-2-o.rempel@pengutronix.de \
--to=o.rempel@pengutronix.de \
--cc=barebox@lists.infradead.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