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