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