]> Git Repo - J-u-boot.git/commitdiff
board: phytec: imx93: Add eeprom-based hardware introspection
authorChristoph Stoidner <[email protected]>
Wed, 20 Nov 2024 16:31:42 +0000 (17:31 +0100)
committerFabio Estevam <[email protected]>
Tue, 26 Nov 2024 02:08:02 +0000 (23:08 -0300)
The phyCORE-i.MX 93 is available in various variants. Relevant variant
options for the spl/u-boot are:
- with or without HS400 support for the eMMC
- with 1GB ram chip, or 2GB ram chip

The phyCORE's eeprom contains all information about the existing variant
options. Add evaluation of the eeprom data to the spl/u-boot to
enable/disable HS400 and to select the appropriate ram configuration at
startup.

Signed-off-by: Christoph Stoidner <[email protected]>
Reviewed-by: Wadim Egorov <[email protected]>
Reviewed-by: Yannic Moog <[email protected]>
Tested-by: Primoz Fiser <[email protected]>
arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi
arch/arm/mach-imx/imx9/Kconfig
arch/arm/mach-imx/imx9/soc.c
board/phytec/common/Kconfig
board/phytec/common/Makefile
board/phytec/common/imx93_som_detection.c [new file with mode: 0644]
board/phytec/common/imx93_som_detection.h [new file with mode: 0644]
board/phytec/phycore_imx93/Kconfig
board/phytec/phycore_imx93/MAINTAINERS
board/phytec/phycore_imx93/phycore-imx93.c
board/phytec/phycore_imx93/spl.c

index 6897c91f4d925a45a28bce824afaeb1ab697d415..702d86f4e03f295419bb8f5669511d2160f061ab 100644 (file)
 &usdhc1 {
        bootph-pre-ram;
        bootph-some-ram;
+       /*
+        * Remove pinctrl assignments once they are added to imx93-phycore-som.dtsi
+        */
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
 };
 
 &usdhc2 {
                        MX93_PAD_ENET2_RD3__GPIO4_IO27                  0x31e
                >;
        };
+
+       /*
+        * Remove pinctrl_usdhc1_100mhz and pinctrl_usdhc1_200mhz once they
+        * are added to imx93-phycore-som.dtsi
+        */
+       /* need to config the SION for data and cmd pad, refer to ERR052021 */
+       pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+               bootph-pre-ram;
+               bootph-some-ram;
+               fsl,pins = <
+                       MX93_PAD_SD1_CLK__USDHC1_CLK            0x17be
+                       MX93_PAD_SD1_CMD__USDHC1_CMD            0x4000139e
+                       MX93_PAD_SD1_DATA0__USDHC1_DATA0        0x4000138e
+                       MX93_PAD_SD1_DATA1__USDHC1_DATA1        0x4000139e
+                       MX93_PAD_SD1_DATA2__USDHC1_DATA2        0x400013be
+                       MX93_PAD_SD1_DATA3__USDHC1_DATA3        0x4000139e
+                       MX93_PAD_SD1_DATA4__USDHC1_DATA4        0x4000139e
+                       MX93_PAD_SD1_DATA5__USDHC1_DATA5        0x4000139e
+                       MX93_PAD_SD1_DATA6__USDHC1_DATA6        0x4000139e
+                       MX93_PAD_SD1_DATA7__USDHC1_DATA7        0x4000139e
+                       MX93_PAD_SD1_STROBE__USDHC1_STROBE      0x179e
+               >;
+       };
+
+       /* need to config the SION for data and cmd pad, refer to ERR052021 */
+       pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+               bootph-pre-ram;
+               bootph-some-ram;
+               fsl,pins = <
+                       MX93_PAD_SD1_CLK__USDHC1_CLK            0x17be
+                       MX93_PAD_SD1_CMD__USDHC1_CMD            0x4000139e
+                       MX93_PAD_SD1_DATA0__USDHC1_DATA0        0x4000139e
+                       MX93_PAD_SD1_DATA1__USDHC1_DATA1        0x400013be
+                       MX93_PAD_SD1_DATA2__USDHC1_DATA2        0x400013be
+                       MX93_PAD_SD1_DATA3__USDHC1_DATA3        0x400013be
+                       MX93_PAD_SD1_DATA4__USDHC1_DATA4        0x400013be
+                       MX93_PAD_SD1_DATA5__USDHC1_DATA5        0x400013be
+                       MX93_PAD_SD1_DATA6__USDHC1_DATA6        0x400013be
+                       MX93_PAD_SD1_DATA7__USDHC1_DATA7        0x400013be
+                       MX93_PAD_SD1_STROBE__USDHC1_STROBE      0x179e
+               >;
+       };
 };
 
 &lpi2c3 {
                        };
                };
        };
