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 <pdk@semihalf.com>
This commit is contained in:
Patryk Duda 2022-11-22 15:52:52 +01:00 committed by Marti Bolivar
parent bd428663e9
commit d6f8e9ae5b
6 changed files with 140 additions and 0 deletions

View File

@ -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)

View File

@ -30,5 +30,6 @@ comment "Reset Controller Drivers"
rsource "Kconfig.rpi_pico"
rsource "Kconfig.gd32"
rsource "Kconfig.aspeed"
rsource "Kconfig.stm32"
endif # RESET

View File

@ -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

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2022 Google Inc
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT st_stm32_rcc_rctl
#include <zephyr/arch/cpu.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/reset.h>
#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);

View File

@ -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

View File

@ -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_ */