IPQ40xx phy init failed

Here comes another problem..
After ath10k problem is solved, I found that my IPQ40xx board can only boot from bootloader using either tftpboot-then-bootm, or bootipq. Direct boot always crashes when probing PHY
PHY is QCA8072

[    0.691706] libphy: ipq40xx_mdio: probed
[    0.699574] Unable to handle kernel NULL pointer dereference at virtual address 000000a4
[    0.699939] pgd = c0204000
[    0.708026] [000000a4] *pgd=00000000
[    0.710537] Internal error: Oops: 5 [#1] SMP ARM
[    0.714254] Modules linked in:
[    0.718856] CPU: 3 PID: 1 Comm: swapper/0 Not tainted 4.14.107 #0
[    0.721720] Hardware name: Generic DT based system
[    0.727884] task: cf830000 task.stack: cf82e000
[    0.732579] PC is at ar40xx_probe+0x318/0x738
[    0.737000] LR is at ar40xx_probe+0x2fc/0x738
[    0.741511] pc : [<c05b9ea0>]    lr : [<c05b9e84>]    psr: 60000013
[    0.745855] sp : cf82fdf8  ip : cfde5324  fp : 00000000
[    0.751928] r10: cf94f200  r9 : c0334f84  r8 : 00000000
[    0.757138] r7 : c0a58e34  r6 : cf94f210  r5 : cfdf65f4  r4 : cfb80010
[    0.762348] r3 : cfb801e4  r2 : 00000000  r1 : 00000000  r0 : cfb80010
[    0.768947] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[    0.775456] Control: 10c5387d  Table: 8020406a  DAC: 00000051
[    0.782659] Process swapper/0 (pid: 1, stack limit = 0xcf82e210)
[    0.788390] Stack: (0xcf82fdf8 to 0xcf830000)
[    0.794466] fde0:                                                       00000000 00001784
[    0.798729] fe00: cf997a20 cfb801e4 cf997a20 00000004 00098000 000987ff cfdf69a0 00000200
[    0.806888] fe20: 00000000 00000000 00000000 00000000 0c000000 0c07ffff cfdf664c 00000200
[    0.815048] fe40: 00000000 00000000 00000000 00000000 c0a19a28 cf94f210 c0a19a28 c0a581ac
[    0.823208] fe60: 00000000 00000000 c0a19a28 00000000 00000000 c055b76c c0a581a8 cf94f210
[    0.831368] fe80: c0a581ac c055a1ac cf94f210 c0a19a28 cf94f244 00000000 00000007 00000059
[    0.839527] fea0: c0936f44 c055a398 00000000 c0a19a28 c055a30c c0558938 cf817558 cf8e8f34
[    0.847688] fec0: c0a19a28 cf98ac00 c0a16ae0 c05598bc c08179c8 c09164fc c0a19a28 c0a19a28
[    0.855847] fee0: 00000000 c091650c ffffe000 c055aadc c0a03c48 00000000 c091650c c03019f0
[    0.864007] ff00: cf82ff24 00000000 00000000 c0856700 cfffce40 c0856790 0000005a c0856790
[    0.872166] ff20: cfffce52 c033ae18 c085609c c080d978 00000006 00000006 c07e8ed8 00000000
[    0.880324] ff40: c07f1ce4 c07e8f4c cfffce52 c9571fb7 00000000 c0a24000 c0a24000 c092c834
[    0.888485] ff60: c092c83c 00000007 00000059 c0936f44 00000000 c0900dc4 00000006 00000006
[    0.896645] ff80: 00000000 c0900598 00000000 c07297bc 00000000 00000000 00000000 00000000
[    0.904806] ffa0: 00000000 c07297c4 00000000 c0307768 00000000 00000000 00000000 00000000
[    0.912963] ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.921123] ffe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
[    0.929299] [<c05b9ea0>] (ar40xx_probe) from [<c055b76c>] (platform_drv_probe+0x34/0x70)
[    0.937447] [<c055b76c>] (platform_drv_probe) from [<c055a1ac>] (really_probe+0x114/0x274)
[    0.945603] [<c055a1ac>] (really_probe) from [<c055a398>] (__driver_attach+0x8c/0xb0)
[    0.953677] [<c055a398>] (__driver_attach) from [<c0558938>] (bus_for_each_dev+0x4c/0xa0)
[    0.961576] [<c0558938>] (bus_for_each_dev) from [<c05598bc>] (bus_add_driver+0xe8/0x200)
[    0.969735] [<c05598bc>] (bus_add_driver) from [<c055aadc>] (driver_register+0xa8/0xe4)
[    0.977898] [<c055aadc>] (driver_register) from [<c03019f0>] (do_one_initcall+0xc0/0x184)
[    0.985711] [<c03019f0>] (do_one_initcall) from [<c0900dc4>] (kernel_init_freeable+0x13c/0x1d0)
[    0.994045] [<c0900dc4>] (kernel_init_freeable) from [<c07297c4>] (kernel_init+0x8/0x114)
[    1.002553] [<c07297c4>] (kernel_init) from [<c0307768>] (ret_from_fork+0x14/0x2c)
[    1.010881] Code: e58431f4 e3a01000 e1a00004 e58d300c (e59230a4) 
[    1.018474] ---[ end trace 2acf4f4240f07442 ]---
[    1.024511] Kernel panic - not syncing: Fatal exception

