xref: /rk3399_ARM-atf/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h (revision 44ae54af5cadb499cb72cc0edd71711d7a2d019e)
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_CGM1,
34 };
35 
36 struct s32cc_clk_obj {
37 	enum s32cc_clkm_type type;
38 	uint32_t refcount;
39 };
40 
41 struct 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 
56 struct 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 
80 #define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)   \
81 	S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
82 			       INDEX, NCLKS, __VA_ARGS__)
83 
84 struct 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 
103 struct 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 
119 #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 
128 struct 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 
144 struct 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 
160 struct 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 
175 struct 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 
183 struct s32cc_clk_array {
184 	unsigned long type_mask;
185 	struct s32cc_clk **clks;
186 	size_t n_clks;
187 };
188 
189 #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),                                \
198 }
199 
200 #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
201 	S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
202 
203 #define S32CC_MODULE_CLK(PARENT_MODULE) \
204 	S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
205 
206 #define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
207 	S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
208 
209 static 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 
217 static 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 
225 static 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 
234 	return (module->type == s32cc_clkmux_t) ||
235 	    (module->type == s32cc_shared_clkmux_t);
236 }
237 
238 static 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 
246 static 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 
255 static 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 
263 static 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 
271 static 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 
279 static 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 
287 static 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 
295 #endif /* S32CC_CLK_MODULES_H */
296