+
+       eeprom@50 {
+               bootph-pre-ram;
+               bootph-some-ram;
+               compatible = "atmel,24c32";
+               reg = <0x50>;
+               pagesize = <32>;
+               vcc-supply = <&buck4>;
+       };
 };
index 5c1054138fcc854c4070d410a611be9c8f183463..2465e31d738454eb1f28dd6ec061059d4c3d4c52 100644 (file)
@@ -45,6 +45,8 @@ config TARGET_PHYCORE_IMX93
        bool "phycore_imx93"
        select IMX93
        select IMX9_LPDDR4X
+       select OF_BOARD_FIXUP
+       select OF_BOARD_SETUP
 
 endchoice
 
index 21e0e7dd1e8064d2cda222060c8dda1d7fce2e2d..6837ac82b05159899d294e01a0fabcc064ff82a2 100644 (file)
@@ -634,7 +634,7 @@ static int low_drive_freq_update(void *blob)
        return 0;
 }
 
-#ifdef CONFIG_OF_BOARD_FIXUP
+#if defined(CONFIG_OF_BOARD_FIXUP) && !defined(CONFIG_TARGET_PHYCORE_IMX93)
 #ifndef CONFIG_XPL_BUILD
 int board_fix_fdt(void *fdt)
 {
index f394ace786a1be2715f65b022d88e30c39fbdc1c..bc5511707ac7fcefdb6e63a4b8737d2440402a74 100644 (file)
@@ -19,6 +19,14 @@ config PHYTEC_IMX8M_SOM_DETECTION
          Support of I2C EEPROM based SoM detection. Supported
          for PHYTEC i.MX8MM/i.MX8MP boards
 
+config PHYTEC_IMX93_SOM_DETECTION
+       bool "Support SoM detection for i.MX93 PHYTEC platforms"
+       depends on ARCH_IMX9 && PHYTEC_SOM_DETECTION
+       default y
+       help
+         Support of I2C EEPROM based SoM detection. Supported
+         for PHYTEC i.MX93 based boards
+
 config PHYTEC_AM62_SOM_DETECTION
        bool "Support SoM detection for AM62x PHYTEC platforms"
        depends on (TARGET_PHYCORE_AM62X_A53 || TARGET_PHYCORE_AM62X_R5) && \
index cd78f7686fea49cbc51082da2623c4b979fcd6a7..8126f7356e13a69c856944cd94884439e430a971 100644 (file)
@@ -10,3 +10,4 @@ endif
 obj-y += phytec_som_detection.o phytec_som_detection_blocks.o
 obj-$(CONFIG_ARCH_K3) += am6_som_detection.o k3/
 obj-$(CONFIG_ARCH_IMX8M) += imx8m_som_detection.o
+obj-$(CONFIG_ARCH_IMX9) += imx93_som_detection.o
diff --git a/board/phytec/common/imx93_som_detection.c b/board/phytec/common/imx93_som_detection.c
new file mode 100644 (file)
index 0000000..eb9574d
--- /dev/null
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Primoz Fiser <[email protected]>
+ */
+
+#include <asm/arch/sys_proto.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
+#include <i2c.h>
+#include <u-boot/crc.h>
+
+#include "imx93_som_detection.h"
+
+extern struct phytec_eeprom_data eeprom_data;
+
+#if IS_ENABLED(CONFIG_PHYTEC_IMX93_SOM_DETECTION)
+
+/* Check if the SoM is actually one of the following products:
+ * - i.MX93
+ *
+ * Returns 0 in case it's a known SoM. Otherwise, returns 1.
+ */
+u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data)
+{
+       u8 som;
+
+       if (!data)
+               data = &eeprom_data;
+
+       /* Early API revisions are not supported */
+       if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
+               return 1;
+
+       som = data->payload.data.data_api2.som_no;
+       debug("%s: som id: %u\n", __func__, som);
+
+       if (som == PHYTEC_IMX93_SOM && is_imx93())
+               return 0;
+
+       pr_err("%s: SoM ID does not match. Wrong EEPROM data?\n", __func__);
+       return 1;
+}
+
+/*
+ * Filter PHYTEC i.MX93 SoM options by option index
+ *
+ * Returns:
+ *  - option value
+ *  - PHYTEC_EEPROM_INVAL when the data is invalid
+ *
+ */
+u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data,
+                                      enum phytec_imx93_option_index idx)
+{
+       char *opt;
+       u8 opt_id;
+
+       if (!data)
+               data = &eeprom_data;
+
+       if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
+               return PHYTEC_EEPROM_INVAL;
+
+       opt = phytec_get_opt(data);
+       if (opt)
+               opt_id = PHYTEC_GET_OPTION(opt[idx]);
+       else
+               opt_id = PHYTEC_EEPROM_INVAL;
+
+       debug("%s: opt[%d] id: %u\n", __func__, idx, opt_id);
+       return opt_id;
+}
+
+/*
+ * Filter PHYTEC i.MX93 SoM voltage
+ *
+ * Returns:
+ *  - PHYTEC_IMX93_VOLTAGE_1V8 or PHYTEC_IMX93_VOLTAGE_3V3
+ *  - PHYTEC_EEPROM_INVAL when the data is invalid
+ *
+ */
+enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage(struct phytec_eeprom_data *data)
+{
+       u8 option = phytec_imx93_get_opt(data, PHYTEC_IMX93_OPT_FEAT);
+
+       if (option == PHYTEC_EEPROM_INVAL)
+               return PHYTEC_IMX93_VOLTAGE_INVALID;
+       return (option & 0x01) ? PHYTEC_IMX93_VOLTAGE_1V8 : PHYTEC_IMX93_VOLTAGE_3V3;
+}
+
+#else
+
+inline u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data)
+{
+       return 1;
+}
+
+inline u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data,
+                                             enum phytec_imx93_option_index idx)
+{
+       return PHYTEC_EEPROM_INVAL;
+}
+
+inline enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage
+       (struct phytec_eeprom_data *data)
+{
+       return PHYTEC_EEPROM_INVAL;
+}
+
+#endif /* IS_ENABLED(CONFIG_PHYTEC_IMX93_SOM_DETECTION) */
diff --git a/board/phytec/common/imx93_som_detection.h b/board/phytec/common/imx93_som_detection.h
new file mode 100644 (file)
index 0000000..a0803b4
--- /dev/null
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Primoz Fiser <[email protected]>
+ */
+
+#ifndef _PHYTEC_IMX93_SOM_DETECTION_H
+#define _PHYTEC_IMX93_SOM_DETECTION_H
+
+#include "phytec_som_detection.h"
+
+#define PHYTEC_IMX93_SOM       77
+
+enum phytec_imx93_option_index {
+       PHYTEC_IMX93_OPT_DDR = 0,
+       PHYTEC_IMX93_OPT_EMMC = 1,
+       PHYTEC_IMX93_OPT_CPU = 2,
+       PHYTEC_IMX93_OPT_FREQ = 3,
+       PHYTEC_IMX93_OPT_NPU = 4,
+       PHYTEC_IMX93_OPT_DISP = 5,
+       PHYTEC_IMX93_OPT_ETH = 6,
+       PHYTEC_IMX93_OPT_FEAT = 7,
+       PHYTEC_IMX93_OPT_TEMP = 8,
+       PHYTEC_IMX93_OPT_BOOT = 9,
+       PHYTEC_IMX93_OPT_LED = 10,
+       PHYTEC_IMX93_OPT_EEPROM = 11,
+};
+
+enum phytec_imx93_voltage {
+       PHYTEC_IMX93_VOLTAGE_INVALID = PHYTEC_EEPROM_INVAL,
+       PHYTEC_IMX93_VOLTAGE_3V3 = 0,
+       PHYTEC_IMX93_VOLTAGE_1V8 = 1,
+};
+
+enum phytec_imx93_ddr_eeprom_code {
+       PHYTEC_IMX93_DDR_INVALID = PHYTEC_EEPROM_INVAL,
+       PHYTEC_IMX93_LPDDR4X_512MB = 0,
+       PHYTEC_IMX93_LPDDR4X_1GB = 1,
+       PHYTEC_IMX93_LPDDR4X_2GB = 2,
+       PHYTEC_IMX93_LPDDR4_512MB = 3,
+       PHYTEC_IMX93_LPDDR4_1GB = 4,
+       PHYTEC_IMX93_LPDDR4_2GB = 5,
+};
+
+u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data);
+u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data,
+                                      enum phytec_imx93_option_index idx);
+enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage
+       (struct phytec_eeprom_data *data);
+
+#endif /* _PHYTEC_IMX93_SOM_DETECTION_H */
index a70104cb7981808752c228be647f705975b7cbff..09f26e89e333a24020bd38784af6d7732e4699b9 100644 (file)
@@ -10,4 +10,32 @@ config SYS_VENDOR
 config SYS_CONFIG_NAME
        default "phycore_imx93"
 
