1 /*
2 * startup.c
3 *
4 * This file is used to initialize the board hardware.
5 *
6 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 #include <config.h>
24 #include <linux/kconfig.h>
25 #include <asm/io.h>
26 #include <compiler.h>
27 #include <hicpu_common.h>
28
29 /******************************************************************************/
30 const uintptr_t image_entry = (CONFIG_SYS_TEXT_BASE);
31
32 /******************************************************************************/
33 #define error(_s) uart_early_puts(_s)
34 #define putstr(_s) uart_early_puts(_s)
35
36 #include "hw_decompress.c"
37 #define GZIP_SIZE_OFFSET 0x4
38
39 #ifndef CONFIG_SYS_ICACHE_OFF
40 /* Invalidate entire I-cache and branch predictor array */
invalidate_icache_all(void)41 static void invalidate_icache_all(void)
42 {
43 /*
44 * Invalidate all instruction caches to PoU.
45 * Also flushes branch target cache.
46 */
47 asm volatile("mcr p15, 0, %0, c7, c5, 0" : : "r"(0));
48
49 /* Invalidate entire branch predictor array */
50 asm volatile("mcr p15, 0, %0, c7, c5, 6" : : "r"(0));
51
52 /* Full system DSB - make sure that the invalidation is complete */
53 dsb();
54
55 /* ISB - make sure the instruction stream sees it */
56 isb();
57 }
58 #else
invalidate_icache_all(void)59 static void invalidate_icache_all(void)
60 {
61 }
62 #endif
63
64 #ifdef CONFIG_MINI_BOOT
65
66 #ifndef bit
67 #define bit(x) (1 << (x))
68 #endif
69
70 #define TIME2_CLK_SEL bit(18)
71
timer_init(void)72 int timer_init(void)
73 {
74 /*
75 * Under uboot, 0xffffffff is set to load register,
76 * timer_clk equals BUSCLK/2/256.
77 * e.g. BUSCLK equals 50M, it will roll back after 0xffffffff/timer_clk
78 * 43980s equals 12hours
79 */
80 __raw_writel(0, CFG_TIMERBASE + REG_TIMER_CONTROL);
81 __raw_writel(~0, CFG_TIMERBASE + REG_TIMER_RELOAD);
82
83 /* 32 bit, periodic */
84 __raw_writel(CFG_TIMER_CTRL, CFG_TIMERBASE + REG_TIMER_CONTROL);
85
86 /* start timer2 with mode below */
87 unsigned int reg;
88
89 reg = __raw_readl(SYS_CTRL_REG_BASE + REG_SC_CTRL);
90 /* for timer2,use sys BUS clk */
91 reg |= TIME2_CLK_SEL;
92 __raw_writel(reg, SYS_CTRL_REG_BASE + REG_SC_CTRL);
93
94 /* disable timer2 */
95 __raw_writel(0, TIMER2_REG_BASE + REG_TIMER_CONTROL);
96 /* timer2 load */
97 __raw_writel(~0, TIMER2_REG_BASE + REG_TIMER_RELOAD);
98
99 /*
100 * Timing mode: 32bits [bit 1 set as 1]
101 * ticking with 1/256 clock frequency [bit 3 set as 1, bit 2 set as 0]
102 * timing circulary [bit 6 set as 1]
103 * timer enabled [bit 7 set as 1]
104 */
105 reg = (1 << 7) | (1 << 6) | (1 << 3) | (1 << 1);
106 __raw_writel(reg, TIMER2_REG_BASE + REG_TIMER_CONTROL);
107
108 return 0;
109 }
110
111 #define TIME_STAMP_CNT 0x12020138
112 #define TIME_STAMP_VALUE 0x04010050
113 #define CONFIG_TIME_STAMP_ENABLE
114
time_stamp(const char * strfunc,int nline,int type)115 void time_stamp(const char *strfunc, int nline, int type)
116 {
117 #ifdef CONFIG_TIME_STAMP_ENABLE
118 static int init_flag = 0;
119 unsigned int cnt;
120 unsigned int stamp;
121 unsigned int *addr = NULL;
122
123 if (!init_flag) {
124 init_flag = 1;
125 *(unsigned int *)TIME_STAMP_CNT = 0;
126 }
127
128 cnt = *(unsigned int *)TIME_STAMP_CNT;
129 stamp = *(unsigned int *)(TIMER2_REG_BASE + REG_TIMER_VALUE);
130 addr = (unsigned int *)(TIME_STAMP_VALUE + cnt * 16); /* 16:The number in the formula */
131
132 *addr = ~stamp;
133 addr++;
134 *addr = (uintptr_t)strfunc;
135 addr++;
136 *addr = nline;
137 addr++;
138 *addr = type;
139 cnt++;
140 *(unsigned int *)TIME_STAMP_CNT = cnt;
141 #endif
142 }
143 #endif
144
145
146 /******************************************************************************/
start_armboot(void)147 void start_armboot(void)
148 {
149 unsigned char *pdst_l32 = NULL;
150 unsigned int image_data_len;
151 int pdst_len;
152 int ret;
153 int i;
154 char *p = NULL;
155 char *q = NULL;
156
157 #ifndef CONFIG_MINI_BOOT
158 uart_early_init();
159 uart_early_puts("\r\nUncompress ");
160 #endif
161
162 /* use direct address mode */
163 hw_dec_type = 0;
164 /* init hw decompress IP */
165 hw_dec_init();
166
167 /* start decompress */
168 pdst_l32 = (unsigned char *)(uintptr_t)image_entry;
169 image_data_len = input_data_end - input_data;
170
171 /* get dets length from compress image */
172 p = (char *)&pdst_len;
173 q = (char *)(input_data_end - GZIP_SIZE_OFFSET);
174 for (i = 0; i < sizeof(int); i++)
175 p[i] = q[i];
176
177 ret = hw_dec_decompress(pdst_l32, &pdst_len, input_data, image_data_len, NULL);
178 if (!ret) {
179 #ifndef CONFIG_MINI_BOOT
180 uart_early_puts("Ok!");
181 #endif
182 } else {
183 #ifndef CONFIG_MINI_BOOT
184 uart_early_puts("Fail!");
185 #endif
186 while (1);
187 }
188
189 /* uinit hw decompress IP */
190 hw_dec_uinit();
191 void (*uboot)(void);
192 uboot = (void (*))CONFIG_SYS_TEXT_BASE;
193 invalidate_icache_all();
194 uboot();
195 }
196
197 /******************************************************************************/
hang(void)198 void hang(void)
199 {
200 uart_early_puts("### ERROR ### Please RESET the board ###\n");
201 for (;;) ;
202 }
203
204
do_bad_sync(void)205 void do_bad_sync(void)
206 {
207 uart_early_puts("bad sync abort\r\n");
208 uart_early_puts("Resetting CPU ...\r\n");
209 reset_cpu(0);
210 }
211
do_sync(void)212 void do_sync(void)
213 {
214 uart_early_puts("sync abort\r\n");
215 uart_early_puts("Resetting CPU ...\r\n");
216 reset_cpu(0);
217 }
218
do_bad_error(void)219 void do_bad_error(void)
220 {
221 uart_early_puts("bad error\r\n");
222 uart_early_puts("Resetting CPU ...\r\n");
223 reset_cpu(0);
224 }
225
do_error(void)226 void do_error(void)
227 {
228 uart_early_puts("error\r\n");
229 uart_early_puts("Resetting CPU ...\r\n");
230 reset_cpu(0);
231 }
232
do_bad_fiq(void)233 void do_bad_fiq(void)
234 {
235 uart_early_puts("bad fast interrupt request\r\n");
236 uart_early_puts("Resetting CPU ...\r\n");
237 reset_cpu(0);
238 }
239
do_bad_irq(void)240 void do_bad_irq(void)
241 {
242 uart_early_puts("bad interrupt request\r\n");
243 uart_early_puts("Resetting CPU ...\r\n");
244 reset_cpu(0);
245 }
246
do_fiq(void)247 void do_fiq(void)
248 {
249 uart_early_puts("fast interrupt request\r\n");
250 uart_early_puts("Resetting CPU ...\r\n");
251 reset_cpu(0);
252 }
253
do_irq(void)254 void do_irq(void)
255 {
256 uart_early_puts("interrupt request\r\n");
257 uart_early_puts("Resetting CPU ...\r\n");
258 reset_cpu(0);
259 }
260