xref: /rk3399_ARM-atf/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h (revision 5e0be8c0241e5075b34bd5b14df2df9f048715d3)
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_CGM0,
34 	S32CC_CGM1,
35 };
36 
37 struct s32cc_clk_obj {
38 	enum s32cc_clkm_type type;
39 	uint32_t refcount;
40 };
41 
42 struct 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 
57 struct 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 
81 #define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)   \
82 	S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
83 			       INDEX, NCLKS, __VA_ARGS__)
84 
85 struct 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 
104 struct 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 
120 #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 
129 struct 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 
145 struct 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 
161 struct 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 
176 struct 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 
184 struct s32cc_clk_array {
185 	unsigned long type_mask;
186 	struct s32cc_clk **clks;
187 	size_t n_clks;
188 };
189 
190 #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),                                \
199 }
200 
201 #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
202 	S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
203 
204 #define S32CC_MODULE_CLK(PARENT_MODULE) \
205 	S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
206 
207 #define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
208 	S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
209 
210 static 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 
218 static 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 
226 static 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 
235 	return (module->type == s32cc_clkmux_t) ||
236 	    (module->type == s32cc_shared_clkmux_t);
237 }
238 
239 static 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 
247 static 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 
256 static 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 
264 static 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 
272 static 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 
280 static 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 
288 static 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 
296 #endif /* S32CC_CLK_MODULES_H */
297