cpu.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2016 Stefan Roese <sr@denx.de>
  4. * Copyright (C) 2020 Marek Behun <marek.behun@nic.cz>
  5. */
  6. #include <common.h>
  7. #include <cpu_func.h>
  8. #include <dm.h>
  9. #include <fdtdec.h>
  10. #include <init.h>
  11. #include <asm/global_data.h>
  12. #include <linux/bitops.h>
  13. #include <linux/libfdt.h>
  14. #include <asm/io.h>
  15. #include <asm/system.h>
  16. #include <asm/arch/cpu.h>
  17. #include <asm/arch/soc.h>
  18. #include <asm/armv8/mmu.h>
  19. #include <sort.h>
  20. /* Armada 3700 */
  21. #define MVEBU_GPIO_NB_REG_BASE (MVEBU_REGISTER(0x13800))
  22. #define MVEBU_TEST_PIN_LATCH_N (MVEBU_GPIO_NB_REG_BASE + 0x8)
  23. #define MVEBU_XTAL_MODE_MASK BIT(9)
  24. #define MVEBU_XTAL_MODE_OFFS 9
  25. #define MVEBU_XTAL_CLOCK_25MHZ 0x0
  26. #define MVEBU_XTAL_CLOCK_40MHZ 0x1
  27. #define MVEBU_NB_WARM_RST_REG (MVEBU_GPIO_NB_REG_BASE + 0x40)
  28. #define MVEBU_NB_WARM_RST_MAGIC_NUM 0x1d1e
  29. /* Armada 3700 CPU Address Decoder registers */
  30. #define MVEBU_CPU_DEC_WIN_REG_BASE (size_t)(MVEBU_REGISTER(0xcf00))
  31. #define MVEBU_CPU_DEC_WIN_CTRL(w) \
  32. (MVEBU_CPU_DEC_WIN_REG_BASE + ((w) << 4))
  33. #define MVEBU_CPU_DEC_WIN_CTRL_EN BIT(0)
  34. #define MVEBU_CPU_DEC_WIN_CTRL_TGT_MASK 0xf
  35. #define MVEBU_CPU_DEC_WIN_CTRL_TGT_OFFS 4
  36. #define MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM 0
  37. #define MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE 2
  38. #define MVEBU_CPU_DEC_WIN_SIZE(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0x4)
  39. #define MVEBU_CPU_DEC_WIN_BASE(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0x8)
  40. #define MVEBU_CPU_DEC_WIN_REMAP(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0xc)
  41. #define MVEBU_CPU_DEC_WIN_GRANULARITY 16
  42. #define MVEBU_CPU_DEC_WINS 5
  43. #define MAX_MEM_MAP_REGIONS (MVEBU_CPU_DEC_WINS + 2)
  44. #define A3700_PTE_BLOCK_NORMAL \
  45. (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE)
  46. #define A3700_PTE_BLOCK_DEVICE \
  47. (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE)
  48. #define PCIE_PATH "/soc/pcie@d0070000"
  49. DECLARE_GLOBAL_DATA_PTR;
  50. static struct mm_region mvebu_mem_map[MAX_MEM_MAP_REGIONS] = {
  51. {
  52. /*
  53. * SRAM, MMIO regions
  54. * Don't remove this, a3700_build_mem_map needs it.
  55. */
  56. .phys = SOC_REGS_PHY_BASE,
  57. .virt = SOC_REGS_PHY_BASE,
  58. .size = 0x02000000UL, /* 32MiB internal registers */
  59. .attrs = A3700_PTE_BLOCK_DEVICE
  60. },
  61. };
  62. struct mm_region *mem_map = mvebu_mem_map;
  63. static int get_cpu_dec_win(int win, u32 *tgt, u32 *base, u32 *size)
  64. {
  65. u32 reg;
  66. reg = readl(MVEBU_CPU_DEC_WIN_CTRL(win));
  67. if (!(reg & MVEBU_CPU_DEC_WIN_CTRL_EN))
  68. return -1;
  69. if (tgt) {
  70. reg >>= MVEBU_CPU_DEC_WIN_CTRL_TGT_OFFS;
  71. reg &= MVEBU_CPU_DEC_WIN_CTRL_TGT_MASK;
  72. *tgt = reg;
  73. }
  74. if (base) {
  75. reg = readl(MVEBU_CPU_DEC_WIN_BASE(win));
  76. *base = reg << MVEBU_CPU_DEC_WIN_GRANULARITY;
  77. }
  78. if (size) {
  79. /*
  80. * Window size is encoded as the number of 1s from LSB to MSB,
  81. * followed by 0s. The number of 1s specifies the size in 64 KiB
  82. * granularity.
  83. */
  84. reg = readl(MVEBU_CPU_DEC_WIN_SIZE(win));
  85. *size = ((reg + 1) << MVEBU_CPU_DEC_WIN_GRANULARITY);
  86. }
  87. return 0;
  88. }
  89. /*
  90. * Builds mem_map according to CPU Address Decoder settings, which were set by
  91. * the TIMH image on the Cortex-M3 secure processor, or by ARM Trusted Firmware
  92. */
  93. static void build_mem_map(void)
  94. {
  95. int win, region;
  96. region = 1;
  97. for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) {
  98. u32 base, tgt, size;
  99. u64 attrs;
  100. /* skip disabled windows */
  101. if (get_cpu_dec_win(win, &tgt, &base, &size))
  102. continue;
  103. if (tgt == MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM)
  104. attrs = A3700_PTE_BLOCK_NORMAL;
  105. else if (tgt == MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE)
  106. attrs = A3700_PTE_BLOCK_DEVICE;
  107. else
  108. /* skip windows with other targets */
  109. continue;
  110. mvebu_mem_map[region].phys = base;
  111. mvebu_mem_map[region].virt = base;
  112. mvebu_mem_map[region].size = size;
  113. mvebu_mem_map[region].attrs = attrs;
  114. ++region;
  115. }
  116. /* add list terminator */
  117. mvebu_mem_map[region].size = 0;
  118. mvebu_mem_map[region].attrs = 0;
  119. }
  120. void enable_caches(void)
  121. {
  122. build_mem_map();
  123. icache_enable();
  124. dcache_enable();
  125. }
  126. int a3700_dram_init(void)
  127. {
  128. int win;
  129. gd->ram_size = 0;
  130. for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) {
  131. u32 base, tgt, size;
  132. /* skip disabled windows */
  133. if (get_cpu_dec_win(win, &tgt, &base, &size))
  134. continue;
  135. /* skip non-DRAM windows */
  136. if (tgt != MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM)
  137. continue;
  138. /*
  139. * It is possible that one image was built for boards with
  140. * different RAM sizes, for example 512 MiB and 1 GiB.
  141. * We therefore try to determine the actual RAM size in the
  142. * window with get_ram_size.
  143. */
  144. gd->ram_size += get_ram_size((void *)(size_t)base, size);
  145. }
  146. return 0;
  147. }
  148. struct a3700_dram_window {
  149. size_t base, size;
  150. };
  151. static int dram_win_cmp(const void *a, const void *b)
  152. {
  153. size_t ab, bb;
  154. ab = ((const struct a3700_dram_window *)a)->base;
  155. bb = ((const struct a3700_dram_window *)b)->base;
  156. if (ab < bb)
  157. return -1;
  158. else if (ab > bb)
  159. return 1;
  160. else
  161. return 0;
  162. }
  163. int a3700_dram_init_banksize(void)
  164. {
  165. struct a3700_dram_window dram_wins[MVEBU_CPU_DEC_WINS];
  166. int bank, win, ndram_wins;
  167. u32 last_end;
  168. size_t size;
  169. ndram_wins = 0;
  170. for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) {
  171. u32 base, tgt, size;
  172. /* skip disabled windows */
  173. if (get_cpu_dec_win(win, &tgt, &base, &size))
  174. continue;
  175. /* skip non-DRAM windows */
  176. if (tgt != MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM)
  177. continue;
  178. dram_wins[win].base = base;
  179. dram_wins[win].size = size;
  180. ++ndram_wins;
  181. }
  182. qsort(dram_wins, ndram_wins, sizeof(dram_wins[0]), dram_win_cmp);
  183. bank = 0;
  184. last_end = -1;
  185. for (win = 0; win < ndram_wins; ++win) {
  186. /* again determining actual RAM size as in a3700_dram_init */
  187. size = get_ram_size((void *)dram_wins[win].base,
  188. dram_wins[win].size);
  189. /*
  190. * Check if previous window ends as the current starts. If yes,
  191. * merge these windows into one "bank". This is possible by this
  192. * simple check thanks to mem_map regions being qsorted in
  193. * build_mem_map.
  194. */
  195. if (last_end == dram_wins[win].base) {
  196. gd->bd->bi_dram[bank - 1].size += size;
  197. last_end += size;
  198. } else {
  199. if (bank == CONFIG_NR_DRAM_BANKS) {
  200. printf("Need more CONFIG_NR_DRAM_BANKS\n");
  201. return -ENOBUFS;
  202. }
  203. gd->bd->bi_dram[bank].start = dram_wins[win].base;
  204. gd->bd->bi_dram[bank].size = size;
  205. last_end = dram_wins[win].base + size;
  206. ++bank;
  207. }
  208. }
  209. /*
  210. * If there is more place for DRAM BANKS definitions than needed, fill
  211. * the rest with zeros.
  212. */
  213. for (; bank < CONFIG_NR_DRAM_BANKS; ++bank) {
  214. gd->bd->bi_dram[bank].start = 0;
  215. gd->bd->bi_dram[bank].size = 0;
  216. }
  217. return 0;
  218. }
  219. static u32 find_pcie_window_base(void)
  220. {
  221. int win;
  222. for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) {
  223. u32 base, tgt;
  224. /* skip disabled windows */
  225. if (get_cpu_dec_win(win, &tgt, &base, NULL))
  226. continue;
  227. if (tgt == MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE)
  228. return base;
  229. }
  230. return -1;
  231. }
  232. int a3700_fdt_fix_pcie_regions(void *blob)
  233. {
  234. u32 new_ranges[14], base;
  235. const u32 *ranges;
  236. int node, len;
  237. node = fdt_path_offset(blob, PCIE_PATH);
  238. if (node < 0)
  239. return node;
  240. ranges = fdt_getprop(blob, node, "ranges", &len);
  241. if (!ranges)
  242. return -ENOENT;
  243. if (len != sizeof(new_ranges))
  244. return -EINVAL;
  245. memcpy(new_ranges, ranges, len);
  246. base = find_pcie_window_base();
  247. if (base == -1)
  248. return -ENOENT;
  249. new_ranges[2] = cpu_to_fdt32(base);
  250. new_ranges[4] = new_ranges[2];
  251. new_ranges[9] = cpu_to_fdt32(base + 0x1000000);
  252. new_ranges[11] = new_ranges[9];
  253. return fdt_setprop_inplace(blob, node, "ranges", new_ranges, len);
  254. }
  255. void reset_cpu(void)
  256. {
  257. /*
  258. * Write magic number of 0x1d1e to North Bridge Warm Reset register
  259. * to trigger warm reset
  260. */
  261. writel(MVEBU_NB_WARM_RST_MAGIC_NUM, MVEBU_NB_WARM_RST_REG);
  262. }
  263. /*
  264. * get_ref_clk
  265. *
  266. * return: reference clock in MHz (25 or 40)
  267. */
  268. u32 get_ref_clk(void)
  269. {
  270. u32 regval;
  271. regval = (readl(MVEBU_TEST_PIN_LATCH_N) & MVEBU_XTAL_MODE_MASK) >>
  272. MVEBU_XTAL_MODE_OFFS;
  273. if (regval == MVEBU_XTAL_CLOCK_25MHZ)
  274. return 25;
  275. else
  276. return 40;
  277. }