dt-setup.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2010-2016, NVIDIA CORPORATION.
  4. */
  5. #include <common.h>
  6. #include <fdtdec.h>
  7. #include <stdlib.h>
  8. #include <asm/arch-tegra/cboot.h>
  9. #include <asm/arch-tegra/gpu.h>
  10. /*
  11. * This function is called right before the kernel is booted. "blob" is the
  12. * device tree that will be passed to the kernel.
  13. */
  14. int ft_system_setup(void *blob, struct bd_info *bd)
  15. {
  16. const char *gpu_compats[] = {
  17. #if defined(CONFIG_TEGRA124)
  18. "nvidia,gk20a",
  19. #endif
  20. #if defined(CONFIG_TEGRA210)
  21. "nvidia,gm20b",
  22. #endif
  23. };
  24. int i, ret;
  25. /* Enable GPU node if GPU setup has been performed */
  26. for (i = 0; i < ARRAY_SIZE(gpu_compats); i++) {
  27. ret = tegra_gpu_enable_node(blob, gpu_compats[i]);
  28. if (ret)
  29. return ret;
  30. }
  31. return 0;
  32. }
  33. #if defined(CONFIG_ARM64)
  34. void ft_mac_address_setup(void *fdt)
  35. {
  36. const void *cboot_fdt = (const void *)cboot_boot_x0;
  37. uint8_t mac[ETH_ALEN], local_mac[ETH_ALEN];
  38. const char *path;
  39. int offset, err;
  40. err = cboot_get_ethaddr(cboot_fdt, local_mac);
  41. if (err < 0)
  42. memset(local_mac, 0, ETH_ALEN);
  43. path = fdt_get_alias(fdt, "ethernet");
  44. if (!path)
  45. return;
  46. debug("ethernet alias found: %s\n", path);
  47. offset = fdt_path_offset(fdt, path);
  48. if (offset < 0) {
  49. printf("ethernet alias points to absent node %s\n", path);
  50. return;
  51. }
  52. if (is_valid_ethaddr(local_mac)) {
  53. err = fdt_setprop(fdt, offset, "local-mac-address", local_mac,
  54. ETH_ALEN);
  55. if (!err)
  56. debug("Local MAC address set: %pM\n", local_mac);
  57. }
  58. if (eth_env_get_enetaddr("ethaddr", mac)) {
  59. if (memcmp(local_mac, mac, ETH_ALEN) != 0) {
  60. err = fdt_setprop(fdt, offset, "mac-address", mac,
  61. ETH_ALEN);
  62. if (!err)
  63. debug("MAC address set: %pM\n", mac);
  64. }
  65. }
  66. }
  67. static int ft_copy_carveout(void *dst, const void *src, const char *node)
  68. {
  69. const char *names = "memory-region-names";
  70. struct fdt_memory carveout;
  71. unsigned int index = 0;
  72. int err, offset, len;
  73. const void *prop;
  74. while (true) {
  75. const char **compatibles = NULL;
  76. unsigned int num_compatibles;
  77. unsigned long flags;
  78. char *copy = NULL;
  79. const char *name;
  80. err = fdtdec_get_carveout(src, node, "memory-region", index,
  81. &carveout, &name, &compatibles,
  82. &num_compatibles, &flags);
  83. if (err < 0) {
  84. if (err != -FDT_ERR_NOTFOUND)
  85. printf("failed to get carveout for %s: %d\n",
  86. node, err);
  87. else
  88. break;
  89. return err;
  90. }
  91. if (name) {
  92. const char *ptr = strchr(name, '@');
  93. if (ptr) {
  94. copy = strndup(name, ptr - name);
  95. name = copy;
  96. }
  97. } else {
  98. name = "carveout";
  99. }
  100. err = fdtdec_set_carveout(dst, node, "memory-region", index,
  101. &carveout, name, compatibles,
  102. num_compatibles, flags);
  103. if (err < 0) {
  104. printf("failed to set carveout for %s: %d\n", node,
  105. err);
  106. return err;
  107. }
  108. if (copy)
  109. free(copy);
  110. index++;
  111. }
  112. offset = fdt_path_offset(src, node);
  113. if (offset < 0) {
  114. debug("failed to find source offset for %s: %s\n", node,
  115. fdt_strerror(err));
  116. return err;
  117. }
  118. prop = fdt_getprop(src, offset, names, &len);
  119. if (prop) {
  120. offset = fdt_path_offset(dst, node);
  121. if (offset < 0) {
  122. debug("failed to find destination offset for %s: %s\n",
  123. node, fdt_strerror(err));
  124. return err;
  125. }
  126. err = fdt_setprop(dst, offset, "memory-region-names", prop,
  127. len);
  128. if (err < 0) {
  129. debug("failed to copy \"%s\" property: %s\n", names,
  130. fdt_strerror(err));
  131. return err;
  132. }
  133. }
  134. return 0;
  135. }
  136. void ft_carveout_setup(void *fdt, const char * const *nodes, unsigned int count)
  137. {
  138. const void *cboot_fdt = (const void *)cboot_boot_x0;
  139. unsigned int i;
  140. int err;
  141. for (i = 0; i < count; i++) {
  142. printf("copying carveout for %s...\n", nodes[i]);
  143. err = ft_copy_carveout(fdt, cboot_fdt, nodes[i]);
  144. if (err < 0) {
  145. if (err != -FDT_ERR_NOTFOUND)
  146. printf("failed to copy carveout for %s: %d\n",
  147. nodes[i], err);
  148. continue;
  149. }
  150. }
  151. }
  152. #endif