blob: 41fc6f409dc02fb744f1a4f16c005c28427044e1 [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,
20 s32cc_clkmux_t,
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030021 s32cc_shared_clkmux_t,
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +030022 s32cc_fixed_div_t,
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +030023};
24
25enum s32cc_clk_source {
26 S32CC_FIRC,
27 S32CC_FXOSC,
28 S32CC_SIRC,
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030029 S32CC_ARM_PLL,
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030030 S32CC_CGM1,
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +030031};
32
33struct s32cc_clk_obj {
34 enum s32cc_clkm_type type;
35 uint32_t refcount;
36};
37
38struct s32cc_osc {
39 struct s32cc_clk_obj desc;
40 enum s32cc_clk_source source;
41 unsigned long freq;
42 void *base;
43};
44
45#define S32CC_OSC_INIT(SOURCE) \
46{ \
47 .desc = { \
48 .type = s32cc_osc_t, \
49 }, \
50 .source = (SOURCE), \
51}
52
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030053struct s32cc_clkmux {
54 struct s32cc_clk_obj desc;
55 enum s32cc_clk_source module;
56 uint8_t index; /* Mux index in parent module */
57 unsigned long source_id; /* Selected source */
58 uint8_t nclks; /* Number of input clocks */
59 unsigned long clkids[5]; /* IDs of the input clocks */
60};
61
62#define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
63{ \
64 .desc = { \
65 .type = (TYPE), \
66 }, \
67 .module = (MODULE), \
68 .index = (INDEX), \
69 .nclks = (NCLKS), \
70 .clkids = {__VA_ARGS__}, \
71}
72
73#define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
74 S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE, \
75 INDEX, NCLKS, __VA_ARGS__)
76
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +030077#define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...) \
78 S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
79 INDEX, NCLKS, __VA_ARGS__)
80
Ghennadi Procopciuc7277b972024-06-12 09:53:18 +030081struct s32cc_pll {
82 struct s32cc_clk_obj desc;
83 struct s32cc_clk_obj *source;
84 enum s32cc_clk_source instance;
85 unsigned long vco_freq;
86 uint32_t ndividers;
87 uintptr_t base;
88};
89
90#define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
91{ \
92 .desc = { \
93 .type = s32cc_pll_t, \
94 }, \
95 .source = &(PLL_MUX_CLK).desc, \
96 .instance = (INSTANCE), \
97 .ndividers = (NDIVIDERS), \
98}
99
100struct s32cc_pll_out_div {
101 struct s32cc_clk_obj desc;
102 struct s32cc_clk_obj *parent;
103 uint32_t index;
104 unsigned long freq;
105};
106
107#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \
108{ \
109 .desc = { \
110 .type = s32cc_pll_out_div_t, \
111 }, \
112 .parent = &(PARENT).desc, \
113 .index = (INDEX), \
114}
115
Ghennadi Procopciuc2be71a32024-06-12 12:06:36 +0300116#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX) \
117{ \
118 .desc = { \
119 .type = s32cc_pll_out_div_t, \
120 }, \
121 .parent = &(PARENT).desc, \
122 .index = (INDEX), \
123}
124
125struct s32cc_fixed_div {
126 struct s32cc_clk_obj desc;
127 struct s32cc_clk_obj *parent;
128 uint32_t rate_div;
129};
130
131#define S32CC_FIXED_DIV_INIT(PARENT, RATE_DIV) \
132{ \
133 .desc = { \
134 .type = s32cc_fixed_div_t, \
135 }, \
136 .parent = &(PARENT).desc, \
137 .rate_div = (RATE_DIV), \
138}
139
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300140struct s32cc_clk {
141 struct s32cc_clk_obj desc;
142 struct s32cc_clk_obj *module;
143 struct s32cc_clk *pclock;
144 unsigned long min_freq;
145 unsigned long max_freq;
146};
147
148struct s32cc_clk_array {
149 unsigned long type_mask;
150 struct s32cc_clk **clks;
151 size_t n_clks;
152};
153
154#define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \
155{ \
156 .desc = { \
157 .type = s32cc_clk_t, \
158 }, \
159 .module = &(PARENT_MODULE).desc, \
160 .min_freq = (MIN_F), \
161 .max_freq = (MAX_F), \
162}
163
164#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
165 S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F)
166
167#define S32CC_MODULE_CLK(PARENT_MODULE) \
168 S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
169
Ghennadi Procopciuc0d525772024-06-12 08:09:19 +0300170static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
171{
172 uintptr_t osc_addr;
173
174 osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
175 return (struct s32cc_osc *)osc_addr;
176}
177
178static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
179{
180 uintptr_t clk_addr;
181
182 clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
183 return (struct s32cc_clk *)clk_addr;
184}
185
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300186static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
187{
188 const struct s32cc_clk_obj *module;
189
190 module = clk->module;
191 if (module == NULL) {
192 return false;
193 }
194
Ghennadi Procopciuc8384d182024-06-12 10:53:06 +0300195 return (module->type == s32cc_clkmux_t) ||
196 (module->type == s32cc_shared_clkmux_t);
Ghennadi Procopciucaa45fa92024-06-12 10:02:07 +0300197}
198
199static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
200{
201 uintptr_t cmux_addr;
202
203 cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
204 return (struct s32cc_clkmux *)cmux_addr;
205}
206
207static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
208{
209 if (!is_s32cc_clk_mux(clk)) {
210 return NULL;
211 }
212
213 return s32cc_obj2clkmux(clk->module);
214}
215
Ghennadi Procopciuce18cf332024-06-12 11:55:32 +0300216static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod)
217{
218 uintptr_t pll_addr;
219
220 pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc);
221 return (struct s32cc_pll *)pll_addr;
222}
223
Ghennadi Procopciuc907f6542024-06-12 12:00:15 +0300224static inline struct s32cc_pll_out_div *s32cc_obj2plldiv(const struct s32cc_clk_obj *mod)
225{
226 uintptr_t plldiv_addr;
227
228 plldiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll_out_div, desc);
229 return (struct s32cc_pll_out_div *)plldiv_addr;
230}
231
Ghennadi Procopciuce6946b62024-06-12 12:29:54 +0300232static inline struct s32cc_fixed_div *s32cc_obj2fixeddiv(const struct s32cc_clk_obj *mod)
233{
234 uintptr_t fdiv_addr;
235
236 fdiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_fixed_div, desc);
237 return (struct s32cc_fixed_div *)fdiv_addr;
238}
239
Ghennadi Procopciucecc98d22024-06-12 07:38:52 +0300240#endif /* S32CC_CLK_MODULES_H */