]> Git Repo - J-u-boot.git/commitdiff
Merge patch series "Update PHYTEC SOM Detection"
authorTom Rini <[email protected]>
Mon, 29 Apr 2024 16:56:05 +0000 (10:56 -0600)
committerTom Rini <[email protected]>
Mon, 29 Apr 2024 16:56:05 +0000 (10:56 -0600)
Daniel Schultz <[email protected]> says:

This patch series extends PHYTEC's SOM detection by minor
fixes, a generic helper function and a new valid flag.

Moreover, it adds a module to provide access to the SOM
detection for our TI AM6 products.

board/phytec/common/Kconfig
board/phytec/common/Makefile
board/phytec/common/am6_som_detection.c [new file with mode: 0644]
board/phytec/common/am6_som_detection.h [new file with mode: 0644]
board/phytec/common/imx8m_som_detection.c
board/phytec/common/phytec_som_detection.c
board/phytec/common/phytec_som_detection.h
board/phytec/phycore_am62x/Kconfig
board/phytec/phycore_am64x/Kconfig

index 3b1c5aa0d02bcc36f307bc9287d13223778d8986..1077f0f4b61abd1aa148ab8c01af4aff5d1fe176 100644 (file)
@@ -11,3 +11,21 @@ config PHYTEC_IMX8M_SOM_DETECTION
        help
          Support of I2C EEPROM based SoM detection. Supported
          for PHYTEC i.MX8MM/i.MX8MP boards
+
+config PHYTEC_AM62_SOM_DETECTION
+       bool "Support SoM detection for AM62x PHYTEC platforms"
+       depends on (TARGET_PHYCORE_AM62X_A53 || TARGET_PHYCORE_AM62X_R5) && \
+                  PHYTEC_SOM_DETECTION
+       default y
+       help
+          Support of I2C EEPROM based SoM detection. Supported
+          for PHYTEC AM62x boards.
+
+config PHYTEC_AM64_SOM_DETECTION
+       bool "Support SoM detection for AM64x PHYTEC platforms"
+       depends on (TARGET_PHYCORE_AM64X_A53 || TARGET_PHYCORE_AM64X_R5) && \
+                  PHYTEC_SOM_DETECTION
+       default y
+       help
+          Support of I2C EEPROM based SoM detection. Supported
+          for PHYTEC AM64x boards.
index 35c817413066d0a6ab733d5e7c376f9ffc40869c..3feb00fd1ecbbcd50c035fc0a75086c914c342af 100644 (file)
@@ -8,4 +8,5 @@ obj- := __dummy__.o
 endif
 
 obj-y += phytec_som_detection.o
+obj-$(CONFIG_ARCH_K3) += am6_som_detection.o
 obj-$(CONFIG_ARCH_IMX8M) += imx8m_som_detection.o
