cpu.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. /*
  2. * Copyright 2014-2015 Freescale Semiconductor, Inc.
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <asm/io.h>
  8. #include <asm/errno.h>
  9. #include <asm/system.h>
  10. #include <asm/armv8/mmu.h>
  11. #include <asm/io.h>
  12. #include <asm/arch/fsl_serdes.h>
  13. #include <asm/arch/soc.h>
  14. #include <asm/arch/cpu.h>
  15. #include <asm/arch/speed.h>
  16. #ifdef CONFIG_MP
  17. #include <asm/arch/mp.h>
  18. #endif
  19. #include <fm_eth.h>
  20. #include <fsl_debug_server.h>
  21. #include <fsl-mc/fsl_mc.h>
  22. #ifdef CONFIG_FSL_ESDHC
  23. #include <fsl_esdhc.h>
  24. #endif
  25. DECLARE_GLOBAL_DATA_PTR;
  26. static struct mm_region layerscape_mem_map[] = {
  27. {
  28. /* List terminator */
  29. 0,
  30. }
  31. };
  32. struct mm_region *mem_map = layerscape_mem_map;
  33. void cpu_name(char *name)
  34. {
  35. struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  36. unsigned int i, svr, ver;
  37. svr = gur_in32(&gur->svr);
  38. ver = SVR_SOC_VER(svr);
  39. for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++)
  40. if ((cpu_type_list[i].soc_ver & SVR_WO_E) == ver) {
  41. strcpy(name, cpu_type_list[i].name);
  42. if (IS_E_PROCESSOR(svr))
  43. strcat(name, "E");
  44. break;
  45. }
  46. if (i == ARRAY_SIZE(cpu_type_list))
  47. strcpy(name, "unknown");
  48. }
  49. #ifndef CONFIG_SYS_DCACHE_OFF
  50. static void set_pgtable_section(u64 *page_table, u64 index, u64 section,
  51. u64 memory_type, u64 attribute)
  52. {
  53. u64 value;
  54. value = section | PTE_TYPE_BLOCK | PTE_BLOCK_AF;
  55. value |= PMD_ATTRINDX(memory_type);
  56. value |= attribute;
  57. page_table[index] = value;
  58. }
  59. static void set_pgtable_table(u64 *page_table, u64 index, u64 *table_addr)
  60. {
  61. u64 value;
  62. value = (u64)table_addr | PTE_TYPE_TABLE;
  63. page_table[index] = value;
  64. }
  65. /*
  66. * Set the block entries according to the information of the table.
  67. */
  68. static int set_block_entry(const struct sys_mmu_table *list,
  69. struct table_info *table)
  70. {
  71. u64 block_size = 0, block_shift = 0;
  72. u64 block_addr, index;
  73. int j;
  74. if (table->entry_size == BLOCK_SIZE_L1) {
  75. block_size = BLOCK_SIZE_L1;
  76. block_shift = SECTION_SHIFT_L1;
  77. } else if (table->entry_size == BLOCK_SIZE_L2) {
  78. block_size = BLOCK_SIZE_L2;
  79. block_shift = SECTION_SHIFT_L2;
  80. } else {
  81. return -EINVAL;
  82. }
  83. block_addr = list->phys_addr;
  84. index = (list->virt_addr - table->table_base) >> block_shift;
  85. for (j = 0; j < (list->size >> block_shift); j++) {
  86. set_pgtable_section(table->ptr,
  87. index,
  88. block_addr,
  89. list->memory_type,
  90. list->attribute);
  91. block_addr += block_size;
  92. index++;
  93. }
  94. return 0;
  95. }
  96. /*
  97. * Find the corresponding table entry for the list.
  98. */
  99. static int find_table(const struct sys_mmu_table *list,
  100. struct table_info *table, u64 *level0_table)
  101. {
  102. u64 index = 0, level = 0;
  103. u64 *level_table = level0_table;
  104. u64 temp_base = 0, block_size = 0, block_shift = 0;
  105. while (level < 3) {
  106. if (level == 0) {
  107. block_size = BLOCK_SIZE_L0;
  108. block_shift = SECTION_SHIFT_L0;
  109. } else if (level == 1) {
  110. block_size = BLOCK_SIZE_L1;
  111. block_shift = SECTION_SHIFT_L1;
  112. } else if (level == 2) {
  113. block_size = BLOCK_SIZE_L2;
  114. block_shift = SECTION_SHIFT_L2;
  115. }
  116. index = 0;
  117. while (list->virt_addr >= temp_base) {
  118. index++;
  119. temp_base += block_size;
  120. }
  121. temp_base -= block_size;
  122. if ((level_table[index - 1] & PTE_TYPE_MASK) ==
  123. PTE_TYPE_TABLE) {
  124. level_table = (u64 *)(level_table[index - 1] &
  125. ~PTE_TYPE_MASK);
  126. level++;
  127. continue;
  128. } else {
  129. if (level == 0)
  130. return -EINVAL;
  131. if ((list->phys_addr + list->size) >
  132. (temp_base + block_size * NUM_OF_ENTRY))
  133. return -EINVAL;
  134. /*
  135. * Check the address and size of the list member is
  136. * aligned with the block size.
  137. */
  138. if (((list->phys_addr & (block_size - 1)) != 0) ||
  139. ((list->size & (block_size - 1)) != 0))
  140. return -EINVAL;
  141. table->ptr = level_table;
  142. table->table_base = temp_base -
  143. ((index - 1) << block_shift);
  144. table->entry_size = block_size;
  145. return 0;
  146. }
  147. }
  148. return -EINVAL;
  149. }
  150. /*
  151. * To start MMU before DDR is available, we create MMU table in SRAM.
  152. * The base address of SRAM is CONFIG_SYS_FSL_OCRAM_BASE. We use three
  153. * levels of translation tables here to cover 40-bit address space.
  154. * We use 4KB granule size, with 40 bits physical address, T0SZ=24
  155. * Level 0 IA[39], table address @0
  156. * Level 1 IA[38:30], table address @0x1000, 0x2000
  157. * Level 2 IA[29:21], table address @0x3000, 0x4000
  158. * Address above 0x5000 is free for other purpose.
  159. */
  160. static inline void early_mmu_setup(void)
  161. {
  162. unsigned int el, i;
  163. u64 *level0_table = (u64 *)CONFIG_SYS_FSL_OCRAM_BASE;
  164. u64 *level1_table0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x1000);
  165. u64 *level1_table1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x2000);
  166. u64 *level2_table0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x3000);
  167. u64 *level2_table1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x4000);
  168. struct table_info table = {level0_table, 0, BLOCK_SIZE_L0};
  169. /* Invalidate all table entries */
  170. memset(level0_table, 0, 0x5000);
  171. /* Fill in the table entries */
  172. set_pgtable_table(level0_table, 0, level1_table0);
  173. set_pgtable_table(level0_table, 1, level1_table1);
  174. set_pgtable_table(level1_table0, 0, level2_table0);
  175. #ifdef CONFIG_FSL_LSCH3
  176. set_pgtable_table(level1_table0,
  177. CONFIG_SYS_FLASH_BASE >> SECTION_SHIFT_L1,
  178. level2_table1);
  179. #elif defined(CONFIG_FSL_LSCH2)
  180. set_pgtable_table(level1_table0, 1, level2_table1);
  181. #endif
  182. /* Find the table and fill in the block entries */
  183. for (i = 0; i < ARRAY_SIZE(early_mmu_table); i++) {
  184. if (find_table(&early_mmu_table[i],
  185. &table, level0_table) == 0) {
  186. /*
  187. * If find_table() returns error, it cannot be dealt
  188. * with here. Breakpoint can be added for debugging.
  189. */
  190. set_block_entry(&early_mmu_table[i], &table);
  191. /*
  192. * If set_block_entry() returns error, it cannot be
  193. * dealt with here too.
  194. */
  195. }
  196. }
  197. el = current_el();
  198. set_ttbr_tcr_mair(el, (u64)level0_table, LAYERSCAPE_TCR,
  199. MEMORY_ATTRIBUTES);
  200. set_sctlr(get_sctlr() | CR_M);
  201. }
  202. #ifdef CONFIG_SYS_MEM_RESERVE_SECURE
  203. /*
  204. * Called from final mmu setup. The phys_addr is new, non-existing
  205. * address. A new sub table is created @level2_table_secure to cover
  206. * size of CONFIG_SYS_MEM_RESERVE_SECURE memory.
  207. */
  208. static inline int final_secure_ddr(u64 *level0_table,
  209. u64 *level2_table_secure,
  210. phys_addr_t phys_addr)
  211. {
  212. int ret = -EINVAL;
  213. struct table_info table = {};
  214. struct sys_mmu_table ddr_entry = {
  215. 0, 0, BLOCK_SIZE_L1, MT_NORMAL,
  216. PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS
  217. };
  218. u64 index;
  219. /* Need to create a new table */
  220. ddr_entry.virt_addr = phys_addr & ~(BLOCK_SIZE_L1 - 1);
  221. ddr_entry.phys_addr = phys_addr & ~(BLOCK_SIZE_L1 - 1);
  222. ret = find_table(&ddr_entry, &table, level0_table);
  223. if (ret)
  224. return ret;
  225. index = (ddr_entry.virt_addr - table.table_base) >> SECTION_SHIFT_L1;
  226. set_pgtable_table(table.ptr, index, level2_table_secure);
  227. table.ptr = level2_table_secure;
  228. table.table_base = ddr_entry.virt_addr;
  229. table.entry_size = BLOCK_SIZE_L2;
  230. ret = set_block_entry(&ddr_entry, &table);
  231. if (ret) {
  232. printf("MMU error: could not fill non-secure ddr block entries\n");
  233. return ret;
  234. }
  235. ddr_entry.virt_addr = phys_addr;
  236. ddr_entry.phys_addr = phys_addr;
  237. ddr_entry.size = CONFIG_SYS_MEM_RESERVE_SECURE;
  238. ddr_entry.attribute = PTE_BLOCK_OUTER_SHARE;
  239. ret = find_table(&ddr_entry, &table, level0_table);
  240. if (ret) {
  241. printf("MMU error: could not find secure ddr table\n");
  242. return ret;
  243. }
  244. ret = set_block_entry(&ddr_entry, &table);
  245. if (ret)
  246. printf("MMU error: could not set secure ddr block entry\n");
  247. return ret;
  248. }
  249. #endif
  250. /*
  251. * The final tables look similar to early tables, but different in detail.
  252. * These tables are in DRAM. Sub tables are added to enable cache for
  253. * QBMan and OCRAM.
  254. *
  255. * Put the MMU table in secure memory if gd->secure_ram is valid.
  256. * OCRAM will be not used for this purpose so gd->secure_ram can't be 0.
  257. *
  258. * Level 1 table 0 contains 512 entries for each 1GB from 0 to 512GB.
  259. * Level 1 table 1 contains 512 entries for each 1GB from 512GB to 1TB.
  260. * Level 2 table 0 contains 512 entries for each 2MB from 0 to 1GB.
  261. *
  262. * For LSCH3:
  263. * Level 2 table 1 contains 512 entries for each 2MB from 32GB to 33GB.
  264. * For LSCH2:
  265. * Level 2 table 1 contains 512 entries for each 2MB from 1GB to 2GB.
  266. * Level 2 table 2 contains 512 entries for each 2MB from 20GB to 21GB.
  267. */
  268. static inline void final_mmu_setup(void)
  269. {
  270. unsigned int el = current_el();
  271. unsigned int i;
  272. u64 *level0_table = (u64 *)gd->arch.tlb_addr;
  273. u64 *level1_table0;
  274. u64 *level1_table1;
  275. u64 *level2_table0;
  276. u64 *level2_table1;
  277. #ifdef CONFIG_FSL_LSCH2
  278. u64 *level2_table2;
  279. #endif
  280. struct table_info table = {NULL, 0, BLOCK_SIZE_L0};
  281. #ifdef CONFIG_SYS_MEM_RESERVE_SECURE
  282. u64 *level2_table_secure;
  283. if (el == 3) {
  284. /*
  285. * Only use gd->secure_ram if the address is recalculated
  286. * Align to 4KB for MMU table
  287. */
  288. if (gd->secure_ram & MEM_RESERVE_SECURE_MAINTAINED)
  289. level0_table = (u64 *)(gd->secure_ram & ~0xfff);
  290. else
  291. printf("MMU warning: gd->secure_ram is not maintained, disabled.\n");
  292. }
  293. #endif
  294. level1_table0 = level0_table + 512;
  295. level1_table1 = level1_table0 + 512;
  296. level2_table0 = level1_table1 + 512;
  297. level2_table1 = level2_table0 + 512;
  298. #ifdef CONFIG_FSL_LSCH2
  299. level2_table2 = level2_table1 + 512;
  300. #endif
  301. table.ptr = level0_table;
  302. /* Invalidate all table entries */
  303. memset(level0_table, 0, PGTABLE_SIZE);
  304. /* Fill in the table entries */
  305. set_pgtable_table(level0_table, 0, level1_table0);
  306. set_pgtable_table(level0_table, 1, level1_table1);
  307. set_pgtable_table(level1_table0, 0, level2_table0);
  308. #ifdef CONFIG_FSL_LSCH3
  309. set_pgtable_table(level1_table0,
  310. CONFIG_SYS_FSL_QBMAN_BASE >> SECTION_SHIFT_L1,
  311. level2_table1);
  312. #elif defined(CONFIG_FSL_LSCH2)
  313. set_pgtable_table(level1_table0, 1, level2_table1);
  314. set_pgtable_table(level1_table0,
  315. CONFIG_SYS_FSL_QBMAN_BASE >> SECTION_SHIFT_L1,
  316. level2_table2);
  317. #endif
  318. /* Find the table and fill in the block entries */
  319. for (i = 0; i < ARRAY_SIZE(final_mmu_table); i++) {
  320. if (find_table(&final_mmu_table[i],
  321. &table, level0_table) == 0) {
  322. if (set_block_entry(&final_mmu_table[i],
  323. &table) != 0) {
  324. printf("MMU error: could not set block entry for %p\n",
  325. &final_mmu_table[i]);
  326. }
  327. } else {
  328. printf("MMU error: could not find the table for %p\n",
  329. &final_mmu_table[i]);
  330. }
  331. }
  332. /* Set the secure memory to secure in MMU */
  333. #ifdef CONFIG_SYS_MEM_RESERVE_SECURE
  334. if (el == 3 && gd->secure_ram & MEM_RESERVE_SECURE_MAINTAINED) {
  335. #ifdef CONFIG_FSL_LSCH3
  336. level2_table_secure = level2_table1 + 512;
  337. #elif defined(CONFIG_FSL_LSCH2)
  338. level2_table_secure = level2_table2 + 512;
  339. #endif
  340. if (!final_secure_ddr(level0_table,
  341. level2_table_secure,
  342. gd->secure_ram & ~0x3)) {
  343. gd->secure_ram |= MEM_RESERVE_SECURE_SECURED;
  344. debug("Now MMU table is in secured memory at 0x%llx\n",
  345. gd->secure_ram & ~0x3);
  346. } else {
  347. printf("MMU warning: Failed to secure DDR\n");
  348. }
  349. }
  350. #endif
  351. /* flush new MMU table */
  352. flush_dcache_range((ulong)level0_table,
  353. (ulong)level0_table + gd->arch.tlb_size);
  354. #ifdef CONFIG_SYS_DPAA_FMAN
  355. flush_dcache_all();
  356. #endif
  357. /* point TTBR to the new table */
  358. set_ttbr_tcr_mair(el, (u64)level0_table, LAYERSCAPE_TCR_FINAL,
  359. MEMORY_ATTRIBUTES);
  360. /*
  361. * MMU is already enabled, just need to invalidate TLB to load the
  362. * new table. The new table is compatible with the current table, if
  363. * MMU somehow walks through the new table before invalidation TLB,
  364. * it still works. So we don't need to turn off MMU here.
  365. */
  366. }
  367. u64 get_page_table_size(void)
  368. {
  369. return 0x10000;
  370. }
  371. int arch_cpu_init(void)
  372. {
  373. icache_enable();
  374. __asm_invalidate_dcache_all();
  375. __asm_invalidate_tlb_all();
  376. early_mmu_setup();
  377. set_sctlr(get_sctlr() | CR_C);
  378. return 0;
  379. }
  380. /*
  381. * This function is called from lib/board.c.
  382. * It recreates MMU table in main memory. MMU and d-cache are enabled earlier.
  383. * There is no need to disable d-cache for this operation.
  384. */
  385. void enable_caches(void)
  386. {
  387. final_mmu_setup();
  388. __asm_invalidate_tlb_all();
  389. }
  390. #endif
  391. static inline u32 initiator_type(u32 cluster, int init_id)
  392. {
  393. struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  394. u32 idx = (cluster >> (init_id * 8)) & TP_CLUSTER_INIT_MASK;
  395. u32 type = 0;
  396. type = gur_in32(&gur->tp_ityp[idx]);
  397. if (type & TP_ITYP_AV)
  398. return type;
  399. return 0;
  400. }
  401. u32 cpu_mask(void)
  402. {
  403. struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  404. int i = 0, count = 0;
  405. u32 cluster, type, mask = 0;
  406. do {
  407. int j;
  408. cluster = gur_in32(&gur->tp_cluster[i].lower);
  409. for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
  410. type = initiator_type(cluster, j);
  411. if (type) {
  412. if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_ARM)
  413. mask |= 1 << count;
  414. count++;
  415. }
  416. }
  417. i++;
  418. } while ((cluster & TP_CLUSTER_EOC) == 0x0);
  419. return mask;
  420. }
  421. /*
  422. * Return the number of cores on this SOC.
  423. */
  424. int cpu_numcores(void)
  425. {
  426. return hweight32(cpu_mask());
  427. }
  428. int fsl_qoriq_core_to_cluster(unsigned int core)
  429. {
  430. struct ccsr_gur __iomem *gur =
  431. (void __iomem *)(CONFIG_SYS_FSL_GUTS_ADDR);
  432. int i = 0, count = 0;
  433. u32 cluster;
  434. do {
  435. int j;
  436. cluster = gur_in32(&gur->tp_cluster[i].lower);
  437. for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
  438. if (initiator_type(cluster, j)) {
  439. if (count == core)
  440. return i;
  441. count++;
  442. }
  443. }
  444. i++;
  445. } while ((cluster & TP_CLUSTER_EOC) == 0x0);
  446. return -1; /* cannot identify the cluster */
  447. }
  448. u32 fsl_qoriq_core_to_type(unsigned int core)
  449. {
  450. struct ccsr_gur __iomem *gur =
  451. (void __iomem *)(CONFIG_SYS_FSL_GUTS_ADDR);
  452. int i = 0, count = 0;
  453. u32 cluster, type;
  454. do {
  455. int j;
  456. cluster = gur_in32(&gur->tp_cluster[i].lower);
  457. for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
  458. type = initiator_type(cluster, j);
  459. if (type) {
  460. if (count == core)
  461. return type;
  462. count++;
  463. }
  464. }
  465. i++;
  466. } while ((cluster & TP_CLUSTER_EOC) == 0x0);
  467. return -1; /* cannot identify the cluster */
  468. }
  469. #ifdef CONFIG_DISPLAY_CPUINFO
  470. int print_cpuinfo(void)
  471. {
  472. struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  473. struct sys_info sysinfo;
  474. char buf[32];
  475. unsigned int i, core;
  476. u32 type, rcw;
  477. puts("SoC: ");
  478. cpu_name(buf);
  479. printf(" %s (0x%x)\n", buf, gur_in32(&gur->svr));
  480. memset((u8 *)buf, 0x00, ARRAY_SIZE(buf));
  481. get_sys_info(&sysinfo);
  482. puts("Clock Configuration:");
  483. for_each_cpu(i, core, cpu_numcores(), cpu_mask()) {
  484. if (!(i % 3))
  485. puts("\n ");
  486. type = TP_ITYP_VER(fsl_qoriq_core_to_type(core));
  487. printf("CPU%d(%s):%-4s MHz ", core,
  488. type == TY_ITYP_VER_A7 ? "A7 " :
  489. (type == TY_ITYP_VER_A53 ? "A53" :
  490. (type == TY_ITYP_VER_A57 ? "A57" : " ")),
  491. strmhz(buf, sysinfo.freq_processor[core]));
  492. }
  493. printf("\n Bus: %-4s MHz ",
  494. strmhz(buf, sysinfo.freq_systembus));
  495. printf("DDR: %-4s MT/s", strmhz(buf, sysinfo.freq_ddrbus));
  496. #ifdef CONFIG_SYS_DPAA_FMAN
  497. printf(" FMAN: %-4s MHz", strmhz(buf, sysinfo.freq_fman[0]));
  498. #endif
  499. #ifdef CONFIG_SYS_FSL_HAS_DP_DDR
  500. printf(" DP-DDR: %-4s MT/s", strmhz(buf, sysinfo.freq_ddrbus2));
  501. #endif
  502. puts("\n");
  503. /*
  504. * Display the RCW, so that no one gets confused as to what RCW
  505. * we're actually using for this boot.
  506. */
  507. puts("Reset Configuration Word (RCW):");
  508. for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) {
  509. rcw = gur_in32(&gur->rcwsr[i]);
  510. if ((i % 4) == 0)
  511. printf("\n %08x:", i * 4);
  512. printf(" %08x", rcw);
  513. }
  514. puts("\n");
  515. return 0;
  516. }
  517. #endif
  518. #ifdef CONFIG_FSL_ESDHC
  519. int cpu_mmc_init(bd_t *bis)
  520. {
  521. return fsl_esdhc_mmc_init(bis);
  522. }
  523. #endif
  524. int cpu_eth_init(bd_t *bis)
  525. {
  526. int error = 0;
  527. #ifdef CONFIG_FSL_MC_ENET
  528. error = fsl_mc_ldpaa_init(bis);
  529. #endif
  530. #ifdef CONFIG_FMAN_ENET
  531. fm_standard_init(bis);
  532. #endif
  533. return error;
  534. }
  535. int arch_early_init_r(void)
  536. {
  537. #ifdef CONFIG_MP
  538. int rv = 1;
  539. #endif
  540. #ifdef CONFIG_SYS_FSL_ERRATUM_A009635
  541. erratum_a009635();
  542. #endif
  543. #ifdef CONFIG_MP
  544. rv = fsl_layerscape_wake_seconday_cores();
  545. if (rv)
  546. printf("Did not wake secondary cores\n");
  547. #endif
  548. #ifdef CONFIG_SYS_HAS_SERDES
  549. fsl_serdes_init();
  550. #endif
  551. #ifdef CONFIG_FMAN_ENET
  552. fman_enet_init();
  553. #endif
  554. return 0;
  555. }
  556. int timer_init(void)
  557. {
  558. u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR;
  559. #ifdef CONFIG_FSL_LSCH3
  560. u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR;
  561. #endif
  562. #ifdef COUNTER_FREQUENCY_REAL
  563. unsigned long cntfrq = COUNTER_FREQUENCY_REAL;
  564. /* Update with accurate clock frequency */
  565. asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory");
  566. #endif
  567. #ifdef CONFIG_FSL_LSCH3
  568. /* Enable timebase for all clusters.
  569. * It is safe to do so even some clusters are not enabled.
  570. */
  571. out_le32(cltbenr, 0xf);
  572. #endif
  573. /* Enable clock for timer
  574. * This is a global setting.
  575. */
  576. out_le32(cntcr, 0x1);
  577. return 0;
  578. }
  579. void reset_cpu(ulong addr)
  580. {
  581. u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR;
  582. u32 val;
  583. /* Raise RESET_REQ_B */
  584. val = scfg_in32(rstcr);
  585. val |= 0x02;
  586. scfg_out32(rstcr, val);
  587. }
  588. phys_size_t board_reserve_ram_top(phys_size_t ram_size)
  589. {
  590. phys_size_t ram_top = ram_size;
  591. #ifdef CONFIG_SYS_MEM_TOP_HIDE
  592. #error CONFIG_SYS_MEM_TOP_HIDE not to be used together with this function
  593. #endif
  594. /* Carve the Debug Server private DRAM block from the end of DRAM */
  595. #ifdef CONFIG_FSL_DEBUG_SERVER
  596. ram_top -= debug_server_get_dram_block_size();
  597. #endif
  598. /* Carve the MC private DRAM block from the end of DRAM */
  599. #ifdef CONFIG_FSL_MC_ENET
  600. ram_top -= mc_get_dram_block_size();
  601. ram_top &= ~(CONFIG_SYS_MC_RSV_MEM_ALIGN - 1);
  602. #endif
  603. return ram_top;
  604. }