bootmain.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  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. * <h2><center>&copy; COPYRIGHT 20120 Shanghai StarFive Technology Co., Ltd. </center></h2>
  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\n", crc_org, crc_ddr);
  105. if (crc_org != crc_ddr) {
  106. printk("ERROR: crc check FAILED\n");
  107. while (1) {
  108. __asm__ ("wfi");
  109. }
  110. } else {
  111. printk("crc check PASSED\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\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("\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. void boot_from_chiplink(void)
  201. {
  202. int bootdelay = 3;
  203. int abort = 0;
  204. char str[6];
  205. char *tmp;
  206. int ret=0;
  207. s32 usel;
  208. unsigned long ts;
  209. struct spi_flash* spi_flash;
  210. unsigned char mode = 1;// or 4
  211. while ((bootdelay > 0) && (!abort)) {
  212. --bootdelay;
  213. /* delay 1000 ms */
  214. ts = get_timer(0);
  215. do {
  216. if (serial_tstc()) { /* we got a key press */
  217. abort = 1; /* don't auto boot */
  218. bootdelay = 0; /* no more delay */
  219. serial_getc(); /* consume input */
  220. break;
  221. }
  222. mdelay(100);
  223. } while (!abort && get_timer(ts) < 1000);
  224. printk("\b\b\b%d ", bootdelay);
  225. }
  226. if(1 == abort)
  227. {
  228. cadence_qspi_init(0, mode);
  229. spi_flash = spi_flash_probe(0, 0, 31250000, 0, (u32)SPI_DATAMODE_8);
  230. printk("***************************************************\r\n");
  231. printk("***************VIC DDR INIT BOOT ********************\r\n");
  232. printk("***************************************************\r\n");
  233. again:
  234. tmp = str;
  235. printk("0:updata second boot\r\n");
  236. printk("1:updata ddr init boot\r\n");
  237. printk("2:updata uboot\r\n");
  238. printk("3:quit\r\n");
  239. printk("Select the function to test : ");
  240. serial_gets(str);
  241. if(str[0] == 0)
  242. goto again;
  243. while(*tmp == 4){tmp++;} /*skip EOT*/
  244. usel = atoi(tmp);
  245. if(usel > 3)
  246. {
  247. printk("error select,try again\r\n");
  248. goto again;
  249. }
  250. /*quit*/
  251. if(usel == 3)
  252. return;
  253. printk("usel:%d\n",usel);
  254. ret = updata_flash_code(spi_flash,usel,mode);
  255. if(ret < 0)
  256. printk("updata fail\r\n");
  257. else
  258. printk("updata success\r\n");
  259. goto again;
  260. }
  261. }
  262. void boot_from_uart(void)
  263. {
  264. sys_cmd_proc();
  265. }
  266. void boot_from_sdio(void)
  267. {
  268. boot_sdio_init();
  269. /*load uboot bin file from sd card*/
  270. boot_load_gpt_partition((void *)DEFAULT_UBOOT_ADDR,&gpt_guid_sifive_uboot);
  271. /*load kernel bin file from sd card*/
  272. // boot_load_gpt_partition((void *)DEFAULT_KERNEL_ADDR,&gpt_guid_sifive_kernel);
  273. }
  274. void boot_from_spi(int mode)
  275. {
  276. struct spi_flash* spi_flash;
  277. int ret;
  278. u32 *addr;
  279. u32 val;
  280. cadence_qspi_init(0, mode);
  281. spi_flash = spi_flash_probe(0, 0, 31250000, 0, (u32)SPI_DATAMODE_8);
  282. /*load uboot*/
  283. load_data(spi_flash,DEFAULT_UBOOT_ADDR,DEFAULT_UBOOT_OFFSET,mode);
  284. }
  285. static int init_ddr(void)
  286. {
  287. int fail_flag = 0;
  288. uint32_t tmp;
  289. uint32_t OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR;
  290. uint64_t mem_addr;
  291. uint32_t wdata;
  292. int i = 0;
  293. u32 count = 0;
  294. uint64_t base_addr = U74_SYS_PORT_DDRC_BASE_ADDR;
  295. ///printf_led("Main start");
  296. //Set PLL to 15750M
  297. //_ASSERT_RESET_rstgen_rstn_ddrphy_apb_ //reset ddrphy,unvalid
  298. _SWITCH_CLOCK_clk_dla_root_SOURCE_clk_osc_sys_;
  299. //SCFG_PLL [31:24] [23:16] [15:8] [7:4] [3] [2] [1] [0]
  300. // OD BWADJ CLKFDIV CLKR bypass infb pd rst
  301. #if defined(DDR_2133)
  302. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x292905);//set reset
  303. udelay(10); //wait(500*(1/25M))
  304. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x0292904);//clear reset
  305. udelay(10); //wait(500*(1/25M))
  306. #elif defined(DDR_2800)
  307. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x373705);//set reset
  308. udelay(10); //wait(500*(1/25M))
  309. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x0373704);//clear reset
  310. udelay(10); //wait(500*(1/25M))
  311. #elif defined(DDR_3200)
  312. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x3f3f05);//set reset
  313. udelay(10); //wait(500*(1/25M))
  314. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x03f3f04);//clear reset
  315. udelay(10); //wait(500*(1/25M))
  316. #endif
  317. _SWITCH_CLOCK_clk_dla_root_SOURCE_clk_pll1_out_;
  318. //_CLEAR_RESET_rstgen_rstn_ddrphy_apb_ //clear reset of ddrphy,unvalid
  319. //ddrc_clock=400M test
  320. //_SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrpll_div4_;
  321. //_SWITCH_CLOCK_clk_ddrc1_SOURCE_clk_ddrpll_div4_;
  322. //ddrc_clock=800M
  323. //_SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrpll_div2_;
  324. //_SWITCH_CLOCK_clk_ddrc1_SOURCE_clk_ddrpll_div2_;
  325. //12.5M
  326. _SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrosc_div2_;
  327. _SWITCH_CLOCK_clk_ddrc1_SOURCE_clk_ddrosc_div2_;
  328. _ENABLE_CLOCK_clk_ddrc0_;
  329. _ENABLE_CLOCK_clk_ddrc1_;
  330. #if 0
  331. _ENABLE_CLOCK_clk_ddrphy_apb_ ;
  332. _CLEAR_RESET_rstgen_rstn_ddrphy_apb_ ;
  333. _ENABLE_CLOCK_clk_dla_bus_ ;
  334. _ENABLE_CLOCK_clk_dla_axi_ ;
  335. _ENABLE_CLOCK_clk_dlanoc_axi_ ;
  336. _ENABLE_CLOCK_clk_dla_apb_ ;
  337. _ENABLE_CLOCK_clk_dlaslv_axi_ ;
  338. _CLEAR_RESET_rstgen_rstn_dla_axi_ ;
  339. _CLEAR_RESET_rstgen_rstn_dlanoc_axi_ ;
  340. _CLEAR_RESET_rstgen_rstn_dla_apb_ ;
  341. _CLEAR_RESET_rstgen_rstn_dlaslv_axi_ ;
  342. #endif
  343. //---- config ddrphy0/omc0 ----
  344. for(int ddr_num=0; ddr_num<2; ddr_num++) {
  345. if(ddr_num == 0) {
  346. OMC_APB_BASE_ADDR = OMC_CFG0_BASE_ADDR;
  347. OMC_SECURE_APB_BASE_ADDR = OMC_CFG0_BASE_ADDR+0x1000;
  348. PHY_APB_BASE_ADDR = DDRPHY0_CSR_BASE_ADDR;
  349. } else {
  350. OMC_APB_BASE_ADDR = OMC_CFG1_BASE_ADDR;
  351. OMC_SECURE_APB_BASE_ADDR = OMC_CFG1_BASE_ADDR+0x1000;
  352. PHY_APB_BASE_ADDR = DDRPHY1_CSR_BASE_ADDR;
  353. }
  354. //reg_wr_test;
  355. //`ifdef G_OPENEDGE_DDRPHY
  356. // `include "noc/continue_wr/orbit_cfg/orbit_boot.c"
  357. //`else
  358. #if 0
  359. #include "./ddrphy_cfg/regconfig.h.sim_PI.C"
  360. #include "./ddrphy_cfg/regconfig.h.sim_PHY.C"
  361. #else
  362. regconfig_h_sim_pi(OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR);
  363. regconfig_h_sim_phy(OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR);
  364. #endif
  365. //#include "./ddrc_cfg/lpddr4_1600_cl28_bl16/orbit_boot_8gx16.v"
  366. regconfig_pi_start(OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR, ddr_num);
  367. if(ddr_num == 0) //ddrc_clock=12.5M
  368. {
  369. _SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrosc_div2_;
  370. //_SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrpll_div4_;
  371. }
  372. else
  373. {
  374. _SWITCH_CLOCK_clk_ddrc1_SOURCE_clk_ddrosc_div2_;
  375. }
  376. udelay(300);
  377. apb_write(PHY_APB_BASE_ADDR + (0 +0 << 2), 0x01);//release dll_rst_n
  378. udelay(300);
  379. orbit_boot(OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR, ddr_num);
  380. //`endif
  381. }
  382. #if 1
  383. //while(1)
  384. {
  385. for(i = 0; i < 0x80000; i++)
  386. {
  387. writel(0xa5a5a5a5, 0x1000000000 + i *4);
  388. tmp = readl(0x1000000000 + i *4);
  389. if(tmp != 0xa5a5a5a5)
  390. {
  391. printk("error addr %d = 0x%x\n", i *4, tmp);
  392. fail_flag = -1;
  393. }
  394. writel(0x5a5a5a5a, 0x1000000000 + i *4);
  395. tmp = readl(0x1000000000 + i *4);
  396. if(tmp != 0x5a5a5a5a)
  397. {
  398. printk("error addr %d = 0x%x\n", i *4, tmp);
  399. fail_flag = -1;
  400. }
  401. writel(0x00000000, 0x1000000000 + i *4);
  402. tmp = readl(0x1000000000 + i *4);
  403. if(tmp != 0x00000000)
  404. {
  405. printk("error addr %d = 0x%x\n", i *4, tmp);
  406. fail_flag = -1;
  407. }
  408. writel(0xffffffff, 0x1000000000 + i *4);
  409. tmp = readl(0x1000000000 + i *4);
  410. if(tmp != 0xffffffff)
  411. {
  412. printk("error addr %d = 0x%x\n", i *4, tmp);
  413. fail_flag = -1;
  414. }
  415. if((i% 262144) == 0)
  416. {
  417. count++;
  418. printk("ddr 0x%x, %dM test\r\n",(i * 4), count);
  419. }
  420. }
  421. }
  422. #endif
  423. }
  424. /*only hartid 0 call this function*/
  425. void BootMain(void)
  426. {
  427. int boot_mode = 0;
  428. int ret=0;
  429. // gpio_init();
  430. uart_init(3);
  431. ret = init_ddr();
  432. if(ret == 0)
  433. {
  434. _SET_SYSCON_REG_register68_SCFG_disable_u74_memaxi_remap(1);
  435. #if defined(DDR_2133)
  436. printk("DDR clk 2133M,Version: %s\r\n",VERSION);
  437. #elif defined(DDR_2800)
  438. printk("DDR clk 2800M,Version: %s\r\n",VERSION);
  439. #elif defined(DDR_3200)
  440. printk("DDR clk 3200M,Version: %s\r\n",VERSION);
  441. #endif
  442. }
  443. else
  444. printk("End init lpddr4, test ddr fail\r\n");
  445. #if (UBOOT_EXEC_AT_NBDLA_2M == 1)
  446. printk("init nbdla 2M ram\r\n");
  447. _SET_SYSCON_REG_register16_SCFG_nbdla_clkgating_en(1);
  448. _ENABLE_CLOCK_clk_dla_axi_;
  449. _ENABLE_CLOCK_clk_dlanoc_axi_;
  450. _ENABLE_CLOCK_clk_dla_apb_;
  451. _ENABLE_CLOCK_clk_dlaslv_axi_;
  452. _CLEAR_RESET_rstgen_rstn_dla_axi_;
  453. _CLEAR_RESET_rstgen_rstn_dlanoc_axi_;
  454. _CLEAR_RESET_rstgen_rstn_dla_apb_;
  455. _CLEAR_RESET_rstgen_rstn_dlaslv_axi_;
  456. #endif /* UBOOT_EXEC_AT_NBDLA_2M */
  457. boot_from_chiplink();
  458. boot_mode = get_boot_mode();
  459. switch(boot_mode){
  460. case 0:
  461. boot_from_spi(1);
  462. break;
  463. case 1:
  464. boot_from_spi(4);
  465. break;
  466. case 2:
  467. boot_from_sdio();
  468. break;
  469. case 4:
  470. boot_from_uart();
  471. break;
  472. case 6:
  473. boot_from_chiplink();
  474. break;
  475. default:
  476. break;
  477. }
  478. printk("\nbootloader.\n");
  479. writel(0x1, 0x2000004);
  480. }