1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2008-2011 Freescale Semiconductor, Inc.
4  */
5 
6 #include <common.h>
7 #include <linux/libfdt.h>
8 #include <fdt_support.h>
9 
10 #include <asm/processor.h>
11 #include <asm/io.h>
12 
13 #include <asm/fsl_portals.h>
14 #include <asm/fsl_liodn.h>
15 
16 /* Update portal containter to match LAW setup of portal in phy map */
17 void fdt_portal(void *blob, const char *compat, const char *container,
18 			u64 addr, u32 size)
19 {
20 	int off;
21 
22 	off = fdt_node_offset_by_compatible(blob, -1, compat);
23 	if (off < 0)
24 		return ;
25 
26 	off = fdt_parent_offset(blob, off);
27 	/* if non-zero assume we have a container */
28 	if (off > 0) {
29 		char buf[60];
30 		const char *p, *name;
31 		u32 *range;
32 		int len;
33 
34 		/* fixup ranges */
35 		range = fdt_getprop_w(blob, off, "ranges", &len);
36 		if (range == NULL) {
37 			printf("ERROR: container for %s has no ranges", compat);
38 			return ;
39 		}
40 
41 		range[0] = 0;
42 		if (len == 16) {
43 			range[1] = addr >> 32;
44 			range[2] = addr & 0xffffffff;
45 			range[3] = size;
46 		} else {
47 			range[1] = addr & 0xffffffff;
48 			range[2] = size;
49 		}
50 		fdt_setprop_inplace(blob, off, "ranges", range, len);
51 
52 		/* fixup the name */
53 		name = fdt_get_name(blob, off, &len);
54 		p = memchr(name, '@', len);
55 
56 		if (p)
57 			len = p - name;
58 
59 		/* if we are given a container name check it
60 		 * against what we found, if it doesnt match exit out */
61 		if (container && (memcmp(container, name, len))) {
62 			printf("WARNING: container names didn't match %s %s\n",
63 				container, name);
64 			return ;
65 		}
66 
67 		memcpy(&buf, name, len);
68 		len += sprintf(&buf[len], "@%llx", addr);
69 		fdt_set_name(blob, off, buf);
70 		return ;
71 	}
72 
73 	printf("ERROR: %s isn't in a container.  Not supported\n", compat);
74 }
75