Hi,
> - Asserting PHY's reset signal is the remedy, but no definition in DTB
>
> Orange Pi One Plus assigns GPIO-PD14 for resetting PHY chip,
> but there is no definition in Device Tree. If it is defined,
> if_dwxe does not handle the signal (if_dwge, if_fec can handle this).
> Currently there is no way to reset PHY via Device Tree manner.
>
> I hope simply replace powering on to off/delay(1sec?)/on sequence in
> dwxe_attach() will fix this problem but not tested yet.
> I will try it later but please tell me if there is better idea.
regulator_disable() -> wait 1sec -> regulator_enable() got worse.
Somehow we have to assert PHY's reset signal like this (ugly solution...).
Index: dev/fdt/if_dwxe.c
===================================================================
RCS file: /cvs/src/sys/dev/fdt/if_dwxe.c,v
retrieving revision 1.19
diff -u -p -u -p -r1.19 if_dwxe.c
--- dev/fdt/if_dwxe.c 24 Oct 2021 17:52:26 -0000 1.19
+++ dev/fdt/if_dwxe.c 4 Dec 2021 21:42:11 -0000
@@ -41,6 +41,7 @@
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_clock.h>
+#include <dev/ofw/ofw_gpio.h>
#include <dev/ofw/ofw_misc.h>
#include <dev/ofw/ofw_pinctrl.h>
#include <dev/ofw/ofw_regulator.h>
@@ -348,6 +349,7 @@ void dwxe_iff(struct dwxe_softc *);
int dwxe_encap(struct dwxe_softc *, struct mbuf *, int *);
void dwxe_reset(struct dwxe_softc *);
+void dwxe_reset_phy(void);
void dwxe_stop_dma(struct dwxe_softc *);
struct dwxe_dmamem *
@@ -367,6 +369,54 @@ dwxe_match(struct device *parent, void *
}
void
+dwxe_reset_phy(void)
+{
+ int node, t1, t2;
+ uint32_t phandle, port, pin, flags;
+ uint32_t gpio[4];
+
+ node = OF_finddevice("/");
+ if (!node)
+ return;
+
+ /*
+ * There is no binding definiton about the GPIO that is used for
+ * resetting external PHY. But some boards have GPIO connected to
+ * PHY's reset and need to assert at dwxe_attach().
+ * This is workaround.
+ */
+ if (OF_is_compatible(node, "xunlong,orangepi-one-plus")) {
+ /* PD14, active-low */
+ port = 3;
+ pin = 14;
+ flags = GPIO_ACTIVE_LOW;
+
+ /* PHY(RTL8211) requires 10ms pulse and 30ms release wait */
+ t1 = 10000;
+ t2 = 30000;
+ } else
+ return;
+
+ node = OF_finddevice("/soc/pinctrl");
+ if (!node)
+ return;
+
+ phandle = OF_getpropint(node, "phandle", 0);
+ if (!phandle)
+ return;
+
+ gpio[0] = phandle;
+ gpio[1] = port;
+ gpio[2] = pin;
+ gpio[3] = flags;
+ gpio_controller_config_pin(gpio, GPIO_CONFIG_OUTPUT);
+ gpio_controller_set_pin(gpio, 1);
+ delay(t1);
+ gpio_controller_set_pin(gpio, 0);
+ delay(t2);
+}
+
+void
dwxe_attach(struct device *parent, struct device *self, void *aux)
{
struct dwxe_softc *sc = (void *)self;
@@ -403,6 +453,9 @@ dwxe_attach(struct device *parent, struc
phy_supply = OF_getpropint(faa->fa_node, "phy-supply", 0);
if (phy_supply)
regulator_enable(phy_supply);
+
+ /* Reset PHY. */
+ dwxe_reset_phy();
sc->sc_clk = clock_get_frequency(faa->fa_node, "stmmaceth");
if (sc->sc_clk > 160000000)
It looks that many Allwinner-based board assigns PD6 or PD14 to reset signal.
This code can be applied for other problematic boards until device bindings
will be improved.
And, kernel configuration for RAMDISK needs to be modified.
Index: arch/arm64/conf/RAMDISK
===================================================================
RCS file: /cvs/src/sys/arch/arm64/conf/RAMDISK,v
retrieving revision 1.161
diff -u -p -u -p -r1.161 RAMDISK
--- arch/arm64/conf/RAMDISK 22 Nov 2021 20:25:50 -0000 1.161
+++ arch/arm64/conf/RAMDISK 4 Dec 2021 21:42:08 -0000
@@ -230,7 +230,7 @@ sximmc* at fdt? # SD/MMC card controll
sdmmc* at sximmc? # SD/MMC bus
sxisid* at fdt? early 1
sxisyscon* at fdt? early 1 # System controller
-sxitwi* at fdt? # I2C controller
+sxitwi* at fdt? early 1 # I2C controller
iic* at sxitwi? # I2C bus
dwxe* at fdt?
@@ -328,6 +328,7 @@ uk* at scsibus?
# I2C devices
abcrtc* at iic? # Abracon x80x RTC
+axppmic* at iic? # AXP80x PMIC
dsxrtc* at iic? # DS3231 RTC
fusbtc* at iic? # USB Type-C controller
islrtc* at iic? # ISL1208 RTC
Best regards,
--
SASANO Takayoshi (JG1UAA) <[email protected]>