blob: 703713bb99573e696517f0c19999d4eef7fb9190 [file] [log] [blame]
Ghennadi Procopciuc7c362092024-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 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 Procopciuc7c362092024-06-12 07:38:52 +030025};
26
27enum s32cc_clk_source {
28 S32CC_FIRC,
29 S32CC_FXOSC,
30 S32CC_SIRC,
Ghennadi Procopciuca8be7482024-06-12 09:53:18 +030031 S32CC_ARM_PLL,
Ghennadi Procopciuc44ae54a2024-08-05 16:42:04 +030032 S32CC_ARM_DFS,
Ghennadi Procopciuc9dbca852024-08-05 16:50:52 +030033 S32CC_CGM0,
Ghennadi Procopciuc3fa91a92024-06-12 10:53:06 +030034 S32CC_CGM1,
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +030035};
36
37struct s32cc_clk_obj {
38 enum s32cc_clkm_type type;
39 uint32_t refcount;
40};
41
42struct s32cc_osc {
43 struct s32cc_clk_obj desc;
44 enum s32cc_clk_source source;
45 unsigned long freq;
46 void *base;
47};
48
49#define S32CC_OSC_INIT(SOURCE) \
50{ \
51 .desc = { \
52 .type = s32cc_osc_t, \
53 }, \
54 .source = (SOURCE), \
55}
56
Ghennadi Procopciuca8be7482024-06-12 09:53:18 +030057struct s32cc_clkmux {
58 struct s32cc_clk_obj desc;
59 enum s32cc_clk_source module;
60 uint8_t index; /* Mux index in parent module */
61 unsigned long source_id; /* Selected source */
62 uint8_t nclks; /* Number of input clocks */
63 unsigned long clkids[5]; /* IDs of the input clocks */
64};
65
66#define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
67{ \
68 .desc = { \
69 .type = (TYPE), \
70 }, \
71 .module = (MODULE), \
72 .index = (INDEX), \
73 .nclks = (NCLKS), \
74 .clkids = {__VA_ARGS__}, \
75}
76
77#define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
78 S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \
79 INDEX, NCLKS, __VA_ARGS__)
80
Ghennadi Procopciuc3fa91a92024-06-12 10:53:06 +030081#define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
82 S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
83 INDEX, NCLKS, __VA_ARGS__)
84
Ghennadi Procopciuca8be7482024-06-12 09:53:18 +030085struct s32cc_pll {
86 struct s32cc_clk_obj desc;
87 struct s32cc_clk_obj *source;
88 enum s32cc_clk_source instance;
89 unsigned long vco_freq;
90 uint32_t ndividers;
91 uintptr_t base;
92};
93
94#define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
95{ \
96 .desc = { \
97 .type = s32cc_pll_t, \
98 }, \
99 .source = &(PLL_MUX_CLK).desc, \
100 .instance = (INSTANCE), \
101 .ndividers = (NDIVIDERS), \
102}
103
104struct s32cc_pll_out_div {
105 struct s32cc_clk_obj desc;
106 struct s32cc_clk_obj *parent;
107 uint32_t index;
108 unsigned long freq;
109};
110
111#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \
112{ \
113 .desc = { \
114 .type = s32cc_pll_out_div_t, \
115 }, \
116 .parent = &(PARENT).desc, \
117 .index = (INDEX), \
118}
119
Ghennadi Procopciuc44e21302024-06-12 12:06:36 +0300120#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \
121{ \
122 .desc = { \
123 .type = s32cc_pll_out_div_t, \
124 }, \
125 .parent = &(PARENT).desc, \
126 .index = (INDEX), \
127}
128
Ghennadi Procopciuc44ae54a2024-08-05 16:42:04 +0300129struct s32cc_dfs {
130 struct s32cc_clk_obj desc;
131 struct s32cc_clk_obj *parent;
132 enum s32cc_clk_source instance;
133 uintptr_t base;
134};
135
136#define S32CC_DFS_INIT(PARENT, INSTANCE) \
137{ \
138 .desc = { \
139 .type = s32cc_dfs_t, \
140 }, \
141 .parent = &(PARENT).desc, \
142 .instance = (INSTANCE), \
143}
144
145struct s32cc_dfs_div {
146 struct s32cc_clk_obj desc;
147 struct s32cc_clk_obj *parent;
148 uint32_t index;
149 unsigned long freq;
150};
151
152#define S32CC_DFS_DIV_INIT(PARENT, INDEX) \
153{ \
154 .desc = { \
155 .type = s32cc_dfs_div_t, \
156 }, \
157 .parent = &(PARENT).desc, \
158 .index = (INDEX), \
159}
160
Ghennadi Procopciuc44e21302024-06-12 12:06:36 +0300161struct s32cc_fixed_div {
162 struct s32cc_clk_obj desc;
163 struct s32cc_clk_obj *parent;
164 uint32_t rate_div;
165};
166
167#define S32CC_FIXED_DIV_INIT(PARENT, RATE_DIV) \
168{ \
169 .desc = { \
170 .type = s32cc_fixed_div_t, \
171 }, \
172 .parent = &(PARENT).desc, \
173 .rate_div = (RATE_DIV), \
174}
175
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +0300176struct s32cc_clk {
177 struct s32cc_clk_obj desc;
178 struct s32cc_clk_obj *module;
179 struct s32cc_clk *pclock;
180 unsigned long min_freq;
181 unsigned long max_freq;
182};
183
184struct s32cc_clk_array {
185 unsigned long type_mask;
186 struct s32cc_clk **clks;
187 size_t n_clks;
188};
189
Ghennadi Procopciuc44ae54a2024-08-05 16:42:04 +0300190#define S32CC_FREQ_CLK(PARENT_MODULE, PARENT, MIN_F, MAX_F) \
191{ \
192 .desc = { \
193 .type = s32cc_clk_t, \
194 }, \
195 .pclock = (PARENT), \
196 .module = (PARENT_MODULE), \
197 .min_freq = (MIN_F), \
198 .max_freq = (MAX_F), \
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +0300199}
200
201#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
Ghennadi Procopciuc44ae54a2024-08-05 16:42:04 +0300202 S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +0300203
204#define S32CC_MODULE_CLK(PARENT_MODULE) \
205 S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
206
Ghennadi Procopciuc44ae54a2024-08-05 16:42:04 +0300207#define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
208 S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
209
Ghennadi Procopciucd9373512024-06-12 08:09:19 +0300210static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
211{
212 uintptr_t osc_addr;
213
214 osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
215 return (struct s32cc_osc *)osc_addr;
216}
217
218static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
219{
220 uintptr_t clk_addr;
221
222 clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
223 return (struct s32cc_clk *)clk_addr;
224}
225
Ghennadi Procopciuc12e7a2c2024-06-12 10:02:07 +0300226static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
227{
228 const struct s32cc_clk_obj *module;
229
230 module = clk->module;
231 if (module == NULL) {
232 return false;
233 }
234
Ghennadi Procopciuc3fa91a92024-06-12 10:53:06 +0300235 return (module->type == s32cc_clkmux_t) ||
236 (module->type == s32cc_shared_clkmux_t);
Ghennadi Procopciuc12e7a2c2024-06-12 10:02:07 +0300237}
238
239static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
240{
241 uintptr_t cmux_addr;
242
243 cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
244 return (struct s32cc_clkmux *)cmux_addr;
245}
246
247static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
248{
249 if (!is_s32cc_clk_mux(clk)) {
250 return NULL;
251 }
252
253 return s32cc_obj2clkmux(clk->module);
254}
255
Ghennadi Procopciuc7ad4e232024-06-12 11:55:32 +0300256static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod)
257{
258 uintptr_t pll_addr;
259
260 pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc);
261 return (struct s32cc_pll *)pll_addr;
262}
263
Ghennadi Procopciucde950ef2024-06-12 12:00:15 +0300264static inline struct s32cc_pll_out_div *s32cc_obj2plldiv(const struct s32cc_clk_obj *mod)
265{
266 uintptr_t plldiv_addr;
267
268 plldiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll_out_div, desc);
269 return (struct s32cc_pll_out_div *)plldiv_addr;
270}
271
Ghennadi Procopciuc65739db2024-06-12 12:29:54 +0300272static inline struct s32cc_fixed_div *s32cc_obj2fixeddiv(const struct s32cc_clk_obj *mod)
273{
274 uintptr_t fdiv_addr;
275
276 fdiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_fixed_div, desc);
277 return (struct s32cc_fixed_div *)fdiv_addr;
278}
279
Ghennadi Procopciuc44ae54a2024-08-05 16:42:04 +0300280static inline struct s32cc_dfs *s32cc_obj2dfs(const struct s32cc_clk_obj *mod)
281{
282 uintptr_t dfs_addr;
283
284 dfs_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs, desc);
285 return (struct s32cc_dfs *)dfs_addr;
286}
287
288static inline struct s32cc_dfs_div *s32cc_obj2dfsdiv(const struct s32cc_clk_obj *mod)
289{
290 uintptr_t dfs_div_addr;
291
292 dfs_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs_div, desc);
293 return (struct s32cc_dfs_div *)dfs_div_addr;
294}
295
Ghennadi Procopciuc7c362092024-06-12 07:38:52 +0300296#endif /* S32CC_CLK_MODULES_H */