18 #include <linux/slab.h>
19 #include <linux/bitops.h>
42 #define PLL_TYPE_VT8500 0
43 #define PLL_TYPE_WM8650 1
54 #define to_clk_device(_hw) container_of(_hw, struct clk_device, hw)
56 #define VT8500_PMC_BUSY_MASK 0x18
58 static void vt8500_pmc_wait_busy(
void)
64 static int vt8500_dclk_enable(
struct clk_hw *
hw)
68 unsigned long flags = 0;
76 spin_unlock_irqrestore(cdev->
lock, flags);
80 static void vt8500_dclk_disable(
struct clk_hw *
hw)
84 unsigned long flags = 0;
92 spin_unlock_irqrestore(cdev->
lock, flags);
95 static int vt8500_dclk_is_enabled(
struct clk_hw *
hw)
100 return en_val ? 1 : 0;
103 static unsigned long vt8500_dclk_recalc_rate(
struct clk_hw *
hw,
104 unsigned long parent_rate)
111 div = 64 * (div & 0x1f);
117 return parent_rate /
div;
120 static long vt8500_dclk_round_rate(
struct clk_hw *hw,
unsigned long rate,
121 unsigned long *
prate)
128 static int vt8500_dclk_set_rate(
struct clk_hw *hw,
unsigned long rate,
129 unsigned long parent_rate)
133 unsigned long flags = 0;
139 pr_err(
"%s: invalid divisor for clock\n", __func__);
145 vt8500_pmc_wait_busy();
147 vt8500_pmc_wait_busy();
155 static const struct clk_ops vt8500_gated_clk_ops = {
156 .enable = vt8500_dclk_enable,
157 .disable = vt8500_dclk_disable,
158 .is_enabled = vt8500_dclk_is_enabled,
161 static const struct clk_ops vt8500_divisor_clk_ops = {
162 .round_rate = vt8500_dclk_round_rate,
163 .set_rate = vt8500_dclk_set_rate,
164 .recalc_rate = vt8500_dclk_recalc_rate,
167 static const struct clk_ops vt8500_gated_divisor_clk_ops = {
168 .enable = vt8500_dclk_enable,
169 .disable = vt8500_dclk_disable,
170 .is_enabled = vt8500_dclk_is_enabled,
171 .round_rate = vt8500_dclk_round_rate,
172 .set_rate = vt8500_dclk_set_rate,
173 .recalc_rate = vt8500_dclk_recalc_rate,
176 #define CLK_INIT_GATED BIT(0)
177 #define CLK_INIT_DIVISOR BIT(1)
178 #define CLK_INIT_GATED_DIVISOR (CLK_INIT_DIVISOR | CLK_INIT_GATED)
185 const char *clk_name = node->
name;
186 const char *parent_name;
187 struct clk_init_data init;
189 int clk_init_flags = 0;
191 dev_clk = kzalloc(
sizeof(*dev_clk),
GFP_KERNEL);
195 dev_clk->
lock = &_lock;
197 rc = of_property_read_u32(node,
"enable-reg", &en_reg);
199 dev_clk->
en_reg = pmc_base + en_reg;
200 rc = of_property_read_u32(node,
"enable-bit", &dev_clk->
en_bit);
202 pr_err(
"%s: enable-bit property required for gated clock\n",
209 rc = of_property_read_u32(node,
"divisor-reg", &div_reg);
211 dev_clk->
div_reg = pmc_base + div_reg;
218 of_property_read_u32(node,
"divisor-mask", &dev_clk->
div_mask);
224 switch (clk_init_flags) {
226 init.ops = &vt8500_gated_clk_ops;
229 init.ops = &vt8500_divisor_clk_ops;
232 init.ops = &vt8500_gated_divisor_clk_ops;
235 pr_err(
"%s: Invalid clock description in device tree\n",
241 init.name = clk_name;
243 parent_name = of_clk_get_parent_name(node, 0);
244 init.parent_names = &parent_name;
245 init.num_parents = 1;
254 rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
261 #define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
264 #define VT8500_PLL_MUL(x) ((x & 0x1F) << 1)
265 #define VT8500_PLL_DIV(x) ((x & 0x100) ? 1 : 2)
267 #define VT8500_BITS_TO_FREQ(r, m, d) \
270 #define VT8500_BITS_TO_VAL(m, d) \
271 ((d == 2 ? 0 : 0x100) | ((m >> 1) & 0x1F))
274 #define WM8650_PLL_MUL(x) (x & 0x3FF)
275 #define WM8650_PLL_DIV(x) (((x >> 10) & 7) * (1 << ((x >> 13) & 3)))
277 #define WM8650_BITS_TO_FREQ(r, m, d1, d2) \
278 (r * m / (d1 * (1 << d2)))
280 #define WM8650_BITS_TO_VAL(m, d1, d2) \
281 ((d2 << 13) | (d1 << 10) | (m & 0x3FF))
284 static void vt8500_find_pll_bits(
unsigned long rate,
unsigned long parent_rate,
285 u32 *multiplier,
u32 *prediv)
290 if ((rate < parent_rate * 4) || (rate > parent_rate * 62)) {
291 pr_err(
"%s: requested rate out of range\n", __func__);
296 if (rate <= parent_rate * 31)
302 *multiplier = rate / (parent_rate / *prediv);
303 tclk = (parent_rate / *prediv) * *multiplier;
306 pr_warn(
"%s: requested rate %lu, found rate %lu\n", __func__,
310 static void wm8650_find_pll_bits(
unsigned long rate,
unsigned long parent_rate,
311 u32 *multiplier,
u32 *divisor1,
u32 *divisor2)
314 u32 best_mul, best_div1, best_div2;
315 unsigned long tclk, rate_err, best_err;
317 best_err = (
unsigned long)-1;
320 for (div1 = 5; div1 >= 3; div1--)
321 for (div2 = 3; div2 >= 0; div2--)
322 for (mul = 3; mul <= 1023; mul++) {
323 tclk = parent_rate * mul / (div1 * (1 <<
div2));
327 rate_err = rate - tclk;
335 if (rate_err < best_err) {
344 pr_warn(
"%s: requested rate %lu, found rate %lu\n", __func__, rate,
351 static int vtwm_pll_set_rate(
struct clk_hw *hw,
unsigned long rate,
352 unsigned long parent_rate)
357 unsigned long flags = 0;
363 vt8500_find_pll_bits(rate, parent_rate, &mul, &div1);
367 wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
371 pr_err(
"%s: invalid pll type\n", __func__);
377 vt8500_pmc_wait_busy();
379 vt8500_pmc_wait_busy();
381 spin_unlock_irqrestore(pll->
lock, flags);
386 static long vtwm_pll_round_rate(
struct clk_hw *hw,
unsigned long rate,
387 unsigned long *
prate)
395 vt8500_find_pll_bits(rate, *prate, &mul, &div1);
399 wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2);
409 static unsigned long vtwm_pll_recalc_rate(
struct clk_hw *hw,
410 unsigned long parent_rate)
414 unsigned long pll_freq;
433 .round_rate = vtwm_pll_round_rate,
434 .set_rate = vtwm_pll_set_rate,
435 .recalc_rate = vtwm_pll_recalc_rate,
443 const char *clk_name = node->
name;
444 const char *parent_name;
445 struct clk_init_data
init;
448 rc = of_property_read_u32(node,
"reg", ®);
452 pll_clk = kzalloc(
sizeof(*pll_clk),
GFP_KERNEL);
456 pll_clk->
reg = pmc_base +
reg;
457 pll_clk->
lock = &_lock;
458 pll_clk->
type = pll_type;
462 init.name = clk_name;
465 parent_name = of_clk_get_parent_name(node, 0);
466 init.parent_names = &parent_name;
467 init.num_parents = 1;
476 rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
494 { .compatible =
"fixed-clock", .data = of_fixed_clk_setup, },
495 { .compatible =
"via,vt8500-pll-clock", .data = vt8500_pll_init, },
496 { .compatible =
"wm,wm8650-pll-clock", .data = wm8650_pll_init, },
497 { .compatible =
"via,vt8500-device-clock",
498 .data = vtwm_device_clk_init, },
509 of_clk_init(clk_match);