1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) ASPEED Technology Inc.
4  * Ryan Chen <ryan_chen@aspeedtech.com>
5  */
6 
7 #include <common.h>
8 #include <errno.h>
9 #include <asm/io.h>
10 #include <asm/arch/aspeed_scu_info.h>
11 
12 /* SoC mapping Table */
13 #define SOC_ID(str, rev) { .name = str, .rev_id = rev, }
14 
15 struct soc_id {
16 	const char *name;
17 	u32	   rev_id;
18 };
19 
20 static struct soc_id soc_map_table[] = {
21 	SOC_ID("AST1100/AST2050-A0", 0x00000200),
22 	SOC_ID("AST1100/AST2050-A1", 0x00000201),
23 	SOC_ID("AST1100/AST2050-A2,3/AST2150-A0,1", 0x00000202),
24 	SOC_ID("AST1510/AST2100-A0", 0x00000300),
25 	SOC_ID("AST1510/AST2100-A1", 0x00000301),
26 	SOC_ID("AST1510/AST2100-A2,3", 0x00000302),
27 	SOC_ID("AST2200-A0,1", 0x00000102),
28 	SOC_ID("AST2300-A0", 0x01000003),
29 	SOC_ID("AST2300-A1", 0x01010303),
30 	SOC_ID("AST1300-A1", 0x01010003),
31 	SOC_ID("AST1050-A1", 0x01010203),
32 	SOC_ID("AST2400-A0", 0x02000303),
33 	SOC_ID("AST2400-A1", 0x02010303),
34 	SOC_ID("AST1010-A0", 0x03000003),
35 	SOC_ID("AST1010-A1", 0x03010003),
36 	SOC_ID("AST3200-A0", 0x04002003),
37 	SOC_ID("AST3200-A1", 0x04012003),
38 	SOC_ID("AST3200-A2", 0x04032003),
39 	SOC_ID("AST1520-A0", 0x03000203),
40 	SOC_ID("AST1520-A1", 0x03010203),
41 	SOC_ID("AST2510-A0", 0x04000103),
42 	SOC_ID("AST2510-A1", 0x04010103),
43 	SOC_ID("AST2510-A2", 0x04030103),
44 	SOC_ID("AST2520-A0", 0x04000203),
45 	SOC_ID("AST2520-A1", 0x04010203),
46 	SOC_ID("AST2520-A2", 0x04030203),
47 	SOC_ID("AST2500-A0", 0x04000303),
48 	SOC_ID("AST2500-A1", 0x04010303),
49 	SOC_ID("AST2500-A2", 0x04030303),
50 	SOC_ID("AST2530-A0", 0x04000403),
51 	SOC_ID("AST2530-A1", 0x04010403),
52 	SOC_ID("AST2530-A2", 0x04030403),
53 	SOC_ID("AST2600-A0", 0x05000303),
54 	SOC_ID("AST2600-A1", 0x05010303),
55 };
56 
57 void aspeed_print_soc_id(void)
58 {
59 	int i;
60 	u32 rev_id = readl(ASPEED_REVISION_ID);
61 	for (i = 0; i < ARRAY_SIZE(soc_map_table); i++) {
62 		if (rev_id == soc_map_table[i].rev_id)
63 			break;
64 	}
65 	if (i == ARRAY_SIZE(soc_map_table))
66 		printf("UnKnow-SOC: %x \n",rev_id);
67 	else
68 		printf("SOC: %4s \n",soc_map_table[i].name);
69 }
70 
71 int aspeed_get_mac_phy_interface(u8 num)
72 {
73 	u32 strap1 = readl(ASPEED_HW_STRAP1);
74 #ifdef ASPEED_HW_STRAP2
75 	u32 strap2 = readl(ASPEED_HW_STRAP2);
76 #endif
77 	switch(num) {
78 		case 0:
79 			if(strap1 & BIT(6)) {
80 				return 1;
81 			} else {
82 				return 0;
83 			}
84 			break;
85 		case 1:
86 			if(strap1 & BIT(7)) {
87 				return 1;
88 			} else {
89 				return 0;
90 			}
91 			break;
92 #ifdef ASPEED_HW_STRAP2
93 		case 2:
94 			if(strap2 & BIT(0)) {
95 				return 1;
96 			} else {
97 				return 0;
98 			}
99 			break;
100 		case 3:
101 			if(strap2 & BIT(1)) {
102 				return 1;
103 			} else {
104 				return 0;
105 			}
106 			break;
107 #endif
108 	}
109 	return -1;
110 }
111 
112 void aspeed_print_security_info(void)
113 {
114 	if(readl(ASPEED_HW_STRAP1) & BIT(1))
115 		printf("Security Boot \n");
116 }
117 
118 /*	ASPEED_SYS_RESET_CTRL	: System reset contrl/status register*/
119 #define SYS_WDT8_SW_RESET	BIT(15)
120 #define SYS_WDT8_ARM_RESET	BIT(14)
121 #define SYS_WDT8_FULL_RESET	BIT(13)
122 #define SYS_WDT8_SOC_RESET	BIT(12)
123 #define SYS_WDT7_SW_RESET	BIT(11)
124 #define SYS_WDT7_ARM_RESET	BIT(10)
125 #define SYS_WDT7_FULL_RESET	BIT(9)
126 #define SYS_WDT7_SOC_RESET	BIT(8)
127 #define SYS_WDT6_SW_RESET	BIT(7)
128 #define SYS_WDT6_ARM_RESET	BIT(6)
129 #define SYS_WDT6_FULL_RESET	BIT(5)
130 #define SYS_WDT6_SOC_RESET	BIT(4)
131 #define SYS_WDT5_SW_RESET	BIT(3)
132 #define SYS_WDT5_ARM_RESET	BIT(2)
133 #define SYS_WDT5_FULL_RESET	BIT(1)
134 #define SYS_WDT5_SOC_RESET	BIT(0)
135 
136 #define SYS_WDT4_SW_RESET	BIT(31)
137 #define SYS_WDT4_ARM_RESET	BIT(30)
138 #define SYS_WDT4_FULL_RESET	BIT(29)
139 #define SYS_WDT4_SOC_RESET	BIT(28)
140 #define SYS_WDT3_SW_RESET	BIT(27)
141 #define SYS_WDT3_ARM_RESET	BIT(26)
142 #define SYS_WDT3_FULL_RESET	BIT(25)
143 #define SYS_WDT3_SOC_RESET	BIT(24)
144 #define SYS_WDT2_SW_RESET	BIT(23)
145 #define SYS_WDT2_ARM_RESET	BIT(22)
146 #define SYS_WDT2_FULL_RESET	BIT(21)
147 #define SYS_WDT2_SOC_RESET	BIT(20)
148 #define SYS_WDT1_SW_RESET	BIT(19)
149 #define SYS_WDT1_ARM_RESET	BIT(18)
150 #define SYS_WDT1_FULL_RESET	BIT(17)
151 #define SYS_WDT1_SOC_RESET	BIT(16)
152 
153 #define SYS_CM3_EXT_RESET	BIT(6)
154 #define SYS_PCI2_RESET		BIT(5)
155 #define SYS_PCI1_RESET		BIT(4)
156 #define SYS_DRAM_ECC_RESET	BIT(3)
157 #define SYS_FLASH_ABR_RESET	BIT(2)
158 #define SYS_EXT_RESET		BIT(1)
159 #define SYS_PWR_RESET_FLAG	BIT(0)
160 
161 #define BIT_WDT_SOC(x)	SYS_WDT ## x ## _SOC_RESET
162 #define BIT_WDT_FULL(x)	SYS_WDT ## x ## _FULL_RESET
163 #define BIT_WDT_ARM(x)	SYS_WDT ## x ## _ARM_RESET
164 #define BIT_WDT_SW(x)	SYS_WDT ## x ## _SW_RESET
165 
166 #define HANDLE_WDTx_RESET(x, event_log, event_log_reg) \
167 	if (event_log & (BIT_WDT_SOC(x) | BIT_WDT_FULL(x) | BIT_WDT_ARM(x) | BIT_WDT_SW(x))) { \
168 		printf("RST: WDT%d ", x); \
169 		if (event_log & BIT_WDT_SOC(x)) { \
170 			printf("SOC "); \
171 			writel(BIT_WDT_SOC(x), event_log_reg); \
172 		} \
173 		if (event_log & BIT_WDT_FULL(x)) { \
174 			printf("FULL "); \
175 			writel(BIT_WDT_FULL(x), event_log_reg); \
176 		} \
177 		if (event_log & BIT_WDT_ARM(x)) { \
178 			printf("ARM "); \
179 			writel(BIT_WDT_ARM(x), event_log_reg); \
180 		} \
181 		if (event_log & BIT_WDT_SW(x)) { \
182 			printf("SW "); \
183 			writel(BIT_WDT_SW(x), event_log_reg); \
184 		} \
185 		printf("\n"); \
186 	} \
187 	(void)(x)
188 
189 void aspeed_print_sysrst_info(void)
190 {
191 	u32 rest = readl(ASPEED_SYS_RESET_CTRL);
192 	u32 rest3 = readl(ASPEED_SYS_RESET_CTRL3);
193 
194 	if (rest & SYS_PWR_RESET_FLAG) {
195 		printf("RST: Power On \n");
196 		writel(rest, ASPEED_SYS_RESET_CTRL);
197 	} else {
198 		HANDLE_WDTx_RESET(8, rest3, ASPEED_SYS_RESET_CTRL3);
199 		HANDLE_WDTx_RESET(7, rest3, ASPEED_SYS_RESET_CTRL3);
200 		HANDLE_WDTx_RESET(6, rest3, ASPEED_SYS_RESET_CTRL3);
201 		HANDLE_WDTx_RESET(5, rest3, ASPEED_SYS_RESET_CTRL3);
202 		HANDLE_WDTx_RESET(4, rest, ASPEED_SYS_RESET_CTRL);
203 		HANDLE_WDTx_RESET(3, rest, ASPEED_SYS_RESET_CTRL);
204 		HANDLE_WDTx_RESET(2, rest, ASPEED_SYS_RESET_CTRL);
205 		HANDLE_WDTx_RESET(1, rest, ASPEED_SYS_RESET_CTRL);
206 
207 		if (rest & SYS_CM3_EXT_RESET) {
208 			printf("RST: SYS_CM3_EXT_RESET \n");
209 			writel(SYS_CM3_EXT_RESET, ASPEED_SYS_RESET_CTRL);
210 		}
211 
212 		if (rest & (SYS_PCI1_RESET | SYS_PCI2_RESET)) {
213 			printf("PCI RST: ");
214 			if (rest & SYS_PCI1_RESET) {
215 				printf("#1 ");
216 				writel(SYS_PCI1_RESET, ASPEED_SYS_RESET_CTRL);
217 			}
218 
219 			if (rest & SYS_PCI2_RESET) {
220 				printf("#2 ");
221 				writel(SYS_PCI2_RESET, ASPEED_SYS_RESET_CTRL);
222 			}
223 			printf("\n");
224 		}
225 
226 		if (rest & SYS_DRAM_ECC_RESET) {
227 			printf("RST: DRAM_ECC_RESET \n");
228 			writel(SYS_FLASH_ABR_RESET, ASPEED_SYS_RESET_CTRL);
229 		}
230 
231 		if (rest & SYS_FLASH_ABR_RESET) {
232 			printf("RST: SYS_FLASH_ABR_RESET \n");
233 			writel(SYS_FLASH_ABR_RESET, ASPEED_SYS_RESET_CTRL);
234 		}
235 		if (rest & SYS_EXT_RESET) {
236 			printf("RST: External \n");
237 			writel(SYS_EXT_RESET, ASPEED_SYS_RESET_CTRL);
238 		}
239 	}
240 }
241 
242 #define SOC_FW_INIT_DRAM		BIT(7)
243 
244 void aspeed_print_dram_initializer(void)
245 {
246 	if(readl(ASPEED_VGA_HANDSHAKE0) & SOC_FW_INIT_DRAM)
247 		printf("[init by SOC]\n");
248 	else
249 		printf("[init by VBIOS]\n");
250 }
251 
252 void aspeed_print_2nd_wdt_mode(void)
253 {
254 	if(readl(ASPEED_HW_STRAP2) & BIT(11)) {
255 		printf("2nd Boot: Enable, ");
256 		if(readl(ASPEED_HW_STRAP2) & BIT(12))
257 			printf("Single SPI ");
258 		else
259 			printf("Dual SPI ");
260 		printf(": %s", readl(0x1e620064) & BIT(4) ? "Alternate":"Primary");
261 
262 		if(readl(ASPEED_HW_STRAP2) & GENMASK(15, 13)) {
263 			printf(", bspi_size : %ld MB\n", BIT((readl(ASPEED_HW_STRAP2) >> 13) & 0x7));
264 		} else
265 			printf("\n");
266 	}
267 
268 	if(readl(ASPEED_HW_STRAP2) & BIT(22)) {
269 		printf("SPI aux control : Enable");
270 		//gpioY6 : BSPI_ABR
271 		if (readl(0x1e7801e0) & BIT(6))
272 			printf(", Force Alt boot ");
273 
274 		//gpioY7 : BSPI_WP_N
275 		printf(", BSPI_WP : %s \n", readl(0x1e7801e0) & BIT(7) ? "Disable":"Enable");
276 	}
277 }
278 
279 void aspeed_print_spi_strap_mode(void)
280 {
281 	if(readl(ASPEED_HW_STRAP2) & BIT(10))
282 		printf("SPI: 3/4 byte mode auto detection \n");
283 }
284 
285 void aspeed_print_espi_mode(void)
286 {
287 	int espi_mode = 0;
288 	int sio_disable = 0;
289 	u32 sio_addr = 0x2e;
290 
291 	if (readl(ASPEED_HW_STRAP2) & BIT(6))
292 		espi_mode = 0;
293 	else
294 		espi_mode = 1;
295 
296 	if (readl(ASPEED_HW_STRAP2) & BIT(2))
297 		sio_addr = 0x4e;
298 
299 	if (readl(ASPEED_HW_STRAP2) & BIT(3))
300 		sio_disable = 1;
301 
302 	if (espi_mode)
303 		printf("eSPI Mode: SIO:%s ", sio_disable ? "Disable" : "Enable");
304 	else
305 		printf("LPC Mode: SIO:%s ", sio_disable ? "Disable" : "Enable");
306 
307 	if (!sio_disable)
308 		printf(": SuperIO-%02x\n", sio_addr);
309 	else
310 		printf("\n");
311 }
312 
313 void aspeed_print_mac_info(void)
314 {
315 	int i;
316 	printf("Eth: ");
317 	for (i = 0; i < ASPEED_MAC_COUNT; i++) {
318 		printf("MAC%d: %s", i,
319 				aspeed_get_mac_phy_interface(i) ? "RGMII" : "RMII/NCSI");
320 		if (i != (ASPEED_MAC_COUNT -1))
321 			printf(", ");
322 	}
323 	printf("\n");
324 }
325