board-fdt.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2018 Marvell International Ltd.
  4. *
  5. * https://spdx.org/licenses
  6. */
  7. #include <errno.h>
  8. #include <fdtdec.h>
  9. #include <fdt_support.h>
  10. #include <log.h>
  11. #include <linux/compiler.h>
  12. #include <linux/libfdt.h>
  13. #include <asm/arch/board.h>
  14. #include <asm/arch/smc.h>
  15. #include <asm/global_data.h>
  16. #include <asm/io.h>
  17. DECLARE_GLOBAL_DATA_PTR;
  18. static int fdt_get_bdk_node(void)
  19. {
  20. int node, ret;
  21. const void *fdt = gd->fdt_blob;
  22. if (!fdt) {
  23. printf("ERROR: %s: no valid device tree found\n", __func__);
  24. return 0;
  25. }
  26. ret = fdt_check_header(fdt);
  27. if (ret < 0) {
  28. printf("fdt: %s\n", fdt_strerror(ret));
  29. return 0;
  30. }
  31. node = fdt_path_offset(fdt, "/cavium,bdk");
  32. if (node < 0) {
  33. printf("%s: /cavium,bdk is missing from device tree: %s\n",
  34. __func__, fdt_strerror(node));
  35. return 0;
  36. }
  37. return node;
  38. }
  39. u64 fdt_get_board_mac_addr(void)
  40. {
  41. int node, len = 16;
  42. const char *str = NULL;
  43. const void *fdt = gd->fdt_blob;
  44. u64 mac_addr = 0;
  45. node = fdt_get_bdk_node();
  46. if (!node)
  47. return mac_addr;
  48. str = fdt_getprop(fdt, node, "BOARD-MAC-ADDRESS", &len);
  49. if (str)
  50. mac_addr = simple_strtol(str, NULL, 16);
  51. return mac_addr;
  52. }
  53. int fdt_get_board_mac_cnt(void)
  54. {
  55. int node, len = 16;
  56. const char *str = NULL;
  57. const void *fdt = gd->fdt_blob;
  58. int mac_count = 0;
  59. node = fdt_get_bdk_node();
  60. if (!node)
  61. return mac_count;
  62. str = fdt_getprop(fdt, node, "BOARD-MAC-ADDRESS-NUM", &len);
  63. if (str) {
  64. mac_count = simple_strtol(str, NULL, 10);
  65. if (!mac_count)
  66. mac_count = simple_strtol(str, NULL, 16);
  67. debug("fdt: MAC_NUM %d\n", mac_count);
  68. } else {
  69. printf("Error: cannot retrieve mac count prop from fdt\n");
  70. }
  71. str = fdt_getprop(gd->fdt_blob, node, "BOARD-MAC-ADDRESS-NUM-OVERRIDE",
  72. &len);
  73. if (str) {
  74. if (simple_strtol(str, NULL, 10) >= 0)
  75. mac_count = simple_strtol(str, NULL, 10);
  76. debug("fdt: MAC_NUM %d\n", mac_count);
  77. } else {
  78. printf("Error: cannot retrieve mac num override prop\n");
  79. }
  80. return mac_count;
  81. }
  82. const char *fdt_get_board_serial(void)
  83. {
  84. const void *fdt = gd->fdt_blob;
  85. int node, len = 64;
  86. const char *str = NULL;
  87. node = fdt_get_bdk_node();
  88. if (!node)
  89. return NULL;
  90. str = fdt_getprop(fdt, node, "BOARD-SERIAL", &len);
  91. if (!str)
  92. printf("Error: cannot retrieve board serial from fdt\n");
  93. return str;
  94. }
  95. const char *fdt_get_board_revision(void)
  96. {
  97. const void *fdt = gd->fdt_blob;
  98. int node, len = 64;
  99. const char *str = NULL;
  100. node = fdt_get_bdk_node();
  101. if (!node)
  102. return NULL;
  103. str = fdt_getprop(fdt, node, "BOARD-REVISION", &len);
  104. if (!str)
  105. printf("Error: cannot retrieve board revision from fdt\n");
  106. return str;
  107. }
  108. const char *fdt_get_board_model(void)
  109. {
  110. int node, len = 16;
  111. const char *str = NULL;
  112. const void *fdt = gd->fdt_blob;
  113. node = fdt_get_bdk_node();
  114. if (!node)
  115. return NULL;
  116. str = fdt_getprop(fdt, node, "BOARD-MODEL", &len);
  117. if (!str)
  118. printf("Error: cannot retrieve board model from fdt\n");
  119. return str;
  120. }
  121. int arch_fixup_memory_node(void *blob)
  122. {
  123. return 0;
  124. }
  125. int ft_board_setup(void *blob, struct bd_info *bd)
  126. {
  127. int nodeoff, node, ret, i;
  128. const char *temp;
  129. static const char * const
  130. octeontx_brd_nodes[] = {"BOARD-MODEL",
  131. "BOARD-SERIAL",
  132. "BOARD-MAC-ADDRESS",
  133. "BOARD-REVISION",
  134. "BOARD-MAC-ADDRESS-NUM"
  135. };
  136. char nodes[ARRAY_SIZE(octeontx_brd_nodes)][32];
  137. ret = fdt_check_header(blob);
  138. if (ret < 0) {
  139. printf("ERROR: %s\n", fdt_strerror(ret));
  140. return ret;
  141. }
  142. if (blob) {
  143. nodeoff = fdt_path_offset(blob, "/cavium,bdk");
  144. if (nodeoff < 0) {
  145. printf("ERROR: FDT BDK node not found\n");
  146. return nodeoff;
  147. }
  148. /* Read properties in temporary variables */
  149. for (i = 0; i < ARRAY_SIZE(octeontx_brd_nodes); i++) {
  150. temp = fdt_getprop(blob, nodeoff,
  151. octeontx_brd_nodes[i], NULL);
  152. strncpy(nodes[i], temp, sizeof(nodes[i]));
  153. }
  154. /* Delete cavium,bdk node */
  155. ret = fdt_del_node(blob, nodeoff);
  156. if (ret < 0) {
  157. printf("WARNING : could not remove cavium, bdk node\n");
  158. return ret;
  159. }
  160. debug("%s deleted 'cavium,bdk' node\n", __func__);
  161. /*
  162. * Add a new node at root level which would have
  163. * necessary info
  164. */
  165. node = fdt_add_subnode(blob, 0, "octeontx_brd");
  166. if (node < 0) {
  167. printf("Cannot create node octeontx_brd: %s\n",
  168. fdt_strerror(node));
  169. return -EIO;
  170. }
  171. /* Populate properties in node */
  172. for (i = 0; i < ARRAY_SIZE(octeontx_brd_nodes); i++) {
  173. if (fdt_setprop_string(blob, node,
  174. octeontx_brd_nodes[i],
  175. nodes[i])) {
  176. printf("Can't set %s\n", nodes[i]);
  177. return -EIO;
  178. }
  179. }
  180. }
  181. return 0;
  182. }
  183. /**
  184. * Return the FDT base address that was passed by ATF
  185. *
  186. * @return FDT base address received from ATF in x1 register
  187. */
  188. void *board_fdt_blob_setup(void)
  189. {
  190. return (void *)fdt_base_addr;
  191. }