xref: /rk3399_ARM-atf/drivers/nxp/clk/s32cc/s32cc_clk_drv.c (revision 12e7a2cd2f8f535dfd63834ce78e3fc248ff39f2)
13a580e9eSGhennadi Procopciuc /*
23a580e9eSGhennadi Procopciuc  * Copyright 2024 NXP
33a580e9eSGhennadi Procopciuc  *
43a580e9eSGhennadi Procopciuc  * SPDX-License-Identifier: BSD-3-Clause
53a580e9eSGhennadi Procopciuc  */
63a580e9eSGhennadi Procopciuc #include <errno.h>
73a580e9eSGhennadi Procopciuc 
88ab34357SGhennadi Procopciuc #include <s32cc-clk-regs.h>
98ab34357SGhennadi Procopciuc 
10d9373519SGhennadi Procopciuc #include <common/debug.h>
113a580e9eSGhennadi Procopciuc #include <drivers/clk.h>
128ab34357SGhennadi Procopciuc #include <lib/mmio.h>
13d9373519SGhennadi Procopciuc #include <s32cc-clk-modules.h>
14d9373519SGhennadi Procopciuc #include <s32cc-clk-utils.h>
15d9373519SGhennadi Procopciuc 
16d9373519SGhennadi Procopciuc #define MAX_STACK_DEPTH		(15U)
17d9373519SGhennadi Procopciuc 
188ab34357SGhennadi Procopciuc struct s32cc_clk_drv {
198ab34357SGhennadi Procopciuc 	uintptr_t fxosc_base;
208ab34357SGhennadi Procopciuc };
218ab34357SGhennadi Procopciuc 
22d9373519SGhennadi Procopciuc static int update_stack_depth(unsigned int *depth)
23d9373519SGhennadi Procopciuc {
24d9373519SGhennadi Procopciuc 	if (*depth == 0U) {
25d9373519SGhennadi Procopciuc 		return -ENOMEM;
26d9373519SGhennadi Procopciuc 	}
27d9373519SGhennadi Procopciuc 
28d9373519SGhennadi Procopciuc 	(*depth)--;
29d9373519SGhennadi Procopciuc 	return 0;
30d9373519SGhennadi Procopciuc }
313a580e9eSGhennadi Procopciuc 
328ab34357SGhennadi Procopciuc static struct s32cc_clk_drv *get_drv(void)
338ab34357SGhennadi Procopciuc {
348ab34357SGhennadi Procopciuc 	static struct s32cc_clk_drv driver = {
358ab34357SGhennadi Procopciuc 		.fxosc_base = FXOSC_BASE_ADDR,
368ab34357SGhennadi Procopciuc 	};
378ab34357SGhennadi Procopciuc 
388ab34357SGhennadi Procopciuc 	return &driver;
398ab34357SGhennadi Procopciuc }
408ab34357SGhennadi Procopciuc 
418ab34357SGhennadi Procopciuc static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth);
428ab34357SGhennadi Procopciuc 
438ab34357SGhennadi Procopciuc static int enable_clk_module(const struct s32cc_clk_obj *module,
448ab34357SGhennadi Procopciuc 			     const struct s32cc_clk_drv *drv,
458ab34357SGhennadi Procopciuc 			     unsigned int *depth)
468ab34357SGhennadi Procopciuc {
478ab34357SGhennadi Procopciuc 	const struct s32cc_clk *clk = s32cc_obj2clk(module);
488ab34357SGhennadi Procopciuc 	int ret;
498ab34357SGhennadi Procopciuc 
508ab34357SGhennadi Procopciuc 	ret = update_stack_depth(depth);
518ab34357SGhennadi Procopciuc 	if (ret != 0) {
528ab34357SGhennadi Procopciuc 		return ret;
538ab34357SGhennadi Procopciuc 	}
548ab34357SGhennadi Procopciuc 
558ab34357SGhennadi Procopciuc 	if (clk == NULL) {
568ab34357SGhennadi Procopciuc 		return -EINVAL;
578ab34357SGhennadi Procopciuc 	}
588ab34357SGhennadi Procopciuc 
598ab34357SGhennadi Procopciuc 	if (clk->module != NULL) {
608ab34357SGhennadi Procopciuc 		return enable_module(clk->module, depth);
618ab34357SGhennadi Procopciuc 	}
628ab34357SGhennadi Procopciuc 
638ab34357SGhennadi Procopciuc 	if (clk->pclock != NULL) {
648ab34357SGhennadi Procopciuc 		return enable_clk_module(&clk->pclock->desc, drv, depth);
658ab34357SGhennadi Procopciuc 	}
668ab34357SGhennadi Procopciuc 
678ab34357SGhennadi Procopciuc 	return -EINVAL;
688ab34357SGhennadi Procopciuc }
698ab34357SGhennadi Procopciuc 
708ab34357SGhennadi Procopciuc static void enable_fxosc(const struct s32cc_clk_drv *drv)
718ab34357SGhennadi Procopciuc {
728ab34357SGhennadi Procopciuc 	uintptr_t fxosc_base = drv->fxosc_base;
738ab34357SGhennadi Procopciuc 	uint32_t ctrl;
748ab34357SGhennadi Procopciuc 
758ab34357SGhennadi Procopciuc 	ctrl = mmio_read_32(FXOSC_CTRL(fxosc_base));
768ab34357SGhennadi Procopciuc 	if ((ctrl & FXOSC_CTRL_OSCON) != U(0)) {
778ab34357SGhennadi Procopciuc 		return;
788ab34357SGhennadi Procopciuc 	}
798ab34357SGhennadi Procopciuc 
808ab34357SGhennadi Procopciuc 	ctrl = FXOSC_CTRL_COMP_EN;
818ab34357SGhennadi Procopciuc 	ctrl &= ~FXOSC_CTRL_OSC_BYP;
828ab34357SGhennadi Procopciuc 	ctrl |= FXOSC_CTRL_EOCV(0x1);
838ab34357SGhennadi Procopciuc 	ctrl |= FXOSC_CTRL_GM_SEL(0x7);
848ab34357SGhennadi Procopciuc 	mmio_write_32(FXOSC_CTRL(fxosc_base), ctrl);
858ab34357SGhennadi Procopciuc 
868ab34357SGhennadi Procopciuc 	/* Switch ON the crystal oscillator. */
878ab34357SGhennadi Procopciuc 	mmio_setbits_32(FXOSC_CTRL(fxosc_base), FXOSC_CTRL_OSCON);
888ab34357SGhennadi Procopciuc 
898ab34357SGhennadi Procopciuc 	/* Wait until the clock is stable. */
908ab34357SGhennadi Procopciuc 	while ((mmio_read_32(FXOSC_STAT(fxosc_base)) & FXOSC_STAT_OSC_STAT) == U(0)) {
918ab34357SGhennadi Procopciuc 	}
928ab34357SGhennadi Procopciuc }
938ab34357SGhennadi Procopciuc 
948ab34357SGhennadi Procopciuc static int enable_osc(const struct s32cc_clk_obj *module,
958ab34357SGhennadi Procopciuc 		      const struct s32cc_clk_drv *drv,
968ab34357SGhennadi Procopciuc 		      unsigned int *depth)
978ab34357SGhennadi Procopciuc {
988ab34357SGhennadi Procopciuc 	const struct s32cc_osc *osc = s32cc_obj2osc(module);
998ab34357SGhennadi Procopciuc 	int ret = 0;
1008ab34357SGhennadi Procopciuc 
1018ab34357SGhennadi Procopciuc 	ret = update_stack_depth(depth);
1028ab34357SGhennadi Procopciuc 	if (ret != 0) {
1038ab34357SGhennadi Procopciuc 		return ret;
1048ab34357SGhennadi Procopciuc 	}
1058ab34357SGhennadi Procopciuc 
1068ab34357SGhennadi Procopciuc 	switch (osc->source) {
1078ab34357SGhennadi Procopciuc 	case S32CC_FXOSC:
1088ab34357SGhennadi Procopciuc 		enable_fxosc(drv);
1098ab34357SGhennadi Procopciuc 		break;
1108ab34357SGhennadi Procopciuc 	/* FIRC and SIRC oscillators are enabled by default */
1118ab34357SGhennadi Procopciuc 	case S32CC_FIRC:
1128ab34357SGhennadi Procopciuc 		break;
1138ab34357SGhennadi Procopciuc 	case S32CC_SIRC:
1148ab34357SGhennadi Procopciuc 		break;
1158ab34357SGhennadi Procopciuc 	default:
1168ab34357SGhennadi Procopciuc 		ERROR("Invalid oscillator %d\n", osc->source);
1178ab34357SGhennadi Procopciuc 		ret = -EINVAL;
1188ab34357SGhennadi Procopciuc 		break;
1198ab34357SGhennadi Procopciuc 	};
1208ab34357SGhennadi Procopciuc 
1218ab34357SGhennadi Procopciuc 	return ret;
1228ab34357SGhennadi Procopciuc }
1238ab34357SGhennadi Procopciuc 
1248ab34357SGhennadi Procopciuc static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth)
1258ab34357SGhennadi Procopciuc {
1268ab34357SGhennadi Procopciuc 	const struct s32cc_clk_drv *drv = get_drv();
1278ab34357SGhennadi Procopciuc 	int ret = 0;
1288ab34357SGhennadi Procopciuc 
1298ab34357SGhennadi Procopciuc 	ret = update_stack_depth(depth);
1308ab34357SGhennadi Procopciuc 	if (ret != 0) {
1318ab34357SGhennadi Procopciuc 		return ret;
1328ab34357SGhennadi Procopciuc 	}
1338ab34357SGhennadi Procopciuc 
1348ab34357SGhennadi Procopciuc 	if (drv == NULL) {
1358ab34357SGhennadi Procopciuc 		return -EINVAL;
1368ab34357SGhennadi Procopciuc 	}
1378ab34357SGhennadi Procopciuc 
1388ab34357SGhennadi Procopciuc 	switch (module->type) {
1398ab34357SGhennadi Procopciuc 	case s32cc_osc_t:
1408ab34357SGhennadi Procopciuc 		ret = enable_osc(module, drv, depth);
1418ab34357SGhennadi Procopciuc 		break;
1428ab34357SGhennadi Procopciuc 	case s32cc_clk_t:
1438ab34357SGhennadi Procopciuc 		ret = enable_clk_module(module, drv, depth);
1448ab34357SGhennadi Procopciuc 		break;
145a8be748aSGhennadi Procopciuc 	case s32cc_clkmux_t:
146a8be748aSGhennadi Procopciuc 		ret = -ENOTSUP;
147a8be748aSGhennadi Procopciuc 		break;
148a8be748aSGhennadi Procopciuc 	case s32cc_pll_t:
149a8be748aSGhennadi Procopciuc 		ret = -ENOTSUP;
150a8be748aSGhennadi Procopciuc 		break;
151a8be748aSGhennadi Procopciuc 	case s32cc_pll_out_div_t:
152a8be748aSGhennadi Procopciuc 		ret = -ENOTSUP;
153a8be748aSGhennadi Procopciuc 		break;
1548ab34357SGhennadi Procopciuc 	default:
1558ab34357SGhennadi Procopciuc 		ret = -EINVAL;
1568ab34357SGhennadi Procopciuc 		break;
1578ab34357SGhennadi Procopciuc 	}
1588ab34357SGhennadi Procopciuc 
1598ab34357SGhennadi Procopciuc 	return ret;
1608ab34357SGhennadi Procopciuc }
1618ab34357SGhennadi Procopciuc 
1623a580e9eSGhennadi Procopciuc static int s32cc_clk_enable(unsigned long id)
1633a580e9eSGhennadi Procopciuc {
1648ab34357SGhennadi Procopciuc 	unsigned int depth = MAX_STACK_DEPTH;
1658ab34357SGhennadi Procopciuc 	const struct s32cc_clk *clk;
1668ab34357SGhennadi Procopciuc 
1678ab34357SGhennadi Procopciuc 	clk = s32cc_get_arch_clk(id);
1688ab34357SGhennadi Procopciuc 	if (clk == NULL) {
1698ab34357SGhennadi Procopciuc 		return -EINVAL;
1708ab34357SGhennadi Procopciuc 	}
1718ab34357SGhennadi Procopciuc 
1728ab34357SGhennadi Procopciuc 	return enable_module(&clk->desc, &depth);
1733a580e9eSGhennadi Procopciuc }
1743a580e9eSGhennadi Procopciuc 
1753a580e9eSGhennadi Procopciuc static void s32cc_clk_disable(unsigned long id)
1763a580e9eSGhennadi Procopciuc {
1773a580e9eSGhennadi Procopciuc }
1783a580e9eSGhennadi Procopciuc 
1793a580e9eSGhennadi Procopciuc static bool s32cc_clk_is_enabled(unsigned long id)
1803a580e9eSGhennadi Procopciuc {
1813a580e9eSGhennadi Procopciuc 	return false;
1823a580e9eSGhennadi Procopciuc }
1833a580e9eSGhennadi Procopciuc 
1843a580e9eSGhennadi Procopciuc static unsigned long s32cc_clk_get_rate(unsigned long id)
1853a580e9eSGhennadi Procopciuc {
1863a580e9eSGhennadi Procopciuc 	return 0;
1873a580e9eSGhennadi Procopciuc }
1883a580e9eSGhennadi Procopciuc 
189d9373519SGhennadi Procopciuc static int set_module_rate(const struct s32cc_clk_obj *module,
190d9373519SGhennadi Procopciuc 			   unsigned long rate, unsigned long *orate,
191d9373519SGhennadi Procopciuc 			   unsigned int *depth);
192d9373519SGhennadi Procopciuc 
193d9373519SGhennadi Procopciuc static int set_osc_freq(const struct s32cc_clk_obj *module, unsigned long rate,
194d9373519SGhennadi Procopciuc 			unsigned long *orate, unsigned int *depth)
195d9373519SGhennadi Procopciuc {
196d9373519SGhennadi Procopciuc 	struct s32cc_osc *osc = s32cc_obj2osc(module);
197d9373519SGhennadi Procopciuc 	int ret;
198d9373519SGhennadi Procopciuc 
199d9373519SGhennadi Procopciuc 	ret = update_stack_depth(depth);
200d9373519SGhennadi Procopciuc 	if (ret != 0) {
201d9373519SGhennadi Procopciuc 		return ret;
202d9373519SGhennadi Procopciuc 	}
203d9373519SGhennadi Procopciuc 
204d9373519SGhennadi Procopciuc 	if ((osc->freq != 0UL) && (rate != osc->freq)) {
205d9373519SGhennadi Procopciuc 		ERROR("Already initialized oscillator. freq = %lu\n",
206d9373519SGhennadi Procopciuc 		      osc->freq);
207d9373519SGhennadi Procopciuc 		return -EINVAL;
208d9373519SGhennadi Procopciuc 	}
209d9373519SGhennadi Procopciuc 
210d9373519SGhennadi Procopciuc 	osc->freq = rate;
211d9373519SGhennadi Procopciuc 	*orate = osc->freq;
212d9373519SGhennadi Procopciuc 
213d9373519SGhennadi Procopciuc 	return 0;
214d9373519SGhennadi Procopciuc }
215d9373519SGhennadi Procopciuc 
216d9373519SGhennadi Procopciuc static int set_clk_freq(const struct s32cc_clk_obj *module, unsigned long rate,
217d9373519SGhennadi Procopciuc 			unsigned long *orate, unsigned int *depth)
218d9373519SGhennadi Procopciuc {
219d9373519SGhennadi Procopciuc 	const struct s32cc_clk *clk = s32cc_obj2clk(module);
220d9373519SGhennadi Procopciuc 	int ret;
221d9373519SGhennadi Procopciuc 
222d9373519SGhennadi Procopciuc 	ret = update_stack_depth(depth);
223d9373519SGhennadi Procopciuc 	if (ret != 0) {
224d9373519SGhennadi Procopciuc 		return ret;
225d9373519SGhennadi Procopciuc 	}
226d9373519SGhennadi Procopciuc 
227d9373519SGhennadi Procopciuc 	if ((clk->min_freq != 0UL) && (clk->max_freq != 0UL) &&
228d9373519SGhennadi Procopciuc 	    ((rate < clk->min_freq) || (rate > clk->max_freq))) {
229d9373519SGhennadi Procopciuc 		ERROR("%lu frequency is out of the allowed range: [%lu:%lu]\n",
230d9373519SGhennadi Procopciuc 		      rate, clk->min_freq, clk->max_freq);
231d9373519SGhennadi Procopciuc 		return -EINVAL;
232d9373519SGhennadi Procopciuc 	}
233d9373519SGhennadi Procopciuc 
234d9373519SGhennadi Procopciuc 	if (clk->module != NULL) {
235d9373519SGhennadi Procopciuc 		return set_module_rate(clk->module, rate, orate, depth);
236d9373519SGhennadi Procopciuc 	}
237d9373519SGhennadi Procopciuc 
238d9373519SGhennadi Procopciuc 	if (clk->pclock != NULL) {
239d9373519SGhennadi Procopciuc 		return set_clk_freq(&clk->pclock->desc, rate, orate, depth);
240d9373519SGhennadi Procopciuc 	}
241d9373519SGhennadi Procopciuc 
242d9373519SGhennadi Procopciuc 	return -EINVAL;
243d9373519SGhennadi Procopciuc }
244d9373519SGhennadi Procopciuc 
245d9373519SGhennadi Procopciuc static int set_module_rate(const struct s32cc_clk_obj *module,
246d9373519SGhennadi Procopciuc 			   unsigned long rate, unsigned long *orate,
247d9373519SGhennadi Procopciuc 			   unsigned int *depth)
248d9373519SGhennadi Procopciuc {
249d9373519SGhennadi Procopciuc 	int ret = 0;
250d9373519SGhennadi Procopciuc 
251d9373519SGhennadi Procopciuc 	ret = update_stack_depth(depth);
252d9373519SGhennadi Procopciuc 	if (ret != 0) {
253d9373519SGhennadi Procopciuc 		return ret;
254d9373519SGhennadi Procopciuc 	}
255d9373519SGhennadi Procopciuc 
256d9373519SGhennadi Procopciuc 	switch (module->type) {
257d9373519SGhennadi Procopciuc 	case s32cc_clk_t:
258d9373519SGhennadi Procopciuc 		ret = set_clk_freq(module, rate, orate, depth);
259d9373519SGhennadi Procopciuc 		break;
260d9373519SGhennadi Procopciuc 	case s32cc_osc_t:
261d9373519SGhennadi Procopciuc 		ret = set_osc_freq(module, rate, orate, depth);
262d9373519SGhennadi Procopciuc 		break;
263a8be748aSGhennadi Procopciuc 	case s32cc_clkmux_t:
264a8be748aSGhennadi Procopciuc 	case s32cc_pll_t:
265a8be748aSGhennadi Procopciuc 	case s32cc_pll_out_div_t:
266a8be748aSGhennadi Procopciuc 		ret = -ENOTSUP;
267a8be748aSGhennadi Procopciuc 		break;
268d9373519SGhennadi Procopciuc 	default:
269d9373519SGhennadi Procopciuc 		ret = -EINVAL;
270d9373519SGhennadi Procopciuc 		break;
271d9373519SGhennadi Procopciuc 	}
272d9373519SGhennadi Procopciuc 
273d9373519SGhennadi Procopciuc 	return ret;
274d9373519SGhennadi Procopciuc }
275d9373519SGhennadi Procopciuc 
2763a580e9eSGhennadi Procopciuc static int s32cc_clk_set_rate(unsigned long id, unsigned long rate,
2773a580e9eSGhennadi Procopciuc 			      unsigned long *orate)
2783a580e9eSGhennadi Procopciuc {
279d9373519SGhennadi Procopciuc 	unsigned int depth = MAX_STACK_DEPTH;
280d9373519SGhennadi Procopciuc 	const struct s32cc_clk *clk;
281d9373519SGhennadi Procopciuc 	int ret;
282d9373519SGhennadi Procopciuc 
283d9373519SGhennadi Procopciuc 	clk = s32cc_get_arch_clk(id);
284d9373519SGhennadi Procopciuc 	if (clk == NULL) {
285d9373519SGhennadi Procopciuc 		return -EINVAL;
286d9373519SGhennadi Procopciuc 	}
287d9373519SGhennadi Procopciuc 
288d9373519SGhennadi Procopciuc 	ret = set_module_rate(&clk->desc, rate, orate, &depth);
289d9373519SGhennadi Procopciuc 	if (ret != 0) {
290d9373519SGhennadi Procopciuc 		ERROR("Failed to set frequency (%lu MHz) for clock %lu\n",
291d9373519SGhennadi Procopciuc 		      rate, id);
292d9373519SGhennadi Procopciuc 	}
293d9373519SGhennadi Procopciuc 
294d9373519SGhennadi Procopciuc 	return ret;
2953a580e9eSGhennadi Procopciuc }
2963a580e9eSGhennadi Procopciuc 
2973a580e9eSGhennadi Procopciuc static int s32cc_clk_get_parent(unsigned long id)
2983a580e9eSGhennadi Procopciuc {
2993a580e9eSGhennadi Procopciuc 	return -ENOTSUP;
3003a580e9eSGhennadi Procopciuc }
3013a580e9eSGhennadi Procopciuc 
3023a580e9eSGhennadi Procopciuc static int s32cc_clk_set_parent(unsigned long id, unsigned long parent_id)
3033a580e9eSGhennadi Procopciuc {
304*12e7a2cdSGhennadi Procopciuc 	const struct s32cc_clk *parent;
305*12e7a2cdSGhennadi Procopciuc 	const struct s32cc_clk *clk;
306*12e7a2cdSGhennadi Procopciuc 	bool valid_source = false;
307*12e7a2cdSGhennadi Procopciuc 	struct s32cc_clkmux *mux;
308*12e7a2cdSGhennadi Procopciuc 	uint8_t i;
309*12e7a2cdSGhennadi Procopciuc 
310*12e7a2cdSGhennadi Procopciuc 	clk = s32cc_get_arch_clk(id);
311*12e7a2cdSGhennadi Procopciuc 	if (clk == NULL) {
312*12e7a2cdSGhennadi Procopciuc 		return -EINVAL;
313*12e7a2cdSGhennadi Procopciuc 	}
314*12e7a2cdSGhennadi Procopciuc 
315*12e7a2cdSGhennadi Procopciuc 	parent = s32cc_get_arch_clk(parent_id);
316*12e7a2cdSGhennadi Procopciuc 	if (parent == NULL) {
317*12e7a2cdSGhennadi Procopciuc 		return -EINVAL;
318*12e7a2cdSGhennadi Procopciuc 	}
319*12e7a2cdSGhennadi Procopciuc 
320*12e7a2cdSGhennadi Procopciuc 	if (!is_s32cc_clk_mux(clk)) {
321*12e7a2cdSGhennadi Procopciuc 		ERROR("Clock %lu is not a mux\n", id);
322*12e7a2cdSGhennadi Procopciuc 		return -EINVAL;
323*12e7a2cdSGhennadi Procopciuc 	}
324*12e7a2cdSGhennadi Procopciuc 
325*12e7a2cdSGhennadi Procopciuc 	mux = s32cc_clk2mux(clk);
326*12e7a2cdSGhennadi Procopciuc 	if (mux == NULL) {
327*12e7a2cdSGhennadi Procopciuc 		ERROR("Failed to cast clock %lu to clock mux\n", id);
328*12e7a2cdSGhennadi Procopciuc 		return -EINVAL;
329*12e7a2cdSGhennadi Procopciuc 	}
330*12e7a2cdSGhennadi Procopciuc 
331*12e7a2cdSGhennadi Procopciuc 	for (i = 0; i < mux->nclks; i++) {
332*12e7a2cdSGhennadi Procopciuc 		if (mux->clkids[i] == parent_id) {
333*12e7a2cdSGhennadi Procopciuc 			valid_source = true;
334*12e7a2cdSGhennadi Procopciuc 			break;
335*12e7a2cdSGhennadi Procopciuc 		}
336*12e7a2cdSGhennadi Procopciuc 	}
337*12e7a2cdSGhennadi Procopciuc 
338*12e7a2cdSGhennadi Procopciuc 	if (!valid_source) {
339*12e7a2cdSGhennadi Procopciuc 		ERROR("Clock %lu is not a valid clock for mux %lu\n",
340*12e7a2cdSGhennadi Procopciuc 		      parent_id, id);
341*12e7a2cdSGhennadi Procopciuc 		return -EINVAL;
342*12e7a2cdSGhennadi Procopciuc 	}
343*12e7a2cdSGhennadi Procopciuc 
344*12e7a2cdSGhennadi Procopciuc 	mux->source_id = parent_id;
345*12e7a2cdSGhennadi Procopciuc 
346*12e7a2cdSGhennadi Procopciuc 	return 0;
3473a580e9eSGhennadi Procopciuc }
3483a580e9eSGhennadi Procopciuc 
3493a580e9eSGhennadi Procopciuc void s32cc_clk_register_drv(void)
3503a580e9eSGhennadi Procopciuc {
3513a580e9eSGhennadi Procopciuc 	static const struct clk_ops s32cc_clk_ops = {
3523a580e9eSGhennadi Procopciuc 		.enable		= s32cc_clk_enable,
3533a580e9eSGhennadi Procopciuc 		.disable	= s32cc_clk_disable,
3543a580e9eSGhennadi Procopciuc 		.is_enabled	= s32cc_clk_is_enabled,
3553a580e9eSGhennadi Procopciuc 		.get_rate	= s32cc_clk_get_rate,
3563a580e9eSGhennadi Procopciuc 		.set_rate	= s32cc_clk_set_rate,
3573a580e9eSGhennadi Procopciuc 		.get_parent	= s32cc_clk_get_parent,
3583a580e9eSGhennadi Procopciuc 		.set_parent	= s32cc_clk_set_parent,
3593a580e9eSGhennadi Procopciuc 	};
3603a580e9eSGhennadi Procopciuc 
3613a580e9eSGhennadi Procopciuc 	clk_register(&s32cc_clk_ops);
3623a580e9eSGhennadi Procopciuc }
3633a580e9eSGhennadi Procopciuc 
364