portals.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /*
  2. * Copyright 2008-2011 Freescale Semiconductor, 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 <asm/processor.h>
  10. #include <asm/io.h>
  11. #include <asm/fsl_portals.h>
  12. #include <asm/fsl_liodn.h>
  13. #define MAX_BPORTALS (CONFIG_SYS_BMAN_CINH_SIZE / CONFIG_SYS_BMAN_SP_CINH_SIZE)
  14. #define MAX_QPORTALS (CONFIG_SYS_QMAN_CINH_SIZE / CONFIG_SYS_QMAN_SP_CINH_SIZE)
  15. static void inhibit_portals(void __iomem *addr, int max_portals,
  16. int arch_max_portals, int portal_cinh_size)
  17. {
  18. uint32_t val;
  19. int i;
  20. /* arch_max_portals is the maximum based on memory size. This includes
  21. * the reserved memory in the SoC. max_portals the number of physical
  22. * portals in the SoC */
  23. if (max_portals > arch_max_portals) {
  24. printf("ERROR: portal config error\n");
  25. max_portals = arch_max_portals;
  26. }
  27. for (i = 0; i < max_portals; i++) {
  28. out_be32(addr, -1);
  29. val = in_be32(addr);
  30. if (!val) {
  31. printf("ERROR: Stopped after %d portals\n", i);
  32. goto done;
  33. }
  34. addr += portal_cinh_size;
  35. }
  36. #ifdef DEBUG
  37. printf("Cleared %d portals\n", i);
  38. #endif
  39. done:
  40. return;
  41. }
  42. void setup_portals(void)
  43. {
  44. ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;
  45. void __iomem *bpaddr = (void *)CONFIG_SYS_BMAN_CINH_BASE +
  46. CONFIG_SYS_BMAN_SWP_ISDR_REG;
  47. void __iomem *qpaddr = (void *)CONFIG_SYS_QMAN_CINH_BASE +
  48. CONFIG_SYS_QMAN_SWP_ISDR_REG;
  49. #ifdef CONFIG_FSL_CORENET
  50. int i;
  51. for (i = 0; i < CONFIG_SYS_QMAN_NUM_PORTALS; i++) {
  52. u8 sdest = qp_info[i].sdest;
  53. u16 fliodn = qp_info[i].fliodn;
  54. u16 dliodn = qp_info[i].dliodn;
  55. u16 liodn_off = qp_info[i].liodn_offset;
  56. out_be32(&qman->qcsp[i].qcsp_lio_cfg, (liodn_off << 16) |
  57. dliodn);
  58. /* set frame liodn */
  59. out_be32(&qman->qcsp[i].qcsp_io_cfg, (sdest << 16) | fliodn);
  60. }
  61. #endif
  62. /* Set the Qman initiator BAR to match the LAW (for DQRR stashing) */
  63. #ifdef CONFIG_PHYS_64BIT
  64. out_be32(&qman->qcsp_bare, (u32)(CONFIG_SYS_QMAN_MEM_PHYS >> 32));
  65. #endif
  66. out_be32(&qman->qcsp_bar, (u32)CONFIG_SYS_QMAN_MEM_PHYS);
  67. /* Change default state of BMan ISDR portals to all 1s */
  68. inhibit_portals(bpaddr, CONFIG_SYS_BMAN_NUM_PORTALS, MAX_BPORTALS,
  69. CONFIG_SYS_BMAN_SP_CINH_SIZE);
  70. inhibit_portals(qpaddr, CONFIG_SYS_QMAN_NUM_PORTALS, MAX_QPORTALS,
  71. CONFIG_SYS_QMAN_SP_CINH_SIZE);
  72. }
  73. /* Update portal containter to match LAW setup of portal in phy map */
  74. void fdt_portal(void *blob, const char *compat, const char *container,
  75. u64 addr, u32 size)
  76. {
  77. int off;
  78. off = fdt_node_offset_by_compatible(blob, -1, compat);
  79. if (off < 0)
  80. return ;
  81. off = fdt_parent_offset(blob, off);
  82. /* if non-zero assume we have a container */
  83. if (off > 0) {
  84. char buf[60];
  85. const char *p, *name;
  86. u32 *range;
  87. int len;
  88. /* fixup ranges */
  89. range = fdt_getprop_w(blob, off, "ranges", &len);
  90. if (range == NULL) {
  91. printf("ERROR: container for %s has no ranges", compat);
  92. return ;
  93. }
  94. range[0] = 0;
  95. if (len == 16) {
  96. range[1] = addr >> 32;
  97. range[2] = addr & 0xffffffff;
  98. range[3] = size;
  99. } else {
  100. range[1] = addr & 0xffffffff;
  101. range[2] = size;
  102. }
  103. fdt_setprop_inplace(blob, off, "ranges", range, len);
  104. /* fixup the name */
  105. name = fdt_get_name(blob, off, &len);
  106. p = memchr(name, '@', len);
  107. if (p)
  108. len = p - name;
  109. /* if we are given a container name check it
  110. * against what we found, if it doesnt match exit out */
  111. if (container && (memcmp(container, name, len))) {
  112. printf("WARNING: container names didn't match %s %s\n",
  113. container, name);
  114. return ;
  115. }
  116. memcpy(&buf, name, len);
  117. len += sprintf(&buf[len], "@%llx", addr);
  118. fdt_set_name(blob, off, buf);
  119. return ;
  120. }
  121. printf("ERROR: %s isn't in a container. Not supported\n", compat);
  122. }
  123. static int fdt_qportal(void *blob, int off, int id, char *name,
  124. enum fsl_dpaa_dev dev, int create)
  125. {
  126. int childoff, dev_off, ret = 0;
  127. uint32_t dev_handle;
  128. #ifdef CONFIG_FSL_CORENET
  129. int num;
  130. u32 liodns[2];
  131. #endif
  132. childoff = fdt_subnode_offset(blob, off, name);
  133. if (create) {
  134. char handle[64], *p;
  135. strncpy(handle, name, sizeof(handle));
  136. p = strchr(handle, '@');
  137. if (!strncmp(name, "fman", 4)) {
  138. *p = *(p + 1);
  139. p++;
  140. }
  141. *p = '\0';
  142. dev_off = fdt_path_offset(blob, handle);
  143. /* skip this node if alias is not found */
  144. if (dev_off == -FDT_ERR_BADPATH)
  145. return 0;
  146. if (dev_off < 0)
  147. return dev_off;
  148. if (childoff <= 0)
  149. childoff = fdt_add_subnode(blob, off, name);
  150. /* need to update the dev_off after adding a subnode */
  151. dev_off = fdt_path_offset(blob, handle);
  152. if (dev_off < 0)
  153. return dev_off;
  154. if (childoff > 0) {
  155. dev_handle = fdt_get_phandle(blob, dev_off);
  156. if (dev_handle <= 0) {
  157. dev_handle = fdt_alloc_phandle(blob);
  158. ret = fdt_set_phandle(blob, dev_off,
  159. dev_handle);
  160. if (ret < 0)
  161. return ret;
  162. }
  163. ret = fdt_setprop(blob, childoff, "dev-handle",
  164. &dev_handle, sizeof(dev_handle));
  165. if (ret < 0)
  166. return ret;
  167. #ifdef CONFIG_FSL_CORENET
  168. num = get_dpaa_liodn(dev, &liodns[0], id);
  169. ret = fdt_setprop(blob, childoff, "fsl,liodn",
  170. &liodns[0], sizeof(u32) * num);
  171. if (!strncmp(name, "pme", 3)) {
  172. u32 pme_rev1, pme_rev2;
  173. ccsr_pme_t *pme_regs =
  174. (void *)CONFIG_SYS_FSL_CORENET_PME_ADDR;
  175. pme_rev1 = in_be32(&pme_regs->pm_ip_rev_1);
  176. pme_rev2 = in_be32(&pme_regs->pm_ip_rev_2);
  177. ret = fdt_setprop(blob, childoff,
  178. "fsl,pme-rev1", &pme_rev1, sizeof(u32));
  179. if (ret < 0)
  180. return ret;
  181. ret = fdt_setprop(blob, childoff,
  182. "fsl,pme-rev2", &pme_rev2, sizeof(u32));
  183. }
  184. #endif
  185. } else {
  186. return childoff;
  187. }
  188. } else {
  189. if (childoff > 0)
  190. ret = fdt_del_node(blob, childoff);
  191. }
  192. return ret;
  193. }
  194. void fdt_fixup_qportals(void *blob)
  195. {
  196. int off, err;
  197. unsigned int maj, min;
  198. unsigned int ip_cfg;
  199. ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;
  200. u32 rev_1 = in_be32(&qman->ip_rev_1);
  201. u32 rev_2 = in_be32(&qman->ip_rev_2);
  202. char compat[64];
  203. int compat_len;
  204. maj = (rev_1 >> 8) & 0xff;
  205. min = rev_1 & 0xff;
  206. ip_cfg = rev_2 & 0xff;
  207. compat_len = sprintf(compat, "fsl,qman-portal-%u.%u.%u",
  208. maj, min, ip_cfg) + 1;
  209. compat_len += sprintf(compat + compat_len, "fsl,qman-portal") + 1;
  210. off = fdt_node_offset_by_compatible(blob, -1, "fsl,qman-portal");
  211. while (off != -FDT_ERR_NOTFOUND) {
  212. #ifdef CONFIG_FSL_CORENET
  213. u32 liodns[2];
  214. #endif
  215. const int *ci = fdt_getprop(blob, off, "cell-index", &err);
  216. int i;
  217. if (!ci)
  218. goto err;
  219. i = *ci;
  220. #ifdef CONFIG_SYS_DPAA_FMAN
  221. int j;
  222. #endif
  223. err = fdt_setprop(blob, off, "compatible", compat, compat_len);
  224. if (err < 0)
  225. goto err;
  226. #ifdef CONFIG_FSL_CORENET
  227. liodns[0] = qp_info[i].dliodn;
  228. liodns[1] = qp_info[i].fliodn;
  229. err = fdt_setprop(blob, off, "fsl,liodn",
  230. &liodns, sizeof(u32) * 2);
  231. if (err < 0)
  232. goto err;
  233. #endif
  234. i++;
  235. err = fdt_qportal(blob, off, i, "crypto@0", FSL_HW_PORTAL_SEC,
  236. IS_E_PROCESSOR(get_svr()));
  237. if (err < 0)
  238. goto err;
  239. #ifdef CONFIG_FSL_CORENET
  240. #ifdef CONFIG_SYS_DPAA_PME
  241. err = fdt_qportal(blob, off, i, "pme@0", FSL_HW_PORTAL_PME, 1);
  242. if (err < 0)
  243. goto err;
  244. #else
  245. fdt_qportal(blob, off, i, "pme@0", FSL_HW_PORTAL_PME, 0);
  246. #endif
  247. #endif
  248. #ifdef CONFIG_SYS_DPAA_FMAN
  249. for (j = 0; j < CONFIG_SYS_NUM_FMAN; j++) {
  250. char name[] = "fman@0";
  251. name[sizeof(name) - 2] = '0' + j;
  252. err = fdt_qportal(blob, off, i, name,
  253. FSL_HW_PORTAL_FMAN1 + j, 1);
  254. if (err < 0)
  255. goto err;
  256. }
  257. #endif
  258. #ifdef CONFIG_SYS_DPAA_RMAN
  259. err = fdt_qportal(blob, off, i, "rman@0",
  260. FSL_HW_PORTAL_RMAN, 1);
  261. if (err < 0)
  262. goto err;
  263. #endif
  264. err:
  265. if (err < 0) {
  266. printf("ERROR: unable to create props for %s: %s\n",
  267. fdt_get_name(blob, off, NULL), fdt_strerror(err));
  268. return;
  269. }
  270. off = fdt_node_offset_by_compatible(blob, off, "fsl,qman-portal");
  271. }
  272. }
  273. void fdt_fixup_bportals(void *blob)
  274. {
  275. int off, err;
  276. unsigned int maj, min;
  277. unsigned int ip_cfg;
  278. ccsr_bman_t *bman = (void *)CONFIG_SYS_FSL_BMAN_ADDR;
  279. u32 rev_1 = in_be32(&bman->ip_rev_1);
  280. u32 rev_2 = in_be32(&bman->ip_rev_2);
  281. char compat[64];
  282. int compat_len;
  283. maj = (rev_1 >> 8) & 0xff;
  284. min = rev_1 & 0xff;
  285. ip_cfg = rev_2 & 0xff;
  286. compat_len = sprintf(compat, "fsl,bman-portal-%u.%u.%u",
  287. maj, min, ip_cfg) + 1;
  288. compat_len += sprintf(compat + compat_len, "fsl,bman-portal") + 1;
  289. off = fdt_node_offset_by_compatible(blob, -1, "fsl,bman-portal");
  290. while (off != -FDT_ERR_NOTFOUND) {
  291. err = fdt_setprop(blob, off, "compatible", compat, compat_len);
  292. if (err < 0) {
  293. printf("ERROR: unable to create props for %s: %s\n",
  294. fdt_get_name(blob, off, NULL),
  295. fdt_strerror(err));
  296. return;
  297. }
  298. off = fdt_node_offset_by_compatible(blob, off, "fsl,bman-portal");
  299. }
  300. }