Add Davicom phy + reset-gpios
v2 cover Add Davicom phy + reset-gpios
Changes in v2:
- Added patch to enable Davicom PHY on at91sam9263ek - evaluation kit
- Fix so we do reset before comunicating with the PHY
- Rename to mdio_reset()
- Reference correct binding file in commit log (mdio.txt)
- Tested on at91sam9263ek
The at91sam9263ek kit do not require the reset like my proprietary board, so no DT changes required
Intro (from v1):
The following two patches was necessary to get networking operational on my proprietary target.
The target is at91sam9263 based with a Davicom PHY.
The Davicom PHY is a straight copy form the Linux kernel with the interrupt routine removed and minor adjustments to the rest.
The davicom PHY would not work until it had seen a reset cycle - which I think may be an artifact of the board design.
To fix the reset issue I have implemented support for the reset-gpios binding (see net/mdio.txt bindings). A minimal implmentation was done, just enough to get my target running.
I could have implemented something in macb -
but I preferred the more generic solution.
Sam
Sam Ravnborg (3):
phylib: add Davicom PHY support
phylib: add support for reset-gpios
at91sam9263ek: add PHY, miitool etc. to config
arch/arm/configs/at91sam9263ek_defconfig | 12 ++ drivers/net/phy/Kconfig | 5 + drivers/net/phy/Makefile | 1 drivers/net/phy/davicom.c | 140 +++++++++++++++++++++++++++++++ drivers/net/phy/mdio_bus.c | 64 +++++++++++++- include/linux/phy.h | 5 + 6 files changed, 224 insertions(+), 3 deletions(-)
_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
PATCH v2 1/3 phylib: add Davicom PHY support
Based on driver from Linux kernel 4.18.0-rc4
--- drivers/net/phy/Kconfig | 5 ++ drivers/net/phy/Makefile | 1 + drivers/net/phy/davicom.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 drivers/net/phy/davicom.c
drivers/net/phy/Kconfig +5 -0
@@ -18,6 +18,11 @@ config AT803X_PHY ---help--- Currently supports the AT8030, AT8031 and AT8035 PHYs. +config DAVICOM_PHY + bool "Driver for Davicom PHYs" + ---help--- + Currently supports dm9161e and dm9131 + config LXT_PHY bool "Driver for the Intel LXT PHYs" ---help---
drivers/net/phy/Makefile +1 -0
@@ -1,6 +1,7 @@ obj-y += phy.o mdio_bus.o obj-$(CONFIG_AR8327N_PHY) += ar8327.o obj-$(CONFIG_AT803X_PHY) += at803x.o +obj-$(CONFIG_DAVICOM_PHY) += davicom.o obj-$(CONFIG_LXT_PHY) += lxt.o obj-$(CONFIG_MARVELL_PHY) += marvell.o obj-$(CONFIG_MICREL_PHY) += micrel.o
drivers/net/phy/davicom.c new file +140 -0
140 lines not on this page · raw message
Signature · 7 lines
2.12.0 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
PATCH v2 2/3 phylib: add support for reset-gpios
In reply to Sam RavnborgAdd minimal support for reset-gpios.
Example DT that uses this:
mdio {
#address-cells = <1>;
#size-cells = <0>;
reset-gpios = <&pioE 17 GPIO_ACTIVE_LOW>;
reset-delay-us = <1000>;
ethphy0: ethernet-phy@1 {
reg = <3>;
};
};This was required to get the Davicom PHY operational on my proprietary board.
I added the minimal mdio_reset() calls.
Another options was to use a bus reset, but then the net/ driver used should have dedicated reset support.
The reset-gpios solution is general and matches the binding specification in net/mdio.txt
--- drivers/net/phy/mdio_bus.c | 64 ++++++++++++++++++++++++++++++++++++++++++++-- include/linux/phy.h | 5 ++++ 2 files changed, 67 insertions(+), 2 deletions(-)
drivers/net/phy/mdio_bus.c +62 -2
@@ -17,6 +17,8 @@#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt#include <common.h> +#include <of_gpio.h> +#include <gpio.h> #include <driver.h> #include <init.h> #include <clock.h>
@@ -25,6 +27,8 @@#include <linux/phy.h> #include <linux/err.h> +#define DEFAULT_GPIO_RESET_DELAY 10/* us */ +LIST_HEAD (mii_bus_list);int mdiobus_detect (struct device_d *dev)
@@ -83,6 +87,45 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi }/** +* of_mdioibus_register_reset - register optional reset-gpios +* @mdio: pointer to mii_bus structure +* @np: pointer to device_node of MDIO bus. +* +* Read optional reset-gpios from mido node in DT +*/ +static void of_mdiobus_register_reset (struct mii_bus *mdio, +struct device_node *np) +{ +enum of_gpio_flags of_flags; +u32 reset_delay; +int gpio; + +if (!np) +return ; + + reset_delay =DEFAULT_GPIO_RESET_DELAY ; +of_property_read_u32 (np,"reset-delay-us" , &reset_delay); + + gpio =of_get_named_gpio_flags (np,"reset-gpios" ,0 , &of_flags); +if (gpio_is_valid (gpio)) { +unsigned long flags; +char *name; + + name =basprintf ("%s-reset" ,dev_name (&mdio->dev)); + flags =GPIOF_OUT_INIT_INACTIVE ; + +if (of_flags &OF_GPIO_ACTIVE_LOW ) + flags |=GPIOF_ACTIVE_LOW ; + +if (gpio_request_one (gpio, flags, name) >=0 ) { + mdio->reset_gpio = gpio; + mdio->reset_delay = reset_delay; + } + } + +} + +/** * of_mdiobus_register - Register mii_bus and create PHYs from the device tree * @mdio: pointer to mii_bus structure * @np: pointer to device_node of MDIO bus.
@@ -96,6 +139,9 @@ static int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)u32 addr;int ret; +if (!np) +return -ENODEV ; +/* Loop over the child nodes and register a phy_device for each one */ for_each_available_child_of_node (np, child) { ret =of_property_read_u32 (child,"reg" , &addr);
@@ -128,6 +174,7 @@ static int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)*/ int mdiobus_register (struct mii_bus *bus) { +struct device_node *np;int err; if (NULL == bus ||
@@ -147,6 +194,11 @@ int mdiobus_register(struct mii_bus *bus)return -EINVAL ; } + np = bus->dev.device_node; + +of_mdiobus_register_reset (bus, np); + +mdio_reset (bus);if (bus->reset) bus->reset (bus);
@@ -154,8 +206,7 @@ int mdiobus_register(struct mii_bus *bus)pr_info ("%s: probed\n" ,dev_name (&bus->dev)); -if (bus->dev.device_node) -of_mdiobus_register (bus, bus->dev.device_node); +of_mdiobus_register (bus, np);return 0 ; }
@@ -190,6 +241,15 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) }EXPORT_SYMBOL (mdiobus_scan); +void mdio_reset (const struct mii_bus *bus) +{ +if (gpio_is_valid (bus->reset_gpio)) { +gpio_set_active (bus->reset_gpio,1 ); +udelay (bus->reset_delay); +gpio_set_active (bus->reset_gpio,0 ); + } +} +EXPORT_SYMBOL (mdio_reset);/** *
include/linux/phy.h +5 -0
@@ -99,6 +99,10 @@ struct mii_bus {/* PHY addresses to be ignored when probing */ u32 phy_mask; +/* Optional reset of all PHY's on the bus */ +int reset_gpio; +int reset_delay; +struct list_head list;bool is_multiplexed;
@@ -108,6 +112,7 @@ struct mii_bus {int mdiobus_register (struct mii_bus *bus);void mdiobus_unregister (struct mii_bus *bus);struct phy_device *mdiobus_scan (struct mii_bus *bus,int addr); +void mdio_reset (const struct mii_bus *bus);extern struct list_head mii_bus_list;
Signature · 7 lines
2.12.0 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
Re: [PATCH v2 2/3] phylib: add support for reset-gpios
Hi Sam,
Some comments inside.
Quoted 53 lines · Sam Ravnborg
Add minimal support for reset-gpios.
Example DT that uses this:
mdio { #address-cells = <1>; #size-cells = <0>; reset-gpios = <&pioE 17 GPIO_ACTIVE_LOW>; reset-delay-us = <1000>; ethphy0: ethernet-phy@1 { reg = <3>; }; };This was required to get the Davicom PHY operational on my proprietary board.
I added the minimalmdio_reset()calls.Another options was to use a bus reset, but then the
net/driver used should have dedicated reset support.The reset-gpios solution is general and matches the binding specification in
net/mdio.txtSigned-off-by Sam Ravnborg <[email protected]>--- drivers/net/phy/mdio_bus.c | 64 ++++++++++++++++++++++++++++++++++++++++++++-- include/linux/phy.h | 5 ++++ 2 files changed, 67 insertions(+), 2 deletions(-)drivers/net/phy/mdio_bus.c +4
-0@@ -17,6 +17,8 @@#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt#include <common.h> +#include <of_gpio.h> +#include <gpio.h> #include <driver.h> #include <init.h> #include <clock.h> @@ -25,6 +27,8 @@#include <linux/phy.h> #include <linux/err.h> +#define DEFAULT_GPIO_RESET_DELAY 10/* us */ +LIST_HEAD (mii_bus_list);int mdiobus_detect (struct device_d *dev)
drivers/net/phy/mdio_bus.c static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi · line 90
Quoted 4 lines
drivers/net/phy/mdio_bus.c +1
-0@@ -83,6 +87,45 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi }/** +* of_mdioibus_register_reset - register optional reset-gpios
s/mdioibus/mdiobus/
drivers/net/phy/mdio_bus.c static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi · line 94
Quoted 4 lines
drivers/net/phy/mdio_bus.c +4
-0+* @mdio: pointer to mii_bus structure +* @np: pointer to device_node of MDIO bus. +* +* Read optional reset-gpios from mido node in DT
s/mido/mdio/
Quoted 10 lines
drivers/net/phy/mdio_bus.c +10
-0+*/ +static void of_mdiobus_register_reset (struct mii_bus *mdio, +struct device_node *np) +{ +enum of_gpio_flags of_flags; +u32 reset_delay; +int gpio; + +if (!np) +return ;
drivers/net/phy/mdio_bus.c static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi · line 114
Quoted 10 lines
drivers/net/phy/mdio_bus.c +10
-0+ + reset_delay =DEFAULT_GPIO_RESET_DELAY ; +of_property_read_u32 (np,"reset-delay-us" , &reset_delay); + + gpio =of_get_named_gpio_flags (np,"reset-gpios" ,0 , &of_flags); +if (gpio_is_valid (gpio)) { +unsigned long flags; +char *name; + + name =basprintf ("%s-reset" ,dev_name (&mdio->dev));
Free after use?
drivers/net/phy/mdio_bus.c static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi · line 123
Quoted 9 lines
drivers/net/phy/mdio_bus.c +9
-0+ flags =GPIOF_OUT_INIT_INACTIVE ; + +if (of_flags &OF_GPIO_ACTIVE_LOW ) + flags |=GPIOF_ACTIVE_LOW ; + +if (gpio_request_one (gpio, flags, name) >=0 ) { + mdio->reset_gpio = gpio; + mdio->reset_delay = reset_delay; + }
This shouldn't fail silently. If we find a GPIO we should be able to request it, otherwise it's a bug.
Quoted 49 lines
drivers/net/phy/mdio_bus.c +15
-2+ } + +} + +/** * of_mdiobus_register - Register mii_bus and create PHYs from the device tree * @mdio: pointer to mii_bus structure * @np: pointer to device_node of MDIO bus. @@ -96,6 +139,9 @@ static int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)u32 addr;int ret; +if (!np) +return -ENODEV ; +/* Loop over the child nodes and register a phy_device for each one */ for_each_available_child_of_node (np, child) { ret =of_property_read_u32 (child,"reg" , &addr);@@ -128,6 +174,7 @@ static int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)*/ int mdiobus_register (struct mii_bus *bus) { +struct device_node *np;int err; if (NULL == bus ||@@ -147,6 +194,11 @@ int mdiobus_register(struct mii_bus *bus)return -EINVAL ; } + np = bus->dev.device_node; + +of_mdiobus_register_reset (bus, np); + +mdio_reset (bus);if (bus->reset) bus->reset (bus);@@ -154,8 +206,7 @@ int mdiobus_register(struct mii_bus *bus)pr_info ("%s: probed\n" ,dev_name (&bus->dev)); -if (bus->dev.device_node) -of_mdiobus_register (bus, bus->dev.device_node); +of_mdiobus_register (bus, np);return 0 ; }
drivers/net/phy/mdio_bus.c struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) · line 246
Quoted 6 lines
drivers/net/phy/mdio_bus.c +3
-0@@ -190,6 +241,15 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) }EXPORT_SYMBOL (mdiobus_scan); +void mdio_reset (const struct mii_bus *bus) +{ +if (gpio_is_valid (bus->reset_gpio)) {
'0' is a valid GPIO, you have to initialize bus->reset_gpio explicitly to a negative value for the general case when no reset GPIO is available.
Sascha
Signature · 9 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
Re: [PATCH v2 2/3] phylib: add support for reset-gpios
Quoted 3 lines · Sascha Hauer
Hi Sam,
Some comments inside.
snip - many review good comments.
Thanks!
Will address all comments and submit a v3.
Sam
_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
PATCH v2 3/3 at91sam9263ek: add PHY, miitool etc. to config
In reply to Sam RavnborgAdded Davicom phy to the config now it is supported. Add miitool to show the phy info.
Also add a bunch of extra commands that can be useful when handling the evaluation board.
--- arch/arm/configs/at91sam9263ek_defconfig | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
arch/arm/configs/at91sam9263ek_defconfig +11 -1
@@ -18,7 +18,7 @@ CONFIG_BOOTM_OFTREE=y CONFIG_BOOTM_OFTREE_UIMAGE=y CONFIG_CONSOLE_ACTIVATE_ALL=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y -# CONFIG_CMD_ARM_CPUINFO is not set +CONFIG_CMD_DMESG=y CONFIG_LONGHELP=y CONFIG_CMD_IOMEM=y CONFIG_CMD_MEMINFO=y
@@ -33,22 +33,32 @@ CONFIG_CMD_PRINTENV=y CONFIG_CMD_SAVEENV=y CONFIG_CMD_SLEEP=y CONFIG_CMD_DHCP=y +CONFIG_CMD_HOST=y +CONFIG_NET_CMD_IFUP=y +CONFIG_CMD_MIITOOL=y CONFIG_CMD_PING=y CONFIG_CMD_TFTP=y CONFIG_CMD_EDIT=y CONFIG_CMD_SPLASH=y +CONFIG_CMD_FBTEST=y CONFIG_CMD_READLINE=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_CLK=y +CONFIG_CMD_DETECT=y CONFIG_CMD_FLASH=y CONFIG_CMD_GPIO=y CONFIG_CMD_LED=y CONFIG_CMD_LED_TRIGGER=y +CONFIG_CMD_OF_NODE=y +CONFIG_CMD_OF_PROPERTY=y +CONFIG_CMD_OF_DISPLAY_TIMINGS=y +CONFIG_CMD_OF_FIXUP_STATUS=y CONFIG_CMD_OFTREE=y CONFIG_NET=y CONFIG_NET_NFS=y CONFIG_OF_BAREBOX_DRIVERS=y CONFIG_DRIVER_NET_MACB=y +CONFIG_DAVICOM_PHY=y # CONFIG_SPI is not set CONFIG_MTD=y # CONFIG_MTD_OOB_DEVICE is not set
Signature · 7 lines
2.12.0 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox