mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sam Ravnborg <sam@ravnborg.org>
To: Barebox List <barebox@lists.infradead.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Subject: [PATCH v3 2/3] phylib: add support for reset-gpios
Date: Mon, 20 Aug 2018 16:56:11 +0200	[thread overview]
Message-ID: <20180820145612.17576-2-sam@ravnborg.org> (raw)
In-Reply-To: <20180820145215.GA22058@ravnborg.org>

Add minimal support for reset-gpios in the PHY node.

Example DT that uses this:

	macb0: ethernet@fffbc000 {
		phy-mode = "rmii";
		#address-cells = <1>;
		#size-cells = <0>;

		ethphy0: ethernet-phy@1 {
			reg = <3>;
			reset-gpios = <&pioE 17 GPIO_ACTIVE_LOW>;
			reset-assert-us = <1000>;
			reset-deassert-us = <2000>;
		};
	};

The reset is required to get the Davicom PHY operational on
my proprietary board, and is assumed relavant for other boards too.

The PHY is reset when we read the info from DT,
before the phy_id is retreived.

The bindings are documented in dts/Bindings/net/phy.txt.

A side-effect of this patch is that we may see
phy devices created from the DT due to the extra call to:

    of_mdiobus_register()

with the ethernet node as argument.

The logic to determine if a child node is a PHY node
is a simpler version compared to the one used in the kernel.
The kernel have a whitelist of compatible strings
and will also reconize compatible = ethernet-phy-idAAAA.BBBB.
If these are required then they can be added later.

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
---
 drivers/net/phy/mdio_bus.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index d209716a1..c479c25bd 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -17,14 +17,19 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <common.h>
+#include <of_gpio.h>
 #include <driver.h>
 #include <init.h>
+#include <gpio.h>
 #include <clock.h>
 #include <net.h>
 #include <errno.h>
 #include <linux/phy.h>
 #include <linux/err.h>
 
+#define DEFAULT_GPIO_RESET_ASSERT       1000      /* us */
+#define DEFAULT_GPIO_RESET_DEASSERT     1000      /* us */
+
 LIST_HEAD(mii_bus_list);
 
 int mdiobus_detect(struct device_d *dev)
@@ -82,6 +87,76 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
 	return 0;
 }
 
+/*
+ * Node is considered a PHY node if:
+ * o Compatible string of "ethernet-phy-ieee802.3-c45"
+ * o Compatible string of "ethernet-phy-ieee802.3-c22"
+ * o No compatibility string
+ *
+ * A device which is not a phy is expected to have a compatible string
+ * indicating what sort of device it is.
+ */
+static bool of_mdiobus_child_is_phy(struct device_node *np)
+{
+	if (of_device_is_compatible(np, "ethernet-phy-ieee802.3-c45"))
+		return true;
+
+	if (of_device_is_compatible(np, "ethernet-phy-ieee802.3-c22"))
+		return true;
+
+	if (!of_find_property(np, "compatible", NULL))
+		return true;
+
+	return false;
+}
+
+/*
+ * Reset the PHY, based on DT info
+ *
+ * If np is a phy node, and the phy node contains a reset-gpios property
+ * then reset the phy.
+ */
+static void of_reset_phy(struct mii_bus *bus, struct device_node *np)
+{
+	enum of_gpio_flags of_flags;
+	u32 reset_deassert_delay;
+	u32 reset_assert_delay;
+	unsigned long flags;
+	int gpio;
+	int ret;
+
+	if (!of_mdiobus_child_is_phy(np))
+		return;
+
+	gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &of_flags);
+	if (!gpio_is_valid(gpio))
+		return;
+
+	flags = GPIOF_OUT_INIT_INACTIVE;
+	if (of_flags & OF_GPIO_ACTIVE_LOW)
+		flags |= GPIOF_ACTIVE_LOW;
+
+	ret = gpio_request_one(gpio, flags, np->name);
+	if (ret) {
+		dev_err(&bus->dev, "failed to request reset gpio for: %s\n",
+			np->name);
+		return;
+	}
+
+	reset_assert_delay = DEFAULT_GPIO_RESET_ASSERT;
+	of_property_read_u32(np, "reset-assert-us", &reset_assert_delay);
+
+	reset_deassert_delay = DEFAULT_GPIO_RESET_DEASSERT;
+	of_property_read_u32(np, "reset-deassert-us", &reset_deassert_delay);
+
+	/* reset the PHY */
+	dev_dbg(&bus->dev, "reset PHY with GPIO: %d\n", gpio);
+	gpio_set_active(gpio, 1);
+	udelay(reset_assert_delay);
+	gpio_set_active(gpio, 0);
+	udelay(reset_deassert_delay);
+}
+
 /**
  * of_mdiobus_register - Register mii_bus and create PHYs from the device tree
  * @mdio: pointer to mii_bus structure
@@ -111,6 +186,8 @@ static int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
 			continue;
 		}
 
+		of_reset_phy(mdio, child);
+
 		of_mdiobus_register_phy(mdio, child, addr);
 	}
 
@@ -154,6 +231,11 @@ int mdiobus_register(struct mii_bus *bus)
 
 	pr_info("%s: probed\n", dev_name(&bus->dev));
 
+	/* register PHY's as child node to the ethernet node */
+	if (bus->parent->device_node)
+		of_mdiobus_register(bus, bus->parent->device_node);
+
+	/* register PHY's as child node to mdio node */
 	if (bus->dev.device_node)
 		of_mdiobus_register(bus, bus->dev.device_node);
 
-- 
2.12.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2018-08-20 14:56 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-20 14:52 [PATCH v3 0/3] Add Davicom phy + reset-gpios Sam Ravnborg
2018-08-20 14:56 ` [PATCH v3 1/3] phylib: add Davicom PHY support Sam Ravnborg
2018-08-20 14:56 ` Sam Ravnborg [this message]
2018-08-21  7:50   ` [PATCH v3 2/3] phylib: add support for reset-gpios Sascha Hauer
2018-08-21 19:46     ` Sam Ravnborg
2018-08-22 13:14       ` Ahmad Fatoum
2018-08-22 18:26         ` Sam Ravnborg
2018-08-20 14:56 ` [PATCH v3 3/3] at91sam9263ek: add PHY, miitool etc. to config Sam Ravnborg

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=20180820145612.17576-2-sam@ravnborg.org \
    --to=sam@ravnborg.org \
    --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