blob: 50e7a0c0c11cde61967e4bd3f793ca3c61b082a6 [file] [log] [blame]
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +03001/* SPDX-License-Identifier: BSD-3-Clause */
2/*
Ghennadi Procopciucbd691132025-01-10 16:26:21 +02003 * Copyright 2020-2025 NXP
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +03004 */
5#ifndef S32CC_CLK_MODULES_H
6#define S32CC_CLK_MODULES_H
7
8#include <inttypes.h>
Ghennadi Procopciuc12e7a2c2024-06-12 10:02:07 +03009#include <stdbool.h>
Ghennadi Procopciuc7c362092024-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 Procopciuca8be7482024-06-12 09:53:18 +030018 s32cc_pll_t,
19 s32cc_pll_out_div_t,
Ghennadi Procopciuc44ae54a2024-08-05 16:42:04 +030020 s32cc_dfs_t,
21 s32cc_dfs_div_t,
Ghennadi Procopciuca8be7482024-06-12 09:53:18 +030022 s32cc_clkmux_t,
Ghennadi Procopciuc3fa91a92024-06-12 10:53:06 +030023 s32cc_shared_clkmux_t,
Ghennadi Procopciuc44e21302024-06-12 12:06:36 +030024 s32cc_fixed_div_t,
Ghennadi Procopciucaf3020e2024-09-11 15:09:43 +030025 s32cc_part_t,
26 s32cc_part_block_t,
27 s32cc_part_block_link_t,
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +030028};
29
30enum s32cc_clk_source {
31 S32CC_FIRC,
32 S32CC_FXOSC,
33 S32CC_SIRC,
Ghennadi Procopciuca8be7482024-06-12 09:53:18 +030034 S32CC_ARM_PLL,
Ghennadi Procopciuc44ae54a2024-08-05 16:42:04 +030035 S32CC_ARM_DFS,
Ghennadi Procopciuc86533522024-08-06 11:48:11 +030036 S32CC_PERIPH_PLL,
Ghennadi Procopciuc9dbca852024-08-05 16:50:52 +030037 S32CC_CGM0,
Ghennadi Procopciuc3fa91a92024-06-12 10:53:06 +030038 S32CC_CGM1,
Ghennadi Procopciuc18c2b132024-09-09 10:24:35 +030039 S32CC_DDR_PLL,
Ghennadi Procopciuc29f8a952025-01-20 16:02:21 +020040 S32CC_PERIPH_DFS,
Ghennadi Procopciuc4a2ca712024-09-17 09:02:24 +030041 S32CC_CGM5,
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +030042};
43
44struct s32cc_clk_obj {
45 enum s32cc_clkm_type type;
46 uint32_t refcount;
47};
48
49struct s32cc_osc {
50 struct s32cc_clk_obj desc;
51 enum s32cc_clk_source source;
52 unsigned long freq;
53 void *base;
54};
55
Ghennadi Procopciucbd691132025-01-10 16:26:21 +020056#define S32CC_OSC_INIT_FREQ(SOURCE, FREQ) \
57{ \
58 .desc = { \
59 .type = s32cc_osc_t, \
60 }, \
61 .source = (SOURCE), \
62 .freq = (FREQ), \
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +030063}
64
Ghennadi Procopciucbd691132025-01-10 16:26:21 +020065#define S32CC_OSC_INIT(SOURCE) \
66 S32CC_OSC_INIT_FREQ(SOURCE, 0)
67
Ghennadi Procopciuca8be7482024-06-12 09:53:18 +030068struct s32cc_clkmux {
69 struct s32cc_clk_obj desc;
70 enum s32cc_clk_source module;
71 uint8_t index; /* Mux index in parent module */
72 unsigned long source_id; /* Selected source */
73 uint8_t nclks; /* Number of input clocks */
74 unsigned long clkids[5]; /* IDs of the input clocks */
75};
76
77#define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
78{ \
79 .desc = { \
80 .type = (TYPE), \
81 }, \
82 .module = (MODULE), \
83 .index = (INDEX), \
84 .nclks = (NCLKS), \
85 .clkids = {__VA_ARGS__}, \
86}
87
88#define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
89 S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \
90 INDEX, NCLKS, __VA_ARGS__)
91
Ghennadi Procopciuc3fa91a92024-06-12 10:53:06 +030092#define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
93 S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
94 INDEX, NCLKS, __VA_ARGS__)
95
Ghennadi Procopciuca8be7482024-06-12 09:53:18 +030096struct s32cc_pll {
97 struct s32cc_clk_obj desc;
98 struct s32cc_clk_obj *source;
99 enum s32cc_clk_source instance;
100 unsigned long vco_freq;
101 uint32_t ndividers;
102 uintptr_t base;
103};
104
105#define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
106{ \
107 .desc = { \
108 .type = s32cc_pll_t, \
109 }, \
110 .source = &(PLL_MUX_CLK).desc, \
111 .instance = (INSTANCE), \
112 .ndividers = (NDIVIDERS), \
113}
114
115struct s32cc_pll_out_div {
116 struct s32cc_clk_obj desc;
117 struct s32cc_clk_obj *parent;
118 uint32_t index;
119 unsigned long freq;
120};
121
122#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \
123{ \
124 .desc = { \
125 .type = s32cc_pll_out_div_t, \
126 }, \
127 .parent = &(PARENT).desc, \
128 .index = (INDEX), \
129}
130
Ghennadi Procopciuc44e21302024-06-12 12:06:36 +0300131#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \
132{ \
133 .desc = { \
134 .type = s32cc_pll_out_div_t, \
135 }, \
136 .parent = &(PARENT).desc, \
137 .index = (INDEX), \
138}
139
Ghennadi Procopciuc44ae54a2024-08-05 16:42:04 +0300140struct s32cc_dfs {
141 struct s32cc_clk_obj desc;
142 struct s32cc_clk_obj *parent;
143 enum s32cc_clk_source instance;
144 uintptr_t base;
145};
146
147#define S32CC_DFS_INIT(PARENT, INSTANCE) \
148{ \
149 .desc = { \
150 .type = s32cc_dfs_t, \
151 }, \
152 .parent = &(PARENT).desc, \
153 .instance = (INSTANCE), \
154}
155
156struct s32cc_dfs_div {
157 struct s32cc_clk_obj desc;
158 struct s32cc_clk_obj *parent;
159 uint32_t index;
160 unsigned long freq;
161};
162
163#define S32CC_DFS_DIV_INIT(PARENT, INDEX) \
164{ \
165 .desc = { \
166 .type = s32cc_dfs_div_t, \
167 }, \
168 .parent = &(PARENT).desc, \
169 .index = (INDEX), \
170}
171
Ghennadi Procopciuc44e21302024-06-12 12:06:36 +0300172struct s32cc_fixed_div {
173 struct s32cc_clk_obj desc;
174 struct s32cc_clk_obj *parent;
175 uint32_t rate_div;
176};
177
178#define S32CC_FIXED_DIV_INIT(PARENT, RATE_DIV) \
179{ \
180 .desc = { \
181 .type = s32cc_fixed_div_t, \
182 }, \
183 .parent = &(PARENT).desc, \
184 .rate_div = (RATE_DIV), \
185}
186
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +0300187struct s32cc_clk {
188 struct s32cc_clk_obj desc;
189 struct s32cc_clk_obj *module;
190 struct s32cc_clk *pclock;
191 unsigned long min_freq;
192 unsigned long max_freq;
193};
194
195struct s32cc_clk_array {
196 unsigned long type_mask;
197 struct s32cc_clk **clks;
198 size_t n_clks;
199};
200
Ghennadi Procopciuc44ae54a2024-08-05 16:42:04 +0300201#define S32CC_FREQ_CLK(PARENT_MODULE, PARENT, MIN_F, MAX_F) \
202{ \
203 .desc = { \
204 .type = s32cc_clk_t, \
205 }, \
206 .pclock = (PARENT), \
207 .module = (PARENT_MODULE), \
208 .min_freq = (MIN_F), \
209 .max_freq = (MAX_F), \
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +0300210}
211
212#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
Ghennadi Procopciuc44ae54a2024-08-05 16:42:04 +0300213 S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +0300214
215#define S32CC_MODULE_CLK(PARENT_MODULE) \
216 S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
217
Ghennadi Procopciuc44ae54a2024-08-05 16:42:04 +0300218#define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
219 S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
220
Ghennadi Procopciucaf3020e2024-09-11 15:09:43 +0300221struct s32cc_part {
222 struct s32cc_clk_obj desc;
223 uint32_t partition_id;
224};
225
226#define S32CC_PART(PART_NUM) \
227{ \
228 .desc = { \
229 .type = s32cc_part_t, \
230 }, \
231 .partition_id = (PART_NUM), \
232}
233
234enum s32cc_part_block_type {
235 s32cc_part_block0,
236 s32cc_part_block1,
237 s32cc_part_block2,
238 s32cc_part_block3,
239 s32cc_part_block4,
240 s32cc_part_block5,
241 s32cc_part_block6,
242 s32cc_part_block7,
243 s32cc_part_block8,
244 s32cc_part_block9,
245 s32cc_part_block10,
246 s32cc_part_block11,
247 s32cc_part_block12,
248 s32cc_part_block13,
249 s32cc_part_block14,
250 s32cc_part_block15,
251};
252
253struct s32cc_part_block {
254 struct s32cc_clk_obj desc;
255 struct s32cc_part *part;
256 enum s32cc_part_block_type block;
257 bool status;
258};
259
260#define S32CC_PART_BLOCK_STATUS(PART_META, BLOCK_TYPE, STATUS) \
261{ \
262 .desc = { \
263 .type = s32cc_part_block_t, \
264 }, \
265 .part = (PART_META), \
266 .block = (BLOCK_TYPE), \
267 .status = (STATUS), \
268}
269
270#define S32CC_PART_BLOCK(PARENT, BLOCK_TYPE) \
271 S32CC_PART_BLOCK_STATUS(PARENT, BLOCK_TYPE, true)
272
273#define S32CC_PART_BLOCK_NO_STATUS(PARENT, BLOCK_TYPE) \
274 S32CC_PART_BLOCK_STATUS(PARENT, BLOCK_TYPE, false)
275
276struct s32cc_part_block_link {
277 struct s32cc_clk_obj desc;
278 struct s32cc_clk_obj *parent;
279 struct s32cc_part_block *block;
280};
281
282#define S32CC_PART_BLOCK_LINK(PARENT, BLOCK) \
283{ \
284 .desc = { \
285 .type = s32cc_part_block_link_t, \
286 }, \
287 .parent = &(PARENT).desc, \
288 .block = (BLOCK), \
289}
290
Ghennadi Procopciucd9373512024-06-12 08:09:19 +0300291static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
292{
293 uintptr_t osc_addr;
294
295 osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
296 return (struct s32cc_osc *)osc_addr;
297}
298
299static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
300{
301 uintptr_t clk_addr;
302
303 clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
304 return (struct s32cc_clk *)clk_addr;
305}
306
Ghennadi Procopciuc12e7a2c2024-06-12 10:02:07 +0300307static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
308{
309 const struct s32cc_clk_obj *module;
310
311 module = clk->module;
312 if (module == NULL) {
313 return false;
314 }
315
Ghennadi Procopciuc3fa91a92024-06-12 10:53:06 +0300316 return (module->type == s32cc_clkmux_t) ||
317 (module->type == s32cc_shared_clkmux_t);
Ghennadi Procopciuc12e7a2c2024-06-12 10:02:07 +0300318}
319
320static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
321{
322 uintptr_t cmux_addr;
323
324 cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
325 return (struct s32cc_clkmux *)cmux_addr;
326}
327
328static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
329{
330 if (!is_s32cc_clk_mux(clk)) {
331 return NULL;
332 }
333
334 return s32cc_obj2clkmux(clk->module);
335}
336
Ghennadi Procopciuc7ad4e232024-06-12 11:55:32 +0300337static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod)
338{
339 uintptr_t pll_addr;
340
341 pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc);
342 return (struct s32cc_pll *)pll_addr;
343}
344
Ghennadi Procopciucde950ef2024-06-12 12:00:15 +0300345static inline struct s32cc_pll_out_div *s32cc_obj2plldiv(const struct s32cc_clk_obj *mod)
346{
347 uintptr_t plldiv_addr;
348
349 plldiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll_out_div, desc);
350 return (struct s32cc_pll_out_div *)plldiv_addr;
351}
352
Ghennadi Procopciuc65739db2024-06-12 12:29:54 +0300353static inline struct s32cc_fixed_div *s32cc_obj2fixeddiv(const struct s32cc_clk_obj *mod)
354{
355 uintptr_t fdiv_addr;
356
357 fdiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_fixed_div, desc);
358 return (struct s32cc_fixed_div *)fdiv_addr;
359}
360
Ghennadi Procopciuc44ae54a2024-08-05 16:42:04 +0300361static inline struct s32cc_dfs *s32cc_obj2dfs(const struct s32cc_clk_obj *mod)
362{
363 uintptr_t dfs_addr;
364
365 dfs_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs, desc);
366 return (struct s32cc_dfs *)dfs_addr;
367}
368
369static inline struct s32cc_dfs_div *s32cc_obj2dfsdiv(const struct s32cc_clk_obj *mod)
370{
371 uintptr_t dfs_div_addr;
372
373 dfs_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs_div, desc);
374 return (struct s32cc_dfs_div *)dfs_div_addr;
375}
376
Ghennadi Procopciucaf3020e2024-09-11 15:09:43 +0300377static inline struct s32cc_part *s32cc_obj2part(const struct s32cc_clk_obj *mod)
378{
379 uintptr_t part_addr;
380
381 part_addr = ((uintptr_t)mod) - offsetof(struct s32cc_part, desc);
382 return (struct s32cc_part *)part_addr;
383}
384
385static inline struct s32cc_part_block *
386s32cc_obj2partblock(const struct s32cc_clk_obj *mod)
387{
388 uintptr_t part_blk_addr;
389
390 part_blk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_part_block, desc);
391 return (struct s32cc_part_block *)part_blk_addr;
392}
393
394static inline struct s32cc_part_block_link *
395s32cc_obj2partblocklink(const struct s32cc_clk_obj *mod)
396{
397 uintptr_t blk_link;
398
399 blk_link = ((uintptr_t)mod) - offsetof(struct s32cc_part_block_link, desc);
400 return (struct s32cc_part_block_link *)blk_link;
401}
402
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +0300403#endif /* S32CC_CLK_MODULES_H */