1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/string.h> |
3 | #include <linux/kernel.h> |
4 | #include <linux/of.h> |
5 | #include <linux/init.h> |
6 | #include <linux/mod_devicetable.h> |
7 | #include <linux/slab.h> |
8 | #include <linux/errno.h> |
9 | #include <linux/irq.h> |
10 | #include <linux/of_platform.h> |
11 | #include <linux/platform_device.h> |
12 | #include <linux/dma-mapping.h> |
13 | #include <asm/leon.h> |
14 | #include <asm/leon_amba.h> |
15 | |
16 | #include "of_device_common.h" |
17 | #include "irq.h" |
18 | |
19 | /* |
20 | * PCI bus specific translator |
21 | */ |
22 | |
23 | static int of_bus_pci_match(struct device_node *np) |
24 | { |
25 | if (of_node_is_type(np, type: "pci" ) || of_node_is_type(np, type: "pciex" )) { |
26 | /* Do not do PCI specific frobbing if the |
27 | * PCI bridge lacks a ranges property. We |
28 | * want to pass it through up to the next |
29 | * parent as-is, not with the PCI translate |
30 | * method which chops off the top address cell. |
31 | */ |
32 | if (!of_property_present(np, propname: "ranges" )) |
33 | return 0; |
34 | |
35 | return 1; |
36 | } |
37 | |
38 | return 0; |
39 | } |
40 | |
41 | static void of_bus_pci_count_cells(struct device_node *np, |
42 | int *addrc, int *sizec) |
43 | { |
44 | if (addrc) |
45 | *addrc = 3; |
46 | if (sizec) |
47 | *sizec = 2; |
48 | } |
49 | |
50 | static int of_bus_pci_map(u32 *addr, const u32 *range, |
51 | int na, int ns, int pna) |
52 | { |
53 | u32 result[OF_MAX_ADDR_CELLS]; |
54 | int i; |
55 | |
56 | /* Check address type match */ |
57 | if ((addr[0] ^ range[0]) & 0x03000000) |
58 | return -EINVAL; |
59 | |
60 | if (of_out_of_range(addr: addr + 1, base: range + 1, size: range + na + pna, |
61 | na: na - 1, ns)) |
62 | return -EINVAL; |
63 | |
64 | /* Start with the parent range base. */ |
65 | memcpy(result, range + na, pna * 4); |
66 | |
67 | /* Add in the child address offset, skipping high cell. */ |
68 | for (i = 0; i < na - 1; i++) |
69 | result[pna - 1 - i] += |
70 | (addr[na - 1 - i] - |
71 | range[na - 1 - i]); |
72 | |
73 | memcpy(addr, result, pna * 4); |
74 | |
75 | return 0; |
76 | } |
77 | |
78 | static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags) |
79 | { |
80 | u32 w = addr[0]; |
81 | |
82 | /* For PCI, we override whatever child busses may have used. */ |
83 | flags = 0; |
84 | switch((w >> 24) & 0x03) { |
85 | case 0x01: |
86 | flags |= IORESOURCE_IO; |
87 | break; |
88 | |
89 | case 0x02: /* 32 bits */ |
90 | case 0x03: /* 64 bits */ |
91 | flags |= IORESOURCE_MEM; |
92 | break; |
93 | } |
94 | if (w & 0x40000000) |
95 | flags |= IORESOURCE_PREFETCH; |
96 | return flags; |
97 | } |
98 | |
99 | static unsigned long of_bus_sbus_get_flags(const u32 *addr, unsigned long flags) |
100 | { |
101 | return IORESOURCE_MEM; |
102 | } |
103 | |
104 | /* |
105 | * AMBAPP bus specific translator |
106 | */ |
107 | |
108 | static int of_bus_ambapp_match(struct device_node *np) |
109 | { |
110 | return of_node_is_type(np, type: "ambapp" ); |
111 | } |
112 | |
113 | static void of_bus_ambapp_count_cells(struct device_node *child, |
114 | int *addrc, int *sizec) |
115 | { |
116 | if (addrc) |
117 | *addrc = 1; |
118 | if (sizec) |
119 | *sizec = 1; |
120 | } |
121 | |
122 | static int of_bus_ambapp_map(u32 *addr, const u32 *range, |
123 | int na, int ns, int pna) |
124 | { |
125 | return of_bus_default_map(addr, range, na, ns, pna); |
126 | } |
127 | |
128 | static unsigned long of_bus_ambapp_get_flags(const u32 *addr, |
129 | unsigned long flags) |
130 | { |
131 | return IORESOURCE_MEM; |
132 | } |
133 | |
134 | /* |
135 | * Array of bus specific translators |
136 | */ |
137 | |
138 | static struct of_bus of_busses[] = { |
139 | /* PCI */ |
140 | { |
141 | .name = "pci" , |
142 | .addr_prop_name = "assigned-addresses" , |
143 | .match = of_bus_pci_match, |
144 | .count_cells = of_bus_pci_count_cells, |
145 | .map = of_bus_pci_map, |
146 | .get_flags = of_bus_pci_get_flags, |
147 | }, |
148 | /* SBUS */ |
149 | { |
150 | .name = "sbus" , |
151 | .addr_prop_name = "reg" , |
152 | .match = of_bus_sbus_match, |
153 | .count_cells = of_bus_sbus_count_cells, |
154 | .map = of_bus_default_map, |
155 | .get_flags = of_bus_sbus_get_flags, |
156 | }, |
157 | /* AMBA */ |
158 | { |
159 | .name = "ambapp" , |
160 | .addr_prop_name = "reg" , |
161 | .match = of_bus_ambapp_match, |
162 | .count_cells = of_bus_ambapp_count_cells, |
163 | .map = of_bus_ambapp_map, |
164 | .get_flags = of_bus_ambapp_get_flags, |
165 | }, |
166 | /* Default */ |
167 | { |
168 | .name = "default" , |
169 | .addr_prop_name = "reg" , |
170 | .match = NULL, |
171 | .count_cells = of_bus_default_count_cells, |
172 | .map = of_bus_default_map, |
173 | .get_flags = of_bus_default_get_flags, |
174 | }, |
175 | }; |
176 | |
177 | static struct of_bus *of_match_bus(struct device_node *np) |
178 | { |
179 | int i; |
180 | |
181 | for (i = 0; i < ARRAY_SIZE(of_busses); i ++) |
182 | if (!of_busses[i].match || of_busses[i].match(np)) |
183 | return &of_busses[i]; |
184 | BUG(); |
185 | return NULL; |
186 | } |
187 | |
188 | static int __init build_one_resource(struct device_node *parent, |
189 | struct of_bus *bus, |
190 | struct of_bus *pbus, |
191 | u32 *addr, |
192 | int na, int ns, int pna) |
193 | { |
194 | const u32 *ranges; |
195 | unsigned int rlen; |
196 | int rone; |
197 | |
198 | ranges = of_get_property(node: parent, name: "ranges" , lenp: &rlen); |
199 | if (ranges == NULL || rlen == 0) { |
200 | u32 result[OF_MAX_ADDR_CELLS]; |
201 | int i; |
202 | |
203 | memset(result, 0, pna * 4); |
204 | for (i = 0; i < na; i++) |
205 | result[pna - 1 - i] = |
206 | addr[na - 1 - i]; |
207 | |
208 | memcpy(addr, result, pna * 4); |
209 | return 0; |
210 | } |
211 | |
212 | /* Now walk through the ranges */ |
213 | rlen /= 4; |
214 | rone = na + pna + ns; |
215 | for (; rlen >= rone; rlen -= rone, ranges += rone) { |
216 | if (!bus->map(addr, ranges, na, ns, pna)) |
217 | return 0; |
218 | } |
219 | |
220 | return 1; |
221 | } |
222 | |
223 | static int __init use_1to1_mapping(struct device_node *pp) |
224 | { |
225 | /* If we have a ranges property in the parent, use it. */ |
226 | if (of_property_present(np: pp, propname: "ranges" )) |
227 | return 0; |
228 | |
229 | /* Some SBUS devices use intermediate nodes to express |
230 | * hierarchy within the device itself. These aren't |
231 | * real bus nodes, and don't have a 'ranges' property. |
232 | * But, we should still pass the translation work up |
233 | * to the SBUS itself. |
234 | */ |
235 | if (of_node_name_eq(np: pp, name: "dma" ) || |
236 | of_node_name_eq(np: pp, name: "espdma" ) || |
237 | of_node_name_eq(np: pp, name: "ledma" ) || |
238 | of_node_name_eq(np: pp, name: "lebuffer" )) |
239 | return 0; |
240 | |
241 | return 1; |
242 | } |
243 | |
244 | static int of_resource_verbose; |
245 | |
246 | static void __init build_device_resources(struct platform_device *op, |
247 | struct device *parent) |
248 | { |
249 | struct platform_device *p_op; |
250 | struct of_bus *bus; |
251 | int na, ns; |
252 | int index, num_reg; |
253 | const void *preg; |
254 | |
255 | if (!parent) |
256 | return; |
257 | |
258 | p_op = to_platform_device(parent); |
259 | bus = of_match_bus(np: p_op->dev.of_node); |
260 | bus->count_cells(op->dev.of_node, &na, &ns); |
261 | |
262 | preg = of_get_property(node: op->dev.of_node, name: bus->addr_prop_name, lenp: &num_reg); |
263 | if (!preg || num_reg == 0) |
264 | return; |
265 | |
266 | /* Convert to num-cells. */ |
267 | num_reg /= 4; |
268 | |
269 | /* Conver to num-entries. */ |
270 | num_reg /= na + ns; |
271 | |
272 | op->resource = op->archdata.resource; |
273 | op->num_resources = num_reg; |
274 | for (index = 0; index < num_reg; index++) { |
275 | struct resource *r = &op->resource[index]; |
276 | u32 addr[OF_MAX_ADDR_CELLS]; |
277 | const u32 *reg = (preg + (index * ((na + ns) * 4))); |
278 | struct device_node *dp = op->dev.of_node; |
279 | struct device_node *pp = p_op->dev.of_node; |
280 | struct of_bus *pbus, *dbus; |
281 | u64 size, result = OF_BAD_ADDR; |
282 | unsigned long flags; |
283 | int dna, dns; |
284 | int pna, pns; |
285 | |
286 | size = of_read_addr(cell: reg + na, size: ns); |
287 | |
288 | memcpy(addr, reg, na * 4); |
289 | |
290 | flags = bus->get_flags(reg, 0); |
291 | |
292 | if (use_1to1_mapping(pp)) { |
293 | result = of_read_addr(cell: addr, size: na); |
294 | goto build_res; |
295 | } |
296 | |
297 | dna = na; |
298 | dns = ns; |
299 | dbus = bus; |
300 | |
301 | while (1) { |
302 | dp = pp; |
303 | pp = dp->parent; |
304 | if (!pp) { |
305 | result = of_read_addr(cell: addr, size: dna); |
306 | break; |
307 | } |
308 | |
309 | pbus = of_match_bus(np: pp); |
310 | pbus->count_cells(dp, &pna, &pns); |
311 | |
312 | if (build_one_resource(parent: dp, bus: dbus, pbus, addr, |
313 | na: dna, ns: dns, pna)) |
314 | break; |
315 | |
316 | flags = pbus->get_flags(addr, flags); |
317 | |
318 | dna = pna; |
319 | dns = pns; |
320 | dbus = pbus; |
321 | } |
322 | |
323 | build_res: |
324 | memset(r, 0, sizeof(*r)); |
325 | |
326 | if (of_resource_verbose) |
327 | printk("%pOF reg[%d] -> %llx\n" , |
328 | op->dev.of_node, index, |
329 | result); |
330 | |
331 | if (result != OF_BAD_ADDR) { |
332 | r->start = result & 0xffffffff; |
333 | r->end = result + size - 1; |
334 | r->flags = flags | ((result >> 32ULL) & 0xffUL); |
335 | } |
336 | r->name = op->dev.of_node->full_name; |
337 | } |
338 | } |
339 | |
340 | static struct platform_device * __init scan_one_device(struct device_node *dp, |
341 | struct device *parent) |
342 | { |
343 | struct platform_device *op = kzalloc(size: sizeof(*op), GFP_KERNEL); |
344 | const struct linux_prom_irqs *intr; |
345 | struct dev_archdata *sd; |
346 | int len, i; |
347 | |
348 | if (!op) |
349 | return NULL; |
350 | |
351 | sd = &op->dev.archdata; |
352 | sd->op = op; |
353 | |
354 | op->dev.of_node = dp; |
355 | |
356 | intr = of_get_property(node: dp, name: "intr" , lenp: &len); |
357 | if (intr) { |
358 | op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs); |
359 | for (i = 0; i < op->archdata.num_irqs; i++) |
360 | op->archdata.irqs[i] = |
361 | sparc_config.build_device_irq(op, intr[i].pri); |
362 | } else { |
363 | const unsigned int *irq = |
364 | of_get_property(node: dp, name: "interrupts" , lenp: &len); |
365 | |
366 | if (irq) { |
367 | op->archdata.num_irqs = len / sizeof(unsigned int); |
368 | for (i = 0; i < op->archdata.num_irqs; i++) |
369 | op->archdata.irqs[i] = |
370 | sparc_config.build_device_irq(op, irq[i]); |
371 | } else { |
372 | op->archdata.num_irqs = 0; |
373 | } |
374 | } |
375 | |
376 | build_device_resources(op, parent); |
377 | |
378 | op->dev.parent = parent; |
379 | op->dev.bus = &platform_bus_type; |
380 | if (!parent) |
381 | dev_set_name(dev: &op->dev, name: "root" ); |
382 | else |
383 | dev_set_name(dev: &op->dev, name: "%08x" , dp->phandle); |
384 | |
385 | op->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
386 | op->dev.dma_mask = &op->dev.coherent_dma_mask; |
387 | |
388 | if (of_device_register(ofdev: op)) { |
389 | printk("%pOF: Could not register of device.\n" , dp); |
390 | kfree(objp: op); |
391 | op = NULL; |
392 | } |
393 | |
394 | return op; |
395 | } |
396 | |
397 | static void __init scan_tree(struct device_node *dp, struct device *parent) |
398 | { |
399 | while (dp) { |
400 | struct platform_device *op = scan_one_device(dp, parent); |
401 | |
402 | if (op) |
403 | scan_tree(dp: dp->child, parent: &op->dev); |
404 | |
405 | dp = dp->sibling; |
406 | } |
407 | } |
408 | |
409 | static int __init scan_of_devices(void) |
410 | { |
411 | struct device_node *root = of_find_node_by_path(path: "/" ); |
412 | struct platform_device *parent; |
413 | |
414 | parent = scan_one_device(dp: root, NULL); |
415 | if (!parent) |
416 | return 0; |
417 | |
418 | scan_tree(dp: root->child, parent: &parent->dev); |
419 | return 0; |
420 | } |
421 | postcore_initcall(scan_of_devices); |
422 | |
423 | static int __init of_debug(char *str) |
424 | { |
425 | int val = 0; |
426 | |
427 | get_option(str: &str, pint: &val); |
428 | if (val & 1) |
429 | of_resource_verbose = 1; |
430 | return 1; |
431 | } |
432 | |
433 | __setup("of_debug=" , of_debug); |
434 | |