ARM: tegra: Copy memory-region-names property
[platform/kernel/u-boot.git] / arch / arm / mach-tegra / dt-setup.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2010-2016, NVIDIA CORPORATION.
4  */
5
6 #include <common.h>
7 #include <fdtdec.h>
8 #include <stdlib.h>
9 #include <asm/arch-tegra/cboot.h>
10 #include <asm/arch-tegra/gpu.h>
11
12 /*
13  * This function is called right before the kernel is booted. "blob" is the
14  * device tree that will be passed to the kernel.
15  */
16 int ft_system_setup(void *blob, struct bd_info *bd)
17 {
18         const char *gpu_compats[] = {
19 #if defined(CONFIG_TEGRA124)
20                 "nvidia,gk20a",
21 #endif
22 #if defined(CONFIG_TEGRA210)
23                 "nvidia,gm20b",
24 #endif
25         };
26         int i, ret;
27
28         /* Enable GPU node if GPU setup has been performed */
29         for (i = 0; i < ARRAY_SIZE(gpu_compats); i++) {
30                 ret = tegra_gpu_enable_node(blob, gpu_compats[i]);
31                 if (ret)
32                         return ret;
33         }
34
35         return 0;
36 }
37
38 #if defined(CONFIG_ARM64)
39 void ft_mac_address_setup(void *fdt)
40 {
41         const void *cboot_fdt = (const void *)cboot_boot_x0;
42         uint8_t mac[ETH_ALEN], local_mac[ETH_ALEN];
43         const char *path;
44         int offset, err;
45
46         err = cboot_get_ethaddr(cboot_fdt, local_mac);
47         if (err < 0)
48                 memset(local_mac, 0, ETH_ALEN);
49
50         path = fdt_get_alias(fdt, "ethernet");
51         if (!path)
52                 return;
53
54         debug("ethernet alias found: %s\n", path);
55
56         offset = fdt_path_offset(fdt, path);
57         if (offset < 0) {
58                 printf("ethernet alias points to absent node %s\n", path);
59                 return;
60         }
61
62         if (is_valid_ethaddr(local_mac)) {
63                 err = fdt_setprop(fdt, offset, "local-mac-address", local_mac,
64                                   ETH_ALEN);
65                 if (!err)
66                         debug("Local MAC address set: %pM\n", local_mac);
67         }
68
69         if (eth_env_get_enetaddr("ethaddr", mac)) {
70                 if (memcmp(local_mac, mac, ETH_ALEN) != 0) {
71                         err = fdt_setprop(fdt, offset, "mac-address", mac,
72                                           ETH_ALEN);
73                         if (!err)
74                                 debug("MAC address set: %pM\n", mac);
75                 }
76         }
77 }
78
79 static int ft_copy_carveout(void *dst, const void *src, const char *node)
80 {
81         const char *names = "memory-region-names";
82         struct fdt_memory carveout;
83         unsigned int index = 0;
84         int err, offset, len;
85         const void *prop;
86
87         while (true) {
88                 const char **compatibles = NULL;
89                 unsigned int num_compatibles;
90                 unsigned long flags;
91                 char *copy = NULL;
92                 const char *name;
93
94                 err = fdtdec_get_carveout(src, node, "memory-region", index,
95                                           &carveout, &name, &compatibles,
96                                           &num_compatibles, &flags);
97                 if (err < 0) {
98                         if (err != -FDT_ERR_NOTFOUND)
99                                 printf("failed to get carveout for %s: %d\n",
100                                        node, err);
101                         else
102                                 break;
103
104                         return err;
105                 }
106
107                 if (name) {
108                         const char *ptr = strchr(name, '@');
109
110                         if (ptr) {
111                                 copy = strndup(name, ptr - name);
112                                 name = copy;
113                         }
114                 } else {
115                         name = "carveout";
116                 }
117
118                 err = fdtdec_set_carveout(dst, node, "memory-region", index,
119                                           &carveout, name, compatibles,
120                                           num_compatibles, flags);
121                 if (err < 0) {
122                         printf("failed to set carveout for %s: %d\n", node,
123                                err);
124                         return err;
125                 }
126
127                 if (copy)
128                         free(copy);
129
130                 index++;
131         }
132
133         offset = fdt_path_offset(src, node);
134         if (offset < 0) {
135                 debug("failed to find source offset for %s: %s\n", node,
136                       fdt_strerror(err));
137                 return err;
138         }
139
140         prop = fdt_getprop(src, offset, names, &len);
141         if (prop) {
142                 offset = fdt_path_offset(dst, node);
143                 if (offset < 0) {
144                         debug("failed to find destination offset for %s: %s\n",
145                               node, fdt_strerror(err));
146                         return err;
147                 }
148
149                 err = fdt_setprop(dst, offset, "memory-region-names", prop,
150                                   len);
151                 if (err < 0) {
152                         debug("failed to copy \"%s\" property: %s\n", names,
153                               fdt_strerror(err));
154                         return err;
155                 }
156         }
157
158         return 0;
159 }
160
161 void ft_carveout_setup(void *fdt, const char * const *nodes, unsigned int count)
162 {
163         const void *cboot_fdt = (const void *)cboot_boot_x0;
164         unsigned int i;
165         int err;
166
167         for (i = 0; i < count; i++) {
168                 printf("copying carveout for %s...\n", nodes[i]);
169
170                 err = ft_copy_carveout(fdt, cboot_fdt, nodes[i]);
171                 if (err < 0) {
172                         if (err != -FDT_ERR_NOTFOUND)
173                                 printf("failed to copy carveout for %s: %d\n",
174                                        nodes[i], err);
175
176                         continue;
177                 }
178         }
179 }
180 #endif