Lines Matching +full:fixed +full:- +full:rate
1 // SPDX-License-Identifier: GPL-2.0
7 * Based on arch/arm/mach-davinci/clock.c
8 * Copyright (C) 2006-2007 Texas Instruments.
9 * Copyright (C) 2008-2009 Deep Root Systems, LLC
12 #include <linux/clk-provider.h>
22 #include <linux/platform_data/clk-davinci-pll.h>
79 * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN
86 /* From OMAP-L138 datasheet table 6-4. Units are micro seconds */
90 * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4
96 * struct davinci_pll_clk - Main PLL clock (aka PLLOUT)
118 unsigned long rate = parent_rate; in davinci_pll_recalc_rate() local
121 mult = readl(pll->base + PLLM) & pll->pllm_mask; in davinci_pll_recalc_rate()
122 rate *= mult + 1; in davinci_pll_recalc_rate()
124 return rate; in davinci_pll_recalc_rate()
131 struct clk_hw *parent = req->best_parent_hw; in davinci_pll_determine_rate()
132 unsigned long parent_rate = req->best_parent_rate; in davinci_pll_determine_rate()
133 unsigned long rate = req->rate; in davinci_pll_determine_rate() local
138 if (rate < req->min_rate) in davinci_pll_determine_rate()
139 return -EINVAL; in davinci_pll_determine_rate()
141 rate = min(rate, req->max_rate); in davinci_pll_determine_rate()
142 mult = rate / parent_rate; in davinci_pll_determine_rate()
147 if (best_rate < req->min_rate) in davinci_pll_determine_rate()
148 return -EINVAL; in davinci_pll_determine_rate()
150 if (mult < pll->pllm_min || mult > pll->pllm_max) in davinci_pll_determine_rate()
151 return -EINVAL; in davinci_pll_determine_rate()
153 req->rate = best_rate; in davinci_pll_determine_rate()
161 for (mult = pll->pllm_min; mult <= pll->pllm_max; mult++) { in davinci_pll_determine_rate()
162 parent_rate = clk_hw_round_rate(parent, rate / mult); in davinci_pll_determine_rate()
164 if (r < req->min_rate) in davinci_pll_determine_rate()
166 if (r > rate || r > req->max_rate) in davinci_pll_determine_rate()
170 req->rate = best_rate; in davinci_pll_determine_rate()
171 req->best_parent_rate = parent_rate; in davinci_pll_determine_rate()
172 if (best_rate == rate) in davinci_pll_determine_rate()
180 static int davinci_pll_set_rate(struct clk_hw *hw, unsigned long rate, in davinci_pll_set_rate() argument
186 mult = rate / parent_rate; in davinci_pll_set_rate()
187 writel(mult - 1, pll->base + PLLM); in davinci_pll_set_rate()
210 unsigned long rate = parent_rate; in dm365_pll_recalc_rate() local
213 mult = readl(pll->base + PLLM) & pll->pllm_mask; in dm365_pll_recalc_rate()
214 rate *= mult * 2; in dm365_pll_recalc_rate()
216 return rate; in dm365_pll_recalc_rate()
225 * davinci_pll_div_register - common *DIV clock implementation
230 * @fixed: if true, the divider is a fixed value
231 * @flags: bitmap of CLK_* flags from clock-provider.h
237 bool fixed, u32 flags) in davinci_pll_div_register() argument
249 return ERR_PTR(-ENOMEM); in davinci_pll_div_register()
251 gate->reg = reg; in davinci_pll_div_register()
252 gate->bit_idx = DIV_ENABLE_SHIFT; in davinci_pll_div_register()
256 ret = -ENOMEM; in davinci_pll_div_register()
260 divider->reg = reg; in davinci_pll_div_register()
261 divider->shift = DIV_RATIO_SHIFT; in davinci_pll_div_register()
262 divider->width = DIV_RATIO_WIDTH; in davinci_pll_div_register()
264 if (fixed) { in davinci_pll_div_register()
265 divider->flags |= CLK_DIVIDER_READ_ONLY; in davinci_pll_div_register()
270 NULL, NULL, ÷r->hw, divider_ops, in davinci_pll_div_register()
271 &gate->hw, &clk_gate_ops, flags); in davinci_pll_div_register()
300 * The PLL has to be switched into bypass mode while we are chaning the rate,
309 struct clk_hw *hw = __clk_get_hw(cnd->clk); in davinci_pllen_rate_change()
313 ctrl = readl(pll->base + PLLCTL); in davinci_pllen_rate_change()
318 writel(ctrl, pll->base + PLLCTL); in davinci_pllen_rate_change()
324 writel(ctrl, pll->base + PLLCTL); in davinci_pllen_rate_change()
330 writel(ctrl, pll->base + PLLCTL); in davinci_pllen_rate_change()
336 writel(ctrl, pll->base + PLLCTL); in davinci_pllen_rate_change()
347 * davinci_pll_clk_register - Register a PLL clock
349 * @info: The device-specific clock info
352 * @cfgchip: CFGCHIP syscon regmap for info->unlock_reg or NULL
358 * - OSCIN is the parent clock (on secondary PLL, may come from primary PLL)
359 * - PREDIV and POSTDIV are optional (depends on the PLL controller)
360 * - PLL is the PLL output (aka PLLOUT)
361 * - PLLEN is the bypass multiplexer
385 if (info->flags & PLL_HAS_CLKMODE) { in davinci_pll_clk_register()
403 if (info->flags & PLL_HAS_PREDIV) { in davinci_pll_clk_register()
404 bool fixed = info->flags & PLL_PREDIV_FIXED_DIV; in davinci_pll_clk_register() local
407 snprintf(prediv_name, MAX_NAME_SIZE, "%s_prediv", info->name); in davinci_pll_clk_register()
409 if (info->flags & PLL_PREDIV_ALWAYS_ENABLED) in davinci_pll_clk_register()
413 if (info->flags & PLL_PREDIV_FIXED8) in davinci_pll_clk_register()
418 parent_name, base + PREDIV, fixed, flags); in davinci_pll_clk_register()
428 if (info->unlock_reg) { in davinci_pll_clk_register()
433 regmap_write_bits(cfgchip, info->unlock_reg, in davinci_pll_clk_register()
434 info->unlock_mask, 0); in davinci_pll_clk_register()
439 ret = -ENOMEM; in davinci_pll_clk_register()
443 snprintf(pllout_name, MAX_NAME_SIZE, "%s_pllout", info->name); in davinci_pll_clk_register()
446 if (info->flags & PLL_PLLM_2X) in davinci_pll_clk_register()
454 if (info->flags & PLL_HAS_PREDIV) in davinci_pll_clk_register()
457 pllout->hw.init = &init; in davinci_pll_clk_register()
458 pllout->base = base; in davinci_pll_clk_register()
459 pllout->pllm_mask = info->pllm_mask; in davinci_pll_clk_register()
460 pllout->pllm_min = info->pllm_min; in davinci_pll_clk_register()
461 pllout->pllm_max = info->pllm_max; in davinci_pll_clk_register()
463 pllout_clk = clk_register(dev, &pllout->hw); in davinci_pll_clk_register()
469 clk_hw_set_rate_range(&pllout->hw, info->pllout_min_rate, in davinci_pll_clk_register()
470 info->pllout_max_rate); in davinci_pll_clk_register()
474 if (info->flags & PLL_HAS_POSTDIV) { in davinci_pll_clk_register()
475 bool fixed = info->flags & PLL_POSTDIV_FIXED_DIV; in davinci_pll_clk_register() local
478 snprintf(postdiv_name, MAX_NAME_SIZE, "%s_postdiv", info->name); in davinci_pll_clk_register()
480 if (info->flags & PLL_POSTDIV_ALWAYS_ENABLED) in davinci_pll_clk_register()
484 parent_name, base + POSTDIV, fixed, flags); in davinci_pll_clk_register()
495 ret = -ENOMEM; in davinci_pll_clk_register()
499 snprintf(pllen_name, MAX_NAME_SIZE, "%s_pllen", info->name); in davinci_pll_clk_register()
507 pllen->hw.init = &init; in davinci_pll_clk_register()
508 pllen->base = base; in davinci_pll_clk_register()
510 pllen_clk = clk_register(dev, &pllen->hw); in davinci_pll_clk_register()
537 * davinci_pll_auxclk_register - Register bypass clock (AUXCLK)
551 * davinci_pll_sysclkbp_clk_register - Register bypass divider clock (SYSCLKBP)
566 * davinci_pll_obsclk_register - Register oscillator divider clock (OBSCLK)
585 return ERR_PTR(-ENOMEM); in davinci_pll_obsclk_register()
587 mux->reg = base + OCSEL; in davinci_pll_obsclk_register()
588 mux->table = info->table; in davinci_pll_obsclk_register()
589 mux->mask = info->ocsrc_mask; in davinci_pll_obsclk_register()
593 ret = -ENOMEM; in davinci_pll_obsclk_register()
597 gate->reg = base + CKEN; in davinci_pll_obsclk_register()
598 gate->bit_idx = CKEN_OBSCLK_SHIFT; in davinci_pll_obsclk_register()
602 ret = -ENOMEM; in davinci_pll_obsclk_register()
606 divider->reg = base + OSCDIV; in davinci_pll_obsclk_register()
607 divider->shift = DIV_RATIO_SHIFT; in davinci_pll_obsclk_register()
608 divider->width = DIV_RATIO_WIDTH; in davinci_pll_obsclk_register()
615 clk = clk_register_composite(dev, info->name, info->parent_names, in davinci_pll_obsclk_register()
616 info->num_parents, in davinci_pll_obsclk_register()
617 &mux->hw, &clk_mux_ops, in davinci_pll_obsclk_register()
618 ÷r->hw, &clk_divider_ops, in davinci_pll_obsclk_register()
619 &gate->hw, &clk_gate_ops, 0); in davinci_pll_obsclk_register()
638 /* The PLL SYSCLKn clocks have a mechanism for synchronizing rate changes. */
643 struct clk_hw *hw = __clk_get_hw(clk_get_parent(cnd->clk)); in davinci_pll_sysclk_rate_change()
650 pllcmd = readl(pll->base + PLLCMD); in davinci_pll_sysclk_rate_change()
652 writel(pllcmd, pll->base + PLLCMD); in davinci_pll_sysclk_rate_change()
657 pllstat = readl(pll->base + PLLSTAT); in davinci_pll_sysclk_rate_change()
670 * davinci_pll_sysclk_register - Register divider clocks (SYSCLKn)
689 if (info->id < 4) in davinci_pll_sysclk_register()
690 reg = PLLDIV1 + 4 * (info->id - 1); in davinci_pll_sysclk_register()
692 reg = PLLDIV4 + 4 * (info->id - 4); in davinci_pll_sysclk_register()
696 return ERR_PTR(-ENOMEM); in davinci_pll_sysclk_register()
698 gate->reg = base + reg; in davinci_pll_sysclk_register()
699 gate->bit_idx = DIV_ENABLE_SHIFT; in davinci_pll_sysclk_register()
703 ret = -ENOMEM; in davinci_pll_sysclk_register()
707 divider->reg = base + reg; in davinci_pll_sysclk_register()
708 divider->shift = DIV_RATIO_SHIFT; in davinci_pll_sysclk_register()
709 divider->width = info->ratio_width; in davinci_pll_sysclk_register()
710 divider->flags = 0; in davinci_pll_sysclk_register()
712 if (info->flags & SYSCLK_FIXED_DIV) { in davinci_pll_sysclk_register()
713 divider->flags |= CLK_DIVIDER_READ_ONLY; in davinci_pll_sysclk_register()
717 /* Only the ARM clock can change the parent PLL rate */ in davinci_pll_sysclk_register()
718 if (info->flags & SYSCLK_ARM_RATE) in davinci_pll_sysclk_register()
721 if (info->flags & SYSCLK_ALWAYS_ENABLED) in davinci_pll_sysclk_register()
724 clk = clk_register_composite(dev, info->name, &info->parent_name, 1, in davinci_pll_sysclk_register()
725 NULL, NULL, ÷r->hw, divider_ops, in davinci_pll_sysclk_register()
726 &gate->hw, &clk_gate_ops, flags); in davinci_pll_sysclk_register()
756 if (info->flags & PLL_HAS_CLKMODE) in of_davinci_pll_init()
763 dev_err(dev, "failed to register %s\n", info->name); in of_davinci_pll_init()
782 return -ENOMEM; in of_davinci_pll_init()
789 return -ENOMEM; in of_davinci_pll_init()
792 clk_data->clks = clks; in of_davinci_pll_init()
793 clk_data->clk_num = n_clks; in of_davinci_pll_init()
796 clks[i] = ERR_PTR(-ENOENT); in of_davinci_pll_init()
802 (*div_info)->name, PTR_ERR(clk)); in of_davinci_pll_init()
804 clks[(*div_info)->id] = clk; in of_davinci_pll_init()
814 snprintf(child_name, MAX_NAME_SIZE, "%s_auxclk", info->name); in of_davinci_pll_init()
830 clk = ERR_PTR(-EINVAL); in of_davinci_pll_init()
857 if (dev->of_node) in davinci_pll_get_pdata()
858 pdata->cfgchip = in davinci_pll_get_pdata()
859 syscon_regmap_lookup_by_compatible("ti,da830-cfgchip"); in davinci_pll_get_pdata()
866 CLK_OF_DECLARE(da850_pll0, "ti,da850-pll0", of_da850_pll0_init);
871 { .compatible = "ti,da850-pll1", .data = of_da850_pll1_init },
878 { .name = "da830-pll", .driver_data = (kernel_ulong_t)da830_pll_init },
881 { .name = "da850-pll0", .driver_data = (kernel_ulong_t)da850_pll0_init },
882 { .name = "da850-pll1", .driver_data = (kernel_ulong_t)da850_pll1_init },
892 struct device *dev = &pdev->dev; in davinci_pll_probe()
898 if (!pll_init && pdev->id_entry) in davinci_pll_probe()
899 pll_init = (void *)pdev->id_entry->driver_data; in davinci_pll_probe()
903 return -EINVAL; in davinci_pll_probe()
909 return -EINVAL; in davinci_pll_probe()
916 return pll_init(dev, base, pdata->cfgchip); in davinci_pll_probe()
922 .name = "davinci-pll-clk",
982 regset->regs = davinci_pll_regs; in davinci_pll_debug_init()
983 regset->nregs = ARRAY_SIZE(davinci_pll_regs); in davinci_pll_debug_init()
984 regset->base = pll->base; in davinci_pll_debug_init()