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