summaryrefslogtreecommitdiffstats
path: root/common/boards/phytec/phytec-som-imx8m-detection.c
blob: 495896f5b2c6e1458dc4aad2f013f66c73e88786 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2020 PHYTEC Messtechnik GmbH
 * Author: Teresa Remmet <t.remmet@phytec.de>
 */

#include <boards/phytec/phytec-som-imx8m-detection.h>
#include <common.h>
#include <mach/imx/generic.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 -errno.
 */
int phytec_imx8m_detect(u8 som, const char *opt, u8 cpu_type)
{
	if (som == PHYTEC_IMX8MP_SOM && cpu_type == IMX_CPU_IMX8MP)
		return 0;

	if (som == PHYTEC_IMX8MM_SOM) {
		if (((opt[0] - '0') != 0) &&
		    ((opt[1] - '0') == 0) && cpu_type == IMX_CPU_IMX8MM)
			return 0;
		else if (((opt[0] - '0') == 0) &&
			 ((opt[1] - '0') != 0) && cpu_type == IMX_CPU_IMX8MN)
			return 0;
		return -EINVAL;
	}

	if (som == PHYTEC_IMX8MQ_SOM && cpu_type == IMX_CPU_IMX8MQ)
		return 0;

	return -EINVAL;
}

/*
 * So far all PHYTEC i.MX8M boards have RAM size definition at the
 * same location.
 */
enum phytec_imx8m_ddr_size phytec_get_imx8m_ddr_size(const struct phytec_eeprom_data *data)
{
	const char *opt;
	u8 ddr_id;

	if (!data)
		data = &eeprom_data;

	opt = phytec_get_opt(data);
	if (opt)
		ddr_id = opt[2] - '0';
	else
		ddr_id = PHYTEC_IMX8M_DDR_AUTODETECT;

	pr_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 phytec_get_imx8m_spi(const struct phytec_eeprom_data *data)
{
	const 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 = opt[4] - '0';
	else
		spi = PHYTEC_EEPROM_INVAL;

	pr_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 poulated. 0x1 if it is populated.
 * PHYTEC_EEPROM_INVAL when the data is invalid.
 */
u8 phytec_get_imx8m_eth(const struct phytec_eeprom_data *data)
{
	const 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 = opt[5] - '0';
		eth &= 0x1;
	} else {
		eth = PHYTEC_EEPROM_INVAL;
	}

	pr_debug("%s: eth: %u\n", __func__, eth);

	return eth;
}

/*
 * Filter RTC information.
 * returns: 0 if no RTC is poulated. 1 if it is populated.
 * PHYTEC_EEPROM_INVAL when the data is invalid.
 */
u8 phytec_get_imx8mp_rtc(const struct phytec_eeprom_data *data)
{
	const 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 = opt[5] - '0';
		rtc &= 0x4;
		rtc = !(rtc >> 2);
	} else {
		rtc = PHYTEC_EEPROM_INVAL;
	}

	pr_debug("%s: rtc: %u\n", __func__, rtc);

	return rtc;
}