public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Yannic Moog <Y.Moog@phytec.de>
To: "festevam@gmail.com" <festevam@gmail.com>,
	"uboot-imx@nxp.com" <uboot-imx@nxp.com>,
	"sbabic@denx.de" <sbabic@denx.de>,
	Teresa Remmet <T.Remmet@phytec.de>
Cc: "upstream@lists.phytec.de" <upstream@lists.phytec.de>,
	"u-boot@lists.denx.de" <u-boot@lists.denx.de>,
	Daniel Schultz <D.Schultz@phytec.de>,
	Wadim Egorov <W.Egorov@phytec.de>
Subject: Re: [PATCH v2 1/6] board: phytec: Add common PHYTEC SoM detection
Date: Mon, 28 Aug 2023 12:32:05 +0000	[thread overview]
Message-ID: <c3ae2eca245851ac7f7395edd19f91af7eab4dfd.camel@phytec.de> (raw)
In-Reply-To: <20230817085711.45339-2-t.remmet@phytec.de>

On Thu, 2023-08-17 at 10:57 +0200, Teresa Remmet wrote:
> Recent shipped PHYTEC SoMs come with an i2c  EEPROM containing
> information about the hardware such as board revision and variant.
> This can be used for RAM detection and loading device tree overlays
> during kernel start.
> 
> Signed-off-by: Teresa Remmet <t.remmet@phytec.de>

Reviewed-by: Yannic Moog <y.moog@phytec.de>
Tested-by: Yannic Moog <y.moog@phytec.de>

