1 /*
2  * SPDX-License-Identifier: Apache-2.0
3  *
4  * Copyright (c) 2021 ASPEED Technology Inc.
5  */
6 
7 #include <zephyr/init.h>
8 #include <zephyr/kernel.h>
9 #include <stdint.h>
10 #include <string.h>
11 #include <zephyr/linker/linker-defs.h>
12 #include <zephyr/device.h>
13 #include <zephyr/cache.h>
14 #include <soc.h>
15 
16 extern char __bss_nc_start__[];
17 extern char __bss_nc_end__[];
18 
19 /* SCU registers */
20 #define JTAG_PINMUX_REG		0x41c
21 
22 /* ASPEED System reset contrl/status register */
23 #define SYS_WDT4_SW_RESET	BIT(31)
24 #define SYS_WDT4_ARM_RESET	BIT(30)
25 #define SYS_WDT4_FULL_RESET	BIT(29)
26 #define SYS_WDT4_SOC_RESET	BIT(28)
27 #define SYS_WDT3_SW_RESET	BIT(27)
28 #define SYS_WDT3_ARM_RESET	BIT(26)
29 #define SYS_WDT3_FULL_RESET	BIT(25)
30 #define SYS_WDT3_SOC_RESET	BIT(24)
31 #define SYS_WDT2_SW_RESET	BIT(23)
32 #define SYS_WDT2_ARM_RESET	BIT(22)
33 #define SYS_WDT2_FULL_RESET	BIT(21)
34 #define SYS_WDT2_SOC_RESET	BIT(20)
35 #define SYS_WDT1_SW_RESET	BIT(19)
36 #define SYS_WDT1_ARM_RESET	BIT(18)
37 #define SYS_WDT1_FULL_RESET	BIT(17)
38 #define SYS_WDT1_SOC_RESET	BIT(16)
39 
40 #define SYS_FLASH_ABR_RESET	BIT(2)
41 #define SYS_EXT_RESET		BIT(1)
42 #define SYS_PWR_RESET_FLAG	BIT(0)
43 
44 #define BIT_WDT_SOC(x)	SYS_WDT ## x ## _SOC_RESET
45 #define BIT_WDT_FULL(x)	SYS_WDT ## x ## _FULL_RESET
46 #define BIT_WDT_ARM(x)	SYS_WDT ## x ## _ARM_RESET
47 #define BIT_WDT_SW(x)	SYS_WDT ## x ## _SW_RESET
48 
49 #define HANDLE_WDTx_RESET(x, event_log, event_log_reg) \
50 	if (event_log & (BIT_WDT_SOC(x) | BIT_WDT_FULL(x) | BIT_WDT_ARM(x) | BIT_WDT_SW(x))) { \
51 		printk("RST: WDT%d ", x); \
52 		if (event_log & BIT_WDT_SOC(x)) { \
53 			printk("SOC "); \
54 			sys_write32(BIT_WDT_SOC(x), event_log_reg); \
55 		} \
56 		if (event_log & BIT_WDT_FULL(x)) { \
57 			printk("FULL "); \
58 			sys_write32(BIT_WDT_FULL(x), event_log_reg); \
59 		} \
60 		if (event_log & BIT_WDT_ARM(x)) { \
61 			printk("ARM "); \
62 			sys_write32(BIT_WDT_ARM(x), event_log_reg); \
63 		} \
64 		if (event_log & BIT_WDT_SW(x)) { \
65 			printk("SW "); \
66 			sys_write32(BIT_WDT_SW(x), event_log_reg); \
67 		} \
68 		printk("\n"); \
69 	} \
70 	(void)(x)
71 
72 /* secure boot header : provide image size to bootROM for SPI boot */
73 struct sb_header {
74 	uint32_t key_location;
75 	uint32_t enc_img_addr;
76 	uint32_t img_size;
77 	uint32_t sign_location;
78 	uint32_t header_rev[2];
79 	uint32_t patch_location;
80 	uint32_t checksum;
81 };
82 
83 struct sb_header sbh __attribute((used, section(".sboot"))) = {
84 	.img_size = (uint32_t)&__bss_start,
85 };
86 
z_arm_platform_init(void)87 void z_arm_platform_init(void)
88 {
89 	uint32_t jtag_pinmux;
90 	uint32_t base = DT_REG_ADDR(DT_NODELABEL(syscon));
91 
92 	/* enable JTAG pins */
93 	jtag_pinmux = sys_read32(base + JTAG_PINMUX_REG);
94 	jtag_pinmux |= (0x1f << 25);
95 	sys_write32(jtag_pinmux, base + JTAG_PINMUX_REG);
96 
97 	/* clear non-cached .bss */
98 	if (CONFIG_SRAM_NC_SIZE > 0) {
99 		(void)memset(__bss_nc_start__, 0, __bss_nc_end__ - __bss_nc_start__);
100 	}
101 
102 	sys_cache_instr_enable();
103 }
104 
aspeed_print_abr_wdt_mode(void)105 void aspeed_print_abr_wdt_mode(void)
106 {
107 	/* ABR enable */
108 	if (sys_read32(HW_STRAP2_SCU510) & BIT(11)) {
109 		printk("FMC ABR: Enable");
110 		if (sys_read32(HW_STRAP2_SCU510) & BIT(12))
111 			printk(", Single flash");
112 		else
113 			printk(", Dual flashes");
114 
115 		printk(", Source: %s (%d)",
116 			(sys_read32(ASPEED_FMC_WDT2_CTRL) & BIT(4)) ? "Alternate" : "Primary",
117 			(sys_read32(HW_STRAP1_SCU500) & BIT(3)) ? 1 : 0);
118 
119 		if (sys_read32(HW_STRAP2_SCU510) & GENMASK(15, 13)) {
120 			printk(", bspi sz: %ldMB",
121 				BIT((sys_read32(HW_STRAP2_SCU510) >> 13) & 0x7) / 2);
122 		}
123 		printk("\n");
124 	}
125 }
126 
aspeed_print_sysrst_info(void)127 void aspeed_print_sysrst_info(void)
128 {
129 	uint32_t rest1 = sys_read32(SYS_RESET_LOG_REG1);
130 	uint32_t rest2 = sys_read32(SYS_RESET_LOG_REG2);
131 
132 	if (rest1 & SYS_PWR_RESET_FLAG) {
133 		printk("RST: Power On\n");
134 		sys_write32(rest1, SYS_RESET_LOG_REG1);
135 	} else {
136 		HANDLE_WDTx_RESET(4, rest1, SYS_RESET_LOG_REG1);
137 		HANDLE_WDTx_RESET(3, rest1, SYS_RESET_LOG_REG1);
138 		HANDLE_WDTx_RESET(2, rest1, SYS_RESET_LOG_REG1);
139 		HANDLE_WDTx_RESET(1, rest1, SYS_RESET_LOG_REG1);
140 
141 		if (rest1 & SYS_FLASH_ABR_RESET) {
142 			printk("RST: SYS_FLASH_ABR_RESET\n");
143 			sys_write32(SYS_FLASH_ABR_RESET, SYS_RESET_LOG_REG1);
144 		}
145 
146 		if (rest1 & SYS_EXT_RESET) {
147 			printk("RST: External\n");
148 			sys_write32(SYS_EXT_RESET, SYS_RESET_LOG_REG1);
149 		}
150 	}
151 
152 	ARG_UNUSED(rest2);
153 
154 	aspeed_print_abr_wdt_mode();
155 }
156