Tried both 4.14 and 4.19 kernel.

I found the exact same problem here but neither has the solution:

@chunkeey @robimarko @ptpt52
Could you please take a look?

Maybe you used a wrong DTS to define some wrong hardware, track the code corresponding to the stack information, find the relevant dts definition to see if it matches the real hardware.

The board is based on dk04.1-c1.
PHY is QCA8072, MDC = GPIO#7, MDIO=GPIO#6
Here is the not working DTS:

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT

#include "qcom-ipq4019.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/soc/qcom,tcsr.h>

/ {

	model = "Some model";
	compatible = "some,model", "qcom,ipq4019";

	memory {
		device_type = "memory";
		reg = <0x80000000 0x10000000>;
	};

	soc {
		mdio@90000 {
			status = "okay";
			pinctrl-0 = <&mdio_pins>;
			pinctrl-names = "default";
		};

		ess-psgmii@98000 {
			status = "okay";
		};

		tcsr@1949000 {
			compatible = "qcom,tcsr";
			reg = <0x1949000 0x100>;
			qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
		};

		tcsr@194b000 {
			compatible = "qcom,tcsr";
			reg = <0x194b000 0x100>;
			qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
			status = "okay";
		};

		ess_tcsr@1953000 {
			compatible = "qcom,tcsr";
			reg = <0x1953000 0x1000>;
			qcom,ess-interface-select = <TCSR_ESS_PSGMII>;
		};

		tcsr@1957000 {
			compatible = "qcom,tcsr";
			reg = <0x1957000 0x100>;
			qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
		};

		usb2: usb2@60f8800 {
			status = "okay";

			dwc3@6000000 {
				#address-cells = <1>;
				#size-cells = <0>;

				usb2_port1: port@1 {
					reg = <1>;
					#trigger-source-cells = <0>;
				};
			};
		};

		serial@78af000 {
			pinctrl-0 = <&serial_0_pins>;
			pinctrl-names = "default";
			status = "okay";
		};

		serial@78b0000 {
			status = "okay";
		};

		i2c@78b7000 {
			status = "okay";
		};

		usb3_ss_phy: ssphy@9a000 {
			status = "okay";
		};

		usb3_hs_phy: hsphy@a6000 {
			status = "okay";
		};

		usb3: usb3@8af8800 {
			status = "okay";

			dwc3@8a00000 {
				#address-cells = <1>;
				#size-cells = <0>;

				usb3_port1: port@1 {
					reg = <1>;
					#trigger-source-cells = <0>;
				};

				usb3_port2: port@2 {
					reg = <2>;
					#trigger-source-cells = <0>;
				};
			};
		};

		crypto@8e3a000 {
			status = "okay";
		};

		watchdog@b017000 {
			status = "okay";
		};

		ess-switch@c000000 {
			status = "okay";

			switch_lan_bmp = <0x10>;
			switch_wan_bmp = <0x20>;
		};

		edma@c080000 {
			status = "okay";
			qcom,num_gmac = <2>;
		};
	};

	keys {
		compatible = "gpio-keys";

		reset {
			label = "reset";
			gpios = <&tlmm 18 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_RESTART>;
		};
	};
};

&blsp_dma {
	status = "okay";
};

&cryptobam {
	status = "okay";
};

&qpic_bam {
	status = "okay";
};

