board: phytec: common: Add imx8m specific EEPROM detection support

Add imx8m specific detection part. Which includes checking the
EEPROM data for article number options.

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>
This commit is contained in:
Teresa Remmet 2023-08-17 10:57:07 +02:00 committed by Stefano Babic
parent dc22188cdc
commit a9719ef045
4 changed files with 231 additions and 0 deletions

View file

@ -3,3 +3,11 @@ config PHYTEC_SOM_DETECTION
select SPL_CRC8 if SPL
help
Support of I2C EEPROM based SoM detection.
config PHYTEC_IMX8M_SOM_DETECTION
bool "Support SoM detection for i.MX8M PHYTEC platforms"
depends on ARCH_IMX8M && PHYTEC_SOM_DETECTION
default y
help
Support of I2C EEPROM based SoM detection. Supported
for PHYTEC i.MX8MM/i.MX8MP boards

View file

@ -8,3 +8,4 @@ obj- := __dummy__.o
endif
obj-$(CONFIG_PHYTEC_SOM_DETECTION) += phytec_som_detection.o
obj-$(CONFIG_PHYTEC_IMX8M_SOM_DETECTION) += imx8m_som_detection.o

View file

@ -0,0 +1,168 @@
// 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/arch/sys_proto.h>
#include <dm/device.h>
#include <dm/uclass.h>
#include <i2c.h>
#include <u-boot/crc.h>
#include "imx8m_som_detection.h"
extern struct phytec_eeprom_data eeprom_data;
/* Check if the SoM is actually one of the following products:
* - i.MX8MM
* - i.MX8MN
* - i.MX8MP
* - i.MX8MQ
*
* Returns 0 in case it's a known SoM. Otherwise, returns -1.
*/
u8 __maybe_unused phytec_imx8m_detect(struct phytec_eeprom_data *data)
{
char *opt;
u8 som;
/* We can not do the check for early API revisions */
if (data->api_rev < PHYTEC_API_REV2)
return -1;
if (!data)
data = &eeprom_data;
som = data->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_IMX8MP_SOM && is_imx8mp())
return 0;
if (som == PHYTEC_IMX8MM_SOM) {
if ((PHYTEC_GET_OPTION(opt[0]) != 0) &&
(PHYTEC_GET_OPTION(opt[1]) == 0) && is_imx8mm())
return 0;
else if ((PHYTEC_GET_OPTION(opt[0]) == 0) &&
(PHYTEC_GET_OPTION(opt[1]) != 0) && is_imx8mn())
return 0;
}
if (som == PHYTEC_IMX8MQ_SOM && is_imx8mq())
return 0;
pr_err("%s: SoM ID does not match. Wrong EEPROM data?\n", __func__);
return -1;
}
/*
* All PHYTEC i.MX8M boards have RAM size definition at the
* same location.
*/
u8 __maybe_unused phytec_get_imx8m_ddr_size(struct phytec_eeprom_data *data)
{
char *opt;
u8 ddr_id;
if (!data)
data = &eeprom_data;
opt = phytec_get_opt(data);
if (opt)
ddr_id = PHYTEC_GET_OPTION(opt[2]);
else
ddr_id = PHYTEC_EEPROM_INVAL;
debug("%s: ddr id: %u\n", __func__, ddr_id);
return ddr_id;
}
/*
* Filter SPI-NOR flash information. All i.MX8M boards have this at
* the same location.
* returns: 0x0 if no SPI is populated. Otherwise a board depended
* code for the size. PHYTEC_EEPROM_INVAL when the data is invalid.
*/
u8 __maybe_unused phytec_get_imx8m_spi(struct phytec_eeprom_data *data)
{
char *opt;
u8 spi;
if (!data)
data = &eeprom_data;
if (data->api_rev < PHYTEC_API_REV2)
return PHYTEC_EEPROM_INVAL;
opt = phytec_get_opt(data);
if (opt)
spi = PHYTEC_GET_OPTION(opt[4]);
else
spi = PHYTEC_EEPROM_INVAL;
debug("%s: spi: %u\n", __func__, spi);
return spi;
}
/*
* Filter ethernet phy information. All i.MX8M boards have this at
* the same location.
* returns: 0x0 if no ethernet phy is populated. 0x1 if it is populated.
* PHYTEC_EEPROM_INVAL when the data is invalid.
*/
u8 __maybe_unused phytec_get_imx8m_eth(struct phytec_eeprom_data *data)
{
char *opt;
u8 eth;
if (!data)
data = &eeprom_data;
if (data->api_rev < PHYTEC_API_REV2)
return PHYTEC_EEPROM_INVAL;
opt = phytec_get_opt(data);
if (opt) {
eth = PHYTEC_GET_OPTION(opt[5]);
eth &= 0x1;
} else {
eth = PHYTEC_EEPROM_INVAL;
}
debug("%s: eth: %u\n", __func__, eth);
return eth;
}
/*
* Filter RTC information for phyCORE-i.MX8MP.
* returns: 0 if no RTC is populated. 1 if it is populated.
* PHYTEC_EEPROM_INVAL when the data is invalid.
*/
u8 __maybe_unused phytec_get_imx8mp_rtc(struct phytec_eeprom_data *data)
{
char *opt;
u8 rtc;
if (!data)
data = &eeprom_data;
if (data->api_rev < PHYTEC_API_REV2)
return PHYTEC_EEPROM_INVAL;
opt = phytec_get_opt(data);
if (opt) {
rtc = PHYTEC_GET_OPTION(opt[5]);
rtc &= 0x4;
rtc = !(rtc >> 2);
} else {
rtc = PHYTEC_EEPROM_INVAL;
}
debug("%s: rtc: %u\n", __func__, rtc);
return rtc;
}

