• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2019 DENX Software Engineering
4  * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
5  *
6  * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
7  */
8 #include <common.h>
9 #include <malloc.h>
10 #include <clk-uclass.h>
11 #include <dm/device.h>
12 #include <linux/clk-provider.h>
13 #include <div64.h>
14 #include <clk.h>
15 #include "clk.h"
16 
17 #define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor"
18 
clk_factor_recalc_rate(struct clk * clk)19 static ulong clk_factor_recalc_rate(struct clk *clk)
20 {
21 	struct clk_fixed_factor *fix =
22 		to_clk_fixed_factor(dev_get_clk_ptr(clk->dev));
23 	unsigned long parent_rate = clk_get_parent_rate(clk);
24 	unsigned long long int rate;
25 
26 	rate = (unsigned long long int)parent_rate * fix->mult;
27 	do_div(rate, fix->div);
28 	return (ulong)rate;
29 }
30 
31 const struct clk_ops ccf_clk_fixed_factor_ops = {
32 	.get_rate = clk_factor_recalc_rate,
33 };
34 
clk_hw_register_fixed_factor(struct device * dev,const char * name,const char * parent_name,unsigned long flags,unsigned int mult,unsigned int div)35 struct clk *clk_hw_register_fixed_factor(struct device *dev,
36 		const char *name, const char *parent_name, unsigned long flags,
37 		unsigned int mult, unsigned int div)
38 {
39 	struct clk_fixed_factor *fix;
40 	struct clk *clk;
41 	int ret;
42 
43 	fix = kzalloc(sizeof(*fix), GFP_KERNEL);
44 	if (!fix)
45 		return ERR_PTR(-ENOMEM);
46 
47 	/* struct clk_fixed_factor assignments */
48 	fix->mult = mult;
49 	fix->div = div;
50 	clk = &fix->clk;
51 
52 	ret = clk_register(clk, UBOOT_DM_CLK_IMX_FIXED_FACTOR, name,
53 			   parent_name);
54 	if (ret) {
55 		kfree(fix);
56 		return ERR_PTR(ret);
57 	}
58 
59 	return clk;
60 }
61 
clk_register_fixed_factor(struct device * dev,const char * name,const char * parent_name,unsigned long flags,unsigned int mult,unsigned int div)62 struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
63 		const char *parent_name, unsigned long flags,
64 		unsigned int mult, unsigned int div)
65 {
66 	struct clk *clk;
67 
68 	clk = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult,
69 					  div);
70 	if (IS_ERR(clk))
71 		return ERR_CAST(clk);
72 	return clk;
73 }
74 
75 U_BOOT_DRIVER(imx_clk_fixed_factor) = {
76 	.name	= UBOOT_DM_CLK_IMX_FIXED_FACTOR,
77 	.id	= UCLASS_CLK,
78 	.ops	= &ccf_clk_fixed_factor_ops,
79 	.flags = DM_FLAG_PRE_RELOC,
80 };
81