1 // SPDX-License-Identifier: GPL-2.0+
3 // OWL pll 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/slab.h>
14 #include <linux/delay.h>
18 static u32
owl_pll_calculate_mul(struct owl_pll_hw
*pll_hw
, unsigned long rate
)
22 mul
= DIV_ROUND_CLOSEST(rate
, pll_hw
->bfreq
);
23 if (mul
< pll_hw
->min_mul
)
24 mul
= pll_hw
->min_mul
;
25 else if (mul
> pll_hw
->max_mul
)
26 mul
= pll_hw
->max_mul
;
28 return mul
&= mul_mask(pll_hw
);
31 static unsigned long _get_table_rate(const struct clk_pll_table
*table
,
34 const struct clk_pll_table
*clkt
;
36 for (clkt
= table
; clkt
->rate
; clkt
++)
43 static const struct clk_pll_table
*_get_pll_table(
44 const struct clk_pll_table
*table
, unsigned long rate
)
46 const struct clk_pll_table
*clkt
;
48 for (clkt
= table
; clkt
->rate
; clkt
++) {
49 if (clkt
->rate
== rate
) {
52 } else if (clkt
->rate
< rate
)
59 static long owl_pll_round_rate(struct clk_hw
*hw
, unsigned long rate
,
60 unsigned long *parent_rate
)
62 struct owl_pll
*pll
= hw_to_owl_pll(hw
);
63 struct owl_pll_hw
*pll_hw
= &pll
->pll_hw
;
64 const struct clk_pll_table
*clkt
;
68 clkt
= _get_pll_table(pll_hw
->table
, rate
);
73 if (pll_hw
->width
== 0)
76 mul
= owl_pll_calculate_mul(pll_hw
, rate
);
78 return pll_hw
->bfreq
* mul
;
81 static unsigned long owl_pll_recalc_rate(struct clk_hw
*hw
,
82 unsigned long parent_rate
)
84 struct owl_pll
*pll
= hw_to_owl_pll(hw
);
85 struct owl_pll_hw
*pll_hw
= &pll
->pll_hw
;
86 const struct owl_clk_common
*common
= &pll
->common
;
90 regmap_read(common
->regmap
, pll_hw
->reg
, &val
);
92 val
= val
>> pll_hw
->shift
;
93 val
&= mul_mask(pll_hw
);
95 return _get_table_rate(pll_hw
->table
, val
);
99 if (pll_hw
->width
== 0)
100 return pll_hw
->bfreq
;
102 regmap_read(common
->regmap
, pll_hw
->reg
, &val
);
104 val
= val
>> pll_hw
->shift
;
105 val
&= mul_mask(pll_hw
);
107 return pll_hw
->bfreq
* val
;
110 static int owl_pll_is_enabled(struct clk_hw
*hw
)
112 struct owl_pll
*pll
= hw_to_owl_pll(hw
);
113 struct owl_pll_hw
*pll_hw
= &pll
->pll_hw
;
114 const struct owl_clk_common
*common
= &pll
->common
;
117 regmap_read(common
->regmap
, pll_hw
->reg
, ®
);
119 return !!(reg
& BIT(pll_hw
->bit_idx
));
122 static void owl_pll_set(const struct owl_clk_common
*common
,
123 const struct owl_pll_hw
*pll_hw
, bool enable
)
127 regmap_read(common
->regmap
, pll_hw
->reg
, ®
);
130 reg
|= BIT(pll_hw
->bit_idx
);
132 reg
&= ~BIT(pll_hw
->bit_idx
);
134 regmap_write(common
->regmap
, pll_hw
->reg
, reg
);
137 static int owl_pll_enable(struct clk_hw
*hw
)
139 struct owl_pll
*pll
= hw_to_owl_pll(hw
);
140 const struct owl_clk_common
*common
= &pll
->common
;
142 owl_pll_set(common
, &pll
->pll_hw
, true);
147 static void owl_pll_disable(struct clk_hw
*hw
)
149 struct owl_pll
*pll
= hw_to_owl_pll(hw
);
150 const struct owl_clk_common
*common
= &pll
->common
;
152 owl_pll_set(common
, &pll
->pll_hw
, false);
155 static int owl_pll_set_rate(struct clk_hw
*hw
, unsigned long rate
,
156 unsigned long parent_rate
)
158 struct owl_pll
*pll
= hw_to_owl_pll(hw
);
159 struct owl_pll_hw
*pll_hw
= &pll
->pll_hw
;
160 const struct owl_clk_common
*common
= &pll
->common
;
161 const struct clk_pll_table
*clkt
;
164 /* fixed frequency */
165 if (pll_hw
->width
== 0)
169 clkt
= _get_pll_table(pll_hw
->table
, rate
);
172 val
= owl_pll_calculate_mul(pll_hw
, rate
);
175 regmap_read(common
->regmap
, pll_hw
->reg
, ®
);
177 reg
&= ~mul_mask(pll_hw
);
178 reg
|= val
<< pll_hw
->shift
;
180 regmap_write(common
->regmap
, pll_hw
->reg
, reg
);
182 udelay(pll_hw
->delay
);
187 const struct clk_ops owl_pll_ops
= {
188 .enable
= owl_pll_enable
,
189 .disable
= owl_pll_disable
,
190 .is_enabled
= owl_pll_is_enabled
,
191 .round_rate
= owl_pll_round_rate
,
192 .recalc_rate
= owl_pll_recalc_rate
,
193 .set_rate
= owl_pll_set_rate
,