xref: /rk3399_ARM-atf/drivers/nxp/clk/s32cc/s32cc_clk_drv.c (revision 8ab34357497b454b2f5e505d06ce9437da7772e4)
1 /*
2  * Copyright 2024 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include <errno.h>
7 
8 #include <s32cc-clk-regs.h>
9 
10 #include <common/debug.h>
11 #include <drivers/clk.h>
12 #include <lib/mmio.h>
13 #include <s32cc-clk-modules.h>
14 #include <s32cc-clk-utils.h>
15 
16 #define MAX_STACK_DEPTH		(15U)
17 
18 struct s32cc_clk_drv {
19 	uintptr_t fxosc_base;
20 };
21 
22 static int update_stack_depth(unsigned int *depth)
23 {
24 	if (*depth == 0U) {
25 		return -ENOMEM;
26 	}
27 
28 	(*depth)--;
29 	return 0;
30 }
31 
32 static struct s32cc_clk_drv *get_drv(void)
33 {
34 	static struct s32cc_clk_drv driver = {
35 		.fxosc_base = FXOSC_BASE_ADDR,
36 	};
37 
38 	return &driver;
39 }
40 
41 static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth);
42 
43 static int enable_clk_module(const struct s32cc_clk_obj *module,
44 			     const struct s32cc_clk_drv *drv,
45 			     unsigned int *depth)
46 {
47 	const struct s32cc_clk *clk = s32cc_obj2clk(module);
48 	int ret;
49 
50 	ret = update_stack_depth(depth);
51 	if (ret != 0) {
52 		return ret;
53 	}
54 
55 	if (clk == NULL) {
56 		return -EINVAL;
57 	}
58 
59 	if (clk->module != NULL) {
60 		return enable_module(clk->module, depth);
61 	}
62 
63 	if (clk->pclock != NULL) {
64 		return enable_clk_module(&clk->pclock->desc, drv, depth);
65 	}
66 
67 	return -EINVAL;
68 }
69 
70 static void enable_fxosc(const struct s32cc_clk_drv *drv)
71 {
72 	uintptr_t fxosc_base = drv->fxosc_base;
73 	uint32_t ctrl;
74 
75 	ctrl = mmio_read_32(FXOSC_CTRL(fxosc_base));
76 	if ((ctrl & FXOSC_CTRL_OSCON) != U(0)) {
77 		return;
78 	}
79 
80 	ctrl = FXOSC_CTRL_COMP_EN;
81 	ctrl &= ~FXOSC_CTRL_OSC_BYP;
82 	ctrl |= FXOSC_CTRL_EOCV(0x1);
83 	ctrl |= FXOSC_CTRL_GM_SEL(0x7);
84 	mmio_write_32(FXOSC_CTRL(fxosc_base), ctrl);
85 
86 	/* Switch ON the crystal oscillator. */
87 	mmio_setbits_32(FXOSC_CTRL(fxosc_base), FXOSC_CTRL_OSCON);
88 
89 	/* Wait until the clock is stable. */
90 	while ((mmio_read_32(FXOSC_STAT(fxosc_base)) & FXOSC_STAT_OSC_STAT) == U(0)) {
91 	}
92 }
93 
94 static int enable_osc(const struct s32cc_clk_obj *module,
95 		      const struct s32cc_clk_drv *drv,
96 		      unsigned int *depth)
97 {
98 	const struct s32cc_osc *osc = s32cc_obj2osc(module);
99 	int ret = 0;
100 
101 	ret = update_stack_depth(depth);
102 	if (ret != 0) {
103 		return ret;
104 	}
105 
106 	switch (osc->source) {
107 	case S32CC_FXOSC:
108 		enable_fxosc(drv);
109 		break;
110 	/* FIRC and SIRC oscillators are enabled by default */
111 	case S32CC_FIRC:
112 		break;
113 	case S32CC_SIRC:
114 		break;
115 	default:
116 		ERROR("Invalid oscillator %d\n", osc->source);
117 		ret = -EINVAL;
118 		break;
119 	};
120 
121 	return ret;
122 }
123 
124 static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth)
125 {
126 	const struct s32cc_clk_drv *drv = get_drv();
127 	int ret = 0;
128 
129 	ret = update_stack_depth(depth);
130 	if (ret != 0) {
131 		return ret;
132 	}
133 
134 	if (drv == NULL) {
135 		return -EINVAL;
136 	}
137 
138 	switch (module->type) {
139 	case s32cc_osc_t:
140 		ret = enable_osc(module, drv, depth);
141 		break;
142 	case s32cc_clk_t:
143 		ret = enable_clk_module(module, drv, depth);
144 		break;
145 	default:
146 		ret = -EINVAL;
147 		break;
148 	}
149 
150 	return ret;
151 }
152 
153 static int s32cc_clk_enable(unsigned long id)
154 {
155 	unsigned int depth = MAX_STACK_DEPTH;
156 	const struct s32cc_clk *clk;
157 
158 	clk = s32cc_get_arch_clk(id);
159 	if (clk == NULL) {
160 		return -EINVAL;
161 	}
162 
163 	return enable_module(&clk->desc, &depth);
164 }
165 
166 static void s32cc_clk_disable(unsigned long id)
167 {
168 }
169 
170 static bool s32cc_clk_is_enabled(unsigned long id)
171 {
172 	return false;
173 }
174 
175 static unsigned long s32cc_clk_get_rate(unsigned long id)
176 {
177 	return 0;
178 }
179 
180 static int set_module_rate(const struct s32cc_clk_obj *module,
181 			   unsigned long rate, unsigned long *orate,
182 			   unsigned int *depth);
183 
184 static int set_osc_freq(const struct s32cc_clk_obj *module, unsigned long rate,
185 			unsigned long *orate, unsigned int *depth)
186 {
187 	struct s32cc_osc *osc = s32cc_obj2osc(module);
188 	int ret;
189 
190 	ret = update_stack_depth(depth);
191 	if (ret != 0) {
192 		return ret;
193 	}
194 
195 	if ((osc->freq != 0UL) && (rate != osc->freq)) {
196 		ERROR("Already initialized oscillator. freq = %lu\n",
197 		      osc->freq);
198 		return -EINVAL;
199 	}
200 
201 	osc->freq = rate;
202 	*orate = osc->freq;
203 
204 	return 0;
205 }
206 
207 static int set_clk_freq(const struct s32cc_clk_obj *module, unsigned long rate,
208 			unsigned long *orate, unsigned int *depth)
209 {
210 	const struct s32cc_clk *clk = s32cc_obj2clk(module);
211 	int ret;
212 
213 	ret = update_stack_depth(depth);
214 	if (ret != 0) {
215 		return ret;
216 	}
217 
218 	if ((clk->min_freq != 0UL) && (clk->max_freq != 0UL) &&
219 	    ((rate < clk->min_freq) || (rate > clk->max_freq))) {
220 		ERROR("%lu frequency is out of the allowed range: [%lu:%lu]\n",
221 		      rate, clk->min_freq, clk->max_freq);
222 		return -EINVAL;
223 	}
224 
225 	if (clk->module != NULL) {
226 		return set_module_rate(clk->module, rate, orate, depth);
227 	}
228 
229 	if (clk->pclock != NULL) {
230 		return set_clk_freq(&clk->pclock->desc, rate, orate, depth);
231 	}
232 
233 	return -EINVAL;
234 }
235 
236 static int set_module_rate(const struct s32cc_clk_obj *module,
237 			   unsigned long rate, unsigned long *orate,
238 			   unsigned int *depth)
239 {
240 	int ret = 0;
241 
242 	ret = update_stack_depth(depth);
243 	if (ret != 0) {
244 		return ret;
245 	}
246 
247 	switch (module->type) {
248 	case s32cc_clk_t:
249 		ret = set_clk_freq(module, rate, orate, depth);
250 		break;
251 	case s32cc_osc_t:
252 		ret = set_osc_freq(module, rate, orate, depth);
253 		break;
254 	default:
255 		ret = -EINVAL;
256 		break;
257 	}
258 
259 	return ret;
260 }
261 
262 static int s32cc_clk_set_rate(unsigned long id, unsigned long rate,
263 			      unsigned long *orate)
264 {
265 	unsigned int depth = MAX_STACK_DEPTH;
266 	const struct s32cc_clk *clk;
267 	int ret;
268 
269 	clk = s32cc_get_arch_clk(id);
270 	if (clk == NULL) {
271 		return -EINVAL;
272 	}
273 
274 	ret = set_module_rate(&clk->desc, rate, orate, &depth);
275 	if (ret != 0) {
276 		ERROR("Failed to set frequency (%lu MHz) for clock %lu\n",
277 		      rate, id);
278 	}
279 
280 	return ret;
281 }
282 
283 static int s32cc_clk_get_parent(unsigned long id)
284 {
285 	return -ENOTSUP;
286 }
287 
288 static int s32cc_clk_set_parent(unsigned long id, unsigned long parent_id)
289 {
290 	return -ENOTSUP;
291 }
292 
293 void s32cc_clk_register_drv(void)
294 {
295 	static const struct clk_ops s32cc_clk_ops = {
296 		.enable		= s32cc_clk_enable,
297 		.disable	= s32cc_clk_disable,
298 		.is_enabled	= s32cc_clk_is_enabled,
299 		.get_rate	= s32cc_clk_get_rate,
300 		.set_rate	= s32cc_clk_set_rate,
301 		.get_parent	= s32cc_clk_get_parent,
302 		.set_parent	= s32cc_clk_set_parent,
303 	};
304 
305 	clk_register(&s32cc_clk_ops);
306 }
307 
308