&tlmm {
	serial_0_pins: serial0-pinmux {
		mux {
			pins = "gpio16", "gpio17";
			function = "blsp_uart0";
			bias-disable;
		};
	};

	spi_0_pins: spi_0_pinmux {
		pinmux {
			function = "blsp_spi0";
			pins = "gpio13", "gpio14", "gpio15";
		};
		pinmux_cs {
			function = "gpio";
			pins = "gpio12";
		};
		pinconf {
			pins = "gpio13", "gpio14", "gpio15";
			drive-strength = <12>;
			bias-disable;
		};
		pinconf_cs {
			pins = "gpio12";
			drive-strength = <2>;
			bias-disable;
			output-high;
		};
	};

	mdio_pins: mdio_pinmux {
		mux_1 {
			pins = "gpio6";
			function = "mdio";
			bias-pull-up;
		};
		mux_2 {
			pins = "gpio7";
			function = "mdc";
			bias-pull-up;
		};
	};
};

&gmac0 {
	qcom,phy_mdio_addr = <4>;
	qcom,poll_required = <1>;
	qcom,forced_speed = <1000>;
	qcom,forced_duplex = <1>;
	vlan_tag = <2 0x20>;
};

&gmac1 {
	qcom,phy_mdio_addr = <3>;
	qcom,poll_required = <1>;
	qcom,forced_speed = <1000>;
	qcom,forced_duplex = <1>;
	vlan_tag = <1 0x10>;
};

&usb3_ss_phy {
	status = "okay";
};

&usb3_hs_phy {
	status = "okay";
};

&usb2_hs_phy {
	status = "okay";
};

&wifi0 {
	status = "okay";
};

&wifi1 {
	status = "okay";
};

&blsp1_spi1 {
	pinctrl-0 = <&spi_0_pins>;
	pinctrl-names = "default";
	status = "okay";
	cs-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;

	flash@0 {
		reg = <0>;
		compatible = "jedec,spi-nor";
		spi-max-frequency = <24000000>;

		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			partition@0 {
				label = "0:SBL1";
				reg = <0x0 0x40000>;
				read-only;
			};
			partition@40000 {
				label = "0:MIBIB";
				reg = <0x40000 0x20000>;
				read-only;
			};
			partition@60000 {
				label = "0:QSEE";
				reg = <0x60000 0x60000>;
				read-only;
			};
			partition@c0000 {
				label = "0:CDT";
				reg = <0xc0000 0x10000>;
				read-only;
			};
			partition@d0000 {
				label = "0:DDRPARAMS";
				reg = <0xd0000 0x10000>;
				read-only;
			};
			partition@e0000 {
				label = "0:APPSBLENV";
				reg = <0xe0000 0x10000>;
				read-only;
			};
			partition@f0000 {
				label = "0:APPSBL";
				reg = <0xf0000 0x80000>;
				read-only;
			};
			partition@170000 {
				label = "0:ART";
				reg = <0x170000 0x10000>;
				read-only;
			};
			partition@180000 {
				compatible = "denx,fit";
				label = "firmware";
				reg = <0x180000 0x1e80000>;
			};
		};
	};
};

Edit: PHY reset pin is GPIO#47

Finally I solved this issue by myself (again)
At first i used @chunkeey 's staging tree, which has switched to DSA driver (Kernel 4.19 only)
That didn't fix the issue, but at least it didn't panic anymore

[    0.692126] libphy: ipq40xx_mdio: probed
[    0.698865] libphy: Fixed MDIO Bus: probed
[    1.895127] PHY 0 single test PSGMII issue happen!
[    2.768637] PHY 1 single test PSGMII issue happen!
[    3.642123] PHY 2 single test PSGMII issue happen!
[    4.515581] PHY 3 single test PSGMII issue happen!
[    5.389077] PHY 4 single test PSGMII issue happen!
[    6.262583] PHY0 test see issue!
[    6.266638] PHY1 test see issue!
[    6.270683] PHY2 test see issue!
[    6.274733] PHY3 test see issue!
[    6.278777] PHY4 test see issue!
... repeat 100 times

And as he mentioned in this reply Ipq4018 dk01.1 kernel panic , a patch is needed to reset the phy via a GPIO pin

