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