xref: /rk3399_rockchip-uboot/arch/arm/cpu/armv8/spin_table.c (revision 6b6024eadb96bc471643bd183fe940fb657bef83)
1*6b6024eaSMasahiro Yamada /*
2*6b6024eaSMasahiro Yamada  * Copyright (C) 2016 Socionext Inc.
3*6b6024eaSMasahiro Yamada  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4*6b6024eaSMasahiro Yamada  *
5*6b6024eaSMasahiro Yamada  * SPDX-License-Identifier:	GPL-2.0+
6*6b6024eaSMasahiro Yamada  */
7*6b6024eaSMasahiro Yamada 
8*6b6024eaSMasahiro Yamada #include <common.h>
9*6b6024eaSMasahiro Yamada #include <libfdt.h>
10*6b6024eaSMasahiro Yamada #include <asm/spin_table.h>
11*6b6024eaSMasahiro Yamada 
12*6b6024eaSMasahiro Yamada int spin_table_update_dt(void *fdt)
13*6b6024eaSMasahiro Yamada {
14*6b6024eaSMasahiro Yamada 	int cpus_offset, offset;
15*6b6024eaSMasahiro Yamada 	const char *prop;
16*6b6024eaSMasahiro Yamada 	int ret;
17*6b6024eaSMasahiro Yamada 	unsigned long rsv_addr = (unsigned long)&spin_table_reserve_begin;
18*6b6024eaSMasahiro Yamada 	unsigned long rsv_size = &spin_table_reserve_end -
19*6b6024eaSMasahiro Yamada 						&spin_table_reserve_begin;
20*6b6024eaSMasahiro Yamada 
21*6b6024eaSMasahiro Yamada 	cpus_offset = fdt_path_offset(fdt, "/cpus");
22*6b6024eaSMasahiro Yamada 	if (cpus_offset < 0)
23*6b6024eaSMasahiro Yamada 		return -ENODEV;
24*6b6024eaSMasahiro Yamada 
25*6b6024eaSMasahiro Yamada 	for (offset = fdt_first_subnode(fdt, cpus_offset);
26*6b6024eaSMasahiro Yamada 	     offset >= 0;
27*6b6024eaSMasahiro Yamada 	     offset = fdt_next_subnode(fdt, offset)) {
28*6b6024eaSMasahiro Yamada 		prop = fdt_getprop(fdt, offset, "device_type", NULL);
29*6b6024eaSMasahiro Yamada 		if (!prop || strcmp(prop, "cpu"))
30*6b6024eaSMasahiro Yamada 			continue;
31*6b6024eaSMasahiro Yamada 
32*6b6024eaSMasahiro Yamada 		/*
33*6b6024eaSMasahiro Yamada 		 * In the first loop, we check if every CPU node specifies
34*6b6024eaSMasahiro Yamada 		 * spin-table.  Otherwise, just return successfully to not
35*6b6024eaSMasahiro Yamada 		 * disturb other methods, like psci.
36*6b6024eaSMasahiro Yamada 		 */
37*6b6024eaSMasahiro Yamada 		prop = fdt_getprop(fdt, offset, "enable-method", NULL);
38*6b6024eaSMasahiro Yamada 		if (!prop || strcmp(prop, "spin-table"))
39*6b6024eaSMasahiro Yamada 			return 0;
40*6b6024eaSMasahiro Yamada 	}
41*6b6024eaSMasahiro Yamada 
42*6b6024eaSMasahiro Yamada 	for (offset = fdt_first_subnode(fdt, cpus_offset);
43*6b6024eaSMasahiro Yamada 	     offset >= 0;
44*6b6024eaSMasahiro Yamada 	     offset = fdt_next_subnode(fdt, offset)) {
45*6b6024eaSMasahiro Yamada 		prop = fdt_getprop(fdt, offset, "device_type", NULL);
46*6b6024eaSMasahiro Yamada 		if (!prop || strcmp(prop, "cpu"))
47*6b6024eaSMasahiro Yamada 			continue;
48*6b6024eaSMasahiro Yamada 
49*6b6024eaSMasahiro Yamada 		ret = fdt_setprop_u64(fdt, offset, "cpu-release-addr",
50*6b6024eaSMasahiro Yamada 				(unsigned long)&spin_table_cpu_release_addr);
51*6b6024eaSMasahiro Yamada 		if (ret)
52*6b6024eaSMasahiro Yamada 			return -ENOSPC;
53*6b6024eaSMasahiro Yamada 	}
54*6b6024eaSMasahiro Yamada 
55*6b6024eaSMasahiro Yamada 	ret = fdt_add_mem_rsv(fdt, rsv_addr, rsv_size);
56*6b6024eaSMasahiro Yamada 	if (ret)
57*6b6024eaSMasahiro Yamada 		return -ENOSPC;
58*6b6024eaSMasahiro Yamada 
59*6b6024eaSMasahiro Yamada 	printf("   Reserved memory region for spin-table: addr=%lx size=%lx\n",
60*6b6024eaSMasahiro Yamada 	       rsv_addr, rsv_size);
61*6b6024eaSMasahiro Yamada 
62*6b6024eaSMasahiro Yamada 	return 0;
63*6b6024eaSMasahiro Yamada }
64