blob: 4837f795b58222d245d255cf80f00e276f0c2966 [file] [log] [blame]
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +03001/* 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>
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 Procopciuc7277b972024-06-12 09:53:18 +030022 s32cc_clkmux_t,
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030023 s32cc_shared_clkmux_t,
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +030024 s32cc_fixed_div_t,
Ghennadi Procopciucd01fe9c2024-09-11 15:09:43 +030025 s32cc_part_t,
26 s32cc_part_block_t,
27 s32cc_part_block_link_t,
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +030028};
29
30enum s32cc_clk_source {
31 S32CC_FIRC,
32 S32CC_FXOSC,
33 S32CC_SIRC,
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030034 S32CC_ARM_PLL,
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +030035 S32CC_ARM_DFS,
Ghennadi Procopciuc22f94742024-08-06 11:48:11 +030036 S32CC_PERIPH_PLL,
Ghennadi Procopciuc90c90002024-08-05 16:50:52 +030037 S32CC_CGM0,
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030038 S32CC_CGM1,
Ghennadi Procopciuc74dde092024-09-09 10:24:35 +030039 S32CC_DDR_PLL,
Ghennadi Procopciucd3cd7832024-09-17 09:02:24 +030040 S32CC_CGM5,
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +030041};
42
43struct s32cc_clk_obj {
44 enum s32cc_clkm_type type;
45 uint32_t refcount;
46};
47
48struct 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
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030063struct 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
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030087#define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
88 S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
89 INDEX, NCLKS, __VA_ARGS__)
90
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030091struct 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
110struct 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
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +0300126#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
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300135struct 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
151struct 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
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +0300167struct 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
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300182struct 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
190struct s32cc_clk_array {
191 unsigned long type_mask;
192 struct s32cc_clk **clks;
193 size_t n_clks;
194};
195
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300196#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), \
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300205}
206
207#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300208 S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300209
210#define S32CC_MODULE_CLK(PARENT_MODULE) \
211 S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
212
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300213#define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
214 S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
215
Ghennadi Procopciucd01fe9c2024-09-11 15:09:43 +0300216struct 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
229enum 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
248struct 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
271struct 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
Ghennadi Procopciuc0d525772024-06-12 08:09:19 +0300286static 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
294static 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
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300302static 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
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +0300311 return (module->type == s32cc_clkmux_t) ||
312 (module->type == s32cc_shared_clkmux_t);
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300313}
314
315static 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
323static 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
Ghennadi Procopciuce18cf332024-06-12 11:55:32 +0300332static 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
Ghennadi Procopciuc907f6542024-06-12 12:00:15 +0300340static 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
Ghennadi Procopciuce6946b62024-06-12 12:29:54 +0300348static 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
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300356static 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
364static 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
Ghennadi Procopciucd01fe9c2024-09-11 15:09:43 +0300372static 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
380static inline struct s32cc_part_block *
381s32cc_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
389static inline struct s32cc_part_block_link *
390s32cc_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
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300398#endif /* S32CC_CLK_MODULES_H */