blob: 75d82043689e1289b9e6694aa1e70ad398d91cd9 [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 Procopciuc8384d182024-06-12 10:53:06 +030033 S32CC_CGM1,
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +030034};
35
36struct s32cc_clk_obj {
37 enum s32cc_clkm_type type;
38 uint32_t refcount;
39};
40
41struct s32cc_osc {
42 struct s32cc_clk_obj desc;
43 enum s32cc_clk_source source;
44 unsigned long freq;
45 void *base;
46};
47
48#define S32CC_OSC_INIT(SOURCE) \
49{ \
50 .desc = { \
51 .type = s32cc_osc_t, \
52 }, \
53 .source = (SOURCE), \
54}
55
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030056struct s32cc_clkmux {
57 struct s32cc_clk_obj desc;
58 enum s32cc_clk_source module;
59 uint8_t index; /* Mux index in parent module */
60 unsigned long source_id; /* Selected source */
61 uint8_t nclks; /* Number of input clocks */
62 unsigned long clkids[5]; /* IDs of the input clocks */
63};
64
65#define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
66{ \
67 .desc = { \
68 .type = (TYPE), \
69 }, \
70 .module = (MODULE), \
71 .index = (INDEX), \
72 .nclks = (NCLKS), \
73 .clkids = {__VA_ARGS__}, \
74}
75
76#define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
77 S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \
78 INDEX, NCLKS, __VA_ARGS__)
79
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030080#define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
81 S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
82 INDEX, NCLKS, __VA_ARGS__)
83
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030084struct s32cc_pll {
85 struct s32cc_clk_obj desc;
86 struct s32cc_clk_obj *source;
87 enum s32cc_clk_source instance;
88 unsigned long vco_freq;
89 uint32_t ndividers;
90 uintptr_t base;
91};
92
93#define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
94{ \
95 .desc = { \
96 .type = s32cc_pll_t, \
97 }, \
98 .source = &(PLL_MUX_CLK).desc, \
99 .instance = (INSTANCE), \
100 .ndividers = (NDIVIDERS), \
101}
102
103struct s32cc_pll_out_div {
104 struct s32cc_clk_obj desc;
105 struct s32cc_clk_obj *parent;
106 uint32_t index;
107 unsigned long freq;
108};
109
110#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \
111{ \
112 .desc = { \
113 .type = s32cc_pll_out_div_t, \
114 }, \
115 .parent = &(PARENT).desc, \
116 .index = (INDEX), \
117}
118
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +0300119#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \
120{ \
121 .desc = { \
122 .type = s32cc_pll_out_div_t, \
123 }, \
124 .parent = &(PARENT).desc, \
125 .index = (INDEX), \
126}
127
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300128struct s32cc_dfs {
129 struct s32cc_clk_obj desc;
130 struct s32cc_clk_obj *parent;
131 enum s32cc_clk_source instance;
132 uintptr_t base;
133};
134
135#define S32CC_DFS_INIT(PARENT, INSTANCE) \
136{ \
137 .desc = { \
138 .type = s32cc_dfs_t, \
139 }, \
140 .parent = &(PARENT).desc, \
141 .instance = (INSTANCE), \
142}
143
144struct s32cc_dfs_div {
145 struct s32cc_clk_obj desc;
146 struct s32cc_clk_obj *parent;
147 uint32_t index;
148 unsigned long freq;
149};
150
151#define S32CC_DFS_DIV_INIT(PARENT, INDEX) \
152{ \
153 .desc = { \
154 .type = s32cc_dfs_div_t, \
155 }, \
156 .parent = &(PARENT).desc, \
157 .index = (INDEX), \
158}
159
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +0300160struct s32cc_fixed_div {
161 struct s32cc_clk_obj desc;
162 struct s32cc_clk_obj *parent;
163 uint32_t rate_div;
164};
165
166#define S32CC_FIXED_DIV_INIT(PARENT, RATE_DIV) \
167{ \
168 .desc = { \
169 .type = s32cc_fixed_div_t, \
170 }, \
171 .parent = &(PARENT).desc, \
172 .rate_div = (RATE_DIV), \
173}
174
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300175struct s32cc_clk {
176 struct s32cc_clk_obj desc;
177 struct s32cc_clk_obj *module;
178 struct s32cc_clk *pclock;
179 unsigned long min_freq;
180 unsigned long max_freq;
181};
182
183struct s32cc_clk_array {
184 unsigned long type_mask;
185 struct s32cc_clk **clks;
186 size_t n_clks;
187};
188
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300189#define S32CC_FREQ_CLK(PARENT_MODULE, PARENT, MIN_F, MAX_F) \
190{ \
191 .desc = { \
192 .type = s32cc_clk_t, \
193 }, \
194 .pclock = (PARENT), \
195 .module = (PARENT_MODULE), \
196 .min_freq = (MIN_F), \
197 .max_freq = (MAX_F), \
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300198}
199
200#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300201 S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300202
203#define S32CC_MODULE_CLK(PARENT_MODULE) \
204 S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
205
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300206#define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
207 S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
208
Ghennadi Procopciuc0d525772024-06-12 08:09:19 +0300209static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
210{
211 uintptr_t osc_addr;
212
213 osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
214 return (struct s32cc_osc *)osc_addr;
215}
216
217static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
218{
219 uintptr_t clk_addr;
220
221 clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
222 return (struct s32cc_clk *)clk_addr;
223}
224
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300225static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
226{
227 const struct s32cc_clk_obj *module;
228
229 module = clk->module;
230 if (module == NULL) {
231 return false;
232 }
233
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +0300234 return (module->type == s32cc_clkmux_t) ||
235 (module->type == s32cc_shared_clkmux_t);
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300236}
237
238static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
239{
240 uintptr_t cmux_addr;
241
242 cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
243 return (struct s32cc_clkmux *)cmux_addr;
244}
245
246static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
247{
248 if (!is_s32cc_clk_mux(clk)) {
249 return NULL;
250 }
251
252 return s32cc_obj2clkmux(clk->module);
253}
254
Ghennadi Procopciuce18cf332024-06-12 11:55:32 +0300255static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod)
256{
257 uintptr_t pll_addr;
258
259 pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc);
260 return (struct s32cc_pll *)pll_addr;
261}
262
Ghennadi Procopciuc907f6542024-06-12 12:00:15 +0300263static inline struct s32cc_pll_out_div *s32cc_obj2plldiv(const struct s32cc_clk_obj *mod)
264{
265 uintptr_t plldiv_addr;
266
267 plldiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll_out_div, desc);
268 return (struct s32cc_pll_out_div *)plldiv_addr;
269}
270
Ghennadi Procopciuce6946b62024-06-12 12:29:54 +0300271static inline struct s32cc_fixed_div *s32cc_obj2fixeddiv(const struct s32cc_clk_obj *mod)
272{
273 uintptr_t fdiv_addr;
274
275 fdiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_fixed_div, desc);
276 return (struct s32cc_fixed_div *)fdiv_addr;
277}
278
Ghennadi Procopciucda5d2702024-08-05 16:42:04 +0300279static inline struct s32cc_dfs *s32cc_obj2dfs(const struct s32cc_clk_obj *mod)
280{
281 uintptr_t dfs_addr;
282
283 dfs_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs, desc);
284 return (struct s32cc_dfs *)dfs_addr;
285}
286
287static inline struct s32cc_dfs_div *s32cc_obj2dfsdiv(const struct s32cc_clk_obj *mod)
288{
289 uintptr_t dfs_div_addr;
290
291 dfs_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs_div, desc);
292 return (struct s32cc_dfs_div *)dfs_div_addr;
293}
294
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300295#endif /* S32CC_CLK_MODULES_H */