1 /*
2  * Copyright (c) 2024 Silicon Laboratories Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef SL_CLOCK_MANAGER_TREE_CONFIG_H
8 #define SL_CLOCK_MANAGER_TREE_CONFIG_H
9 
10 #include <zephyr/devicetree.h>
11 
12 #include <em_device.h>
13 
14 /* Internal macros that must be defined to make parameter validation in the HAL pass,
15  * but are unused since Zephyr derives all clock tree configuration from DeviceTree
16  */
17 #define SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE           0xFF
18 #define SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE_HFRCODPLL 0xFF
19 #define SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE           0xFC
20 #define SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_LFRCO     0xFC
21 
22 #define SL_CLOCK_MANAGER_INVALID 0xFF
23 
24 /* SYSCLK */
25 #define SL_CLOCK_MANAGER_SYSCLK_SOURCE                                                             \
26 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(sysclk)), DT_NODELABEL(fsrco))                   \
27 		 ? CMU_SYSCLKCTRL_CLKSEL_FSRCO                                                     \
28 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(sysclk)), DT_NODELABEL(hfrcodpll))             \
29 		 ? CMU_SYSCLKCTRL_CLKSEL_HFRCODPLL                                                 \
30 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(sysclk)), DT_NODELABEL(hfxo))                  \
31 		 ? CMU_SYSCLKCTRL_CLKSEL_HFXO                                                      \
32 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(sysclk)), DT_NODELABEL(clkin0))                \
33 		 ? CMU_SYSCLKCTRL_CLKSEL_CLKIN0                                                    \
34 		 : SL_CLOCK_MANAGER_INVALID)
35 
36 #if SL_CLOCK_MANAGER_SYSCLK_SOURCE == SL_CLOCK_MANAGER_INVALID
37 #error "Invalid clock source selection for SYSCLK"
38 #endif
39 
40 #define SL_CLOCK_MANAGER_HCLK_DIVIDER                                                              \
41 	CONCAT(CMU_SYSCLKCTRL_HCLKPRESC_DIV, DT_PROP(DT_NODELABEL(hclk), clock_div))
42 
43 #define SL_CLOCK_MANAGER_PCLK_DIVIDER                                                              \
44 	CONCAT(CMU_SYSCLKCTRL_PCLKPRESC_DIV, DT_PROP(DT_NODELABEL(pclk), clock_div))
45 
46 /* TRACECLK */
47 #if defined(_CMU_TRACECLKCTRL_CLKSEL_MASK)
48 #if DT_NUM_CLOCKS(DT_NODELABEL(traceclk)) == 0
49 #define SL_CLOCK_MANAGER_TRACECLK_SOURCE CMU_TRACECLKCTRL_CLKSEL_DISABLE
50 #else
51 #if defined(CMU_TRACECLKCTRL_CLKSEL_SYSCLK)
52 /* TRACECLK can be clocked from SYSCLK */
53 #define SL_CLOCK_MANAGER_TRACECLK_SOURCE                                                           \
54 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(traceclk)), DT_NODELABEL(sysclk))                \
55 		 ? CMU_TRACECLKCTRL_CLKSEL_SYSCLK                                                  \
56 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(traceclk)), DT_NODELABEL(hfrcodpllrt))         \
57 		 ? CMU_TRACECLKCTRL_CLKSEL_HFRCODPLLRT                                             \
58 		 : COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(hfrcoem23)), (                          \
59 			DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(traceclk)),                       \
60 				DT_NODELABEL(hfrcoem23))                                           \
61 			? CMU_TRACECLKCTRL_CLKSEL_HFRCOEM23                                        \
62 			: SL_CLOCK_MANAGER_INVALID), (SL_CLOCK_MANAGER_INVALID)))
63 
64 #else
65 /* TRACECLK can be clocked from HCLK */
66 #define SL_CLOCK_MANAGER_TRACECLK_SOURCE                                                           \
67 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(traceclk)), DT_NODELABEL(hclk))                  \
68 		 ? CMU_TRACECLKCTRL_CLKSEL_HCLK                                                    \
69 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(traceclk)), DT_NODELABEL(hfrcoem23))           \
70 		 ? CMU_TRACECLKCTRL_CLKSEL_HFRCOEM23                                               \
71 		 : SL_CLOCK_MANAGER_INVALID)
72 #endif /* defined(CMU_TRACECLKCTRL_CLKSEL_SYSCLK) */
73 #if SL_CLOCK_MANAGER_TRACECLK_SOURCE == SL_CLOCK_MANAGER_INVALID
74 #error "Invalid clock source selection for TRACECLK"
75 #endif
76 #endif /* DT_NUM_CLOCKS(traceclk) */
77 #endif /* defined(_CMU_TRACECLKCTRL_CLKSEL_MASK) */
78 
79 #if DT_NODE_HAS_PROP(DT_NODELABEL(traceclk), clock_div)
80 #define SL_CLOCK_MANAGER_TRACECLK_DIVIDER                                                          \
81 	CONCAT(CMU_TRACECLKCTRL_PRESC_DIV, DT_PROP(DT_NODELABEL(traceclk), clock_div))
82 #endif
83 
84 /* EM01GRPACLK */
85 #define SL_CLOCK_MANAGER_EM01GRPACLK_SOURCE                                                        \
86 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpaclk)), DT_NODELABEL(hfrcodpll))          \
87 		 ? CMU_EM01GRPACLKCTRL_CLKSEL_HFRCODPLL                                            \
88 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpaclk)), DT_NODELABEL(hfxo))             \
89 		 ? CMU_EM01GRPACLKCTRL_CLKSEL_HFXO                                                 \
90 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpaclk)), DT_NODELABEL(fsrco))            \
91 		 ? CMU_EM01GRPACLKCTRL_CLKSEL_FSRCO                                                \
92 		 : COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(hfrcoem23)), (                          \
93 			DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpaclk)),                    \
94 				DT_NODELABEL(hfrcoem23))                                           \
95 			? CMU_EM01GRPACLKCTRL_CLKSEL_HFRCOEM23                                     \
96 			: COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(hfrcodpllrt)), (                 \
97 				DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpaclk)),            \
98 					DT_NODELABEL(hfrcodpllrt))                                 \
99 				? CMU_EM01GRPACLKCTRL_CLKSEL_HFRCODPLLRT                           \
100 				: DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpaclk)),          \
101 					DT_NODELABEL(hfxort))                                      \
102 				? CMU_EM01GRPACLKCTRL_CLKSEL_HFXORT                                \
103 				: SL_CLOCK_MANAGER_INVALID), (SL_CLOCK_MANAGER_INVALID))),         \
104 			(SL_CLOCK_MANAGER_INVALID)))
105 
106 #if SL_CLOCK_MANAGER_EM01GRPACLK_SOURCE == SL_CLOCK_MANAGER_INVALID
107 #error "Invalid clock source selection for EM01GRPACLK"
108 #endif
109 
110 /* EM01GRPBCLK */
111 #if DT_NODE_EXISTS(DT_NODELABEL(em01grpbclk))
112 #define SL_CLOCK_MANAGER_EM01GRPBCLK_SOURCE                                                        \
113 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpbclk)), DT_NODELABEL(hfrcodpll))          \
114 		 ? CMU_EM01GRPBCLKCTRL_CLKSEL_HFRCODPLL                                            \
115 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpbclk)), DT_NODELABEL(hfxo))             \
116 		 ? CMU_EM01GRPBCLKCTRL_CLKSEL_HFXO                                                 \
117 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpbclk)), DT_NODELABEL(fsrco))            \
118 		 ? CMU_EM01GRPBCLKCTRL_CLKSEL_FSRCO                                                \
119 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpbclk)), DT_NODELABEL(clkin0))           \
120 		 ? CMU_EM01GRPBCLKCTRL_CLKSEL_CLKIN0                                               \
121 		 : COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(hfrcodpllrt)), (                        \
122 			DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpbclk)),                    \
123 				DT_NODELABEL(hfrcodpllrt))                                         \
124 			? CMU_EM01GRPBCLKCTRL_CLKSEL_HFRCODPLLRT                                   \
125 			: DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpbclk)),                  \
126 				DT_NODELABEL(hfxort))                                              \
127 			? CMU_EM01GRPBCLKCTRL_CLKSEL_HFXORT                                        \
128 			: SL_CLOCK_MANAGER_INVALID), (SL_CLOCK_MANAGER_INVALID)))
129 
130 #if SL_CLOCK_MANAGER_EM01GRPBCLK_SOURCE == SL_CLOCK_MANAGER_INVALID
131 #error "Invalid clock source selection for EM01GRPBCLK"
132 #endif
133 #endif /* DT_NODE_EXISTS(em01grpbclk)*/
134 
135 /* EM01GRPCCLK */
136 #if DT_NODE_EXISTS(DT_NODELABEL(em01grpcclk))
137 #define SL_CLOCK_MANAGER_EM01GRPCCLK_SOURCE                                                        \
138 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpcclk)), DT_NODELABEL(hfrcodpll))          \
139 		 ? CMU_EM01GRPCCLKCTRL_CLKSEL_HFRCODPLL                                            \
140 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpcclk)), DT_NODELABEL(hfxo))             \
141 		 ? CMU_EM01GRPCCLKCTRL_CLKSEL_HFXO                                                 \
142 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpcclk)), DT_NODELABEL(fsrco))            \
143 		 ? CMU_EM01GRPCCLKCTRL_CLKSEL_FSRCO                                                \
144 		 : COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(hfrcoem23)), (                          \
145 			DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpcclk)),                    \
146 				DT_NODELABEL(hfrcodpllrt))                                         \
147 			? CMU_EM01GRPACLKCTRL_CLKSEL_HFRCODPLLRT                                   \
148 			: DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpcclk)),                  \
149 				DT_NODELABEL(hfxort))                                              \
150 			? CMU_EM01GRPACLKCTRL_CLKSEL_HFXORT                                        \
151 			: DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em01grpcclk)),                  \
152 				DT_NODELABEL(hfrcoem23))                                           \
153 			? CMU_EM01GRPCCLKCTRL_CLKSEL_HFRCOEM23                                     \
154 			: SL_CLOCK_MANAGER_INVALID), (SL_CLOCK_MANAGER_INVALID)))
155 
156 #if SL_CLOCK_MANAGER_EM01GRPCCLK_SOURCE == SL_CLOCK_MANAGER_INVALID
157 #error "Invalid clock source selection for EM01GRPCCLK"
158 #endif
159 #endif /* DT_NODE_EXISTS(em01grpcclk)*/
160 
161 /* IADCCLK */
162 #if DT_NODE_EXISTS(DT_NODELABEL(iadcclk))
163 #define SL_CLOCK_MANAGER_IADCCLK_SOURCE                                                            \
164 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(iadcclk)), DT_NODELABEL(em01grpaclk))            \
165 		 ? CMU_IADCCLKCTRL_CLKSEL_EM01GRPACLK                                              \
166 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(iadcclk)), DT_NODELABEL(fsrco))                \
167 		 ? CMU_IADCCLKCTRL_CLKSEL_FSRCO                                                    \
168 		 : COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(hfrcoem23)), (                          \
169 			DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(iadcclk)),                        \
170 				DT_NODELABEL(hfrcoem23))                                           \
171 			? CMU_IADCCLKCTRL_CLKSEL_HFRCOEM23                                         \
172 			: SL_CLOCK_MANAGER_INVALID), (SL_CLOCK_MANAGER_INVALID)))
173 
174 #if SL_CLOCK_MANAGER_IADCCLK_SOURCE == SL_CLOCK_MANAGER_INVALID
175 #error "Invalid clock source selection for IADCCLK"
176 #endif
177 #endif /* DT_NODE_EXISTS(iadcclk) */
178 
179 /* LESENSEHFCLK */
180 #if DT_NODE_EXISTS(DT_NODELABEL(lesensehfclk))
181 #define SL_CLOCK_MANAGER_LESENSEHFCLK_SOURCE                                                       \
182 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(lesensehfclk)), DT_NODELABEL(hfrcoem23))         \
183 		 ? CMU_LESENSEHFCLKCTRL_CLKSEL_HFRCOEM23                                           \
184 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(lesensehfclk)), DT_NODELABEL(fsrco))           \
185 		 ? CMU_LESENSEHFCLKCTRL_CLKSEL_FSRCO                                               \
186 		 : SL_CLOCK_MANAGER_INVALID)
187 
188 #if SL_CLOCK_MANAGER_LESENSEHFCLK_SOURCE == SL_CLOCK_MANAGER_INVALID
189 #error "Invalid clock source selection for LESENSEHFCLK"
190 #endif
191 #endif /* DT_NODE_EXISTS(lesensehfclk) */
192 
193 /* EM23GRPACLK */
194 #define SL_CLOCK_MANAGER_EM23GRPACLK_SOURCE                                                        \
195 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em23grpaclk)), DT_NODELABEL(lfrco))              \
196 		 ? CMU_EM23GRPACLKCTRL_CLKSEL_LFRCO                                                \
197 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em23grpaclk)), DT_NODELABEL(lfxo))             \
198 		 ? CMU_EM23GRPACLKCTRL_CLKSEL_LFXO                                                 \
199 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em23grpaclk)), DT_NODELABEL(ulfrco))           \
200 		 ? CMU_EM23GRPACLKCTRL_CLKSEL_ULFRCO                                               \
201 		 : SL_CLOCK_MANAGER_INVALID)
202 
203 #if SL_CLOCK_MANAGER_EM23GRPACLK_SOURCE == SL_CLOCK_MANAGER_INVALID
204 #error "Invalid clock source selection for EM23GRPACLK"
205 #endif
206 
207 /* EM4GRPACLK */
208 #define SL_CLOCK_MANAGER_EM4GRPACLK_SOURCE                                                         \
209 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em4grpaclk)), DT_NODELABEL(lfrco))               \
210 		 ? CMU_EM4GRPACLKCTRL_CLKSEL_LFRCO                                                 \
211 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em4grpaclk)), DT_NODELABEL(lfxo))              \
212 		 ? CMU_EM4GRPACLKCTRL_CLKSEL_LFXO                                                  \
213 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(em4grpaclk)), DT_NODELABEL(ulfrco))            \
214 		 ? CMU_EM4GRPACLKCTRL_CLKSEL_ULFRCO                                                \
215 		 : SL_CLOCK_MANAGER_INVALID)
216 
217 #if SL_CLOCK_MANAGER_EM4GRPACLK_SOURCE == SL_CLOCK_MANAGER_INVALID
218 #error "Invalid clock source selection for EM4GRPACLK"
219 #endif
220 
221 /* RTCCCLK */
222 #if DT_NODE_EXISTS(DT_NODELABEL(rtccclk))
223 #define SL_CLOCK_MANAGER_RTCCCLK_SOURCE                                                            \
224 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(rtccclk)), DT_NODELABEL(lfrco))                  \
225 		 ? CMU_RTCCCLKCTRL_CLKSEL_LFRCO                                                    \
226 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(rtccclk)), DT_NODELABEL(lfxo))                 \
227 		 ? CMU_RTCCCLKCTRL_CLKSEL_LFXO                                                     \
228 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(rtccclk)), DT_NODELABEL(ulfrco))               \
229 		 ? CMU_RTCCCLKCTRL_CLKSEL_ULFRCO                                                   \
230 		 : SL_CLOCK_MANAGER_INVALID)
231 
232 #if SL_CLOCK_MANAGER_RTCCCLK_SOURCE == SL_CLOCK_MANAGER_INVALID
233 #error "Invalid clock source selection for RTCCCLK"
234 #endif
235 #endif /* DT_NODE_EXISTS(rtccclk) */
236 
237 /* SYSRTCCLK */
238 #if DT_NODE_EXISTS(DT_NODELABEL(sysrtcclk))
239 #define SL_CLOCK_MANAGER_SYSRTCCLK_SOURCE                                                          \
240 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(sysrtcclk)), DT_NODELABEL(lfrco))                \
241 		 ? CMU_SYSRTC0CLKCTRL_CLKSEL_LFRCO                                                 \
242 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(sysrtcclk)), DT_NODELABEL(lfxo))               \
243 		 ? CMU_SYSRTC0CLKCTRL_CLKSEL_LFXO                                                  \
244 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(sysrtcclk)), DT_NODELABEL(ulfrco))             \
245 		 ? CMU_SYSRTC0CLKCTRL_CLKSEL_ULFRCO                                                \
246 		 : SL_CLOCK_MANAGER_INVALID)
247 
248 #if SL_CLOCK_MANAGER_SYSRTCCLK_SOURCE == SL_CLOCK_MANAGER_INVALID
249 #error "Invalid clock source selection for SYSRTCCLK"
250 #endif
251 #endif /* DT_NODE_EXISTS(sysrtcclk) */
252 
253 /* WDOG0CLK */
254 #define SL_CLOCK_MANAGER_WDOG0CLK_SOURCE                                                           \
255 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(wdog0clk)), DT_NODELABEL(lfrco))                 \
256 		 ? CMU_WDOG0CLKCTRL_CLKSEL_LFRCO                                                   \
257 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(wdog0clk)), DT_NODELABEL(lfxo))                \
258 		 ? CMU_WDOG0CLKCTRL_CLKSEL_LFXO                                                    \
259 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(wdog0clk)), DT_NODELABEL(ulfrco))              \
260 		 ? CMU_WDOG0CLKCTRL_CLKSEL_ULFRCO                                                  \
261 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(wdog0clk)), DT_NODELABEL(hclkdiv1024))         \
262 		 ? CMU_WDOG0CLKCTRL_CLKSEL_HCLKDIV1024                                             \
263 		 : SL_CLOCK_MANAGER_INVALID)
264 
265 #if SL_CLOCK_MANAGER_WDOG0CLK_SOURCE == SL_CLOCK_MANAGER_INVALID
266 #error "Invalid clock source selection for WDOG0CLK"
267 #endif
268 
269 /* WDOG1CLK */
270 #if DT_NODE_EXISTS(DT_NODELABEL(wdog1clk))
271 #define SL_CLOCK_MANAGER_WDOG1CLK_SOURCE                                                           \
272 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(wdog1clk)), DT_NODELABEL(lfrco))                 \
273 		 ? CMU_WDOG1CLKCTRL_CLKSEL_LFRCO                                                   \
274 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(wdog1clk)), DT_NODELABEL(lfxo))                \
275 		 ? CMU_WDOG1CLKCTRL_CLKSEL_LFXO                                                    \
276 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(wdog1clk)), DT_NODELABEL(ulfrco))              \
277 		 ? CMU_WDOG1CLKCTRL_CLKSEL_ULFRCO                                                  \
278 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(wdog1clk)), DT_NODELABEL(hclkdiv1024))         \
279 		 ? CMU_WDOG1CLKCTRL_CLKSEL_HCLKDIV1024                                             \
280 		 : SL_CLOCK_MANAGER_INVALID)
281 
282 #if SL_CLOCK_MANAGER_WDOG1CLK_SOURCE == SL_CLOCK_MANAGER_INVALID
283 #error "Invalid clock source selection for WDOG1CLK"
284 #endif
285 #endif /* DT_NODE_EXISTS(wdog1clk) */
286 
287 /* LCDCLK */
288 #if DT_NODE_EXISTS(DT_NODELABEL(lcdclk))
289 #define SL_CLOCK_MANAGER_LCDCLK_SOURCE                                                             \
290 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(lcdclk)), DT_NODELABEL(lfrco))                   \
291 		 ? CMU_LCDCLKCTRL_CLKSEL_LFRCO                                                     \
292 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(lcdclk)), DT_NODELABEL(lfxo))                  \
293 		 ? CMU_LCDCLKCTRL_CLKSEL_LFXO                                                      \
294 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(lcdclk)), DT_NODELABEL(ulfrco))                \
295 		 ? CMU_LCDCLKCTRL_CLKSEL_ULFRCO                                                    \
296 		 : SL_CLOCK_MANAGER_INVALID)
297 
298 #if SL_CLOCK_MANAGER_LCDCLK_SOURCE == SL_CLOCK_MANAGER_INVALID
299 #error "Invalid clock source selection for LCDCLK"
300 #endif
301 #endif /* DT_NODE_EXISTS(lcdclk) */
302 
303 /* PCNT0CLK */
304 /* FIXME: allow clock selection from S0 pin */
305 #if DT_NODE_EXISTS(DT_NODELABEL(pcnt0clk))
306 #if DT_NUM_CLOCKS(DT_NODELABEL(pcnt0clk)) == 0
307 #define SL_CLOCK_MANAGER_PCNT0CLK_SOURCE CMU_PCNT0CLKCTRL_CLKSEL_DISABLED
308 #else
309 #define SL_CLOCK_MANAGER_PCNT0CLK_SOURCE                                                           \
310 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(pcnt0clk)), DT_NODELABEL(em23grpaclk))           \
311 		 ? CMU_PCNT0CLKCTRL_CLKSEL_EM23GRPACLK                                             \
312 		 : SL_CLOCK_MANAGER_INVALID)
313 
314 #if SL_CLOCK_MANAGER_PCNT0CLK_SOURCE == SL_CLOCK_MANAGER_INVALID
315 #error "Invalid clock source selection for PCNT0CLK"
316 #endif
317 #endif /* DT_NUM_CLOCKS(pcnt0clk) */
318 #endif /* DT_NODE_EXISTS(pcnt0clk) */
319 
320 /* EUART0CLK */
321 #if DT_NODE_EXISTS(DT_NODELABEL(euart0clk))
322 #if DT_NUM_CLOCKS(DT_NODELABEL(euart0clk)) == 0
323 #define SL_CLOCK_MANAGER_EUART0CLK_SOURCE CMU_EUART0CLKCTRL_CLKSEL_DISABLED
324 #else
325 #define SL_CLOCK_MANAGER_EUART0CLK_SOURCE                                                          \
326 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(euart0clk)), DT_NODELABEL(em01grpaclk))          \
327 		 ? CMU_EUART0CLKCTRL_CLKSEL_EM01GRPACLK                                            \
328 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(euart0clk)), DT_NODELABEL(em23grpaclk))        \
329 		 ? CMU_EUART0CLKCTRL_CLKSEL_EM23GRPACLK                                            \
330 		 : SL_CLOCK_MANAGER_INVALID)
331 
332 #if SL_CLOCK_MANAGER_EUART0CLK_SOURCE == SL_CLOCK_MANAGER_INVALID
333 #error "Invalid clock source selection for EUART0CLK"
334 #endif
335 #endif /* DT_NUM_CLOCKS(euart0clk) */
336 #endif /* DT_NODE_EXISTS(euart0clk) */
337 
338 /* EUSART0CLK */
339 #if DT_NODE_EXISTS(DT_NODELABEL(eusart0clk))
340 #if DT_NUM_CLOCKS(DT_NODELABEL(eusart0clk)) == 0
341 #define SL_CLOCK_MANAGER_EUSART0CLK_SOURCE CMU_EUSART0CLKCTRL_CLKSEL_DISABLED
342 #else
343 #if DT_NODE_EXISTS(DT_NODELABEL(em01grpbclk))
344 /* If EM01GRPB clock exists, EUSART0 is in EM01GRPA or EM23GRPA */
345 #define SL_CLOCK_MANAGER_EUSART0CLK_SOURCE                                                         \
346 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(eusart0clk)), DT_NODELABEL(em01grpaclk))         \
347 		 ? CMU_EUSART0CLKCTRL_CLKSEL_EM01GRPACLK                                           \
348 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(eusart0clk)), DT_NODELABEL(em23grpaclk))       \
349 		 ? CMU_EUSART0CLKCTRL_CLKSEL_EM23GRPACLK                                           \
350 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(eusart0clk)), DT_NODELABEL(fsrco))             \
351 		 ? CMU_EUSART0CLKCTRL_CLKSEL_FSRCO                                                 \
352 		 : SL_CLOCK_MANAGER_INVALID)
353 #else
354 /* Otherwise, EUSART0 is in EM01GRPC or directly connected to oscillators */
355 #define SL_CLOCK_MANAGER_EUSART0CLK_SOURCE                                                         \
356 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(eusart0clk)), DT_NODELABEL(em01grpcclk))         \
357 		 ? CMU_EUSART0CLKCTRL_CLKSEL_EM01GRPCCLK                                           \
358 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(eusart0clk)), DT_NODELABEL(hfrcoem23))         \
359 		 ? CMU_EUSART0CLKCTRL_CLKSEL_HFRCOEM23                                             \
360 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(eusart0clk)), DT_NODELABEL(lfrco))             \
361 		 ? CMU_EUSART0CLKCTRL_CLKSEL_LFRCO                                                 \
362 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(eusart0clk)), DT_NODELABEL(lfxo))              \
363 		 ? CMU_EUSART0CLKCTRL_CLKSEL_LFXO                                                  \
364 		 : SL_CLOCK_MANAGER_INVALID)
365 #endif /* DT_NODE_EXISTS(em01grpbclk) */
366 #if SL_CLOCK_MANAGER_EUSART0CLK_SOURCE == SL_CLOCK_MANAGER_INVALID
367 #error "Invalid clock source selection for EUSART0CLK"
368 #endif
369 #endif /* DT_NUM_CLOCKS(eusart0clk) */
370 #endif /* DT_NODE_EXISTS(eusart0clk) */
371 
372 /* SYSTICKCLK */
373 #if DT_NODE_EXISTS(DT_NODELABEL(systickclk))
374 #define SL_CLOCK_MANAGER_SYSTICKCLK_SOURCE                                                         \
375 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(systickclk)), DT_NODELABEL(hclk)) ? 0            \
376 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(systickclk)), DT_NODELABEL(em23grpaclk))       \
377 		 ? 1                                                                               \
378 		 : SL_CLOCK_MANAGER_INVALID)
379 
380 #if SL_CLOCK_MANAGER_SYSTICKCLK_SOURCE == SL_CLOCK_MANAGER_INVALID
381 #error "Invalid clock source selection for SYSTICKCLK"
382 #endif
383 #endif /* DT_NODE_EXISTS(systickclk) */
384 
385 /* VDAC0CLK */
386 #if DT_NODE_EXISTS(DT_NODELABEL(vdac0clk))
387 #if DT_NUM_CLOCKS(DT_NODELABEL(vdac0clk)) == 0
388 #define SL_CLOCK_MANAGER_VDAC0CLK_SOURCE CMU_VDAC0CLKCTRL_CLKSEL_DISABLED
389 #else
390 #define SL_CLOCK_MANAGER_VDAC0CLK_SOURCE                                                           \
391 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(vdac0clk)), DT_NODELABEL(em01grpaclk))           \
392 		 ? CMU_VDAC0CLKCTRL_CLKSEL_EM01GRPACLK                                             \
393 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(vdac0clk)), DT_NODELABEL(em23grpaclk))         \
394 		 ? CMU_VDAC0CLKCTRL_CLKSEL_EM23GRPACLK                                             \
395 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(vdac0clk)), DT_NODELABEL(fsrco))               \
396 		 ? CMU_VDAC0CLKCTRL_CLKSEL_FSRCO                                                   \
397 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(vdac0clk)), DT_NODELABEL(hfrcoem23))           \
398 		 ? CMU_VDAC0CLKCTRL_CLKSEL_HFRCOEM23                                               \
399 		 : SL_CLOCK_MANAGER_INVALID)
400 
401 #if SL_CLOCK_MANAGER_VDAC0CLK_SOURCE == SL_CLOCK_MANAGER_INVALID
402 #error "Invalid clock source selection for VDAC0CLK"
403 #endif
404 #endif /* DT_NUM_CLOCKS(vdac0clk) */
405 #endif /* DT_NODE_EXISTS(vdac0clk) */
406 
407 /* VDAC1CLK */
408 #if DT_NODE_EXISTS(DT_NODELABEL(vdac1clk))
409 #if DT_NUM_CLOCKS(DT_NODELABEL(vdac1clk)) == 0
410 #define SL_CLOCK_MANAGER_VDAC1CLK_SOURCE CMU_VDAC1CLKCTRL_CLKSEL_DISABLED
411 #else
412 #define SL_CLOCK_MANAGER_VDAC1CLK_SOURCE                                                           \
413 	(DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(vdac1clk)), DT_NODELABEL(em01grpaclk))           \
414 		 ? CMU_VDAC1CLKCTRL_CLKSEL_EM01GRPACLK                                             \
415 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(vdac1clk)), DT_NODELABEL(em23grpaclk))         \
416 		 ? CMU_VDAC1CLKCTRL_CLKSEL_EM23GRPACLK                                             \
417 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(vdac1clk)), DT_NODELABEL(fsrco))               \
418 		 ? CMU_VDAC1CLKCTRL_CLKSEL_FSRCO                                                   \
419 	 : DT_SAME_NODE(DT_CLOCKS_CTLR(DT_NODELABEL(vdac1clk)), DT_NODELABEL(hfrcoem23))           \
420 		 ? CMU_VDAC1CLKCTRL_CLKSEL_HFRCOEM23                                               \
421 		 : SL_CLOCK_MANAGER_INVALID)
422 
423 #if SL_CLOCK_MANAGER_VDAC1CLK_SOURCE == SL_CLOCK_MANAGER_INVALID
424 #error "Invalid clock source selection for VDAC1CLK"
425 #endif
426 #endif /* DT_NUM_CLOCKS(vdac1clk) */
427 #endif /* DT_NODE_EXISTS(vdac1clk) */
428 
429 #endif /* SL_CLOCK_MANAGER_TREE_CONFIG_H */
430