From 84619fe8f7eb0c30affb29bc44e3a8e48e1f1d1d Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Thu, 19 Jun 2025 18:40:51 +0200 Subject: [PATCH] drivers: misc: stm32n6: ramcfg driver Add a driver to handle AXISRAM3/4/5/6 configurations. Provide the required changes to add RAM sections into the build system. Signed-off-by: Erwan Gouriou --- drivers/misc/CMakeLists.txt | 1 + drivers/misc/Kconfig | 1 + drivers/misc/stm32n6_axisram/CMakeLists.txt | 6 ++ drivers/misc/stm32n6_axisram/Kconfig | 7 ++ .../misc/stm32n6_axisram/stm32n6_axisram.c | 80 +++++++++++++++++++ 5 files changed, 95 insertions(+) create mode 100644 drivers/misc/stm32n6_axisram/CMakeLists.txt create mode 100644 drivers/misc/stm32n6_axisram/Kconfig create mode 100644 drivers/misc/stm32n6_axisram/stm32n6_axisram.c diff --git a/drivers/misc/CMakeLists.txt b/drivers/misc/CMakeLists.txt index 051a285785f..437bd124247 100644 --- a/drivers/misc/CMakeLists.txt +++ b/drivers/misc/CMakeLists.txt @@ -13,6 +13,7 @@ add_subdirectory_ifdef(CONFIG_MCUX_FLEXIO mcux_flexio) add_subdirectory_ifdef(CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT renesas_ra_external_interrupt) add_subdirectory_ifdef(CONFIG_RENESAS_RX_EXTERNAL_INTERRUPT renesas_rx_external_interrupt) add_subdirectory_ifdef(CONFIG_NXP_RTXXX_DSP_CTRL nxp_rtxxx_dsp_ctrl) +add_subdirectory_ifdef(CONFIG_STM32N6_AXISRAM stm32n6_axisram) add_subdirectory(coresight) add_subdirectory(interconn) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 715bcb68e61..2fd046e2430 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -20,5 +20,6 @@ source "drivers/misc/interconn/Kconfig" source "drivers/misc/renesas_ra_external_interrupt/Kconfig" source "drivers/misc/renesas_rx_external_interrupt/Kconfig" source "drivers/misc/nxp_rtxxx_dsp_ctrl/Kconfig" +source "drivers/misc/stm32n6_axisram/Kconfig" endmenu diff --git a/drivers/misc/stm32n6_axisram/CMakeLists.txt b/drivers/misc/stm32n6_axisram/CMakeLists.txt new file mode 100644 index 00000000000..ed8c6167336 --- /dev/null +++ b/drivers/misc/stm32n6_axisram/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(stm32n6_axisram.c) diff --git a/drivers/misc/stm32n6_axisram/Kconfig b/drivers/misc/stm32n6_axisram/Kconfig new file mode 100644 index 00000000000..b6c2493ac6e --- /dev/null +++ b/drivers/misc/stm32n6_axisram/Kconfig @@ -0,0 +1,7 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config STM32N6_AXISRAM + bool + select USE_STM32_HAL_RAMCFG + default y if DT_HAS_ST_STM32N6_RAMCFG_ENABLED diff --git a/drivers/misc/stm32n6_axisram/stm32n6_axisram.c b/drivers/misc/stm32n6_axisram/stm32n6_axisram.c new file mode 100644 index 00000000000..c8f545089c2 --- /dev/null +++ b/drivers/misc/stm32n6_axisram/stm32n6_axisram.c @@ -0,0 +1,80 @@ +/* + * Copyright 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include + +#include + +#define DT_DRV_COMPAT st_stm32n6_ramcfg + +/* Read-only driver configuration */ +struct axisram_stm32_cfg { + /* RAMCFG instance. */ + RAMCFG_TypeDef *base; + /* SRAM Clock configuration. */ + struct stm32_pclken pclken_axisram; + /* RAMCFG Clock configuration. */ + struct stm32_pclken pclken_ramcfg; +}; + +static int axisram_stm32_init(const struct device *dev) +{ + const struct axisram_stm32_cfg *cfg = dev->config; + RAMCFG_HandleTypeDef ramcfg = {0}; + /* enable clock for subsystem */ + const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); + + if (!device_is_ready(clk)) { + return -ENODEV; + } + + if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken_ramcfg) != 0) { + return -EIO; + } + + if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken_axisram) != 0) { + return -EIO; + } + + ramcfg.Instance = cfg->base; + HAL_RAMCFG_EnableAXISRAM(&ramcfg); + + return 0; +} + +/** + * On other series which have no RAMCFG, whether RAMs are enabled + * or not can be controlled by changing their "status" in Device Tree. + * To match this behavior on N6, we check manually during instantation + * of RAMCFG nodes whether they have an enabled child (= RAM node) and + * perform our own instantiation only if so thanks to COND_CODE. + */ +#define STM32N6_AXISRAM_INIT(idx) \ + \ +COND_CODE_0(DT_INST_CHILD_NUM_STATUS_OKAY(idx), (), ( \ + \ +static const struct axisram_stm32_cfg axisram_stm32_cfg_##idx = { \ + .base = (RAMCFG_TypeDef *)DT_INST_REG_ADDR(idx), \ + .pclken_axisram = { \ + .enr = DT_INST_CLOCKS_CELL_BY_NAME(idx, axisram, bits), \ + .bus = DT_INST_CLOCKS_CELL_BY_NAME(idx, axisram, bus), \ + }, \ + .pclken_ramcfg = { \ + .enr = DT_INST_CLOCKS_CELL_BY_NAME(idx, ramcfg, bits), \ + .bus = DT_INST_CLOCKS_CELL_BY_NAME(idx, ramcfg, bus), \ + }, \ +}; \ + \ +DEVICE_DT_INST_DEFINE(idx, &axisram_stm32_init, NULL, \ + NULL, &axisram_stm32_cfg_##idx, \ + PRE_KERNEL_2, 0, NULL);)) + +DT_INST_FOREACH_STATUS_OKAY(STM32N6_AXISRAM_INIT)