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