From: Sam Ravnborg <sam@ravnborg.org>
To: Barebox List <barebox@lists.infradead.org>
Cc: Sam Ravnborg <sam@ravnborg.org>
Subject: [PATCH v4 2/3] phylib: add support for reset-gpios
Date: Wed, 22 Aug 2018 20:36:50 +0200 [thread overview]
Message-ID: <20180822183651.32071-2-sam@ravnborg.org> (raw)
In-Reply-To: <20180822183555.GA24084@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 relevant 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
that is not included in the barebox version.
They can be added later if needed.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
---
drivers/net/phy/mdio_bus.c | 96 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 95 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index d209716a1..636bdd1db 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,82 @@ 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-idX.X"
+ * 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)
+{
+ struct property *prop;
+ const char *cp;
+
+ of_property_for_each_string(np, "compatible", prop, cp) {
+ if (!strncmp(cp, "ethernet-phy-id", strlen("ethernet-phy-id")))
+ return true;
+ }
+
+ 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_mdiobus_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;
+
+ 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 +192,10 @@ static int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
continue;
}
+ if (!of_mdiobus_child_is_phy(child))
+ continue;
+
+ of_mdiobus_reset_phy(mdio, child);
of_mdiobus_register_phy(mdio, child, addr);
}
@@ -154,8 +239,17 @@ int mdiobus_register(struct mii_bus *bus)
pr_info("%s: probed\n", dev_name(&bus->dev));
- if (bus->dev.device_node)
+ if (bus->dev.device_node) {
+ /* Register PHY's as child node to mdio node */
of_mdiobus_register(bus, bus->dev.device_node);
+ }
+ else if (bus->parent->device_node) {
+ /*
+ * Register PHY's as child node to the ethernet node,
+ * if there was no mdio node
+ */
+ of_mdiobus_register(bus, bus->parent->device_node);
+ }
return 0;
}
--
2.12.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2018-08-22 18:37 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-22 18:35 [PATCH v4 0/3] Add Davicom phy + reset-gpios Sam Ravnborg
2018-08-22 18:36 ` [PATCH v4 1/3] phylib: add Davicom PHY support Sam Ravnborg
2018-08-22 18:36 ` Sam Ravnborg [this message]
2018-08-22 18:36 ` [PATCH v4 3/3] at91sam9263ek: add PHY, miitool etc. to config Sam Ravnborg
2018-08-24 8:03 ` [PATCH v4 0/3] Add Davicom phy + reset-gpios Sascha Hauer
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=20180822183651.32071-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