+config PHYCORE_IMX93_RAM_TYPE_FIX
+       bool "Set phyCORE-i.MX93 RAM type and size fix instead of detecting"
+       default false
+       help
+         RAM type and size is being automatically detected with the help
+         of the PHYTEC EEPROM introspection data.
+         Set RAM type to a fix value instead.
+
+choice
+       prompt "phyCORE-i.MX93 RAM type"
+       depends on PHYCORE_IMX93_RAM_TYPE_FIX
+       default PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB
+
+config PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB
+       bool "LPDDR4X 1GB RAM"
+       help
+         Set RAM type fixed to LPDDR4X and RAM size fixed to 1GB
+         for phyCORE-i.MX93.
+
+config PHYCORE_IMX93_RAM_TYPE_LPDDR4X_2GB
+       bool "LPDDR4X 2GB RAM"
+       help
+         Set RAM type fixed to LPDDR4X and RAM size fixed to 2GB
+         for phyCORE-i.MX93.
+
+endchoice
+
+source "board/phytec/common/Kconfig"
 endif
index 9e91a29dc3132c7e0af343138cbfb2cfd50da05e..cea817ffdc0b69d051e8c522b60d534aa90c6093 100644 (file)
@@ -1,10 +1,13 @@
 phyCORE-i.MX93
