Skip to content

Commit 9d85e18

Browse files
committed
drivers: misc: ethos_u: support nuvoton numaker m55m1x
This addes frontend of arm ethos-u core driver for nuvoton numaker m55m1x. Special notes include: 1. Leaving application overriding dcache flush/invalidate weak functions for cacheable NPU buffer 2. Configuring macs_per_cc to 256 in arm ethos-u core driver to match m55m1x ethos-u RTL config Signed-off-by: Chun-Chieh Li <[email protected]>
1 parent 8a6e096 commit 9d85e18

File tree

6 files changed

+186
-0
lines changed

6 files changed

+186
-0
lines changed

drivers/misc/ethos_u/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
zephyr_library()
66
zephyr_library_sources(ethos_u_common.c)
77
zephyr_library_sources_ifdef(CONFIG_ETHOS_U_ARM ethos_u_arm.c)
8+
zephyr_library_sources_ifdef(CONFIG_ETHOS_U_NUMAKER ethos_u_numaker.c)

drivers/misc/ethos_u/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@ choice
55
prompt "Select vendor Ethos-U NPU driver"
66
depends on ETHOS_U
77
default ETHOS_U_ARM if DT_HAS_ARM_ETHOS_U_ENABLED
8+
default ETHOS_U_NUMAKER if DT_HAS_NUVOTON_NUMAKER_NPU_ENABLED
89

910
config ETHOS_U_ARM
1011
bool "Arm Ethos-U NPU driver"
1112
help
1213
Enables Arm Ethos-U NPU driver.
1314

15+
config ETHOS_U_NUMAKER
16+
bool "Nuvoton NuMaker Ethos-U NPU driver"
17+
help
18+
Enables Nuvoton NuMaker frontend of Arm Ethos-U NPU driver
19+
1420
endchoice
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Copyright (c) 2025 Nuvoton Technology Corporation.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT nuvoton_numaker_npu
8+
9+
#include <zephyr/kernel.h>
10+
#include <zephyr/drivers/clock_control.h>
11+
#include <zephyr/drivers/clock_control/clock_control_numaker.h>
12+
#include <zephyr/drivers/reset.h>
13+
14+
#include <ethosu_driver.h>
15+
16+
#include <zephyr/logging/log.h>
17+
LOG_MODULE_REGISTER(ethos_u_numaker, CONFIG_ETHOS_U_LOG_LEVEL);
18+
19+
#include <soc.h>
20+
21+
struct ethos_u_numaker_config {
22+
void *base_addr;
23+
const struct device *clkctrl_dev;
24+
struct numaker_scc_subsys pcc;
25+
struct reset_dt_spec reset;
26+
void (*irq_config)(const struct device *dev);
27+
bool secure_enable;
28+
bool privilege_enable;
29+
uint8_t flush_mask;
30+
uint8_t invalidate_mask;
31+
};
32+
33+
struct ethos_u_numaker_data {
34+
struct ethosu_driver drv;
35+
};
36+
37+
static void ethos_u_numaker_irq_handler(const struct device *dev)
38+
{
39+
struct ethos_u_numaker_data *data = dev->data;
40+
struct ethosu_driver *drv = &data->drv;
41+
42+
ethosu_irq_handler(drv);
43+
}
44+
45+
static int ethos_u_numaker_init(const struct device *dev)
46+
{
47+
const struct ethos_u_numaker_config *config = dev->config;
48+
struct ethos_u_numaker_data *data = dev->data;
49+
struct ethosu_driver *drv = &data->drv;
50+
int rc;
51+
52+
/* Invoke Clock controller to enable module clock */
53+
54+
/* Equivalent to CLK_EnableModuleClock() */
55+
rc = clock_control_on(config->clkctrl_dev, (clock_control_subsys_t)&config->pcc);
56+
if (rc < 0) {
57+
return rc;
58+
}
59+
rc = clock_control_on(config->clkctrl_dev, (clock_control_subsys_t)&config->pcc);
60+
if (rc < 0) {
61+
return rc;
62+
}
63+
64+
/* Equivalent to CLK_SetModuleClock() */
65+
rc = clock_control_configure(config->clkctrl_dev, (clock_control_subsys_t)&config->pcc,
66+
NULL);
67+
if (rc < 0) {
68+
return rc;
69+
}
70+
71+
/* Invoke Reset controller to reset module to default state */
72+
/* Equivalent to SYS_ResetModule() */
73+
rc = reset_line_toggle_dt(&config->reset);
74+
if (rc < 0) {
75+
return rc;
76+
}
77+
78+
LOG_DBG("Ethos-U DTS info: base_addr=0x%p, secure_enable=%u, privilege_enable=%u",
79+
config->base_addr, config->secure_enable, config->privilege_enable);
80+
81+
if (ethosu_init(drv, config->base_addr, NULL, 0, config->secure_enable,
82+
config->privilege_enable)) {
83+
LOG_ERR("Failed to initialize NPU with ethosu_init().");
84+
return -EINVAL;
85+
}
86+
87+
ethosu_set_basep_cache_mask(drv, config->flush_mask, config->invalidate_mask);
88+
89+
config->irq_config(dev);
90+
91+
return 0;
92+
}
93+
94+
/* Peripheral Clock Control */
95+
#define NUMAKER_PCC_INST_GET(inst) \
96+
{ \
97+
.subsys_id = NUMAKER_SCC_SUBSYS_ID_PCC, \
98+
.pcc.clk_modidx = DT_INST_CLOCKS_CELL(inst, clock_module_index), \
99+
.pcc.clk_src = DT_INST_CLOCKS_CELL(inst, clock_source), \
100+
.pcc.clk_div = DT_INST_CLOCKS_CELL(inst, clock_divider), \
101+
}
102+
103+
#define NUMAKER_ETHOS_U_INIT(inst) \
104+
static void ethos_u_numaker_irq_config_##inst(const struct device *dev) \
105+
{ \
106+
IRQ_CONNECT(DT_INST_IRQ(inst, irq), DT_INST_IRQ(inst, priority), \
107+
ethos_u_numaker_irq_handler, DEVICE_DT_INST_GET(inst), 0); \
108+
\
109+
irq_enable(DT_INST_IRQ(inst, irq)); \
110+
} \
111+
\
112+
static const struct ethos_u_numaker_config ethos_u_numaker_config_##inst = { \
113+
.base_addr = (void *)DT_INST_REG_ADDR(inst), \
114+
.clkctrl_dev = DEVICE_DT_GET(DT_PARENT(DT_INST_CLOCKS_CTLR(inst))), \
115+
.pcc = NUMAKER_PCC_INST_GET(inst), \
116+
.reset = RESET_DT_SPEC_INST_GET(inst), \
117+
.irq_config = ethos_u_numaker_irq_config_##inst, \
118+
.secure_enable = DT_INST_PROP(inst, secure_enable), \
119+
.privilege_enable = DT_INST_PROP(inst, privilege_enable), \
120+
.flush_mask = DT_INST_PROP(inst, flush_mask), \
121+
.invalidate_mask = DT_INST_PROP(inst, invalidate_mask), \
122+
}; \
123+
\
124+
static struct ethos_u_numaker_data ethos_u_numaker_data_##inst; \
125+
\
126+
DEVICE_DT_INST_DEFINE(inst, ethos_u_numaker_init, NULL, &ethos_u_numaker_data_##inst, \
127+
&ethos_u_numaker_config_##inst, POST_KERNEL, \
128+
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);
129+
130+
DT_INST_FOREACH_STATUS_OKAY(NUMAKER_ETHOS_U_INIT);

