diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index ce63b00c874..c2b5eb9fdbd 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -67,6 +67,8 @@ if(CONFIG_SOC_SERIES_STM32MP1X) zephyr_library_sources(clock_stm32_ll_mp1.c) elseif(CONFIG_SOC_SERIES_STM32MP13X) zephyr_library_sources(clock_stm32_ll_mp13.c) +elseif(CONFIG_SOC_SERIES_STM32MP2X) + zephyr_library_sources(clock_stm32_ll_mp2.c) elseif(CONFIG_SOC_SERIES_STM32H7X) zephyr_library_sources(clock_stm32_ll_h7.c) elseif(CONFIG_SOC_SERIES_STM32H7RSX) diff --git a/drivers/clock_control/clock_stm32_ll_mp2.c b/drivers/clock_control/clock_stm32_ll_mp2.c new file mode 100644 index 00000000000..0164c67a9e0 --- /dev/null +++ b/drivers/clock_control/clock_stm32_ll_mp2.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2025 Savoir-faire Linux, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +static int stm32_clock_control_on(const struct device *dev, clock_control_subsys_t sub_system) +{ + struct stm32_pclken *pclken = (struct stm32_pclken *) sub_system; + + ARG_UNUSED(dev); + + if (!IN_RANGE(pclken->bus, STM32_CLOCK_PERIPH_MIN, STM32_CLOCK_PERIPH_MAX)) { + /* Attempt to change a wrong periph clock bit */ + return -ENOTSUP; + } + + sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus, pclken->enr); + + return 0; +} + +static int stm32_clock_control_off(const struct device *dev, clock_control_subsys_t sub_system) +{ + struct stm32_pclken *pclken = (struct stm32_pclken *) sub_system; + + ARG_UNUSED(dev); + + if (!IN_RANGE(pclken->bus, STM32_CLOCK_PERIPH_MIN, STM32_CLOCK_PERIPH_MAX)) { + /* Attempt to toggle a wrong periph clock bit */ + return -ENOTSUP; + } + + sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus, pclken->enr); + + return 0; +} + +static int stm32_clock_control_get_subsys_rate(const struct device *dev, + clock_control_subsys_t sub_system, uint32_t *rate) +{ + ARG_UNUSED(dev); + ARG_UNUSED(sub_system); + ARG_UNUSED(rate); + return -ENOTSUP; +} + +static DEVICE_API(clock_control, stm32_clock_control_api) = { + .on = stm32_clock_control_on, + .off = stm32_clock_control_off, + .get_rate = stm32_clock_control_get_subsys_rate, +}; + +static int stm32_clock_control_init(const struct device *dev) +{ + ARG_UNUSED(dev); + return 0; +} + +/** + * @brief RCC device, note that priority is intentionally set to 1 so + * that the device init runs just after SOC init + */ +DEVICE_DT_DEFINE(DT_NODELABEL(rcc), stm32_clock_control_init, NULL, NULL, NULL, PRE_KERNEL_1, + CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &stm32_clock_control_api); diff --git a/include/zephyr/drivers/clock_control/stm32_clock_control.h b/include/zephyr/drivers/clock_control/stm32_clock_control.h index 8ae23a1233c..d6e710a89ab 100644 --- a/include/zephyr/drivers/clock_control/stm32_clock_control.h +++ b/include/zephyr/drivers/clock_control/stm32_clock_control.h @@ -41,6 +41,8 @@ #elif defined(CONFIG_SOC_SERIES_STM32L4X) || \ defined(CONFIG_SOC_SERIES_STM32L5X) #include +#elif defined(CONFIG_SOC_SERIES_STM32MP2X) +#include #elif defined(CONFIG_SOC_SERIES_STM32WBX) #include #elif defined(CONFIG_SOC_SERIES_STM32WB0X)