-M:     Mathieu Othacehe <[email protected]>
+M:      Mathieu Othacehe <[email protected]>
+R:      Christoph Stoidner <[email protected]>
 W:      https://www.phytec.eu/en/produkte/system-on-modules/phycore-imx-91-93/
 S:      Maintained
 F:      arch/arm/dts/imx93-phyboard-segin.dts
 F:      arch/arm/dts/imx93-phycore-som.dtsi
 F:      arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi
 F:      board/phytec/phycore_imx93/
+F:      board/phytec/common/imx93_som_detection.c
+F:      board/phytec/common/imx93_som_detection.h
 F:      configs/imx93-phyboard-segin_defconfig
 F:      include/configs/phycore_imx93.h
index 085c8e195a6c1798553cd77f908a350f081e02f6..a55795e06034f21f9188483dd7f76471a9e22568 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (C) 2023 PHYTEC Messtechnik GmbH
  * Author: Christoph Stoidner <[email protected]>
  * Copyright (C) 2024 Mathieu Othacehe <[email protected]>
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
  */
 
 #include <asm/arch-imx9/ccm_regs.h>
 #include <asm/global_data.h>
 #include <asm/mach-imx/boot_mode.h>
 #include <env.h>
+#include <fdt_support.h>
+
+#include "../common/imx93_som_detection.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#define EEPROM_ADDR            0x50
+
 int board_init(void)
 {
+       int ret = phytec_eeprom_data_setup(NULL, 2, EEPROM_ADDR);
+
+       if (ret)
+               printf("%s: EEPROM data init failed\n", __func__);
+
        return 0;
 }
 
