1 /* SPDX-License-Identifier: Apache-2.0 */
2 /*
3  * Copyright (c) 2023 Intel Corporation
4  *
5  * Author: Adrian Warecki <adrian.warecki@intel.com>
6  */
7 
8 #ifndef ZEPHYR_DRIVERS_WATCHDOG_WDT_INTEL_ADSP_H_
9 #define ZEPHYR_DRIVERS_WATCHDOG_WDT_INTEL_ADSP_H_
10 
11 /*
12  * Get register offset for core
13  */
14 #define DSPBRx_OFFSET(x)	(0x0020 * (x))
15 
16 /*
17  * DSPCxWDTCS
18  * DSP Core Watch Dog Timer Control & Status
19  *
20  * Offset: 04h
21  * Block: DSPBRx
22  *
23  * This register controls the DSP Core watch dog timer policy.
24  */
25 #define DSPCxWDTCS		0x0004
26 
27 /*
28  * Pause Code
29  * type: WO, rst: 00b, rst domain: nan
30  *
31  * FW write 76h as the code to set the PAUSED bit. Other value are ignored and has no effect.
32  */
33 #define DSPCxWDTCS_PCODE	GENMASK(7, 0)
34 #define DSPCxWDTCS_PCODE_VALUE	0x76
35 
36 /*
37  * Paused
38  * type: RW/1C, rst: 0b, rst domain: DSPLRST
39  *
40  * When set, it pauses the watch dog timer.  Set when 76h is written to the PCODE
41  * field.  Clear when FW writes a 1 to the bit.
42  */
43 #define DSPCxWDTCS_PAUSED	BIT(8)
44 
45 /*
46  * Second Time Out Reset Enable
47  * type: RW/1S, rst: 0b, rst domain: DSPLRST
48  *
49  * When set, it allow the DSP Core reset to take place upon second time out of the
50  * watch dog timer. Clear when DSPCCTL.CPA = 0.  Set when FW writes a 1 to the bit.
51  */
52 #define DSPCxWDTCS_STORE	BIT(9)
53 
54 /*
55  * DSPCxWDTIPPTR
56  * DSP Core Watch Dog Timer IP Pointer
57  *
58  * Offset: 08h
59  * Block: DSPBRx
60  *
61  * This register provides the pointer to the DSP Core watch dog timer IP registers.
62  */
63 #define DSPCxWDTIPPTR		0x0008
64 
65 /*
66  * IP Pointer
67  * type: RO, rst: 07 8300h + 100h * x, rst domain: nan
68  *
69  * This field contains the offset to the IP.
70  */
71 #define DSPCxWDTIPPTR_PTR	GENMASK(20, 0)
72 
73 /*
74  * IP Version
75  * type: RO, rst: 000b, rst domain: nan
76  *
77  * This field indicates the version of the IP.
78  */
79 #define DSPCxWDTIPPTR_VER	GENMASK(23, 21)
80 
81 /**
82  * @brief Set pause signal
83  *
84  * Sets the pause signal to stop the watchdog timing
85  *
86  * @param base Device base address.
87  * @param core Core ID
88  */
intel_adsp_wdt_pause(uint32_t base,const uint32_t core)89 static inline void intel_adsp_wdt_pause(uint32_t base, const uint32_t core)
90 {
91 	const uint32_t reg_addr = base + DSPCxWDTCS + DSPBRx_OFFSET(core);
92 	uint32_t control;
93 
94 	control = sys_read32(reg_addr);
95 	control &= DSPCxWDTCS_STORE;
96 	control |= FIELD_PREP(DSPCxWDTCS_PCODE, DSPCxWDTCS_PCODE_VALUE);
97 	sys_write32(control, reg_addr);
98 }
99 
100 /**
101  * @brief Clear pause signal
102  *
103  * Clears the pause signal to resume the watchdog timing
104  *
105  * @param base Device base address.
106  * @param core Core ID
107  */
intel_adsp_wdt_resume(uint32_t base,const uint32_t core)108 static inline void intel_adsp_wdt_resume(uint32_t base, const uint32_t core)
109 {
110 	const uint32_t reg_addr = base + DSPCxWDTCS + DSPBRx_OFFSET(core);
111 	uint32_t control;
112 
113 	control = sys_read32(reg_addr);
114 	control &= DSPCxWDTCS_STORE;
115 	control |= DSPCxWDTCS_PAUSED;
116 	sys_write32(control, reg_addr);
117 }
118 
119 /**
120  * @brief Second Time Out Reset Enable
121  *
122  * When set, it allow the DSP Core reset to take place upon second time out of the watchdog timer.
123  *
124  * @param base Device base address.
125  * @param core Core ID
126  */
intel_adsp_wdt_reset_set(uint32_t base,const uint32_t core,const bool enable)127 static inline void intel_adsp_wdt_reset_set(uint32_t base, const uint32_t core, const bool enable)
128 {
129 	sys_write32(enable ? DSPCxWDTCS_STORE : 0, base + DSPCxWDTCS + DSPBRx_OFFSET(core));
130 }
131 
132 /*
133  * Second Time Out Reset Enable
134  * type: RW/1S, rst: 0b, rst domain: DSPLRST
135  *
136  * When set, it allow the DSP Core reset to take place upon second time out of the
137  * watch dog timer. Clear when DSPCCTL.CPA = 0.  Set when FW writes a 1 to the bit.
138  */
139 #define DSPCxWDTCS_STORE BIT(9)
140 
141 /**
142  * @brief Get watchdog IP pointer for specified core.
143  *
144  * Returns the base address of the watchdog IP
145  *
146  * @param base Device base address.
147  * @param core Core ID
148  */
intel_adsp_wdt_pointer_get(uint32_t base,const uint32_t core)149 static inline uint32_t intel_adsp_wdt_pointer_get(uint32_t base, const uint32_t core)
150 {
151 	return FIELD_GET(DSPCxWDTIPPTR_PTR, sys_read32(base + DSPCxWDTIPPTR + DSPBRx_OFFSET(core)));
152 }
153 
154 /**
155  * @brief Get watchdog version
156  *
157  * Returns the version of the watchdog IP
158  *
159  * @param base Device base address.
160  * @param core Core ID
161  */
intel_adsp_wdt_version_get(uint32_t base,const uint32_t core)162 static inline uint32_t intel_adsp_wdt_version_get(uint32_t base, const uint32_t core)
163 {
164 	return FIELD_GET(DSPCxWDTIPPTR_VER, sys_read32(base + DSPCxWDTIPPTR + DSPBRx_OFFSET(core)));
165 }
166 
167 #endif /* ZEPHYR_DRIVERS_WATCHDOG_WDT_INTEL_ADSP_H_ */
168