1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright (C) 2019 Socionext Inc.
4 //   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
5 
6 #include <dm/of.h>
7 #include <fdt_support.h>
8 #include <linux/errno.h>
9 #include <linux/io.h>
10 #include <linux/libfdt.h>
11 #include <linux/sizes.h>
12 #include <asm/global_data.h>
13 
14 #include "base-address.h"
15 #include "sc64-regs.h"
16 #include "sg-regs.h"
17 
18 /*
19  * Dummy initializers are needed to allocate these to .data section instead of
20  * .bss section. The .bss section is unusable before relocation because the
21  * .bss section and DT share the same address. Without the initializers,
22  * DT would be broken.
23  */
24 void __iomem *sc_base = (void *)0xdeadbeef;
25 void __iomem *sg_base = (void *)0xdeadbeef;
26 
uniphier_base_address_get(const char * compat_tail)27 static u64 uniphier_base_address_get(const char *compat_tail)
28 {
29 	DECLARE_GLOBAL_DATA_PTR;
30 	const void *fdt = gd->fdt_blob;
31 	int offset, len, i;
32 	const char *str;
33 
34 	for (offset = fdt_next_node(fdt, 0, NULL);
35 	     offset >= 0;
36 	     offset = fdt_next_node(fdt, offset, NULL)) {
37 		for (i = 0;
38 		     (str = fdt_stringlist_get(fdt, offset, "compatible", i, &len));
39 		     i++) {
40 			if (!memcmp(compat_tail,
41 				    str + len - strlen(compat_tail),
42 				    strlen(compat_tail)))
43 				return fdt_get_base_address(fdt, offset);
44 		}
45 	}
46 
47 	return OF_BAD_ADDR;
48 }
49 
uniphier_base_address_init(void)50 int uniphier_base_address_init(void)
51 {
52 	u64 base;
53 
54 	base = uniphier_base_address_get("-soc-glue");
55 	if (base == OF_BAD_ADDR)
56 		return -EINVAL;
57 
58 	sg_base = ioremap(base, SZ_8K);
59 
60 	base = uniphier_base_address_get("-sysctrl");
61 	if (base == OF_BAD_ADDR)
62 		return -EINVAL;
63 
64 	sc_base = ioremap(base, SZ_64K);
65 
66 	return 0;
67 }
68