bootmain.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. /**
  2. ******************************************************************************
  3. * @file bootmain.c
  4. * @author StarFive Technology
  5. * @version V1.0
  6. * @date 07/29/2020
  7. * @brief
  8. ******************************************************************************
  9. * @copy
  10. *
  11. * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  12. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  13. * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
  14. * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  15. * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  16. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  17. *
  18. * COPYRIGHT 20120 Shanghai StarFive Technology Co., Ltd.
  19. */
  20. #include "sys.h"
  21. #include "spi_flash.h"
  22. #include "spi.h"
  23. #include "timer.h"
  24. #include "encoding.h"
  25. #include "gpt.h"
  26. #include "clkgen_ctrl_macro.h"
  27. #include "syscon_sysmain_ctrl_macro.h"
  28. #include "rstgen_ctrl_macro.h"
  29. #include "crc32.h"
  30. extern void boot_sdio_init(void);
  31. extern int boot_load_gpt_partition(void* dst, const gpt_guid* partition_type_guid);
  32. extern const gpt_guid gpt_guid_sifive_uboot;
  33. extern const gpt_guid gpt_guid_sifive_kernel;
  34. extern unsigned int receive_count;
  35. typedef void ( *STARTRUNNING )( unsigned int par1 );
  36. /*
  37. To run a procedure from the address:start
  38. start: start address of runing in armmode, not do address align checking
  39. */
  40. void start2run32(unsigned int start)
  41. {
  42. (( STARTRUNNING )(start))(0);
  43. }
  44. #define SPIBOOT_LOAD_ADDR_OFFSET 252
  45. /*read data from flash to the destination address
  46. *
  47. *spi_flash: flash device informations
  48. *des_addr: store the data read from flash
  49. *page_offset:Offset of data stored in flash
  50. *mode:flash work mode
  51. */
  52. static int load_data(struct spi_flash* spi_flash,void *des_addr,unsigned int page_offset,int mode)
  53. {
  54. u8 dataBuf[260];
  55. u32 startPage,endPage;
  56. u32 pageSize;
  57. u32 fileSize;
  58. u8 *addr;
  59. int ret;
  60. int i;
  61. u32 offset;
  62. pageSize = spi_flash->page_size;
  63. addr = (u8 *)des_addr;
  64. offset = page_offset*pageSize;
  65. /*read first page,get the file size*/
  66. ret = spi_flash->read(spi_flash,offset,pageSize,dataBuf,mode);
  67. if(ret != 0)
  68. {
  69. printk("read fail#\r\n");
  70. return -1;
  71. }
  72. /*calculate file size*/
  73. fileSize = (dataBuf[3] << 24) | (dataBuf[2] << 16) | (dataBuf[1] << 8) | (dataBuf[0]) ;
  74. if(fileSize == 0)
  75. return -1;
  76. endPage = ((fileSize + 255) >> 8);//page align
  77. /*copy the first page data*/
  78. sys_memcpy(addr, &dataBuf[4], SPIBOOT_LOAD_ADDR_OFFSET);
  79. //copy data from flash to des_addr, with crc check
  80. #if 1
  81. uint32_t crc_org = 0, crc_ddr = 0;
  82. uint32_t n_bytes_left = fileSize - SPIBOOT_LOAD_ADDR_OFFSET;
  83. uint32_t once = 0;
  84. crc32(dataBuf+4, SPIBOOT_LOAD_ADDR_OFFSET, &crc_org);
  85. crc32(addr, SPIBOOT_LOAD_ADDR_OFFSET, &crc_ddr);
  86. offset += pageSize;
  87. addr += SPIBOOT_LOAD_ADDR_OFFSET;
  88. /*read Remaining pages data*/
  89. while (n_bytes_left) {
  90. once = n_bytes_left > pageSize ? pageSize : n_bytes_left;
  91. ret = spi_flash->read(spi_flash, offset, once, dataBuf, mode);
  92. if(ret != 0)
  93. {
  94. printk("read 0x%x fail##\r\n", offset);
  95. return -1;
  96. }
  97. sys_memcpy(addr, dataBuf, once);
  98. crc32(dataBuf, once, &crc_org);
  99. crc32(addr, once, &crc_ddr);
  100. offset += once;
  101. addr += once;
  102. n_bytes_left -= once;
  103. }
  104. printk("crc flash: %08x, crc ddr: %08x\r\n", crc_org, crc_ddr);
  105. if (crc_org != crc_ddr) {
  106. printk("ERROR: crc check FAILED\r\n");
  107. while (1) {
  108. __asm__ ("wfi");
  109. }
  110. } else {
  111. printk("crc check PASSED\r\n");
  112. }
  113. #else
  114. offset += pageSize;
  115. addr += SPIBOOT_LOAD_ADDR_OFFSET;
  116. for(i=1; i<=endPage; i++)
  117. {
  118. ret = spi_flash->read(spi_flash,offset,pageSize, addr, mode);
  119. if(ret != 0)
  120. {
  121. printk("read fail##\r\n");
  122. return -1;
  123. }
  124. offset += pageSize;
  125. addr +=pageSize;
  126. }
  127. #endif
  128. return 0;
  129. }
  130. int updata_flash(struct spi_flash* spi_flash,u32 flash_addr,u32 flash_size_limit, u32 load_addr,unsigned char mode)
  131. {
  132. int ret = 0;
  133. u32 offset = 0;
  134. int erase_block = 0;
  135. unsigned int page_count = 0;
  136. unsigned int index = 0;
  137. unsigned int blockSize,pageSize;
  138. u8 *data;
  139. printk("send file by xmodem\r\n");
  140. blockSize = spi_flash->block_size;
  141. pageSize = spi_flash->page_size;
  142. ret = xmodemReceive((unsigned char *)load_addr,0);
  143. if(ret <= 0)
  144. return -1;
  145. if ((u32)ret > flash_size_limit) {
  146. printk("error: size %d exceeds the limit %d\r\n", ret, flash_size_limit);
  147. return -1;
  148. }
  149. erase_block = (ret + blockSize - 1) / blockSize;
  150. page_count = (ret + pageSize - 1) / pageSize;
  151. /*erase flash*/
  152. offset = flash_addr;
  153. for(index=0; index<erase_block; index++)
  154. {
  155. ret = spi_flash->erase(spi_flash, offset, blockSize, 64);
  156. if(ret < 0)
  157. {
  158. printk("erases block %d fail\r\n",offset);
  159. return -1;
  160. }
  161. offset +=blockSize;
  162. }
  163. /*write data*/
  164. offset = flash_addr;
  165. data = (u8 *)load_addr;
  166. for(index=0; index<page_count; index++)
  167. {
  168. ret = spi_flash->write(spi_flash, offset,pageSize, data, mode);
  169. printk(".");
  170. if(index%64 == 0)
  171. printk("\r\n");
  172. if(ret < 0)
  173. {
  174. printk("write page %d fail\r\n",offset);
  175. return -1;
  176. }
  177. offset +=pageSize;
  178. data += pageSize;
  179. }
  180. return 0;
  181. }
  182. static int updata_flash_code(struct spi_flash* spi_flash,unsigned int updata_num,unsigned char mode)
  183. {
  184. int ret = 0;
  185. switch (updata_num){
  186. case 0:
  187. ret = updata_flash(spi_flash,FLASH_SECONDBOOT_START_ADDR,FLASH_SECONDBOOT_SIZE_LIMIT,DEFAULT_SECONDBOOT_LOAD_ADDR,mode);
  188. break;
  189. case 1:
  190. ret = updata_flash(spi_flash,FLASH_DDRINIT_START_ADDR,FLASH_DDRINIT_SIZE_LIMIT,DEFAULT_DDRINIT_LOAD_ADDR,mode);
  191. break;
  192. case 2:
  193. ret = updata_flash(spi_flash,FLASH_UBOOT_START_ADDR,FLASH_UBOOT_SIZE_LIMIT,DEFAULT_UBOOT_LOAD_ADDR,mode);
  194. break;
  195. default:
  196. break;
  197. }
  198. return ret;
  199. }
  200. static int prog_2ndboot(struct spi_flash *flash, int mode)
  201. {
  202. updata_flash_code(flash, 0, mode);
  203. return 0;
  204. }
  205. static int prog_ddrinit(struct spi_flash *flash, int mode)
  206. {
  207. updata_flash_code(flash, 1, mode);
  208. return 0;
  209. }
  210. static int prog_uboot(struct spi_flash *flash, int mode)
  211. {
  212. updata_flash_code(flash, 2, mode);
  213. return 0;
  214. }
  215. typedef struct
  216. {
  217. const char *text;
  218. int (*prog_op)(struct spi_flash *, int);
  219. } prog_menu_t;
  220. static int prog_menu(struct spi_flash *flash, int mode, const prog_menu_t *menu, int count)
  221. {
  222. int i, sel;
  223. char buff[32]={0};
  224. char *str = NULL, *str_end = NULL;
  225. const char *ROOT_MENU_KEY = "root@s5t";
  226. while (1) {
  227. printk("\r\n");
  228. for (i = 0; i < count; i++) {
  229. printk("%d:%s\r\n", i, menu[i].text);
  230. }
  231. printk("%d:quit\r\n", count);
  232. printk("select the function: ");
  233. serial_gets(buff);
  234. str = buff;
  235. while (*str == '\n' || *str == ' ') {
  236. //skip white
  237. str++;
  238. }
  239. if (strcmp(str, ROOT_MENU_KEY) == 0) {
  240. //request root menu
  241. return 1;
  242. }
  243. sel = (int)strtol(str, &str_end, 10);
  244. if (str == str_end || sel < 0 || sel > count) {
  245. //invalid sel
  246. continue;
  247. }
  248. if (sel == count) {
  249. //quit
  250. printk("\r\nquit\r\n");
  251. return 0;
  252. }
  253. if (menu[sel].prog_op) {
  254. menu[sel].prog_op(flash, mode);
  255. }
  256. }
  257. return 0;
  258. }
  259. static void prog_flash(void)
  260. {
  261. prog_menu_t user_menu[] = {
  262. { "update uboot", prog_uboot },
  263. };
  264. prog_menu_t root_menu[] = {
  265. { "update second boot", prog_2ndboot },
  266. { "update ddr init boot", prog_ddrinit },
  267. { "update uboot", prog_uboot },
  268. };
  269. struct spi_flash *flash = NULL;
  270. unsigned char mode = 1;// or 4
  271. cadence_qspi_init(0, mode);
  272. flash = spi_flash_probe(0, 0, 31250000, 0, (u32)SPI_DATAMODE_8);
  273. printk("\r\n***************************************************\r\n");
  274. printk("*************** FLASH PROGRAMMING *****************\r\n");
  275. printk("***************************************************\r\n");
  276. if (prog_menu(flash, mode, &user_menu, sizeof(user_menu)/sizeof(user_menu[0]))) {
  277. prog_menu(flash, mode, &root_menu, ARRAY_SIZE(root_menu));
  278. }
  279. }
  280. void boot_from_chiplink(void)
  281. {
  282. int bootdelay = 3;
  283. int abort = 0;
  284. char str[6];
  285. char *tmp;
  286. int ret=0;
  287. s32 usel;
  288. unsigned long ts;
  289. struct spi_flash* spi_flash;
  290. unsigned char mode = 1;// or 4
  291. while ((bootdelay > 0) && (!abort)) {
  292. --bootdelay;
  293. /* delay 1000 ms */
  294. ts = get_timer(0);
  295. do {
  296. if (serial_tstc()) { /* we got a key press */
  297. abort = 1; /* don't auto boot */
  298. bootdelay = 0; /* no more delay */
  299. serial_getc(); /* consume input */
  300. break;
  301. }
  302. mdelay(100);
  303. } while (!abort && get_timer(ts) < 1000);
  304. printk("\b\b\b%d ", bootdelay);
  305. }
  306. if(1 == abort)
  307. {
  308. prog_flash();
  309. #if 0
  310. cadence_qspi_init(0, mode);
  311. spi_flash = spi_flash_probe(0, 0, 31250000, 0, (u32)SPI_DATAMODE_8);
  312. printk("***************************************************\r\n");
  313. printk("***************VIC DDR INIT BOOT ********************\r\n");
  314. printk("***************************************************\r\n");
  315. again:
  316. tmp = str;
  317. printk("0:updata second boot\r\n");
  318. printk("1:updata ddr init boot\r\n");
  319. printk("2:updata uboot\r\n");
  320. printk("3:quit\r\n");
  321. printk("Select the function to test : ");
  322. serial_gets(str);
  323. if(str[0] == 0)
  324. goto again;
  325. while(*tmp == 4){tmp++;} /*skip EOT*/
  326. usel = atoi(tmp);
  327. if(usel > 3)
  328. {
  329. printk("error select,try again\r\n");
  330. goto again;
  331. }
  332. /*quit*/
  333. if(usel == 3)
  334. return;
  335. printk("usel:%d\n",usel);
  336. ret = updata_flash_code(spi_flash,usel,mode);
  337. if(ret < 0)
  338. printk("updata fail\r\n");
  339. else
  340. printk("updata success\r\n");
  341. goto again;
  342. #endif
  343. }
  344. }
  345. void boot_from_uart(void)
  346. {
  347. sys_cmd_proc();
  348. }
  349. void boot_from_sdio(void)
  350. {
  351. boot_sdio_init();
  352. /*load uboot bin file from sd card*/
  353. boot_load_gpt_partition((void *)DEFAULT_UBOOT_ADDR,&gpt_guid_sifive_uboot);
  354. /*load kernel bin file from sd card*/
  355. // boot_load_gpt_partition((void *)DEFAULT_KERNEL_ADDR,&gpt_guid_sifive_kernel);
  356. }
  357. void boot_from_spi(int mode)
  358. {
  359. struct spi_flash* spi_flash;
  360. int ret;
  361. u32 *addr;
  362. u32 val;
  363. cadence_qspi_init(0, mode);
  364. spi_flash = spi_flash_probe(0, 0, 31250000, 0, (u32)SPI_DATAMODE_8);
  365. /*load uboot*/
  366. load_data(spi_flash,DEFAULT_UBOOT_ADDR,DEFAULT_UBOOT_OFFSET,mode);
  367. }
  368. static int init_ddr(void)
  369. {
  370. int fail_flag = 0;
  371. uint32_t tmp;
  372. uint32_t OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR;
  373. uint64_t mem_addr;
  374. uint32_t wdata;
  375. int i = 0;
  376. u32 count = 0;
  377. uint64_t base_addr = U74_SYS_PORT_DDRC_BASE_ADDR;
  378. ///printf_led("Main start");
  379. //Set PLL to 15750M
  380. //_ASSERT_RESET_rstgen_rstn_ddrphy_apb_ //reset ddrphy,unvalid
  381. _SWITCH_CLOCK_clk_dla_root_SOURCE_clk_osc_sys_;
  382. //SCFG_PLL [31:24] [23:16] [15:8] [7:4] [3] [2] [1] [0]
  383. // OD BWADJ CLKFDIV CLKR bypass infb pd rst
  384. #if defined(DDR_2133)
  385. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x292905);//set reset
  386. udelay(10); //wait(500*(1/25M))
  387. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x0292904);//clear reset
  388. udelay(10); //wait(500*(1/25M))
  389. #elif defined(DDR_2800)
  390. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x373705);//set reset
  391. udelay(10); //wait(500*(1/25M))
  392. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x0373704);//clear reset
  393. udelay(10); //wait(500*(1/25M))
  394. #elif defined(DDR_3200)
  395. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x3f3f05);//set reset
  396. udelay(10); //wait(500*(1/25M))
  397. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x03f3f04);//clear reset
  398. udelay(10); //wait(500*(1/25M))
  399. #endif
  400. _SWITCH_CLOCK_clk_dla_root_SOURCE_clk_pll1_out_;
  401. //_CLEAR_RESET_rstgen_rstn_ddrphy_apb_ //clear reset of ddrphy,unvalid
  402. //ddrc_clock=400M test
  403. //_SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrpll_div4_;
  404. //_SWITCH_CLOCK_clk_ddrc1_SOURCE_clk_ddrpll_div4_;
  405. //ddrc_clock=800M
  406. //_SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrpll_div2_;
  407. //_SWITCH_CLOCK_clk_ddrc1_SOURCE_clk_ddrpll_div2_;
  408. //12.5M
  409. _SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrosc_div2_;
  410. _SWITCH_CLOCK_clk_ddrc1_SOURCE_clk_ddrosc_div2_;
  411. _ENABLE_CLOCK_clk_ddrc0_;
  412. _ENABLE_CLOCK_clk_ddrc1_;
  413. #if 0
  414. _ENABLE_CLOCK_clk_ddrphy_apb_ ;
  415. _CLEAR_RESET_rstgen_rstn_ddrphy_apb_ ;
  416. _ENABLE_CLOCK_clk_dla_bus_ ;
  417. _ENABLE_CLOCK_clk_dla_axi_ ;
  418. _ENABLE_CLOCK_clk_dlanoc_axi_ ;
  419. _ENABLE_CLOCK_clk_dla_apb_ ;
  420. _ENABLE_CLOCK_clk_dlaslv_axi_ ;
  421. _CLEAR_RESET_rstgen_rstn_dla_axi_ ;
  422. _CLEAR_RESET_rstgen_rstn_dlanoc_axi_ ;
  423. _CLEAR_RESET_rstgen_rstn_dla_apb_ ;
  424. _CLEAR_RESET_rstgen_rstn_dlaslv_axi_ ;
  425. #endif
  426. //---- config ddrphy0/omc0 ----
  427. for(int ddr_num=0; ddr_num<2; ddr_num++) {
  428. if(ddr_num == 0) {
  429. OMC_APB_BASE_ADDR = OMC_CFG0_BASE_ADDR;
  430. OMC_SECURE_APB_BASE_ADDR = OMC_CFG0_BASE_ADDR+0x1000;
  431. PHY_APB_BASE_ADDR = DDRPHY0_CSR_BASE_ADDR;
  432. } else {
  433. OMC_APB_BASE_ADDR = OMC_CFG1_BASE_ADDR;
  434. OMC_SECURE_APB_BASE_ADDR = OMC_CFG1_BASE_ADDR+0x1000;
  435. PHY_APB_BASE_ADDR = DDRPHY1_CSR_BASE_ADDR;
  436. }
  437. //reg_wr_test;
  438. //`ifdef G_OPENEDGE_DDRPHY
  439. // `include "noc/continue_wr/orbit_cfg/orbit_boot.c"
  440. //`else
  441. #if 0
  442. #include "./ddrphy_cfg/regconfig.h.sim_PI.C"
  443. #include "./ddrphy_cfg/regconfig.h.sim_PHY.C"
  444. #else
  445. regconfig_h_sim_pi(OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR);
  446. regconfig_h_sim_phy(OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR);
  447. #endif
  448. //#include "./ddrc_cfg/lpddr4_1600_cl28_bl16/orbit_boot_8gx16.v"
  449. regconfig_pi_start(OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR, ddr_num);
  450. if(ddr_num == 0) //ddrc_clock=12.5M
  451. {
  452. _SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrosc_div2_;
  453. //_SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrpll_div4_;
  454. }
  455. else
  456. {
  457. _SWITCH_CLOCK_clk_ddrc1_SOURCE_clk_ddrosc_div2_;
  458. }
  459. udelay(300);
  460. apb_write(PHY_APB_BASE_ADDR + (0 +0 << 2), 0x01);//release dll_rst_n
  461. udelay(300);
  462. orbit_boot(OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR, ddr_num);
  463. //`endif
  464. }
  465. #if 1
  466. //while(1)
  467. {
  468. for(i = 0; i < 0x80000; i++)
  469. {
  470. writel(0xa5a5a5a5, 0x1000000000 + i *4);
  471. tmp = readl(0x1000000000 + i *4);
  472. if(tmp != 0xa5a5a5a5)
  473. {
  474. printk("error addr %d = 0x%x\r\n", i *4, tmp);
  475. fail_flag = -1;
  476. }
  477. writel(0x5a5a5a5a, 0x1000000000 + i *4);
  478. tmp = readl(0x1000000000 + i *4);
  479. if(tmp != 0x5a5a5a5a)
  480. {
  481. printk("error addr %d = 0x%x\r\n", i *4, tmp);
  482. fail_flag = -1;
  483. }
  484. writel(0x00000000, 0x1000000000 + i *4);
  485. tmp = readl(0x1000000000 + i *4);
  486. if(tmp != 0x00000000)
  487. {
  488. printk("error addr %d = 0x%x\r\n", i *4, tmp);
  489. fail_flag = -1;
  490. }
  491. writel(0xffffffff, 0x1000000000 + i *4);
  492. tmp = readl(0x1000000000 + i *4);
  493. if(tmp != 0xffffffff)
  494. {
  495. printk("error addr %d = 0x%x\r\n", i *4, tmp);
  496. fail_flag = -1;
  497. }
  498. if((i% 262144) == 0)
  499. {
  500. count++;
  501. printk("ddr 0x%x, %dM test\r\n",(i * 4), count);
  502. }
  503. }
  504. }
  505. #endif
  506. }
  507. /*only hartid 0 call this function*/
  508. void BootMain(void)
  509. {
  510. int boot_mode = 0;
  511. int ret=0;
  512. // gpio_init();
  513. uart_init(3);
  514. ret = init_ddr();
  515. if(ret == 0)
  516. {
  517. _SET_SYSCON_REG_register68_SCFG_disable_u74_memaxi_remap(1);
  518. #if defined(DDR_2133)
  519. printk("DDR clk 2133M,Version: %s\r\n",VERSION);
  520. #elif defined(DDR_2800)
  521. printk("DDR clk 2800M,Version: %s\r\n",VERSION);
  522. #elif defined(DDR_3200)
  523. printk("DDR clk 3200M,Version: %s\r\n",VERSION);
  524. #endif
  525. }
  526. else
  527. printk("End init lpddr4, test ddr fail\r\n");
  528. #if (UBOOT_EXEC_AT_NBDLA_2M == 1)
  529. printk("init nbdla 2M ram\r\n");
  530. _SET_SYSCON_REG_register16_SCFG_nbdla_clkgating_en(1);
  531. _ENABLE_CLOCK_clk_dla_axi_;
  532. _ENABLE_CLOCK_clk_dlanoc_axi_;
  533. _ENABLE_CLOCK_clk_dla_apb_;
  534. _ENABLE_CLOCK_clk_dlaslv_axi_;
  535. _CLEAR_RESET_rstgen_rstn_dla_axi_;
  536. _CLEAR_RESET_rstgen_rstn_dlanoc_axi_;
  537. _CLEAR_RESET_rstgen_rstn_dla_apb_;
  538. _CLEAR_RESET_rstgen_rstn_dlaslv_axi_;
  539. #endif /* UBOOT_EXEC_AT_NBDLA_2M */
  540. boot_from_chiplink();
  541. boot_mode = get_boot_mode();
  542. switch(boot_mode){
  543. case 0:
  544. boot_from_spi(1);
  545. break;
  546. case 1:
  547. boot_from_spi(4);
  548. break;
  549. case 2:
  550. boot_from_sdio();
  551. break;
  552. case 4:
  553. boot_from_uart();
  554. break;
  555. case 6:
  556. boot_from_chiplink();
  557. break;
  558. default:
  559. break;
  560. }
  561. printk("\r\nbootloader.\r\n");
  562. writel(0x1, 0x2000004);
  563. }