blob: 3ddc41fed2973790c3ec35976b595daa7e238472 [file] [log] [blame]
l.yangb8fdece2024-10-10 14:56:17 +08001/*
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"
20#include "pub_flags.h"
21
22#define FLAGS_PARTITION_ERROR (0x1111) /*·ÖÇøÒì³£*/
23//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
28typedef 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
142#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF)
143void 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;
l.yangc3c1e4d2024-10-10 15:12:55 +0800149 int32_t switch_flag = 0;
l.yangb8fdece2024-10-10 14:56:17 +0800150 T_BOOT_TARGET bootTarget;
151 T_FLAGS flagsData;
152 T_FLAGS_INFO *fotaFlag;
153 T_BOOT_DUALSYSTEM_TYPE dualSystemType;
154
155 clk_init();
156 timer_init();
157#if CFG_PRINTF
158 uart_init();
159#endif
160//xf.li@20230815 add for download without powerkey start
161#if 1//pshold on
162 amt_value = readl(IO_CFG_BASE+0x4);
163 amt_value &= ~(3<<28);
164 writel(amt_value, (IO_CFG_BASE+0x4));
165 /*direction: out*/
166 amt_value = readl(GPIO0_REG_BASE + (GPIO24_PSHOLD/16)*0x40);
167 amt_value &= ~(1<<(24%16));
168 writel(amt_value, GPIO0_REG_BASE + (GPIO24_PSHOLD/16)*0x40);
169 /*set out 1*/
170 amt_value = readl(GPIO0_REG_BASE + 0x18+ (GPIO24_PSHOLD/16)*0x40);
171 amt_value |= (1<<(24%16));
172 writel(amt_value, GPIO0_REG_BASE + 0x18+ (GPIO24_PSHOLD/16)*0x40);
173#endif
174//xf.li@20230815 add for download without powerkey end
175 print_info();
176
177 /* After reset, Copy zloader forcely. */
178 /* Now IRAM1 maybe occupied by dirty data. */
179 writel(0, CFG_START_STAGE1_ADDR);
180 amt_value = readl(CFG_AMT_MODE_SWITCH_ADDR);
181 clear_iram();
182 writel(amt_value, CFG_AMT_MODE_SWITCH_ADDR);
183
184 ret = board_flash_init();
185 if(ret != 0)
186 {
187 goto error;
188 }
189
190 efuse_init();
191
192 if(get_ddr_flag() == CHIP_DDR_IS_32M)
193 {
194 ddr_init(CHIP_DDR_IS_32M);
195 }
196 else if(get_ddr_flag() == CHIP_DDR_IS_64M)
197 {
198 ddr_init(CHIP_DDR_IS_64M);
199 }
200 else if(get_ddr_flag() == CHIP_DDR_IS_128M)
201 {
202 ddr_init(CHIP_DDR_IS_128M);
203 }
204 else if(get_ddr_flag() == CHIP_DDR_IS_256M)
205 {
206 ddr_init(CHIP_DDR_IS_256M);
207 }
208 else if(get_ddr_flag() == CHIP_DDR_IS_512M)
209 {
210 ddr_init(CHIP_DDR_IS_512M);
211 }
212 else
213 {
214 ddr_init(CHIP_DDR_IS_128M);
215 }
216
217 usb_apcore_poweroff();
218/********************* ÔËÐÐT-LOAD,½øÈëÏÂÔØÄ£Ê½ ******************/
219#if defined(CFG_TLOAD)
220 write_loader_mode(CFG_TLOAD_MODE);
221
222#if CFG_USB
223 usb_boot(SYS_USB_BASE);
224#endif
225
226#if CFG_UART
227 uart_boot();
228#endif
229
230#endif /* CFG_TLOAD */
231
232/********************* ÔËÐÐZ-LOAD,½øÈëÕý³£Æô¶¯Ä£Ê½ **********/
233#if defined(CFG_ZLOAD)
234 uint32_t uboot_entry_point = 0;
235 char boot_mode = 0;
236
237 write_loader_mode(CFG_ZLOAD_MODE);
238
239 /*read flags·ÖÇø*/
240 ret = read_flags_image((uint8_t *)FLAGS_IMAGE);
241
242 if( ret != 0 )
243 {
244 printf("read flags partition error! Use default parameters\n");
245 //goto error;
246 err_flag = 1;
247
248 /*ĬÈÏflags·ÖÇøÊý¾Ý*/
249 flagsData.magic_start = FLAGS_MAGIC;
250 flagsData.boot_fota_flag.boot_to = DUAL_SYSTEM;
251 flagsData.boot_fota_flag.fota_status = 1;
252 flagsData.boot_fota_flag.system.status = DUALSYSTEM_STATUS_BOOTABLE;
253 flagsData.boot_fota_flag.system2.status = DUALSYSTEM_STATUS_BOOTABLE;
254 flagsData.magic_end = FLAGS_MAGIC;
255 fotaFlag = &flagsData;
256 }
257 else
258 {
259 fotaFlag = (T_FLAGS_INFO *)(CFG_TEMP_ADDR);
260 }
261
262 bootTarget = fotaFlag->boot_fota_flag.boot_to;
263
264 writel(DUALSYSTEM_STATUS_BOOTABLE, BOOT_FLAG_ADDR);/*ĬÈÏ¿ÉÆô¶¯*/
265
266 if(bootTarget == DUAL_SYSTEM)
267 {
268 if (fotaFlag->boot_fota_flag.system.status == DUALSYSTEM_STATUS_UNBOOTABLE)
269 {
270 printf("dual_system status is unbootable!");
l.yangc3c1e4d2024-10-10 15:12:55 +0800271 //goto error;
272 if(fotaFlag->boot_fota_flag.system2.status == DUALSYSTEM_STATUS_UNBOOTABLE)
273 {
274 printf("system status is both unbootable,restart system1!");
275 err_flag = 1;
276 /*ĬÈÏflags·ÖÇøÊý¾Ý*/
277 flagsData.magic_start = FLAGS_MAGIC;
278 flagsData.boot_fota_flag.boot_to = DUAL_SYSTEM;
279 flagsData.boot_fota_flag.fota_status = 1;
280 flagsData.boot_fota_flag.system.status = DUALSYSTEM_STATUS_BOOTABLE;
281 flagsData.boot_fota_flag.system2.status = DUALSYSTEM_STATUS_BOOTABLE;
282 flagsData.magic_end = FLAGS_MAGIC;
283 fotaFlag = &flagsData;
284 }
285 else
286 {
287 writel(DUALSYSTEM_STATUS_UNBOOTABLE, BOOT_FLAG_ADDR);
288 printf("restart system2!");
289 switch_flag = 1;
290 }
291
l.yangb8fdece2024-10-10 14:56:17 +0800292 }
l.yangc3c1e4d2024-10-10 15:12:55 +0800293
294 if(1 == switch_flag)
295 {
296 ret = read_uboot_image((uint8_t *)UBOOT2_IMAGE, &uboot_entry_point);
l.yangb8fdece2024-10-10 14:56:17 +0800297 if( ret != 0)
298 {
l.yangc3c1e4d2024-10-10 15:12:55 +0800299 printf("read uboot2 image error, goto uboot!");
300 writel(DUALSYSTEM_STATUS_UNBOOTABLE, BOOT_FLAG_ADDR);
301 ret = read_uboot_image((uint8_t *)UBOOT_IMAGE, &uboot_entry_point);
302 if( ret != 0)
303 {
304 printf("read uboot image error!");
305 goto error;
306 }
l.yangb8fdece2024-10-10 14:56:17 +0800307 }
l.yangc3c1e4d2024-10-10 15:12:55 +0800308 else
309 printf("goto uboot2!");
l.yangb8fdece2024-10-10 14:56:17 +0800310 }
l.yangc3c1e4d2024-10-10 15:12:55 +0800311 else
312 {
313 ret = read_uboot_image((uint8_t *)UBOOT_IMAGE, &uboot_entry_point);
314 if( ret != 0)
315 {
316 printf("read uboot1 image error, goto uboot2!");
317 writel(DUALSYSTEM_STATUS_UNBOOTABLE, BOOT_FLAG_ADDR);
318 ret = read_uboot_image((uint8_t *)UBOOT2_IMAGE, &uboot_entry_point);
319 if( ret != 0)
320 {
321 printf("read uboot2 image error!");
322 goto error;
323 }
324 }
325 else
326 printf("goto uboot!");
327 }
328
l.yangb8fdece2024-10-10 14:56:17 +0800329 }
330 else if(bootTarget == DUAL_SYSTEM2)
331 {
332 if (fotaFlag->boot_fota_flag.system2.status == DUALSYSTEM_STATUS_UNBOOTABLE)
333 {
334 printf("dual_system2 status is unbootable!");
l.yangc3c1e4d2024-10-10 15:12:55 +0800335 //goto error;
336 if(fotaFlag->boot_fota_flag.system.status == DUALSYSTEM_STATUS_UNBOOTABLE)
337 {
338 printf("system status is both unbootable,restart system2!");
339 err_flag = 1;
340 /*ĬÈÏflags·ÖÇøÊý¾Ý*/
341 flagsData.magic_start = FLAGS_MAGIC;
342 flagsData.boot_fota_flag.boot_to = DUAL_SYSTEM2;
343 flagsData.boot_fota_flag.fota_status = 1;
344 flagsData.boot_fota_flag.system.status = DUALSYSTEM_STATUS_BOOTABLE;
345 flagsData.boot_fota_flag.system2.status = DUALSYSTEM_STATUS_BOOTABLE;
346 flagsData.magic_end = FLAGS_MAGIC;
347 fotaFlag = &flagsData;
348 }
349 else
350 {
351 writel(DUALSYSTEM_STATUS_UNBOOTABLE, BOOT_FLAG_ADDR);
352 printf("restart system1!");
353 switch_flag = 1;
l.yangb8fdece2024-10-10 14:56:17 +0800354 }
355 }
l.yangc3c1e4d2024-10-10 15:12:55 +0800356
357 if(1 == switch_flag)
358 {
359 ret = read_uboot_image((uint8_t *)UBOOT_IMAGE, &uboot_entry_point);
360 if( ret != 0)
361 {
362 printf("read uboot image error, goto uboot2!");
363 writel(DUALSYSTEM_STATUS_UNBOOTABLE, BOOT_FLAG_ADDR);
364 ret = read_uboot_image((uint8_t *)UBOOT2_IMAGE, &uboot_entry_point);
365 if( ret != 0)
366 {
367 printf("read uboot2 image error!");
368 goto error;
369 }
370 }
371 else
372 printf("goto uboot!");
373 }
l.yangb8fdece2024-10-10 14:56:17 +0800374 else
l.yangc3c1e4d2024-10-10 15:12:55 +0800375 {
376 ret = read_uboot_image((uint8_t *)UBOOT2_IMAGE, &uboot_entry_point);
377 if( ret != 0)
378 {
379 printf("read uboot2 image error, goto uboot!");
380 writel(DUALSYSTEM_STATUS_UNBOOTABLE, BOOT_FLAG_ADDR);
381 ret = read_uboot_image((uint8_t *)UBOOT_IMAGE, &uboot_entry_point);
382 if( ret != 0)
383 {
384 printf("read uboot image error!");
385 goto error;
386 }
387 }
388 else
389 printf("goto uboot2!");
390 }
391
l.yangb8fdece2024-10-10 14:56:17 +0800392 }
393 else
394 {
395 printf("boot target get error!");
396 goto error;
397 }
398
399 if(err_flag == 1)
400 {
401 writel(FLAGS_PARTITION_ERROR, BOOT_FLAG_ADDR);
402 }
403
404 printf("read uboot ok.\n");
405
406 /* set arm jump PC start code */
407 writel(0xE59ff000, SYS_IRAM1_BASE);
408 writel(uboot_entry_point, SYS_IRAM1_BASE + 8);
409
410 printf("start uboot...\n");
411 /* Relese A9 Core, A9 start to run uboot right now. */
412 writel(CPU_UFI_SW_RSTEN, CPU_A9_SUBSYS_CFG);
413
414
415 /* waiting for uboot read m0 image. */
416 uint32_t m0_entry_point = 0;
417 ret = nand_read_m0(&m0_entry_point);
418 if(ret != 0)
419 {
420 goto error;
421 }
422
423 /* M0 Core start to run cpurpm right now. */
424 ((init_fnc_t *)m0_entry_point)();
425
426#endif
427
428error:
429 printf("ERR\n");
430 hang();
431}
432#else
433void start_armboot (void)
434{
435 int32_t ret = 0;
436 uint32_t amt_value = 0;
437
438
439 clk_init();
440 timer_init();
441#if CFG_PRINTF
442 uart_init();
443#endif
444 print_info();
445
446 /* After reset, Copy zloader forcely. */
447 /* Now IRAM1 maybe occupied by dirty data. */
448 writel(0, CFG_START_STAGE1_ADDR);
449 amt_value = readl(CFG_AMT_MODE_SWITCH_ADDR);
450 clear_iram();
451 writel(amt_value, CFG_AMT_MODE_SWITCH_ADDR);
452
453 ret = board_flash_init();
454 if(ret != 0)
455 {
456 goto error;
457 }
458
459 efuse_init();
460
461 if(get_ddr_flag() == CHIP_DDR_IS_32M)
462 {
463 ddr_init(CHIP_DDR_IS_32M);
464 }
465 else if(get_ddr_flag() == CHIP_DDR_IS_64M)
466 {
467 ddr_init(CHIP_DDR_IS_64M);
468 }
469 else if(get_ddr_flag() == CHIP_DDR_IS_128M)
470 {
471 ddr_init(CHIP_DDR_IS_128M);
472 }
473 else if(get_ddr_flag() == CHIP_DDR_IS_256M)
474 {
475 ddr_init(CHIP_DDR_IS_256M);
476 }
477 else if(get_ddr_flag() == CHIP_DDR_IS_512M)
478 {
479 ddr_init(CHIP_DDR_IS_512M);
480 }
481 else
482 {
483 ddr_init(CHIP_DDR_IS_128M);
484 }
485
486
487 usb_apcore_poweroff();
488/********************* ÔËÐÐT-LOAD,½øÈëÏÂÔØÄ£Ê½ ******************/
489#if defined(CFG_TLOAD)
490 write_loader_mode(CFG_TLOAD_MODE);
491
492#if CFG_USB
493 usb_boot(SYS_USB_BASE);
494#endif
495
496#if CFG_UART
497 uart_boot();
498#endif
499
500#endif /* CFG_TLOAD */
501
502/********************* ÔËÐÐZ-LOAD,½øÈëÕý³£Æô¶¯Ä£Ê½ **********/
503#if defined(CFG_ZLOAD)
504 uint32_t uboot_entry_point = 0;
505 char boot_mode = 0;
506
507 write_loader_mode(CFG_ZLOAD_MODE);
508
509 ret = read_uboot_image((uint8_t *)UBOOT_IMAGE, &uboot_entry_point);
510 if( ret != 0 )
511 {
512 boot_mode = get_boot_mode();
513 if((boot_mode == SPI_NAND_BOOT) || (boot_mode == NAND_BOOT))
514 {
515 ret = read_uboot_image((uint8_t *)UBOOT_MIRROR_IMAGE,
516 &uboot_entry_point);
517 if(ret != 0)
518 {
519 goto error;
520 }
521 }
522 else
523 {
524 goto error;
525 }
526 }
527 //printf("read uboot ok.\n");
528
529 /* set arm jump PC start code */
530 writel(0xE59ff000, SYS_IRAM1_BASE);
531 writel(uboot_entry_point, SYS_IRAM1_BASE + 8);
532
533 printf("start uboot...\n");
534 /* Relese A9 Core, A9 start to run uboot right now. */
535 writel(CPU_UFI_SW_RSTEN, CPU_A9_SUBSYS_CFG);
536
537
538 /* waiting for uboot read m0 image. */
539 uint32_t m0_entry_point = 0;
540 ret = nand_read_m0(&m0_entry_point);
541 if(ret != 0)
542 {
543 goto error;
544 }
545
546 /* M0 Core start to run cpurpm right now. */
547 ((init_fnc_t *)m0_entry_point)();
548
549#endif
550
551error:
552 printf("ERR\n");
553 hang();
554}
555#endif