mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-04 05:50:17 +00:00 
			
		
		
		
	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>
		
			
				
	
	
		
			169 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// 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;
 | 
						|
}
 |