bootmain.c 12 KB

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