portals.c 7.1 KB

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