1 // SPDX-License-Identifier: GPL-2.0+
3 // OWL divider clock driver
5 // Copyright (c) 2014 Actions Semi Inc.
6 // Author: David Liu <liuwei@actions-semi.com>
8 // Copyright (c) 2018 Linaro Ltd.
9 // Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
11 #include <linux/clk-provider.h>
12 #include <linux/regmap.h>
14 #include "owl-divider.h"
16 long owl_divider_helper_round_rate(struct owl_clk_common
*common
,
17 const struct owl_divider_hw
*div_hw
,
19 unsigned long *parent_rate
)
21 return divider_round_rate(&common
->hw
, rate
, parent_rate
,
22 div_hw
->table
, div_hw
->width
,
26 static long owl_divider_round_rate(struct clk_hw
*hw
, unsigned long rate
,
27 unsigned long *parent_rate
)
29 struct owl_divider
*div
= hw_to_owl_divider(hw
);
31 return owl_divider_helper_round_rate(&div
->common
, &div
->div_hw
,
35 unsigned long owl_divider_helper_recalc_rate(struct owl_clk_common
*common
,
36 const struct owl_divider_hw
*div_hw
,
37 unsigned long parent_rate
)
42 regmap_read(common
->regmap
, div_hw
->reg
, ®
);
43 val
= reg
>> div_hw
->shift
;
44 val
&= (1 << div_hw
->width
) - 1;
46 return divider_recalc_rate(&common
->hw
, parent_rate
,
52 static unsigned long owl_divider_recalc_rate(struct clk_hw
*hw
,
53 unsigned long parent_rate
)
55 struct owl_divider
*div
= hw_to_owl_divider(hw
);
57 return owl_divider_helper_recalc_rate(&div
->common
,
58 &div
->div_hw
, parent_rate
);
61 int owl_divider_helper_set_rate(const struct owl_clk_common
*common
,
62 const struct owl_divider_hw
*div_hw
,
64 unsigned long parent_rate
)
69 val
= divider_get_val(rate
, parent_rate
, div_hw
->table
,
72 regmap_read(common
->regmap
, div_hw
->reg
, ®
);
73 reg
&= ~GENMASK(div_hw
->width
+ div_hw
->shift
- 1, div_hw
->shift
);
75 regmap_write(common
->regmap
, div_hw
->reg
,
76 reg
| (val
<< div_hw
->shift
));
81 static int owl_divider_set_rate(struct clk_hw
*hw
, unsigned long rate
,
82 unsigned long parent_rate
)
84 struct owl_divider
*div
= hw_to_owl_divider(hw
);
86 return owl_divider_helper_set_rate(&div
->common
, &div
->div_hw
,
90 const struct clk_ops owl_divider_ops
= {
91 .recalc_rate
= owl_divider_recalc_rate
,
92 .round_rate
= owl_divider_round_rate
,
93 .set_rate
= owl_divider_set_rate
,