Lines Matching +full:gated +full:- +full:fixed +full:- +full:clock
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Clock implementation for VIA/Wondermedia SoC's
13 #include <linux/clk-provider.h>
53 of_find_compatible_node(NULL, NULL, "via,vt8500-pmc"); in vtwm_set_pmc_base()
81 spin_lock_irqsave(cdev->lock, flags); in vt8500_dclk_enable()
83 en_val = readl(cdev->en_reg); in vt8500_dclk_enable()
84 en_val |= BIT(cdev->en_bit); in vt8500_dclk_enable()
85 writel(en_val, cdev->en_reg); in vt8500_dclk_enable()
87 spin_unlock_irqrestore(cdev->lock, flags); in vt8500_dclk_enable()
97 spin_lock_irqsave(cdev->lock, flags); in vt8500_dclk_disable()
99 en_val = readl(cdev->en_reg); in vt8500_dclk_disable()
100 en_val &= ~BIT(cdev->en_bit); in vt8500_dclk_disable()
101 writel(en_val, cdev->en_reg); in vt8500_dclk_disable()
103 spin_unlock_irqrestore(cdev->lock, flags); in vt8500_dclk_disable()
109 u32 en_val = (readl(cdev->en_reg) & BIT(cdev->en_bit)); in vt8500_dclk_is_enabled()
118 u32 div = readl(cdev->div_reg) & cdev->div_mask; in vt8500_dclk_recalc_rate()
121 if ((cdev->div_mask == 0x3F) && (div & BIT(5))) in vt8500_dclk_recalc_rate()
126 div = (cdev->div_mask + 1); in vt8500_dclk_recalc_rate()
148 * when >31 to use the fixed predivisor in vt8500_dclk_round_rate()
150 if ((cdev->div_mask == 0x3F) && (divisor > 31)) { in vt8500_dclk_round_rate()
169 if (divisor == cdev->div_mask + 1) in vt8500_dclk_set_rate()
173 if ((cdev->div_mask == 0x3F) && (divisor > 31)) { in vt8500_dclk_set_rate()
175 * Bit 5 is a fixed /64 predivisor. If the requested divisor in vt8500_dclk_set_rate()
176 * is >31 then correct for the fixed divisor being required. in vt8500_dclk_set_rate()
181 if (divisor > cdev->div_mask) { in vt8500_dclk_set_rate()
182 pr_err("%s: invalid divisor for clock\n", __func__); in vt8500_dclk_set_rate()
183 return -EINVAL; in vt8500_dclk_set_rate()
186 spin_lock_irqsave(cdev->lock, flags); in vt8500_dclk_set_rate()
189 writel(divisor, cdev->div_reg); in vt8500_dclk_set_rate()
192 spin_unlock_irqrestore(cdev->lock, flags); in vt8500_dclk_set_rate()
228 const char *clk_name = node->name; in vtwm_device_clk_init()
241 dev_clk->lock = &_lock; in vtwm_device_clk_init()
243 rc = of_property_read_u32(node, "enable-reg", &en_reg); in vtwm_device_clk_init()
245 dev_clk->en_reg = pmc_base + en_reg; in vtwm_device_clk_init()
246 rc = of_property_read_u32(node, "enable-bit", &dev_clk->en_bit); in vtwm_device_clk_init()
248 pr_err("%s: enable-bit property required for gated clock\n", in vtwm_device_clk_init()
255 rc = of_property_read_u32(node, "divisor-reg", &div_reg); in vtwm_device_clk_init()
257 dev_clk->div_reg = pmc_base + div_reg; in vtwm_device_clk_init()
262 dev_clk->div_mask = 0x1f; in vtwm_device_clk_init()
264 of_property_read_u32(node, "divisor-mask", &dev_clk->div_mask); in vtwm_device_clk_init()
268 of_property_read_string(node, "clock-output-names", &clk_name); in vtwm_device_clk_init()
281 pr_err("%s: Invalid clock description in device tree\n", in vtwm_device_clk_init()
293 dev_clk->hw.init = &init; in vtwm_device_clk_init()
295 hw = &dev_clk->hw; in vtwm_device_clk_init()
304 CLK_OF_DECLARE(vt8500_device, "via,vt8500-device-clock", vtwm_device_clk_init);
306 /* PLL clock related functions */
338 ((f << 24) | ((m - 1) << 16) | ((d1 - 1) << 8) | d2)
348 ((((m / 2) - 1) << 16) | ((d1 - 1) << 8) | d2)
360 return -EINVAL; in vt8500_find_pll_bits()
396 return -EINVAL; in wm8650_find_pll_bits()
405 for (*divisor1 = 5; *divisor1 >= 3; (*divisor1)--) { in wm8650_find_pll_bits()
418 return -EINVAL; in wm8650_find_pll_bits()
427 /* calculate frequency (MHz) after pre-divisor */ in wm8750_get_filter()
459 best_err = (unsigned long)-1; in wm8750_find_pll_bits()
462 for (div1 = 1; div1 >= 0; div1--) in wm8750_find_pll_bits()
463 for (div2 = 7; div2 >= 0; div2--) in wm8750_find_pll_bits()
469 rate_err = rate - tclk; in wm8750_find_pll_bits()
486 if (best_err == (unsigned long)-1) { in wm8750_find_pll_bits()
488 return -EINVAL; in wm8750_find_pll_bits()
493 rate - best_err); in wm8750_find_pll_bits()
507 best_err = (unsigned long)-1; in wm8850_find_pll_bits()
510 for (div1 = 1; div1 >= 0; div1--) in wm8850_find_pll_bits()
511 for (div2 = 3; div2 >= 0; div2--) in wm8850_find_pll_bits()
518 rate_err = rate - tclk; in wm8850_find_pll_bits()
534 if (best_err == (unsigned long)-1) { in wm8850_find_pll_bits()
536 return -EINVAL; in wm8850_find_pll_bits()
541 rate - best_err); in wm8850_find_pll_bits()
557 switch (pll->type) { in vtwm_pll_set_rate()
580 ret = -EINVAL; in vtwm_pll_set_rate()
586 spin_lock_irqsave(pll->lock, flags); in vtwm_pll_set_rate()
589 writel(pll_val, pll->reg); in vtwm_pll_set_rate()
592 spin_unlock_irqrestore(pll->lock, flags); in vtwm_pll_set_rate()
605 switch (pll->type) { in vtwm_pll_round_rate()
627 ret = -EINVAL; in vtwm_pll_round_rate()
640 u32 pll_val = readl(pll->reg); in vtwm_pll_recalc_rate()
643 switch (pll->type) { in vtwm_pll_recalc_rate()
678 const char *clk_name = node->name; in vtwm_pll_clk_init()
694 pll_clk->reg = pmc_base + reg; in vtwm_pll_clk_init()
695 pll_clk->lock = &_lock; in vtwm_pll_clk_init()
696 pll_clk->type = pll_type; in vtwm_pll_clk_init()
698 of_property_read_string(node, "clock-output-names", &clk_name); in vtwm_pll_clk_init()
707 pll_clk->hw.init = &init; in vtwm_pll_clk_init()
709 hw = &pll_clk->hw; in vtwm_pll_clk_init()
710 rc = clk_hw_register(NULL, &pll_clk->hw); in vtwm_pll_clk_init()
726 CLK_OF_DECLARE(vt8500_pll, "via,vt8500-pll-clock", vt8500_pll_init);
732 CLK_OF_DECLARE(wm8650_pll, "wm,wm8650-pll-clock", wm8650_pll_init);
738 CLK_OF_DECLARE(wm8750_pll, "wm,wm8750-pll-clock", wm8750_pll_init);
744 CLK_OF_DECLARE(wm8850_pll, "wm,wm8850-pll-clock", wm8850_pll_init);