1/*
2 * Copyright (c) 2018 Foundries.io Ltd
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#include <zephyr/linker/sections.h>
8#include <zephyr/toolchain.h>
9#include <zephyr/arch/cpu.h>
10
11/* Exports */
12GTEXT(_WdogInit)
13
14/* WDOG instance base address. */
15#ifdef CONFIG_SOC_OPENISA_RV32M1_RI5CY
16#define WDOG_BASE 0x4002A000	/* WDOG0 */
17#else
18#define WDOG_BASE 0x41026000	/* WDOG1 */
19#endif
20
21/* Register offsets. */
22#define WDOG_CS_OFFSET 0x00
23#define WDOG_CNT_OFFSET 0x04
24#define WDOG_TOVAL_OFFSET 0x08
25
26/* Watchdog unlock key. */
27#define WDOG_CNT_UNLOCK 0xD928C520
28
29/* TOVAL must be set when disabling watchdog after reset. */
30#define WDOG_TOVAL_SET 0xFFFF
31
32/* Disable the WDOG_CS[EN] bit. */
33#define WDOG_CS_EN_DISABLED ~0x80
34/* Set WDOG_CS[UPDATE] bit. */
35#define WDOG_CS_UPDATE_ENABLED 0x20
36
37/*
38 * Unlock and disable the watchdog, which is enabled by default.
39 */
40SECTION_FUNC(TEXT, _WdogInit)
41	/* Disable interrupts if they're on. This is timing-sensitive code. */
42	csrrc t0, mstatus, MSTATUS_IEN
43
44	/* Get base address. */
45	li t1, WDOG_BASE
46
47	/* Unlock the watchdog. */
48	li t2, WDOG_CNT_UNLOCK
49	sw t2, WDOG_CNT_OFFSET(t1)
50
51	/* Disable the watchdog. Allow updates later. */
52	lw t2, WDOG_CS_OFFSET(t1)
53	andi t2, t2, WDOG_CS_EN_DISABLED
54	ori t2, t2, WDOG_CS_UPDATE_ENABLED
55	sw t2, WDOG_CS_OFFSET(t1)
56
57	/* This must also be done per reference manual. */
58	li t2, WDOG_TOVAL_SET
59	sw t2, WDOG_TOVAL_OFFSET(t1)
60
61	/* Re-enable interrupts if they were disabled. */
62	csrrs x0, mstatus, t0
63	ret
64