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