blob: 26d2782f346ff2678c8ca6d68db67db9b527033d [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 Procopciucecc98d22024-06-12 07:38:52 +030040};
41
42struct s32cc_clk_obj {
43 enum s32cc_clkm_type type;
44 uint32_t refcount;
45};
46
47struct 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
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030062struct 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
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030086#define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
87 S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
88 INDEX, NCLKS, __VA_ARGS__)
89
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030090struct 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
109struct 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
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +0300125#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
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300134struct 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
150struct 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
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +0300166struct 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
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300181struct 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
189struct s32cc_clk_array {
190 unsigned long type_mask;
191 struct s32cc_clk **clks;
192 size_t n_clks;
193};
194
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300195#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), \
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300204}
205
206#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300207 S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300208
209#define S32CC_MODULE_CLK(PARENT_MODULE) \
210 S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
211
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300212#define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
213 S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
214
Ghennadi Procopciucd01fe9c2024-09-11 15:09:43 +0300215struct 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
228enum 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
247struct 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
270struct 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
Ghennadi Procopciuc0d525772024-06-12 08:09:19 +0300285static 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
293static 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
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300301static 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
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +0300310 return (module->type == s32cc_clkmux_t) ||
311 (module->type == s32cc_shared_clkmux_t);
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300312}
313
314static 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
322static 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
Ghennadi Procopciuce18cf332024-06-12 11:55:32 +0300331static 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
Ghennadi Procopciuc907f6542024-06-12 12:00:15 +0300339static 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
Ghennadi Procopciuce6946b62024-06-12 12:29:54 +0300347static 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
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300355static 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
363static 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
Ghennadi Procopciucd01fe9c2024-09-11 15:09:43 +0300371static 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
379static inline struct s32cc_part_block *
380s32cc_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
388static inline struct s32cc_part_block_link *
389s32cc_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
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300397#endif /* S32CC_CLK_MODULES_H */