2 * Copyright 2017 Google, Inc
4 * SPDX-License-Identifier: GPL-2.0+
12 #include <asm/arch/wdt.h>
14 #define WDT_AST2500 2500
15 #define WDT_AST2400 2400
17 DECLARE_GLOBAL_DATA_PTR
;
23 static int ast_wdt_start(struct udevice
*dev
, u64 timeout
, ulong flags
)
25 struct ast_wdt_priv
*priv
= dev_get_priv(dev
);
26 ulong driver_data
= dev_get_driver_data(dev
);
27 u32 reset_mode
= ast_reset_mode_from_flags(flags
);
29 clrsetbits_le32(&priv
->regs
->ctrl
,
30 WDT_CTRL_RESET_MASK
<< WDT_CTRL_RESET_MODE_SHIFT
,
31 reset_mode
<< WDT_CTRL_RESET_MODE_SHIFT
);
33 if (driver_data
>= WDT_AST2500
&& reset_mode
== WDT_CTRL_RESET_SOC
)
34 writel(ast_reset_mask_from_flags(flags
),
35 &priv
->regs
->reset_mask
);
37 writel((u32
) timeout
, &priv
->regs
->counter_reload_val
);
38 writel(WDT_COUNTER_RESTART_VAL
, &priv
->regs
->counter_restart
);
40 * Setting CLK1MHZ bit is just for compatibility with ast2400 part.
41 * On ast2500 watchdog timer clock is fixed at 1MHz and the bit is
44 setbits_le32(&priv
->regs
->ctrl
,
45 WDT_CTRL_EN
| WDT_CTRL_RESET
| WDT_CTRL_CLK1MHZ
);
50 static int ast_wdt_stop(struct udevice
*dev
)
52 struct ast_wdt_priv
*priv
= dev_get_priv(dev
);
54 clrbits_le32(&priv
->regs
->ctrl
, WDT_CTRL_EN
);
59 static int ast_wdt_reset(struct udevice
*dev
)
61 struct ast_wdt_priv
*priv
= dev_get_priv(dev
);
63 writel(WDT_COUNTER_RESTART_VAL
, &priv
->regs
->counter_restart
);
68 static int ast_wdt_expire_now(struct udevice
*dev
, ulong flags
)
70 struct ast_wdt_priv
*priv
= dev_get_priv(dev
);
73 ret
= ast_wdt_start(dev
, 1, flags
);
77 while (readl(&priv
->regs
->ctrl
) & WDT_CTRL_EN
)
80 return ast_wdt_stop(dev
);
83 static int ast_wdt_ofdata_to_platdata(struct udevice
*dev
)
85 struct ast_wdt_priv
*priv
= dev_get_priv(dev
);
87 priv
->regs
= devfdt_get_addr_ptr(dev
);
88 if (IS_ERR(priv
->regs
))
89 return PTR_ERR(priv
->regs
);
94 static const struct wdt_ops ast_wdt_ops
= {
95 .start
= ast_wdt_start
,
96 .reset
= ast_wdt_reset
,
98 .expire_now
= ast_wdt_expire_now
,
101 static const struct udevice_id ast_wdt_ids
[] = {
102 { .compatible
= "aspeed,wdt", .data
= WDT_AST2500
},
103 { .compatible
= "aspeed,ast2500-wdt", .data
= WDT_AST2500
},
104 { .compatible
= "aspeed,ast2400-wdt", .data
= WDT_AST2400
},
108 static int ast_wdt_probe(struct udevice
*dev
)
110 debug("%s() wdt%u\n", __func__
, dev
->seq
);
116 U_BOOT_DRIVER(ast_wdt
) = {
119 .of_match
= ast_wdt_ids
,
120 .probe
= ast_wdt_probe
,
121 .priv_auto_alloc_size
= sizeof(struct ast_wdt_priv
),
122 .ofdata_to_platdata
= ast_wdt_ofdata_to_platdata
,
124 .flags
= DM_FLAG_PRE_RELOC
,