blob: 53a304b620d88f656310a050032025896842efe0 [file] [log] [blame]
alexander3c798932021-03-26 21:42:19 +00001/*
2 * Copyright (c) 2021 Arm Limited. All rights reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17#include "hal.h" /* API */
18
19#include "hal_config.h" /* HAL configuration */
20#include "system_init.h"
21
22#include <stdio.h>
23#include <assert.h>
24
25#if defined(ARM_NPU)
26
Isabella Gottardi118f73e2021-09-16 17:54:35 +010027#include "ethosu_mem_config.h" /* Arm Ethos-U memory config */
Cisco Cervelleraf085fa52021-08-02 09:32:07 +010028#include "ethosu_driver.h" /* Arm Ethos-U driver header */
29#include "timing_adapter.h" /* Arm Ethos-U timing adapter driver header */
30#include "timing_adapter_settings.h" /* Arm Ethos-U timing adapter settings */
alexander3c798932021-03-26 21:42:19 +000031
Cisco Cervellera414b1b92021-09-28 18:15:10 +010032struct ethosu_driver ethosu_drv; /* Default Ethos-U device driver */
Kshitij Sisodia659fcd92021-05-19 10:30:06 +010033
Isabella Gottardi118f73e2021-09-16 17:54:35 +010034#if defined(ETHOS_U_CACHE_BUF_SZ) && (ETHOS_U_CACHE_BUF_SZ > 0)
35 static uint8_t cache_arena[ETHOS_U_CACHE_BUF_SZ] CACHE_BUF_ATTRIBUTE;
36#else /* defined (ETHOS_U_CACHE_BUF_SZ) && (ETHOS_U_CACHE_BUF_SZ > 0) */
37 static uint8_t* cache_arena = NULL;
38#endif /* defined (ETHOS_U_CACHE_BUF_SZ) && (ETHOS_U_CACHE_BUF_SZ > 0) */
39
alexander3c798932021-03-26 21:42:19 +000040/**
Cisco Cervelleraf085fa52021-08-02 09:32:07 +010041 * @brief Initialises the Arm Ethos-U NPU
alexander3c798932021-03-26 21:42:19 +000042 * @return 0 if successful, error code otherwise
43 **/
alexanderc350cdc2021-04-29 20:36:09 +010044static int arm_npu_init(void);
alexander3c798932021-03-26 21:42:19 +000045
Isabella Gottardi118f73e2021-09-16 17:54:35 +010046static uint8_t * get_cache_arena()
47{
48 return cache_arena;
49}
50
51static size_t get_cache_arena_size()
52{
53#if defined(ETHOS_U_CACHE_BUF_SZ) && (ETHOS_U_CACHE_BUF_SZ > 0)
54 return sizeof(cache_arena);
55#else /* defined (ETHOS_U_CACHE_BUF_SZ) && (ETHOS_U_CACHE_BUF_SZ > 0) */
56 return 0;
57#endif /* defined (ETHOS_U_CACHE_BUF_SZ) && (ETHOS_U_CACHE_BUF_SZ > 0) */
58}
59
alexander3c798932021-03-26 21:42:19 +000060#endif /* ARM_NPU */
61
62int hal_init(hal_platform* platform, data_acq_module* data_acq,
63 data_psn_module* data_psn, platform_timer* timer)
64{
65 assert(platform && data_acq && data_psn);
66
67 platform->data_acq = data_acq;
68 platform->data_psn = data_psn;
69 platform->timer = timer;
70 platform->platform_init = system_init;
71 platform->platform_release = system_release;
72 system_name(platform->plat_name, sizeof(platform->plat_name));
73
74 return 0;
75}
76
77/**
78 * @brief Local helper function to clean the slate for current platform.
79 **/
alexanderc350cdc2021-04-29 20:36:09 +010080static void hal_platform_clear(hal_platform* platform)
alexander3c798932021-03-26 21:42:19 +000081{
82 assert(platform);
83 platform->inited = 0;
84}
85
86int hal_platform_init(hal_platform* platform)
87{
88 int state;
89 assert(platform && platform->platform_init);
alexanderc350cdc2021-04-29 20:36:09 +010090 hal_platform_clear(platform);
alexander3c798932021-03-26 21:42:19 +000091
92 /* Initialise platform */
93 if (0 != (state = platform->platform_init())) {
94 printf_err("failed to initialise platform %s\n", platform->plat_name);
95 return state;
96 }
97
98 /* Initialise the data acquisition module */
99 if (0 != (state = data_acq_channel_init(platform->data_acq))) {
100 if (!platform->data_acq->inited) {
101 printf_err("failed to initialise data acq module: %s\n",
102 platform->data_acq->system_name);
103 }
104 hal_platform_release(platform);
105 return state;
106 }
107
108 /* Initialise the presentation module */
109 if (0 != (state = data_psn_system_init(platform->data_psn))) {
110 printf_err("failed to initialise data psn module: %s\n",
111 platform->data_psn->system_name);
112 data_acq_channel_release(platform->data_acq);
113 hal_platform_release(platform);
114 return state;
115 }
116
117#if defined(ARM_NPU)
118
Cisco Cervelleraf085fa52021-08-02 09:32:07 +0100119 /* If Arm Ethos-U NPU is to be used, we initialise it here */
alexanderc350cdc2021-04-29 20:36:09 +0100120 if (0 != (state = arm_npu_init())) {
alexander3c798932021-03-26 21:42:19 +0000121 return state;
122 }
123
124#endif /* ARM_NPU */
125
126 /* followed by the timer module */
127 init_timer(platform->timer);
128
129 info("%s platform initialised\n", platform->plat_name);
130 debug("using %s module for data acquisition\n",
131 platform->data_acq->system_name);
132 debug("using %s module for data presentation\n",
133 platform->data_psn->system_name);
134
135 platform->inited = !state;
136
137 return state;
138}
139
140void hal_platform_release(hal_platform *platform)
141{
142 assert(platform && platform->platform_release);
143 data_acq_channel_release(platform->data_acq);
144 data_psn_system_release(platform->data_psn);
145
alexanderc350cdc2021-04-29 20:36:09 +0100146 hal_platform_clear(platform);
alexander3c798932021-03-26 21:42:19 +0000147 info("releasing platform %s\n", platform->plat_name);
148 platform->platform_release();
149}
150
151#if defined(ARM_NPU)
152/**
153 * @brief Defines the Ethos-U interrupt handler: just a wrapper around the default
154 * implementation.
155 **/
alexanderc350cdc2021-04-29 20:36:09 +0100156static void arm_npu_irq_handler(void)
alexander3c798932021-03-26 21:42:19 +0000157{
158 /* Call the default interrupt handler from the NPU driver */
Kshitij Sisodia659fcd92021-05-19 10:30:06 +0100159 ethosu_irq_handler(&ethosu_drv);
alexander3c798932021-03-26 21:42:19 +0000160}
161
162/**
163 * @brief Initialises the NPU IRQ
164 **/
alexanderc350cdc2021-04-29 20:36:09 +0100165static void arm_npu_irq_init(void)
alexander3c798932021-03-26 21:42:19 +0000166{
167 const IRQn_Type ethosu_irqnum = (IRQn_Type)EthosU_IRQn;
168
169 /* Register the EthosU IRQ handler in our vector table.
170 * Note, this handler comes from the EthosU driver */
alexanderc350cdc2021-04-29 20:36:09 +0100171 NVIC_SetVector(ethosu_irqnum, (uint32_t)arm_npu_irq_handler);
alexander3c798932021-03-26 21:42:19 +0000172
173 /* Enable the IRQ */
174 NVIC_EnableIRQ(ethosu_irqnum);
175
176 debug("EthosU IRQ#: %u, Handler: 0x%p\n",
alexanderc350cdc2021-04-29 20:36:09 +0100177 ethosu_irqnum, arm_npu_irq_handler);
alexander3c798932021-03-26 21:42:19 +0000178}
179
180static int _arm_npu_timing_adapter_init(void)
181{
182#if defined (TA0_BASE)
183 struct timing_adapter ta_0;
184 struct timing_adapter_settings ta_0_settings = {
185 .maxr = TA0_MAXR,
186 .maxw = TA0_MAXW,
187 .maxrw = TA0_MAXRW,
188 .rlatency = TA0_RLATENCY,
189 .wlatency = TA0_WLATENCY,
190 .pulse_on = TA0_PULSE_ON,
191 .pulse_off = TA0_PULSE_OFF,
192 .bwcap = TA0_BWCAP,
193 .perfctrl = TA0_PERFCTRL,
194 .perfcnt = TA0_PERFCNT,
195 .mode = TA0_MODE,
196 .maxpending = 0, /* This is a read-only parameter */
197 .histbin = TA0_HISTBIN,
198 .histcnt = TA0_HISTCNT
199 };
200
201 if (0 != ta_init(&ta_0, TA0_BASE)) {
202 printf_err("TA0 initialisation failed\n");
203 return 1;
204 }
205
206 ta_set_all(&ta_0, &ta_0_settings);
207#endif /* defined (TA0_BASE) */
208
209#if defined (TA1_BASE)
210 struct timing_adapter ta_1;
211 struct timing_adapter_settings ta_1_settings = {
212 .maxr = TA1_MAXR,
213 .maxw = TA1_MAXW,
214 .maxrw = TA1_MAXRW,
215 .rlatency = TA1_RLATENCY,
216 .wlatency = TA1_WLATENCY,
217 .pulse_on = TA1_PULSE_ON,
218 .pulse_off = TA1_PULSE_OFF,
219 .bwcap = TA1_BWCAP,
220 .perfctrl = TA1_PERFCTRL,
221 .perfcnt = TA1_PERFCNT,
222 .mode = TA1_MODE,
223 .maxpending = 0, /* This is a read-only parameter */
224 .histbin = TA1_HISTBIN,
225 .histcnt = TA1_HISTCNT
226 };
227
228 if (0 != ta_init(&ta_1, TA1_BASE)) {
229 printf_err("TA1 initialisation failed\n");
230 return 1;
231 }
232
233 ta_set_all(&ta_1, &ta_1_settings);
234#endif /* defined (TA1_BASE) */
235
236 return 0;
237}
238
alexanderc350cdc2021-04-29 20:36:09 +0100239static int arm_npu_init(void)
alexander3c798932021-03-26 21:42:19 +0000240{
241 int err = 0;
242
Cisco Cervelleraf085fa52021-08-02 09:32:07 +0100243 /* If the platform has timing adapter blocks along with Ethos-U core
alexander3c798932021-03-26 21:42:19 +0000244 * block, initialise them here. */
245 if (0 != (err = _arm_npu_timing_adapter_init())) {
246 return err;
247 }
248
249 /* Initialise the IRQ */
alexanderc350cdc2021-04-29 20:36:09 +0100250 arm_npu_irq_init();
alexander3c798932021-03-26 21:42:19 +0000251
Cisco Cervelleraf085fa52021-08-02 09:32:07 +0100252 /* Initialise Ethos-U device */
253 const void * ethosu_base_address = (void *)(SEC_ETHOS_U_NPU_BASE);
alexander3c798932021-03-26 21:42:19 +0000254
Kshitij Sisodia659fcd92021-05-19 10:30:06 +0100255 if (0 != (err = ethosu_init(
Isabella Gottardi118f73e2021-09-16 17:54:35 +0100256 &ethosu_drv, /* Ethos-U driver device pointer */
257 ethosu_base_address, /* Ethos-U NPU's base address. */
258 get_cache_arena(), /* Pointer to fast mem area - NULL for U55. */
259 get_cache_arena_size(), /* Fast mem region size. */
260 1, /* Security enable. */
261 1))) { /* Privilege enable. */
Cisco Cervelleraf085fa52021-08-02 09:32:07 +0100262 printf_err("failed to initalise Ethos-U device\n");
alexander3c798932021-03-26 21:42:19 +0000263 return err;
264 }
265
Cisco Cervelleraf085fa52021-08-02 09:32:07 +0100266 info("Ethos-U device initialised\n");
alexander3c798932021-03-26 21:42:19 +0000267
Cisco Cervelleraf085fa52021-08-02 09:32:07 +0100268 /* Get Ethos-U version */
Cisco Cervellera414b1b92021-09-28 18:15:10 +0100269 struct ethosu_driver_version driver_version;
270 struct ethosu_hw_info hw_info;
271
272 ethosu_get_driver_version(&driver_version);
273 ethosu_get_hw_info(&ethosu_drv, &hw_info);
alexander3c798932021-03-26 21:42:19 +0000274
Cisco Cervelleraf085fa52021-08-02 09:32:07 +0100275 info("Ethos-U version info:\n");
Cisco Cervellera414b1b92021-09-28 18:15:10 +0100276 info("\tArch: v%"PRIu32".%"PRIu32".%"PRIu32"\n",
277 hw_info.version.arch_major_rev,
278 hw_info.version.arch_minor_rev,
279 hw_info.version.arch_patch_rev);
280 info("\tDriver: v%"PRIu8".%"PRIu8".%"PRIu8"\n",
281 driver_version.major,
282 driver_version.minor,
283 driver_version.patch);
284 info("\tMACs/cc: %"PRIu32"\n", (uint32_t)(1 << hw_info.cfg.macs_per_cc));
285 info("\tCmd stream: v%"PRIu32"\n", hw_info.cfg.cmd_stream_version);
286 info("\tSHRAM size: %"PRIu32"\n", hw_info.cfg.shram_size);
alexander3c798932021-03-26 21:42:19 +0000287
288 return 0;
289}
Isabella Gottardi118f73e2021-09-16 17:54:35 +0100290
alexander3c798932021-03-26 21:42:19 +0000291#endif /* ARM_NPU */