1*858d4976Smaxims@google.com /*
2*858d4976Smaxims@google.com * Copyright 2017 Google, Inc
3*858d4976Smaxims@google.com *
4*858d4976Smaxims@google.com * SPDX-License-Identifier: GPL-2.0
5*858d4976Smaxims@google.com */
6*858d4976Smaxims@google.com
7*858d4976Smaxims@google.com #include <common.h>
8*858d4976Smaxims@google.com #include <dm.h>
9*858d4976Smaxims@google.com #include <misc.h>
10*858d4976Smaxims@google.com #include <reset.h>
11*858d4976Smaxims@google.com #include <reset-uclass.h>
12*858d4976Smaxims@google.com #include <wdt.h>
13*858d4976Smaxims@google.com #include <asm/io.h>
14*858d4976Smaxims@google.com #include <asm/arch/scu_ast2500.h>
15*858d4976Smaxims@google.com #include <asm/arch/wdt.h>
16*858d4976Smaxims@google.com
17*858d4976Smaxims@google.com DECLARE_GLOBAL_DATA_PTR;
18*858d4976Smaxims@google.com
19*858d4976Smaxims@google.com struct ast2500_reset_priv {
20*858d4976Smaxims@google.com /* WDT used to perform resets. */
21*858d4976Smaxims@google.com struct udevice *wdt;
22*858d4976Smaxims@google.com struct ast2500_scu *scu;
23*858d4976Smaxims@google.com };
24*858d4976Smaxims@google.com
ast2500_ofdata_to_platdata(struct udevice * dev)25*858d4976Smaxims@google.com static int ast2500_ofdata_to_platdata(struct udevice *dev)
26*858d4976Smaxims@google.com {
27*858d4976Smaxims@google.com struct ast2500_reset_priv *priv = dev_get_priv(dev);
28*858d4976Smaxims@google.com int ret;
29*858d4976Smaxims@google.com
30*858d4976Smaxims@google.com ret = uclass_get_device_by_phandle(UCLASS_WDT, dev, "aspeed,wdt",
31*858d4976Smaxims@google.com &priv->wdt);
32*858d4976Smaxims@google.com if (ret) {
33*858d4976Smaxims@google.com debug("%s: can't find WDT for reset controller", __func__);
34*858d4976Smaxims@google.com return ret;
35*858d4976Smaxims@google.com }
36*858d4976Smaxims@google.com
37*858d4976Smaxims@google.com return 0;
38*858d4976Smaxims@google.com }
39*858d4976Smaxims@google.com
ast2500_reset_assert(struct reset_ctl * reset_ctl)40*858d4976Smaxims@google.com static int ast2500_reset_assert(struct reset_ctl *reset_ctl)
41*858d4976Smaxims@google.com {
42*858d4976Smaxims@google.com struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev);
43*858d4976Smaxims@google.com u32 reset_mode, reset_mask;
44*858d4976Smaxims@google.com bool reset_sdram;
45*858d4976Smaxims@google.com int ret;
46*858d4976Smaxims@google.com
47*858d4976Smaxims@google.com /*
48*858d4976Smaxims@google.com * To reset SDRAM, a specifal flag in SYSRESET register
49*858d4976Smaxims@google.com * needs to be enabled first
50*858d4976Smaxims@google.com */
51*858d4976Smaxims@google.com reset_mode = ast_reset_mode_from_flags(reset_ctl->id);
52*858d4976Smaxims@google.com reset_mask = ast_reset_mask_from_flags(reset_ctl->id);
53*858d4976Smaxims@google.com reset_sdram = reset_mode == WDT_CTRL_RESET_SOC &&
54*858d4976Smaxims@google.com (reset_mask & WDT_RESET_SDRAM);
55*858d4976Smaxims@google.com
56*858d4976Smaxims@google.com if (reset_sdram) {
57*858d4976Smaxims@google.com ast_scu_unlock(priv->scu);
58*858d4976Smaxims@google.com setbits_le32(&priv->scu->sysreset_ctrl1,
59*858d4976Smaxims@google.com SCU_SYSRESET_SDRAM_WDT);
60*858d4976Smaxims@google.com ret = wdt_expire_now(priv->wdt, reset_ctl->id);
61*858d4976Smaxims@google.com clrbits_le32(&priv->scu->sysreset_ctrl1,
62*858d4976Smaxims@google.com SCU_SYSRESET_SDRAM_WDT);
63*858d4976Smaxims@google.com ast_scu_lock(priv->scu);
64*858d4976Smaxims@google.com } else {
65*858d4976Smaxims@google.com ret = wdt_expire_now(priv->wdt, reset_ctl->id);
66*858d4976Smaxims@google.com }
67*858d4976Smaxims@google.com
68*858d4976Smaxims@google.com return ret;
69*858d4976Smaxims@google.com }
70*858d4976Smaxims@google.com
ast2500_reset_request(struct reset_ctl * reset_ctl)71*858d4976Smaxims@google.com static int ast2500_reset_request(struct reset_ctl *reset_ctl)
72*858d4976Smaxims@google.com {
73*858d4976Smaxims@google.com debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl,
74*858d4976Smaxims@google.com reset_ctl->dev, reset_ctl->id);
75*858d4976Smaxims@google.com
76*858d4976Smaxims@google.com return 0;
77*858d4976Smaxims@google.com }
78*858d4976Smaxims@google.com
ast2500_reset_probe(struct udevice * dev)79*858d4976Smaxims@google.com static int ast2500_reset_probe(struct udevice *dev)
80*858d4976Smaxims@google.com {
81*858d4976Smaxims@google.com struct ast2500_reset_priv *priv = dev_get_priv(dev);
82*858d4976Smaxims@google.com
83*858d4976Smaxims@google.com priv->scu = ast_get_scu();
84*858d4976Smaxims@google.com
85*858d4976Smaxims@google.com return 0;
86*858d4976Smaxims@google.com }
87*858d4976Smaxims@google.com
88*858d4976Smaxims@google.com static const struct udevice_id ast2500_reset_ids[] = {
89*858d4976Smaxims@google.com { .compatible = "aspeed,ast2500-reset" },
90*858d4976Smaxims@google.com { }
91*858d4976Smaxims@google.com };
92*858d4976Smaxims@google.com
93*858d4976Smaxims@google.com struct reset_ops ast2500_reset_ops = {
94*858d4976Smaxims@google.com .rst_assert = ast2500_reset_assert,
95*858d4976Smaxims@google.com .request = ast2500_reset_request,
96*858d4976Smaxims@google.com };
97*858d4976Smaxims@google.com
98*858d4976Smaxims@google.com U_BOOT_DRIVER(ast2500_reset) = {
99*858d4976Smaxims@google.com .name = "ast2500_reset",
100*858d4976Smaxims@google.com .id = UCLASS_RESET,
101*858d4976Smaxims@google.com .of_match = ast2500_reset_ids,
102*858d4976Smaxims@google.com .probe = ast2500_reset_probe,
103*858d4976Smaxims@google.com .ops = &ast2500_reset_ops,
104*858d4976Smaxims@google.com .ofdata_to_platdata = ast2500_ofdata_to_platdata,
105*858d4976Smaxims@google.com .priv_auto_alloc_size = sizeof(struct ast2500_reset_priv),
106*858d4976Smaxims@google.com };
107