]> git.ipfire.org Git - thirdparty/u-boot.git/blame - drivers/watchdog/mpc8xxx_wdt.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[thirdparty/u-boot.git] / drivers / watchdog / mpc8xxx_wdt.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
c0bc2a7e
CL
2/*
3 * Copyright 2017 CS Systemes d'Information
c0bc2a7e
CL
4 */
5
d678a59d 6#include <common.h>
ea8de984 7#include <env.h>
749c9aae
CL
8#include <dm.h>
9#include <wdt.h>
26e8ebcd 10#include <clock_legacy.h>
c0bc2a7e
CL
11#include <asm/io.h>
12
26e8ebcd
CL
13struct mpc8xxx_wdt {
14 __be32 res0;
15 __be32 swcrr; /* System watchdog control register */
16#define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count. */
17#define SWCRR_BME 0x00000080 /* Bus monitor enable (mpc8xx) */
18#define SWCRR_SWF 0x00000008 /* Software Watchdog Freeze (mpc8xx). */
19#define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit. */
20#define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit.*/
21#define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit. */
22 __be32 swcnr; /* System watchdog count register */
23 u8 res1[2];
24 __be16 swsrr; /* System watchdog service register */
25 u8 res2[0xf0];
26};
27
28struct mpc8xxx_wdt_priv {
29 struct mpc8xxx_wdt __iomem *base;
30};
31
32static int mpc8xxx_wdt_reset(struct udevice *dev)
c0bc2a7e 33{
26e8ebcd
CL
34 struct mpc8xxx_wdt_priv *priv = dev_get_priv(dev);
35
36 out_be16(&priv->base->swsrr, 0x556c); /* write magic1 */
37 out_be16(&priv->base->swsrr, 0xaa39); /* write magic2 */
c0bc2a7e 38
26e8ebcd 39 return 0;
c0bc2a7e
CL
40}
41
21eaade4 42static int mpc8xxx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
749c9aae 43{
26e8ebcd 44 struct mpc8xxx_wdt_priv *priv = dev_get_priv(dev);
ea8de984 45 const char *mode = env_get("watchdog_mode");
26e8ebcd
CL
46 ulong prescaler = dev_get_driver_data(dev);
47 u16 swtc = min_t(u16, timeout * get_board_sys_clk() / 1000 / prescaler, U16_MAX);
48 u32 val;
49
50 mpc8xxx_wdt_reset(dev);
749c9aae 51
ea8de984 52 if (strcmp(mode, "off") == 0)
26e8ebcd 53 val = (swtc << 16) | SWCRR_SWPR;
ea8de984 54 else if (strcmp(mode, "nmi") == 0)
26e8ebcd
CL
55 val = (swtc << 16) | SWCRR_SWPR | SWCRR_SWEN;
56 else
57 val = (swtc << 16) | SWCRR_SWPR | SWCRR_SWEN | SWCRR_SWRI;
58
59 if (IS_ENABLED(CONFIG_WDT_MPC8xxx_BME))
60 val |= (CONFIG_WDT_MPC8xxx_BMT << 8) | SWCRR_BME;
ea8de984 61
26e8ebcd 62 out_be32(&priv->base->swcrr, val);
749c9aae 63
26e8ebcd 64 if (!(in_be32(&priv->base->swcrr) & SWCRR_SWEN))
749c9aae
CL
65 return -EBUSY;
66 return 0;
67
68}
69
21eaade4 70static int mpc8xxx_wdt_stop(struct udevice *dev)
749c9aae 71{
26e8ebcd 72 struct mpc8xxx_wdt_priv *priv = dev_get_priv(dev);
749c9aae 73
26e8ebcd 74 clrbits_be32(&priv->base->swcrr, SWCRR_SWEN);
749c9aae 75
26e8ebcd 76 if (in_be32(&priv->base->swcrr) & SWCRR_SWEN)
749c9aae
CL
77 return -EBUSY;
78 return 0;
79}
80
26e8ebcd 81static int mpc8xxx_wdt_of_to_plat(struct udevice *dev)
749c9aae 82{
26e8ebcd
CL
83 struct mpc8xxx_wdt_priv *priv = dev_get_priv(dev);
84
85 priv->base = (void __iomem *)devfdt_remap_addr(dev);
86
87 if (!priv->base)
88 return -EINVAL;
749c9aae
CL
89
90 return 0;
91}
92
21eaade4
CL
93static const struct wdt_ops mpc8xxx_wdt_ops = {
94 .start = mpc8xxx_wdt_start,
95 .reset = mpc8xxx_wdt_reset,
96 .stop = mpc8xxx_wdt_stop,
749c9aae
CL
97};
98
21eaade4 99static const struct udevice_id mpc8xxx_wdt_ids[] = {
26e8ebcd 100 { .compatible = "fsl,pq1-wdt", .data = 0x800 },
0fd79138 101 { .compatible = "fsl,pq2pro-wdt", .data = 0x10000 },
749c9aae
CL
102 {}
103};
104
21eaade4
CL
105U_BOOT_DRIVER(wdt_mpc8xxx) = {
106 .name = "wdt_mpc8xxx",
749c9aae 107 .id = UCLASS_WDT,
21eaade4
CL
108 .of_match = mpc8xxx_wdt_ids,
109 .ops = &mpc8xxx_wdt_ops,
26e8ebcd
CL
110 .of_to_plat = mpc8xxx_wdt_of_to_plat,
111 .priv_auto = sizeof(struct mpc8xxx_wdt_priv),
749c9aae 112};