cuboot-tl-wdr4900-v1.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * U-Boot compatibility wrapper for the TP-Link TL-WDR4900 v1 board
  3. *
  4. * Copyright (c) 2013 Gabor Juhos <juhosg@openwrt.org>
  5. *
  6. * Based on:
  7. * cuboot-85xx.c
  8. * Author: Scott Wood <scottwood@freescale.com>
  9. * Copyright (c) 2007 Freescale Semiconductor, Inc.
  10. *
  11. * simpleboot.c
  12. * Authors: Scott Wood <scottwood@freescale.com>
  13. * Grant Likely <grant.likely@secretlab.ca>
  14. * Copyright (c) 2007 Freescale Semiconductor, Inc.
  15. * Copyright (c) 2008 Secret Lab Technologies Ltd.
  16. *
  17. * This program is free software; you can redistribute it and/or modify it
  18. * under the terms of the GNU General Public License version 2 as published
  19. * by the Free Software Foundation.
  20. */
  21. #include "ops.h"
  22. #include "types.h"
  23. #include "io.h"
  24. #include "stdio.h"
  25. #include <libfdt.h>
  26. BSS_STACK(4*1024);
  27. static unsigned long bus_freq;
  28. static unsigned long int_freq;
  29. static u64 mem_size;
  30. static unsigned char enetaddr[6];
  31. static void process_boot_dtb(void *boot_dtb)
  32. {
  33. const u32 *na, *ns, *reg, *val32;
  34. const char *path;
  35. u64 memsize64;
  36. int node, size, i;
  37. /* Make sure FDT blob is sane */
  38. if (fdt_check_header(boot_dtb) != 0)
  39. fatal("Invalid device tree blob\n");
  40. /* Find the #address-cells and #size-cells properties */
  41. node = fdt_path_offset(boot_dtb, "/");
  42. if (node < 0)
  43. fatal("Cannot find root node\n");
  44. na = fdt_getprop(boot_dtb, node, "#address-cells", &size);
  45. if (!na || (size != 4))
  46. fatal("Cannot find #address-cells property");
  47. ns = fdt_getprop(boot_dtb, node, "#size-cells", &size);
  48. if (!ns || (size != 4))
  49. fatal("Cannot find #size-cells property");
  50. /* Find the memory range */
  51. node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type",
  52. "memory", sizeof("memory"));
  53. if (node < 0)
  54. fatal("Cannot find memory node\n");
  55. reg = fdt_getprop(boot_dtb, node, "reg", &size);
  56. if (size < (*na+*ns) * sizeof(u32))
  57. fatal("cannot get memory range\n");
  58. /* Only interested in memory based at 0 */
  59. for (i = 0; i < *na; i++)
  60. if (*reg++ != 0)
  61. fatal("Memory range is not based at address 0\n");
  62. /* get the memsize and trucate it to under 4G on 32 bit machines */
  63. memsize64 = 0;
  64. for (i = 0; i < *ns; i++)
  65. memsize64 = (memsize64 << 32) | *reg++;
  66. if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL)
  67. memsize64 = 0xffffffff;
  68. mem_size = memsize64;
  69. /* get clock frequencies */
  70. node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type",
  71. "cpu", sizeof("cpu"));
  72. if (!node)
  73. fatal("Cannot find cpu node\n");
  74. val32 = fdt_getprop(boot_dtb, node, "clock-frequency", &size);
  75. if (!val32 || (size != 4))
  76. fatal("Cannot get clock frequency");
  77. int_freq = *val32;
  78. val32 = fdt_getprop(boot_dtb, node, "bus-frequency", &size);
  79. if (!val32 || (size != 4))
  80. fatal("Cannot get bus frequency");
  81. bus_freq = *val32;
  82. path = fdt_get_alias(boot_dtb, "ethernet0");
  83. if (path) {
  84. const void *p;
  85. node = fdt_path_offset(boot_dtb, path);
  86. if (node < 0)
  87. fatal("Cannot find ethernet0 node");
  88. p = fdt_getprop(boot_dtb, node, "mac-address", &size);
  89. if (!p || (size < 6)) {
  90. printf("no mac-address property, finding local\n\r");
  91. p = fdt_getprop(boot_dtb, node, "local-mac-address", &size);
  92. }
  93. if (!p || (size < 6))
  94. fatal("cannot get MAC addres");
  95. memcpy(enetaddr, p, sizeof(enetaddr));
  96. }
  97. }
  98. static void platform_fixups(void)
  99. {
  100. void *soc, *mpic;
  101. dt_fixup_memory(0, mem_size);
  102. dt_fixup_mac_address_by_alias("ethernet0", enetaddr);
  103. dt_fixup_cpu_clocks(int_freq, bus_freq / 8, bus_freq);
  104. /* Unfortunately, the specific model number is encoded in the
  105. * soc node name in existing dts files -- once that is fixed,
  106. * this can do a simple path lookup.
  107. */
  108. soc = find_node_by_devtype(NULL, "soc");
  109. if (soc) {
  110. void *serial = NULL;
  111. setprop(soc, "bus-frequency", &bus_freq, sizeof(bus_freq));
  112. while ((serial = find_node_by_devtype(serial, "serial"))) {
  113. if (get_parent(serial) != soc)
  114. continue;
  115. setprop(serial, "clock-frequency", &bus_freq,
  116. sizeof(bus_freq));
  117. }
  118. }
  119. mpic = find_node_by_compatible(NULL, "fsl,mpic");
  120. if (mpic)
  121. setprop(mpic, "clock-frequency", &bus_freq, sizeof(bus_freq));
  122. }
  123. void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
  124. unsigned long r6, unsigned long r7)
  125. {
  126. mem_size = 64 * 1024 * 1024;
  127. simple_alloc_init(_end, mem_size - (u32)_end - 1024*1024, 32, 64);
  128. fdt_init(_dtb_start);
  129. serial_console_init();
  130. printf("\n\r-- TL-WDR4900 v1 boot wrapper --\n\r");
  131. process_boot_dtb((void *) r3);
  132. platform_ops.fixups = platform_fixups;
  133. }