public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [PATCH] arm64: imx8mp: Auto-detect PHY on i.MX8MP DHCOM
@ 2023-02-11 22:10 Marek Vasut
  2023-03-30  8:44 ` sbabic
  0 siblings, 1 reply; 2+ messages in thread
From: Marek Vasut @ 2023-02-11 22:10 UTC (permalink / raw)
  To: u-boot
  Cc: Marek Vasut, NXP i.MX U-Boot Team, Fabio Estevam, Peng Fan,
	Stefano Babic

The i.MX8MP DHCOM SoM may be populated with either KSZ9131RNXI RGMII PHY
or LAN8740Ai RMII PHY attached to EQoS MAC, and either external RGMII PHY
or LAN8740Ai RMII PHY attached to FEC MAC. The SoM configuration can be
detected for each MAC by reading RX_CTL pull resistor state early on boot.
Make use of this, detect the exact PHY configuration, and patch control DT
accordingly so that the ethernet is configured correctly in U-Boot.

Signed-off-by: Marek Vasut <marex@denx.de>
---
Cc: "NXP i.MX U-Boot Team" <uboot-imx@nxp.com>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: u-boot@lists.denx.de
---
 .../dh_imx8mp/imx8mp_dhcom_pdk2.c             | 228 ++++++++++++++++++
 1 file changed, 228 insertions(+)

diff --git a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c
index 5edb85e1de5..760ea4be35c 100644
--- a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c
+++ b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c
@@ -5,12 +5,16 @@
 
 #include <common.h>
 #include <asm/arch/clock.h>
+#include <asm/mach-imx/iomux-v3.h>
+#include <asm/arch/imx8mp_pins.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/io.h>
 #include <dm.h>
+#include <dt-bindings/clock/imx8mp-clock.h>
 #include <env.h>
 #include <env_internal.h>
 #include <i2c_eeprom.h>
+#include <linux/bitfield.h>
 #include <malloc.h>
 #include <net.h>
 #include <miiphy.h>
@@ -116,3 +120,227 @@ enum env_location env_get_location(enum env_operation op, int prio)
 {
 	return prio ? ENVL_UNKNOWN : ENVL_SPI_FLASH;
 }
+
+static const char *iomuxc_compat = "fsl,imx8mp-iomuxc";
+static const char *lan_compat = "ethernet-phy-id0007.c110";
+static const char *ksz_compat = "ethernet-phy-id0022.1642";
+
+static int dh_dt_patch_som_eqos(const void *fdt_blob)
+{
+	const void __iomem *mux = (void __iomem *)IOMUXC_BASE_ADDR +
+		FIELD_GET(MUX_CTRL_OFS_MASK, MX8MP_PAD_ENET_RX_CTL__GPIO1_IO24);
+	int mac_node, mdio_node, iomuxc_node, ksz_node, lan_node, subnode;
+	const char *mac_compat = "nxp,imx8mp-dwmac-eqos";
+	void *blob = (void *)fdt_blob;
+	const fdt32_t *clk_prop;
+	bool is_gigabit;
+	u32 handle;
+	u32 clk[6];
+
+	setbits_le32(mux, IOMUX_CONFIG_SION);
+	is_gigabit = !(readl(GPIO1_BASE_ADDR) & BIT(24));
+	clrbits_le32(mux, IOMUX_CONFIG_SION);
+
+	/* Adjust EQoS node for Gigabit KSZ9131RNXI or Fast LAN8740Ai PHY */
+	mac_node = fdt_node_offset_by_compatible(blob, -1, mac_compat);
+	if (mac_node < 0)
+		return 0;
+
+	mdio_node = fdt_first_subnode(blob, mac_node);
+	if (mdio_node < 0)
+		return 0;
+
+	/* KSZ9131RNXI */
+	ksz_node = fdt_node_offset_by_compatible(blob, mdio_node, ksz_compat);
+	if (ksz_node < 0)
+		return 0;
+
+	/* LAN8740Ai */
+	lan_node = fdt_node_offset_by_compatible(blob, mdio_node, lan_compat);
+	if (lan_node < 0)
+		return 0;
+
+	iomuxc_node = fdt_node_offset_by_compatible(blob, -1, iomuxc_compat);
+	if (iomuxc_node < 0)
+		return 0;
+
+	/*
+	 * The code below adjusts the following DT properties:
+	 * - assigned-clock-parents .. 125 MHz RGMII / 50 MHz RMII ref clock
+	 * - assigned-clock-rates .... 125 MHz RGMII / 50 MHz RMII ref clock
+	 * - phy-handle .............. KSZ9131RNXI RGMII / LAN8740Ai RMII
+	 * - phy-mode ................ RGMII / RMII
+	 * - pinctrl-0 ............... RGMII / RMII
+	 * - PHY subnode status ...... "disabled"/"okay" per RGMII / RMII
+	 */
+
+	/* Perform all inplace changes first, string changes last. */
+	clk_prop = fdt_getprop(blob, mac_node, "assigned-clock-parents", NULL);
+	if (!clk_prop)
+		return 0;
+	clk[0] = clk_prop[0];
+	clk[1] = cpu_to_fdt32(IMX8MP_SYS_PLL1_266M);
+	clk[2] = clk_prop[2];
+	clk[3] = cpu_to_fdt32(IMX8MP_SYS_PLL2_100M);
+	clk[4] = clk_prop[4];
+	clk[5] = is_gigabit ? cpu_to_fdt32(IMX8MP_SYS_PLL2_125M) :
+			      cpu_to_fdt32(IMX8MP_SYS_PLL2_50M);
+	fdt_setprop_inplace(blob, mac_node, "assigned-clock-parents",
+			    clk, 6 * sizeof(u32));
+
+	clk[0] = cpu_to_fdt32(0);
+	clk[1] = cpu_to_fdt32(100000000);
+	clk[2] = is_gigabit ? cpu_to_fdt32(125000000) :
+			      cpu_to_fdt32(50000000);
+	fdt_setprop_inplace(blob, mac_node, "assigned-clock-rates",
+			    clk, 3 * sizeof(u32));
+
+	handle = fdt_get_phandle(blob, is_gigabit ? ksz_node : lan_node);
+	fdt_setprop_inplace_u32(blob, mac_node, "phy-handle", handle);
+
+	fdt_for_each_subnode(subnode, blob, iomuxc_node) {
+		if (!strstr(fdt_get_name(blob, subnode, NULL),
+			    is_gigabit ? "eqos-rgmii" : "eqos-rmii"))
+			continue;
+
+		handle = fdt_get_phandle(blob, subnode);
+		fdt_setprop_inplace_u32(blob, mac_node, "pinctrl-0", handle);
+		break;
+	}
+
+	fdt_setprop_string(blob, mac_node, "phy-mode",
+			   is_gigabit ? "rgmii-id" : "rmii");
+
+	mac_node = fdt_node_offset_by_compatible(blob, -1, mac_compat);
+	mdio_node = fdt_first_subnode(blob, mac_node);
+	ksz_node = fdt_node_offset_by_compatible(blob, mdio_node, ksz_compat);
+	fdt_setprop_string(blob, ksz_node, "status",
+			   is_gigabit ? "okay" : "disabled");
+
+	mac_node = fdt_node_offset_by_compatible(blob, -1, mac_compat);
+	mdio_node = fdt_first_subnode(blob, mac_node);
+	lan_node = fdt_node_offset_by_compatible(blob, mdio_node, lan_compat);
+	fdt_setprop_string(blob, lan_node, "status",
+			   is_gigabit ? "disabled" : "okay");
+
+	return 0;
+}
+
+static int dh_dt_patch_som_fec(const void *fdt_blob)
+{
+	const void __iomem *mux = (void __iomem *)IOMUXC_BASE_ADDR +
+		FIELD_GET(MUX_CTRL_OFS_MASK, MX8MP_PAD_SAI1_TXFS__GPIO4_IO10);
+	int mac_node, mdio_node, iomuxc_node, lan_node, phy_node, subnode;
+	const char *mac_compat = "fsl,imx8mp-fec";
+	void *blob = (void *)fdt_blob;
+	const fdt32_t *clk_prop;
+	bool is_gigabit;
+	u32 handle;
+	u32 clk[8];
+
+	setbits_le32(mux, IOMUX_CONFIG_SION);
+	is_gigabit = !(readl(GPIO4_BASE_ADDR) & BIT(10));
+	clrbits_le32(mux, IOMUX_CONFIG_SION);
+
+	/* Test for non-default SoM with 100/Full PHY attached to FEC */
+	if (is_gigabit)
+		return 0;
+
+	/* Adjust FEC node for Fast LAN8740Ai PHY */
+	mac_node = fdt_node_offset_by_compatible(blob, -1, mac_compat);
+	if (mac_node < 0)
+		return 0;
+
+	/* Optional PHY pointed to by phy-handle, possibly on carrier board */
+	phy_node = fdtdec_lookup_phandle(blob, mac_node, "phy-handle");
+	if (phy_node > 0) {
+		fdt_setprop_string(blob, phy_node, "status", "disabled");
+		mac_node = fdt_node_offset_by_compatible(blob, -1, mac_compat);
+	}
+
+	mdio_node = fdt_first_subnode(blob, mac_node);
+	if (mdio_node < 0)
+		return 0;
+
+	/* LAN8740Ai */
+	lan_node = fdt_node_offset_by_compatible(blob, mdio_node, lan_compat);
+	if (lan_node < 0)
+		return 0;
+
+	iomuxc_node = fdt_node_offset_by_compatible(blob, -1, iomuxc_compat);
+	if (iomuxc_node < 0)
+		return 0;
+
+	/*
+	 * The code below adjusts the following DT properties:
+	 * - assigned-clock-parents .. 50 MHz RMII ref clock
+	 * - assigned-clock-rates .... 50 MHz RMII ref clock
+	 * - phy-handle .............. LAN8740Ai RMII
+	 * - phy-mode ................ RMII
+	 * - pinctrl-0 ............... RMII
+	 * - PHY subnode status ...... "okay" for RMII PHY
+	 */
+
+	/* Perform all inplace changes first, string changes last. */
+	clk_prop = fdt_getprop(blob, mac_node, "assigned-clock-parents", NULL);
+	if (!clk_prop)
+		return 0;
+	clk[0] = clk_prop[0];
+	clk[1] = cpu_to_fdt32(IMX8MP_SYS_PLL1_266M);
+	clk[2] = clk_prop[2];
+	clk[3] = cpu_to_fdt32(IMX8MP_SYS_PLL2_100M);
+	clk[4] = clk_prop[4];
+	clk[5] = cpu_to_fdt32(IMX8MP_SYS_PLL2_50M);
+	clk[6] = clk_prop[6];
+	clk[7] = cpu_to_fdt32(IMX8MP_SYS_PLL2_50M);
+	fdt_setprop_inplace(blob, mac_node, "assigned-clock-parents",
+			    clk, 8 * sizeof(u32));
+
+	clk[0] = cpu_to_fdt32(0);
+	clk[1] = cpu_to_fdt32(100000000);
+	clk[2] = cpu_to_fdt32(50000000);
+	clk[3] = cpu_to_fdt32(0);
+	fdt_setprop_inplace(blob, mac_node, "assigned-clock-rates",
+			    clk, 4 * sizeof(u32));
+
+	handle = fdt_get_phandle(blob, lan_node);
+	fdt_setprop_inplace_u32(blob, mac_node, "phy-handle", handle);
+
+	fdt_for_each_subnode(subnode, blob, iomuxc_node) {
+		if (!strstr(fdt_get_name(blob, subnode, NULL), "fec-rmii"))
+			continue;
+
+		handle = fdt_get_phandle(blob, subnode);
+		fdt_setprop_inplace_u32(blob, mac_node, "pinctrl-0", handle);
+		break;
+	}
+
+	fdt_setprop_string(blob, mac_node, "phy-mode", "rmii");
+	mac_node = fdt_node_offset_by_compatible(blob, -1, mac_compat);
+	mdio_node = fdt_first_subnode(blob, mac_node);
+	lan_node = fdt_node_offset_by_compatible(blob, mdio_node, lan_compat);
+	fdt_setprop_string(blob, lan_node, "status", "okay");
+
+	return 0;
+}
+
+static int dh_dt_patch_som(const void *fdt_blob)
+{
+	int ret;
+
+	/* Do nothing if not i.MX8MP DHCOM SoM */
+	ret = fdt_node_check_compatible(fdt_blob, 0, "dh,imx8mp-dhcom-som");
+	if (ret)
+		return 0;
+
+	ret = dh_dt_patch_som_eqos(fdt_blob);
+	if (ret)
+		return ret;
+
+	return dh_dt_patch_som_fec(fdt_blob);
+}
+
+int fdtdec_board_setup(const void *fdt_blob)
+{
+	return dh_dt_patch_som(fdt_blob);
+}
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH] arm64: imx8mp: Auto-detect PHY on i.MX8MP DHCOM
  2023-02-11 22:10 [PATCH] arm64: imx8mp: Auto-detect PHY on i.MX8MP DHCOM Marek Vasut
@ 2023-03-30  8:44 ` sbabic
  0 siblings, 0 replies; 2+ messages in thread
From: sbabic @ 2023-03-30  8:44 UTC (permalink / raw)
  To: Marek Vasut, u-boot

> The i.MX8MP DHCOM SoM may be populated with either KSZ9131RNXI RGMII PHY
> or LAN8740Ai RMII PHY attached to EQoS MAC, and either external RGMII PHY
> or LAN8740Ai RMII PHY attached to FEC MAC. The SoM configuration can be
> detected for each MAC by reading RX_CTL pull resistor state early on boot.
> Make use of this, detect the exact PHY configuration, and patch control DT
> accordingly so that the ethernet is configured correctly in U-Boot.
> Signed-off-by: Marek Vasut <marex@denx.de>
Applied to u-boot-imx, next, thanks !

Best regards,
Stefano Babic

-- 
=====================================================================
DENX Software Engineering GmbH,        Managing Director: Erika Unter  
HRB 165235 Munich,   Office: Kirchenstr.5, 82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic@denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-03-30  8:47 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-11 22:10 [PATCH] arm64: imx8mp: Auto-detect PHY on i.MX8MP DHCOM Marek Vasut
2023-03-30  8:44 ` sbabic

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox