board.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
  4. *
  5. * (C) Copyright 2007-2011
  6. * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
  7. * Tom Cubie <tangliang@allwinnertech.com>
  8. *
  9. * Some init for sunxi platform.
  10. */
  11. #include <common.h>
  12. #include <cpu_func.h>
  13. #include <mmc.h>
  14. #include <i2c.h>
  15. #include <serial.h>
  16. #include <spl.h>
  17. #include <asm/cache.h>
  18. #include <asm/gpio.h>
  19. #include <asm/io.h>
  20. #include <asm/arch/clock.h>
  21. #include <asm/arch/gpio.h>
  22. #include <asm/arch/spl.h>
  23. #include <asm/arch/sys_proto.h>
  24. #include <asm/arch/timer.h>
  25. #include <asm/arch/tzpc.h>
  26. #include <asm/arch/mmc.h>
  27. #include <linux/compiler.h>
  28. struct fel_stash {
  29. uint32_t sp;
  30. uint32_t lr;
  31. uint32_t cpsr;
  32. uint32_t sctlr;
  33. uint32_t vbar;
  34. uint32_t cr;
  35. };
  36. struct fel_stash fel_stash __attribute__((section(".data")));
  37. #ifdef CONFIG_ARM64
  38. #include <asm/armv8/mmu.h>
  39. static struct mm_region sunxi_mem_map[] = {
  40. {
  41. /* SRAM, MMIO regions */
  42. .virt = 0x0UL,
  43. .phys = 0x0UL,
  44. .size = 0x40000000UL,
  45. .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
  46. PTE_BLOCK_NON_SHARE
  47. }, {
  48. /* RAM */
  49. .virt = 0x40000000UL,
  50. .phys = 0x40000000UL,
  51. .size = 0xC0000000UL,
  52. .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
  53. PTE_BLOCK_INNER_SHARE
  54. }, {
  55. /* List terminator */
  56. 0,
  57. }
  58. };
  59. struct mm_region *mem_map = sunxi_mem_map;
  60. #endif
  61. static int gpio_init(void)
  62. {
  63. __maybe_unused uint val;
  64. #if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
  65. #if defined(CONFIG_MACH_SUN4I) || \
  66. defined(CONFIG_MACH_SUN7I) || \
  67. defined(CONFIG_MACH_SUN8I_R40)
  68. /* disable GPB22,23 as uart0 tx,rx to avoid conflict */
  69. sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUNXI_GPIO_INPUT);
  70. sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT);
  71. #endif
  72. #if defined(CONFIG_MACH_SUN8I) && !defined(CONFIG_MACH_SUN8I_R40)
  73. sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUN8I_GPF_UART0);
  74. sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUN8I_GPF_UART0);
  75. #else
  76. sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF_UART0);
  77. sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF_UART0);
  78. #endif
  79. sunxi_gpio_set_pull(SUNXI_GPF(4), 1);
  80. #elif CONFIG_CONS_INDEX == 1 && (defined(CONFIG_MACH_SUN4I) || \
  81. defined(CONFIG_MACH_SUN7I) || \
  82. defined(CONFIG_MACH_SUN8I_R40))
  83. sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB_UART0);
  84. sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB_UART0);
  85. sunxi_gpio_set_pull(SUNXI_GPB(23), SUNXI_GPIO_PULL_UP);
  86. #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN5I)
  87. sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN5I_GPB_UART0);
  88. sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN5I_GPB_UART0);
  89. sunxi_gpio_set_pull(SUNXI_GPB(20), SUNXI_GPIO_PULL_UP);
  90. #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN6I)
  91. sunxi_gpio_set_cfgpin(SUNXI_GPH(20), SUN6I_GPH_UART0);
  92. sunxi_gpio_set_cfgpin(SUNXI_GPH(21), SUN6I_GPH_UART0);
  93. sunxi_gpio_set_pull(SUNXI_GPH(21), SUNXI_GPIO_PULL_UP);
  94. #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_A33)
  95. sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN8I_A33_GPB_UART0);
  96. sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_A33_GPB_UART0);
  97. sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP);
  98. #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUNXI_H3_H5)
  99. sunxi_gpio_set_cfgpin(SUNXI_GPA(4), SUN8I_H3_GPA_UART0);
  100. sunxi_gpio_set_cfgpin(SUNXI_GPA(5), SUN8I_H3_GPA_UART0);
  101. sunxi_gpio_set_pull(SUNXI_GPA(5), SUNXI_GPIO_PULL_UP);
  102. #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN50I)
  103. sunxi_gpio_set_cfgpin(SUNXI_GPB(8), SUN50I_GPB_UART0);
  104. sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN50I_GPB_UART0);
  105. sunxi_gpio_set_pull(SUNXI_GPB(9), SUNXI_GPIO_PULL_UP);
  106. #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN50I_H6)
  107. sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_H6_GPH_UART0);
  108. sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_H6_GPH_UART0);
  109. sunxi_gpio_set_pull(SUNXI_GPH(1), SUNXI_GPIO_PULL_UP);
  110. #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_A83T)
  111. sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_A83T_GPB_UART0);
  112. sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN8I_A83T_GPB_UART0);
  113. sunxi_gpio_set_pull(SUNXI_GPB(10), SUNXI_GPIO_PULL_UP);
  114. #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_V3S)
  115. sunxi_gpio_set_cfgpin(SUNXI_GPB(8), SUN8I_V3S_GPB_UART0);
  116. sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_V3S_GPB_UART0);
  117. sunxi_gpio_set_pull(SUNXI_GPB(9), SUNXI_GPIO_PULL_UP);
  118. #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN9I)
  119. sunxi_gpio_set_cfgpin(SUNXI_GPH(12), SUN9I_GPH_UART0);
  120. sunxi_gpio_set_cfgpin(SUNXI_GPH(13), SUN9I_GPH_UART0);
  121. sunxi_gpio_set_pull(SUNXI_GPH(13), SUNXI_GPIO_PULL_UP);
  122. #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN5I)
  123. sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG_UART1);
  124. sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG_UART1);
  125. sunxi_gpio_set_pull(SUNXI_GPG(4), SUNXI_GPIO_PULL_UP);
  126. #elif CONFIG_CONS_INDEX == 3 && defined(CONFIG_MACH_SUN8I)
  127. sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN8I_GPB_UART2);
  128. sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_GPB_UART2);
  129. sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP);
  130. #elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I)
  131. sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART);
  132. sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART);
  133. sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP);
  134. #else
  135. #error Unsupported console port number. Please fix pin mux settings in board.c
  136. #endif
  137. #ifdef CONFIG_MACH_SUN50I_H6
  138. /* Update PIO power bias configuration by copy hardware detected value */
  139. val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
  140. writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
  141. val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
  142. writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
  143. #endif
  144. return 0;
  145. }
  146. #if defined(CONFIG_SPL_BOARD_LOAD_IMAGE) && defined(CONFIG_SPL_BUILD)
  147. static int spl_board_load_image(struct spl_image_info *spl_image,
  148. struct spl_boot_device *bootdev)
  149. {
  150. debug("Returning to FEL sp=%x, lr=%x\n", fel_stash.sp, fel_stash.lr);
  151. return_to_fel(fel_stash.sp, fel_stash.lr);
  152. return 0;
  153. }
  154. SPL_LOAD_IMAGE_METHOD("FEL", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
  155. #endif
  156. void s_init(void)
  157. {
  158. /*
  159. * Undocumented magic taken from boot0, without this DRAM
  160. * access gets messed up (seems cache related).
  161. * The boot0 sources describe this as: "config ema for cache sram"
  162. */
  163. #if defined CONFIG_MACH_SUN6I
  164. setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0x1800);
  165. #elif defined CONFIG_MACH_SUN8I
  166. __maybe_unused uint version;
  167. /* Unlock sram version info reg, read it, relock */
  168. setbits_le32(SUNXI_SRAMC_BASE + 0x24, (1 << 15));
  169. version = readl(SUNXI_SRAMC_BASE + 0x24) >> 16;
  170. clrbits_le32(SUNXI_SRAMC_BASE + 0x24, (1 << 15));
  171. /*
  172. * Ideally this would be a switch case, but we do not know exactly
  173. * which versions there are and which version needs which settings,
  174. * so reproduce the per SoC code from the BSP.
  175. */
  176. #if defined CONFIG_MACH_SUN8I_A23
  177. if (version == 0x1650)
  178. setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0x1800);
  179. else /* 0x1661 ? */
  180. setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0xc0);
  181. #elif defined CONFIG_MACH_SUN8I_A33
  182. if (version != 0x1667)
  183. setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0xc0);
  184. #endif
  185. /* A83T BSP never modifies SUNXI_SRAMC_BASE + 0x44 */
  186. /* No H3 BSP, boot0 seems to not modify SUNXI_SRAMC_BASE + 0x44 */
  187. #endif
  188. #if !defined(CONFIG_ARM_CORTEX_CPU_IS_UP) && !defined(CONFIG_ARM64)
  189. /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */
  190. asm volatile(
  191. "mrc p15, 0, r0, c1, c0, 1\n"
  192. "orr r0, r0, #1 << 6\n"
  193. "mcr p15, 0, r0, c1, c0, 1\n"
  194. ::: "r0");
  195. #endif
  196. #if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I_H3
  197. /* Enable non-secure access to some peripherals */
  198. tzpc_init();
  199. #endif
  200. clock_init();
  201. timer_init();
  202. gpio_init();
  203. #ifndef CONFIG_DM_I2C
  204. i2c_init_board();
  205. #endif
  206. eth_init_board();
  207. }
  208. #define SUNXI_INVALID_BOOT_SOURCE -1
  209. static int sunxi_get_boot_source(void)
  210. {
  211. if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
  212. return SUNXI_INVALID_BOOT_SOURCE;
  213. return readb(SPL_ADDR + 0x28);
  214. }
  215. /* The sunxi internal brom will try to loader external bootloader
  216. * from mmc0, nand flash, mmc2.
  217. */
  218. uint32_t sunxi_get_boot_device(void)
  219. {
  220. int boot_source = sunxi_get_boot_source();
  221. /*
  222. * When booting from the SD card or NAND memory, the "eGON.BT0"
  223. * signature is expected to be found in memory at the address 0x0004
  224. * (see the "mksunxiboot" tool, which generates this header).
  225. *
  226. * When booting in the FEL mode over USB, this signature is patched in
  227. * memory and replaced with something else by the 'fel' tool. This other
  228. * signature is selected in such a way, that it can't be present in a
  229. * valid bootable SD card image (because the BROM would refuse to
  230. * execute the SPL in this case).
  231. *
  232. * This checks for the signature and if it is not found returns to
  233. * the FEL code in the BROM to wait and receive the main u-boot
  234. * binary over USB. If it is found, it determines where SPL was
  235. * read from.
  236. */
  237. switch (boot_source) {
  238. case SUNXI_INVALID_BOOT_SOURCE:
  239. return BOOT_DEVICE_BOARD;
  240. case SUNXI_BOOTED_FROM_MMC0:
  241. case SUNXI_BOOTED_FROM_MMC0_HIGH:
  242. return BOOT_DEVICE_MMC1;
  243. case SUNXI_BOOTED_FROM_NAND:
  244. return BOOT_DEVICE_NAND;
  245. case SUNXI_BOOTED_FROM_MMC2:
  246. case SUNXI_BOOTED_FROM_MMC2_HIGH:
  247. return BOOT_DEVICE_MMC2;
  248. case SUNXI_BOOTED_FROM_SPI:
  249. return BOOT_DEVICE_SPI;
  250. }
  251. panic("Unknown boot source %d\n", boot_source);
  252. return -1; /* Never reached */
  253. }
  254. #ifdef CONFIG_SPL_BUILD
  255. /*
  256. * The eGON SPL image can be located at 8KB or at 128KB into an SD card or
  257. * an eMMC device. The boot source has bit 4 set in the latter case.
  258. * By adding 120KB to the normal offset when booting from a "high" location
  259. * we can support both cases.
  260. */
  261. unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc)
  262. {
  263. unsigned long sector = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR;
  264. switch (sunxi_get_boot_source()) {
  265. case SUNXI_BOOTED_FROM_MMC0_HIGH:
  266. case SUNXI_BOOTED_FROM_MMC2_HIGH:
  267. sector += (128 - 8) * 2;
  268. break;
  269. }
  270. return sector;
  271. }
  272. u32 spl_boot_device(void)
  273. {
  274. return sunxi_get_boot_device();
  275. }
  276. void board_init_f(ulong dummy)
  277. {
  278. spl_init();
  279. preloader_console_init();
  280. #ifdef CONFIG_SPL_I2C_SUPPORT
  281. /* Needed early by sunxi_board_init if PMU is enabled */
  282. i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
  283. #endif
  284. sunxi_board_init();
  285. }
  286. #endif
  287. void reset_cpu(ulong addr)
  288. {
  289. #if defined(CONFIG_SUNXI_GEN_SUN4I) || defined(CONFIG_MACH_SUN8I_R40)
  290. static const struct sunxi_wdog *wdog =
  291. &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
  292. /* Set the watchdog for its shortest interval (.5s) and wait */
  293. writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
  294. writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl);
  295. while (1) {
  296. /* sun5i sometimes gets stuck without this */
  297. writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
  298. }
  299. #elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_MACH_SUN50I_H6)
  300. #if defined(CONFIG_MACH_SUN50I_H6)
  301. /* WDOG is broken for some H6 rev. use the R_WDOG instead */
  302. static const struct sunxi_wdog *wdog =
  303. (struct sunxi_wdog *)SUNXI_R_WDOG_BASE;
  304. #else
  305. static const struct sunxi_wdog *wdog =
  306. ((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
  307. #endif
  308. /* Set the watchdog for its shortest interval (.5s) and wait */
  309. writel(WDT_CFG_RESET, &wdog->cfg);
  310. writel(WDT_MODE_EN, &wdog->mode);
  311. writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl);
  312. while (1) { }
  313. #endif
  314. }
  315. #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_ARM64)
  316. void enable_caches(void)
  317. {
  318. /* Enable D-cache. I-cache is already enabled in start.S */
  319. dcache_enable();
  320. }
  321. #endif