]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
imx8mn-var-som: adjust PHY reset gpios according to hardware configuration
authorHugo Villeneuve <hvilleneuve@dimonoff.com>
Thu, 25 May 2023 21:02:29 +0000 (17:02 -0400)
committerStefano Babic <sbabic@denx.de>
Thu, 13 Jul 2023 09:29:40 +0000 (11:29 +0200)
For SOM with the EC configuration, the ethernet PHY is located on the
SOM itself, and connected to the CPU ethernet controller. It has a
reset line controlled via GPIO1_IO9. In this configuration, the PHY
located on the carrier board is not connected to anything and is
therefore not used.

For SOM without EC configuration, the ethernet PHY on the carrier
board is connected to the CPU ethernet controller. It has a reset line
controlled via the GPIO expander PCA9534_IO5.

The hardware configuration (EC) is determined at runtime by
reading from the SOM EEPROM.

To support both hardware configurations (EC and non-EC), adjust/fix
the PHY reset gpios according to the hardware configuration
read at runtime from the SOM EEPROM. This adjustement is done in
U-Boot (OF_BOARD_FIXUP) and kernel (OF_BOARD_SETUP) device trees.

Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
arch/arm/dts/imx8mn-var-som-symphony.dts
board/variscite/imx8mn_var_som/imx8mn_var_som.c
configs/imx8mn_var_som_defconfig

index 3ed7021a487cf11e4b5533b4b9bf512815adcb7c..5c8e4e81752f9ef826a956d9a49d62ef62a6c967 100644 (file)
        };
 };
 
-&ethphy {
-       reset-gpios = <&pca9534 5 GPIO_ACTIVE_HIGH>;
-};
-
 &i2c2 {
        clock-frequency = <400000>;
        pinctrl-names = "default";
index a89457e8f57f34fb7a03559b235cdae9769eccfc..61b9455a8f4e23e203c2ad55e78b36cbcd6a028b 100644 (file)
@@ -14,6 +14,7 @@
 #include <malloc.h>
 #include <asm/io.h>
 #include <asm/global_data.h>
+#include <dt-bindings/gpio/gpio.h>
 #include <linux/libfdt.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -161,4 +162,83 @@ int checkboard(void)
 
 #endif /* CONFIG_DISPLAY_BOARDINFO */
 
+static int insert_gpios_prop(void *blob, int node, const char *prop,
+                            unsigned int phandle, u32 gpio, u32 flags)
+{
+       fdt32_t val[3] = { cpu_to_fdt32(phandle), cpu_to_fdt32(gpio),
+                          cpu_to_fdt32(flags) };
+       return fdt_setprop(blob, node, prop, &val, sizeof(val));
+}
+
+static int configure_phy_reset_gpios(void *blob)
+{
+       int node;
+       int phynode;
+       int ret;
+       u32 handle;
+       u32 gpio;
+       u32 flags;
+       char path[1024];
+       const char *eth_alias = "ethernet0";
+
+       snprintf(path, sizeof(path), "%s/mdio/ethernet-phy@4",
+                fdt_get_alias(blob, eth_alias));
+
+       phynode = fdt_path_offset(blob, path);
+       if (phynode < 0) {
+               pr_err("%s(): unable to locate PHY node: %s\n", __func__, path);
+               return 0;
+       }
+
+       if (gd_board_type() & VAR_EEPROM_F_ETH) {
+               snprintf(path, sizeof(path), "%s",
+                        fdt_get_alias(blob, "gpio0")); /* Alias to gpio1 */
+               gpio = 9;
+               flags = GPIO_ACTIVE_LOW;
+       } else {
+               snprintf(path, sizeof(path), "%s/gpio@20",
+                        fdt_get_alias(blob, "i2c1")); /* Alias to i2c2 */
+               gpio = 5;
+               flags = GPIO_ACTIVE_HIGH;
+       }
+
+       node = fdt_path_offset(blob, path);
+       if (node < 0) {
+               pr_err("%s(): unable to locate GPIO node: %s\n", __func__,
+                      path);
+               return 0;
+       }
+
+       handle = fdt_get_phandle(blob, node);
+       if (handle < 0) {
+               pr_err("%s(): unable to locate GPIO controller handle: %s\n",
+                      __func__, path);
+       }
+
+       ret = insert_gpios_prop(blob, phynode, "reset-gpios",
+                               handle, gpio, flags);
+       if (ret < 0) {
+               pr_err("%s(): failed to set reset-gpios property\n", __func__);
+               return ret;
+       }
+
+       return 0;
+}
+
+#if defined(CONFIG_OF_BOARD_FIXUP)
+int board_fix_fdt(void *blob)
+{
+       /* Fix U-Boot device tree: */
+       return configure_phy_reset_gpios(blob);
+}
+#endif /* CONFIG_OF_BOARD_FIXUP */
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+       /* Fix kernel device tree: */
+       return configure_phy_reset_gpios(blob);
+}
+#endif /* CONFIG_OF_BOARD_SETUP */
+
 #endif /* CONFIG_SPL_BUILD */
index e54c20e1531e10dba9ff61711a7557f9a6c6fd6c..b346b14ebdd2c41cebd743b0e26c0634ca1d89bb 100644 (file)
@@ -23,9 +23,11 @@ CONFIG_SPL_SYS_MALLOC_F_LEN=0x2000
 CONFIG_SPL=y
 CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000
 CONFIG_SYS_LOAD_ADDR=0x40480000
+CONFIG_OF_BOARD_FIXUP=y
 CONFIG_FIT=y
 CONFIG_FIT_EXTERNAL_OFFSET=0x3000
 CONFIG_SPL_LOAD_FIT=y
+CONFIG_OF_BOARD_SETUP=y
 CONFIG_OF_SYSTEM_SETUP=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_DEFAULT_FDT_FILE="freescale/imx8mn-var-som-symphony.dtb"