• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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