// 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;

#if IS_ENABLED(CONFIG_PHYTEC_IMX8M_SOM_DETECTION)

/* 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.
 */
int __maybe_unused phytec_imx8m_detect(struct phytec_eeprom_data *data)
{
	char *opt;
	u8 som;

	if (!data)
		data = &eeprom_data;

	/* We can not 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_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;

	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]);
	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->valid || data->payload.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->valid || data->payload.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->valid || data->payload.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;
}

#else

inline int __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) */
