xref: /rk3399_ARM-atf/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h (revision 7f152ea6856c7780424ec3e92b181d805a314f43)
1 /* 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>
9 #include <stdbool.h>
10 #include <stddef.h>
11 
12 #define MHZ	UL(1000000)
13 #define GHZ	(UL(1000) * MHZ)
14 
15 enum s32cc_clkm_type {
16 	s32cc_osc_t,
17 	s32cc_clk_t,
18 	s32cc_pll_t,
19 	s32cc_pll_out_div_t,
20 	s32cc_dfs_t,
21 	s32cc_dfs_div_t,
22 	s32cc_clkmux_t,
23 	s32cc_shared_clkmux_t,
24 	s32cc_fixed_div_t,
25 };
26 
27 enum s32cc_clk_source {
28 	S32CC_FIRC,
29 	S32CC_FXOSC,
30 	S32CC_SIRC,
31 	S32CC_ARM_PLL,
32 	S32CC_ARM_DFS,
33 	S32CC_PERIPH_PLL,
34 	S32CC_CGM0,
35 	S32CC_CGM1,
36 };
37 
38 struct s32cc_clk_obj {
39 	enum s32cc_clkm_type type;
40 	uint32_t refcount;
41 };
42 
43 struct 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 
58 struct 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 
82 #define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)   \
83 	S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
84 			       INDEX, NCLKS, __VA_ARGS__)
85 
86 struct 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 
105 struct 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 
121 #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 
130 struct 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 
146 struct 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 
162 struct 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 
177 struct 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 
185 struct s32cc_clk_array {
186 	unsigned long type_mask;
187 	struct s32cc_clk **clks;
188 	size_t n_clks;
189 };
190 
191 #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),                                \
200 }
201 
202 #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
203 	S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
204 
205 #define S32CC_MODULE_CLK(PARENT_MODULE) \
206 	S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
207 
208 #define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
209 	S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
210 
211 static 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 
219 static 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 
227 static 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 
236 	return (module->type == s32cc_clkmux_t) ||
237 	    (module->type == s32cc_shared_clkmux_t);
238 }
239 
240 static 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 
248 static 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 
257 static 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 
265 static 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 
273 static 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 
281 static 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 
289 static 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 
297 #endif /* S32CC_CLK_MODULES_H */
298