blob: 0af1a20fb4513af607dee16b7b985b1831e3b459 [file] [log] [blame]
Mikael Olsson7da66192021-02-12 17:30:22 +01001/*
2 * Copyright (c) 2021, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <string.h>
9
10#include <common/debug.h>
11#include <common/fdt_wrappers.h>
12#include <libfdt.h>
13#include <plat/arm/common/fconf_ethosn_getter.h>
14
Laurent Carlier5205df22021-09-16 15:10:35 +010015struct ethosn_config_t ethosn_config = {.num_cores = 0};
Mikael Olsson7da66192021-02-12 17:30:22 +010016
17static uint8_t fdt_node_get_status(const void *fdt, int node)
18{
19 int len;
20 uint8_t status = ETHOSN_STATUS_DISABLED;
21 const char *node_status;
22
23 node_status = fdt_getprop(fdt, node, "status", &len);
24 if (node_status == NULL ||
25 (len == 5 && /* Includes null character */
26 strncmp(node_status, "okay", 4U) == 0)) {
27 status = ETHOSN_STATUS_ENABLED;
28 }
29
30 return status;
31}
32
33int fconf_populate_ethosn_config(uintptr_t config)
34{
35 int ethosn_node;
Mikael Olsson7da66192021-02-12 17:30:22 +010036 const void *hw_conf_dtb = (const void *)config;
37
38 /* Find offset to node with 'ethosn' compatible property */
Laurent Carlier5205df22021-09-16 15:10:35 +010039 INFO("Probing Arm Ethos-N NPU\n");
40 uint32_t total_core_count = 0U;
Mikael Olsson7da66192021-02-12 17:30:22 +010041
Laurent Carlier5205df22021-09-16 15:10:35 +010042 fdt_for_each_compatible_node(hw_conf_dtb, ethosn_node, "ethosn") {
43 int sub_node;
44 uint8_t ethosn_status;
45 uint32_t device_core_count = 0U;
Mikael Olsson7da66192021-02-12 17:30:22 +010046
Laurent Carlier5205df22021-09-16 15:10:35 +010047 /* If the Arm Ethos-N NPU is disabled the core check can be skipped */
48 ethosn_status = fdt_node_get_status(hw_conf_dtb, ethosn_node);
49 if (ethosn_status == ETHOSN_STATUS_DISABLED) {
Mikael Olsson7da66192021-02-12 17:30:22 +010050 continue;
51 }
52
Laurent Carlier5205df22021-09-16 15:10:35 +010053 fdt_for_each_subnode(sub_node, hw_conf_dtb, ethosn_node) {
54 int err;
55 uintptr_t core_addr;
56 uint8_t core_status;
Mikael Olsson7da66192021-02-12 17:30:22 +010057
Laurent Carlier5205df22021-09-16 15:10:35 +010058 if (total_core_count >= ETHOSN_CORE_NUM_MAX) {
59 ERROR("FCONF: Reached max number of Arm Ethos-N NPU cores\n");
60 return -FDT_ERR_BADSTRUCTURE;
61 }
62
63 /* Check that the sub node is "ethosn-core" compatible */
64 if (fdt_node_check_compatible(hw_conf_dtb,
65 sub_node,
66 "ethosn-core") != 0) {
67 /* Ignore incompatible sub node */
68 continue;
69 }
70
71 core_status = fdt_node_get_status(hw_conf_dtb, sub_node);
72 if (core_status == ETHOSN_STATUS_DISABLED) {
73 continue;
74 }
75
76 err = fdt_get_reg_props_by_index(hw_conf_dtb,
77 ethosn_node,
78 device_core_count,
79 &core_addr,
80 NULL);
81 if (err < 0) {
82 ERROR(
83 "FCONF: Failed to read reg property for Arm Ethos-N NPU core %u\n",
84 device_core_count);
85 return err;
86 }
87
88 INFO("NPU core probed at address 0x%lx\n", core_addr);
89 ethosn_config.core[total_core_count].addr = core_addr;
90 total_core_count++;
91 device_core_count++;
Mikael Olsson7da66192021-02-12 17:30:22 +010092 }
93
Laurent Carlier5205df22021-09-16 15:10:35 +010094 if ((sub_node < 0) && (sub_node != -FDT_ERR_NOTFOUND)) {
95 ERROR("FCONF: Failed to parse sub nodes\n");
96 return -FDT_ERR_BADSTRUCTURE;
Mikael Olsson7da66192021-02-12 17:30:22 +010097 }
98
Laurent Carlier5205df22021-09-16 15:10:35 +010099 if (device_core_count == 0U) {
100 ERROR(
101 "FCONF: Enabled Arm Ethos-N NPU device must have at least one enabled core\n");
102 return -FDT_ERR_BADSTRUCTURE;
103 }
Mikael Olsson7da66192021-02-12 17:30:22 +0100104 }
105
Laurent Carlier5205df22021-09-16 15:10:35 +0100106 if (total_core_count == 0U) {
107 ERROR("FCONF: Can't find 'ethosn' compatible node in dtb\n");
108 return -FDT_ERR_BADSTRUCTURE;
Mikael Olsson7da66192021-02-12 17:30:22 +0100109 }
110
Laurent Carlier5205df22021-09-16 15:10:35 +0100111 ethosn_config.num_cores = total_core_count;
Mikael Olsson7da66192021-02-12 17:30:22 +0100112
Laurent Carlier5205df22021-09-16 15:10:35 +0100113 INFO("%d NPU core%s probed\n",
114 ethosn_config.num_cores,
115 ethosn_config.num_cores > 1 ? "s" : "");
Mikael Olsson7da66192021-02-12 17:30:22 +0100116
117 return 0;
118}
119
120FCONF_REGISTER_POPULATOR(HW_CONFIG, ethosn_config, fconf_populate_ethosn_config);