blob: 0a55f70bb97087e11f3b94fa4697a5c13176561a [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*
2 * Copyright (C) 2016 ZXIC Inc.
3 *
4 */
5#include <common.h>
6#include <version.h>
7#include <asm/io.h>
8#include <asm/string.h>
9#include <asm/arch/cpu.h>
10#include <image.h>
11#include <linux/byteorder/generic.h>
12#include <load_mode.h>
13#include <asm/arch/top_clock.h>
14#include <asm/arch/uart.h>
15
16#include "config.h"
17#include "ddr.h"
18#include "../drivers/efuse.h"
19#include "../drivers/flash.h"
xf.li6c8fc1e2023-08-12 00:11:09 -070020#include "pub_flags.h"
lh9ed821d2023-04-07 01:36:19 -070021
22#define FLAGS_PARTITION_ERROR (0x1111) /*·ÖÇøÒì³£*/
xf.lif5401db2023-08-16 20:40:40 -070023//xf.li@20230815 add for download without powerkey start
24#define GPIO0_REG_BASE 0x0013D000
25#define GPIO24_PSHOLD (24)
26#define IO_CFG_BASE (0x0013C000+0x800)
27//xf.li@20230815 add for download without powerkey end
lh9ed821d2023-04-07 01:36:19 -070028typedef short (init_fnc_t) (void);
29
30int print_info(void)
31{
32#if defined(CFG_ZLOAD)
33 printf ("\nInc zloader 1.3.4\n");
34#else
35 printf ("\nInc tLoader 1.3.4\n");
36#endif
37 return 0;
38}
39
40void copy_to_iram1(void)
41{
42 memcpy(0x100000, 0x8a000, 0x2000); /* TEXT_BASE=0x100000 */
43 writel(CFG_START_STAGE1_STATE, CFG_START_STAGE1_ADDR);
44}
45
46/*
47 ******************************************************************************
48 * Function:
49 * Description:
50 * Parameters:
51 * Input:
52 * Output:
53 * Returns:
54 * Others: IRAM addr is provided from ap
55 *******************************************************************************
56 */
57void clear_iram( void )
58{
59 uint32_t i = 0;
60
61 for( i=0x82000400; i<=0x82003400; i+=4 )
62 {
63 writel(0x0, i);
64 }
65}
66
67/*
68 ******************************************************************************
69 * Function:
70 * Description:
71 * Parameters:
72 * Input:
73 * Output:
74 * Returns:
75 * Others:
76 *******************************************************************************
77 */
78 void write_loader_mode(uint32_t mode)
79{
80 writel(mode, CFG_BOOT_MODE_SAVE_ADDR_FOR_UBOOT);
81}
82
83void hang (void)
84{
85 /* call board specific hang function */
86 for (;;);
87}
88
89/*******************************************************************************
90 * Function:
91 * Description:
92 * Parameters:
93 * Input:
94 *
95 * Output:
96 *
97 * Returns:
98 *
99 *
100 * Others:
101 ********************************************************************************/
102void usb_apcore_poweroff(void)
103{
104 u32 tmp;
105
106 tmp =readl(USB_RESET); /*usb hsic reset*/
107 tmp &= ~0x7;
108 writel(tmp, USB_RESET);
109
110 tmp =readl(CORE_OUTPUT_SWITCH_CONFIG_REG);/*ap clk&mg control by sw*/
111 tmp &= ~((0x1<<2)|(0x1<<5));
112 writel(tmp, CORE_OUTPUT_SWITCH_CONFIG_REG);
113
114 tmp =readl(CORE_OUTPUT_SW_CONFIG_REG1);/*ap clk off*/
115 tmp &= ~(0x1<<2);
116 writel(tmp, CORE_OUTPUT_SW_CONFIG_REG1);
117
118 tmp =readl(CORE_OUTPUT_SW_CONFIG_REG2);/*ap mg iso*/
119 tmp |= (0x1<<5);
120 writel(tmp, CORE_OUTPUT_SW_CONFIG_REG2);
121
122 usdelay(1);
123
124 tmp =readl(CORE_OUTPUT_SW_CONFIG_REG2);/*ap mg rst*/
125 tmp |= (0x1<<4);
126 writel(tmp, CORE_OUTPUT_SW_CONFIG_REG2);
127
128 usdelay(1);
129
130 tmp =readl(CORE_OUTPUT_SW_CONFIG_REG2);/*ap mg off*/
131 tmp &= ~(0x1<<3);
132 writel(tmp, CORE_OUTPUT_SW_CONFIG_REG2);
133
134 //__REG(0x0013a0ac) &= ~((0x1<<2)|(0x1<<5)); /*ap clk&mg control by sw*/
135 //__REG(0x0013a0b8) &= ~(0x1<<2); /*ap clk off*/
136 //__REG(0x0013a0bc) |= (0x1<<5); /*ap mg iso*/
137 //__REG(0x0013a0bc) |= (0x1<<4); /*ap mg rst*/
138 //__REG(0x0013a0bc) &= ~(0x1<<3); /*ap mg off*/
139}
140
141//#ifdef CONFIG_ZX297520V3E_MDL_AB
xf.li6c8fc1e2023-08-12 00:11:09 -0700142#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF)
lh9ed821d2023-04-07 01:36:19 -0700143void start_armboot (void)
144{
145 int32_t ret = 0;
146 int32_t add;
147 uint32_t amt_value = 0;
148 int32_t err_flag = 0;
149 T_BOOT_TARGET bootTarget;
xf.li6c8fc1e2023-08-12 00:11:09 -0700150 T_FLAGS_INFO flagsData;
151 T_FLAGS_INFO *fotaFlag;
lh9ed821d2023-04-07 01:36:19 -0700152 T_BOOT_DUALSYSTEM_TYPE dualSystemType;
153
154 clk_init();
155 timer_init();
156#if CFG_PRINTF
157 uart_init();
158#endif
xf.lif5401db2023-08-16 20:40:40 -0700159//xf.li@20230815 add for download without powerkey start
160#if 1//pshold on
161 amt_value = readl(IO_CFG_BASE+0x4);
162 amt_value &= ~(3<<28);
163 writel(amt_value, (IO_CFG_BASE+0x4));
164 /*direction: out*/
165 amt_value = readl(GPIO0_REG_BASE + (GPIO24_PSHOLD/16)*0x40);
166 amt_value &= ~(1<<(24%16));
167 writel(amt_value, GPIO0_REG_BASE + (GPIO24_PSHOLD/16)*0x40);
168 /*set out 1*/
169 amt_value = readl(GPIO0_REG_BASE + 0x18+ (GPIO24_PSHOLD/16)*0x40);
170 amt_value |= (1<<(24%16));
171 writel(amt_value, GPIO0_REG_BASE + 0x18+ (GPIO24_PSHOLD/16)*0x40);
172#endif
173//xf.li@20230815 add for download without powerkey end
lh9ed821d2023-04-07 01:36:19 -0700174 print_info();
175
176 /* After reset, Copy zloader forcely. */
177 /* Now IRAM1 maybe occupied by dirty data. */
178 writel(0, CFG_START_STAGE1_ADDR);
179 amt_value = readl(CFG_AMT_MODE_SWITCH_ADDR);
180 clear_iram();
181 writel(amt_value, CFG_AMT_MODE_SWITCH_ADDR);
182
183 ret = board_flash_init();
184 if(ret != 0)
185 {
186 goto error;
187 }
188
189 efuse_init();
190
191 if(get_ddr_flag() == CHIP_DDR_IS_32M)
192 {
193 ddr_init(CHIP_DDR_IS_32M);
194 }
195 else if(get_ddr_flag() == CHIP_DDR_IS_64M)
196 {
197 ddr_init(CHIP_DDR_IS_64M);
198 }
199 else if(get_ddr_flag() == CHIP_DDR_IS_128M)
200 {
201 ddr_init(CHIP_DDR_IS_128M);
202 }
203 else
204 {
205 ddr_init(CHIP_DDR_IS_256M);
206 }
207
208 usb_apcore_poweroff();
209/********************* ÔËÐÐT-LOAD,½øÈëÏÂÔØÄ£Ê½ ******************/
210#if defined(CFG_TLOAD)
211 write_loader_mode(CFG_TLOAD_MODE);
212
213#if CFG_USB
214 usb_boot(SYS_USB_BASE);
215#endif
216
217#if CFG_UART
218 uart_boot();
219#endif
220
221#endif /* CFG_TLOAD */
222
223/********************* ÔËÐÐZ-LOAD,½øÈëÕý³£Æô¶¯Ä£Ê½ **********/
224#if defined(CFG_ZLOAD)
225 uint32_t uboot_entry_point = 0;
226 char boot_mode = 0;
227
228 write_loader_mode(CFG_ZLOAD_MODE);
229
230 /*read flags·ÖÇø*/
231 ret = read_flags_image((uint8_t *)FLAGS_IMAGE);
232
233 if( ret != 0 )
234 {
235 printf("read flags partition error! Use default parameters\n");
236 //goto error;
237 err_flag = 1;
238
239 /*ĬÈÏflags·ÖÇøÊý¾Ý*/
xf.li6c8fc1e2023-08-12 00:11:09 -0700240 flagsData.magic_start = FLAGS_MAGIC;
241 flagsData.boot_fota_flag.boot_to = DUAL_SYSTEM;
242 flagsData.boot_fota_flag.fota_status = 1;
243 flagsData.boot_fota_flag.system.status = DUALSYSTEM_STATUS_BOOTABLE;
244 flagsData.boot_fota_flag.system2.status = DUALSYSTEM_STATUS_BOOTABLE;
245 flagsData.magic_end = FLAGS_MAGIC;
lh9ed821d2023-04-07 01:36:19 -0700246 fotaFlag = &flagsData;
247 }
248 else
249 {
xf.li6c8fc1e2023-08-12 00:11:09 -0700250 fotaFlag = (T_FLAGS_INFO *)(CFG_TEMP_ADDR);
lh9ed821d2023-04-07 01:36:19 -0700251 }
252
xf.li6c8fc1e2023-08-12 00:11:09 -0700253 bootTarget = fotaFlag->boot_fota_flag.boot_to;
lh9ed821d2023-04-07 01:36:19 -0700254
255 writel(DUALSYSTEM_STATUS_BOOTABLE, BOOT_FLAG_ADDR);/*ĬÈÏ¿ÉÆô¶¯*/
256
257 if(bootTarget == DUAL_SYSTEM)
258 {
xf.li6c8fc1e2023-08-12 00:11:09 -0700259 if (fotaFlag->boot_fota_flag.system.status == DUALSYSTEM_STATUS_UNBOOTABLE)
lh9ed821d2023-04-07 01:36:19 -0700260 {
261 printf("dual_system status is unbootable!");
262 goto error;
263 }
264 ret = read_uboot_image((uint8_t *)UBOOT_IMAGE, &uboot_entry_point);
265 if( ret != 0)
266 {
267 printf("read uboot1 image error, goto uboot2!");
268 writel(DUALSYSTEM_STATUS_UNBOOTABLE, BOOT_FLAG_ADDR);
269 ret = read_uboot_image((uint8_t *)UBOOT2_IMAGE, &uboot_entry_point);
270 if( ret != 0)
271 {
272 printf("read uboot2 iamge error!");
273 goto error;
274 }
275 }
276 else
277 printf("goto uboot!");
278 }
279 else if(bootTarget == DUAL_SYSTEM2)
280 {
xf.li6c8fc1e2023-08-12 00:11:09 -0700281 if (fotaFlag->boot_fota_flag.system2.status == DUALSYSTEM_STATUS_UNBOOTABLE)
lh9ed821d2023-04-07 01:36:19 -0700282 {
283 printf("dual_system2 status is unbootable!");
284 goto error;
285 }
286 ret = read_uboot_image((uint8_t *)UBOOT2_IMAGE, &uboot_entry_point);
287 if( ret != 0)
288 {
289 printf("read uboot2 iamge error, goto uboot!");
290 writel(DUALSYSTEM_STATUS_UNBOOTABLE, BOOT_FLAG_ADDR);
291 ret = read_uboot_image((uint8_t *)UBOOT_IMAGE, &uboot_entry_point);
292 if( ret != 0)
293 {
294 printf("read uboot iamge error!");
295 goto error;
296 }
297 }
298 else
299 printf("goto uboot2!");
300 }
301 else
302 {
303 printf("boot target get error!");
304 goto error;
305 }
306
307 if(err_flag == 1)
308 {
309 writel(FLAGS_PARTITION_ERROR, BOOT_FLAG_ADDR);
310 }
311
312 printf("read uboot ok.\n");
313
314 /* set arm jump PC start code */
315 writel(0xE59ff000, SYS_IRAM1_BASE);
316 writel(uboot_entry_point, SYS_IRAM1_BASE + 8);
317
318 printf("start uboot...\n");
319 /* Relese A9 Core, A9 start to run uboot right now. */
320 writel(CPU_UFI_SW_RSTEN, CPU_A9_SUBSYS_CFG);
321
322
323 /* waiting for uboot read m0 image. */
324 uint32_t m0_entry_point = 0;
325 ret = nand_read_m0(&m0_entry_point);
326 if(ret != 0)
327 {
328 goto error;
329 }
330
331 /* M0 Core start to run cpurpm right now. */
332 ((init_fnc_t *)m0_entry_point)();
333
334#endif
335
336error:
337 printf("ERR\n");
338 hang();
339}
340#else
341void start_armboot (void)
342{
343 int32_t ret = 0;
344 uint32_t amt_value = 0;
345
346
347 clk_init();
348 timer_init();
349#if CFG_PRINTF
350 uart_init();
351#endif
352 print_info();
353
354 /* After reset, Copy zloader forcely. */
355 /* Now IRAM1 maybe occupied by dirty data. */
356 writel(0, CFG_START_STAGE1_ADDR);
357 amt_value = readl(CFG_AMT_MODE_SWITCH_ADDR);
358 clear_iram();
359 writel(amt_value, CFG_AMT_MODE_SWITCH_ADDR);
360
361 ret = board_flash_init();
362 if(ret != 0)
363 {
364 goto error;
365 }
366
367 efuse_init();
368
369 if(get_ddr_flag() == CHIP_DDR_IS_32M)
370 {
371 ddr_init(CHIP_DDR_IS_32M);
372 }
373 else if(get_ddr_flag() == CHIP_DDR_IS_64M)
374 {
375 ddr_init(CHIP_DDR_IS_64M);
376 }
377 else if(get_ddr_flag() == CHIP_DDR_IS_128M)
378 {
379 ddr_init(CHIP_DDR_IS_128M);
380 }
381 else
382 {
383 ddr_init(CHIP_DDR_IS_256M);
384 }
385
386
387 usb_apcore_poweroff();
388/********************* ÔËÐÐT-LOAD,½øÈëÏÂÔØÄ£Ê½ ******************/
389#if defined(CFG_TLOAD)
390 write_loader_mode(CFG_TLOAD_MODE);
391
392#if CFG_USB
393 usb_boot(SYS_USB_BASE);
394#endif
395
396#if CFG_UART
397 uart_boot();
398#endif
399
400#endif /* CFG_TLOAD */
401
402/********************* ÔËÐÐZ-LOAD,½øÈëÕý³£Æô¶¯Ä£Ê½ **********/
403#if defined(CFG_ZLOAD)
404 uint32_t uboot_entry_point = 0;
405 char boot_mode = 0;
406
407 write_loader_mode(CFG_ZLOAD_MODE);
408
409 ret = read_uboot_image((uint8_t *)UBOOT_IMAGE, &uboot_entry_point);
410 if( ret != 0 )
411 {
412 boot_mode = get_boot_mode();
413 if((boot_mode == SPI_NAND_BOOT) || (boot_mode == NAND_BOOT))
414 {
415 ret = read_uboot_image((uint8_t *)UBOOT_MIRROR_IMAGE,
416 &uboot_entry_point);
417 if(ret != 0)
418 {
419 goto error;
420 }
421 }
422 else
423 {
424 goto error;
425 }
426 }
xf.li9d1a0e12023-09-20 01:43:20 -0700427 //printf("read uboot ok.\n");
lh9ed821d2023-04-07 01:36:19 -0700428
429 /* set arm jump PC start code */
430 writel(0xE59ff000, SYS_IRAM1_BASE);
431 writel(uboot_entry_point, SYS_IRAM1_BASE + 8);
432
433 printf("start uboot...\n");
434 /* Relese A9 Core, A9 start to run uboot right now. */
435 writel(CPU_UFI_SW_RSTEN, CPU_A9_SUBSYS_CFG);
436
437
438 /* waiting for uboot read m0 image. */
439 uint32_t m0_entry_point = 0;
440 ret = nand_read_m0(&m0_entry_point);
441 if(ret != 0)
442 {
443 goto error;
444 }
445
446 /* M0 Core start to run cpurpm right now. */
447 ((init_fnc_t *)m0_entry_point)();
448
449#endif
450
451error:
452 printf("ERR\n");
453 hang();
454}
455#endif