Merge tag 'u-boot-imx-20200825' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
[platform/kernel/u-boot.git] / board / Marvell / octeontx2 / board-fdt.c
1 // SPDX-License-Identifier:    GPL-2.0
2 /*
3  * Copyright (C) 2018 Marvell International Ltd.
4  *
5  * https://spdx.org/licenses
6  */
7
8 #include <errno.h>
9 #include <fdtdec.h>
10 #include <fdt_support.h>
11 #include <log.h>
12
13 #include <linux/compiler.h>
14 #include <linux/libfdt.h>
15
16 #include <asm/arch/board.h>
17 #include <asm/arch/smc.h>
18 #include <asm/global_data.h>
19 #include <asm/io.h>
20
21 DECLARE_GLOBAL_DATA_PTR;
22
23 static int fdt_get_bdk_node(void)
24 {
25         int node, ret;
26         const void *fdt = gd->fdt_blob;
27
28         if (!fdt) {
29                 printf("ERROR: %s: no valid device tree found\n", __func__);
30                 return 0;
31         }
32
33         ret = fdt_check_header(fdt);
34         if (ret < 0) {
35                 printf("fdt: %s\n", fdt_strerror(ret));
36                 return 0;
37         }
38
39         node = fdt_path_offset(fdt, "/cavium,bdk");
40         if (node < 0) {
41                 printf("%s: /cavium,bdk is missing from device tree: %s\n",
42                        __func__, fdt_strerror(node));
43                 return 0;
44         }
45         return node;
46 }
47
48 u64 fdt_get_board_mac_addr(void)
49 {
50         int node, len = 16;
51         const char *str = NULL;
52         const void *fdt = gd->fdt_blob;
53         u64 mac_addr = 0;
54
55         node = fdt_get_bdk_node();
56         if (!node)
57                 return mac_addr;
58         str = fdt_getprop(fdt, node, "BOARD-MAC-ADDRESS", &len);
59         if (str)
60                 mac_addr = simple_strtol(str, NULL, 16);
61         return mac_addr;
62 }
63
64 int fdt_get_board_mac_cnt(void)
65 {
66         int node, len = 16;
67         const char *str = NULL;
68         const void *fdt = gd->fdt_blob;
69         int mac_count = 0;
70
71         node = fdt_get_bdk_node();
72         if (!node)
73                 return mac_count;
74         str = fdt_getprop(fdt, node, "BOARD-MAC-ADDRESS-NUM", &len);
75         if (str) {
76                 mac_count = simple_strtol(str, NULL, 10);
77                 if (!mac_count)
78                         mac_count = simple_strtol(str, NULL, 16);
79                 debug("fdt: MAC_NUM %d\n", mac_count);
80         } else {
81                 printf("Error: cannot retrieve mac count prop from fdt\n");
82         }
83         str = fdt_getprop(gd->fdt_blob, node, "BOARD-MAC-ADDRESS-NUM-OVERRIDE",
84                           &len);
85         if (str) {
86                 if (simple_strtol(str, NULL, 10) >= 0)
87                         mac_count = simple_strtol(str, NULL, 10);
88                 debug("fdt: MAC_NUM %d\n", mac_count);
89         } else {
90                 printf("Error: cannot retrieve mac num override prop\n");
91         }
92         return mac_count;
93 }
94
95 const char *fdt_get_board_serial(void)
96 {
97         const void *fdt = gd->fdt_blob;
98         int node, len = 64;
99         const char *str = NULL;
100
101         node = fdt_get_bdk_node();
102         if (!node)
103                 return NULL;
104
105         str = fdt_getprop(fdt, node, "BOARD-SERIAL", &len);
106         if (!str)
107                 printf("Error: cannot retrieve board serial from fdt\n");
108         return str;
109 }
110
111 const char *fdt_get_board_revision(void)
112 {
113         const void *fdt = gd->fdt_blob;
114         int node, len = 64;
115         const char *str = NULL;
116
117         node = fdt_get_bdk_node();
118         if (!node)
119                 return NULL;
120
121         str = fdt_getprop(fdt, node, "BOARD-REVISION", &len);
122         if (!str)
123                 printf("Error: cannot retrieve board revision from fdt\n");
124         return str;
125 }
126
127 const char *fdt_get_board_model(void)
128 {
129         int node, len = 16;
130         const char *str = NULL;
131         const void *fdt = gd->fdt_blob;
132
133         node = fdt_get_bdk_node();
134         if (!node)
135                 return NULL;
136         str = fdt_getprop(fdt, node, "BOARD-MODEL", &len);
137         if (!str)
138                 printf("Error: cannot retrieve board model from fdt\n");
139         return str;
140 }
141
142 int arch_fixup_memory_node(void *blob)
143 {
144         return 0;
145 }
146
147 int ft_board_setup(void *blob, struct bd_info *bd)
148 {
149         int nodeoff, node, ret, i;
150         const char *temp;
151
152         static const char * const
153                 octeontx_brd_nodes[] = {"BOARD-MODEL",
154                                         "BOARD-SERIAL",
155                                         "BOARD-MAC-ADDRESS",
156                                         "BOARD-REVISION",
157                                         "BOARD-MAC-ADDRESS-NUM"
158                                         };
159         char nodes[ARRAY_SIZE(octeontx_brd_nodes)][32];
160
161         ret = fdt_check_header(blob);
162         if (ret < 0) {
163                 printf("ERROR: %s\n", fdt_strerror(ret));
164                 return ret;
165         }
166
167         if (blob) {
168                 nodeoff = fdt_path_offset(blob, "/cavium,bdk");
169                 if (nodeoff < 0) {
170                         printf("ERROR: FDT BDK node not found\n");
171                         return nodeoff;
172                 }
173
174                 /* Read properties in temporary variables */
175                 for (i = 0; i < ARRAY_SIZE(octeontx_brd_nodes); i++) {
176                         temp = fdt_getprop(blob, nodeoff,
177                                            octeontx_brd_nodes[i], NULL);
178                         strncpy(nodes[i], temp, sizeof(nodes[i]));
179                 }
180
181                 /* Delete cavium,bdk node */
182                 ret = fdt_del_node(blob, nodeoff);
183                 if (ret < 0) {
184                         printf("WARNING : could not remove cavium, bdk node\n");
185                         return ret;
186                 }
187                 debug("%s deleted 'cavium,bdk' node\n", __func__);
188                 /*
189                  * Add a new node at root level which would have
190                  * necessary info
191                  */
192                 node = fdt_add_subnode(blob, 0, "octeontx_brd");
193                 if (node < 0) {
194                         printf("Cannot create node octeontx_brd: %s\n",
195                                fdt_strerror(node));
196                         return -EIO;
197                 }
198
199                 /* Populate properties in node */
200                 for (i = 0; i < ARRAY_SIZE(octeontx_brd_nodes); i++) {
201                         if (fdt_setprop_string(blob, node,
202                                                octeontx_brd_nodes[i],
203                                                nodes[i])) {
204                                 printf("Can't set %s\n", nodes[i]);
205                                 return -EIO;
206                         }
207                 }
208         }
209
210         return 0;
211 }
212
213 /**
214  * Return the FDT base address that was passed by ATF
215  *
216  * @return      FDT base address received from ATF in x1 register
217  */
218 void *board_fdt_blob_setup(void)
219 {
220         return (void *)fdt_base_addr;
221 }