blob: 285aeb336c8f0987e6bc1df6545cf82e9a53d08c [file] [log] [blame]
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +03001/* SPDX-License-Identifier: BSD-3-Clause */
2/*
Ghennadi Procopciuc7d927632025-01-10 16:26:21 +02003 * Copyright 2020-2025 NXP
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +03004 */
5#ifndef S32CC_CLK_MODULES_H
6#define S32CC_CLK_MODULES_H
7
8#include <inttypes.h>
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +03009#include <stdbool.h>
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +030010#include <stddef.h>
11
12#define MHZ UL(1000000)
13#define GHZ (UL(1000) * MHZ)
14
15enum s32cc_clkm_type {
16 s32cc_osc_t,
17 s32cc_clk_t,
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030018 s32cc_pll_t,
19 s32cc_pll_out_div_t,
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +030020 s32cc_dfs_t,
21 s32cc_dfs_div_t,
Ghennadi Procopciuc224a0762025-01-23 10:34:35 +020022 s32cc_cgm_div_t,
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030023 s32cc_clkmux_t,
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030024 s32cc_shared_clkmux_t,
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +030025 s32cc_fixed_div_t,
Ghennadi Procopciucd01fe9c2024-09-11 15:09:43 +030026 s32cc_part_t,
27 s32cc_part_block_t,
28 s32cc_part_block_link_t,
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +030029};
30
31enum s32cc_clk_source {
32 S32CC_FIRC,
33 S32CC_FXOSC,
34 S32CC_SIRC,
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030035 S32CC_ARM_PLL,
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +030036 S32CC_ARM_DFS,
Ghennadi Procopciuc22f94742024-08-06 11:48:11 +030037 S32CC_PERIPH_PLL,
Ghennadi Procopciuc90c90002024-08-05 16:50:52 +030038 S32CC_CGM0,
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030039 S32CC_CGM1,
Ghennadi Procopciuc74dde092024-09-09 10:24:35 +030040 S32CC_DDR_PLL,
Ghennadi Procopciuceb26f082025-01-20 16:02:21 +020041 S32CC_PERIPH_DFS,
Ghennadi Procopciucd3cd7832024-09-17 09:02:24 +030042 S32CC_CGM5,
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +030043};
44
45struct s32cc_clk_obj {
46 enum s32cc_clkm_type type;
47 uint32_t refcount;
48};
49
50struct s32cc_osc {
51 struct s32cc_clk_obj desc;
52 enum s32cc_clk_source source;
53 unsigned long freq;
54 void *base;
55};
56
Ghennadi Procopciuc7d927632025-01-10 16:26:21 +020057#define S32CC_OSC_INIT_FREQ(SOURCE, FREQ) \
58{ \
59 .desc = { \
60 .type = s32cc_osc_t, \
61 }, \
62 .source = (SOURCE), \
63 .freq = (FREQ), \
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +030064}
65
Ghennadi Procopciuc7d927632025-01-10 16:26:21 +020066#define S32CC_OSC_INIT(SOURCE) \
67 S32CC_OSC_INIT_FREQ(SOURCE, 0)
68
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030069struct s32cc_clkmux {
70 struct s32cc_clk_obj desc;
71 enum s32cc_clk_source module;
72 uint8_t index; /* Mux index in parent module */
73 unsigned long source_id; /* Selected source */
74 uint8_t nclks; /* Number of input clocks */
75 unsigned long clkids[5]; /* IDs of the input clocks */
76};
77
78#define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
79{ \
80 .desc = { \
81 .type = (TYPE), \
82 }, \
83 .module = (MODULE), \
84 .index = (INDEX), \
85 .nclks = (NCLKS), \
86 .clkids = {__VA_ARGS__}, \
87}
88
89#define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
90 S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \
91 INDEX, NCLKS, __VA_ARGS__)
92
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030093#define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
94 S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
95 INDEX, NCLKS, __VA_ARGS__)
96
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030097struct s32cc_pll {
98 struct s32cc_clk_obj desc;
99 struct s32cc_clk_obj *source;
100 enum s32cc_clk_source instance;
101 unsigned long vco_freq;
102 uint32_t ndividers;
103 uintptr_t base;
104};
105
106#define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
107{ \
108 .desc = { \
109 .type = s32cc_pll_t, \
110 }, \
111 .source = &(PLL_MUX_CLK).desc, \
112 .instance = (INSTANCE), \
113 .ndividers = (NDIVIDERS), \
114}
115
116struct s32cc_pll_out_div {
117 struct s32cc_clk_obj desc;
118 struct s32cc_clk_obj *parent;
119 uint32_t index;
120 unsigned long freq;
121};
122
123#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \
124{ \
125 .desc = { \
126 .type = s32cc_pll_out_div_t, \
127 }, \
128 .parent = &(PARENT).desc, \
129 .index = (INDEX), \
130}
131
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +0300132#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \
133{ \
134 .desc = { \
135 .type = s32cc_pll_out_div_t, \
136 }, \
137 .parent = &(PARENT).desc, \
138 .index = (INDEX), \
139}
140
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300141struct s32cc_dfs {
142 struct s32cc_clk_obj desc;
143 struct s32cc_clk_obj *parent;
144 enum s32cc_clk_source instance;
145 uintptr_t base;
146};
147
148#define S32CC_DFS_INIT(PARENT, INSTANCE) \
149{ \
150 .desc = { \
151 .type = s32cc_dfs_t, \
152 }, \
153 .parent = &(PARENT).desc, \
154 .instance = (INSTANCE), \
155}
156
157struct s32cc_dfs_div {
158 struct s32cc_clk_obj desc;
159 struct s32cc_clk_obj *parent;
160 uint32_t index;
161 unsigned long freq;
162};
163
164#define S32CC_DFS_DIV_INIT(PARENT, INDEX) \
165{ \
166 .desc = { \
167 .type = s32cc_dfs_div_t, \
168 }, \
169 .parent = &(PARENT).desc, \
170 .index = (INDEX), \
171}
172
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +0300173struct s32cc_fixed_div {
174 struct s32cc_clk_obj desc;
175 struct s32cc_clk_obj *parent;
176 uint32_t rate_div;
177};
178
179#define S32CC_FIXED_DIV_INIT(PARENT, RATE_DIV) \
180{ \
181 .desc = { \
182 .type = s32cc_fixed_div_t, \
183 }, \
184 .parent = &(PARENT).desc, \
185 .rate_div = (RATE_DIV), \
186}
187
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300188struct s32cc_clk {
189 struct s32cc_clk_obj desc;
190 struct s32cc_clk_obj *module;
191 struct s32cc_clk *pclock;
192 unsigned long min_freq;
193 unsigned long max_freq;
194};
195
196struct s32cc_clk_array {
197 unsigned long type_mask;
198 struct s32cc_clk **clks;
199 size_t n_clks;
200};
201
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300202#define S32CC_FREQ_CLK(PARENT_MODULE, PARENT, MIN_F, MAX_F) \
203{ \
204 .desc = { \
205 .type = s32cc_clk_t, \
206 }, \
207 .pclock = (PARENT), \
208 .module = (PARENT_MODULE), \
209 .min_freq = (MIN_F), \
210 .max_freq = (MAX_F), \
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300211}
212
213#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300214 S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300215
216#define S32CC_MODULE_CLK(PARENT_MODULE) \
217 S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
218
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300219#define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
220 S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
221
Ghennadi Procopciucd01fe9c2024-09-11 15:09:43 +0300222struct s32cc_part {
223 struct s32cc_clk_obj desc;
224 uint32_t partition_id;
225};
226
227#define S32CC_PART(PART_NUM) \
228{ \
229 .desc = { \
230 .type = s32cc_part_t, \
231 }, \
232 .partition_id = (PART_NUM), \
233}
234
235enum s32cc_part_block_type {
236 s32cc_part_block0,
237 s32cc_part_block1,
238 s32cc_part_block2,
239 s32cc_part_block3,
240 s32cc_part_block4,
241 s32cc_part_block5,
242 s32cc_part_block6,
243 s32cc_part_block7,
244 s32cc_part_block8,
245 s32cc_part_block9,
246 s32cc_part_block10,
247 s32cc_part_block11,
248 s32cc_part_block12,
249 s32cc_part_block13,
250 s32cc_part_block14,
251 s32cc_part_block15,
252};
253
254struct s32cc_part_block {
255 struct s32cc_clk_obj desc;
256 struct s32cc_part *part;
257 enum s32cc_part_block_type block;
258 bool status;
259};
260
261#define S32CC_PART_BLOCK_STATUS(PART_META, BLOCK_TYPE, STATUS) \
262{ \
263 .desc = { \
264 .type = s32cc_part_block_t, \
265 }, \
266 .part = (PART_META), \
267 .block = (BLOCK_TYPE), \
268 .status = (STATUS), \
269}
270
271#define S32CC_PART_BLOCK(PARENT, BLOCK_TYPE) \
272 S32CC_PART_BLOCK_STATUS(PARENT, BLOCK_TYPE, true)
273
274#define S32CC_PART_BLOCK_NO_STATUS(PARENT, BLOCK_TYPE) \
275 S32CC_PART_BLOCK_STATUS(PARENT, BLOCK_TYPE, false)
276
277struct s32cc_part_block_link {
278 struct s32cc_clk_obj desc;
279 struct s32cc_clk_obj *parent;
280 struct s32cc_part_block *block;
281};
282
283#define S32CC_PART_BLOCK_LINK(PARENT, BLOCK) \
284{ \
285 .desc = { \
286 .type = s32cc_part_block_link_t, \
287 }, \
288 .parent = &(PARENT).desc, \
289 .block = (BLOCK), \
290}
291
Ghennadi Procopciuc224a0762025-01-23 10:34:35 +0200292struct s32cc_cgm_div {
293 struct s32cc_clk_obj desc;
294 struct s32cc_clk_obj *parent;
295 unsigned long freq;
296 uint32_t index;
297};
298
299#define S32CC_CGM_DIV_INIT(PARENT, INDEX) \
300{ \
301 .desc = { \
302 .type = s32cc_cgm_div_t, \
303 }, \
304 .parent = &(PARENT).desc, \
305 .index = (INDEX), \
306}
307
Ghennadi Procopciuc0d525772024-06-12 08:09:19 +0300308static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
309{
310 uintptr_t osc_addr;
311
312 osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
313 return (struct s32cc_osc *)osc_addr;
314}
315
316static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
317{
318 uintptr_t clk_addr;
319
320 clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
321 return (struct s32cc_clk *)clk_addr;
322}
323
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300324static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
325{
326 const struct s32cc_clk_obj *module;
327
328 module = clk->module;
329 if (module == NULL) {
330 return false;
331 }
332
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +0300333 return (module->type == s32cc_clkmux_t) ||
334 (module->type == s32cc_shared_clkmux_t);
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300335}
336
337static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
338{
339 uintptr_t cmux_addr;
340
341 cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
342 return (struct s32cc_clkmux *)cmux_addr;
343}
344
345static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
346{
347 if (!is_s32cc_clk_mux(clk)) {
348 return NULL;
349 }
350
351 return s32cc_obj2clkmux(clk->module);
352}
353
Ghennadi Procopciuce18cf332024-06-12 11:55:32 +0300354static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod)
355{
356 uintptr_t pll_addr;
357
358 pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc);
359 return (struct s32cc_pll *)pll_addr;
360}
361
Ghennadi Procopciuc907f6542024-06-12 12:00:15 +0300362static inline struct s32cc_pll_out_div *s32cc_obj2plldiv(const struct s32cc_clk_obj *mod)
363{
364 uintptr_t plldiv_addr;
365
366 plldiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll_out_div, desc);
367 return (struct s32cc_pll_out_div *)plldiv_addr;
368}
369
Ghennadi Procopciuce6946b62024-06-12 12:29:54 +0300370static inline struct s32cc_fixed_div *s32cc_obj2fixeddiv(const struct s32cc_clk_obj *mod)
371{
372 uintptr_t fdiv_addr;
373
374 fdiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_fixed_div, desc);
375 return (struct s32cc_fixed_div *)fdiv_addr;
376}
377
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300378static inline struct s32cc_dfs *s32cc_obj2dfs(const struct s32cc_clk_obj *mod)
379{
380 uintptr_t dfs_addr;
381
382 dfs_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs, desc);
383 return (struct s32cc_dfs *)dfs_addr;
384}
385
386static inline struct s32cc_dfs_div *s32cc_obj2dfsdiv(const struct s32cc_clk_obj *mod)
387{
388 uintptr_t dfs_div_addr;
389
390 dfs_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs_div, desc);
391 return (struct s32cc_dfs_div *)dfs_div_addr;
392}
393
Ghennadi Procopciucd01fe9c2024-09-11 15:09:43 +0300394static inline struct s32cc_part *s32cc_obj2part(const struct s32cc_clk_obj *mod)
395{
396 uintptr_t part_addr;
397
398 part_addr = ((uintptr_t)mod) - offsetof(struct s32cc_part, desc);
399 return (struct s32cc_part *)part_addr;
400}
401
402static inline struct s32cc_part_block *
403s32cc_obj2partblock(const struct s32cc_clk_obj *mod)
404{
405 uintptr_t part_blk_addr;
406
407 part_blk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_part_block, desc);
408 return (struct s32cc_part_block *)part_blk_addr;
409}
410
411static inline struct s32cc_part_block_link *
412s32cc_obj2partblocklink(const struct s32cc_clk_obj *mod)
413{
414 uintptr_t blk_link;
415
416 blk_link = ((uintptr_t)mod) - offsetof(struct s32cc_part_block_link, desc);
417 return (struct s32cc_part_block_link *)blk_link;
418}
419
Ghennadi Procopciuc224a0762025-01-23 10:34:35 +0200420static inline struct s32cc_cgm_div *s32cc_obj2cgmdiv(const struct s32cc_clk_obj *mod)
421{
422 uintptr_t cgm_div_addr;
423
424 cgm_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_cgm_div, desc);
425 return (struct s32cc_cgm_div *)cgm_div_addr;
426}
427
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300428#endif /* S32CC_CLK_MODULES_H */