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