blob: a6d58cc0a731f7d0ac6551574a2610fb285ebef3 [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 Procopciucecc98d22024-06-12 07:38:52 +030025};
26
27enum s32cc_clk_source {
28 S32CC_FIRC,
29 S32CC_FXOSC,
30 S32CC_SIRC,
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030031 S32CC_ARM_PLL,
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +030032 S32CC_ARM_DFS,
Ghennadi Procopciuc22f94742024-08-06 11:48:11 +030033 S32CC_PERIPH_PLL,
Ghennadi Procopciuc90c90002024-08-05 16:50:52 +030034 S32CC_CGM0,
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030035 S32CC_CGM1,
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +030036};
37
38struct s32cc_clk_obj {
39 enum s32cc_clkm_type type;
40 uint32_t refcount;
41};
42
43struct s32cc_osc {
44 struct s32cc_clk_obj desc;
45 enum s32cc_clk_source source;
46 unsigned long freq;
47 void *base;
48};
49
50#define S32CC_OSC_INIT(SOURCE) \
51{ \
52 .desc = { \
53 .type = s32cc_osc_t, \
54 }, \
55 .source = (SOURCE), \
56}
57
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030058struct s32cc_clkmux {
59 struct s32cc_clk_obj desc;
60 enum s32cc_clk_source module;
61 uint8_t index; /* Mux index in parent module */
62 unsigned long source_id; /* Selected source */
63 uint8_t nclks; /* Number of input clocks */
64 unsigned long clkids[5]; /* IDs of the input clocks */
65};
66
67#define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
68{ \
69 .desc = { \
70 .type = (TYPE), \
71 }, \
72 .module = (MODULE), \
73 .index = (INDEX), \
74 .nclks = (NCLKS), \
75 .clkids = {__VA_ARGS__}, \
76}
77
78#define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
79 S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \
80 INDEX, NCLKS, __VA_ARGS__)
81
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030082#define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
83 S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
84 INDEX, NCLKS, __VA_ARGS__)
85
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030086struct s32cc_pll {
87 struct s32cc_clk_obj desc;
88 struct s32cc_clk_obj *source;
89 enum s32cc_clk_source instance;
90 unsigned long vco_freq;
91 uint32_t ndividers;
92 uintptr_t base;
93};
94
95#define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
96{ \
97 .desc = { \
98 .type = s32cc_pll_t, \
99 }, \
100 .source = &(PLL_MUX_CLK).desc, \
101 .instance = (INSTANCE), \
102 .ndividers = (NDIVIDERS), \
103}
104
105struct s32cc_pll_out_div {
106 struct s32cc_clk_obj desc;
107 struct s32cc_clk_obj *parent;
108 uint32_t index;
109 unsigned long freq;
110};
111
112#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \
113{ \
114 .desc = { \
115 .type = s32cc_pll_out_div_t, \
116 }, \
117 .parent = &(PARENT).desc, \
118 .index = (INDEX), \
119}
120
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +0300121#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 Procopciucda5d2702024-08-05 16:42:04 +0300130struct s32cc_dfs {
131 struct s32cc_clk_obj desc;
132 struct s32cc_clk_obj *parent;
133 enum s32cc_clk_source instance;
134 uintptr_t base;
135};
136
137#define S32CC_DFS_INIT(PARENT, INSTANCE) \
138{ \
139 .desc = { \
140 .type = s32cc_dfs_t, \
141 }, \
142 .parent = &(PARENT).desc, \
143 .instance = (INSTANCE), \
144}
145
146struct s32cc_dfs_div {
147 struct s32cc_clk_obj desc;
148 struct s32cc_clk_obj *parent;
149 uint32_t index;
150 unsigned long freq;
151};
152
153#define S32CC_DFS_DIV_INIT(PARENT, INDEX) \
154{ \
155 .desc = { \
156 .type = s32cc_dfs_div_t, \
157 }, \
158 .parent = &(PARENT).desc, \
159 .index = (INDEX), \
160}
161
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +0300162struct s32cc_fixed_div {
163 struct s32cc_clk_obj desc;
164 struct s32cc_clk_obj *parent;
165 uint32_t rate_div;
166};
167
168#define S32CC_FIXED_DIV_INIT(PARENT, RATE_DIV) \
169{ \
170 .desc = { \
171 .type = s32cc_fixed_div_t, \
172 }, \
173 .parent = &(PARENT).desc, \
174 .rate_div = (RATE_DIV), \
175}
176
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300177struct s32cc_clk {
178 struct s32cc_clk_obj desc;
179 struct s32cc_clk_obj *module;
180 struct s32cc_clk *pclock;
181 unsigned long min_freq;
182 unsigned long max_freq;
183};
184
185struct s32cc_clk_array {
186 unsigned long type_mask;
187 struct s32cc_clk **clks;
188 size_t n_clks;
189};
190
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300191#define S32CC_FREQ_CLK(PARENT_MODULE, PARENT, MIN_F, MAX_F) \
192{ \
193 .desc = { \
194 .type = s32cc_clk_t, \
195 }, \
196 .pclock = (PARENT), \
197 .module = (PARENT_MODULE), \
198 .min_freq = (MIN_F), \
199 .max_freq = (MAX_F), \
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300200}
201
202#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300203 S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300204
205#define S32CC_MODULE_CLK(PARENT_MODULE) \
206 S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
207
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300208#define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
209 S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
210
Ghennadi Procopciuc0d525772024-06-12 08:09:19 +0300211static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
212{
213 uintptr_t osc_addr;
214
215 osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
216 return (struct s32cc_osc *)osc_addr;
217}
218
219static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
220{
221 uintptr_t clk_addr;
222
223 clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
224 return (struct s32cc_clk *)clk_addr;
225}
226
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300227static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
228{
229 const struct s32cc_clk_obj *module;
230
231 module = clk->module;
232 if (module == NULL) {
233 return false;
234 }
235
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +0300236 return (module->type == s32cc_clkmux_t) ||
237 (module->type == s32cc_shared_clkmux_t);
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300238}
239
240static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
241{
242 uintptr_t cmux_addr;
243
244 cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
245 return (struct s32cc_clkmux *)cmux_addr;
246}
247
248static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
249{
250 if (!is_s32cc_clk_mux(clk)) {
251 return NULL;
252 }
253
254 return s32cc_obj2clkmux(clk->module);
255}
256
Ghennadi Procopciuce18cf332024-06-12 11:55:32 +0300257static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod)
258{
259 uintptr_t pll_addr;
260
261 pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc);
262 return (struct s32cc_pll *)pll_addr;
263}
264
Ghennadi Procopciuc907f6542024-06-12 12:00:15 +0300265static inline struct s32cc_pll_out_div *s32cc_obj2plldiv(const struct s32cc_clk_obj *mod)
266{
267 uintptr_t plldiv_addr;
268
269 plldiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll_out_div, desc);
270 return (struct s32cc_pll_out_div *)plldiv_addr;
271}
272
Ghennadi Procopciuce6946b62024-06-12 12:29:54 +0300273static inline struct s32cc_fixed_div *s32cc_obj2fixeddiv(const struct s32cc_clk_obj *mod)
274{
275 uintptr_t fdiv_addr;
276
277 fdiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_fixed_div, desc);
278 return (struct s32cc_fixed_div *)fdiv_addr;
279}
280
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300281static inline struct s32cc_dfs *s32cc_obj2dfs(const struct s32cc_clk_obj *mod)
282{
283 uintptr_t dfs_addr;
284
285 dfs_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs, desc);
286 return (struct s32cc_dfs *)dfs_addr;
287}
288
289static inline struct s32cc_dfs_div *s32cc_obj2dfsdiv(const struct s32cc_clk_obj *mod)
290{
291 uintptr_t dfs_div_addr;
292
293 dfs_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs_div, desc);
294 return (struct s32cc_dfs_div *)dfs_div_addr;
295}
296
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300297#endif /* S32CC_CLK_MODULES_H */