dts/arm/nuvoton/m55m1h2l.dtsi

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,16 @@
3131
reg = <0x100000 DT_SIZE_K(2048)>;
3232
};
3333
};
34+
35+
npu0: npu@40003000 {
36+
compatible = "nuvoton,numaker-npu";
37+
reg = <0x40003000 0x1000>;
38+
interrupts = <13 0>;
39+
resets = <&rst NUMAKER_SYS_NPURST>;
40+
clocks = <&pcc NUMAKER_NPU0_MODULE 0 0>;
41+
secure-enable;
42+
privilege-enable;
43+
status = "disabled";
44+
};
3445
};
3546
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright (c) 2025 Nuvoton Technology Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Nuvoton NuMaker frontend of Arm Ethos-U NPU driver
5+
6+
compatible: "nuvoton,numaker-npu"
7+
8+
include: ["arm,ethos-u.yaml", reset-device.yaml]
9+
10+
properties:
11+
reg:
12+
required: true
13+
14+
interrupts:
15+
required: true
16+
17+
resets:
18+
required: true
19+
20+
clocks:
21+
required: true
22+
23+
flush-mask:
24+
type: int
25+
default: 2
26+
description: |
27+
Base pointer cache flush mask passed to ethos-u core driver
28+
ethosu_set_basep_cache_mask(). Default is to follow ethos-u
29+
core driver for scratch region.
30+
31+
invalidate-mask:
32+
type: int
33+
default: 2
34+
description: |
35+
Base pointer cache invalidation mask passed to ethos-u core driver
36+
ethosu_set_basep_cache_mask(). Default is to follow ethos-u
37+
core driver for scratch region.

modules/hal_ethos_u/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ choice ETHOS_U_NPU_CONFIG
1616
default ETHOS_U55_128 if SOC_SERIES_MPS3
1717
default ETHOS_U65_256 if SOC_MPS4_CORSTONE315
1818
default ETHOS_U85_256 if SOC_MPS4_CORSTONE320
19+
default ETHOS_U55_256 if SOC_SERIES_M55M1X
1920
config ETHOS_U55_64
2021
bool "using Ethos-U55 with 64 macs"
2122
config ETHOS_U55_128

0 commit comments

Comments
 (0)