]>
Commit | Line | Data |
---|---|---|
a9719ef0 TR |
1 | // 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 | ||
d678a59d | 7 | #include <common.h> |
a9719ef0 TR |
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 | ||
16 | extern struct phytec_eeprom_data eeprom_data; | |
17 | ||
aa7858fe YM |
18 | #if IS_ENABLED(CONFIG_PHYTEC_IMX8M_SOM_DETECTION) |
19 | ||
a9719ef0 TR |
20 | /* 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 | */ | |
e2be177c | 28 | int __maybe_unused phytec_imx8m_detect(struct phytec_eeprom_data *data) |
a9719ef0 TR |
29 | { |
30 | char *opt; | |
31 | u8 som; | |
32 | ||
da37f785 YM |
33 | if (!data) |
34 | data = &eeprom_data; | |
35 | ||
a9719ef0 | 36 | /* We can not do the check for early API revisions */ |
1e5de690 | 37 | if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) |
a9719ef0 TR |
38 | return -1; |
39 | ||
8fe6e9a0 | 40 | som = data->payload.data.data_api2.som_no; |
a9719ef0 TR |
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 | */ | |
70 | u8 __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 | ||
1e5de690 YM |
78 | if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) |
79 | return PHYTEC_EEPROM_INVAL; | |
80 | ||
a9719ef0 TR |
81 | opt = phytec_get_opt(data); |
82 | if (opt) | |
83 | ddr_id = PHYTEC_GET_OPTION(opt[2]); | |
84 | else | |
85 | ddr_id = PHYTEC_EEPROM_INVAL; | |
86 | ||
87 | debug("%s: ddr id: %u\n", __func__, ddr_id); | |
88 | return ddr_id; | |
89 | } | |
90 | ||
91 | /* | |
92 | * Filter SPI-NOR flash information. All i.MX8M boards have this at | |
93 | * the same location. | |
94 | * returns: 0x0 if no SPI is populated. Otherwise a board depended | |
95 | * code for the size. PHYTEC_EEPROM_INVAL when the data is invalid. | |
96 | */ | |
97 | u8 __maybe_unused phytec_get_imx8m_spi(struct phytec_eeprom_data *data) | |
98 | { | |
99 | char *opt; | |
100 | u8 spi; | |
101 | ||
102 | if (!data) | |
103 | data = &eeprom_data; | |
104 | ||
1e5de690 | 105 | if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) |
a9719ef0 TR |
106 | return PHYTEC_EEPROM_INVAL; |
107 | ||
108 | opt = phytec_get_opt(data); | |
109 | if (opt) | |
110 | spi = PHYTEC_GET_OPTION(opt[4]); | |
111 | else | |
112 | spi = PHYTEC_EEPROM_INVAL; | |
113 | ||
114 | debug("%s: spi: %u\n", __func__, spi); | |
115 | return spi; | |
116 | } | |
117 | ||
118 | /* | |
119 | * Filter ethernet phy information. All i.MX8M boards have this at | |
120 | * the same location. | |
121 | * returns: 0x0 if no ethernet phy is populated. 0x1 if it is populated. | |
122 | * PHYTEC_EEPROM_INVAL when the data is invalid. | |
123 | */ | |
124 | u8 __maybe_unused phytec_get_imx8m_eth(struct phytec_eeprom_data *data) | |
125 | { | |
126 | char *opt; | |
127 | u8 eth; | |
128 | ||
129 | if (!data) | |
130 | data = &eeprom_data; | |
131 | ||
1e5de690 | 132 | if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) |
a9719ef0 TR |
133 | return PHYTEC_EEPROM_INVAL; |
134 | ||
135 | opt = phytec_get_opt(data); | |
136 | if (opt) { | |
137 | eth = PHYTEC_GET_OPTION(opt[5]); | |
138 | eth &= 0x1; | |
139 | } else { | |
140 | eth = PHYTEC_EEPROM_INVAL; | |
141 | } | |
142 | ||
143 | debug("%s: eth: %u\n", __func__, eth); | |
144 | return eth; | |
145 | } | |
146 | ||
147 | /* | |
148 | * Filter RTC information for phyCORE-i.MX8MP. | |
149 | * returns: 0 if no RTC is populated. 1 if it is populated. | |
150 | * PHYTEC_EEPROM_INVAL when the data is invalid. | |
151 | */ | |
152 | u8 __maybe_unused phytec_get_imx8mp_rtc(struct phytec_eeprom_data *data) | |
153 | { | |
154 | char *opt; | |
155 | u8 rtc; | |
156 | ||
157 | if (!data) | |
158 | data = &eeprom_data; | |
159 | ||
1e5de690 | 160 | if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) |
a9719ef0 TR |
161 | return PHYTEC_EEPROM_INVAL; |
162 | ||
163 | opt = phytec_get_opt(data); | |
164 | if (opt) { | |
165 | rtc = PHYTEC_GET_OPTION(opt[5]); | |
166 | rtc &= 0x4; | |
167 | rtc = !(rtc >> 2); | |
168 | } else { | |
169 | rtc = PHYTEC_EEPROM_INVAL; | |
170 | } | |
171 | debug("%s: rtc: %u\n", __func__, rtc); | |
172 | return rtc; | |
173 | } | |
aa7858fe YM |
174 | |
175 | #else | |
176 | ||
177 | inline int __maybe_unused phytec_imx8m_detect(struct phytec_eeprom_data *data) | |
178 | { | |
179 | return -1; | |
180 | } | |
181 | ||
182 | inline u8 __maybe_unused | |
183 | phytec_get_imx8m_ddr_size(struct phytec_eeprom_data *data) | |
184 | { | |
185 | return PHYTEC_EEPROM_INVAL; | |
186 | } | |
187 | ||
188 | inline u8 __maybe_unused phytec_get_imx8mp_rtc(struct phytec_eeprom_data *data) | |
189 | { | |
190 | return PHYTEC_EEPROM_INVAL; | |
191 | } | |
192 | ||
193 | inline u8 __maybe_unused phytec_get_imx8m_spi(struct phytec_eeprom_data *data) | |
194 | { | |
195 | return PHYTEC_EEPROM_INVAL; | |
196 | } | |
197 | ||
198 | inline u8 __maybe_unused phytec_get_imx8m_eth(struct phytec_eeprom_data *data) | |
199 | { | |
200 | return PHYTEC_EEPROM_INVAL; | |
201 | } | |
202 | ||
203 | #endif /* IS_ENABLED(CONFIG_PHYTEC_IMX8M_SOM_DETECTION) */ |