fdt.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /*
  2. * Copyright 2016 Texas Instruments, Inc.
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <libfdt.h>
  8. #include <fdt_support.h>
  9. #include <malloc.h>
  10. #include <asm/omap_common.h>
  11. #include <asm/arch-omap5/sys_proto.h>
  12. #ifdef CONFIG_TI_SECURE_DEVICE
  13. /* Give zero values if not already defined */
  14. #ifndef TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ
  15. #define TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ (0)
  16. #endif
  17. #ifndef CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ
  18. #define CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ (0)
  19. #endif
  20. static u32 hs_irq_skip[] = {
  21. 8, /* Secure violation reporting interrupt */
  22. 15, /* One interrupt for SDMA by secure world */
  23. 118 /* One interrupt for Crypto DMA by secure world */
  24. };
  25. static int ft_hs_fixup_crossbar(void *fdt, bd_t *bd)
  26. {
  27. const char *path;
  28. int offs;
  29. int ret;
  30. int len, i, old_cnt, new_cnt;
  31. u32 *temp;
  32. const u32 *p_data;
  33. /*
  34. * Increase the size of the fdt
  35. * so we have some breathing room
  36. */
  37. ret = fdt_increase_size(fdt, 512);
  38. if (ret < 0) {
  39. printf("Could not increase size of device tree: %s\n",
  40. fdt_strerror(ret));
  41. return ret;
  42. }
  43. /* Reserve IRQs that are used/needed by secure world */
  44. path = "/ocp/crossbar";
  45. offs = fdt_path_offset(fdt, path);
  46. if (offs < 0) {
  47. debug("Node %s not found.\n", path);
  48. return 0;
  49. }
  50. /* Get current entries */
  51. p_data = fdt_getprop(fdt, offs, "ti,irqs-skip", &len);
  52. if (p_data)
  53. old_cnt = len / sizeof(u32);
  54. else
  55. old_cnt = 0;
  56. new_cnt = sizeof(hs_irq_skip) /
  57. sizeof(hs_irq_skip[0]);
  58. /* Create new/updated skip list for HS parts */
  59. temp = malloc(sizeof(u32) * (old_cnt + new_cnt));
  60. for (i = 0; i < new_cnt; i++)
  61. temp[i] = cpu_to_fdt32(hs_irq_skip[i]);
  62. for (i = 0; i < old_cnt; i++)
  63. temp[i + new_cnt] = p_data[i];
  64. /* Blow away old data and set new data */
  65. fdt_delprop(fdt, offs, "ti,irqs-skip");
  66. ret = fdt_setprop(fdt, offs, "ti,irqs-skip",
  67. temp,
  68. (old_cnt + new_cnt) * sizeof(u32));
  69. free(temp);
  70. /* Check if the update worked */
  71. if (ret < 0) {
  72. printf("Could not add ti,irqs-skip property to node %s: %s\n",
  73. path, fdt_strerror(ret));
  74. return ret;
  75. }
  76. return 0;
  77. }
  78. static int ft_hs_disable_rng(void *fdt, bd_t *bd)
  79. {
  80. const char *path;
  81. int offs;
  82. int ret;
  83. /* Make HW RNG reserved for secure world use */
  84. path = "/ocp/rng";
  85. offs = fdt_path_offset(fdt, path);
  86. if (offs < 0) {
  87. debug("Node %s not found.\n", path);
  88. return 0;
  89. }
  90. ret = fdt_setprop_string(fdt, offs,
  91. "status", "disabled");
  92. if (ret < 0) {
  93. printf("Could not add status property to node %s: %s\n",
  94. path, fdt_strerror(ret));
  95. return ret;
  96. }
  97. return 0;
  98. }
  99. #if ((TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ != 0) || \
  100. (CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ != 0))
  101. static int ft_hs_fixup_sram(void *fdt, bd_t *bd)
  102. {
  103. const char *path;
  104. int offs;
  105. int ret;
  106. u32 temp[2];
  107. /*
  108. * Update SRAM reservations on secure devices. The OCMC RAM
  109. * is always reserved for secure use from the start of that
  110. * memory region
  111. */
  112. path = "/ocp/ocmcram@40300000/sram-hs";
  113. offs = fdt_path_offset(fdt, path);
  114. if (offs < 0) {
  115. debug("Node %s not found.\n", path);
  116. return 0;
  117. }
  118. /* relative start offset */
  119. temp[0] = cpu_to_fdt32(0);
  120. /* reservation size */
  121. temp[1] = cpu_to_fdt32(max(TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ,
  122. CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ));
  123. fdt_delprop(fdt, offs, "reg");
  124. ret = fdt_setprop(fdt, offs, "reg", temp, 2 * sizeof(u32));
  125. if (ret < 0) {
  126. printf("Could not add reg property to node %s: %s\n",
  127. path, fdt_strerror(ret));
  128. return ret;
  129. }
  130. return 0;
  131. }
  132. #else
  133. static int ft_hs_fixup_sram(void *fdt, bd_t *bd) { return 0; }
  134. #endif
  135. #if (CONFIG_TI_SECURE_EMIF_TOTAL_REGION_SIZE != 0)
  136. static int ft_hs_fixup_dram(void *fdt, bd_t *bd)
  137. {
  138. const char *path, *subpath;
  139. int offs;
  140. u32 sec_mem_start = CONFIG_TI_SECURE_EMIF_REGION_START;
  141. u32 sec_mem_size = CONFIG_TI_SECURE_EMIF_TOTAL_REGION_SIZE;
  142. fdt64_t temp[2];
  143. fdt32_t two;
  144. /* If start address is zero, place at end of DRAM */
  145. if (0 == sec_mem_start)
  146. sec_mem_start =
  147. (CONFIG_SYS_SDRAM_BASE +
  148. (omap_sdram_size() - sec_mem_size));
  149. /* Delete any original secure_reserved node */
  150. path = "/reserved-memory/secure_reserved";
  151. offs = fdt_path_offset(fdt, path);
  152. if (offs >= 0)
  153. fdt_del_node(fdt, offs);
  154. /* Add new secure_reserved node */
  155. path = "/reserved-memory";
  156. offs = fdt_path_offset(fdt, path);
  157. if (offs < 0) {
  158. debug("Node %s not found\n", path);
  159. path = "/";
  160. subpath = "reserved-memory";
  161. offs = fdt_path_offset(fdt, path);
  162. offs = fdt_add_subnode(fdt, offs, subpath);
  163. if (offs < 0) {
  164. printf("Could not create %s%s node.\n", path, subpath);
  165. return 1;
  166. }
  167. path = "/reserved-memory";
  168. offs = fdt_path_offset(fdt, path);
  169. two = cpu_to_fdt32(2);
  170. fdt_setprop(fdt, offs, "#address-cells", &two, sizeof(two));
  171. fdt_setprop(fdt, offs, "#size-cells", &two, sizeof(two));
  172. fdt_setprop(fdt, offs, "ranges", NULL, 0);
  173. }
  174. subpath = "secure_reserved";
  175. offs = fdt_add_subnode(fdt, offs, subpath);
  176. if (offs < 0) {
  177. printf("Could not create %s%s node.\n", path, subpath);
  178. return 1;
  179. }
  180. temp[0] = cpu_to_fdt64(((u64)sec_mem_start));
  181. temp[1] = cpu_to_fdt64(((u64)sec_mem_size));
  182. fdt_setprop_string(fdt, offs, "compatible",
  183. "ti,dra7-secure-memory");
  184. fdt_setprop_string(fdt, offs, "status", "okay");
  185. fdt_setprop(fdt, offs, "no-map", NULL, 0);
  186. fdt_setprop(fdt, offs, "reg", temp, sizeof(temp));
  187. return 0;
  188. }
  189. #else
  190. static int ft_hs_fixup_dram(void *fdt, bd_t *bd) { return 0; }
  191. #endif
  192. static int ft_hs_add_tee(void *fdt, bd_t *bd)
  193. {
  194. const char *path, *subpath;
  195. int offs;
  196. extern int tee_loaded;
  197. if (!tee_loaded)
  198. return 0;
  199. path = "/";
  200. offs = fdt_path_offset(fdt, path);
  201. subpath = "firmware";
  202. offs = fdt_add_subnode(fdt, offs, subpath);
  203. if (offs < 0) {
  204. printf("Could not create %s node.\n", subpath);
  205. return 1;
  206. }
  207. subpath = "optee";
  208. offs = fdt_add_subnode(fdt, offs, subpath);
  209. if (offs < 0) {
  210. printf("Could not create %s node.\n", subpath);
  211. return 1;
  212. }
  213. fdt_setprop_string(fdt, offs, "compatible", "linaro,optee-tz");
  214. fdt_setprop_string(fdt, offs, "method", "smc");
  215. return 0;
  216. }
  217. static void ft_hs_fixups(void *fdt, bd_t *bd)
  218. {
  219. /* Check we are running on an HS/EMU device type */
  220. if (GP_DEVICE != get_device_type()) {
  221. if ((ft_hs_fixup_crossbar(fdt, bd) == 0) &&
  222. (ft_hs_disable_rng(fdt, bd) == 0) &&
  223. (ft_hs_fixup_sram(fdt, bd) == 0) &&
  224. (ft_hs_fixup_dram(fdt, bd) == 0) &&
  225. (ft_hs_add_tee(fdt, bd) == 0))
  226. return;
  227. } else {
  228. printf("ERROR: Incorrect device type (GP) detected!");
  229. }
  230. /* Fixup failed or wrong device type */
  231. hang();
  232. }
  233. #else
  234. static void ft_hs_fixups(void *fdt, bd_t *bd)
  235. {
  236. }
  237. #endif /* #ifdef CONFIG_TI_SECURE_DEVICE */
  238. #if defined(CONFIG_TARGET_DRA7XX_EVM) || defined(CONFIG_TARGET_AM57XX_EVM)
  239. #define OPP_DSP_CLK_NUM 3
  240. #define OPP_IVA_CLK_NUM 2
  241. #define OPP_GPU_CLK_NUM 2
  242. const char *dra7_opp_dsp_clk_names[OPP_DSP_CLK_NUM] = {
  243. "dpll_dsp_ck",
  244. "dpll_dsp_m2_ck",
  245. "dpll_dsp_m3x2_ck",
  246. };
  247. const char *dra7_opp_iva_clk_names[OPP_IVA_CLK_NUM] = {
  248. "dpll_iva_ck",
  249. "dpll_iva_m2_ck",
  250. };
  251. const char *dra7_opp_gpu_clk_names[OPP_GPU_CLK_NUM] = {
  252. "dpll_gpu_ck",
  253. "dpll_gpu_m2_ck",
  254. };
  255. /* DSPEVE voltage domain */
  256. u32 dra7_opp_dsp_clk_rates[NUM_OPPS][OPP_DSP_CLK_NUM] = {
  257. {}, /*OPP_LOW */
  258. {600000000, 600000000, 400000000}, /* OPP_NOM */
  259. {700000000, 700000000, 466666667}, /* OPP_OD */
  260. {750000000, 750000000, 500000000}, /* OPP_HIGH */
  261. };
  262. /* IVA voltage domain */
  263. u32 dra7_opp_iva_clk_rates[NUM_OPPS][OPP_IVA_CLK_NUM] = {
  264. {}, /* OPP_LOW */
  265. {1165000000, 388333334}, /* OPP_NOM */
  266. {860000000, 430000000}, /* OPP_OD */
  267. {1064000000, 532000000}, /* OPP_HIGH */
  268. };
  269. /* GPU voltage domain */
  270. u32 dra7_opp_gpu_clk_rates[NUM_OPPS][OPP_GPU_CLK_NUM] = {
  271. {}, /* OPP_LOW */
  272. {1277000000, 425666667}, /* OPP_NOM */
  273. {1000000000, 500000000}, /* OPP_OD */
  274. {1064000000, 532000000}, /* OPP_HIGH */
  275. };
  276. static int ft_fixup_clocks(void *fdt, const char **names, u32 *rates, int num)
  277. {
  278. int offs, node_offs, ret, i;
  279. uint32_t phandle;
  280. offs = fdt_path_offset(fdt, "/ocp/l4@4a000000/cm_core_aon@5000/clocks");
  281. if (offs < 0) {
  282. debug("Could not find cm_core_aon clocks node path offset : %s\n",
  283. fdt_strerror(offs));
  284. return offs;
  285. }
  286. for (i = 0; i < num; i++) {
  287. node_offs = fdt_subnode_offset(fdt, offs, names[i]);
  288. if (node_offs < 0) {
  289. debug("Could not find clock sub-node %s: %s\n",
  290. names[i], fdt_strerror(node_offs));
  291. return offs;
  292. }
  293. phandle = fdt_get_phandle(fdt, node_offs);
  294. if (!phandle) {
  295. debug("Could not find phandle for clock %s\n",
  296. names[i]);
  297. return -1;
  298. }
  299. ret = fdt_setprop_u32(fdt, node_offs, "assigned-clocks",
  300. phandle);
  301. if (ret < 0) {
  302. debug("Could not add assigned-clocks property to clock node %s: %s\n",
  303. names[i], fdt_strerror(ret));
  304. return ret;
  305. }
  306. ret = fdt_setprop_u32(fdt, node_offs, "assigned-clock-rates",
  307. rates[i]);
  308. if (ret < 0) {
  309. debug("Could not add assigned-clock-rates property to clock node %s: %s\n",
  310. names[i], fdt_strerror(ret));
  311. return ret;
  312. }
  313. }
  314. return 0;
  315. }
  316. static void ft_opp_clock_fixups(void *fdt, bd_t *bd)
  317. {
  318. const char **clk_names;
  319. u32 *clk_rates;
  320. int ret;
  321. if (!is_dra72x() && !is_dra7xx())
  322. return;
  323. /* fixup DSP clocks */
  324. clk_names = dra7_opp_dsp_clk_names;
  325. clk_rates = dra7_opp_dsp_clk_rates[get_voltrail_opp(VOLT_EVE)];
  326. ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_DSP_CLK_NUM);
  327. if (ret) {
  328. printf("ft_fixup_clocks failed for DSP voltage domain: %s\n",
  329. fdt_strerror(ret));
  330. return;
  331. }
  332. /* fixup IVA clocks */
  333. clk_names = dra7_opp_iva_clk_names;
  334. clk_rates = dra7_opp_iva_clk_rates[get_voltrail_opp(VOLT_IVA)];
  335. ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_IVA_CLK_NUM);
  336. if (ret) {
  337. printf("ft_fixup_clocks failed for IVA voltage domain: %s\n",
  338. fdt_strerror(ret));
  339. return;
  340. }
  341. /* fixup GPU clocks */
  342. clk_names = dra7_opp_gpu_clk_names;
  343. clk_rates = dra7_opp_gpu_clk_rates[get_voltrail_opp(VOLT_GPU)];
  344. ret = ft_fixup_clocks(fdt, clk_names, clk_rates, OPP_GPU_CLK_NUM);
  345. if (ret) {
  346. printf("ft_fixup_clocks failed for GPU voltage domain: %s\n",
  347. fdt_strerror(ret));
  348. return;
  349. }
  350. }
  351. #else
  352. static void ft_opp_clock_fixups(void *fdt, bd_t *bd) { }
  353. #endif /* CONFIG_TARGET_DRA7XX_EVM || CONFIG_TARGET_AM57XX_EVM */
  354. /*
  355. * Place for general cpu/SoC FDT fixups. Board specific
  356. * fixups should remain in the board files which is where
  357. * this function should be called from.
  358. */
  359. void ft_cpu_setup(void *fdt, bd_t *bd)
  360. {
  361. ft_hs_fixups(fdt, bd);
  362. ft_opp_clock_fixups(fdt, bd);
  363. }