patch, slightly modified
diff --git a/target/linux/ipq40xx/patches-4.19/857-ipq40xx-Fix-mdio-driver-to-work-with-IPQ40xx-SoC.patch b/target/linux/ipq40xx/patches-4.19/857-ipq40xx-Fix-mdio-driver-to-work-with-IPQ40xx-SoC.patch
new file mode 100644
index 0000000000..1545ed477a
--- /dev/null
+++ b/target/linux/ipq40xx/patches-4.19/857-ipq40xx-Fix-mdio-driver-to-work-with-IPQ40xx-SoC.patch
@@ -0,0 +1,91 @@
+From 1d8433be4af4a5862b8805a5668d404bd6fde945 Mon Sep 17 00:00:00 2001
+From: Ram Chandra Jangir <rjangir at codeaurora.org>
+Date: Tue, 28 Mar 2017 22:32:07 +0530
+Subject: [PATCH] ipq40xx: Fix mdio driver to work with IPQ40xx SoC
+
+- Add phy-reset-gpio support in probe function to fix hang
+  at board booting.
+- Add proper assignment of mii_bus read/write operations
+
+Signed-off-by: Ram Chandra Jangir <rjangir at codeaurora.org>
+---
+ drivers/net/phy/mdio-ipq40xx.c | 56 +++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 51 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/net/phy/mdio-ipq40xx.c b/drivers/net/phy/mdio-ipq40xx.c
+index 335d531..6f13c96 100644
+--- a/drivers/net/phy/mdio-ipq40xx.c
++++ b/drivers/net/phy/mdio-ipq40xx.c
+@@ -22,6 +22,7 @@
+ #include <linux/of_mdio.h>
+ #include <linux/phy.h>
+ #include <linux/platform_device.h>
++#include <linux/of_gpio.h>
+
+ #define MDIO_CTRL_0_REG		0x40
+ #define MDIO_CTRL_1_REG		0x44
+@@ -121,11 +122,61 @@ static int ipq40xx_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+	return 0;
+ }
+
++static int ipq40xx_phy_reset(struct platform_device *pdev)
++{
++	struct device_node *mdio_node;
++	int phy_reset_gpio_number;
++	int ret;
++
++	mdio_node = of_find_node_by_name(NULL, "mdio");
++	if (!mdio_node) {
++		dev_err(&pdev->dev, "Could not find mdio node\n");
++		return -ENOENT;
++	}
++
++	ret = of_get_named_gpio(mdio_node, "phy-reset-gpio", 0);
++	if (ret < 0) {
++		dev_warn(&pdev->dev, "Could not find DT gpio phy-reset-gpio missing/malformed:%d\n",ret);
++		ret = 0;
++		return ret;
++	}
++
++	phy_reset_gpio_number = ret;
++
++	ret = gpio_request(phy_reset_gpio_number, "phy-reset-gpio");
++	if (ret) {
++		dev_err(&pdev->dev, "Can't get phy-reset-gpio %d\n", ret);
++		return ret;
++	}
++
++	ret = gpio_direction_output(phy_reset_gpio_number, 0x0);
++	if (ret) {
++		dev_err(&pdev->dev,
++			"Can't set direction for phy-reset-gpio %d\n", ret);
++		goto phy_reset_out;
++	}
++
++	usleep_range(1000, 10005);
++
++	gpio_set_value(phy_reset_gpio_number, 0x01);
++
++phy_reset_out:
++	gpio_free(phy_reset_gpio_number);
++
++	return ret;
++}
++
+ static int ipq40xx_mdio_probe(struct platform_device *pdev)
+ {
+	struct ipq40xx_mdio_data *am;
+	struct resource *res;
+-	int i;
++	int i, ret;
++
++	ret = ipq40xx_phy_reset(pdev);
++	if (ret) {
++		dev_err(&pdev->dev, "Could not find qca8075 reset gpio\n");
++		return ret;
++	}
+
+	am = devm_kzalloc(&pdev->dev, sizeof(*am), GFP_KERNEL);
+	if (!am)
+--
+2.7.2

And here's the working DTS (with DSA driver):

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT

#include "qcom-ipq4019.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/soc/qcom,tcsr.h>

/ {

	model = "Some model";
	compatible = "some,model", "qcom,ipq4019";

	aliases {
		ethernet0 = &gmac;
	};

	memory {
		device_type = "memory";
		reg = <0x80000000 0x10000000>;
	};

	soc {
		tcsr@1949000 {
			compatible = "qcom,tcsr";
			reg = <0x1949000 0x100>;
			qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
		};

		tcsr@194b000 {
			compatible = "qcom,tcsr";
			reg = <0x194b000 0x100>;
			qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
			status = "okay";
		};

		tcsr@1957000 {
			compatible = "qcom,tcsr";
			reg = <0x1957000 0x100>;
			qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
		};

		usb2: usb2@60f8800 {
			status = "okay";

			dwc3@6000000 {
				#address-cells = <1>;
				#size-cells = <0>;

				usb2_port1: port@1 {
					reg = <1>;
					#trigger-source-cells = <0>;
				};
			};
		};

		serial@78af000 {
			pinctrl-0 = <&serial_0_pins>;
			pinctrl-names = "default";
			status = "okay";
		};

		serial@78b0000 {
			status = "okay";
		};

		i2c@78b7000 {
			status = "okay";
		};

		usb3_ss_phy: ssphy@9a000 {
			status = "okay";
		};

		usb3_hs_phy: hsphy@a6000 {
			status = "okay";
		};

		usb3: usb3@8af8800 {
			status = "okay";

			dwc3@8a00000 {
				#address-cells = <1>;
				#size-cells = <0>;

				usb3_port1: port@1 {
					reg = <1>;
					#trigger-source-cells = <0>;
				};

				usb3_port2: port@2 {
					reg = <2>;
					#trigger-source-cells = <0>;
				};
			};
		};

		crypto@8e3a000 {
			status = "okay";
		};

		watchdog@b017000 {
			status = "okay";
		};
	};

	keys {
		compatible = "gpio-keys";

		reset {
			label = "reset";
			gpios = <&tlmm 18 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_RESTART>;
		};
	};
};

&mdio {
	status = "okay";
	pinctrl-0 = <&mdio_pins>;
	pinctrl-names = "default";
	phy-reset-gpio = <&tlmm 47 GPIO_ACTIVE_HIGH>;
};

&psgmii_phy {
	status = "okay";
};

&ess {
	status = "okay";

	ports {
		/delete-node/ port@1;
		/delete-node/ port@2;
		/delete-node/ port@3;

		port@4 {
			label = "lan";
		};

		port@5 {
			label = "wan";
		};
	};
};

&gmac {
	status = "okay";
};

&blsp_dma {
	status = "okay";
};

&cryptobam {
	status = "okay";
};

&qpic_bam {
	status = "okay";
};

&tlmm {
	serial_0_pins: serial0-pinmux {
		mux {
			pins = "gpio16", "gpio17";
			function = "blsp_uart0";
			bias-disable;
		};
	};

	spi_0_pins: spi_0_pinmux {
		pinmux {
			function = "blsp_spi0";
			pins = "gpio13", "gpio14", "gpio15";
		};
		pinmux_cs {
			function = "gpio";
			pins = "gpio12";
		};
		pinconf {
			pins = "gpio13", "gpio14", "gpio15";
			drive-strength = <12>;
			bias-disable;
		};
		pinconf_cs {
			pins = "gpio12";
			drive-strength = <2>;
			bias-disable;
			output-high;
		};
	};

	mdio_pins: mdio_pinmux {
		mux_1 {
			pins = "gpio6";
			function = "mdio";
			bias-pull-up;
		};
		mux_2 {
			pins = "gpio7";
			function = "mdc";
			bias-pull-up;
		};
	};
};

&usb3_ss_phy {
	status = "okay";
};

&usb3_hs_phy {
	status = "okay";
};

&usb2_hs_phy {
	status = "okay";
};

&wifi0 {
	status = "okay";
};

&wifi1 {
	status = "okay";
};

&blsp1_spi1 {
	pinctrl-0 = <&spi_0_pins>;
	pinctrl-names = "default";
	status = "okay";
	cs-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;

	flash@0 {
		reg = <0>;
		compatible = "jedec,spi-nor";
		spi-max-frequency = <24000000>;

		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			partition@0 {
				label = "0:SBL1";
				reg = <0x0 0x40000>;
				read-only;
			};
			partition@40000 {
				label = "0:MIBIB";
				reg = <0x40000 0x20000>;
				read-only;
			};
			partition@60000 {
				label = "0:QSEE";
				reg = <0x60000 0x60000>;
				read-only;
			};
			partition@c0000 {
				label = "0:CDT";
				reg = <0xc0000 0x10000>;
				read-only;
			};
			partition@d0000 {
				label = "0:DDRPARAMS";
				reg = <0xd0000 0x10000>;
				read-only;
			};
			partition@e0000 {
				label = "0:APPSBLENV";
				reg = <0xe0000 0x10000>;
				read-only;
			};
			partition@f0000 {
				label = "0:APPSBL";
				reg = <0xf0000 0x80000>;
				read-only;
			};
			partition@170000 {
				label = "0:ART";
				reg = <0x170000 0x10000>;
				read-only;
			};
			partition@180000 {
				compatible = "denx,fit";
				label = "firmware";
				reg = <0x180000 0x1e80000>;
			};
		};
	};
};
2 Likes

@chunkeey
Update: I tried master branch 4.14 with the phy-reset patch, also works.
Also tried using gpio-hog or gpio-export to set the pin, neither one worked.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.