From 0994a627c27849f616b6d145508aed6bb8acc33d Mon Sep 17 00:00:00 2001 From: Gabriel Fernandez Date: Tue, 27 May 2025 15:27:53 +0200 Subject: reset: stm32mp25: add stm32mp25 reset driver Implement STM32MP25 reset drivers using stm32-core-reset API. This reset stm32-reset-core API and will be able to use DT binding index started from 0. This patch also moves legacy reset into stm32 directory reset. Signed-off-by: Gabriel Fernandez Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- drivers/reset/stm32/stm32-reset-core.c | 92 ++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 drivers/reset/stm32/stm32-reset-core.c (limited to 'drivers/reset/stm32/stm32-reset-core.c') diff --git a/drivers/reset/stm32/stm32-reset-core.c b/drivers/reset/stm32/stm32-reset-core.c new file mode 100644 index 00000000000..7dd92e07e1a --- /dev/null +++ b/drivers/reset/stm32/stm32-reset-core.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause +/* + * Copyright (C) 2024, STMicroelectronics - All Rights Reserved + * Author(s): Gabriel Fernandez, for STMicroelectronics. + */ + +#include +#include +#include +#include +#include +#include + +static int stm32_reset_update(struct reset_ctl *reset_ctl, bool status) +{ + struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev); + const struct stm32_reset_data *data = priv->data; + const struct stm32_reset_cfg *ptr_line; + fdt_addr_t addr; + + assert(priv->data->get_reset_line); + + ptr_line = priv->data->get_reset_line(reset_ctl); + if (!ptr_line) + return -EPERM; + + addr = priv->base + ptr_line->offset; + + dev_dbg(reset_ctl->dev, "reset id=%ld offset=0x%x bit=%d status=%d\n", + reset_ctl->id, ptr_line->offset, ptr_line->bit_idx, status); + + status = ptr_line->inverted ^ status; + + if (ptr_line->set_clr) { + if (!status) + addr += data->clear_offset; + + writel(BIT(ptr_line->bit_idx), addr); + + } else { + if (status) + setbits_le32(addr, BIT(ptr_line->bit_idx)); + else + clrbits_le32(addr, BIT(ptr_line->bit_idx)); + } + + /* Check deassert */ + if (!status) { + u32 reg; + + return readl_poll_timeout(addr, reg, + !(reg & BIT(ptr_line->bit_idx)), + data->reset_us); + } + + return 0; +} + +static int stm32_reset_assert(struct reset_ctl *reset_ctl) +{ + return stm32_reset_update(reset_ctl, true); +} + +static int stm32_reset_deassert(struct reset_ctl *reset_ctl) +{ + return stm32_reset_update(reset_ctl, false); +} + +const struct reset_ops stm32_reset_ops = { + .rst_assert = stm32_reset_assert, + .rst_deassert = stm32_reset_deassert, +}; + +int stm32_reset_core_probe(struct udevice *dev, + const struct stm32_reset_data *data) +{ + struct stm32_reset_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr(dev); + if (priv->base == FDT_ADDR_T_NONE) { + /* for MFD, get address of parent */ + priv->base = dev_read_addr(dev->parent); + if (priv->base == FDT_ADDR_T_NONE) + return -EINVAL; + } + + priv->data = data; + + assert(priv->data); + + return 0; +} -- cgit v1.2.3