spl.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2011
  4. * Heiko Schocher, DENX Software Engineering, hs@denx.de.
  5. *
  6. * Copyright (C) 2012 Stefan Roese <sr@denx.de>
  7. */
  8. #include <common.h>
  9. #include <init.h>
  10. #include <spl.h>
  11. #include <version.h>
  12. #include <asm/io.h>
  13. #include <asm/arch/hardware.h>
  14. #include <asm/arch/spr_defs.h>
  15. #include <asm/arch/spr_misc.h>
  16. #include <asm/arch/spr_syscntl.h>
  17. #include <linux/mtd/st_smi.h>
  18. /* Reserve some space to store the BootROM's stack pointer during SPL operation.
  19. * The BSS cannot be used for this purpose because it will be zeroed after
  20. * having stored the pointer, so force the location to the data section.
  21. */
  22. u32 bootrom_stash_sp __attribute__((section(".data")));
  23. static void ddr_clock_init(void)
  24. {
  25. struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
  26. u32 clkenb, ddrpll;
  27. clkenb = readl(&misc_p->periph1_clken);
  28. clkenb &= ~PERIPH_MPMCMSK;
  29. clkenb |= PERIPH_MPMC_WE;
  30. /* Intentionally done twice */
  31. writel(clkenb, &misc_p->periph1_clken);
  32. writel(clkenb, &misc_p->periph1_clken);
  33. ddrpll = readl(&misc_p->pll_ctr_reg);
  34. ddrpll &= ~MEM_CLK_SEL_MSK;
  35. #if (CONFIG_DDR_HCLK)
  36. ddrpll |= MEM_CLK_HCLK;
  37. #elif (CONFIG_DDR_2HCLK)
  38. ddrpll |= MEM_CLK_2HCLK;
  39. #elif (CONFIG_DDR_PLL2)
  40. ddrpll |= MEM_CLK_PLL2;
  41. #else
  42. #error "please define one of CONFIG_DDR_(HCLK|2HCLK|PLL2)"
  43. #endif
  44. writel(ddrpll, &misc_p->pll_ctr_reg);
  45. writel(readl(&misc_p->periph1_clken) | PERIPH_MPMC_EN,
  46. &misc_p->periph1_clken);
  47. }
  48. static void mpmc_init_values(void)
  49. {
  50. u32 i;
  51. u32 *mpmc_reg_p = (u32 *)CONFIG_SPEAR_MPMCBASE;
  52. u32 *mpmc_val_p = &mpmc_conf_vals[0];
  53. for (i = 0; i < CONFIG_SPEAR_MPMCREGS; i++, mpmc_reg_p++, mpmc_val_p++)
  54. writel(*mpmc_val_p, mpmc_reg_p);
  55. mpmc_reg_p = (u32 *)CONFIG_SPEAR_MPMCBASE;
  56. /*
  57. * MPMC controller start
  58. * MPMC waiting for DLLLOCKREG high
  59. */
  60. writel(0x01000100, &mpmc_reg_p[7]);
  61. while (!(readl(&mpmc_reg_p[3]) & 0x10000))
  62. ;
  63. }
  64. static void mpmc_init(void)
  65. {
  66. /* Clock related settings for DDR */
  67. ddr_clock_init();
  68. /*
  69. * DDR pad register bits are different for different SoCs
  70. * Compensation values are also handled separately
  71. */
  72. plat_ddr_init();
  73. /* Initialize mpmc register values */
  74. mpmc_init_values();
  75. }
  76. static void pll_init(void)
  77. {
  78. struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
  79. /* Initialize PLLs */
  80. writel(FREQ_332, &misc_p->pll1_frq);
  81. writel(0x1C0A, &misc_p->pll1_cntl);
  82. writel(0x1C0E, &misc_p->pll1_cntl);
  83. writel(0x1C06, &misc_p->pll1_cntl);
  84. writel(0x1C0E, &misc_p->pll1_cntl);
  85. writel(FREQ_332, &misc_p->pll2_frq);
  86. writel(0x1C0A, &misc_p->pll2_cntl);
  87. writel(0x1C0E, &misc_p->pll2_cntl);
  88. writel(0x1C06, &misc_p->pll2_cntl);
  89. writel(0x1C0E, &misc_p->pll2_cntl);
  90. /* wait for pll locks */
  91. while (!(readl(&misc_p->pll1_cntl) & 0x1))
  92. ;
  93. while (!(readl(&misc_p->pll2_cntl) & 0x1))
  94. ;
  95. }
  96. static void mac_init(void)
  97. {
  98. struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
  99. writel(readl(&misc_p->periph1_clken) & (~PERIPH_GMAC),
  100. &misc_p->periph1_clken);
  101. writel(SYNTH23, &misc_p->gmac_synth_clk);
  102. switch (get_socrev()) {
  103. case SOC_SPEAR600_AA:
  104. case SOC_SPEAR600_AB:
  105. case SOC_SPEAR600_BA:
  106. case SOC_SPEAR600_BB:
  107. case SOC_SPEAR600_BC:
  108. case SOC_SPEAR600_BD:
  109. writel(0x0, &misc_p->gmac_ctr_reg);
  110. break;
  111. case SOC_SPEAR300:
  112. case SOC_SPEAR310:
  113. case SOC_SPEAR320:
  114. writel(0x4, &misc_p->gmac_ctr_reg);
  115. break;
  116. }
  117. writel(readl(&misc_p->periph1_clken) | PERIPH_GMAC,
  118. &misc_p->periph1_clken);
  119. writel(readl(&misc_p->periph1_rst) | PERIPH_GMAC,
  120. &misc_p->periph1_rst);
  121. writel(readl(&misc_p->periph1_rst) & (~PERIPH_GMAC),
  122. &misc_p->periph1_rst);
  123. }
  124. static void sys_init(void)
  125. {
  126. struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
  127. struct syscntl_regs *syscntl_p =
  128. (struct syscntl_regs *)CONFIG_SPEAR_SYSCNTLBASE;
  129. /* Set system state to SLOW */
  130. writel(SLOW, &syscntl_p->scctrl);
  131. writel(PLL_TIM << 3, &syscntl_p->scpllctrl);
  132. /* Initialize PLLs */
  133. pll_init();
  134. /*
  135. * Ethernet configuration
  136. * To be done only if the tftp boot is not selected already
  137. * Boot code ensures the correct configuration in tftp booting
  138. */
  139. if (!tftp_boot_selected())
  140. mac_init();
  141. writel(RTC_DISABLE | PLLTIMEEN, &misc_p->periph_clk_cfg);
  142. writel(0x555, &misc_p->amba_clk_cfg);
  143. writel(NORMAL, &syscntl_p->scctrl);
  144. /* Wait for system to switch to normal mode */
  145. while (((readl(&syscntl_p->scctrl) >> MODE_SHIFT) & MODE_MASK)
  146. != NORMAL)
  147. ;
  148. }
  149. /*
  150. * get_socrev
  151. *
  152. * Get SoC Revision.
  153. * @return SOC_SPEARXXX
  154. */
  155. int get_socrev(void)
  156. {
  157. #if defined(CONFIG_SPEAR600)
  158. struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
  159. u32 soc_id = readl(&misc_p->soc_core_id);
  160. u32 pri_socid = (soc_id >> SOC_PRI_SHFT) & 0xFF;
  161. u32 sec_socid = (soc_id >> SOC_SEC_SHFT) & 0xFF;
  162. if ((pri_socid == 'B') && (sec_socid == 'B'))
  163. return SOC_SPEAR600_BB;
  164. else if ((pri_socid == 'B') && (sec_socid == 'C'))
  165. return SOC_SPEAR600_BC;
  166. else if ((pri_socid == 'B') && (sec_socid == 'D'))
  167. return SOC_SPEAR600_BD;
  168. else if (soc_id == 0)
  169. return SOC_SPEAR600_BA;
  170. else
  171. return SOC_SPEAR_NA;
  172. #elif defined(CONFIG_SPEAR300)
  173. return SOC_SPEAR300;
  174. #elif defined(CONFIG_SPEAR310)
  175. return SOC_SPEAR310;
  176. #elif defined(CONFIG_SPEAR320)
  177. return SOC_SPEAR320;
  178. #endif
  179. }
  180. /*
  181. * SNOR (Serial NOR flash) related functions
  182. */
  183. static void snor_init(void)
  184. {
  185. struct smi_regs *const smicntl =
  186. (struct smi_regs * const)CONFIG_SYS_SMI_BASE;
  187. /* Setting the fast mode values. SMI working at 166/4 = 41.5 MHz */
  188. writel(HOLD1 | FAST_MODE | BANK_EN | DSEL_TIME | PRESCAL4,
  189. &smicntl->smi_cr1);
  190. }
  191. u32 spl_boot_device(void)
  192. {
  193. u32 mode = 0;
  194. if (usb_boot_selected()) {
  195. mode = BOOT_DEVICE_BOOTROM;
  196. } else if (snor_boot_selected()) {
  197. /* SNOR-SMI initialization */
  198. snor_init();
  199. mode = BOOT_DEVICE_NOR;
  200. }
  201. return mode;
  202. }
  203. void board_boot_order(u32 *spl_boot_list)
  204. {
  205. spl_boot_list[0] = spl_boot_device();
  206. /*
  207. * If the main boot device (eg. NOR) is empty, try to jump back into the
  208. * BootROM for USB boot process.
  209. */
  210. if (USB_BOOT_SUPPORTED)
  211. spl_boot_list[1] = BOOT_DEVICE_BOOTROM;
  212. }
  213. void board_init_f(ulong dummy)
  214. {
  215. struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
  216. /* Initialize PLLs */
  217. sys_init();
  218. preloader_console_init();
  219. arch_cpu_init();
  220. /* Enable IPs (release reset) */
  221. writel(PERIPH_RST_ALL, &misc_p->periph1_rst);
  222. /* Initialize MPMC */
  223. puts("Configure DDR\n");
  224. mpmc_init();
  225. spear_late_init();
  226. }
  227. /*
  228. * In a few cases (Ethernet, UART or USB boot, we might want to go back into the
  229. * BootROM code right after having initialized a few components like the DRAM).
  230. * The following function is called from SPL common code (board_init_r).
  231. */
  232. int board_return_to_bootrom(struct spl_image_info *spl_image,
  233. struct spl_boot_device *bootdev)
  234. {
  235. /*
  236. * Retrieve the BootROM's stack pointer and jump back to the start of
  237. * the SPL, where we can easily branch back into the BootROM. Don't do
  238. * it right here because SPL might be compiled in Thumb mode while the
  239. * BootROM expects ARM mode.
  240. */
  241. asm volatile ("ldr r0, =bootrom_stash_sp;"
  242. "ldr r0, [r0];"
  243. "mov sp, r0;"
  244. #if defined(CONFIG_SPL_SYS_THUMB_BUILD)
  245. "blx back_to_bootrom;"
  246. #else
  247. "bl back_to_bootrom;"
  248. #endif
  249. );
  250. return 0;
  251. }