cancel
Showing results for 
Search instead for 
Did you mean: 

Ethernet on STM32MP157A with PHY AR8035 no PHY found

jhi
Senior

I have a problem to get the ethernet to work with the PHY AR8035 (Atheros). The board is from MYiR (MYC-YA157C-V2), but they are only providing yocto based image and I'm doing my work with buildroot. I'm using the bootlin buildroot branch: st/2021.02 https://github.com/bootlin/buildroot.git

The kernel can't find MDIO: mdio_bus stmmac-0: MDIO device at address 6 is missing.

The funny thing is, if I first boot the board from eMMC where the original image from MYiR is flashed, and afterwards, without switching power off, I start my image from the sdcard, the ethernet works. I guess this means that some register value is wrong, but I don't know where to start look. This also means that address 6 for the MDIO is also correct.

On TF-A I have CLK_ETH_DISABLED, because the 125MHz is coming from the PHY.

Below is the device tree for the kernel (CONFIG_AT803X_PHY=y is set):

&ethernet0 {
	interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
						<&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
						<&exti 70 1>;
	interrupt-names = "macirq",
				"eth_wake_irq",
				"stm32_pwr_wakeup";
 
	clock-names = "stmmaceth",
				"mac-clk-tx",
				"mac-clk-rx",
				"eth-ck",
				"ethstp";
 
	clocks = <&rcc ETHMAC>,
			<&rcc ETHTX>,
			<&rcc ETHRX>,
			<&rcc ETHCK_K>,
			<&rcc ETHSTP>;
					
	status = "okay";
	pinctrl-0 = <&eth1_pins_mx>;
	pinctrl-1 = <&eth1_sleep_pins_mx>;
	pinctrl-names = "default", "sleep";
	phy-mode = "rgmii";
	max-speed = <1000>;
	phy-handle = <&phy0>;
	nvmem-cells = <&ethernet_mac_address>;
	nvmem-cell-names = "mac-address";
 
	mdio0 {
		#address-cells = <1>;
		#size-cells = <0>;
		compatible = "snps,dwmac-mdio";
		phy0: ethernet-phy@6 {
			reg = <6>;
			qca,clk-out-frequency = <125000000>;
                        qca,clk-out-strength = <AR803X_STRENGTH_FULL>;
			reset-assert-us = <1000>;
			reset-deassert-us = <2000>; 
			reset-gpios = <&gpiog 0 GPIO_ACTIVE_LOW>;
		};
	};
};

I have added the "eth-ck", because I read somewhere that it would be needed on all cases (it doesn't also work without it). Do I need to enable something else on TF-A or in u-boot?

13 REPLIES 13
OlivierK
ST Employee

Hi jhi (Community Member),

Congrats on your findings regarding the atheros driver.

Let me correct then for the DT syntax since you point to the latest DV3.1 ST release (kernel 5.10.x) it is here: https://wiki.st.com/stm32mpu/wiki/Ethernet_device_tree_configuration

For U-boot side and the phy-handle, in DV3.1 the DTS on U-boot and kernel are the same. Driver side, normally the following patch has been merged but could you double check that in your version the patch that handles the gpio reset with assert and deassert delays is included.

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c

index ef78806..c394a61 100644

--- a/drivers/net/dwc_eth_qos.c

+++ b/drivers/net/dwc_eth_qos.c

@@ -737,29 +737,6 @@

 static int eqos_start_resets_stm32(struct udevice *dev)

 {

- struct eqos_priv *eqos = dev_get_priv(dev);

- int ret;

-

- debug("%s(dev=%p):\n", __func__, dev);

- if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {

- ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1);

- if (ret < 0) {

- pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d",

-    ret);

- return ret;

- }

-

- udelay(2);

-

- ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);

- if (ret < 0) {

- pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d",

-    ret);

- return ret;

- }

- }

- debug("%s: OK\n", __func__);

-

 return 0;

 }

@@ -780,18 +757,6 @@

 static int eqos_stop_resets_stm32(struct udevice *dev)

 {

- struct eqos_priv *eqos = dev_get_priv(dev);

- int ret;

-

- if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {

- ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1);

- if (ret < 0) {

- pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d",

-    ret);

- return ret;

- }

- }

-

 return 0;

 }

@@ -1814,7 +1779,6 @@

 struct eqos_priv *eqos = dev_get_priv(dev);

 int ret;

 phy_interface_t interface;

- struct ofnode_phandle_args phandle_args;

 debug("%s(dev=%p):\n", __func__, dev);

@@ -1854,20 +1818,6 @@

 if (ret)

 pr_warn("No phy clock provided %d", ret);

- ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,

- &phandle_args);

- if (!ret) {

- /* search "reset-gpios" in phy node */

- ret = gpio_request_by_name_nodev(phandle_args.node,

- "reset-gpios", 0,

- &eqos->phy_reset_gpio,

- GPIOD_IS_OUT |

- GPIOD_IS_OUT_ACTIVE);

- if (ret)

- pr_warn("gpio_request_by_name(phy reset) not provided %d",

- ret);

- }

-

 debug("%s: OK\n", __func__);

 return 0;

jhi
Senior

The u-boot is v2020.10-stm32mp-r2. It doesn't have any of the functions on your patch (your patch is actually removing all the stuff, but I guess it should add those?).

OlivierK
ST Employee

Patch is already present in DV3.1 but you need to apply it if not already done,

for p in `ls -1 ../*.patch`; do patch -p1 < $p; done

indeed the patch is removing the code because reset is handled by the phy driver instead of the ethernet driver.

In drivers/net/dwc_eth_qos.c:

you should have

static struct eqos_ops eqos_stm32_ops = {

...

    .eqos_stop_resets = eqos_null_ops,

    .eqos_start_resets = eqos_null_ops,

...

}

... and reset gpio is handled in /driver/net/eth-phy-uclass.c

jhi
Senior

Then I have this patch already.