Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / arch / arm / mach-uniphier / base-address.c
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
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
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 }