diff options
Diffstat (limited to 'drivers/reset')
-rw-r--r-- | drivers/reset/Kconfig | 9 | ||||
-rw-r--r-- | drivers/reset/Makefile | 1 | ||||
-rw-r--r-- | drivers/reset/reset-ast2600.c | 108 | ||||
-rw-r--r-- | drivers/reset/stm32-reset.c | 13 |
4 files changed, 127 insertions, 4 deletions
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 33c2736554e..f5b3f8826fb 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -81,6 +81,15 @@ config RESET_AST2500 Say Y if you want to control reset signals of different peripherals through System Control Unit (SCU). +config RESET_AST2600 + bool "Reset controller driver for AST2600 SoCs" + depends on DM_RESET + default y if ASPEED_AST2600 + help + Support for reset controller on AST2600 SoC. + Say Y if you want to control reset signals of different peripherals + through System Control Unit (SCU). + config RESET_ROCKCHIP bool "Reset controller driver for Rockchip SoCs" depends on DM_RESET && ARCH_ROCKCHIP && CLK diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index fa52aa33291..8a0f5280761 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o obj-$(CONFIG_RESET_AST2500) += reset-ast2500.o +obj-$(CONFIG_RESET_AST2600) += reset-ast2600.o obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o obj-$(CONFIG_RESET_MESON) += reset-meson.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o diff --git a/drivers/reset/reset-ast2600.c b/drivers/reset/reset-ast2600.c new file mode 100644 index 00000000000..f64adaf74e8 --- /dev/null +++ b/drivers/reset/reset-ast2600.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2020 ASPEED Technology Inc. + */ + +#include <common.h> +#include <dm.h> +#include <log.h> +#include <misc.h> +#include <reset.h> +#include <reset-uclass.h> +#include <linux/err.h> +#include <asm/io.h> +#include <asm/arch/scu_ast2600.h> + +struct ast2600_reset_priv { + struct ast2600_scu *scu; +}; + +static int ast2600_reset_request(struct reset_ctl *reset_ctl) +{ + debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, + reset_ctl->dev, reset_ctl->id); + + return 0; +} + +static int ast2600_reset_free(struct reset_ctl *reset_ctl) +{ + debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, + reset_ctl->dev, reset_ctl->id); + + return 0; +} + +static int ast2600_reset_assert(struct reset_ctl *reset_ctl) +{ + struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev); + struct ast2600_scu *scu = priv->scu; + + debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); + + if (reset_ctl->id < 32) + writel(BIT(reset_ctl->id), scu->modrst_ctrl1); + else + writel(BIT(reset_ctl->id - 32), scu->modrst_ctrl2); + + return 0; +} + +static int ast2600_reset_deassert(struct reset_ctl *reset_ctl) +{ + struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev); + struct ast2600_scu *scu = priv->scu; + + debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); + + if (reset_ctl->id < 32) + writel(BIT(reset_ctl->id), scu->modrst_clr1); + else + writel(BIT(reset_ctl->id - 32), scu->modrst_clr2); + + return 0; +} + +static int ast2600_reset_probe(struct udevice *dev) +{ + int rc; + struct ast2600_reset_priv *priv = dev_get_priv(dev); + struct udevice *scu_dev; + + /* get SCU base from clock device */ + rc = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(aspeed_ast2600_scu), &scu_dev); + if (rc) { + debug("%s: clock device not found, rc=%d\n", __func__, rc); + return rc; + } + + priv->scu = devfdt_get_addr_ptr(scu_dev); + if (IS_ERR_OR_NULL(priv->scu)) { + debug("%s: invalid SCU base pointer\n", __func__); + return PTR_ERR(priv->scu); + } + + return 0; +} + +static const struct udevice_id ast2600_reset_ids[] = { + { .compatible = "aspeed,ast2600-reset" }, + { } +}; + +struct reset_ops ast2600_reset_ops = { + .request = ast2600_reset_request, + .rfree = ast2600_reset_free, + .rst_assert = ast2600_reset_assert, + .rst_deassert = ast2600_reset_deassert, +}; + +U_BOOT_DRIVER(ast2600_reset) = { + .name = "ast2600_reset", + .id = UCLASS_RESET, + .of_match = ast2600_reset_ids, + .probe = ast2600_reset_probe, + .ops = &ast2600_reset_ops, + .priv_auto = sizeof(struct ast2600_reset_priv), +}; diff --git a/drivers/reset/stm32-reset.c b/drivers/reset/stm32-reset.c index b84c9daec74..daa2e47ebbe 100644 --- a/drivers/reset/stm32-reset.c +++ b/drivers/reset/stm32-reset.c @@ -4,6 +4,8 @@ * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. */ +#define LOG_CATEGORY UCLASS_RESET + #include <common.h> #include <dm.h> #include <errno.h> @@ -12,6 +14,7 @@ #include <reset-uclass.h> #include <stm32_rcc.h> #include <asm/io.h> +#include <dm/device_compat.h> #include <linux/bitops.h> /* offset of register without set/clear management */ @@ -39,8 +42,9 @@ static int stm32_reset_assert(struct reset_ctl *reset_ctl) struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev); int bank = (reset_ctl->id / BITS_PER_LONG) * 4; int offset = reset_ctl->id % BITS_PER_LONG; - debug("%s: reset id = %ld bank = %d offset = %d)\n", __func__, - reset_ctl->id, bank, offset); + + dev_dbg(reset_ctl->dev, "reset id = %ld bank = %d offset = %d)\n", + reset_ctl->id, bank, offset); if (dev_get_driver_data(reset_ctl->dev) == STM32MP1) if (bank != RCC_MP_GCR_OFFSET) @@ -59,8 +63,9 @@ static int stm32_reset_deassert(struct reset_ctl *reset_ctl) struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev); int bank = (reset_ctl->id / BITS_PER_LONG) * 4; int offset = reset_ctl->id % BITS_PER_LONG; - debug("%s: reset id = %ld bank = %d offset = %d)\n", __func__, - reset_ctl->id, bank, offset); + + dev_dbg(reset_ctl->dev, "reset id = %ld bank = %d offset = %d)\n", + reset_ctl->id, bank, offset); if (dev_get_driver_data(reset_ctl->dev) == STM32MP1) if (bank != RCC_MP_GCR_OFFSET) |