blob: bfd60ffb777307ecad2aad626386733c6099bebd [file] [log] [blame]
Teresa Remmetc6dd9c62023-08-17 10:57:07 +02001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2023 PHYTEC Messtechnik GmbH
4 * Author: Teresa Remmet <t.remmet@phytec.de>
5 */
6
Teresa Remmetc6dd9c62023-08-17 10:57:07 +02007#include <asm/arch/sys_proto.h>
8#include <dm/device.h>
9#include <dm/uclass.h>
10#include <i2c.h>
11#include <u-boot/crc.h>
12
13#include "imx8m_som_detection.h"
14
15extern struct phytec_eeprom_data eeprom_data;
16
Yannic Moog5dd7f7c2023-12-20 09:45:35 +010017#if IS_ENABLED(CONFIG_PHYTEC_IMX8M_SOM_DETECTION)
18
Teresa Remmetc6dd9c62023-08-17 10:57:07 +020019/* Check if the SoM is actually one of the following products:
20 * - i.MX8MM
21 * - i.MX8MN
22 * - i.MX8MP
23 * - i.MX8MQ
24 *
25 * Returns 0 in case it's a known SoM. Otherwise, returns -1.
26 */
Yannic Moog1132f362023-12-20 09:45:32 +010027int __maybe_unused phytec_imx8m_detect(struct phytec_eeprom_data *data)
Teresa Remmetc6dd9c62023-08-17 10:57:07 +020028{
29 char *opt;
30 u8 som;
31
Yannic Moog4feeda62023-12-20 09:45:33 +010032 if (!data)
33 data = &eeprom_data;
34
Teresa Remmetc6dd9c62023-08-17 10:57:07 +020035 /* We can not do the check for early API revisions */
Yannic Moog51b9d532024-04-19 08:55:38 -070036 if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
Teresa Remmetc6dd9c62023-08-17 10:57:07 +020037 return -1;
38
Yannic Moogdb2dfb02024-04-19 08:55:37 -070039 som = data->payload.data.data_api2.som_no;
Teresa Remmetc6dd9c62023-08-17 10:57:07 +020040 debug("%s: som id: %u\n", __func__, som);
41
42 opt = phytec_get_opt(data);
43 if (!opt)
44 return -1;
45
46 if (som == PHYTEC_IMX8MP_SOM && is_imx8mp())
47 return 0;
48
49 if (som == PHYTEC_IMX8MM_SOM) {
50 if ((PHYTEC_GET_OPTION(opt[0]) != 0) &&
51 (PHYTEC_GET_OPTION(opt[1]) == 0) && is_imx8mm())
52 return 0;
53 else if ((PHYTEC_GET_OPTION(opt[0]) == 0) &&
54 (PHYTEC_GET_OPTION(opt[1]) != 0) && is_imx8mn())
55 return 0;
56 }
57
58 if (som == PHYTEC_IMX8MQ_SOM && is_imx8mq())
59 return 0;
60
61 pr_err("%s: SoM ID does not match. Wrong EEPROM data?\n", __func__);
62 return -1;
63}
64
65/*
66 * All PHYTEC i.MX8M boards have RAM size definition at the
67 * same location.
68 */
69u8 __maybe_unused phytec_get_imx8m_ddr_size(struct phytec_eeprom_data *data)
70{
71 char *opt;
72 u8 ddr_id;
73
74 if (!data)
75 data = &eeprom_data;
76
Yannic Moog51b9d532024-04-19 08:55:38 -070077 if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
78 return PHYTEC_EEPROM_INVAL;
79
Teresa Remmetc6dd9c62023-08-17 10:57:07 +020080 opt = phytec_get_opt(data);
81 if (opt)
82 ddr_id = PHYTEC_GET_OPTION(opt[2]);
83 else
84 ddr_id = PHYTEC_EEPROM_INVAL;
85
86 debug("%s: ddr id: %u\n", __func__, ddr_id);
87 return ddr_id;
88}
89
90/*
91 * Filter SPI-NOR flash information. All i.MX8M boards have this at
92 * the same location.
93 * returns: 0x0 if no SPI is populated. Otherwise a board depended
94 * code for the size. PHYTEC_EEPROM_INVAL when the data is invalid.
95 */
96u8 __maybe_unused phytec_get_imx8m_spi(struct phytec_eeprom_data *data)
97{
98 char *opt;
99 u8 spi;
100
101 if (!data)
102 data = &eeprom_data;
103
Yannic Moog51b9d532024-04-19 08:55:38 -0700104 if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
Teresa Remmetc6dd9c62023-08-17 10:57:07 +0200105 return PHYTEC_EEPROM_INVAL;
106
107 opt = phytec_get_opt(data);
108 if (opt)
109 spi = PHYTEC_GET_OPTION(opt[4]);
110 else
111 spi = PHYTEC_EEPROM_INVAL;
112
113 debug("%s: spi: %u\n", __func__, spi);
114 return spi;
115}
116
117/*
118 * Filter ethernet phy information. All i.MX8M boards have this at
119 * the same location.
120 * returns: 0x0 if no ethernet phy is populated. 0x1 if it is populated.
121 * PHYTEC_EEPROM_INVAL when the data is invalid.
122 */
123u8 __maybe_unused phytec_get_imx8m_eth(struct phytec_eeprom_data *data)
124{
125 char *opt;
126 u8 eth;
127
128 if (!data)
129 data = &eeprom_data;
130
Yannic Moog51b9d532024-04-19 08:55:38 -0700131 if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
Teresa Remmetc6dd9c62023-08-17 10:57:07 +0200132 return PHYTEC_EEPROM_INVAL;
133
134 opt = phytec_get_opt(data);
135 if (opt) {
136 eth = PHYTEC_GET_OPTION(opt[5]);
137 eth &= 0x1;
138 } else {
139 eth = PHYTEC_EEPROM_INVAL;
140 }
141
142 debug("%s: eth: %u\n", __func__, eth);
143 return eth;
144}
145
146/*
147 * Filter RTC information for phyCORE-i.MX8MP.
148 * returns: 0 if no RTC is populated. 1 if it is populated.
149 * PHYTEC_EEPROM_INVAL when the data is invalid.
150 */
151u8 __maybe_unused phytec_get_imx8mp_rtc(struct phytec_eeprom_data *data)
152{
153 char *opt;
154 u8 rtc;
155
156 if (!data)
157 data = &eeprom_data;
158
Yannic Moog51b9d532024-04-19 08:55:38 -0700159 if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
Teresa Remmetc6dd9c62023-08-17 10:57:07 +0200160 return PHYTEC_EEPROM_INVAL;
161
162 opt = phytec_get_opt(data);
163 if (opt) {
164 rtc = PHYTEC_GET_OPTION(opt[5]);
165 rtc &= 0x4;
166 rtc = !(rtc >> 2);
167 } else {
168 rtc = PHYTEC_EEPROM_INVAL;
169 }
170 debug("%s: rtc: %u\n", __func__, rtc);
171 return rtc;
172}
Yannic Moog5dd7f7c2023-12-20 09:45:35 +0100173
174#else
175
176inline int __maybe_unused phytec_imx8m_detect(struct phytec_eeprom_data *data)
177{
178 return -1;
179}
180
181inline u8 __maybe_unused
182phytec_get_imx8m_ddr_size(struct phytec_eeprom_data *data)
183{
184 return PHYTEC_EEPROM_INVAL;
185}
186
187inline u8 __maybe_unused phytec_get_imx8mp_rtc(struct phytec_eeprom_data *data)
188{
189 return PHYTEC_EEPROM_INVAL;
190}
191
192inline u8 __maybe_unused phytec_get_imx8m_spi(struct phytec_eeprom_data *data)
193{
194 return PHYTEC_EEPROM_INVAL;
195}
196
197inline u8 __maybe_unused phytec_get_imx8m_eth(struct phytec_eeprom_data *data)
198{
199 return PHYTEC_EEPROM_INVAL;
200}
201
202#endif /* IS_ENABLED(CONFIG_PHYTEC_IMX8M_SOM_DETECTION) */