diff --git a/board/phytec/common/am6_som_detection.c b/board/phytec/common/am6_som_detection.c
new file mode 100644 (file)
index 0000000..2e9884d
--- /dev/null
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Daniel Schultz <[email protected]>
+ */
+
+#include <asm/arch/hardware.h>
+
+#include "am6_som_detection.h"
+
+extern struct phytec_eeprom_data eeprom_data;
+
+#if IS_ENABLED(CONFIG_PHYTEC_AM62_SOM_DETECTION) || \
+       IS_ENABLED(CONFIG_PHYTEC_AM64_SOM_DETECTION)
+
+/* Check if the SoM is actually one of the following products:
+ * - phyCORE-AM62x
+ * - phyCORE-AM64x
+ *
+ * Returns 0 in case it's a known SoM. Otherwise, returns -1.
+ */
+int phytec_am6_detect(struct phytec_eeprom_data *data)
+{
+       char *opt;
+       u8 som;
+
+       if (!data)
+               data = &eeprom_data;
+
+       /* We cannot do the check for early API revisions */
+       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);
+
+       opt = phytec_get_opt(data);
+       if (!opt)
+               return -1;
+
+       if (som == PHYTEC_AM62X_SOM && soc_is_am62x())
+               return 0;
+
+       if (som == PHYTEC_AM64X_SOM && soc_is_am64x())
+               return 0;
+
+       return -1;
+}
+
+static u8 phytec_check_opt(struct phytec_eeprom_data *data, u8 option)
+{
+       char *opt;
+
+       if (!data)
+               data = &eeprom_data;
+
+       if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
+               return PHYTEC_EEPROM_INVAL;
+
+       if (option > 8)
+               return PHYTEC_EEPROM_INVAL;
+
+       opt = phytec_get_opt(data);
+       if (opt)
+               return PHYTEC_GET_OPTION(opt[option]);
+       return PHYTEC_EEPROM_INVAL;
+}
+
+/*
+ * Reads LPDDR4 ram size from EEPROM.
+ *
+ * returns:
+ *  - The size
+ *  - PHYTEC_EEPROM_INVAL when the data is invalid.
+ */
+u8 __maybe_unused phytec_get_am62_ddr_size(struct phytec_eeprom_data *data)
+{
+       u8 ddr_id = phytec_check_opt(data, 3);
+
+       pr_debug("%s: ddr id: %u\n", __func__, ddr_id);
+       return ddr_id;
+}
+
+/*
+ * Reads SPI-NOR flash size and type from EEPROM.
+ *
+ * returns:
+ *  - PHYTEC_EEPROM_VALUE_X if no SPI is poulated.
+ *  - Otherwise a board depended code for the size.
+ *  - PHYTEC_EEPROM_INVAL when the data is invalid.
+ */
+u8 __maybe_unused phytec_get_am62_spi(struct phytec_eeprom_data *data)
+{
+       u8 spi = phytec_check_opt(data, 5);
+
+       pr_debug("%s: spi: %u\n", __func__, spi);
+       return spi;
+}
+
+/*
+ * Reads Ethernet phy information from EEPROM.
+ *
+ * returns:
+ *  - 0x0 no ethernet phy is populated.
+ *  - 0x1 if 10/100/1000 MBit Phy is populated.
+ *  - PHYTEC_EEPROM_INVAL when the data is invalid.
+ */
+u8 __maybe_unused phytec_get_am62_eth(struct phytec_eeprom_data *data)
+{
+       u8 eth = phytec_check_opt(data, 6);
+
+       pr_debug("%s: eth: %u\n", __func__, eth);
+       return eth;
+}
+
+/*
+ * Reads RTC information from EEPROM.
+ *
+ * returns:
+ *  - 0 if no RTC is poulated.
+ *  - 1 if it is populated.
+ *  - PHYTEC_EEPROM_INVAL when the data is invalid.
+ */
+u8 __maybe_unused phytec_get_am62_rtc(struct phytec_eeprom_data *data)
+{
+       u8 rtc = phytec_check_opt(data, 7);
+
+       pr_debug("%s: rtc: %u\n", __func__, rtc);
+       return rtc;
+}
+
+#else
+
+inline int __maybe_unused phytec_am62_detect(struct phytec_eeprom_data *data)
+{
+       return -1;
+}
+
+inline u8 __maybe_unused
+phytec_get_am62_ddr_size(struct phytec_eeprom_data *data)
+{
+       return PHYTEC_EEPROM_INVAL;
+}
+
+inline u8 __maybe_unused phytec_get_am62_spi(struct phytec_eeprom_data *data)
+{
+       return PHYTEC_EEPROM_INVAL;
+}
+
+inline u8 __maybe_unused phytec_get_am62_eth(struct phytec_eeprom_data *data)
+{
+       return PHYTEC_EEPROM_INVAL;
+}
+
+inline u8 __maybe_unused phytec_get_am62_rtc(struct phytec_eeprom_data *data)
+{
+       return PHYTEC_EEPROM_INVAL;
+}
+#endif
diff --git a/board/phytec/common/am6_som_detection.h b/board/phytec/common/am6_som_detection.h
new file mode 100644 (file)
index 0000000..032f9da
--- /dev/null
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Daniel Schultz <[email protected]>
+ */
+
+#ifndef _PHYTEC_AM6_SOM_DETECTION_H
+#define _PHYTEC_AM6_SOM_DETECTION_H
+
+#include "phytec_som_detection.h"
+
+#define PHYTEC_AM62X_SOM                       71
+#define PHYTEC_AM64X_SOM                       72
+#define PHYTEC_EEPROM_VALUE_X                  0x21
+#define PHYTEC_EEPROM_NOR_FLASH_64MB_QSPI      0xC
+
+int __maybe_unused phytec_am6_detect(struct phytec_eeprom_data *data);
+u8 __maybe_unused phytec_get_am6_ddr_size(struct phytec_eeprom_data *data);
+u8 __maybe_unused phytec_get_am6_spi(struct phytec_eeprom_data *data);
+u8 __maybe_unused phytec_get_am6_eth(struct phytec_eeprom_data *data);
+u8 __maybe_unused phytec_get_am6_rtc(struct phytec_eeprom_data *data);
+
+static inline int phytec_am6_is_qspi(struct phytec_eeprom_data *data)
+{
+       u8 spi = phytec_get_am6_spi(data);
+
+       if (spi == PHYTEC_EEPROM_VALUE_X)
+               return 0;
+       return spi <= PHYTEC_EEPROM_NOR_FLASH_64MB_QSPI;
+}
+
+static inline int phytec_am6_is_ospi(struct phytec_eeprom_data *data)
+{
+       return phytec_get_am6_spi(data) > PHYTEC_EEPROM_NOR_FLASH_64MB_QSPI;
+}
+#endif /* _PHYTEC_AM6_SOM_DETECTION_H */
index 214b75db3b0e46e7182469606361665ccc6f8bd7..ee34a5b95791d39f645010de6e30ee92120c7248 100644 (file)
@@ -34,10 +34,10 @@ int __maybe_unused phytec_imx8m_detect(struct phytec_eeprom_data *data)
                data = &eeprom_data;
 
        /* We can not do the check for early API revisions */
-       if (data->api_rev < PHYTEC_API_REV2)
+       if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
                return -1;
 
-       som = data->data.data_api2.som_no;
+       som = data->payload.data.data_api2.som_no;
        debug("%s: som id: %u\n", __func__, som);
 
        opt = phytec_get_opt(data);
@@ -75,6 +75,9 @@ u8 __maybe_unused phytec_get_imx8m_ddr_size(struct phytec_eeprom_data *data)
        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)
                ddr_id = PHYTEC_GET_OPTION(opt[2]);
@@ -99,7 +102,7 @@ u8 __maybe_unused phytec_get_imx8m_spi(struct phytec_eeprom_data *data)
        if (!data)
                data = &eeprom_data;
 
-       if (data->api_rev < PHYTEC_API_REV2)
+       if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
                return PHYTEC_EEPROM_INVAL;
 
        opt = phytec_get_opt(data);
@@ -126,7 +129,7 @@ u8 __maybe_unused phytec_get_imx8m_eth(struct phytec_eeprom_data *data)
        if (!data)
                data = &eeprom_data;
 
-       if (data->api_rev < PHYTEC_API_REV2)
+       if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
                return PHYTEC_EEPROM_INVAL;
 
        opt = phytec_get_opt(data);
@@ -154,7 +157,7 @@ u8 __maybe_unused phytec_get_imx8mp_rtc(struct phytec_eeprom_data *data)
        if (!data)
                data = &eeprom_data;
 
-       if (data->api_rev < PHYTEC_API_REV2)
+       if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
                return PHYTEC_EEPROM_INVAL;
 
        opt = phytec_get_opt(data);
index a56e0f60d6289a4f2d07ad0ee687f45652b92c6e..78c173df20d44c415d9ba8a3460e63e489452e3a 100644 (file)
@@ -9,6 +9,8 @@
 #include <dm/uclass.h>
 #include <i2c.h>
 #include <u-boot/crc.h>
+#include <malloc.h>
+#include <extension_board.h>
 
 #include "phytec_som_detection.h"
 
