summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2024-03-24 22:34:07 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2024-03-24 22:34:07 +0000
commit888131a24dbba5a15aaf1ce5173fe11389d5593f (patch)
treec93164f58e8505d544ccccfc56616d37ebc2210a /sys
parent154b097e7f9d32c5e6434d6087ee4fadf7aaa84a (diff)
Implement resetting the PHY via a GPIO pin, like in fec(4). This helps
enable the PHY on the Raspberry Pi 5. ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/fdt/if_cad.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/sys/dev/fdt/if_cad.c b/sys/dev/fdt/if_cad.c
index 7e20c9f3e75..9baa28aa805 100644
--- a/sys/dev/fdt/if_cad.c
+++ b/sys/dev/fdt/if_cad.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_cad.c,v 1.13 2023/08/15 08:27:30 miod Exp $ */
+/* $OpenBSD: if_cad.c,v 1.14 2024/03/24 22:34:06 patrick Exp $ */
/*
* Copyright (c) 2021-2022 Visa Hankala
@@ -54,6 +54,7 @@
#include <dev/ofw/fdt.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_clock.h>
+#include <dev/ofw/ofw_gpio.h>
#define GEM_NETCTL 0x0000
#define GEM_NETCTL_DPRAM (1 << 18)
@@ -388,6 +389,8 @@ cad_attach(struct device *parent, struct device *self, void *aux)
struct fdt_attach_args *faa = aux;
struct cad_softc *sc = (struct cad_softc *)self;
struct ifnet *ifp = &sc->sc_ac.ac_if;
+ uint32_t phy_reset_gpio[3];
+ uint32_t phy_reset_duration;
uint32_t hi, lo;
uint32_t rev, ver;
uint32_t val;
@@ -427,6 +430,20 @@ cad_attach(struct device *parent, struct device *self, void *aux)
ether_fakeaddr(ifp);
}
+ if (OF_getpropintarray(faa->fa_node, "phy-reset-gpios", phy_reset_gpio,
+ sizeof(phy_reset_gpio)) == sizeof(phy_reset_gpio)) {
+ phy_reset_duration = OF_getpropint(faa->fa_node,
+ "phy-reset-duration", 1);
+ if (phy_reset_duration > 1000)
+ phy_reset_duration = 1;
+
+ gpio_controller_config_pin(phy_reset_gpio, GPIO_CONFIG_OUTPUT);
+ gpio_controller_set_pin(phy_reset_gpio, 1);
+ delay((phy_reset_duration + 1) * 1000);
+ gpio_controller_set_pin(phy_reset_gpio, 0);
+ delay(1000);
+ }
+
phy = OF_getpropint(faa->fa_node, "phy-handle", 0);
node = OF_getnodebyphandle(phy);
if (node != 0)