]>
Commit | Line | Data |
---|---|---|
843a2654 JCPV |
1 | /* |
2 | * [origin: Linux kernel drivers/watchdog/at91sam9_wdt.c] | |
3 | * | |
4 | * Watchdog driver for Atmel AT91SAM9x processors. | |
5 | * | |
6 | * Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | |
7 | * Copyright (C) 2008 Renaud CERRATO r.cerrato@til-technologies.fr | |
8 | * | |
1a459660 | 9 | * SPDX-License-Identifier: GPL-2.0+ |
843a2654 JCPV |
10 | */ |
11 | ||
12 | /* | |
13 | * The Watchdog Timer Mode Register can be only written to once. If the | |
14 | * timeout need to be set from U-Boot, be sure that the bootstrap doesn't | |
15 | * write to this register. Inform Linux to it too | |
16 | */ | |
17 | ||
18 | #include <common.h> | |
19 | #include <watchdog.h> | |
20 | #include <asm/arch/hardware.h> | |
7f6ed7ff | 21 | #include <asm/io.h> |
843a2654 JCPV |
22 | #include <asm/arch/at91_wdt.h> |
23 | ||
24 | /* | |
25 | * AT91SAM9 watchdog runs a 12bit counter @ 256Hz, | |
26 | * use this to convert a watchdog | |
27 | * value from/to milliseconds. | |
28 | */ | |
29 | #define ms_to_ticks(t) (((t << 8) / 1000) - 1) | |
30 | #define ticks_to_ms(t) (((t + 1) * 1000) >> 8) | |
31 | ||
32 | /* Hardware timeout in seconds */ | |
33 | #define WDT_HW_TIMEOUT 2 | |
34 | ||
35 | /* | |
36 | * Set the watchdog time interval in 1/256Hz (write-once) | |
37 | * Counter is 12 bit. | |
38 | */ | |
39 | static int at91_wdt_settimeout(unsigned int timeout) | |
40 | { | |
41 | unsigned int reg; | |
372f2783 | 42 | at91_wdt_t *wd = (at91_wdt_t *) ATMEL_BASE_WDT; |
843a2654 JCPV |
43 | |
44 | /* Check if disabled */ | |
f936aa05 | 45 | if (readl(&wd->mr) & AT91_WDT_MR_WDDIS) { |
843a2654 JCPV |
46 | printf("sorry, watchdog is disabled\n"); |
47 | return -1; | |
48 | } | |
49 | ||
50 | /* | |
51 | * All counting occurs at SLOW_CLOCK / 128 = 256 Hz | |
52 | * | |
53 | * Since WDV is a 12-bit counter, the maximum period is | |
54 | * 4096 / 256 = 16 seconds. | |
55 | */ | |
f936aa05 AE |
56 | |
57 | reg = AT91_WDT_MR_WDRSTEN /* causes watchdog reset */ | |
58 | | AT91_WDT_MR_WDDBGHLT /* disabled in debug mode */ | |
59 | | AT91_WDT_MR_WDD(0xfff) /* restart at any time */ | |
60 | | AT91_WDT_MR_WDV(timeout); /* timer value */ | |
61 | ||
62 | writel(reg, &wd->mr); | |
843a2654 JCPV |
63 | |
64 | return 0; | |
65 | } | |
66 | ||
67 | void hw_watchdog_reset(void) | |
68 | { | |
372f2783 | 69 | at91_wdt_t *wd = (at91_wdt_t *) ATMEL_BASE_WDT; |
f936aa05 | 70 | writel(AT91_WDT_CR_WDRSTT | AT91_WDT_CR_KEY, &wd->cr); |
843a2654 JCPV |
71 | } |
72 | ||
73 | void hw_watchdog_init(void) | |
74 | { | |
75 | /* 16 seconds timer, resets enabled */ | |
76 | at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000)); | |
77 | } |