xref: /rk3399_ARM-atf/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h (revision ed0c801fc69f55103c597dcc29cadf4c7cb7d575)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*
3  * Copyright 2020-2025 NXP
4  */
5 #ifndef S32CC_CLK_MODULES_H
6 #define S32CC_CLK_MODULES_H
7 
8 #include <inttypes.h>
9 #include <stdbool.h>
10 #include <stddef.h>
11 
12 #define MHZ	UL(1000000)
13 #define GHZ	(UL(1000) * MHZ)
14 
15 enum s32cc_clkm_type {
16 	s32cc_osc_t,
17 	s32cc_clk_t,
18 	s32cc_pll_t,
19 	s32cc_pll_out_div_t,
20 	s32cc_dfs_t,
21 	s32cc_dfs_div_t,
22 	s32cc_cgm_div_t,
23 	s32cc_clkmux_t,
24 	s32cc_shared_clkmux_t,
25 	s32cc_fixed_div_t,
26 	s32cc_part_t,
27 	s32cc_part_block_t,
28 	s32cc_part_block_link_t,
29 };
30 
31 enum s32cc_clk_source {
32 	S32CC_FIRC,
33 	S32CC_FXOSC,
34 	S32CC_SIRC,
35 	S32CC_ARM_PLL,
36 	S32CC_ARM_DFS,
37 	S32CC_PERIPH_PLL,
38 	S32CC_CGM0,
39 	S32CC_CGM1,
40 	S32CC_DDR_PLL,
41 	S32CC_PERIPH_DFS,
42 	S32CC_CGM5,
43 };
44 
45 struct s32cc_clk_obj {
46 	enum s32cc_clkm_type type;
47 	uint32_t refcount;
48 };
49 
50 struct s32cc_osc {
51 	struct s32cc_clk_obj desc;
52 	enum s32cc_clk_source source;
53 	unsigned long freq;
54 	void *base;
55 };
56 
57 #define S32CC_OSC_INIT_FREQ(SOURCE, FREQ) \
58 {                                         \
59 	.desc = {                         \
60 		.type = s32cc_osc_t,      \
61 	},                                \
62 	.source = (SOURCE),               \
63 	.freq = (FREQ),                   \
64 }
65 
66 #define S32CC_OSC_INIT(SOURCE) \
67 	S32CC_OSC_INIT_FREQ(SOURCE, 0)
68 
69 struct s32cc_clkmux {
70 	struct s32cc_clk_obj desc;
71 	enum s32cc_clk_source module;
72 	uint8_t index; /* Mux index in parent module */
73 	unsigned long source_id; /* Selected source */
74 	uint8_t nclks; /* Number of input clocks */
75 	unsigned long clkids[5]; /* IDs of the input clocks */
76 };
77 
78 #define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
79 {                                                               \
80 	.desc = {                                               \
81 		.type = (TYPE),                                 \
82 	},                                                      \
83 	.module = (MODULE),                                     \
84 	.index = (INDEX),                                       \
85 	.nclks = (NCLKS),                                       \
86 	.clkids = {__VA_ARGS__},                                \
87 }
88 
89 #define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)     \
90 	S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE,   \
91 			       INDEX, NCLKS, __VA_ARGS__)
92 
93 #define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)   \
94 	S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
95 			       INDEX, NCLKS, __VA_ARGS__)
96 
97 struct s32cc_pll {
98 	struct s32cc_clk_obj desc;
99 	struct s32cc_clk_obj *source;
100 	enum s32cc_clk_source instance;
101 	unsigned long vco_freq;
102 	uint32_t ndividers;
103 	uintptr_t base;
104 };
105 
106 #define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
107 {                                                        \
108 	.desc = {                                        \
109 		.type = s32cc_pll_t,                     \
110 	},                                               \
111 	.source = &(PLL_MUX_CLK).desc,                   \
112 	.instance = (INSTANCE),                          \
113 	.ndividers = (NDIVIDERS),                        \
114 }
115 
116 struct s32cc_pll_out_div {
117 	struct s32cc_clk_obj desc;
118 	struct s32cc_clk_obj *parent;
119 	uint32_t index;
120 	unsigned long freq;
121 };
122 
123 #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX)  \
124 {                                              \
125 	.desc = {                              \
126 		.type = s32cc_pll_out_div_t,   \
127 	},                                     \
128 	.parent = &(PARENT).desc,              \
129 	.index = (INDEX),                      \
130 }
131 
132 #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX)  \
133 {                                              \
134 	.desc = {                              \
135 		.type = s32cc_pll_out_div_t,   \
136 	},                                     \
137 	.parent = &(PARENT).desc,              \
138 	.index = (INDEX),                      \
139 }
140 
141 struct s32cc_dfs {
142 	struct s32cc_clk_obj desc;
143 	struct s32cc_clk_obj *parent;
144 	enum s32cc_clk_source instance;
145 	uintptr_t base;
146 };
147 
148 #define S32CC_DFS_INIT(PARENT, INSTANCE) \
149 {                                        \
150 	.desc = {                        \
151 		.type = s32cc_dfs_t,     \
152 	},                               \
153 	.parent = &(PARENT).desc,        \
154 	.instance = (INSTANCE),          \
155 }
156 
157 struct s32cc_dfs_div {
158 	struct s32cc_clk_obj desc;
159 	struct s32cc_clk_obj *parent;
160 	uint32_t index;
161 	unsigned long freq;
162 };
163 
164 #define S32CC_DFS_DIV_INIT(PARENT, INDEX) \
165 {                                         \
166 	.desc = {                         \
167 		.type = s32cc_dfs_div_t,  \
168 	},                                \
169 	.parent = &(PARENT).desc,         \
170 	.index = (INDEX),                 \
171 }
172 
173 struct s32cc_fixed_div {
174 	struct s32cc_clk_obj desc;
175 	struct s32cc_clk_obj *parent;
176 	uint32_t rate_div;
177 };
178 
179 #define S32CC_FIXED_DIV_INIT(PARENT, RATE_DIV) \
180 {                                              \
181 	.desc = {                              \
182 		.type = s32cc_fixed_div_t,     \
183 	},                                     \
184 	.parent = &(PARENT).desc,              \
185 	.rate_div = (RATE_DIV),                \
186 }
187 
188 struct s32cc_clk {
189 	struct s32cc_clk_obj desc;
190 	struct s32cc_clk_obj *module;
191 	struct s32cc_clk *pclock;
192 	unsigned long min_freq;
193 	unsigned long max_freq;
194 };
195 
196 struct s32cc_clk_array {
197 	unsigned long type_mask;
198 	struct s32cc_clk **clks;
199 	size_t n_clks;
200 };
201 
202 #define S32CC_FREQ_CLK(PARENT_MODULE, PARENT, MIN_F, MAX_F) \
203 {                                                           \
204 	.desc = {                                           \
205 		.type = s32cc_clk_t,                        \
206 	},                                                  \
207 	.pclock = (PARENT),                                 \
208 	.module = (PARENT_MODULE),                          \
209 	.min_freq = (MIN_F),                                \
210 	.max_freq = (MAX_F),                                \
211 }
212 
213 #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
214 	S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
215 
216 #define S32CC_MODULE_CLK(PARENT_MODULE) \
217 	S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
218 
219 #define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
220 	S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
221 
222 struct s32cc_part {
223 	struct s32cc_clk_obj desc;
224 	uint32_t partition_id;
225 };
226 
227 #define S32CC_PART(PART_NUM)          \
228 {                                     \
229 	.desc = {                     \
230 		.type = s32cc_part_t, \
231 	},                            \
232 	.partition_id = (PART_NUM),   \
233 }
234 
235 enum s32cc_part_block_type {
236 	s32cc_part_block0,
237 	s32cc_part_block1,
238 	s32cc_part_block2,
239 	s32cc_part_block3,
240 	s32cc_part_block4,
241 	s32cc_part_block5,
242 	s32cc_part_block6,
243 	s32cc_part_block7,
244 	s32cc_part_block8,
245 	s32cc_part_block9,
246 	s32cc_part_block10,
247 	s32cc_part_block11,
248 	s32cc_part_block12,
249 	s32cc_part_block13,
250 	s32cc_part_block14,
251 	s32cc_part_block15,
252 };
253 
254 struct s32cc_part_block {
255 	struct s32cc_clk_obj desc;
256 	struct s32cc_part *part;
257 	enum s32cc_part_block_type block;
258 	bool status;
259 };
260 
261 #define S32CC_PART_BLOCK_STATUS(PART_META, BLOCK_TYPE, STATUS) \
262 {                                                              \
263 	.desc = {                                              \
264 		.type = s32cc_part_block_t,                    \
265 	},                                                     \
266 	.part = (PART_META),                                   \
267 	.block = (BLOCK_TYPE),                                 \
268 	.status = (STATUS),                                    \
269 }
270 
271 #define S32CC_PART_BLOCK(PARENT, BLOCK_TYPE) \
272 	S32CC_PART_BLOCK_STATUS(PARENT, BLOCK_TYPE, true)
273 
274 #define S32CC_PART_BLOCK_NO_STATUS(PARENT, BLOCK_TYPE) \
275 	S32CC_PART_BLOCK_STATUS(PARENT, BLOCK_TYPE, false)
276 
277 struct s32cc_part_block_link {
278 	struct s32cc_clk_obj desc;
279 	struct s32cc_clk_obj *parent;
280 	struct s32cc_part_block *block;
281 };
282 
283 #define S32CC_PART_BLOCK_LINK(PARENT, BLOCK)     \
284 {                                                \
285 	.desc = {                                \
286 		.type = s32cc_part_block_link_t, \
287 	},                                       \
288 	.parent = &(PARENT).desc,                \
289 	.block = (BLOCK),                        \
290 }
291 
292 struct s32cc_cgm_div {
293 	struct s32cc_clk_obj desc;
294 	struct s32cc_clk_obj *parent;
295 	unsigned long freq;
296 	uint32_t index;
297 };
298 
299 #define S32CC_CGM_DIV_INIT(PARENT, INDEX) \
300 {                                         \
301 	.desc = {                         \
302 		.type = s32cc_cgm_div_t,  \
303 	},                                \
304 	.parent = &(PARENT).desc,         \
305 	.index = (INDEX),                 \
306 }
307 
308 static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
309 {
310 	uintptr_t osc_addr;
311 
312 	osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
313 	return (struct s32cc_osc *)osc_addr;
314 }
315 
316 static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
317 {
318 	uintptr_t clk_addr;
319 
320 	clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
321 	return (struct s32cc_clk *)clk_addr;
322 }
323 
324 static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
325 {
326 	const struct s32cc_clk_obj *module;
327 
328 	module = clk->module;
329 	if (module == NULL) {
330 		return false;
331 	}
332 
333 	return (module->type == s32cc_clkmux_t) ||
334 	    (module->type == s32cc_shared_clkmux_t);
335 }
336 
337 static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
338 {
339 	uintptr_t cmux_addr;
340 
341 	cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
342 	return (struct s32cc_clkmux *)cmux_addr;
343 }
344 
345 static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
346 {
347 	if (!is_s32cc_clk_mux(clk)) {
348 		return NULL;
349 	}
350 
351 	return s32cc_obj2clkmux(clk->module);
352 }
353 
354 static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod)
355 {
356 	uintptr_t pll_addr;
357 
358 	pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc);
359 	return (struct s32cc_pll *)pll_addr;
360 }
361 
362 static inline struct s32cc_pll_out_div *s32cc_obj2plldiv(const struct s32cc_clk_obj *mod)
363 {
364 	uintptr_t plldiv_addr;
365 
366 	plldiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll_out_div, desc);
367 	return (struct s32cc_pll_out_div *)plldiv_addr;
368 }
369 
370 static inline struct s32cc_fixed_div *s32cc_obj2fixeddiv(const struct s32cc_clk_obj *mod)
371 {
372 	uintptr_t fdiv_addr;
373 
374 	fdiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_fixed_div, desc);
375 	return (struct s32cc_fixed_div *)fdiv_addr;
376 }
377 
378 static inline struct s32cc_dfs *s32cc_obj2dfs(const struct s32cc_clk_obj *mod)
379 {
380 	uintptr_t dfs_addr;
381 
382 	dfs_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs, desc);
383 	return (struct s32cc_dfs *)dfs_addr;
384 }
385 
386 static inline struct s32cc_dfs_div *s32cc_obj2dfsdiv(const struct s32cc_clk_obj *mod)
387 {
388 	uintptr_t dfs_div_addr;
389 
390 	dfs_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs_div, desc);
391 	return (struct s32cc_dfs_div *)dfs_div_addr;
392 }
393 
394 static inline struct s32cc_part *s32cc_obj2part(const struct s32cc_clk_obj *mod)
395 {
396 	uintptr_t part_addr;
397 
398 	part_addr = ((uintptr_t)mod) - offsetof(struct s32cc_part, desc);
399 	return (struct s32cc_part *)part_addr;
400 }
401 
402 static inline struct s32cc_part_block *
403 s32cc_obj2partblock(const struct s32cc_clk_obj *mod)
404 {
405 	uintptr_t part_blk_addr;
406 
407 	part_blk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_part_block, desc);
408 	return (struct s32cc_part_block *)part_blk_addr;
409 }
410 
411 static inline struct s32cc_part_block_link *
412 s32cc_obj2partblocklink(const struct s32cc_clk_obj *mod)
413 {
414 	uintptr_t blk_link;
415 
416 	blk_link = ((uintptr_t)mod) - offsetof(struct s32cc_part_block_link, desc);
417 	return (struct s32cc_part_block_link *)blk_link;
418 }
419 
420 static inline struct s32cc_cgm_div *s32cc_obj2cgmdiv(const struct s32cc_clk_obj *mod)
421 {
422 	uintptr_t cgm_div_addr;
423 
424 	cgm_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_cgm_div, desc);
425 	return (struct s32cc_cgm_div *)cgm_div_addr;
426 }
427 
428 #endif /* S32CC_CLK_MODULES_H */
429