blob: dcedbbb30830a98f0fbec268fb21080e57e21ba3 [file] [log] [blame]
Stefan Roese4f14ed62007-10-05 17:07:50 +02001/*
2 * (C) Copyright 2007
3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/* define DEBUG for debugging output (obviously ;-)) */
25#if 0
26#define DEBUG
27#endif
28
29#include <common.h>
30#include <watchdog.h>
31#include <command.h>
32#include <asm/cache.h>
33#include <ppc4xx.h>
34
35#if defined(CONFIG_OF_LIBFDT)
36#include <libfdt.h>
37#include <libfdt_env.h>
38
Stefan Roesef10493c2007-10-23 11:31:05 +020039DECLARE_GLOBAL_DATA_PTR;
40
Stefan Roese4f14ed62007-10-05 17:07:50 +020041static void do_fixup(void *fdt, const char *node, const char *prop,
42 const void *val, int len, int create)
43{
44#if defined(DEBUG)
45 int i;
46 debug("Updating property '%s/%s' = ", node, prop);
47 for (i = 0; i < len; i++)
48 debug(" %.2x", *(u8*)(val+i));
Stefan Roesef10493c2007-10-23 11:31:05 +020049 debug("(%d)\n", *(u32 *)val);
Stefan Roese4f14ed62007-10-05 17:07:50 +020050#endif
51 int rc = fdt_find_and_setprop(fdt, node, prop, val, len, create);
52 if (rc)
53 printf("Unable to update property %s:%s, err=%s\n",
54 node, prop, fdt_strerror(rc));
55}
56
57static void do_fixup_macaddr(void *fdt, int offset, const void *val, int i)
58{
59 int rc;
60
61 debug("Updating node EMAC%d\n", i);
62
63 rc = fdt_setprop(fdt, offset, "mac-address", val, 6);
64 if (rc)
65 printf("Unable to update property %s, err=%s\n",
66 "mac-address", fdt_strerror(rc));
67 rc = fdt_setprop(fdt, offset, "local-mac-address", val, 6);
68 if (rc)
69 printf("Unable to update property %s, err=%s\n",
70 "local-mac-address", fdt_strerror(rc));
71}
72
73static void do_fixup_u32(void *fdt, const char *node, const char *prop,
74 u32 val, int create)
75{
76 val = cpu_to_fdt32(val);
77 do_fixup(fdt, node, prop, &val, sizeof(val), create);
78}
79
80static void do_fixup_uart(void *fdt, int offset, int i, bd_t *bd)
81{
82 int rc;
83 u32 val;
Stefan Roesefa8aea22007-10-22 07:33:52 +020084 PPC4xx_SYS_INFO sys_info;
85
86 get_sys_info(&sys_info);
Stefan Roese4f14ed62007-10-05 17:07:50 +020087
Stefan Roesef10493c2007-10-23 11:31:05 +020088 debug("Updating node UART%d: clock-frequency=%d\n", i, gd->uart_clk);
Stefan Roese4f14ed62007-10-05 17:07:50 +020089
Stefan Roesef10493c2007-10-23 11:31:05 +020090 val = cpu_to_fdt32(gd->uart_clk);
Stefan Roese4f14ed62007-10-05 17:07:50 +020091 rc = fdt_setprop(fdt, offset, "clock-frequency", &val, 4);
92 if (rc)
93 printf("Unable to update node UART, err=%s\n", fdt_strerror(rc));
94
95 val = cpu_to_fdt32(bd->bi_baudrate);
96 rc = fdt_setprop(fdt, offset, "current-speed", &val, 4);
97 if (rc)
98 printf("Unable to update node UART, err=%s\n", fdt_strerror(rc));
99}
100
101void ft_cpu_setup(void *blob, bd_t *bd)
102{
103 char * cpu_path = "/cpus/" OF_CPU;
104 sys_info_t sys_info;
105 int offset;
106 int i;
107 int tmp[2];
108
109 get_sys_info (&sys_info);
110
111 do_fixup_u32(blob, cpu_path, "timebase-frequency", bd->bi_intfreq, 1);
112 do_fixup_u32(blob, cpu_path, "clock-frequency", bd->bi_intfreq, 1);
113 do_fixup_u32(blob, "/plb", "clock-frequency", sys_info.freqPLB, 1);
114 do_fixup_u32(blob, "/plb/opb", "clock-frequency", sys_info.freqOPB, 1);
115 do_fixup_u32(blob, "/plb/opb/ebc", "clock-frequency", sys_info.freqEBC, 1);
116
117 /* update, or add and update /memory node */
118 offset = fdt_find_node_by_path(blob, "/memory");
119 if (offset < 0) {
120 offset = fdt_add_subnode(blob, 0, "memory");
121 if (offset < 0)
122 debug("failed to add /memory node: %s\n",
123 fdt_strerror(offset));
124 }
125 if (offset >= 0) {
126 fdt_setprop(blob, offset, "device_type",
127 "memory", sizeof("memory"));
128 tmp[0] = cpu_to_fdt32(bd->bi_memstart);
129 tmp[1] = cpu_to_fdt32(bd->bi_memsize);
130 fdt_setprop(blob, offset, "reg", tmp, sizeof(tmp));
Stefan Roese4994ffd2007-10-11 11:11:45 +0200131 debug("Updating /memory node to %d:%d\n",
132 bd->bi_memstart, bd->bi_memsize);
Stefan Roese4f14ed62007-10-05 17:07:50 +0200133 }
134
135 /*
136 * Setup all baudrates for the UARTs
137 */
138 offset = 0;
139 for (i = 0; i < 4; i++) {
140 offset = fdt_find_node_by_type(blob, offset, "serial");
141 if (offset < 0)
142 break;
143
144 do_fixup_uart(blob, offset, i, bd);
145 }
146
147 /*
148 * Setup all MAC addresses in fdt
149 */
150 offset = 0;
151 for (i = 0; i < 4; i++) {
152 offset = fdt_find_node_by_type(blob, offset, "network");
153 if (offset < 0)
154 break;
155
156 switch (i) {
157 case 0:
158 do_fixup_macaddr(blob, offset, bd->bi_enetaddr, 0);
159 break;
160#ifdef CONFIG_HAS_ETH1
161 case 1:
162 do_fixup_macaddr(blob, offset, bd->bi_enet1addr, 1);
163 break;
164#endif
165#ifdef CONFIG_HAS_ETH2
166 case 2:
167 do_fixup_macaddr(blob, offset, bd->bi_enet2addr, 2);
168 break;
169#endif
170#ifdef CONFIG_HAS_ETH3
171 case 3:
172 do_fixup_macaddr(blob, offset, bd->bi_enet3addr, 3);
173 break;
174#endif
175 }
176 }
177}
178#endif /* CONFIG_OF_LIBFDT */