xref: /rk3399_ARM-atf/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h (revision 1e4480bb54b0f567688cfbea2119aa703fcbb7b8)
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_clkmux_t,
21 	s32cc_shared_clkmux_t,
22 	s32cc_fixed_div_t,
23 };
24 
25 enum s32cc_clk_source {
26 	S32CC_FIRC,
27 	S32CC_FXOSC,
28 	S32CC_SIRC,
29 	S32CC_ARM_PLL,
30 	S32CC_CGM1,
31 };
32 
33 struct s32cc_clk_obj {
34 	enum s32cc_clkm_type type;
35 	uint32_t refcount;
36 };
37 
38 struct 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 
53 struct 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 
77 #define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)   \
78 	S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
79 			       INDEX, NCLKS, __VA_ARGS__)
80 
81 struct 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 
100 struct 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 
116 #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 
125 struct 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 
140 struct 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 
148 struct 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 
170 static 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 
178 static 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 
186 static 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 
195 	return (module->type == s32cc_clkmux_t) ||
196 	    (module->type == s32cc_shared_clkmux_t);
197 }
198 
199 static 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 
207 static 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 
216 static 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 
224 static 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 
232 static 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 
240 #endif /* S32CC_CLK_MODULES_H */
241