> ---
> Changes in v2:
> - none
> ---
>  board/phytec/common/Kconfig                |   5 +
>  board/phytec/common/Makefile               |  10 ++
>  board/phytec/common/phytec_som_detection.c | 188
> +++++++++++++++++++++
>  board/phytec/common/phytec_som_detection.h | 104 ++++++++++++
>  4 files changed, 307 insertions(+)
>  create mode 100644 board/phytec/common/Kconfig
>  create mode 100644 board/phytec/common/Makefile
>  create mode 100644 board/phytec/common/phytec_som_detection.c
>  create mode 100644 board/phytec/common/phytec_som_detection.h
> 
> diff --git a/board/phytec/common/Kconfig b/board/phytec/common/Kconfig
> new file mode 100644
> index 000000000000..d614d45b1d60
> --- /dev/null
> +++ b/board/phytec/common/Kconfig
> @@ -0,0 +1,5 @@
> +config PHYTEC_SOM_DETECTION
> +       bool "Support SoM detection for PHYTEC platforms"
> +       select SPL_CRC8 if SPL
> +       help
> +          Support of I2C EEPROM based SoM detection.
> diff --git a/board/phytec/common/Makefile
> b/board/phytec/common/Makefile
> new file mode 100644
> index 000000000000..5fe8725ef684
> --- /dev/null
> +++ b/board/phytec/common/Makefile
> @@ -0,0 +1,10 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +# Copyright (C) 2023 PHYTEC Messtechnik GmbH
> +# Author: Teresa Remmet <t.remmet@phytec.de>
> +
> +ifdef CONFIG_SPL_BUILD
> +# necessary to create built-in.o
> +obj- := __dummy__.o
> +endif
> +
> +obj-$(CONFIG_PHYTEC_SOM_DETECTION) += phytec_som_detection.o
> diff --git a/board/phytec/common/phytec_som_detection.c
> b/board/phytec/common/phytec_som_detection.c
> new file mode 100644
> index 000000000000..366bdd4ace4b
> --- /dev/null
> +++ b/board/phytec/common/phytec_som_detection.c
> @@ -0,0 +1,188 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2023 PHYTEC Messtechnik GmbH
> + * Author: Teresa Remmet <t.remmet@phytec.de>
> + */
> +
> +#include <common.h>
> +#include <asm/mach-imx/mxc_i2c.h>
> +#include <asm/arch/sys_proto.h>
> +#include <dm/device.h>
> +#include <dm/uclass.h>
> +#include <i2c.h>
> +#include <u-boot/crc.h>
> +
> +#include "phytec_som_detection.h"
> +
> +struct phytec_eeprom_data eeprom_data;
> +
> +int phytec_eeprom_data_setup_fallback(struct phytec_eeprom_data
> *data,
> +                                     int bus_num, int addr, int
> addr_fallback)
> +{
> +       int ret;
> +
> +       ret = phytec_eeprom_data_init(data, bus_num, addr);
> +       if (ret) {
> +               pr_err("%s: init failed. Trying fall back address
> 0x%x\n",
> +                      __func__, addr_fallback);
> +               ret = phytec_eeprom_data_init(data, bus_num,
> addr_fallback);
> +       }
> +
> +       if (ret)
> +               pr_err("%s: EEPROM data init failed\n", __func__);
> +
> +       return ret;
> +}
> +
> +int phytec_eeprom_data_setup(struct phytec_eeprom_data *data,
> +                            int bus_num, int addr)
> +{
> +       int ret;
> +
> +       ret = phytec_eeprom_data_init(data, bus_num, addr);
> +       if (ret)
> +               pr_err("%s: EEPROM data init failed\n", __func__);
> +
> +       return ret;
> +}
> +
> +int phytec_eeprom_data_init(struct phytec_eeprom_data *data,
> +                           int bus_num, int addr)
> +{
> +       int ret, i;
> +       unsigned int crc;
> +       int *ptr;
> +
> +       if (!data)
> +               data = &eeprom_data;
> +
> +#if CONFIG_IS_ENABLED(DM_I2C)
> +       struct udevice *dev;
> +
> +       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;
> +       }
> +
> +       ret = dm_i2c_read(dev, 0, (uint8_t *)data,
> +                         sizeof(struct phytec_eeprom_data));
> +       if (ret) {
> +               pr_err("%s: Unable to read EEPROM data\n", __func__);
> +               return ret;
> +       }
> +#else
> +       i2c_set_bus_num(bus_num);
> +       ret = i2c_read(addr, 0, 2, (uint8_t *)data,
> +                      sizeof(struct phytec_eeprom_data));
> +#endif
> +
> +       if (data->api_rev == 0xff) {
> +               pr_err("%s: EEPROM is not flashed. Prototype?\n",
> __func__);
> +               return -EINVAL;
> +       }
> +
> +       ptr = (int *)data;
> +       for (i = 0; i < sizeof(struct phytec_eeprom_data); i +=
> sizeof(ptr))
> +               if (*ptr != 0x0)
> +                       break;
> +
> +       if (i == sizeof(struct phytec_eeprom_data)) {
> +               pr_err("%s: EEPROM data is all zero. Erased?\n",
> __func__);
> +               return -EINVAL;
> +       }
> +
> +       /* We are done here for early revisions */
> +       if (data->api_rev <= PHYTEC_API_REV1)
> +               return 0;
> +
> +       crc = crc8(0, (const unsigned char *)data,
> +                  sizeof(struct phytec_eeprom_data));
> +       debug("%s: crc: %x\n", __func__, crc);
> +
> +       if (crc) {
> +               pr_err("%s: CRC mismatch. EEPROM data is not
> usable\n",
> +                      __func__);
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +void __maybe_unused phytec_print_som_info(struct phytec_eeprom_data
> *data)
> +{
> +       struct phytec_api2_data *api2;
> +       char pcb_sub_rev;
> +       unsigned int ksp_no, sub_som_type1, sub_som_type2;
> +
> +       if (!data)
> +               data = &eeprom_data;
> +
> +       if (data->api_rev < PHYTEC_API_REV2)
> +               return;
> +
> +       api2 = &data->data.data_api2;
> +
> +       /* Calculate PCB subrevision */
> +       pcb_sub_rev = api2->pcb_sub_opt_rev & 0x0f;
> +       pcb_sub_rev = pcb_sub_rev ? ((pcb_sub_rev - 1) + 'a') : ' ';
> +
> +       /* print standard product string */
> +       if (api2->som_type <= 1) {
> +               printf("SoM: %s-%03u-%s.%s PCB rev: %u%c\n",
> +                      phytec_som_type_str[api2->som_type], api2-
> >som_no,
> +                      api2->opt, api2->bom_rev, api2->pcb_rev,
> pcb_sub_rev);
> +               return;
> +       }
> +       /* print KSP/KSM string */
> +       if (api2->som_type <= 3) {
> +               ksp_no = (api2->ksp_no << 8) | api2->som_no;
> +               printf("SoM: %s-%u ",
> +                      phytec_som_type_str[api2->som_type], ksp_no);
> +       /* print standard product based KSP/KSM strings */
> +       } else {
> +               switch (api2->som_type) {
> +               case 4:
> +                       sub_som_type1 = 0;
> +                       sub_som_type2 = 3;
> +                       break;
> +               case 5:
> +                       sub_som_type1 = 0;
> +                       sub_som_type2 = 2;
> +                       break;
> +               case 6:
> +                       sub_som_type1 = 1;
> +                       sub_som_type2 = 3;
> +                       break;
> +               case 7:
> +                       sub_som_type1 = 1;
> +                       sub_som_type2 = 2;
> +                       break;
> +               default:
> +                       break;
> +               };
> +
> +               printf("SoM: %s-%03u-%s-%03u ",
> +                      phytec_som_type_str[sub_som_type1],
> +                      api2->som_no,
> phytec_som_type_str[sub_som_type2],
> +                      api2->ksp_no);
> +       }
> +
> +       printf("Option: %s BOM rev: %s PCB rev: %u%c\n", api2->opt,
> +              api2->bom_rev, api2->pcb_rev, pcb_sub_rev);
> +}
> +
> +char * __maybe_unused phytec_get_opt(struct phytec_eeprom_data *data)
> +{
> +       char *opt;
> +
> +       if (!data)
> +               data = &eeprom_data;
> +
> +       if (data->api_rev < PHYTEC_API_REV2)
> +               opt = data->data.data_api0.opt;
> +       else
> +               opt = data->data.data_api2.opt;
> +
> +       return opt;
> +}
> diff --git a/board/phytec/common/phytec_som_detection.h
> b/board/phytec/common/phytec_som_detection.h
> new file mode 100644
> index 000000000000..01f7e4652ddb
> --- /dev/null
> +++ b/board/phytec/common/phytec_som_detection.h
> @@ -0,0 +1,104 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2023 PHYTEC Messtechnik GmbH
> + * Author: Teresa Remmet <t.remmet@phytec.de>
> + */
> +
> +#ifndef _PHYTEC_SOM_DETECTION_H
> +#define _PHYTEC_SOM_DETECTION_H
> +
> +#define PHYTEC_MAX_OPTIONS     17
> +#define PHYTEC_EEPROM_INVAL    0xff
> +
> +#define PHYTEC_GET_OPTION(option) \
> +       (((option) > '9') ? (option) - 'A' + 10 : (option) - '0')
> +
> +enum {
> +       PHYTEC_API_REV0 = 0,
> +       PHYTEC_API_REV1,
> +       PHYTEC_API_REV2,
> +};
> +
> +static const char * const phytec_som_type_str[] = {
> +       "PCM",
> +       "PCL",
> +       "KSM",
> +       "KSP",
> +};
> +
> +struct phytec_api0_data {
> +       u8 pcb_rev;             /* PCB revision of SoM */
> +       u8 som_type;            /* SoM type */
> +       u8 ksp_no;              /* KSP no */
> +       char opt[16];           /* SoM options */
> +       u8 mac[6];              /* MAC address (optional) */
> +       u8 pad[5];              /* padding */
> +       u8 cksum;               /* checksum */
> +} __packed;
> +
> +struct phytec_api2_data {
> +       u8 pcb_rev;             /* PCB revision of SoM */
> +       u8 pcb_sub_opt_rev;     /* PCB subrevision and opt revision */
> +       u8 som_type;            /* SoM type */
> +       u8 som_no;              /* SoM number */
> +       u8 ksp_no;              /* KSP information */
> +       char opt[PHYTEC_MAX_OPTIONS]; /* SoM options */
> +       char bom_rev[2];        /* BOM revision */
> +       u8 mac[6];              /* MAC address (optional) */
> +       u8 crc8;                /* checksum */
> +} __packed;
> +
> +struct phytec_eeprom_data {
> +       u8 api_rev;
> +       union {
> +               struct phytec_api0_data data_api0;
> +               struct phytec_api2_data data_api2;
> +       } data;
> +} __packed;
> +
> +#if IS_ENABLED(CONFIG_PHYTEC_SOM_DETECTION)
> +
> +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);
> +void __maybe_unused phytec_print_som_info(struct phytec_eeprom_data
> *data);
> +
> +char * __maybe_unused phytec_get_opt(struct phytec_eeprom_data
> *data);
> +
> +#else
> +
> +inline int phytec_eeprom_data_setup(struct phytec_eeprom_data *data,
> +                                   int bus_num, int addr)
> +{
> +       return PHYTEC_EEPROM_INVAL;
> +}
> +
> +inline int phytec_eeprom_data_setup_fallback(struct
> phytec_eeprom_data *data,
> +                                            int bus_num, int addr,
> +                                            int addr_fallback)
> +{
> +       return PHYTEC_EEPROM_INVAL;
> +}
> +
> +inline int phytec_eeprom_data_init(struct phytec_eeprom_data *data,
> +                                  int bus_num, int addr)
> +{
> +       return PHYTEC_EEPROM_INVAL;
> +}
> +
> +inline void __maybe_unused phytec_print_som_info(struct
> phytec_eeprom_data *data)
> +{
> +}
> +
> +inline char *__maybe_unused phytec_get_opt(struct phytec_eeprom_data
> *data)
> +{
> +       return NULL;
> +}
> +
> +#endif /* IS_ENABLED(CONFIG_PHYTEC_SOM_DETECTION) */
> +
> +#endif /* _PHYTEC_SOM_DETECTION_H */


  reply	other threads:[~2023-08-28 12:32 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-17  8:57 [PATCH v2 0/6] PHYTEC SoM detection for phyCORE-i.MX8MP Teresa Remmet
2023-08-17  8:57 ` [PATCH v2 1/6] board: phytec: Add common PHYTEC SoM detection Teresa Remmet
2023-08-28 12:32   ` Yannic Moog [this message]
2023-10-07 13:00     ` Fabio Estevam
2023-08-17  8:57 ` [PATCH v2 2/6] board: phytec: common: Add imx8m specific EEPROM detection support Teresa Remmet
2023-08-28 12:32   ` Yannic Moog
2023-08-17  8:57 ` [PATCH v2 3/6] board: phytec: phycore-imx8mp: Add EEPROM detection initialisation Teresa Remmet
2023-08-28 12:32   ` Yannic Moog
2023-08-17  8:57 ` [PATCH v2 4/6] board: phytec: phycore_imx8mp: Update 2GB RAM Timings Teresa Remmet
2023-08-28 12:33   ` Yannic Moog
2023-08-17  8:57 ` [PATCH v2 5/6] board: phytec: common: phytec_som_detection: Add helper for PCB revision Teresa Remmet
2023-08-28 12:33   ` Yannic Moog
2023-08-17  8:57 ` [PATCH v2 6/6] board: phytec: phycore_imx8mp: Add 4000MTS RAM timings based on PCB rev Teresa Remmet
2023-08-28 12:33   ` Yannic Moog
2023-08-24 11:52 ` [PATCH v2 0/6] PHYTEC SoM detection for phyCORE-i.MX8MP Fabio Estevam
2023-08-25 11:46   ` Yannic Moog
  -- strict thread matches above, loose matches on Subject: below --
2023-10-16 11:50 [PATCH v2 1/6] board: phytec: Add common PHYTEC SoM detection sbabic

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c3ae2eca245851ac7f7395edd19f91af7eab4dfd.camel@phytec.de \
    --to=y.moog@phytec.de \
    --cc=D.Schultz@phytec.de \
    --cc=T.Remmet@phytec.de \
    --cc=W.Egorov@phytec.de \
    --cc=festevam@gmail.com \
    --cc=sbabic@denx.de \
    --cc=u-boot@lists.denx.de \
    --cc=uboot-imx@nxp.com \
    --cc=upstream@lists.phytec.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox