Add all functions to read each SOM option from the EEPROM
image and detect whether it's the correct product for this
image.

Signed-off-by: Daniel Schultz <d.schu...@phytec.de>
---
 board/phytec/common/Kconfig             |  18 +++
 board/phytec/common/Makefile            |   1 +
 board/phytec/common/am6_som_detection.c | 159 ++++++++++++++++++++++++
 board/phytec/common/am6_som_detection.h |  36 ++++++
 board/phytec/phycore_am62x/Kconfig      |   4 +
 board/phytec/phycore_am64x/Kconfig      |   4 +
 6 files changed, 222 insertions(+)
 create mode 100644 board/phytec/common/am6_som_detection.c
 create mode 100644 board/phytec/common/am6_som_detection.h

diff --git a/board/phytec/common/Kconfig b/board/phytec/common/Kconfig
index 3b1c5aa0d02..1077f0f4b61 100644
--- a/board/phytec/common/Kconfig
+++ b/board/phytec/common/Kconfig
@@ -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.
diff --git a/board/phytec/common/Makefile b/board/phytec/common/Makefile
index 35c81741306..3feb00fd1ec 100644
--- a/board/phytec/common/Makefile
+++ b/board/phytec/common/Makefile
@@ -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
index 00000000000..2e9884dab44
--- /dev/null
+++ b/board/phytec/common/am6_som_detection.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Daniel Schultz <d.schu...@phytec.de>
+ */
+
+#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
index 00000000000..032f9da3aab
--- /dev/null
+++ b/board/phytec/common/am6_som_detection.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Daniel Schultz <d.schu...@phytec.de>
+ */
+
+#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 */
diff --git a/board/phytec/phycore_am62x/Kconfig 
b/board/phytec/phycore_am62x/Kconfig
index b64c3451389..1de8850c6c4 100644
--- a/board/phytec/phycore_am62x/Kconfig
+++ b/board/phytec/phycore_am62x/Kconfig
@@ -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
diff --git a/board/phytec/phycore_am64x/Kconfig 
b/board/phytec/phycore_am64x/Kconfig
index 427adb6fedd..829526c3295 100644
--- a/board/phytec/phycore_am64x/Kconfig
+++ b/board/phytec/phycore_am64x/Kconfig
@@ -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
-- 
2.25.1

Reply via email to