View file

@ -0,0 +1,54 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2023 PHYTEC Messtechnik GmbH
* Author: Teresa Remmet <t.remmet@phytec.de>
*/
#ifndef _PHYTEC_IMX8M_SOM_DETECTION_H
#define _PHYTEC_IMX8M_SOM_DETECTION_H
#include "phytec_som_detection.h"
#define PHYTEC_IMX8MQ_SOM 66
#define PHYTEC_IMX8MM_SOM 69
#define PHYTEC_IMX8MP_SOM 70
#if IS_ENABLED(CONFIG_PHYTEC_IMX8M_SOM_DETECTION)
u8 __maybe_unused phytec_imx8m_detect(struct phytec_eeprom_data *data);
u8 __maybe_unused phytec_get_imx8m_ddr_size(struct phytec_eeprom_data *data);
u8 __maybe_unused phytec_get_imx8mp_rtc(struct phytec_eeprom_data *data);
u8 __maybe_unused phytec_get_imx8m_spi(struct phytec_eeprom_data *data);
u8 __maybe_unused phytec_get_imx8m_eth(struct phytec_eeprom_data *data);
#else
inline u8 __maybe_unused phytec_imx8m_detect(struct phytec_eeprom_data *data)
{
return -1;
}
inline u8 __maybe_unused
phytec_get_imx8m_ddr_size(struct phytec_eeprom_data *data)
{
return PHYTEC_EEPROM_INVAL;
}
inline u8 __maybe_unused phytec_get_imx8mp_rtc(struct phytec_eeprom_data *data)
{
return PHYTEC_EEPROM_INVAL;
}
inline u8 __maybe_unused phytec_get_imx8m_spi(struct phytec_eeprom_data *data)
{
return PHYTEC_EEPROM_INVAL;
}
inline u8 __maybe_unused phytec_get_imx8m_eth(struct phytec_eeprom_data *data)
{
return PHYTEC_EEPROM_INVAL;
}
#endif /* IS_ENABLED(CONFIG_PHYTEC_IMX8M_SOM_DETECTION) */
#endif /* _PHYTEC_IMX8M_SOM_DETECTION_H */