2022-07-19 05:45 PM
I cannot make the Ethernet work on my custom board (STM32MP153CA + automotive Ethernet PHY NXP TJA1101) in U-BOOT (haven't even tried loading kernel). The PHY is connected to an external 25MHz xtal. I'm working with 5-10-dunfell-mp1-21-11-17 files included on the 3.1.0 ecosystem. I tried the ecosystem 4.0.1 but got panic errors with RNG, UARTS, etc. After a few days I gave up and went back to 3.1.0
After U-Boot finishes loading, I configure the ethaddr, ipaddr, gatewayip, netmask and serverip, but whatever command I send I got straightaway:
STM32MP> ping 192.168.1.6
--- net_loop Entry
--- net_loop UDP handler set (00000000)
--- net_loop ARP handler set (00000000)
--- net_loop timeout handler cancelled
Trying ethernet@5800a000
eqos_start(dev=ddf05618):
eqos_start_clks_stm32(dev=ddf05618):
clk_enable(clk=ddf07290)
stm32mp1_clk_enable: id clock 105 has been enabled
clk_enable(clk=ddf072b0)
stm32mp1_clk_enable: id clock 104 has been enabled
clk_enable(clk=ddf072f0)
stm32mp1_clk_enable: id clock 103 has been enabled
clk_enable(clk=ddf07310)
stm32mp1_clk_enable: id clock 123 has been enabled
eqos_start_clks_stm32: OK
wait_for_bit_le32: Timeout (reg=5800b000 mask=1 wait_set=0)
EQOS_DMA_MODE_SWR stuckeqos_stop_clks_stm32(dev=ddf05618):
eqos_stop_clks_stm32: OK
FAILED: -110FAIL
ping failed; host 192.168.1.6 is not alive
Command failed, result=1.
I checked with the scope an there's no activity on the MDIO lines nor the TX/RX lines. (TX_CLK and RX_CLK look good though).
My U-Boot device tree looks like this:
ðernet0{
pinctrl-names = "default", "sleep";
pinctrl-0 = <ð1_pins_mx>;
pinctrl-1 = <ð1_sleep_pins_mx>;
status = "okay";
phy-mode = "mii";
max-speed = <100>;
phy-handle = <&phy0>;
nvmem-cells = <ðernet_mac_address>;
nvmem-cell-names = "mac-address";
//phy-reset-gpios = <&gpiof 11 GPIO_ACTIVE_LOW>; //PF11
mdio0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,dwmac-mdio";
reset-gpios = <&gpiof 11 GPIO_ACTIVE_LOW>;
reset-delay-us = <1000>;
phy0: ethernet-phy@0 {
compatible = "ethernet-phy-id0060.dd02", "ethernet-phy-ieee802.3-c22";
//reset-gpios = <&gpiof 11 GPIO_ACTIVE_LOW>;
reg = <0>;
};
};
};
(It doesn't matter which reset line I activate, the reset doesn't work. I got :
gpio_request_tail: Node 'ethernet-phy@0', property 'reset-gpios', failed to request GPIO index 0: -2
I tried changing the PHY mode to RMII as it's set by default
phy-mode = "rmii";
Then I see activity on the MDIO pins and TX pins. Of course I got errors because my PHY is configured in MII mode.
I checked my U-BOOT config and the default option CONFIG_PHY_REALTEK=y was set. I tried with other PHY such as :
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ8XXX=y
But it didn't work.
Has anyone had a Ethernet PHY working in MII mode?
Do I need a PHY driver for the NXP TJA1101 or I can work with a generic instead?
Any clue why the reset port cannot be configured (regardless of the PHY-MODE)? I got Node 'ethernet-phy@0', property 'reset-gpios', failed to request GPIO index 0: -2
during U-Boot initialization.
Thanks.
2022-07-25 07:30 AM
Hi LCast.2 (Community Member),
Are you sure about the ID used for your phy? In the datasheet PHY NXP TJA1101 :
I would go for compatible = "ethernet-phy-id0180.dd02" instead ( [3:0] depending of the phy revision)
Linux side with the DV3.1, the phy driver is available:
net/phy/nxp-tja11xx.c
#define PHY_ID_TJA1100 0x0180dc40
#define PHY_ID_TJA1101 0x0180dd00
#define PHY_ID_TJA1102 0x0180dc80
2- I've enclosed a patch has been merged in DV4.0.1 to rationalize the settings and also fix the MII setup, this was due to an incorrect register muxing setup which did not follow the product Reference Manual:
Hope that will fix your issue.
Regards,
Olivier
2022-07-27 05:56 PM
Thanks for your input Olivier. I implemented the changes but still had eth_send errors. I noticed that after the negotiation with the PHY, the speed was set in 10Mbps and halt-duplex. The TJA1101 is full duplex. Besides, the ETH_COL and ETH_CRS signals on the processor weren't connected (ETH_CRS was uses as WAKE port). So I try to force it in full-duplex by adding:
fixed-link {
speed = <100>;
full-duplex;
};
on the u-boot device tree file. But, it didn't make any difference.
So I ended up modifying the function eqos_adjust_link on drivers/net/dwc_ethqos.c to force full-duplex and 100Mbps.
It works fine after that.
So the outstanding issue now is the PHY reset line. it's connected to the F Port (PF11). On the STM32MP15xxAB, ports F and G don't come with 16 outputs. Port F goes from PF6 to PF11 and port G goes from PG6 to PG15. When configuring port functions on u-boot tree file, &pinctrl node looks like:
pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH1_TXD0 */
<STM32_PINMUX('G', 14, AF11)>; /* ETH1_TXD1 */
it makes sense, PG13 and PG14 as per HW spec.
Now if I'm using ports in u-boot for example to reset PHY and LEDs, the ports are defined in a different way, Port F goes from GPIOF0 to GPIOF5, and G goes from GPIOG0 to GPIOG9. The u-boot device tree then looks like this:
led {
compatible = "gpio-leds";
led1 {
label = "green";
gpios = <&gpioe 9 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
led2 {
label = "red";
gpios = <&gpiog 4 GPIO_ACTIVE_HIGH>; //instead of PG10
default-state = "off";
};
led3 {
label = "blue";
gpios = <&gpiog 5 GPIO_ACTIVE_HIGH>; //instead of PG11
default-state = "off";
};
};
So when I run u-boot command gpio status I see
Bank GPIOF:
GPIOF0: unused: 0 [ ]
GPIOF1: unused: 0 [ ]
GPIOF2: unused: 0 [ ]
GPIOF3: unused: 0 [ ]
GPIOF4: unused: 0 [ ]
GPIOF5: output: 0 [x] ethernet-phy@0.reset-gpios
Bank GPIOG:
GPIOG0: unused: 0 [ ]
GPIOG1: unused: 0 [ ]
GPIOG2: unused: 0 [ ]
GPIOG3: unused: 0 [ ]
GPIOG4: output: 0 [x] led2.gpios
GPIOG5: output: 0 [x] led3.gpios
GPIOG6: unused: 0 [ ]
GPIOG7: unused: 0 [ ]
GPIOG8: unused: 0 [ ]
GPIOG9: unused: 0 [ ]
Then when I try to toggle the pins, it doesn't work. I got the message:
STM32MP> gpio toggle GPIOG5
gpio: pin GPIOG5 (gpio 91) value is 1
Warning: value of pin is still 0
Command failed, result=1
The same command works just fine if I run it in a port with 16 pins such as the LED connected to GPIOE9.
So I wonder if there's an issue with the way the ports are numbered in the GPIO functions for STM32MP15xxAB devices.
2022-07-27 10:16 PM
Hi @LCast.2,
As shared with you by e-mail and as per your confirmation it solved your issue:
===========================================================
You are right, there are some GPIO index issue for STM32MP15XXAB serials in u-boot.
As we can see from STM32mp15xxAB data sheet, there are only 10 pins available in PG group and the range is PG6 ~ PG15.
In stm32mp15xxab-pinctrl.dts the gpio-ranges property show pins 102..111 on pin controller is mapped to GPIO line 6..15.
But from u-boot "gpio status -a" command, the GPIOG group is started from PG0 which confuse customer.
46 gpiog: gpio@50008000 {
47 status = "okay";
48 ngpios = <10>;
49 gpio-ranges = <&pinctrl 6 102 10>;
50 };
Attached is the patch to solve the issue.
Example for a 16 pins GPIO bank with the [2-7] mapping (only 6 pins mapped):
GPIOI0 : unknown
GPIOI1 : unknown
GPIOI2 : analog
GPIOI3 : analog
GPIOI4 : alt function 0 push-pull pull-down
GPIOI5 : alt function 0 push-pull pull-down
GPIOI6 : alt function 0 push-pull pull-down
GPIOI7 : analog
GPIOI8 : unknown
GPIOI9 : unknown
GPIOI10 : unknown
GPIOI11 : unknown
GPIOI12 : unknown
GPIOI13 : unknown
GPIOI14 : unknown
GPIOI15 : unknown
Regards,
Christophe
2022-07-28 02:05 AM
Hi LCast.2 (Community Member)
Thank you for your comprehensive feedback and good to hear that you are sorted out.
The GPIO F/G numbering issue in U-boot has been fixed in latest public DV 4.0.1. It would be interesting to know why this delivery doesn't work for you.
Also could you please share what are your changes in eqos_adjust_link on drivers/net/dwc_ethqos.c to force full-duplex and 100Mbps.
Regards,
Olivier
2022-07-31 06:25 PM
The changes I made in function eqos_adjust_link on drivers/net/dwc_eth_qos.c to force full-duplex and 100Mbps are the 2 lines with the comment "//added" at the end:
static int eqos_adjust_link(struct udevice *dev)
{
struct eqos_priv *eqos = dev_get_priv(dev);
int ret;
bool en_calibration;
debug("%s(dev=%p):\n", __func__, dev);
+ eqos->phy->duplex=DUPLEX_FULL; //added
if (eqos->phy->duplex)
ret = eqos_set_full_duplex(dev);
else
ret = eqos_set_half_duplex(dev);
if (ret < 0) {
pr_err("eqos_set_*_duplex() failed: %d", ret);
return ret;
}
+ eqos->phy->speed=SPEED_100; //added
switch (eqos->phy->speed) {
case SPEED_1000:
...
}
I'm ware it's not the most "elegant" solution, but it worked for me. That change enabled me to load the kernel into RAM via tftp.
Regards
Luciano