bootmain.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /**
  3. ******************************************************************************
  4. * @file bootmain.c
  5. * @author StarFive Technology
  6. * @version V1.0
  7. * @date 06/25/2020
  8. * @brief
  9. ******************************************************************************
  10. * @copy
  11. *
  12. * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  13. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  14. * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
  15. * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  16. * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  17. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  18. *
  19. * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
  20. */
  21. #include "sys.h"
  22. #include "spi_flash.h"
  23. #include "spi.h"
  24. #include "encoding.h"
  25. #include <clkgen_ctrl_macro.h>
  26. #include <syscon_sysmain_ctrl_macro.h>
  27. #include <ezGPIO_fullMux_ctrl_macro.h>
  28. #include <rstgen_ctrl_macro.h>
  29. #include <syscon_iopad_ctrl_macro.h>
  30. typedef void ( *STARTRUNNING )( unsigned int par1 );
  31. /*
  32. To run a procedure from the address:start
  33. start: start address of runing in armmode, not do address align checking
  34. */
  35. void start2run32(unsigned int start)
  36. {
  37. (( STARTRUNNING )(start))(0);
  38. }
  39. #define SPIBOOT_LOAD_ADDR_OFFSET 252
  40. /*read data from flash to the destination address
  41. *
  42. *spi_flash: flash device informations
  43. *des_addr: store the data read from flash
  44. *page_offset:Offset of data stored in flash
  45. *mode:flash work mode
  46. */
  47. static int load_data(struct spi_flash* spi_flash,unsigned int des_addr,unsigned int page_offset,int mode)
  48. {
  49. u8 dataBuf[260];
  50. u32 startPage,endPage;
  51. u32 pageSize;
  52. u32 fileSize;
  53. u8 *addr;
  54. int ret;
  55. int i;
  56. u32 offset;
  57. pageSize = spi_flash->page_size;
  58. addr = (u8 *)des_addr;
  59. offset = page_offset*pageSize;
  60. /*read first page,get the file size*/
  61. ret = spi_flash->read(spi_flash,offset,pageSize,dataBuf,mode);
  62. if(ret != 0)
  63. {
  64. printk("read fail#\r\n");
  65. return -1;
  66. }
  67. /*calculate file size*/
  68. fileSize = (dataBuf[3] << 24) | (dataBuf[2] << 16) | (dataBuf[1] << 8) | (dataBuf[0]) ;
  69. if(fileSize == 0)
  70. return -1;
  71. endPage = ((fileSize + 255) >> 8);//page align
  72. /*copy the first page data*/
  73. sys_memcpy(addr, &dataBuf[4], SPIBOOT_LOAD_ADDR_OFFSET);
  74. offset += pageSize;
  75. addr += SPIBOOT_LOAD_ADDR_OFFSET;
  76. /*read Remaining pages data*/
  77. for(i=1; i<=endPage; i++)
  78. {
  79. ret = spi_flash->read(spi_flash,offset,pageSize, addr, mode);
  80. if(ret != 0)
  81. {
  82. printk("read fail##\r\n");
  83. return -1;
  84. }
  85. offset += pageSize;
  86. addr +=pageSize;
  87. }
  88. return 0;
  89. }
  90. void load_and_run_ddr(struct spi_flash* spi_flash,int mode)
  91. {
  92. unsigned int addr;
  93. int ret;
  94. addr = DEFAULT_DDR_ADDR;
  95. ret = load_data(spi_flash,addr,DEFAULT_DDR_OFFSET,mode);
  96. printk("\r\nbootloader version:%s\r\n",VERSION);
  97. if(!ret)
  98. {
  99. writel(0x1, 0x2000004);
  100. start2run32(addr);
  101. }
  102. else
  103. printk("\nload ddr bin fail.\n");
  104. /*never run to here*/
  105. while(1);
  106. }
  107. void boot_from_spi(int mode)
  108. {
  109. struct spi_flash* spi_flash;
  110. int ret;
  111. u32 *addr;
  112. u32 val;
  113. cadence_qspi_init(0, mode);
  114. spi_flash = spi_flash_probe(0, 0, 31250000, 0, (u32)SPI_DATAMODE_8);
  115. /*init ddr*/
  116. load_and_run_ddr(spi_flash,mode);
  117. }
  118. static void chip_clk_init()
  119. {
  120. _SWITCH_CLOCK_clk_cpundbus_root_SOURCE_clk_pll0_out_;
  121. _SWITCH_CLOCK_clk_dla_root_SOURCE_clk_pll1_out_;
  122. _SWITCH_CLOCK_clk_dsp_root_SOURCE_clk_pll2_out_;
  123. _SWITCH_CLOCK_clk_perh0_root_SOURCE_clk_pll0_out_;
  124. // slow down nne bus can fix nne50 & vp6 ram scan issue,
  125. // as well as vin_subsys reg scan issue.
  126. // _SWITCH_CLOCK_clk_nne_bus_SOURCE_clk_cpu_axi_;
  127. }
  128. /*only hartid 0 call this function*/
  129. void BootMain(void)
  130. {
  131. int boot_mode = 0;
  132. /*switch to pll mode*/
  133. chip_clk_init();
  134. //for illegal instruction exception
  135. _SET_SYSCON_REG_register50_SCFG_funcshare_pad_ctrl_18(0x00c000c0);
  136. _CLEAR_RESET_rstgen_rstn_usbnoc_axi_;
  137. _CLEAR_RESET_rstgen_rstn_hifi4noc_axi_;
  138. _ENABLE_CLOCK_clk_x2c_axi_;
  139. _CLEAR_RESET_rstgen_rstn_x2c_axi_;
  140. _CLEAR_RESET_rstgen_rstn_dspx2c_axi_;
  141. _CLEAR_RESET_rstgen_rstn_dma1p_axi_;
  142. _ENABLE_CLOCK_clk_msi_apb_;
  143. _CLEAR_RESET_rstgen_rstn_msi_apb_;
  144. _ASSERT_RESET_rstgen_rstn_x2c_axi_;
  145. _CLEAR_RESET_rstgen_rstn_x2c_axi_;
  146. //end for illegal instruction exception
  147. _SET_SYSCON_REG_register69_core1_en(1);
  148. _SET_SYSCON_REG_register104_SCFG_io_padshare_sel(6);
  149. _SET_SYSCON_REG_register32_SCFG_funcshare_pad_ctrl_0(0x00c00000);
  150. _SET_SYSCON_REG_register33_SCFG_funcshare_pad_ctrl_1(0x00c000c0);
  151. _SET_SYSCON_REG_register34_SCFG_funcshare_pad_ctrl_2(0x00c000c0);
  152. _SET_SYSCON_REG_register35_SCFG_funcshare_pad_ctrl_3(0x00c000c0);
  153. _SET_SYSCON_REG_register39_SCFG_funcshare_pad_ctrl_7(0x00c300c3);
  154. _SET_SYSCON_REG_register38_SCFG_funcshare_pad_ctrl_6(0x00c00000);
  155. uart_init(3);
  156. writel(0x18000000, 0x1801fffc);
  157. writel(0x1, 0x2000004); /*从bootrom中恢复hart1*/
  158. boot_from_spi(1);
  159. /*never run to heare*/
  160. }