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