From d6f8e9ae5baedde84df4757fed44e04105abb868 Mon Sep 17 00:00:00 2001 From: Patryk Duda Date: Tue, 22 Nov 2022 15:52:52 +0100 Subject: [PATCH] drivers: reset: Introduce STM32 reset controller This driver exposes STM32 RCC reset functionality through reset API. Information about RCC register offset and bit is encoded just like GD32. The first 5 least significant bits contains register bit number. Next 12 bits are used to keep RCC register offset. Remaining bits are unused. Signed-off-by: Patryk Duda --- drivers/reset/CMakeLists.txt | 1 + drivers/reset/Kconfig | 1 + drivers/reset/Kconfig.stm32 | 7 ++ drivers/reset/reset_stm32.c | 78 +++++++++++++++++++ dts/bindings/reset/st,stm32-rcc-rctl.yaml | 31 ++++++++ .../zephyr/dt-bindings/reset/stm32-common.h | 22 ++++++ 6 files changed, 140 insertions(+) create mode 100644 drivers/reset/Kconfig.stm32 create mode 100644 drivers/reset/reset_stm32.c create mode 100644 dts/bindings/reset/st,stm32-rcc-rctl.yaml create mode 100644 include/zephyr/dt-bindings/reset/stm32-common.h diff --git a/drivers/reset/CMakeLists.txt b/drivers/reset/CMakeLists.txt index 742c9a6fda7..a589886a4da 100644 --- a/drivers/reset/CMakeLists.txt +++ b/drivers/reset/CMakeLists.txt @@ -4,3 +4,4 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_RESET_GD32 reset_gd32.c) zephyr_library_sources_ifdef(CONFIG_RESET_RPI_PICO reset_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_RESET_AST10X0 reset_ast10x0.c) +zephyr_library_sources_ifdef(CONFIG_RESET_STM32 reset_stm32.c) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 1217434346c..063eccde7c4 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -30,5 +30,6 @@ comment "Reset Controller Drivers" rsource "Kconfig.rpi_pico" rsource "Kconfig.gd32" rsource "Kconfig.aspeed" +rsource "Kconfig.stm32" endif # RESET diff --git a/drivers/reset/Kconfig.stm32 b/drivers/reset/Kconfig.stm32 new file mode 100644 index 00000000000..873567f382a --- /dev/null +++ b/drivers/reset/Kconfig.stm32 @@ -0,0 +1,7 @@ +# Copyright (c) 2022 Google Inc +# SPDX-License-Identifier: Apache-2.0 + +config RESET_STM32 + bool "STM32 Reset Controller Driver" + default y + depends on DT_HAS_ST_STM32_RCC_RCTL_ENABLED diff --git a/drivers/reset/reset_stm32.c b/drivers/reset/reset_stm32.c new file mode 100644 index 00000000000..814c2567daa --- /dev/null +++ b/drivers/reset/reset_stm32.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022 Google Inc + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT st_stm32_rcc_rctl + +#include +#include +#include +#include + +#define STM32_RESET_SET_OFFSET(id) (((id) >> 5U) & 0xFFFU) +#define STM32_RESET_REG_BIT(id) ((id)&0x1FU) + +struct reset_stm32_config { + uintptr_t base; +}; + +static int reset_stm32_status(const struct device *dev, uint32_t id, + uint8_t *status) +{ + const struct reset_stm32_config *config = dev->config; + + *status = !!sys_test_bit(config->base + STM32_RESET_SET_OFFSET(id), + STM32_RESET_REG_BIT(id)); + + return 0; +} + +static int reset_stm32_line_assert(const struct device *dev, uint32_t id) +{ + const struct reset_stm32_config *config = dev->config; + + sys_set_bit(config->base + STM32_RESET_SET_OFFSET(id), + STM32_RESET_REG_BIT(id)); + + return 0; +} + +static int reset_stm32_line_deassert(const struct device *dev, uint32_t id) +{ + const struct reset_stm32_config *config = dev->config; + + sys_clear_bit(config->base + STM32_RESET_SET_OFFSET(id), + STM32_RESET_REG_BIT(id)); + + return 0; +} + +static int reset_stm32_line_toggle(const struct device *dev, uint32_t id) +{ + reset_stm32_line_assert(dev, id); + reset_stm32_line_deassert(dev, id); + + return 0; +} + +static int reset_stm32_init(const struct device *dev) +{ + return 0; +} + +static const struct reset_driver_api reset_stm32_driver_api = { + .status = reset_stm32_status, + .line_assert = reset_stm32_line_assert, + .line_deassert = reset_stm32_line_deassert, + .line_toggle = reset_stm32_line_toggle, +}; + +static const struct reset_stm32_config reset_stm32_config = { + .base = DT_REG_ADDR(DT_INST_PARENT(0)), +}; + +DEVICE_DT_INST_DEFINE(0, reset_stm32_init, NULL, NULL, &reset_stm32_config, + PRE_KERNEL_1, CONFIG_RESET_INIT_PRIORITY, + &reset_stm32_driver_api); diff --git a/dts/bindings/reset/st,stm32-rcc-rctl.yaml b/dts/bindings/reset/st,stm32-rcc-rctl.yaml new file mode 100644 index 00000000000..685fb43b1c9 --- /dev/null +++ b/dts/bindings/reset/st,stm32-rcc-rctl.yaml @@ -0,0 +1,31 @@ +# Copyright (c) 2022, Google Inc +# SPDX-License-Identifier: Apache-2.0 + +description: | + STM32 Reset and Clock Control (RCC) node. + This node is in charge of reset control for AHB (Advanced High Performance) + and APB (Advanced Peripheral) bus domains. + + To specify the reset line in a peripheral, the standard resets property needs + to be used, e.g.: + + usart1: serial@xxx { + ... + /* Cell contains information about RCU register offset and bit */ + resets = <&rctl STM32_RESET(ABP2, 4U)>; + ... + }; + + RCC reset cells are available in + include/zephyr/dts-bindings/reset/stm32{soc_family}_reset.h header files. + +compatible: "st,stm32-rcc-rctl" + +include: [reset-controller.yaml, base.yaml] + +properties: + "#reset-cells": + const: 1 + +reset-cells: + - id diff --git a/include/zephyr/dt-bindings/reset/stm32-common.h b/include/zephyr/dt-bindings/reset/stm32-common.h new file mode 100644 index 00000000000..814a986e0e4 --- /dev/null +++ b/include/zephyr/dt-bindings/reset/stm32-common.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 Google Inc + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RESET_STM32_RESET_COMMON_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RESET_STM32_RESET_COMMON_H_ + +/** + * Pack RCC register offset and bit in one 32-bit value. + * + * 5 LSBs are used to keep bit number in 32-bit RCC register. + * Next 12 bits are used to keep RCC register offset. + * Remaining bits are unused. + * + * @param bus STM32 bus name (expands to STM32_RESET_BUS_{bus}) + * @param bit Reset bit + */ +#define STM32_RESET(bus, bit) (((STM32_RESET_BUS_##bus) << 5U) | (bit)) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RESET_STM32_RESET_COMMON_H_ */