Skip to content

Commit 79545ec

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 5439c20 commit 79545ec

File tree

7 files changed

+194
-0
lines changed

7 files changed

+194
-0
lines changed

drivers/misc/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
menu "Miscellaneous Drivers"
77

8+
source "drivers/misc/ethos_u/Kconfig"
89
source "drivers/misc/ft8xx/Kconfig"
910
source "drivers/misc/grove_lcd_rgb/Kconfig"
1011
source "drivers/misc/pio_rpi_pico/Kconfig"

drivers/misc/ethos_u/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44

55
zephyr_library()
66
zephyr_library_sources(ethos_u.c)
7+
zephyr_library_sources_ifdef(CONFIG_ETHOS_U_NUMAKER ethos_u_numaker.c)

drivers/misc/ethos_u/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright (c) 2025
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
if ARM_ETHOS_U
5+
6+
config ETHOS_U_NUMAKER
7+
bool "Nuvoton NuMaker Ethos-U NPU driver"
8+
default y
9+
depends on DT_HAS_NUVOTON_NUMAKER_NPU_ENABLED
10+
help
11+
Enables Nuvoton NuMaker frontend of Arm Ethos-U NPU driver
12+
13+
endif
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_ARM_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
@@ -13,6 +13,7 @@ if ARM_ETHOS_U
1313
menu "Arm Ethos-U NPU configuration"
1414
choice ARM_ETHOS_U_NPU_CONFIG
1515
prompt "Arm Ethos-U NPU configuration"
16+
default ARM_ETHOS_U55_256 if SOC_SERIES_M55M1X
1617
default ARM_ETHOS_U55_128
1718
config ARM_ETHOS_U55_64
1819
bool "using Ethos-U55 with 64 macs"

0 commit comments

Comments
 (0)