@@ -51,7 +53,8 @@ int phytec_eeprom_data_init(struct phytec_eeprom_data *data,
 {
        int ret, i;
        unsigned int crc;
-       int *ptr;
+       u8 *ptr;
+       const unsigned int payload_size = sizeof(struct phytec_eeprom_payload);
 
        if (!data)
                data = &eeprom_data;
@@ -62,14 +65,13 @@ int phytec_eeprom_data_init(struct phytec_eeprom_data *data,
        ret = i2c_get_chip_for_busnum(bus_num, addr, 2, &dev);
        if (ret) {
                pr_err("%s: i2c EEPROM not found: %i.\n", __func__, ret);
-               return ret;
+               goto err;
        }
 
-       ret = dm_i2c_read(dev, 0, (uint8_t *)data,
-                         sizeof(struct phytec_eeprom_data));
+       ret = dm_i2c_read(dev, 0, (uint8_t *)data, payload_size);
        if (ret) {
-               pr_err("%s: Unable to read EEPROM data\n", __func__);
-               return ret;
+               pr_err("%s: Unable to read EEPROM data: %i\n", __func__, ret);
+               goto err;
        }
 #else
        i2c_set_bus_num(bus_num);
@@ -77,36 +79,44 @@ int phytec_eeprom_data_init(struct phytec_eeprom_data *data,
                       sizeof(struct phytec_eeprom_data));
 #endif
 
-       if (data->api_rev == 0xff) {
+       if (data->payload.api_rev == 0xff) {
                pr_err("%s: EEPROM is not flashed. Prototype?\n", __func__);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err;
        }
 
-       ptr = (int *)data;
-       for (i = 0; i < sizeof(struct phytec_eeprom_data); i++)
+       ptr = (u8 *)data;
+       for (i = 0; i < payload_size; ++i)
                if (ptr[i] != 0x0)
                        break;
 
-       if (i == sizeof(struct phytec_eeprom_data)) {
+       if (i == payload_size) {
                pr_err("%s: EEPROM data is all zero. Erased?\n", __func__);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err;
        }
 
        /* We are done here for early revisions */
-       if (data->api_rev <= PHYTEC_API_REV1)
+       if (data->payload.api_rev <= PHYTEC_API_REV1) {
+               data->valid = true;
                return 0;
+       }
 
-       crc = crc8(0, (const unsigned char *)data,
-                  sizeof(struct phytec_eeprom_data));
+       crc = crc8(0, (const unsigned char *)&data->payload, payload_size);
        debug("%s: crc: %x\n", __func__, crc);
 
        if (crc) {
-               pr_err("%s: CRC mismatch. EEPROM data is not usable\n",
+               pr_err("%s: CRC mismatch. EEPROM data is not usable.\n",
                       __func__);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err;
        }
 
+       data->valid = true;
        return 0;
+err:
+       data->valid = false;
+       return ret;
 }
 
 void __maybe_unused phytec_print_som_info(struct phytec_eeprom_data *data)
@@ -118,10 +128,10 @@ void __maybe_unused phytec_print_som_info(struct phytec_eeprom_data *data)
        if (!data)
                data = &eeprom_data;
 
-       if (data->api_rev < PHYTEC_API_REV2)
+       if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
                return;
 
-       api2 = &data->data.data_api2;
+       api2 = &data->payload.data.data_api2;
 
        /* Calculate PCB subrevision */
        pcb_sub_rev = api2->pcb_sub_opt_rev & 0x0f;
@@ -180,10 +190,13 @@ char * __maybe_unused phytec_get_opt(struct phytec_eeprom_data *data)
        if (!data)
                data = &eeprom_data;
 
-       if (data->api_rev < PHYTEC_API_REV2)
-               opt = data->data.data_api0.opt;
+       if (!data->valid)
+               return NULL;
+
+       if (data->payload.api_rev < PHYTEC_API_REV2)
+               opt = data->payload.data.data_api0.opt;
        else
-               opt = data->data.data_api2.opt;
+               opt = data->payload.data.data_api2.opt;
 
        return opt;
 }
@@ -195,10 +208,10 @@ u8 __maybe_unused phytec_get_rev(struct phytec_eeprom_data *data)
        if (!data)
                data = &eeprom_data;
 
-       if (data->api_rev < PHYTEC_API_REV2)
+       if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
                return PHYTEC_EEPROM_INVAL;
 
-       api2 = &data->data.data_api2;
+       api2 = &data->payload.data.data_api2;
 
        return api2->pcb_rev;
 }
@@ -207,12 +220,35 @@ u8 __maybe_unused phytec_get_som_type(struct phytec_eeprom_data *data)
 {
        if (!data)
                data = &eeprom_data;
-       if (data->api_rev < PHYTEC_API_REV2)
+
+       if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
                return PHYTEC_EEPROM_INVAL;
 
-       return data->data.data_api2.som_type;
+       return data->payload.data.data_api2.som_type;
 }
 
+#if IS_ENABLED(CONFIG_CMD_EXTENSION)
+struct extension *phytec_add_extension(const char *name, const char *overlay,
+                                      const char *other)
+{
+       struct extension *extension;
+
+       if (strlen(overlay) > sizeof(extension->overlay)) {
+               pr_err("Overlay name %s is longer than %lu.\n", overlay,
+                      sizeof(extension->overlay));
+               return NULL;
+       }
+
+       extension = calloc(1, sizeof(struct extension));
+       snprintf(extension->name, sizeof(extension->name), name);
+       snprintf(extension->overlay, sizeof(extension->overlay), overlay);
+       snprintf(extension->other, sizeof(extension->other), other);
+       snprintf(extension->owner, sizeof(extension->owner), "PHYTEC");
+
+       return extension;
+}
+#endif /* IS_ENABLED(CONFIG_CMD_EXTENSION) */
+
 #else
 
 inline int phytec_eeprom_data_setup(struct phytec_eeprom_data *data,
@@ -253,4 +289,13 @@ u8 __maybe_unused phytec_get_som_type(struct phytec_eeprom_data *data)
        return PHYTEC_EEPROM_INVAL;
 }
 
+#if IS_ENABLED(CONFIG_CMD_EXTENSION)
+inline struct extension *phytec_add_extension(const char *name,
+                                             const char *overlay,
+                                             const char *other)
+{
+       return NULL;
+}
+#endif /* IS_ENABLED(CONFIG_CMD_EXTENSION) */
+
 #endif /* IS_ENABLED(CONFIG_PHYTEC_SOM_DETECTION) */
index 7edbfa3ca5c65f4503e008a8007c32d870bd03ab..0ad5c14ef4e25cdd60aa0285efd01e0d85faf3ac 100644 (file)
@@ -55,7 +55,7 @@ struct phytec_api2_data {
        u8 crc8;                /* checksum */
 } __packed;
 
-struct phytec_eeprom_data {
+struct phytec_eeprom_payload {
        u8 api_rev;
        union {
                struct phytec_api0_data data_api0;
@@ -63,17 +63,27 @@ struct phytec_eeprom_data {
        } data;
 } __packed;
 
+struct phytec_eeprom_data {
+       struct phytec_eeprom_payload payload;
+       bool valid;
+};
+
 int phytec_eeprom_data_setup_fallback(struct phytec_eeprom_data *data,
                                      int bus_num, int addr,
                                      int addr_fallback);
 int phytec_eeprom_data_setup(struct phytec_eeprom_data *data,
                             int bus_num, int addr);
-int phytec_eeprom_data_init(struct phytec_eeprom_data *data,
-                           int bus_num, int addr);
+int phytec_eeprom_data_init(struct phytec_eeprom_data *data, int bus_num,
+                           int addr);
 void __maybe_unused phytec_print_som_info(struct phytec_eeprom_data *data);
 
 char * __maybe_unused phytec_get_opt(struct phytec_eeprom_data *data);
 u8 __maybe_unused phytec_get_rev(struct phytec_eeprom_data *data);
 u8 __maybe_unused phytec_get_som_type(struct phytec_eeprom_data *data);
 
+#if IS_ENABLED(CONFIG_CMD_EXTENSION)
+struct extension *phytec_add_extension(const char *name, const char *overlay,
+                                      const char *other);
+#endif /* IS_ENABLED(CONFIG_CMD_EXTENSION) */
+
 #endif /* _PHYTEC_SOM_DETECTION_H */
index b64c34513899c8c0bfa5c527a37831c59411e270..1de8850c6c4644ff6f40b46b915827b6ed7301d0 100644 (file)
@@ -14,6 +14,8 @@ config SYS_VENDOR
 config SYS_CONFIG_NAME
        default "phycore_am62x"
 
+source "board/phytec/common/Kconfig"
+
 endif
 
 if TARGET_PHYCORE_AM62X_R5
@@ -30,4 +32,6 @@ config SYS_CONFIG_NAME
 config SPL_LDSCRIPT
        default "arch/arm/mach-omap2/u-boot-spl.lds"
 
+source "board/phytec/common/Kconfig"
+
 endif
index 427adb6fedd0951cbe8136b4d76746ecba2e03e2..829526c3295bb811023bb3ae49fa3dc9afeb8e35 100644 (file)
@@ -17,6 +17,8 @@ config SYS_VENDOR
 config SYS_CONFIG_NAME
        default "phycore_am64x"
 
+source "board/phytec/common/Kconfig"
+
 endif
 
 if TARGET_PHYCORE_AM64X_R5
@@ -30,4 +32,6 @@ config SYS_VENDOR
 config SYS_CONFIG_NAME
        default "phycore_am64x"
 
+source "board/phytec/common/Kconfig"
+
 endif
This page took 0.056172 seconds and 4 git commands to generate.