// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2018 Marvell International Ltd. * * https://spdx.org/licenses */ #include #include #include #include #include #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; static int fdt_get_bdk_node(void) { int node, ret; const void *fdt = gd->fdt_blob; if (!fdt) { printf("ERROR: %s: no valid device tree found\n", __func__); return 0; } ret = fdt_check_header(fdt); if (ret < 0) { printf("fdt: %s\n", fdt_strerror(ret)); return 0; } node = fdt_path_offset(fdt, "/cavium,bdk"); if (node < 0) { printf("%s: /cavium,bdk is missing from device tree: %s\n", __func__, fdt_strerror(node)); return 0; } return node; } u64 fdt_get_board_mac_addr(void) { int node, len = 16; const char *str = NULL; const void *fdt = gd->fdt_blob; u64 mac_addr = 0; node = fdt_get_bdk_node(); if (!node) return mac_addr; str = fdt_getprop(fdt, node, "BOARD-MAC-ADDRESS", &len); if (str) mac_addr = simple_strtol(str, NULL, 16); return mac_addr; } int fdt_get_board_mac_cnt(void) { int node, len = 16; const char *str = NULL; const void *fdt = gd->fdt_blob; int mac_count = 0; node = fdt_get_bdk_node(); if (!node) return mac_count; str = fdt_getprop(fdt, node, "BOARD-MAC-ADDRESS-NUM", &len); if (str) { mac_count = simple_strtol(str, NULL, 10); if (!mac_count) mac_count = simple_strtol(str, NULL, 16); debug("fdt: MAC_NUM %d\n", mac_count); } else { printf("Error: cannot retrieve mac count prop from fdt\n"); } str = fdt_getprop(gd->fdt_blob, node, "BOARD-MAC-ADDRESS-NUM-OVERRIDE", &len); if (str) { if (simple_strtol(str, NULL, 10) >= 0) mac_count = simple_strtol(str, NULL, 10); debug("fdt: MAC_NUM %d\n", mac_count); } else { printf("Error: cannot retrieve mac num override prop\n"); } return mac_count; } const char *fdt_get_board_serial(void) { const void *fdt = gd->fdt_blob; int node, len = 64; const char *str = NULL; node = fdt_get_bdk_node(); if (!node) return NULL; str = fdt_getprop(fdt, node, "BOARD-SERIAL", &len); if (!str) printf("Error: cannot retrieve board serial from fdt\n"); return str; } const char *fdt_get_board_revision(void) { const void *fdt = gd->fdt_blob; int node, len = 64; const char *str = NULL; node = fdt_get_bdk_node(); if (!node) return NULL; str = fdt_getprop(fdt, node, "BOARD-REVISION", &len); if (!str) printf("Error: cannot retrieve board revision from fdt\n"); return str; } const char *fdt_get_board_model(void) { int node, len = 16; const char *str = NULL; const void *fdt = gd->fdt_blob; node = fdt_get_bdk_node(); if (!node) return NULL; str = fdt_getprop(fdt, node, "BOARD-MODEL", &len); if (!str) printf("Error: cannot retrieve board model from fdt\n"); return str; } int arch_fixup_memory_node(void *blob) { return 0; } int ft_board_setup(void *blob, struct bd_info *bd) { int nodeoff, node, ret, i; const char *temp; static const char * const octeontx_brd_nodes[] = {"BOARD-MODEL", "BOARD-SERIAL", "BOARD-MAC-ADDRESS", "BOARD-REVISION", "BOARD-MAC-ADDRESS-NUM" }; char nodes[ARRAY_SIZE(octeontx_brd_nodes)][32]; ret = fdt_check_header(blob); if (ret < 0) { printf("ERROR: %s\n", fdt_strerror(ret)); return ret; } if (blob) { nodeoff = fdt_path_offset(blob, "/cavium,bdk"); if (nodeoff < 0) { printf("ERROR: FDT BDK node not found\n"); return nodeoff; } /* Read properties in temporary variables */ for (i = 0; i < ARRAY_SIZE(octeontx_brd_nodes); i++) { temp = fdt_getprop(blob, nodeoff, octeontx_brd_nodes[i], NULL); strncpy(nodes[i], temp, sizeof(nodes[i])); } /* Delete cavium,bdk node */ ret = fdt_del_node(blob, nodeoff); if (ret < 0) { printf("WARNING : could not remove cavium, bdk node\n"); return ret; } debug("%s deleted 'cavium,bdk' node\n", __func__); /* * Add a new node at root level which would have * necessary info */ node = fdt_add_subnode(blob, 0, "octeontx_brd"); if (node < 0) { printf("Cannot create node octeontx_brd: %s\n", fdt_strerror(node)); return -EIO; } /* Populate properties in node */ for (i = 0; i < ARRAY_SIZE(octeontx_brd_nodes); i++) { if (fdt_setprop_string(blob, node, octeontx_brd_nodes[i], nodes[i])) { printf("Can't set %s\n", nodes[i]); return -EIO; } } } return 0; } /** * Return the FDT base address that was passed by ATF * * @return FDT base address received from ATF in x1 register */ void *board_fdt_blob_setup(int *err) { *err = 0; return (void *)fdt_base_addr; }