aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorChristian Krafft <krafft@de.ibm.com>2007-04-23 15:35:46 -0400
committerArnd Bergmann <arnd@klappe.arndb.de>2007-04-23 15:44:40 -0400
commit9dd855a729abb4670522d5eae6854db48d624498 (patch)
tree686c5e26fc68b16822df87308d553981908d295e /arch
parent6bf05fd776e38a0a9c17e17c2345b59b1b9aa2cb (diff)
[POWERPC] cell: add support for proper device-tree
This patch adds support for a proper device-tree. A porper device-tree on cell contains be nodes for each CBE containg nodes for SPEs and all the other special devices on it. Ofcourse oldschool devicetree is still supported. Signed-off-by: Christian Krafft <krafft@de.ibm.com> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/cell/cbe_regs.c118
1 files changed, 88 insertions, 30 deletions
diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c
index dca39c0af7ea..12c9674b4b1f 100644
--- a/arch/powerpc/platforms/cell/cbe_regs.c
+++ b/arch/powerpc/platforms/cell/cbe_regs.c
@@ -14,6 +14,8 @@
14#include <asm/pgtable.h> 14#include <asm/pgtable.h>
15#include <asm/prom.h> 15#include <asm/prom.h>
16#include <asm/ptrace.h> 16#include <asm/ptrace.h>
17#include <asm/of_device.h>
18#include <asm/of_platform.h>
17 19
18#include "cbe_regs.h" 20#include "cbe_regs.h"
19 21
@@ -27,6 +29,7 @@
27static struct cbe_regs_map 29static struct cbe_regs_map
28{ 30{
29 struct device_node *cpu_node; 31 struct device_node *cpu_node;
32 struct device_node *be_node;
30 struct cbe_pmd_regs __iomem *pmd_regs; 33 struct cbe_pmd_regs __iomem *pmd_regs;
31 struct cbe_iic_regs __iomem *iic_regs; 34 struct cbe_iic_regs __iomem *iic_regs;
32 struct cbe_mic_tm_regs __iomem *mic_tm_regs; 35 struct cbe_mic_tm_regs __iomem *mic_tm_regs;
@@ -37,6 +40,7 @@ static int cbe_regs_map_count;
37static struct cbe_thread_map 40static struct cbe_thread_map
38{ 41{
39 struct device_node *cpu_node; 42 struct device_node *cpu_node;
43 struct device_node *be_node;
40 struct cbe_regs_map *regs; 44 struct cbe_regs_map *regs;
41 unsigned int thread_id; 45 unsigned int thread_id;
42 unsigned int cbe_id; 46 unsigned int cbe_id;
@@ -50,22 +54,29 @@ static struct cbe_regs_map *cbe_find_map(struct device_node *np)
50 int i; 54 int i;
51 struct device_node *tmp_np; 55 struct device_node *tmp_np;
52 56
53 if (strcasecmp(np->type, "spe") == 0) { 57 if (strcasecmp(np->type, "spe")) {
54 if (np->data == NULL) { 58 for (i = 0; i < cbe_regs_map_count; i++)
55 /* walk up path until cpu node was found */ 59 if (cbe_regs_maps[i].cpu_node == np ||
56 tmp_np = np->parent; 60 cbe_regs_maps[i].be_node == np)
57 while (tmp_np != NULL && strcasecmp(tmp_np->type, "cpu") != 0) 61 return &cbe_regs_maps[i];
58 tmp_np = tmp_np->parent; 62 return NULL;
63 }
59 64
60 np->data = cbe_find_map(tmp_np); 65 if (np->data)
61 }
62 return np->data; 66 return np->data;
63 }
64 67
65 for (i = 0; i < cbe_regs_map_count; i++) 68 /* walk up path until cpu or be node was found */
66 if (cbe_regs_maps[i].cpu_node == np) 69 tmp_np = np;
67 return &cbe_regs_maps[i]; 70 do {
68 return NULL; 71 tmp_np = tmp_np->parent;
72 /* on a correct devicetree we wont get up to root */
73 BUG_ON(!tmp_np);
74 } while (strcasecmp(tmp_np->type, "cpu") &&
75 strcasecmp(tmp_np->type, "be"));
76
77 np->data = cbe_find_map(tmp_np);
78
79 return np->data;
69} 80}
70 81
71struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np) 82struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np)
@@ -153,6 +164,67 @@ u32 cbe_node_to_cpu(int node)
153} 164}
154EXPORT_SYMBOL_GPL(cbe_node_to_cpu); 165EXPORT_SYMBOL_GPL(cbe_node_to_cpu);
155 166
167static struct device_node *cbe_get_be_node(int cpu_id)
168{
169 struct device_node *np;
170
171 for_each_node_by_type (np, "be") {
172 int len,i;
173 const phandle *cpu_handle;
174
175 cpu_handle = of_get_property(np, "cpus", &len);
176
177 for (i=0; i<len; i++)
178 if (of_find_node_by_phandle(cpu_handle[i]) == of_get_cpu_node(cpu_id, NULL))
179 return np;
180 }
181
182 return NULL;
183}
184
185void __init cbe_fill_regs_map(struct cbe_regs_map *map)
186{
187 if(map->be_node) {
188 struct device_node *be, *np;
189
190 be = map->be_node;
191
192 for_each_node_by_type(np, "pervasive")
193 if (of_get_parent(np) == be)
194 map->pmd_regs = of_iomap(np, 0);
195
196 for_each_node_by_type(np, "CBEA-Internal-Interrupt-Controller")
197 if (of_get_parent(np) == be)
198 map->iic_regs = of_iomap(np, 2);
199
200 for_each_node_by_type(np, "mic-tm")
201 if (of_get_parent(np) == be)
202 map->mic_tm_regs = of_iomap(np, 0);
203 } else {
204 struct device_node *cpu;
205 /* That hack must die die die ! */
206 const struct address_prop {
207 unsigned long address;
208 unsigned int len;
209 } __attribute__((packed)) *prop;
210
211 cpu = map->cpu_node;
212
213 prop = of_get_property(cpu, "pervasive", NULL);
214 if (prop != NULL)
215 map->pmd_regs = ioremap(prop->address, prop->len);
216
217 prop = of_get_property(cpu, "iic", NULL);
218 if (prop != NULL)
219 map->iic_regs = ioremap(prop->address, prop->len);
220
221 prop = of_get_property(cpu, "mic-tm", NULL);
222 if (prop != NULL)
223 map->mic_tm_regs = ioremap(prop->address, prop->len);
224 }
225}
226
227
156void __init cbe_regs_init(void) 228void __init cbe_regs_init(void)
157{ 229{
158 int i; 230 int i;
@@ -162,6 +234,7 @@ void __init cbe_regs_init(void)
162 /* Build local fast map of CPUs */ 234 /* Build local fast map of CPUs */
163 for_each_possible_cpu(i) { 235 for_each_possible_cpu(i) {
164 cbe_thread_map[i].cpu_node = of_get_cpu_node(i, &thread_id); 236 cbe_thread_map[i].cpu_node = of_get_cpu_node(i, &thread_id);
237 cbe_thread_map[i].be_node = cbe_get_be_node(i);
165 cbe_thread_map[i].thread_id = thread_id; 238 cbe_thread_map[i].thread_id = thread_id;
166 } 239 }
167 240
@@ -170,12 +243,6 @@ void __init cbe_regs_init(void)
170 struct cbe_regs_map *map; 243 struct cbe_regs_map *map;
171 unsigned int cbe_id; 244 unsigned int cbe_id;
172 245
173 /* That hack must die die die ! */
174 const struct address_prop {
175 unsigned long address;
176 unsigned int len;
177 } __attribute__((packed)) *prop;
178
179 cbe_id = cbe_regs_map_count++; 246 cbe_id = cbe_regs_map_count++;
180 map = &cbe_regs_maps[cbe_id]; 247 map = &cbe_regs_maps[cbe_id];
181 248
@@ -193,23 +260,14 @@ void __init cbe_regs_init(void)
193 if (thread->cpu_node == cpu) { 260 if (thread->cpu_node == cpu) {
194 thread->regs = map; 261 thread->regs = map;
195 thread->cbe_id = cbe_id; 262 thread->cbe_id = cbe_id;
263 map->be_node = thread->be_node;
196 cpu_set(i, cbe_local_mask[cbe_id]); 264 cpu_set(i, cbe_local_mask[cbe_id]);
197 if(thread->thread_id == 0) 265 if(thread->thread_id == 0)
198 cpu_set(i, cbe_first_online_cpu); 266 cpu_set(i, cbe_first_online_cpu);
199 } 267 }
200 } 268 }
201 269
202 prop = of_get_property(cpu, "pervasive", NULL); 270 cbe_fill_regs_map(map);
203 if (prop != NULL)
204 map->pmd_regs = ioremap(prop->address, prop->len);
205
206 prop = of_get_property(cpu, "iic", NULL);
207 if (prop != NULL)
208 map->iic_regs = ioremap(prop->address, prop->len);
209
210 prop = of_get_property(cpu, "mic-tm", NULL);
211 if (prop != NULL)
212 map->mic_tm_regs = ioremap(prop->address, prop->len);
213 } 271 }
214} 272}
215 273