@@ -40,3 +51,43 @@ int board_late_init(void)
 
        return 0;
 }
+
+static void emmc_fixup(void *blob, struct phytec_eeprom_data *data)
+{
+       enum phytec_imx93_voltage voltage = phytec_imx93_get_voltage(data);
+       int offset;
+
+       if (voltage == PHYTEC_IMX93_VOLTAGE_INVALID)
+               goto err;
+
+       if (voltage == PHYTEC_IMX93_VOLTAGE_1V8) {
+               offset = fdt_node_offset_by_compat_reg(blob, "fsl,imx93-usdhc",
+                                                      0x42850000);
+               if (offset)
+                       fdt_delprop(blob, offset, "no-1-8-v");
+               else
+                       goto err;
+       }
+
+       return;
+err:
+       printf("Could not detect eMMC VDD-IO. Fall back to default.\n");
+}
+
+int board_fix_fdt(void *blob)
+{
+       struct phytec_eeprom_data data;
+
+       phytec_eeprom_data_setup(&data, 2, EEPROM_ADDR);
+
+       emmc_fixup(blob, &data);
+
+       return 0;
+}
+
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+       emmc_fixup(blob, NULL);
+
+       return 0;
+}
index 17a8736c73ff3406b6ce3deb3484b215abfe9e92..a4d2aaac32040c4f3f6cfc81b024f53af28a6ba4 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (C) 2023 PHYTEC Messtechnik GmbH
  * Author: Christoph Stoidner <[email protected]>
  * Copyright (C) 2024 Mathieu Othacehe <[email protected]>
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
  */
 
 #include <asm/arch/clock.h>
@@ -20,6 +21,8 @@
 #include <power/pca9450.h>
 #include <spl.h>
 
+#include "../common/imx93_som_detection.h"
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -27,6 +30,13 @@ DECLARE_GLOBAL_DATA_PTR;
  * when pca9451a support is added.
  */
 #define PCA9450_REG_PWRCTRL_TOFF_DEB    BIT(5)
+#define EEPROM_ADDR            0x50
+
+/*
+ * Prototypes of automatically generated ram config file
+ */
+void set_dram_timings_2gb_lpddr4x(void);
+void set_dram_timings_1gb_lpddr4x_900mhz(void);
 
 int spl_board_boot_device(enum boot_device boot_dev_spl)
 {
@@ -46,6 +56,44 @@ void spl_board_init(void)
 
 void spl_dram_init(void)
 {
+       int ret;
+       enum phytec_imx93_ddr_eeprom_code ddr_opt = PHYTEC_IMX93_DDR_INVALID;
+
+       /* NOTE: In SPL lpi2c3 is mapped to bus 0 */
+       ret = phytec_eeprom_data_setup(NULL, 0, EEPROM_ADDR);
+       if (ret && !IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_FIX))
+               goto out;
+
+       ret = phytec_imx93_detect(NULL);
+       if (!ret)
+               phytec_print_som_info(NULL);
+
+       if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_FIX)) {
+               if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB))
+                       ddr_opt = PHYTEC_IMX93_LPDDR4X_1GB;
+               else if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_LPDDR4X_2GB))
+                       ddr_opt = PHYTEC_IMX93_LPDDR4X_2GB;
+       } else {
+               ddr_opt = phytec_imx93_get_opt(NULL, PHYTEC_IMX93_OPT_DDR);
+       }
+
+       switch (ddr_opt) {
+       case PHYTEC_IMX93_LPDDR4X_1GB:
+               if (is_voltage_mode(VOLT_LOW_DRIVE))
+                       set_dram_timings_1gb_lpddr4x_900mhz();
+               break;
+       case PHYTEC_IMX93_LPDDR4X_2GB:
+               set_dram_timings_2gb_lpddr4x();
+               break;
+       default:
+               goto out;
+       }
+       ddr_init(&dram_timing);
+       return;
+out:
+       puts("Could not detect correct RAM type and size. Fall back to default.\n");
+       if (is_voltage_mode(VOLT_LOW_DRIVE))
+               set_dram_timings_1gb_lpddr4x_900mhz();
        ddr_init(&dram_timing);
 }
 
This page took 0.056478 seconds and 4 git commands to generate.