From 611a28ce271164941aac02feea19f1d87bd1cf32 Mon Sep 17 00:00:00 2001 From: "Chia-Wei, Wang" Date: Thu, 15 Oct 2020 10:25:13 +0800 Subject: reset: ast2500: Use SCU for reset control The System Control Unit (SCU) controller of Aspeed SoCs provides the reset control for each peripheral. This patch refactors the reset method to leverage the SCU reset control. Thus the driver dependency on watchdog including dedicated WDT API and reset flag encoding can be eliminated. The Kconfig description is also updated accordingly. Signed-off-by: Chia-Wei, Wang Reviewed-by: Ryan Chen --- drivers/reset/Kconfig | 9 ++-- drivers/reset/ast2500-reset.c | 97 +++++++++++++++++++++++-------------------- 2 files changed, 55 insertions(+), 51 deletions(-) (limited to 'drivers/reset') diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index b60e11f98b2..8b243fdcc66 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -74,13 +74,12 @@ config RESET_UNIPHIER config AST2500_RESET bool "Reset controller driver for AST2500 SoCs" - depends on DM_RESET && WDT_ASPEED + depends on DM_RESET default y if ASPEED_AST2500 help - Support for reset controller on AST2500 SoC. This controller uses - watchdog to reset different peripherals and thus only supports - resets that are supported by watchdog. The main limitation though - is that some reset signals, like I2C or MISC reset multiple devices. + Support for reset controller on AST2500 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" diff --git a/drivers/reset/ast2500-reset.c b/drivers/reset/ast2500-reset.c index beb5cd8fa8c..e7b5c7decab 100644 --- a/drivers/reset/ast2500-reset.c +++ b/drivers/reset/ast2500-reset.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright 2017 Google, Inc + * Copyright 2020 ASPEED Technology Inc. */ #include @@ -9,28 +10,26 @@ #include #include #include -#include +#include #include #include -#include struct ast2500_reset_priv { - /* WDT used to perform resets. */ - struct udevice *wdt; struct ast2500_scu *scu; }; -static int ast2500_ofdata_to_platdata(struct udevice *dev) +static int ast2500_reset_request(struct reset_ctl *reset_ctl) { - struct ast2500_reset_priv *priv = dev_get_priv(dev); - int ret; + debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, + reset_ctl->dev, reset_ctl->id); - ret = uclass_get_device_by_phandle(UCLASS_WDT, dev, "aspeed,wdt", - &priv->wdt); - if (ret) { - debug("%s: can't find WDT for reset controller", __func__); - return ret; - } + return 0; +} + +static int ast2500_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; } @@ -38,47 +37,52 @@ static int ast2500_ofdata_to_platdata(struct udevice *dev) static int ast2500_reset_assert(struct reset_ctl *reset_ctl) { struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev); - u32 reset_mode, reset_mask; - bool reset_sdram; - int ret; - - /* - * To reset SDRAM, a specifal flag in SYSRESET register - * needs to be enabled first - */ - reset_mode = ast_reset_mode_from_flags(reset_ctl->id); - reset_mask = ast_reset_mask_from_flags(reset_ctl->id); - reset_sdram = reset_mode == WDT_CTRL_RESET_SOC && - (reset_mask & WDT_RESET_SDRAM); - - if (reset_sdram) { - ast_scu_unlock(priv->scu); - setbits_le32(&priv->scu->sysreset_ctrl1, - SCU_SYSRESET_SDRAM_WDT); - ret = wdt_expire_now(priv->wdt, reset_ctl->id); - clrbits_le32(&priv->scu->sysreset_ctrl1, - SCU_SYSRESET_SDRAM_WDT); - ast_scu_lock(priv->scu); - } else { - ret = wdt_expire_now(priv->wdt, reset_ctl->id); - } + struct ast2500_scu *scu = priv->scu; + + debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); - return ret; + if (reset_ctl->id < 32) + setbits_le32(&scu->sysreset_ctrl1, BIT(reset_ctl->id)); + else + setbits_le32(&scu->sysreset_ctrl2, BIT(reset_ctl->id - 32)); + + return 0; } -static int ast2500_reset_request(struct reset_ctl *reset_ctl) +static int ast2500_reset_deassert(struct reset_ctl *reset_ctl) { - debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, - reset_ctl->dev, reset_ctl->id); + struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev); + struct ast2500_scu *scu = priv->scu; + + debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); + + if (reset_ctl->id < 32) + clrbits_le32(&scu->sysreset_ctrl1, BIT(reset_ctl->id)); + else + clrbits_le32(&scu->sysreset_ctrl2, BIT(reset_ctl->id - 32)); return 0; } static int ast2500_reset_probe(struct udevice *dev) { + int rc; struct ast2500_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_GET_DRIVER(aspeed_ast2500_scu), &scu_dev); + if (rc) { + debug("%s: clock device not found, rc=%d\n", __func__, rc); + return rc; + } - priv->scu = ast_get_scu(); + 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; } @@ -89,16 +93,17 @@ static const struct udevice_id ast2500_reset_ids[] = { }; struct reset_ops ast2500_reset_ops = { - .rst_assert = ast2500_reset_assert, .request = ast2500_reset_request, + .rfree = ast2500_reset_free, + .rst_assert = ast2500_reset_assert, + .rst_deassert = ast2500_reset_deassert, }; U_BOOT_DRIVER(ast2500_reset) = { - .name = "ast2500_reset", - .id = UCLASS_RESET, + .name = "ast2500_reset", + .id = UCLASS_RESET, .of_match = ast2500_reset_ids, .probe = ast2500_reset_probe, .ops = &ast2500_reset_ops, - .ofdata_to_platdata = ast2500_ofdata_to_platdata, .priv_auto_alloc_size = sizeof(struct ast2500_reset_priv), }; -- cgit v1.3.1 From b2424cd2f4337cd36aa635d3bc52485f150d8ae6 Mon Sep 17 00:00:00 2001 From: "Chia-Wei, Wang" Date: Thu, 15 Oct 2020 10:25:14 +0800 Subject: cosmetic: reset: ast2500: Rename driver and configs 1. Rename AST2500 reset driver from ast2500-reset.c to reset-ast2500.c 2. Rename AST2500 reset kconfig option from AST2500_RESET to RESET_AST2500 Signed-off-by: Chia-Wei, Wang Reviewed-by: Ryan Chen --- drivers/reset/Kconfig | 2 +- drivers/reset/Makefile | 2 +- drivers/reset/ast2500-reset.c | 109 ------------------------------------------ drivers/reset/reset-ast2500.c | 109 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+), 111 deletions(-) delete mode 100644 drivers/reset/ast2500-reset.c create mode 100644 drivers/reset/reset-ast2500.c (limited to 'drivers/reset') diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 8b243fdcc66..33c2736554e 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -72,7 +72,7 @@ config RESET_UNIPHIER Say Y if you want to control reset signals provided by System Control block, Media I/O block, Peripheral Block. -config AST2500_RESET +config RESET_AST2500 bool "Reset controller driver for AST2500 SoCs" depends on DM_RESET default y if ASPEED_AST2500 diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 10a7973f823..fa52aa33291 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o -obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o +obj-$(CONFIG_RESET_AST2500) += reset-ast2500.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/ast2500-reset.c b/drivers/reset/ast2500-reset.c deleted file mode 100644 index e7b5c7decab..00000000000 --- a/drivers/reset/ast2500-reset.c +++ /dev/null @@ -1,109 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright 2017 Google, Inc - * Copyright 2020 ASPEED Technology Inc. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct ast2500_reset_priv { - struct ast2500_scu *scu; -}; - -static int ast2500_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 ast2500_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 ast2500_reset_assert(struct reset_ctl *reset_ctl) -{ - struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev); - struct ast2500_scu *scu = priv->scu; - - debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); - - if (reset_ctl->id < 32) - setbits_le32(&scu->sysreset_ctrl1, BIT(reset_ctl->id)); - else - setbits_le32(&scu->sysreset_ctrl2, BIT(reset_ctl->id - 32)); - - return 0; -} - -static int ast2500_reset_deassert(struct reset_ctl *reset_ctl) -{ - struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev); - struct ast2500_scu *scu = priv->scu; - - debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); - - if (reset_ctl->id < 32) - clrbits_le32(&scu->sysreset_ctrl1, BIT(reset_ctl->id)); - else - clrbits_le32(&scu->sysreset_ctrl2, BIT(reset_ctl->id - 32)); - - return 0; -} - -static int ast2500_reset_probe(struct udevice *dev) -{ - int rc; - struct ast2500_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_GET_DRIVER(aspeed_ast2500_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 ast2500_reset_ids[] = { - { .compatible = "aspeed,ast2500-reset" }, - { } -}; - -struct reset_ops ast2500_reset_ops = { - .request = ast2500_reset_request, - .rfree = ast2500_reset_free, - .rst_assert = ast2500_reset_assert, - .rst_deassert = ast2500_reset_deassert, -}; - -U_BOOT_DRIVER(ast2500_reset) = { - .name = "ast2500_reset", - .id = UCLASS_RESET, - .of_match = ast2500_reset_ids, - .probe = ast2500_reset_probe, - .ops = &ast2500_reset_ops, - .priv_auto_alloc_size = sizeof(struct ast2500_reset_priv), -}; diff --git a/drivers/reset/reset-ast2500.c b/drivers/reset/reset-ast2500.c new file mode 100644 index 00000000000..e7b5c7decab --- /dev/null +++ b/drivers/reset/reset-ast2500.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2017 Google, Inc + * Copyright 2020 ASPEED Technology Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ast2500_reset_priv { + struct ast2500_scu *scu; +}; + +static int ast2500_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 ast2500_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 ast2500_reset_assert(struct reset_ctl *reset_ctl) +{ + struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev); + struct ast2500_scu *scu = priv->scu; + + debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); + + if (reset_ctl->id < 32) + setbits_le32(&scu->sysreset_ctrl1, BIT(reset_ctl->id)); + else + setbits_le32(&scu->sysreset_ctrl2, BIT(reset_ctl->id - 32)); + + return 0; +} + +static int ast2500_reset_deassert(struct reset_ctl *reset_ctl) +{ + struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev); + struct ast2500_scu *scu = priv->scu; + + debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); + + if (reset_ctl->id < 32) + clrbits_le32(&scu->sysreset_ctrl1, BIT(reset_ctl->id)); + else + clrbits_le32(&scu->sysreset_ctrl2, BIT(reset_ctl->id - 32)); + + return 0; +} + +static int ast2500_reset_probe(struct udevice *dev) +{ + int rc; + struct ast2500_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_GET_DRIVER(aspeed_ast2500_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 ast2500_reset_ids[] = { + { .compatible = "aspeed,ast2500-reset" }, + { } +}; + +struct reset_ops ast2500_reset_ops = { + .request = ast2500_reset_request, + .rfree = ast2500_reset_free, + .rst_assert = ast2500_reset_assert, + .rst_deassert = ast2500_reset_deassert, +}; + +U_BOOT_DRIVER(ast2500_reset) = { + .name = "ast2500_reset", + .id = UCLASS_RESET, + .of_match = ast2500_reset_ids, + .probe = ast2500_reset_probe, + .ops = &ast2500_reset_ops, + .priv_auto_alloc_size = sizeof(struct ast2500_reset_priv), +}; -- cgit v1.3.1