blob: acad3cd5a674ddac1517c6761247e656b8346156 [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 Procopciucecc98d22024-06-12 07:38:52 +030039};
40
41struct s32cc_clk_obj {
42 enum s32cc_clkm_type type;
43 uint32_t refcount;
44};
45
46struct 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
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030061struct 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
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030085#define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
86 S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
87 INDEX, NCLKS, __VA_ARGS__)
88
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030089struct 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
108struct 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
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +0300124#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
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300133struct 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
149struct 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
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +0300165struct 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
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300180struct 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
188struct s32cc_clk_array {
189 unsigned long type_mask;
190 struct s32cc_clk **clks;
191 size_t n_clks;
192};
193
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300194#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), \
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300203}
204
205#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300206 S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300207
208#define S32CC_MODULE_CLK(PARENT_MODULE) \
209 S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
210
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300211#define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
212 S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
213
Ghennadi Procopciucd01fe9c2024-09-11 15:09:43 +0300214struct 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
227enum 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
246struct 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
269struct 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
Ghennadi Procopciuc0d525772024-06-12 08:09:19 +0300284static 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
292static 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
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300300static 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
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +0300309 return (module->type == s32cc_clkmux_t) ||
310 (module->type == s32cc_shared_clkmux_t);
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300311}
312
313static 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
321static 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
Ghennadi Procopciuce18cf332024-06-12 11:55:32 +0300330static 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
Ghennadi Procopciuc907f6542024-06-12 12:00:15 +0300338static 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
Ghennadi Procopciuce6946b62024-06-12 12:29:54 +0300346static 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
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300354static 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
362static 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
Ghennadi Procopciucd01fe9c2024-09-11 15:09:43 +0300370static 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
378static inline struct s32cc_part_block *
379s32cc_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
387static inline struct s32cc_part_block_link *
388s32cc_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
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300396#endif /* S32CC_CLK_MODULES_H */