diff --git a/drivers/misc/stm32n6_axisram/Kconfig b/drivers/misc/stm32n6_axisram/Kconfig index b6c2493ac6e1d..7d583aec7ce44 100644 --- a/drivers/misc/stm32n6_axisram/Kconfig +++ b/drivers/misc/stm32n6_axisram/Kconfig @@ -4,4 +4,7 @@ config STM32N6_AXISRAM bool select USE_STM32_HAL_RAMCFG - default y if DT_HAS_ST_STM32N6_RAMCFG_ENABLED + default y if $(dt_nodelabel_enabled,axisram3) || \ + $(dt_nodelabel_enabled,axisram4) || \ + $(dt_nodelabel_enabled,axisram5) || \ + $(dt_nodelabel_enabled,axisram6) diff --git a/dts/arm/st/n6/stm32n6.dtsi b/dts/arm/st/n6/stm32n6.dtsi index 5fdd55295b2d0..4112350a58151 100644 --- a/dts/arm/st/n6/stm32n6.dtsi +++ b/dts/arm/st/n6/stm32n6.dtsi @@ -852,6 +852,14 @@ resets = <&rctl STM32_RESET(APB5, 1)>; status = "disabled"; }; + + npu: npu@580c0000 { + compatible = "st,stm32-npu"; + reg = <0x580c0000 0x1000>; + clocks = <&rcc STM32_CLOCK(AHB5, 31)>; + resets = <&rctl STM32_RESET(AHB5, 31)>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/st/n6/stm32n657X0.dtsi b/dts/arm/st/n6/stm32n657X0.dtsi index e692de0af9756..ab4cb6f326024 100644 --- a/dts/arm/st/n6/stm32n657X0.dtsi +++ b/dts/arm/st/n6/stm32n657X0.dtsi @@ -22,7 +22,7 @@ ramcfg@42023100 { axisram3: memory@34200000 { reg = <0x34200000 DT_SIZE_K(448)>; - status = "okay"; + status = "disabled"; }; }; diff --git a/dts/bindings/misc/st,stm32-npu.yaml b/dts/bindings/misc/st,stm32-npu.yaml new file mode 100644 index 0000000000000..84cb2e047d15b --- /dev/null +++ b/dts/bindings/misc/st,stm32-npu.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: STM32 Neural-ART accelerator + +compatible: "st,stm32-npu" + +include: [reset-device.yaml, base.yaml] + +properties: + reg: + required: true + + clocks: + required: true + + resets: + required: true diff --git a/soc/st/stm32/stm32n6x/CMakeLists.txt b/soc/st/stm32/stm32n6x/CMakeLists.txt index c2a8c56b3c0d1..966ce4a109f4d 100644 --- a/soc/st/stm32/stm32n6x/CMakeLists.txt +++ b/soc/st/stm32/stm32n6x/CMakeLists.txt @@ -5,6 +5,10 @@ zephyr_sources( soc.c ) +zephyr_sources_ifdef(CONFIG_STM32N6_NPU + npu/npu_stm32n6.c + ) + zephyr_include_directories(.) set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/st/stm32/stm32n6x/Kconfig b/soc/st/stm32/stm32n6x/Kconfig index 548dea00772fb..c1ac71d118cec 100644 --- a/soc/st/stm32/stm32n6x/Kconfig +++ b/soc/st/stm32/stm32n6x/Kconfig @@ -23,3 +23,8 @@ config SOC_SERIES_STM32N6X config STM32N6_BOOT_SERIAL bool "Serial boot target (USB)" + +config STM32N6_NPU + bool "Neural-ART accelerator (NPU)" + select USE_STM32_HAL_RIF + default y if DT_HAS_ST_STM32_NPU_ENABLED diff --git a/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c b/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c new file mode 100644 index 0000000000000..77c307f649687 --- /dev/null +++ b/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT st_stm32_npu + +#include + +#include +#include +#include +#include + +#include + +/* Read-only driver configuration */ +struct npu_stm32_cfg { + /* Clock configuration. */ + struct stm32_pclken pclken; + /* Reset configuration */ + const struct reset_dt_spec reset; +}; + +static void npu_risaf_config(void) +{ + RIMC_MasterConfig_t RIMC_master = {0}; + + RIMC_master.MasterCID = RIF_CID_1; + RIMC_master.SecPriv = RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV; + HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_NPU, &RIMC_master); + HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_NPU, + RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV); +} + +static int npu_stm32_init(const struct device *dev) +{ + const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); + const struct npu_stm32_cfg *cfg = dev->config; + + if (!device_is_ready(clk)) { + return -ENODEV; + } + + if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken) != 0) { + return -EIO; + } + + if (!device_is_ready(cfg->reset.dev)) { + return -ENODEV; + } + + /* Reset timer to default state using RCC */ + (void)reset_line_toggle_dt(&cfg->reset); + + npu_risaf_config(); + + return 0; +} + + +static const struct npu_stm32_cfg npu_stm32_cfg = { + .pclken = { + .enr = DT_CLOCKS_CELL(DT_NODELABEL(npu), bits), + .bus = DT_CLOCKS_CELL(DT_NODELABEL(npu), bus), + }, + .reset = RESET_DT_SPEC_GET(DT_NODELABEL(npu)), +}; + +DEVICE_DT_DEFINE(DT_NODELABEL(npu), npu_stm32_init, NULL, + NULL, &npu_stm32_cfg, POST_KERNEL, + CONFIG_APPLICATION_INIT_PRIORITY, NULL);