OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 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 | |||
22 | #include "ops.h" |
||
23 | #include "types.h" |
||
24 | #include "io.h" |
||
25 | #include "stdio.h" |
||
26 | #include <libfdt.h> |
||
27 | |||
28 | BSS_STACK(4*1024); |
||
29 | |||
30 | static unsigned long bus_freq; |
||
31 | static unsigned long int_freq; |
||
32 | static u64 mem_size; |
||
33 | static unsigned char enetaddr[6]; |
||
34 | |||
35 | static void process_boot_dtb(void *boot_dtb) |
||
36 | { |
||
37 | const u32 *na, *ns, *reg, *val32; |
||
38 | const char *path; |
||
39 | u64 memsize64; |
||
40 | int node, size, i; |
||
41 | |||
42 | /* Make sure FDT blob is sane */ |
||
43 | if (fdt_check_header(boot_dtb) != 0) |
||
44 | fatal("Invalid device tree blob\n"); |
||
45 | |||
46 | /* Find the #address-cells and #size-cells properties */ |
||
47 | node = fdt_path_offset(boot_dtb, "/"); |
||
48 | if (node < 0) |
||
49 | fatal("Cannot find root node\n"); |
||
50 | na = fdt_getprop(boot_dtb, node, "#address-cells", &size); |
||
51 | if (!na || (size != 4)) |
||
52 | fatal("Cannot find #address-cells property"); |
||
53 | |||
54 | ns = fdt_getprop(boot_dtb, node, "#size-cells", &size); |
||
55 | if (!ns || (size != 4)) |
||
56 | fatal("Cannot find #size-cells property"); |
||
57 | |||
58 | /* Find the memory range */ |
||
59 | node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type", |
||
60 | "memory", sizeof("memory")); |
||
61 | if (node < 0) |
||
62 | fatal("Cannot find memory node\n"); |
||
63 | reg = fdt_getprop(boot_dtb, node, "reg", &size); |
||
64 | if (size < (*na+*ns) * sizeof(u32)) |
||
65 | fatal("cannot get memory range\n"); |
||
66 | |||
67 | /* Only interested in memory based at 0 */ |
||
68 | for (i = 0; i < *na; i++) |
||
69 | if (*reg++ != 0) |
||
70 | fatal("Memory range is not based at address 0\n"); |
||
71 | |||
72 | /* get the memsize and trucate it to under 4G on 32 bit machines */ |
||
73 | memsize64 = 0; |
||
74 | for (i = 0; i < *ns; i++) |
||
75 | memsize64 = (memsize64 << 32) | *reg++; |
||
76 | if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL) |
||
77 | memsize64 = 0xffffffff; |
||
78 | |||
79 | mem_size = memsize64; |
||
80 | |||
81 | /* get clock frequencies */ |
||
82 | node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type", |
||
83 | "cpu", sizeof("cpu")); |
||
84 | if (!node) |
||
85 | fatal("Cannot find cpu node\n"); |
||
86 | |||
87 | val32 = fdt_getprop(boot_dtb, node, "clock-frequency", &size); |
||
88 | if (!val32 || (size != 4)) |
||
89 | fatal("Cannot get clock frequency"); |
||
90 | |||
91 | int_freq = *val32; |
||
92 | |||
93 | val32 = fdt_getprop(boot_dtb, node, "bus-frequency", &size); |
||
94 | if (!val32 || (size != 4)) |
||
95 | fatal("Cannot get bus frequency"); |
||
96 | |||
97 | bus_freq = *val32; |
||
98 | |||
99 | path = fdt_get_alias(boot_dtb, "ethernet0"); |
||
100 | if (path) { |
||
101 | const void *p; |
||
102 | |||
103 | node = fdt_path_offset(boot_dtb, path); |
||
104 | if (node < 0) |
||
105 | fatal("Cannot find ethernet0 node"); |
||
106 | |||
107 | p = fdt_getprop(boot_dtb, node, "mac-address", &size); |
||
108 | if (!p || (size < 6)) { |
||
109 | printf("no mac-address property, finding local\n\r"); |
||
110 | p = fdt_getprop(boot_dtb, node, "local-mac-address", &size); |
||
111 | } |
||
112 | |||
113 | if (!p || (size < 6)) |
||
114 | fatal("cannot get MAC addres"); |
||
115 | |||
116 | memcpy(enetaddr, p, sizeof(enetaddr)); |
||
117 | } |
||
118 | } |
||
119 | |||
120 | static void platform_fixups(void) |
||
121 | { |
||
122 | void *soc, *mpic; |
||
123 | |||
124 | dt_fixup_memory(0, mem_size); |
||
125 | |||
126 | dt_fixup_mac_address_by_alias("ethernet0", enetaddr); |
||
127 | dt_fixup_cpu_clocks(int_freq, bus_freq / 8, bus_freq); |
||
128 | |||
129 | /* Unfortunately, the specific model number is encoded in the |
||
130 | * soc node name in existing dts files -- once that is fixed, |
||
131 | * this can do a simple path lookup. |
||
132 | */ |
||
133 | soc = find_node_by_devtype(NULL, "soc"); |
||
134 | if (soc) { |
||
135 | void *serial = NULL; |
||
136 | |||
137 | setprop(soc, "bus-frequency", &bus_freq, sizeof(bus_freq)); |
||
138 | |||
139 | while ((serial = find_node_by_devtype(serial, "serial"))) { |
||
140 | if (get_parent(serial) != soc) |
||
141 | continue; |
||
142 | |||
143 | setprop(serial, "clock-frequency", &bus_freq, |
||
144 | sizeof(bus_freq)); |
||
145 | } |
||
146 | } |
||
147 | |||
148 | mpic = find_node_by_compatible(NULL, "fsl,mpic"); |
||
149 | if (mpic) |
||
150 | setprop(mpic, "clock-frequency", &bus_freq, sizeof(bus_freq)); |
||
151 | } |
||
152 | |||
153 | void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, |
||
154 | unsigned long r6, unsigned long r7) |
||
155 | { |
||
156 | mem_size = 64 * 1024 * 1024; |
||
157 | |||
158 | simple_alloc_init(_end, mem_size - (u32)_end - 1024*1024, 32, 64); |
||
159 | |||
160 | fdt_init(_dtb_start); |
||
161 | serial_console_init(); |
||
162 | |||
163 | printf("\n\r-- TL-WDR4900 v1 boot wrapper --\n\r"); |
||
164 | |||
165 | process_boot_dtb((void *) r3); |
||
166 | |||
167 | platform_ops.fixups = platform_fixups; |
||
168 | } |