hsdk.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
  4. * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
  5. */
  6. #include <common.h>
  7. #include <config.h>
  8. #include <cpu_func.h>
  9. #include <env.h>
  10. #include <init.h>
  11. #include <irq_func.h>
  12. #include <linux/printk.h>
  13. #include <linux/kernel.h>
  14. #include <linux/io.h>
  15. #include <asm/arcregs.h>
  16. #include <fdt_support.h>
  17. #include <dwmmc.h>
  18. #include <malloc.h>
  19. #include <usb.h>
  20. #include "clk-lib.h"
  21. #include "env-lib.h"
  22. DECLARE_GLOBAL_DATA_PTR;
  23. #define ALL_CPU_MASK GENMASK(NR_CPUS - 1, 0)
  24. #define MASTER_CPU_ID 0
  25. #define APERTURE_SHIFT 28
  26. #define NO_CCM 0x10
  27. #define SLAVE_CPU_READY 0x12345678
  28. #define BOOTSTAGE_1 1 /* after SP, FP setup, before HW init */
  29. #define BOOTSTAGE_2 2 /* after HW init, before self halt */
  30. #define BOOTSTAGE_3 3 /* after self halt */
  31. #define BOOTSTAGE_4 4 /* before app launch */
  32. #define BOOTSTAGE_5 5 /* after app launch, unreachable */
  33. #define RESET_VECTOR_ADDR 0x0
  34. #define CREG_BASE (ARC_PERIPHERAL_BASE + 0x1000)
  35. #define CREG_CPU_START (CREG_BASE + 0x400)
  36. #define CREG_CPU_START_MASK 0xF
  37. #define CREG_CPU_START_POL BIT(4)
  38. #define CREG_CPU_0_ENTRY (CREG_BASE + 0x404)
  39. #define SDIO_BASE (ARC_PERIPHERAL_BASE + 0xA000)
  40. #define SDIO_UHS_REG_EXT (SDIO_BASE + 0x108)
  41. #define SDIO_UHS_REG_EXT_DIV_2 (2 << 30)
  42. /* Uncached access macros */
  43. #define arc_read_uncached_32(ptr) \
  44. ({ \
  45. unsigned int __ret; \
  46. __asm__ __volatile__( \
  47. " ld.di %0, [%1] \n" \
  48. : "=r"(__ret) \
  49. : "r"(ptr)); \
  50. __ret; \
  51. })
  52. #define arc_write_uncached_32(ptr, data)\
  53. ({ \
  54. __asm__ __volatile__( \
  55. " st.di %0, [%1] \n" \
  56. : \
  57. : "r"(data), "r"(ptr)); \
  58. })
  59. struct hsdk_env_core_ctl {
  60. u32_env entry[NR_CPUS];
  61. u32_env iccm[NR_CPUS];
  62. u32_env dccm[NR_CPUS];
  63. };
  64. struct hsdk_env_common_ctl {
  65. bool halt_on_boot;
  66. u32_env core_mask;
  67. u32_env cpu_freq;
  68. u32_env axi_freq;
  69. u32_env tun_freq;
  70. u32_env nvlim;
  71. u32_env icache;
  72. u32_env dcache;
  73. u32_env csm_location;
  74. u32_env l2_cache;
  75. u32_env haps_apb;
  76. };
  77. /*
  78. * Uncached cross-cpu structure. All CPUs must access to this structure fields
  79. * only with arc_read_uncached_32() / arc_write_uncached_32() accessors (which
  80. * implement ld.di / st.di instructions). Simultaneous cached and uncached
  81. * access to this area will lead to data loss.
  82. * We flush all data caches in board_early_init_r() as we don't want to have
  83. * any dirty line in L1d$ or SL$ in this area.
  84. */
  85. struct hsdk_cross_cpu {
  86. /* slave CPU ready flag */
  87. u32 ready_flag;
  88. /* address of the area, which can be used for stack by slave CPU */
  89. u32 stack_ptr;
  90. /* slave CPU status - bootstage number */
  91. s32 status[NR_CPUS];
  92. /*
  93. * Slave CPU data - it is copy of corresponding fields in
  94. * hsdk_env_core_ctl and hsdk_env_common_ctl structures which are
  95. * required for slave CPUs initialization.
  96. * This fields can be populated by copying from hsdk_env_core_ctl
  97. * and hsdk_env_common_ctl structures with sync_cross_cpu_data()
  98. * function.
  99. */
  100. u32 entry[NR_CPUS];
  101. u32 iccm[NR_CPUS];
  102. u32 dccm[NR_CPUS];
  103. u32 core_mask;
  104. u32 icache;
  105. u32 dcache;
  106. u8 cache_padding[ARCH_DMA_MINALIGN];
  107. } __aligned(ARCH_DMA_MINALIGN);
  108. /* Place for slave CPUs temporary stack */
  109. static u32 slave_stack[256 * NR_CPUS] __aligned(ARCH_DMA_MINALIGN);
  110. static struct hsdk_env_common_ctl env_common = {};
  111. static struct hsdk_env_core_ctl env_core = {};
  112. static struct hsdk_cross_cpu cross_cpu_data;
  113. static const struct env_map_common env_map_common[] = {
  114. { "core_mask", ENV_HEX, true, 0x1, 0xF, &env_common.core_mask },
  115. { "non_volatile_limit", ENV_HEX, true, 0, 0xF, &env_common.nvlim },
  116. { "icache_ena", ENV_HEX, true, 0, 1, &env_common.icache },
  117. { "dcache_ena", ENV_HEX, true, 0, 1, &env_common.dcache },
  118. #if defined(CONFIG_BOARD_HSDK_4XD)
  119. { "l2_cache_ena", ENV_HEX, true, 0, 1, &env_common.l2_cache },
  120. { "csm_location", ENV_HEX, true, 0, NO_CCM, &env_common.csm_location },
  121. { "haps_apb_location", ENV_HEX, true, 0, 1, &env_common.haps_apb },
  122. #endif /* CONFIG_BOARD_HSDK_4XD */
  123. {}
  124. };
  125. static const struct env_map_common env_map_clock[] = {
  126. { "cpu_freq", ENV_DEC, false, 100, 1000, &env_common.cpu_freq },
  127. { "axi_freq", ENV_DEC, false, 200, 800, &env_common.axi_freq },
  128. { "tun_freq", ENV_DEC, false, 0, 150, &env_common.tun_freq },
  129. {}
  130. };
  131. static const struct env_map_percpu env_map_core[] = {
  132. { "core_iccm", ENV_HEX, true, {NO_CCM, 0, NO_CCM, 0}, {NO_CCM, 0xF, NO_CCM, 0xF}, &env_core.iccm },
  133. { "core_dccm", ENV_HEX, true, {NO_CCM, 0, NO_CCM, 0}, {NO_CCM, 0xF, NO_CCM, 0xF}, &env_core.dccm },
  134. {}
  135. };
  136. static const struct env_map_common env_map_mask[] = {
  137. { "core_mask", ENV_HEX, false, 0x1, 0xF, &env_common.core_mask },
  138. {}
  139. };
  140. static const struct env_map_percpu env_map_go[] = {
  141. { "core_entry", ENV_HEX, true, {0, 0, 0, 0}, {U32_MAX, U32_MAX, U32_MAX, U32_MAX}, &env_core.entry },
  142. {}
  143. };
  144. enum board_type {
  145. T_BOARD_NONE,
  146. T_BOARD_HSDK,
  147. T_BOARD_HSDK_4XD
  148. };
  149. static inline enum board_type get_board_type_runtime(void)
  150. {
  151. u32 arc_id = read_aux_reg(ARC_AUX_IDENTITY) & 0xFF;
  152. if (arc_id == 0x52)
  153. return T_BOARD_HSDK;
  154. else if (arc_id == 0x54)
  155. return T_BOARD_HSDK_4XD;
  156. else
  157. return T_BOARD_NONE;
  158. }
  159. static inline enum board_type get_board_type_config(void)
  160. {
  161. if (IS_ENABLED(CONFIG_BOARD_HSDK))
  162. return T_BOARD_HSDK;
  163. else if (IS_ENABLED(CONFIG_BOARD_HSDK_4XD))
  164. return T_BOARD_HSDK_4XD;
  165. else
  166. return T_BOARD_NONE;
  167. }
  168. static bool is_board_match_runtime(enum board_type type_req)
  169. {
  170. return get_board_type_runtime() == type_req;
  171. }
  172. static bool is_board_match_config(enum board_type type_req)
  173. {
  174. return get_board_type_config() == type_req;
  175. }
  176. static const char * board_name(enum board_type type)
  177. {
  178. switch (type) {
  179. case T_BOARD_HSDK:
  180. return "ARC HS Development Kit";
  181. case T_BOARD_HSDK_4XD:
  182. return "ARC HS4x/HS4xD Development Kit";
  183. default:
  184. return "?";
  185. }
  186. }
  187. static bool board_mismatch(void)
  188. {
  189. return get_board_type_config() != get_board_type_runtime();
  190. }
  191. static void sync_cross_cpu_data(void)
  192. {
  193. u32 value;
  194. for (u32 i = 0; i < NR_CPUS; i++) {
  195. value = env_core.entry[i].val;
  196. arc_write_uncached_32(&cross_cpu_data.entry[i], value);
  197. }
  198. for (u32 i = 0; i < NR_CPUS; i++) {
  199. value = env_core.iccm[i].val;
  200. arc_write_uncached_32(&cross_cpu_data.iccm[i], value);
  201. }
  202. for (u32 i = 0; i < NR_CPUS; i++) {
  203. value = env_core.dccm[i].val;
  204. arc_write_uncached_32(&cross_cpu_data.dccm[i], value);
  205. }
  206. value = env_common.core_mask.val;
  207. arc_write_uncached_32(&cross_cpu_data.core_mask, value);
  208. value = env_common.icache.val;
  209. arc_write_uncached_32(&cross_cpu_data.icache, value);
  210. value = env_common.dcache.val;
  211. arc_write_uncached_32(&cross_cpu_data.dcache, value);
  212. }
  213. /* Can be used only on master CPU */
  214. static bool is_cpu_used(u32 cpu_id)
  215. {
  216. return !!(env_common.core_mask.val & BIT(cpu_id));
  217. }
  218. /* TODO: add ICCM BCR and DCCM BCR runtime check */
  219. static void init_slave_cpu_func(u32 core)
  220. {
  221. u32 val;
  222. /* Remap ICCM to another memory region if it exists */
  223. val = arc_read_uncached_32(&cross_cpu_data.iccm[core]);
  224. if (val != NO_CCM)
  225. write_aux_reg(ARC_AUX_ICCM_BASE, val << APERTURE_SHIFT);
  226. /* Remap DCCM to another memory region if it exists */
  227. val = arc_read_uncached_32(&cross_cpu_data.dccm[core]);
  228. if (val != NO_CCM)
  229. write_aux_reg(ARC_AUX_DCCM_BASE, val << APERTURE_SHIFT);
  230. if (arc_read_uncached_32(&cross_cpu_data.icache))
  231. icache_enable();
  232. else
  233. icache_disable();
  234. if (arc_read_uncached_32(&cross_cpu_data.dcache))
  235. dcache_enable();
  236. else
  237. dcache_disable();
  238. }
  239. static void init_cluster_nvlim(void)
  240. {
  241. u32 val = env_common.nvlim.val << APERTURE_SHIFT;
  242. flush_dcache_all();
  243. write_aux_reg(ARC_AUX_NON_VOLATILE_LIMIT, val);
  244. /* AUX_AUX_CACHE_LIMIT reg is missing starting from HS48 */
  245. if (is_board_match_runtime(T_BOARD_HSDK))
  246. write_aux_reg(AUX_AUX_CACHE_LIMIT, val);
  247. flush_n_invalidate_dcache_all();
  248. }
  249. static void init_cluster_slc(void)
  250. {
  251. /* ARC HS38 doesn't support SLC disabling */
  252. if (!is_board_match_config(T_BOARD_HSDK_4XD))
  253. return;
  254. if (env_common.l2_cache.val)
  255. slc_enable();
  256. else
  257. slc_disable();
  258. }
  259. #define CREG_CSM_BASE (CREG_BASE + 0x210)
  260. static void init_cluster_csm(void)
  261. {
  262. /* ARC HS38 in HSDK SoC doesn't include CSM */
  263. if (!is_board_match_config(T_BOARD_HSDK_4XD))
  264. return;
  265. if (env_common.csm_location.val == NO_CCM) {
  266. write_aux_reg(ARC_AUX_CSM_ENABLE, 0);
  267. } else {
  268. /*
  269. * CSM base address is 256kByte aligned but we allow to map
  270. * CSM only to aperture start (256MByte aligned)
  271. * The field in CREG_CSM_BASE is in 17:2 bits itself so we need
  272. * to shift it.
  273. */
  274. u32 csm_base = (env_common.csm_location.val * SZ_1K) << 2;
  275. write_aux_reg(ARC_AUX_CSM_ENABLE, 1);
  276. writel(csm_base, (void __iomem *)CREG_CSM_BASE);
  277. }
  278. }
  279. static void init_master_icache(void)
  280. {
  281. if (icache_status()) {
  282. /* I$ is enabled - we need to disable it */
  283. if (!env_common.icache.val)
  284. icache_disable();
  285. } else {
  286. /* I$ is disabled - we need to enable it */
  287. if (env_common.icache.val) {
  288. icache_enable();
  289. /* invalidate I$ right after enable */
  290. invalidate_icache_all();
  291. }
  292. }
  293. }
  294. static void init_master_dcache(void)
  295. {
  296. if (dcache_status()) {
  297. /* D$ is enabled - we need to disable it */
  298. if (!env_common.dcache.val)
  299. dcache_disable();
  300. } else {
  301. /* D$ is disabled - we need to enable it */
  302. if (env_common.dcache.val)
  303. dcache_enable();
  304. /* TODO: probably we need ti invalidate D$ right after enable */
  305. }
  306. }
  307. static int cleanup_before_go(void)
  308. {
  309. disable_interrupts();
  310. sync_n_cleanup_cache_all();
  311. return 0;
  312. }
  313. void slave_cpu_set_boot_addr(u32 addr)
  314. {
  315. /* All cores have reset vector pointing to 0 */
  316. writel(addr, (void __iomem *)RESET_VECTOR_ADDR);
  317. /* Make sure other cores see written value in memory */
  318. sync_n_cleanup_cache_all();
  319. }
  320. static inline void halt_this_cpu(void)
  321. {
  322. __builtin_arc_flag(1);
  323. }
  324. static u32 get_masked_cpu_ctart_reg(void)
  325. {
  326. int cmd = readl((void __iomem *)CREG_CPU_START);
  327. /*
  328. * Quirk for HSDK-4xD - due to HW issues HSDK can use any pulse polarity
  329. * and HSDK-4xD require active low polarity of cpu_start pulse.
  330. */
  331. cmd &= ~CREG_CPU_START_POL;
  332. cmd &= ~CREG_CPU_START_MASK;
  333. return cmd;
  334. }
  335. static void smp_kick_cpu_x(u32 cpu_id)
  336. {
  337. int cmd;
  338. if (cpu_id > NR_CPUS)
  339. return;
  340. cmd = get_masked_cpu_ctart_reg();
  341. cmd |= (1 << cpu_id);
  342. writel(cmd, (void __iomem *)CREG_CPU_START);
  343. }
  344. static u32 prepare_cpu_ctart_reg(void)
  345. {
  346. return get_masked_cpu_ctart_reg() | env_common.core_mask.val;
  347. }
  348. /* slave CPU entry for configuration */
  349. __attribute__((naked, noreturn, flatten)) noinline void hsdk_core_init_f(void)
  350. {
  351. __asm__ __volatile__(
  352. "ld.di r8, [%0]\n"
  353. "mov %%sp, r8\n"
  354. "mov %%fp, %%sp\n"
  355. : /* no output */
  356. : "r" (&cross_cpu_data.stack_ptr));
  357. invalidate_icache_all();
  358. arc_write_uncached_32(&cross_cpu_data.status[CPU_ID_GET()], BOOTSTAGE_1);
  359. init_slave_cpu_func(CPU_ID_GET());
  360. arc_write_uncached_32(&cross_cpu_data.ready_flag, SLAVE_CPU_READY);
  361. arc_write_uncached_32(&cross_cpu_data.status[CPU_ID_GET()], BOOTSTAGE_2);
  362. /* Halt the processor until the master kick us again */
  363. halt_this_cpu();
  364. /*
  365. * 3 NOPs after FLAG 1 instruction are no longer required for ARCv2
  366. * cores but we leave them for gebug purposes.
  367. */
  368. __builtin_arc_nop();
  369. __builtin_arc_nop();
  370. __builtin_arc_nop();
  371. arc_write_uncached_32(&cross_cpu_data.status[CPU_ID_GET()], BOOTSTAGE_3);
  372. /* get the updated entry - invalidate i$ */
  373. invalidate_icache_all();
  374. arc_write_uncached_32(&cross_cpu_data.status[CPU_ID_GET()], BOOTSTAGE_4);
  375. /* Run our program */
  376. ((void (*)(void))(arc_read_uncached_32(&cross_cpu_data.entry[CPU_ID_GET()])))();
  377. /* This bootstage is unreachable as we don't return from app we launch */
  378. arc_write_uncached_32(&cross_cpu_data.status[CPU_ID_GET()], BOOTSTAGE_5);
  379. /* Something went terribly wrong */
  380. while (true)
  381. halt_this_cpu();
  382. }
  383. static void clear_cross_cpu_data(void)
  384. {
  385. arc_write_uncached_32(&cross_cpu_data.ready_flag, 0);
  386. arc_write_uncached_32(&cross_cpu_data.stack_ptr, 0);
  387. for (u32 i = 0; i < NR_CPUS; i++)
  388. arc_write_uncached_32(&cross_cpu_data.status[i], 0);
  389. }
  390. static noinline void do_init_slave_cpu(u32 cpu_id)
  391. {
  392. /* attempts number for check clave CPU ready_flag */
  393. u32 attempts = 100;
  394. u32 stack_ptr = (u32)(slave_stack + (64 * cpu_id));
  395. if (cpu_id >= NR_CPUS)
  396. return;
  397. arc_write_uncached_32(&cross_cpu_data.ready_flag, 0);
  398. /* Use global unique place for each slave cpu stack */
  399. arc_write_uncached_32(&cross_cpu_data.stack_ptr, stack_ptr);
  400. debug("CPU %u: stack pool base: %p\n", cpu_id, slave_stack);
  401. debug("CPU %u: current slave stack base: %x\n", cpu_id, stack_ptr);
  402. slave_cpu_set_boot_addr((u32)hsdk_core_init_f);
  403. smp_kick_cpu_x(cpu_id);
  404. debug("CPU %u: cross-cpu flag: %x [before timeout]\n", cpu_id,
  405. arc_read_uncached_32(&cross_cpu_data.ready_flag));
  406. while (!arc_read_uncached_32(&cross_cpu_data.ready_flag) && attempts--)
  407. mdelay(10);
  408. /* Just to be sure that slave cpu is halted after it set ready_flag */
  409. mdelay(20);
  410. /*
  411. * Only print error here if we reach timeout as there is no option to
  412. * halt slave cpu (or check that slave cpu is halted)
  413. */
  414. if (!attempts)
  415. pr_err("CPU %u is not responding after init!\n", cpu_id);
  416. /* Check current stage of slave cpu */
  417. if (arc_read_uncached_32(&cross_cpu_data.status[cpu_id]) != BOOTSTAGE_2)
  418. pr_err("CPU %u status is unexpected: %d\n", cpu_id,
  419. arc_read_uncached_32(&cross_cpu_data.status[cpu_id]));
  420. debug("CPU %u: cross-cpu flag: %x [after timeout]\n", cpu_id,
  421. arc_read_uncached_32(&cross_cpu_data.ready_flag));
  422. debug("CPU %u: status: %d [after timeout]\n", cpu_id,
  423. arc_read_uncached_32(&cross_cpu_data.status[cpu_id]));
  424. }
  425. static void do_init_slave_cpus(void)
  426. {
  427. clear_cross_cpu_data();
  428. sync_cross_cpu_data();
  429. debug("cross_cpu_data location: %#x\n", (u32)&cross_cpu_data);
  430. for (u32 i = MASTER_CPU_ID + 1; i < NR_CPUS; i++)
  431. if (is_cpu_used(i))
  432. do_init_slave_cpu(i);
  433. }
  434. static void do_init_master_cpu(void)
  435. {
  436. /*
  437. * Setup master caches even if master isn't used as we want to use
  438. * same cache configuration on all running CPUs
  439. */
  440. init_master_icache();
  441. init_master_dcache();
  442. }
  443. enum hsdk_axi_masters {
  444. M_HS_CORE = 0,
  445. M_HS_RTT,
  446. M_AXI_TUN,
  447. M_HDMI_VIDEO,
  448. M_HDMI_AUDIO,
  449. M_USB_HOST,
  450. M_ETHERNET,
  451. M_SDIO,
  452. M_GPU,
  453. M_DMAC_0,
  454. M_DMAC_1,
  455. M_DVFS
  456. };
  457. #define UPDATE_VAL 1
  458. /*
  459. * m master AXI_M_m_SLV0 AXI_M_m_SLV1 AXI_M_m_OFFSET0 AXI_M_m_OFFSET1
  460. * 0 HS (CBU) 0x11111111 0x63111111 0xFEDCBA98 0x0E543210
  461. * 1 HS (RTT) 0x77777777 0x77777777 0xFEDCBA98 0x76543210
  462. * 2 AXI Tunnel 0x88888888 0x88888888 0xFEDCBA98 0x76543210
  463. * 3 HDMI-VIDEO 0x77777777 0x77777777 0xFEDCBA98 0x76543210
  464. * 4 HDMI-ADUIO 0x77777777 0x77777777 0xFEDCBA98 0x76543210
  465. * 5 USB-HOST 0x77777777 0x77999999 0xFEDCBA98 0x76DCBA98
  466. * 6 ETHERNET 0x77777777 0x77999999 0xFEDCBA98 0x76DCBA98
  467. * 7 SDIO 0x77777777 0x77999999 0xFEDCBA98 0x76DCBA98
  468. * 8 GPU 0x77777777 0x77777777 0xFEDCBA98 0x76543210
  469. * 9 DMAC (port #1) 0x77777777 0x77777777 0xFEDCBA98 0x76543210
  470. * 10 DMAC (port #2) 0x77777777 0x77777777 0xFEDCBA98 0x76543210
  471. * 11 DVFS 0x00000000 0x60000000 0x00000000 0x00000000
  472. *
  473. * Please read ARC HS Development IC Specification, section 17.2 for more
  474. * information about apertures configuration.
  475. * NOTE: we intentionally modify default settings in U-boot. Default settings
  476. * are specified in "Table 111 CREG Address Decoder register reset values".
  477. */
  478. #define CREG_AXI_M_SLV0(m) ((void __iomem *)(CREG_BASE + 0x020 * (m)))
  479. #define CREG_AXI_M_SLV1(m) ((void __iomem *)(CREG_BASE + 0x020 * (m) + 0x004))
  480. #define CREG_AXI_M_OFT0(m) ((void __iomem *)(CREG_BASE + 0x020 * (m) + 0x008))
  481. #define CREG_AXI_M_OFT1(m) ((void __iomem *)(CREG_BASE + 0x020 * (m) + 0x00C))
  482. #define CREG_AXI_M_UPDT(m) ((void __iomem *)(CREG_BASE + 0x020 * (m) + 0x014))
  483. #define CREG_AXI_M_HS_CORE_BOOT ((void __iomem *)(CREG_BASE + 0x010))
  484. #define CREG_PAE ((void __iomem *)(CREG_BASE + 0x180))
  485. #define CREG_PAE_UPDT ((void __iomem *)(CREG_BASE + 0x194))
  486. void init_memory_bridge(void)
  487. {
  488. u32 reg;
  489. /*
  490. * M_HS_CORE has one unic register - BOOT.
  491. * We need to clean boot mirror (BOOT[1:0]) bits in them.
  492. */
  493. reg = readl(CREG_AXI_M_HS_CORE_BOOT) & (~0x3);
  494. writel(reg, CREG_AXI_M_HS_CORE_BOOT);
  495. writel(0x11111111, CREG_AXI_M_SLV0(M_HS_CORE));
  496. writel(0x63111111, CREG_AXI_M_SLV1(M_HS_CORE));
  497. writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HS_CORE));
  498. writel(0x0E543210, CREG_AXI_M_OFT1(M_HS_CORE));
  499. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HS_CORE));
  500. writel(0x77777777, CREG_AXI_M_SLV0(M_HS_RTT));
  501. writel(0x77777777, CREG_AXI_M_SLV1(M_HS_RTT));
  502. writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HS_RTT));
  503. writel(0x76543210, CREG_AXI_M_OFT1(M_HS_RTT));
  504. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HS_RTT));
  505. writel(0x88888888, CREG_AXI_M_SLV0(M_AXI_TUN));
  506. writel(0x88888888, CREG_AXI_M_SLV1(M_AXI_TUN));
  507. writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_AXI_TUN));
  508. writel(0x76543210, CREG_AXI_M_OFT1(M_AXI_TUN));
  509. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_AXI_TUN));
  510. writel(0x77777777, CREG_AXI_M_SLV0(M_HDMI_VIDEO));
  511. writel(0x77777777, CREG_AXI_M_SLV1(M_HDMI_VIDEO));
  512. writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HDMI_VIDEO));
  513. writel(0x76543210, CREG_AXI_M_OFT1(M_HDMI_VIDEO));
  514. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HDMI_VIDEO));
  515. writel(0x77777777, CREG_AXI_M_SLV0(M_HDMI_AUDIO));
  516. writel(0x77777777, CREG_AXI_M_SLV1(M_HDMI_AUDIO));
  517. writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HDMI_AUDIO));
  518. writel(0x76543210, CREG_AXI_M_OFT1(M_HDMI_AUDIO));
  519. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HDMI_AUDIO));
  520. writel(0x77777777, CREG_AXI_M_SLV0(M_USB_HOST));
  521. writel(0x77999999, CREG_AXI_M_SLV1(M_USB_HOST));
  522. writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_USB_HOST));
  523. writel(0x76DCBA98, CREG_AXI_M_OFT1(M_USB_HOST));
  524. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_USB_HOST));
  525. writel(0x77777777, CREG_AXI_M_SLV0(M_ETHERNET));
  526. writel(0x77999999, CREG_AXI_M_SLV1(M_ETHERNET));
  527. writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_ETHERNET));
  528. writel(0x76DCBA98, CREG_AXI_M_OFT1(M_ETHERNET));
  529. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_ETHERNET));
  530. writel(0x77777777, CREG_AXI_M_SLV0(M_SDIO));
  531. writel(0x77999999, CREG_AXI_M_SLV1(M_SDIO));
  532. writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_SDIO));
  533. writel(0x76DCBA98, CREG_AXI_M_OFT1(M_SDIO));
  534. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_SDIO));
  535. writel(0x77777777, CREG_AXI_M_SLV0(M_GPU));
  536. writel(0x77777777, CREG_AXI_M_SLV1(M_GPU));
  537. writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_GPU));
  538. writel(0x76543210, CREG_AXI_M_OFT1(M_GPU));
  539. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_GPU));
  540. writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_0));
  541. writel(0x77777777, CREG_AXI_M_SLV1(M_DMAC_0));
  542. writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_0));
  543. writel(0x76543210, CREG_AXI_M_OFT1(M_DMAC_0));
  544. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_0));
  545. writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_1));
  546. writel(0x77777777, CREG_AXI_M_SLV1(M_DMAC_1));
  547. writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_1));
  548. writel(0x76543210, CREG_AXI_M_OFT1(M_DMAC_1));
  549. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_1));
  550. writel(0x00000000, CREG_AXI_M_SLV0(M_DVFS));
  551. writel(0x60000000, CREG_AXI_M_SLV1(M_DVFS));
  552. writel(0x00000000, CREG_AXI_M_OFT0(M_DVFS));
  553. writel(0x00000000, CREG_AXI_M_OFT1(M_DVFS));
  554. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DVFS));
  555. writel(0x00000000, CREG_PAE);
  556. writel(UPDATE_VAL, CREG_PAE_UPDT);
  557. }
  558. /*
  559. * For HSDK-4xD we do additional AXI bridge tweaking in hsdk_init command:
  560. * - we shrink IOC region.
  561. * - we configure HS CORE SLV1 aperture depending on haps_apb_location
  562. * environment variable.
  563. *
  564. * As we've already configured AXI bridge in init_memory_bridge we don't
  565. * do full configuration here but reconfigure changed part.
  566. *
  567. * m master AXI_M_m_SLV0 AXI_M_m_SLV1 AXI_M_m_OFFSET0 AXI_M_m_OFFSET1
  568. * 0 HS (CBU) 0x11111111 0x63111111 0xFEDCBA98 0x0E543210 [haps_apb_location = 0]
  569. * 0 HS (CBU) 0x11111111 0x61111111 0xFEDCBA98 0x06543210 [haps_apb_location = 1]
  570. * 1 HS (RTT) 0x77777777 0x77777777 0xFEDCBA98 0x76543210
  571. * 2 AXI Tunnel 0x88888888 0x88888888 0xFEDCBA98 0x76543210
  572. * 3 HDMI-VIDEO 0x77777777 0x77777777 0xFEDCBA98 0x76543210
  573. * 4 HDMI-ADUIO 0x77777777 0x77777777 0xFEDCBA98 0x76543210
  574. * 5 USB-HOST 0x77777777 0x77779999 0xFEDCBA98 0x7654BA98
  575. * 6 ETHERNET 0x77777777 0x77779999 0xFEDCBA98 0x7654BA98
  576. * 7 SDIO 0x77777777 0x77779999 0xFEDCBA98 0x7654BA98
  577. * 8 GPU 0x77777777 0x77777777 0xFEDCBA98 0x76543210
  578. * 9 DMAC (port #1) 0x77777777 0x77777777 0xFEDCBA98 0x76543210
  579. * 10 DMAC (port #2) 0x77777777 0x77777777 0xFEDCBA98 0x76543210
  580. * 11 DVFS 0x00000000 0x60000000 0x00000000 0x00000000
  581. */
  582. void tweak_memory_bridge_cfg(void)
  583. {
  584. /*
  585. * Only HSDK-4xD requre additional AXI bridge tweaking depending on
  586. * haps_apb_location environment variable
  587. */
  588. if (!is_board_match_config(T_BOARD_HSDK_4XD))
  589. return;
  590. if (env_common.haps_apb.val) {
  591. writel(0x61111111, CREG_AXI_M_SLV1(M_HS_CORE));
  592. writel(0x06543210, CREG_AXI_M_OFT1(M_HS_CORE));
  593. } else {
  594. writel(0x63111111, CREG_AXI_M_SLV1(M_HS_CORE));
  595. writel(0x0E543210, CREG_AXI_M_OFT1(M_HS_CORE));
  596. }
  597. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HS_CORE));
  598. writel(0x77779999, CREG_AXI_M_SLV1(M_USB_HOST));
  599. writel(0x7654BA98, CREG_AXI_M_OFT1(M_USB_HOST));
  600. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_USB_HOST));
  601. writel(0x77779999, CREG_AXI_M_SLV1(M_ETHERNET));;
  602. writel(0x7654BA98, CREG_AXI_M_OFT1(M_ETHERNET));
  603. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_ETHERNET));
  604. writel(0x77779999, CREG_AXI_M_SLV1(M_SDIO));
  605. writel(0x7654BA98, CREG_AXI_M_OFT1(M_SDIO));
  606. writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_SDIO));
  607. }
  608. static void setup_clocks(void)
  609. {
  610. ulong rate;
  611. /* Setup CPU clock */
  612. if (env_common.cpu_freq.set) {
  613. rate = env_common.cpu_freq.val;
  614. soc_clk_ctl("cpu-clk", &rate, CLK_ON | CLK_SET | CLK_MHZ);
  615. }
  616. /* Setup TUN clock */
  617. if (env_common.tun_freq.set) {
  618. rate = env_common.tun_freq.val;
  619. if (rate)
  620. soc_clk_ctl("tun-clk", &rate, CLK_ON | CLK_SET | CLK_MHZ);
  621. else
  622. soc_clk_ctl("tun-clk", NULL, CLK_OFF);
  623. }
  624. if (env_common.axi_freq.set) {
  625. rate = env_common.axi_freq.val;
  626. soc_clk_ctl("axi-clk", &rate, CLK_SET | CLK_ON | CLK_MHZ);
  627. }
  628. }
  629. static void do_init_cluster(void)
  630. {
  631. /*
  632. * A multi-core ARC HS configuration always includes only one
  633. * ARC_AUX_NON_VOLATILE_LIMIT register, which is shared by all the
  634. * cores.
  635. */
  636. init_cluster_nvlim();
  637. init_cluster_csm();
  638. init_cluster_slc();
  639. tweak_memory_bridge_cfg();
  640. }
  641. static int check_master_cpu_id(void)
  642. {
  643. if (CPU_ID_GET() == MASTER_CPU_ID)
  644. return 0;
  645. pr_err("u-boot runs on non-master cpu with id: %lu\n", CPU_ID_GET());
  646. return -ENOENT;
  647. }
  648. static noinline int prepare_cpus(void)
  649. {
  650. int ret;
  651. ret = check_master_cpu_id();
  652. if (ret)
  653. return ret;
  654. ret = envs_process_and_validate(env_map_common, env_map_core, is_cpu_used);
  655. if (ret)
  656. return ret;
  657. printf("CPU start mask is %#x\n", env_common.core_mask.val);
  658. do_init_slave_cpus();
  659. do_init_master_cpu();
  660. do_init_cluster();
  661. return 0;
  662. }
  663. static int hsdk_go_run(u32 cpu_start_reg)
  664. {
  665. /* Cleanup caches, disable interrupts */
  666. cleanup_before_go();
  667. if (env_common.halt_on_boot)
  668. halt_this_cpu();
  669. /*
  670. * 3 NOPs after FLAG 1 instruction are no longer required for ARCv2
  671. * cores but we leave them for gebug purposes.
  672. */
  673. __builtin_arc_nop();
  674. __builtin_arc_nop();
  675. __builtin_arc_nop();
  676. /* Kick chosen slave CPUs */
  677. writel(cpu_start_reg, (void __iomem *)CREG_CPU_START);
  678. if (is_cpu_used(MASTER_CPU_ID))
  679. ((void (*)(void))(env_core.entry[MASTER_CPU_ID].val))();
  680. else
  681. halt_this_cpu();
  682. pr_err("u-boot still runs on cpu [%ld]\n", CPU_ID_GET());
  683. /*
  684. * We will never return after executing our program if master cpu used
  685. * otherwise halt master cpu manually.
  686. */
  687. while (true)
  688. halt_this_cpu();
  689. return 0;
  690. }
  691. int board_prep_linux(bootm_headers_t *images)
  692. {
  693. int ret, ofst;
  694. char mask[15];
  695. ret = envs_read_validate_common(env_map_mask);
  696. if (ret)
  697. return ret;
  698. /* Rollback to default values */
  699. if (!env_common.core_mask.set) {
  700. env_common.core_mask.val = ALL_CPU_MASK;
  701. env_common.core_mask.set = true;
  702. }
  703. printf("CPU start mask is %#x\n", env_common.core_mask.val);
  704. if (!is_cpu_used(MASTER_CPU_ID))
  705. pr_err("ERR: try to launch linux with CPU[0] disabled! It doesn't work for ARC.\n");
  706. /*
  707. * If we want to launch linux on all CPUs we don't need to patch
  708. * linux DTB as it is default configuration
  709. */
  710. if (env_common.core_mask.val == ALL_CPU_MASK)
  711. return 0;
  712. if (!IMAGE_ENABLE_OF_LIBFDT || !images->ft_len) {
  713. pr_err("WARN: core_mask setup will work properly only with external DTB!\n");
  714. return 0;
  715. }
  716. /* patch '/possible-cpus' property according to cpu mask */
  717. ofst = fdt_path_offset(images->ft_addr, "/");
  718. sprintf(mask, "%s%s%s%s",
  719. is_cpu_used(0) ? "0," : "",
  720. is_cpu_used(1) ? "1," : "",
  721. is_cpu_used(2) ? "2," : "",
  722. is_cpu_used(3) ? "3," : "");
  723. ret = fdt_setprop_string(images->ft_addr, ofst, "possible-cpus", mask);
  724. /*
  725. * If we failed to patch '/possible-cpus' property we don't need break
  726. * linux loading process: kernel will handle it but linux will print
  727. * warning like "Timeout: CPU1 FAILED to comeup !!!".
  728. * So warn here about error, but return 0 like no error had occurred.
  729. */
  730. if (ret)
  731. pr_err("WARN: failed to patch '/possible-cpus' property, ret=%d\n",
  732. ret);
  733. return 0;
  734. }
  735. void board_jump_and_run(ulong entry, int zero, int arch, uint params)
  736. {
  737. void (*kernel_entry)(int zero, int arch, uint params);
  738. u32 cpu_start_reg;
  739. kernel_entry = (void (*)(int, int, uint))entry;
  740. /* Prepare CREG_CPU_START for kicking chosen CPUs */
  741. cpu_start_reg = prepare_cpu_ctart_reg();
  742. /* In case of run without hsdk_init */
  743. slave_cpu_set_boot_addr(entry);
  744. /* In case of run with hsdk_init */
  745. for (u32 i = 0; i < NR_CPUS; i++) {
  746. env_core.entry[i].val = entry;
  747. env_core.entry[i].set = true;
  748. }
  749. /* sync cross_cpu struct as we updated core-entry variables */
  750. sync_cross_cpu_data();
  751. /* Kick chosen slave CPUs */
  752. writel(cpu_start_reg, (void __iomem *)CREG_CPU_START);
  753. if (is_cpu_used(0))
  754. kernel_entry(zero, arch, params);
  755. }
  756. static int hsdk_go_prepare_and_run(void)
  757. {
  758. /* Prepare CREG_CPU_START for kicking chosen CPUs */
  759. u32 reg = prepare_cpu_ctart_reg();
  760. if (env_common.halt_on_boot)
  761. printf("CPU will halt before application start, start application with debugger.\n");
  762. return hsdk_go_run(reg);
  763. }
  764. static int do_hsdk_go(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
  765. {
  766. int ret;
  767. if (board_mismatch()) {
  768. printf("ERR: U-boot is not configured for this board!\n");
  769. return CMD_RET_FAILURE;
  770. }
  771. /*
  772. * Check for 'halt' parameter. 'halt' = enter halt-mode just before
  773. * starting the application; can be used for debug.
  774. */
  775. if (argc > 1) {
  776. env_common.halt_on_boot = !strcmp(argv[1], "halt");
  777. if (!env_common.halt_on_boot) {
  778. pr_err("Unrecognised parameter: \'%s\'\n", argv[1]);
  779. return CMD_RET_FAILURE;
  780. }
  781. }
  782. ret = check_master_cpu_id();
  783. if (ret)
  784. return ret;
  785. ret = envs_process_and_validate(env_map_mask, env_map_go, is_cpu_used);
  786. if (ret)
  787. return ret;
  788. /* sync cross_cpu struct as we updated core-entry variables */
  789. sync_cross_cpu_data();
  790. ret = hsdk_go_prepare_and_run();
  791. return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
  792. }
  793. U_BOOT_CMD(
  794. hsdk_go, 3, 0, do_hsdk_go,
  795. "Synopsys HSDK specific command",
  796. " - Boot stand-alone application on HSDK\n"
  797. "hsdk_go halt - Boot stand-alone application on HSDK, halt CPU just before application run\n"
  798. );
  799. /*
  800. * We may simply use static variable here to store init status, but we also want
  801. * to avoid the situation when we reload U-boot via MDB after previous
  802. * init is done but HW reset (board reset) isn't done. So let's store the
  803. * init status in any unused register (i.e CREG_CPU_0_ENTRY) so status will
  804. * survive after U-boot is reloaded via MDB.
  805. */
  806. #define INIT_MARKER_REGISTER ((void __iomem *)CREG_CPU_0_ENTRY)
  807. /* must be equal to INIT_MARKER_REGISTER reset value */
  808. #define INIT_MARKER_PENDING 0
  809. static bool init_marker_get(void)
  810. {
  811. return readl(INIT_MARKER_REGISTER) != INIT_MARKER_PENDING;
  812. }
  813. static void init_mark_done(void)
  814. {
  815. writel(~INIT_MARKER_PENDING, INIT_MARKER_REGISTER);
  816. }
  817. static int do_hsdk_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
  818. {
  819. int ret;
  820. if (board_mismatch()) {
  821. printf("ERR: U-boot is not configured for this board!\n");
  822. return CMD_RET_FAILURE;
  823. }
  824. /* hsdk_init can be run only once */
  825. if (init_marker_get()) {
  826. printf("HSDK HW is already initialized! Please reset the board if you want to change the configuration.\n");
  827. return CMD_RET_FAILURE;
  828. }
  829. ret = prepare_cpus();
  830. if (!ret)
  831. init_mark_done();
  832. return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
  833. }
  834. U_BOOT_CMD(
  835. hsdk_init, 1, 0, do_hsdk_init,
  836. "Synopsys HSDK specific command",
  837. "- Init HSDK HW\n"
  838. );
  839. static int do_hsdk_clock_set(cmd_tbl_t *cmdtp, int flag, int argc,
  840. char *const argv[])
  841. {
  842. int ret = 0;
  843. /* Strip off leading subcommand argument */
  844. argc--;
  845. argv++;
  846. envs_cleanup_common(env_map_clock);
  847. if (!argc) {
  848. printf("Set clocks to values specified in environment\n");
  849. ret = envs_read_common(env_map_clock);
  850. } else {
  851. printf("Set clocks to values specified in args\n");
  852. ret = args_envs_enumerate(env_map_clock, 2, argc, argv);
  853. }
  854. if (ret)
  855. return CMD_RET_FAILURE;
  856. ret = envs_validate_common(env_map_clock);
  857. if (ret)
  858. return CMD_RET_FAILURE;
  859. /* Setup clock tree HW */
  860. setup_clocks();
  861. return CMD_RET_SUCCESS;
  862. }
  863. static int do_hsdk_clock_get(cmd_tbl_t *cmdtp, int flag, int argc,
  864. char *const argv[])
  865. {
  866. ulong rate;
  867. if (soc_clk_ctl("cpu-clk", &rate, CLK_GET | CLK_MHZ))
  868. return CMD_RET_FAILURE;
  869. if (env_set_ulong("cpu_freq", rate))
  870. return CMD_RET_FAILURE;
  871. if (soc_clk_ctl("tun-clk", &rate, CLK_GET | CLK_MHZ))
  872. return CMD_RET_FAILURE;
  873. if (env_set_ulong("tun_freq", rate))
  874. return CMD_RET_FAILURE;
  875. if (soc_clk_ctl("axi-clk", &rate, CLK_GET | CLK_MHZ))
  876. return CMD_RET_FAILURE;
  877. if (env_set_ulong("axi_freq", rate))
  878. return CMD_RET_FAILURE;
  879. printf("Clock values are saved to environment\n");
  880. return CMD_RET_SUCCESS;
  881. }
  882. static int do_hsdk_clock_print(cmd_tbl_t *cmdtp, int flag, int argc,
  883. char *const argv[])
  884. {
  885. /* Main clocks */
  886. soc_clk_ctl("cpu-clk", NULL, CLK_PRINT | CLK_MHZ);
  887. soc_clk_ctl("tun-clk", NULL, CLK_PRINT | CLK_MHZ);
  888. soc_clk_ctl("axi-clk", NULL, CLK_PRINT | CLK_MHZ);
  889. soc_clk_ctl("ddr-clk", NULL, CLK_PRINT | CLK_MHZ);
  890. return CMD_RET_SUCCESS;
  891. }
  892. static int do_hsdk_clock_print_all(cmd_tbl_t *cmdtp, int flag, int argc,
  893. char *const argv[])
  894. {
  895. /*
  896. * NOTE: as of today we don't use some peripherals like HDMI / EBI
  897. * so we don't want to print their clocks ("hdmi-sys-clk", "hdmi-pll",
  898. * "hdmi-clk", "ebi-clk"). Nevertheless their clock subsystems is fully
  899. * functional and we can print their clocks if it is required
  900. */
  901. /* CPU clock domain */
  902. soc_clk_ctl("cpu-pll", NULL, CLK_PRINT | CLK_MHZ);
  903. soc_clk_ctl("cpu-clk", NULL, CLK_PRINT | CLK_MHZ);
  904. printf("\n");
  905. /* SYS clock domain */
  906. soc_clk_ctl("sys-pll", NULL, CLK_PRINT | CLK_MHZ);
  907. soc_clk_ctl("apb-clk", NULL, CLK_PRINT | CLK_MHZ);
  908. soc_clk_ctl("axi-clk", NULL, CLK_PRINT | CLK_MHZ);
  909. soc_clk_ctl("eth-clk", NULL, CLK_PRINT | CLK_MHZ);
  910. soc_clk_ctl("usb-clk", NULL, CLK_PRINT | CLK_MHZ);
  911. soc_clk_ctl("sdio-clk", NULL, CLK_PRINT | CLK_MHZ);
  912. if (is_board_match_runtime(T_BOARD_HSDK_4XD))
  913. soc_clk_ctl("hdmi-sys-clk", NULL, CLK_PRINT | CLK_MHZ);
  914. soc_clk_ctl("gfx-core-clk", NULL, CLK_PRINT | CLK_MHZ);
  915. if (is_board_match_runtime(T_BOARD_HSDK)) {
  916. soc_clk_ctl("gfx-dma-clk", NULL, CLK_PRINT | CLK_MHZ);
  917. soc_clk_ctl("gfx-cfg-clk", NULL, CLK_PRINT | CLK_MHZ);
  918. }
  919. soc_clk_ctl("dmac-core-clk", NULL, CLK_PRINT | CLK_MHZ);
  920. soc_clk_ctl("dmac-cfg-clk", NULL, CLK_PRINT | CLK_MHZ);
  921. soc_clk_ctl("sdio-ref-clk", NULL, CLK_PRINT | CLK_MHZ);
  922. soc_clk_ctl("spi-clk", NULL, CLK_PRINT | CLK_MHZ);
  923. soc_clk_ctl("i2c-clk", NULL, CLK_PRINT | CLK_MHZ);
  924. /* soc_clk_ctl("ebi-clk", NULL, CLK_PRINT | CLK_MHZ); */
  925. soc_clk_ctl("uart-clk", NULL, CLK_PRINT | CLK_MHZ);
  926. printf("\n");
  927. /* DDR clock domain */
  928. soc_clk_ctl("ddr-clk", NULL, CLK_PRINT | CLK_MHZ);
  929. printf("\n");
  930. /* HDMI clock domain */
  931. if (is_board_match_runtime(T_BOARD_HSDK_4XD)) {
  932. soc_clk_ctl("hdmi-pll", NULL, CLK_PRINT | CLK_MHZ);
  933. soc_clk_ctl("hdmi-clk", NULL, CLK_PRINT | CLK_MHZ);
  934. printf("\n");
  935. }
  936. /* TUN clock domain */
  937. soc_clk_ctl("tun-pll", NULL, CLK_PRINT | CLK_MHZ);
  938. soc_clk_ctl("tun-clk", NULL, CLK_PRINT | CLK_MHZ);
  939. soc_clk_ctl("rom-clk", NULL, CLK_PRINT | CLK_MHZ);
  940. soc_clk_ctl("pwm-clk", NULL, CLK_PRINT | CLK_MHZ);
  941. if (is_board_match_runtime(T_BOARD_HSDK_4XD))
  942. soc_clk_ctl("timer-clk", NULL, CLK_PRINT | CLK_MHZ);
  943. printf("\n");
  944. return CMD_RET_SUCCESS;
  945. }
  946. cmd_tbl_t cmd_hsdk_clock[] = {
  947. U_BOOT_CMD_MKENT(set, 3, 0, do_hsdk_clock_set, "", ""),
  948. U_BOOT_CMD_MKENT(get, 3, 0, do_hsdk_clock_get, "", ""),
  949. U_BOOT_CMD_MKENT(print, 4, 0, do_hsdk_clock_print, "", ""),
  950. U_BOOT_CMD_MKENT(print_all, 4, 0, do_hsdk_clock_print_all, "", ""),
  951. };
  952. static int do_hsdk_clock(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
  953. {
  954. cmd_tbl_t *c;
  955. if (argc < 2)
  956. return CMD_RET_USAGE;
  957. /* Strip off leading 'hsdk_clock' command argument */
  958. argc--;
  959. argv++;
  960. c = find_cmd_tbl(argv[0], cmd_hsdk_clock, ARRAY_SIZE(cmd_hsdk_clock));
  961. if (!c)
  962. return CMD_RET_USAGE;
  963. return c->cmd(cmdtp, flag, argc, argv);
  964. }
  965. U_BOOT_CMD(
  966. hsdk_clock, CONFIG_SYS_MAXARGS, 0, do_hsdk_clock,
  967. "Synopsys HSDK specific clock command",
  968. "set - Set clock to values specified in environment / command line arguments\n"
  969. "hsdk_clock get - Save clock values to environment\n"
  970. "hsdk_clock print - Print main clock values to console\n"
  971. "hsdk_clock print_all - Print all clock values to console\n"
  972. );
  973. /* init calls */
  974. int board_early_init_f(void)
  975. {
  976. /*
  977. * Setup AXI apertures unconditionally as we want to have DDR
  978. * in 0x00000000 region when we are kicking slave cpus.
  979. */
  980. init_memory_bridge();
  981. /*
  982. * Switch SDIO external ciu clock divider from default div-by-8 to
  983. * minimum possible div-by-2.
  984. */
  985. writel(SDIO_UHS_REG_EXT_DIV_2, (void __iomem *)SDIO_UHS_REG_EXT);
  986. return 0;
  987. }
  988. int board_early_init_r(void)
  989. {
  990. /*
  991. * TODO: Init USB here to be able read environment from USB MSD.
  992. * It can be done with usb_init() call. We can't do it right now
  993. * due to brocken USB IP SW reset and lack of USB IP HW reset in
  994. * linux kernel (if we init USB here we will break USB in linux)
  995. */
  996. /*
  997. * Flush all d$ as we want to use uncached area with st.di / ld.di
  998. * instructions and we don't want to have any dirty line in L1d$ or SL$
  999. * in this area. It is enough to flush all d$ once here as we access to
  1000. * uncached area with regular st (non .di) instruction only when we copy
  1001. * data during u-boot relocation.
  1002. */
  1003. flush_dcache_all();
  1004. printf("Relocation Offset is: %08lx\n", gd->reloc_off);
  1005. return 0;
  1006. }
  1007. int board_late_init(void)
  1008. {
  1009. /*
  1010. * Populate environment with clock frequency values -
  1011. * run hsdk_clock get callback without uboot command run.
  1012. */
  1013. do_hsdk_clock_get(NULL, 0, 0, NULL);
  1014. return 0;
  1015. }
  1016. int checkboard(void)
  1017. {
  1018. printf("Board: Synopsys %s\n", board_name(get_board_type_runtime()));
  1019. if (board_mismatch())
  1020. printf("WARN: U-boot is configured NOT for this board but for %s!\n",
  1021. board_name(get_board_type_config()));
  1022. return 0;
  1023. };