watchdog: mpc8xx_wdt: Allow selection of watchdog mode through environment
[oweals/u-boot.git] / drivers / watchdog / mpc8xx_wdt.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2017 CS Systemes d'Information
4  */
5
6 #include <common.h>
7 #include <env.h>
8 #include <dm.h>
9 #include <wdt.h>
10 #include <mpc8xx.h>
11 #include <asm/cpm_8xx.h>
12 #include <asm/io.h>
13
14 void hw_watchdog_reset(void)
15 {
16         immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
17
18         out_be16(&immap->im_siu_conf.sc_swsr, 0x556c);  /* write magic1 */
19         out_be16(&immap->im_siu_conf.sc_swsr, 0xaa39);  /* write magic2 */
20 }
21
22 static int mpc8xx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
23 {
24         immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
25         u32 val = CONFIG_SYS_SYPCR;
26         const char *mode = env_get("watchdog_mode");
27
28         if (strcmp(mode, "off") == 0)
29                 val = val & ~(SYPCR_SWE | SYPCR_SWRI);
30         else if (strcmp(mode, "nmi") == 0)
31                 val = (val & ~SYPCR_SWRI) | SYPCR_SWE;
32
33         out_be32(&immap->im_siu_conf.sc_sypcr, val);
34
35         if (!(in_be32(&immap->im_siu_conf.sc_sypcr) & SYPCR_SWE))
36                 return -EBUSY;
37         return 0;
38
39 }
40
41 static int mpc8xx_wdt_stop(struct udevice *dev)
42 {
43         immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
44
45         out_be32(&immap->im_siu_conf.sc_sypcr, CONFIG_SYS_SYPCR & ~SYPCR_SWE);
46
47         if (in_be32(&immap->im_siu_conf.sc_sypcr) & SYPCR_SWE)
48                 return -EBUSY;
49         return 0;
50 }
51
52 static int mpc8xx_wdt_reset(struct udevice *dev)
53 {
54         hw_watchdog_reset();
55
56         return 0;
57 }
58
59 static const struct wdt_ops mpc8xx_wdt_ops = {
60         .start = mpc8xx_wdt_start,
61         .reset = mpc8xx_wdt_reset,
62         .stop = mpc8xx_wdt_stop,
63 };
64
65 static const struct udevice_id mpc8xx_wdt_ids[] = {
66         { .compatible = "fsl,pq1-wdt" },
67         {}
68 };
69
70 U_BOOT_DRIVER(wdt_mpc8xx) = {
71         .name = "wdt_mpc8xx",
72         .id = UCLASS_WDT,
73         .of_match = mpc8xx_wdt_ids,
74         .ops = &mpc8xx_wdt_ops,
75 };