> -----Original Message----- > From: ChiaWei Wang <chiawei_w...@aspeedtech.com> > Sent: Monday, October 12, 2020 10:36 AM > To: tr...@konsulko.com; u-boot@lists.denx.de; max...@google.com > Cc: Ryan Chen <ryan_c...@aspeedtech.com>; BMC-SW > <bmc...@aspeedtech.com> > Subject: [v2 1/2] 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 <chiawei_w...@aspeedtech.com>
Reviewed-by: Ryan Chen <ryan_c...@aspeedtech.com> > --- > arch/arm/dts/ast2500-u-boot.dtsi | 7 +- > drivers/reset/Kconfig | 9 +-- > drivers/reset/ast2500-reset.c | 97 ++++++++++++----------- > include/dt-bindings/reset/ast2500-reset.h | 73 +++++++++-------- > 4 files changed, 97 insertions(+), 89 deletions(-) > > diff --git a/arch/arm/dts/ast2500-u-boot.dtsi > b/arch/arm/dts/ast2500-u-boot.dtsi > index 51a5244766..ea60e4c8db 100644 > --- a/arch/arm/dts/ast2500-u-boot.dtsi > +++ b/arch/arm/dts/ast2500-u-boot.dtsi > @@ -16,7 +16,6 @@ > rst: reset-controller { > u-boot,dm-pre-reloc; > compatible = "aspeed,ast2500-reset"; > - aspeed,wdt = <&wdt1>; > #reset-cells = <1>; > }; > > @@ -27,7 +26,7 @@ > 0x1e6e0200 0x1d4 >; > #reset-cells = <1>; > clocks = <&scu ASPEED_CLK_MPLL>; > - resets = <&rst AST_RESET_SDRAM>; > + resets = <&rst ASPEED_RESET_SDRAM>; > }; > > ahb { > @@ -41,7 +40,7 @@ > reg = <0x1e740100>; > #reset-cells = <1>; > clocks = <&scu ASPEED_CLK_SDIO>; > - resets = <&rst AST_RESET_SDIO>; > + resets = <&rst ASPEED_RESET_SDIO>; > }; > > sdhci1: sdhci@1e740200 { > @@ -49,7 +48,7 @@ > reg = <0x1e740200>; > #reset-cells = <1>; > clocks = <&scu ASPEED_CLK_SDIO>; > - resets = <&rst AST_RESET_SDIO>; > + resets = <&rst ASPEED_RESET_SDIO>; > }; > }; > > diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index > b60e11f98b..8b243fdcc6 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 > beb5cd8fa8..e7b5c7deca 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 <common.h> > @@ -9,28 +10,26 @@ > #include <misc.h> > #include <reset.h> > #include <reset-uclass.h> > -#include <wdt.h> > +#include <linux/err.h> > #include <asm/io.h> > #include <asm/arch/scu_ast2500.h> > -#include <asm/arch/wdt.h> > > 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), }; diff > --git > a/include/dt-bindings/reset/ast2500-reset.h > b/include/dt-bindings/reset/ast2500-reset.h > index d1b6b23fc1..cc85a31edf 100644 > --- a/include/dt-bindings/reset/ast2500-reset.h > +++ b/include/dt-bindings/reset/ast2500-reset.h > @@ -1,44 +1,49 @@ > /* SPDX-License-Identifier: GPL-2.0+ */ > /* > * Copyright 2017 Google, Inc > + * Copyright 2020 ASPEED Technology Inc. > */ > > #ifndef _ABI_MACH_ASPEED_AST2500_RESET_H_ #define > _ABI_MACH_ASPEED_AST2500_RESET_H_ > > -/* > - * The values are intentionally layed out as flags in > - * WDT reset parameter. > - */ > - > -#define AST_RESET_SOC 0 > -#define AST_RESET_CHIP 1 > -#define AST_RESET_CPU (1 << 1) > -#define AST_RESET_ARM (1 << 2) > -#define AST_RESET_COPROC (1 << 3) > -#define AST_RESET_SDRAM (1 << 4) > -#define AST_RESET_AHB (1 << 5) > -#define AST_RESET_I2C (1 << 6) > -#define AST_RESET_MAC1 (1 << 7) > -#define AST_RESET_MAC2 (1 << 8) > -#define AST_RESET_GCRT (1 << 9) > -#define AST_RESET_USB20 (1 << 10) > -#define AST_RESET_USB11_HOST (1 << 11) > -#define AST_RESET_USB11_HID (1 << 12) > -#define AST_RESET_VIDEO (1 << 13) > -#define AST_RESET_HAC (1 << 14) > -#define AST_RESET_LPC (1 << 15) > -#define AST_RESET_SDIO (1 << 16) > -#define AST_RESET_MIC (1 << 17) > -#define AST_RESET_CRT2D (1 << 18) > -#define AST_RESET_PWM (1 << 19) > -#define AST_RESET_PECI (1 << 20) > -#define AST_RESET_JTAG (1 << 21) > -#define AST_RESET_ADC (1 << 22) > -#define AST_RESET_GPIO (1 << 23) > -#define AST_RESET_MCTP (1 << 24) > -#define AST_RESET_XDMA (1 << 25) > -#define AST_RESET_SPI (1 << 26) > -#define AST_RESET_MISC (1 << 27) > +#define ASPEED_RESET_CRT1 (37) > +#define ASPEED_RESET_RESERVED36 (36) > +#define ASPEED_RESET_RESERVED35 (35) > +#define ASPEED_RESET_RESERVED34 (34) > +#define ASPEED_RESET_RESERVED33 (33) > +#define ASPEED_RESET_RESERVED32 (32) > +#define ASPEED_RESET_RESERVED31 (31) > +#define ASPEED_RESET_RESERVED30 (30) > +#define ASPEED_RESET_RESERVED29 (29) > +#define ASPEED_RESET_RESERVED28 (28) > +#define ASPEED_RESET_RESERVED27 (27) > +#define ASPEED_RESET_RESERVED26 (26) > +#define ASPEED_RESET_XDMA (25) > +#define ASPEED_RESET_MCTP (24) > +#define ASPEED_RESET_ADC (23) > +#define ASPEED_RESET_JTAG_MASTER (22) > +#define ASPEED_RESET_RESERVED21 (21) > +#define ASPEED_RESET_RESERVED20 (20) > +#define ASPEED_RESET_RESERVED19 (19) > +#define ASPEED_RESET_MIC (18) > +#define ASPEED_RESET_RESERVED17 (17) > +#define ASPEED_RESET_SDIO (16) > +#define ASPEED_RESET_UHCI (15) > +#define ASPEED_RESET_EHCI_P1 (14) > +#define ASPEED_RESET_CRT (13) > +#define ASPEED_RESET_MAC2 (12) > +#define ASPEED_RESET_MAC1 (11) > +#define ASPEED_RESET_PECI (10) > +#define ASPEED_RESET_PWM (9) > +#define ASPEED_RESET_PCI_VGA (8) > +#define ASPEED_RESET_2D (7) > +#define ASPEED_RESET_VIDEO (6) > +#define ASPEED_RESET_LPC_ESPI (5) > +#define ASPEED_RESET_HACE (4) > +#define ASPEED_RESET_EHCI_P2 (3) > +#define ASPEED_RESET_I2C (2) > +#define ASPEED_RESET_AHB (1) > +#define ASPEED_RESET_SDRAM (0) > > #endif /* _ABI_MACH_ASPEED_AST2500_RESET_H_ */ > -- > 2.17.1