bootmain.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  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. #define BOOTLOADER_VERSION "2020.9.16"
  29. extern void boot_sdio_init(void);
  30. extern int boot_load_gpt_partition(void* dst, const gpt_guid* partition_type_guid);
  31. extern const gpt_guid gpt_guid_sifive_uboot;
  32. extern const gpt_guid gpt_guid_sifive_kernel;
  33. extern unsigned int receive_count;
  34. typedef void ( *STARTRUNNING )( unsigned int par1 );
  35. /*
  36. To run a procedure from the address:start
  37. start: start address of runing in armmode, not do address align checking
  38. */
  39. void start2run32(unsigned int start)
  40. {
  41. (( STARTRUNNING )(start))(0);
  42. }
  43. #define SPIBOOT_LOAD_ADDR_OFFSET 252
  44. /*read data from flash to the destination address
  45. *
  46. *spi_flash: flash device informations
  47. *des_addr: store the data read from flash
  48. *page_offset:Offset of data stored in flash
  49. *mode:flash work mode
  50. */
  51. static int load_data(struct spi_flash* spi_flash,unsigned int des_addr,unsigned int page_offset,int mode)
  52. {
  53. u8 dataBuf[260];
  54. u32 startPage,endPage;
  55. u32 pageSize;
  56. u32 fileSize;
  57. u8 *addr;
  58. int ret;
  59. int i;
  60. u32 offset;
  61. pageSize = spi_flash->page_size;
  62. addr = (u8 *)des_addr;
  63. offset = page_offset*pageSize;
  64. /*read first page,get the file size*/
  65. ret = spi_flash->read(spi_flash,offset,pageSize,dataBuf,mode);
  66. if(ret != 0)
  67. {
  68. printk("read fail#\r\n");
  69. return -1;
  70. }
  71. /*calculate file size*/
  72. fileSize = (dataBuf[3] << 24) | (dataBuf[2] << 16) | (dataBuf[1] << 8) | (dataBuf[0]) ;
  73. if(fileSize == 0)
  74. return -1;
  75. endPage = ((fileSize + 255) >> 8);//page align
  76. /*copy the first page data*/
  77. sys_memcpy(addr, &dataBuf[4], SPIBOOT_LOAD_ADDR_OFFSET);
  78. offset += pageSize;
  79. addr += SPIBOOT_LOAD_ADDR_OFFSET;
  80. /*read Remaining pages data*/
  81. for(i=1; i<=endPage; i++)
  82. {
  83. ret = spi_flash->read(spi_flash,offset,pageSize, addr, mode);
  84. if(ret != 0)
  85. {
  86. printk("read fail##\r\n");
  87. return -1;
  88. }
  89. offset += pageSize;
  90. addr +=pageSize;
  91. }
  92. return 0;
  93. }
  94. int updata_flash(struct spi_flash* spi_flash,u32 flash_addr,u32 load_addr,unsigned char mode)
  95. {
  96. int ret = 0;
  97. u32 offset = 0;
  98. int erase_block = 0;
  99. unsigned int receive_count_align = 0;
  100. unsigned int index = 0;
  101. unsigned int blockSize,pageSize;
  102. u8 *data;
  103. printk("send file by xmodem\r\n");
  104. receive_count = 0;
  105. ret = xmodem_recv_file((unsigned char *)load_addr, 0);
  106. if(ret == 0)
  107. return;
  108. blockSize = spi_flash->block_size;
  109. pageSize = spi_flash->page_size;
  110. if(receive_count % 2)
  111. {
  112. receive_count_align = receive_count + 1;//page align
  113. }
  114. else
  115. {
  116. receive_count_align = receive_count;
  117. }
  118. if((receive_count_align * 128) % (64 * 1024))
  119. {
  120. erase_block = (receive_count_align * 128) / (64 * 1024) + 1;
  121. }
  122. else
  123. {
  124. erase_block = (receive_count_align * 128) / (64 * 1024);
  125. }
  126. /*erase flash*/
  127. offset = flash_addr;
  128. for(index=0; index<erase_block; index++)
  129. {
  130. ret = spi_flash->erase(spi_flash, offset, blockSize, 64);
  131. if(ret < 0)
  132. {
  133. printk("erases block %d fail\r\n",offset);
  134. return -1;
  135. }
  136. offset +=blockSize;
  137. }
  138. /*write data*/
  139. offset = flash_addr;
  140. data = (u8 *)load_addr;
  141. for(index=0; index<receive_count_align / 2; index++)
  142. {
  143. ret = spi_flash->write(spi_flash, offset,pageSize, data, mode);
  144. printk(".");
  145. if(index%64 == 0)
  146. printk("\n");
  147. if(ret < 0)
  148. {
  149. printk("write page %d fail\r\n",offset);
  150. return -1;
  151. }
  152. offset +=pageSize;
  153. data += pageSize;
  154. }
  155. return 0;
  156. }
  157. static int updata_flash_code(struct spi_flash* spi_flash,unsigned int updata_num,unsigned char mode)
  158. {
  159. int ret = 0;
  160. switch (updata_num){
  161. case 0:
  162. ret = updata_flash(spi_flash,FLASH_SECONDBOOT_START_ADDR,DEFAULT_SECONDBOOT_LOAD_ADDR,mode);
  163. break;
  164. case 1:
  165. ret = updata_flash(spi_flash,FLASH_DDRINIT_START_ADDR,DEFAULT_DDRINIT_LOAD_ADDR,mode);
  166. break;
  167. case 2:
  168. ret = updata_flash(spi_flash,FLASH_UBOOT_START_ADDR,DEFAULT_UBOOT_LOAD_ADDR,mode);
  169. break;
  170. default:
  171. break;
  172. }
  173. return ret;
  174. }
  175. void boot_from_chiplink(void)
  176. {
  177. int bootdelay = 3;
  178. int abort = 0;
  179. char str[6];
  180. char *tmp;
  181. int ret=0;
  182. s32 usel;
  183. unsigned long ts;
  184. struct spi_flash* spi_flash;
  185. unsigned char mode = 1;// or 4
  186. while ((bootdelay > 0) && (!abort)) {
  187. --bootdelay;
  188. /* delay 1000 ms */
  189. ts = get_timer(0);
  190. do {
  191. if (serial_tstc()) { /* we got a key press */
  192. abort = 1; /* don't auto boot */
  193. bootdelay = 0; /* no more delay */
  194. serial_getc(); /* consume input */
  195. break;
  196. }
  197. mdelay(100);
  198. } while (!abort && get_timer(ts) < 1000);
  199. printk("\b\b\b%d ", bootdelay);
  200. }
  201. if(1 == abort)
  202. {
  203. cadence_qspi_init(0, mode);
  204. spi_flash = spi_flash_probe(0, 0, 50000000, 0, (u32)SPI_DATAMODE_8);
  205. printk("***************************************************\r\n");
  206. printk("***************VIC DDR INIT BOOT ********************\r\n");
  207. printk("***************************************************\r\n");
  208. again:
  209. tmp = str;
  210. printk("0:updata second boot\r\n");
  211. printk("1:updata ddr init boot\r\n");
  212. printk("2:updata uboot\r\n");
  213. printk("3:quit\r\n");
  214. printk("Select the function to test : ");
  215. serial_gets(str);
  216. if(str[0] == 0)
  217. goto again;
  218. while(*tmp == 4){tmp++;} /*skip EOT*/
  219. usel = atoi(tmp);
  220. if(usel > 3)
  221. {
  222. printk("error select,try again\r\n");
  223. goto again;
  224. }
  225. /*quit*/
  226. if(usel == 3)
  227. return;
  228. printk("usel:%d\n",usel);
  229. ret = updata_flash_code(spi_flash,usel,mode);
  230. if(ret < 0)
  231. printk("updata fail\r\n");
  232. else
  233. printk("updata success\r\n");
  234. goto again;
  235. }
  236. }
  237. void boot_from_uart(void)
  238. {
  239. sys_cmd_proc();
  240. }
  241. void boot_from_sdio(void)
  242. {
  243. boot_sdio_init();
  244. /*load uboot bin file from sd card*/
  245. boot_load_gpt_partition((void *)DEFAULT_UBOOT_ADDR,&gpt_guid_sifive_uboot);
  246. /*load kernel bin file from sd card*/
  247. boot_load_gpt_partition((void *)DEFAULT_KERNEL_ADDR,&gpt_guid_sifive_kernel);
  248. }
  249. void boot_from_spi(int mode)
  250. {
  251. struct spi_flash* spi_flash;
  252. int ret;
  253. u32 *addr;
  254. u32 val;
  255. cadence_qspi_init(0, mode);
  256. spi_flash = spi_flash_probe(0, 0, 50000000, 0, (u32)SPI_DATAMODE_8);
  257. /*load uboot*/
  258. load_data(spi_flash,DEFAULT_UBOOT_ADDR,DEFAULT_UBOOT_OFFSET,mode);
  259. }
  260. static int init_ddr(void)
  261. {
  262. int fail_flag = 0;
  263. uint32_t tmp;
  264. uint32_t OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR;
  265. uint64_t mem_addr;
  266. uint32_t wdata;
  267. int i = 0;
  268. u32 count = 0;
  269. uint64_t base_addr = U74_SYS_PORT_DDRC_BASE_ADDR;
  270. ///printf_led("Main start");
  271. //Set PLL to 15750M
  272. //_ASSERT_RESET_rstgen_rstn_ddrphy_apb_ //reset ddrphy,unvalid
  273. _SWITCH_CLOCK_clk_dla_root_SOURCE_clk_osc_sys_;
  274. //SCFG_PLL [31:24] [23:16] [15:8] [7:4] [3] [2] [1] [0]
  275. // OD BWADJ CLKFDIV CLKR bypass infb pd rst
  276. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x292905);//set reset
  277. udelay(10); //wait(500*(1/25M))
  278. MA_OUTW(syscon_sysmain_ctrl_SCFG_pll1_REG_ADDR,0x0292904);//clear reset
  279. udelay(10); //wait(500*(1/25M))
  280. _SWITCH_CLOCK_clk_dla_root_SOURCE_clk_pll1_out_;
  281. //_CLEAR_RESET_rstgen_rstn_ddrphy_apb_ //clear reset of ddrphy,unvalid
  282. //ddrc_clock=400M test
  283. //_SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrpll_div4_;
  284. //_SWITCH_CLOCK_clk_ddrc1_SOURCE_clk_ddrpll_div4_;
  285. //ddrc_clock=800M
  286. //_SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrpll_div2_;
  287. //_SWITCH_CLOCK_clk_ddrc1_SOURCE_clk_ddrpll_div2_;
  288. //12.5M
  289. _SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrosc_div2_;
  290. _SWITCH_CLOCK_clk_ddrc1_SOURCE_clk_ddrosc_div2_;
  291. _ENABLE_CLOCK_clk_ddrc0_;
  292. _ENABLE_CLOCK_clk_ddrc1_;
  293. #if 0
  294. _ENABLE_CLOCK_clk_ddrphy_apb_ ;
  295. _CLEAR_RESET_rstgen_rstn_ddrphy_apb_ ;
  296. _ENABLE_CLOCK_clk_dla_bus_ ;
  297. _ENABLE_CLOCK_clk_dla_axi_ ;
  298. _ENABLE_CLOCK_clk_dlanoc_axi_ ;
  299. _ENABLE_CLOCK_clk_dla_apb_ ;
  300. _ENABLE_CLOCK_clk_dlaslv_axi_ ;
  301. _CLEAR_RESET_rstgen_rstn_dla_axi_ ;
  302. _CLEAR_RESET_rstgen_rstn_dlanoc_axi_ ;
  303. _CLEAR_RESET_rstgen_rstn_dla_apb_ ;
  304. _CLEAR_RESET_rstgen_rstn_dlaslv_axi_ ;
  305. #endif
  306. //---- config ddrphy0/omc0 ----
  307. for(int ddr_num=0; ddr_num<2; ddr_num++) {
  308. if(ddr_num == 0) {
  309. OMC_APB_BASE_ADDR = OMC_CFG0_BASE_ADDR;
  310. OMC_SECURE_APB_BASE_ADDR = OMC_CFG0_BASE_ADDR+0x1000;
  311. PHY_APB_BASE_ADDR = DDRPHY0_CSR_BASE_ADDR;
  312. } else {
  313. OMC_APB_BASE_ADDR = OMC_CFG1_BASE_ADDR;
  314. OMC_SECURE_APB_BASE_ADDR = OMC_CFG1_BASE_ADDR+0x1000;
  315. PHY_APB_BASE_ADDR = DDRPHY1_CSR_BASE_ADDR;
  316. }
  317. //reg_wr_test;
  318. //`ifdef G_OPENEDGE_DDRPHY
  319. // `include "noc/continue_wr/orbit_cfg/orbit_boot.c"
  320. //`else
  321. #if 0
  322. #include "./ddrphy_cfg/regconfig.h.sim_PI.C"
  323. #include "./ddrphy_cfg/regconfig.h.sim_PHY.C"
  324. #else
  325. regconfig_h_sim_pi(OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR);
  326. regconfig_h_sim_phy(OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR);
  327. #endif
  328. //#include "./ddrc_cfg/lpddr4_1600_cl28_bl16/orbit_boot_8gx16.v"
  329. regconfig_pi_start(OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR, ddr_num);
  330. if(ddr_num == 0) //ddrc_clock=12.5M
  331. {
  332. _SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrosc_div2_;
  333. //_SWITCH_CLOCK_clk_ddrc0_SOURCE_clk_ddrpll_div4_;
  334. }
  335. else
  336. {
  337. _SWITCH_CLOCK_clk_ddrc1_SOURCE_clk_ddrosc_div2_;
  338. }
  339. udelay(300);
  340. apb_write(PHY_APB_BASE_ADDR + (0 +0 << 2), 0x01);//release dll_rst_n
  341. udelay(300);
  342. orbit_boot(OMC_APB_BASE_ADDR, OMC_SECURE_APB_BASE_ADDR, PHY_APB_BASE_ADDR, ddr_num);
  343. //`endif
  344. }
  345. #if 1
  346. //while(1)
  347. {
  348. for(i = 0; i < 0x80000; i++)
  349. {
  350. writel(0xa5a5a5a5, 0x1000000000 + i *4);
  351. tmp = readl(0x1000000000 + i *4);
  352. if(tmp != 0xa5a5a5a5)
  353. {
  354. printk("error addr %d = 0x%x\n", i *4, tmp);
  355. fail_flag = -1;
  356. }
  357. writel(0x5a5a5a5a, 0x1000000000 + i *4);
  358. tmp = readl(0x1000000000 + i *4);
  359. if(tmp != 0x5a5a5a5a)
  360. {
  361. printk("error addr %d = 0x%x\n", i *4, tmp);
  362. fail_flag = -1;
  363. }
  364. writel(0x00000000, 0x1000000000 + i *4);
  365. tmp = readl(0x1000000000 + i *4);
  366. if(tmp != 0x00000000)
  367. {
  368. printk("error addr %d = 0x%x\n", i *4, tmp);
  369. fail_flag = -1;
  370. }
  371. writel(0xffffffff, 0x1000000000 + i *4);
  372. tmp = readl(0x1000000000 + i *4);
  373. if(tmp != 0xffffffff)
  374. {
  375. printk("error addr %d = 0x%x\n", i *4, tmp);
  376. fail_flag = -1;
  377. }
  378. if((i% 262144) == 0)
  379. {
  380. count++;
  381. printk("ddr 0x%x, %dM test\r\n",(i * 4), count);
  382. }
  383. }
  384. }
  385. #endif
  386. }
  387. /*only hartid 0 call this function*/
  388. void BootMain(void)
  389. {
  390. int boot_mode = 0;
  391. int ret=0;
  392. timer_init(0);
  393. gpio_init();
  394. uart_init(3);
  395. ret = init_ddr();
  396. if(ret == 0)
  397. {
  398. _SET_SYSCON_REG_register68_SCFG_disable_u74_memaxi_remap(1);
  399. printk("DDR clk 2133M,Version %s\r\n",BOOTLOADER_VERSION);
  400. }
  401. else
  402. printk("End init lpddr4, test ddr fail\r\n");
  403. boot_from_chiplink();
  404. boot_mode = get_boot_mode();
  405. switch(boot_mode){
  406. case 0:
  407. boot_from_spi(1);
  408. break;
  409. case 1:
  410. boot_from_spi(4);
  411. break;
  412. case 2:
  413. boot_from_sdio();
  414. break;
  415. case 4:
  416. boot_from_uart();
  417. break;
  418. case 6:
  419. boot_from_chiplink();
  420. break;
  421. default:
  422. break;
  423. }
  424. printk("\nbootloader.\n");
  425. writel(0x1, 0x2000004);
  426. }