提交 611a28ce 编写于 作者: C Chia-Wei, Wang 提交者: Tom Rini

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: NChia-Wei, Wang <chiawei_wang@aspeedtech.com>
Reviewed-by: NRyan Chen <ryan_chen@aspeedtech.com>
上级 fa181d1a
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
rst: reset-controller { rst: reset-controller {
u-boot,dm-pre-reloc; u-boot,dm-pre-reloc;
compatible = "aspeed,ast2500-reset"; compatible = "aspeed,ast2500-reset";
aspeed,wdt = <&wdt1>;
#reset-cells = <1>; #reset-cells = <1>;
}; };
...@@ -27,7 +26,7 @@ ...@@ -27,7 +26,7 @@
0x1e6e0200 0x1d4 >; 0x1e6e0200 0x1d4 >;
#reset-cells = <1>; #reset-cells = <1>;
clocks = <&scu ASPEED_CLK_MPLL>; clocks = <&scu ASPEED_CLK_MPLL>;
resets = <&rst AST_RESET_SDRAM>; resets = <&rst ASPEED_RESET_SDRAM>;
}; };
ahb { ahb {
...@@ -41,7 +40,7 @@ ...@@ -41,7 +40,7 @@
reg = <0x1e740100>; reg = <0x1e740100>;
#reset-cells = <1>; #reset-cells = <1>;
clocks = <&scu ASPEED_CLK_SDIO>; clocks = <&scu ASPEED_CLK_SDIO>;
resets = <&rst AST_RESET_SDIO>; resets = <&rst ASPEED_RESET_SDIO>;
}; };
sdhci1: sdhci@1e740200 { sdhci1: sdhci@1e740200 {
...@@ -49,7 +48,7 @@ ...@@ -49,7 +48,7 @@
reg = <0x1e740200>; reg = <0x1e740200>;
#reset-cells = <1>; #reset-cells = <1>;
clocks = <&scu ASPEED_CLK_SDIO>; clocks = <&scu ASPEED_CLK_SDIO>;
resets = <&rst AST_RESET_SDIO>; resets = <&rst ASPEED_RESET_SDIO>;
}; };
}; };
......
...@@ -74,13 +74,12 @@ config RESET_UNIPHIER ...@@ -74,13 +74,12 @@ config RESET_UNIPHIER
config AST2500_RESET config AST2500_RESET
bool "Reset controller driver for AST2500 SoCs" bool "Reset controller driver for AST2500 SoCs"
depends on DM_RESET && WDT_ASPEED depends on DM_RESET
default y if ASPEED_AST2500 default y if ASPEED_AST2500
help help
Support for reset controller on AST2500 SoC. This controller uses Support for reset controller on AST2500 SoC.
watchdog to reset different peripherals and thus only supports Say Y if you want to control reset signals of different peripherals
resets that are supported by watchdog. The main limitation though through System Control Unit (SCU).
is that some reset signals, like I2C or MISC reset multiple devices.
config RESET_ROCKCHIP config RESET_ROCKCHIP
bool "Reset controller driver for Rockchip SoCs" bool "Reset controller driver for Rockchip SoCs"
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
/* /*
* Copyright 2017 Google, Inc * Copyright 2017 Google, Inc
* Copyright 2020 ASPEED Technology Inc.
*/ */
#include <common.h> #include <common.h>
...@@ -9,28 +10,26 @@ ...@@ -9,28 +10,26 @@
#include <misc.h> #include <misc.h>
#include <reset.h> #include <reset.h>
#include <reset-uclass.h> #include <reset-uclass.h>
#include <wdt.h> #include <linux/err.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/arch/scu_ast2500.h> #include <asm/arch/scu_ast2500.h>
#include <asm/arch/wdt.h>
struct ast2500_reset_priv { struct ast2500_reset_priv {
/* WDT used to perform resets. */
struct udevice *wdt;
struct ast2500_scu *scu; 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); debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl,
int ret; reset_ctl->dev, reset_ctl->id);
ret = uclass_get_device_by_phandle(UCLASS_WDT, dev, "aspeed,wdt", return 0;
&priv->wdt); }
if (ret) {
debug("%s: can't find WDT for reset controller", __func__); static int ast2500_reset_free(struct reset_ctl *reset_ctl)
return ret; {
} debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl,
reset_ctl->dev, reset_ctl->id);
return 0; return 0;
} }
...@@ -38,47 +37,52 @@ static int ast2500_ofdata_to_platdata(struct udevice *dev) ...@@ -38,47 +37,52 @@ static int ast2500_ofdata_to_platdata(struct udevice *dev)
static int ast2500_reset_assert(struct reset_ctl *reset_ctl) static int ast2500_reset_assert(struct reset_ctl *reset_ctl)
{ {
struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev); struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev);
u32 reset_mode, reset_mask; struct ast2500_scu *scu = priv->scu;
bool reset_sdram;
int ret; debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id);
/*
* 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);
}
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, struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev);
reset_ctl->dev, reset_ctl->id); 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; return 0;
} }
static int ast2500_reset_probe(struct udevice *dev) static int ast2500_reset_probe(struct udevice *dev)
{ {
int rc;
struct ast2500_reset_priv *priv = dev_get_priv(dev); 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; return 0;
} }
...@@ -89,16 +93,17 @@ static const struct udevice_id ast2500_reset_ids[] = { ...@@ -89,16 +93,17 @@ static const struct udevice_id ast2500_reset_ids[] = {
}; };
struct reset_ops ast2500_reset_ops = { struct reset_ops ast2500_reset_ops = {
.rst_assert = ast2500_reset_assert,
.request = ast2500_reset_request, .request = ast2500_reset_request,
.rfree = ast2500_reset_free,
.rst_assert = ast2500_reset_assert,
.rst_deassert = ast2500_reset_deassert,
}; };
U_BOOT_DRIVER(ast2500_reset) = { U_BOOT_DRIVER(ast2500_reset) = {
.name = "ast2500_reset", .name = "ast2500_reset",
.id = UCLASS_RESET, .id = UCLASS_RESET,
.of_match = ast2500_reset_ids, .of_match = ast2500_reset_ids,
.probe = ast2500_reset_probe, .probe = ast2500_reset_probe,
.ops = &ast2500_reset_ops, .ops = &ast2500_reset_ops,
.ofdata_to_platdata = ast2500_ofdata_to_platdata,
.priv_auto_alloc_size = sizeof(struct ast2500_reset_priv), .priv_auto_alloc_size = sizeof(struct ast2500_reset_priv),
}; };
/* SPDX-License-Identifier: GPL-2.0+ */ /* SPDX-License-Identifier: GPL-2.0+ */
/* /*
* Copyright 2017 Google, Inc * Copyright 2017 Google, Inc
* Copyright 2020 ASPEED Technology Inc.
*/ */
#ifndef _ABI_MACH_ASPEED_AST2500_RESET_H_ #ifndef _ABI_MACH_ASPEED_AST2500_RESET_H_
#define _ABI_MACH_ASPEED_AST2500_RESET_H_ #define _ABI_MACH_ASPEED_AST2500_RESET_H_
/* #define ASPEED_RESET_CRT1 (37)
* The values are intentionally layed out as flags in #define ASPEED_RESET_RESERVED36 (36)
* WDT reset parameter. #define ASPEED_RESET_RESERVED35 (35)
*/ #define ASPEED_RESET_RESERVED34 (34)
#define ASPEED_RESET_RESERVED33 (33)
#define AST_RESET_SOC 0 #define ASPEED_RESET_RESERVED32 (32)
#define AST_RESET_CHIP 1 #define ASPEED_RESET_RESERVED31 (31)
#define AST_RESET_CPU (1 << 1) #define ASPEED_RESET_RESERVED30 (30)
#define AST_RESET_ARM (1 << 2) #define ASPEED_RESET_RESERVED29 (29)
#define AST_RESET_COPROC (1 << 3) #define ASPEED_RESET_RESERVED28 (28)
#define AST_RESET_SDRAM (1 << 4) #define ASPEED_RESET_RESERVED27 (27)
#define AST_RESET_AHB (1 << 5) #define ASPEED_RESET_RESERVED26 (26)
#define AST_RESET_I2C (1 << 6) #define ASPEED_RESET_XDMA (25)
#define AST_RESET_MAC1 (1 << 7) #define ASPEED_RESET_MCTP (24)
#define AST_RESET_MAC2 (1 << 8) #define ASPEED_RESET_ADC (23)
#define AST_RESET_GCRT (1 << 9) #define ASPEED_RESET_JTAG_MASTER (22)
#define AST_RESET_USB20 (1 << 10) #define ASPEED_RESET_RESERVED21 (21)
#define AST_RESET_USB11_HOST (1 << 11) #define ASPEED_RESET_RESERVED20 (20)
#define AST_RESET_USB11_HID (1 << 12) #define ASPEED_RESET_RESERVED19 (19)
#define AST_RESET_VIDEO (1 << 13) #define ASPEED_RESET_MIC (18)
#define AST_RESET_HAC (1 << 14) #define ASPEED_RESET_RESERVED17 (17)
#define AST_RESET_LPC (1 << 15) #define ASPEED_RESET_SDIO (16)
#define AST_RESET_SDIO (1 << 16) #define ASPEED_RESET_UHCI (15)
#define AST_RESET_MIC (1 << 17) #define ASPEED_RESET_EHCI_P1 (14)
#define AST_RESET_CRT2D (1 << 18) #define ASPEED_RESET_CRT (13)
#define AST_RESET_PWM (1 << 19) #define ASPEED_RESET_MAC2 (12)
#define AST_RESET_PECI (1 << 20) #define ASPEED_RESET_MAC1 (11)
#define AST_RESET_JTAG (1 << 21) #define ASPEED_RESET_PECI (10)
#define AST_RESET_ADC (1 << 22) #define ASPEED_RESET_PWM (9)
#define AST_RESET_GPIO (1 << 23) #define ASPEED_RESET_PCI_VGA (8)
#define AST_RESET_MCTP (1 << 24) #define ASPEED_RESET_2D (7)
#define AST_RESET_XDMA (1 << 25) #define ASPEED_RESET_VIDEO (6)
#define AST_RESET_SPI (1 << 26) #define ASPEED_RESET_LPC_ESPI (5)
#define AST_RESET_MISC (1 << 27) #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_ */ #endif /* _ABI_MACH_ASPEED_AST2500_RESET_H_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册