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