Lines Matching +full:clock +full:- +full:mult

1 // SPDX-License-Identifier: GPL-2.0
3 * PLL clock driver for TI Davinci SoCs
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>
78 * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN
85 /* From OMAP-L138 datasheet table 6-4. Units are micro seconds */
89 * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4
95 * struct davinci_pll_clk - Main PLL clock (aka PLLOUT)
118 u32 mult; in davinci_pll_recalc_rate() local
120 mult = readl(pll->base + PLLM) & pll->pllm_mask; in davinci_pll_recalc_rate()
121 rate *= mult + 1; in davinci_pll_recalc_rate()
130 struct clk_hw *parent = req->best_parent_hw; in davinci_pll_determine_rate()
131 unsigned long parent_rate = req->best_parent_rate; in davinci_pll_determine_rate()
132 unsigned long rate = req->rate; in davinci_pll_determine_rate()
134 u32 mult; in davinci_pll_determine_rate() local
137 if (rate < req->min_rate) in davinci_pll_determine_rate()
138 return -EINVAL; in davinci_pll_determine_rate()
140 rate = min(rate, req->max_rate); in davinci_pll_determine_rate()
141 mult = rate / parent_rate; in davinci_pll_determine_rate()
142 best_rate = parent_rate * mult; in davinci_pll_determine_rate()
146 if (best_rate < req->min_rate) in davinci_pll_determine_rate()
147 return -EINVAL; in davinci_pll_determine_rate()
149 if (mult < pll->pllm_min || mult > pll->pllm_max) in davinci_pll_determine_rate()
150 return -EINVAL; in davinci_pll_determine_rate()
152 req->rate = best_rate; in davinci_pll_determine_rate()
157 /* see if the PREDIV clock can help us */ in davinci_pll_determine_rate()
160 for (mult = pll->pllm_min; mult <= pll->pllm_max; mult++) { in davinci_pll_determine_rate()
161 parent_rate = clk_hw_round_rate(parent, rate / mult); in davinci_pll_determine_rate()
162 r = parent_rate * mult; in davinci_pll_determine_rate()
163 if (r < req->min_rate) in davinci_pll_determine_rate()
165 if (r > rate || r > req->max_rate) in davinci_pll_determine_rate()
169 req->rate = best_rate; in davinci_pll_determine_rate()
170 req->best_parent_rate = parent_rate; in davinci_pll_determine_rate()
183 u32 mult; in davinci_pll_set_rate() local
185 mult = rate / parent_rate; in davinci_pll_set_rate()
186 writel(mult - 1, pll->base + PLLM); in davinci_pll_set_rate()
210 u32 mult; in dm365_pll_recalc_rate() local
212 mult = readl(pll->base + PLLM) & pll->pllm_mask; in dm365_pll_recalc_rate()
213 rate *= mult * 2; in dm365_pll_recalc_rate()
224 * davinci_pll_div_register - common *DIV clock implementation
226 * @name: the clock name
227 * @parent_name: the parent clock name
230 * @flags: bitmap of CLK_* flags from clock-provider.h
248 return ERR_PTR(-ENOMEM); in davinci_pll_div_register()
250 gate->reg = reg; in davinci_pll_div_register()
251 gate->bit_idx = DIV_ENABLE_SHIFT; in davinci_pll_div_register()
255 ret = -ENOMEM; in davinci_pll_div_register()
259 divider->reg = reg; in davinci_pll_div_register()
260 divider->shift = DIV_RATIO_SHIFT; in davinci_pll_div_register()
261 divider->width = DIV_RATIO_WIDTH; in davinci_pll_div_register()
264 divider->flags |= CLK_DIVIDER_READ_ONLY; in davinci_pll_div_register()
269 NULL, NULL, &divider->hw, divider_ops, in davinci_pll_div_register()
270 &gate->hw, &clk_gate_ops, flags); in davinci_pll_div_register()
295 /* this clocks just uses the clock notification feature */
300 * so we do that on the PLLEN clock since it is the end of the line. This will
308 struct clk_hw *hw = __clk_get_hw(cnd->clk); in davinci_pllen_rate_change()
312 ctrl = readl(pll->base + PLLCTL); in davinci_pllen_rate_change()
317 writel(ctrl, pll->base + PLLCTL); in davinci_pllen_rate_change()
323 writel(ctrl, pll->base + PLLCTL); in davinci_pllen_rate_change()
329 writel(ctrl, pll->base + PLLCTL); in davinci_pllen_rate_change()
335 writel(ctrl, pll->base + PLLCTL); in davinci_pllen_rate_change()
346 * davinci_pll_clk_register - Register a PLL clock
348 * @info: The device-specific clock info
349 * @parent_name: The parent clock name
351 * @cfgchip: CFGCHIP syscon regmap for info->unlock_reg or NULL
357 * - OSCIN is the parent clock (on secondary PLL, may come from primary PLL)
358 * - PREDIV and POSTDIV are optional (depends on the PLL controller)
359 * - PLL is the PLL output (aka PLLOUT)
360 * - PLLEN is the bypass multiplexer
362 * Returns: The PLLOUT clock or a negative error code.
384 if (info->flags & PLL_HAS_CLKMODE) { in davinci_pll_clk_register()
387 * We register a clock named "oscin" that serves as the internal in davinci_pll_clk_register()
388 * "input clock" domain shared by both PLLs (if there are 2) in davinci_pll_clk_register()
389 * and will be the parent clock to the AUXCLK, SYSCLKBP and in davinci_pll_clk_register()
402 if (info->flags & PLL_HAS_PREDIV) { in davinci_pll_clk_register()
403 bool fixed = info->flags & PLL_PREDIV_FIXED_DIV; in davinci_pll_clk_register()
406 snprintf(prediv_name, MAX_NAME_SIZE, "%s_prediv", info->name); in davinci_pll_clk_register()
408 if (info->flags & PLL_PREDIV_ALWAYS_ENABLED) in davinci_pll_clk_register()
412 if (info->flags & PLL_PREDIV_FIXED8) in davinci_pll_clk_register()
427 if (info->unlock_reg) { in davinci_pll_clk_register()
432 regmap_write_bits(cfgchip, info->unlock_reg, in davinci_pll_clk_register()
433 info->unlock_mask, 0); in davinci_pll_clk_register()
438 ret = -ENOMEM; in davinci_pll_clk_register()
442 snprintf(pllout_name, MAX_NAME_SIZE, "%s_pllout", info->name); in davinci_pll_clk_register()
445 if (info->flags & PLL_PLLM_2X) in davinci_pll_clk_register()
453 if (info->flags & PLL_HAS_PREDIV) in davinci_pll_clk_register()
456 pllout->hw.init = &init; in davinci_pll_clk_register()
457 pllout->base = base; in davinci_pll_clk_register()
458 pllout->pllm_mask = info->pllm_mask; in davinci_pll_clk_register()
459 pllout->pllm_min = info->pllm_min; in davinci_pll_clk_register()
460 pllout->pllm_max = info->pllm_max; in davinci_pll_clk_register()
462 pllout_clk = clk_register(dev, &pllout->hw); in davinci_pll_clk_register()
468 clk_hw_set_rate_range(&pllout->hw, info->pllout_min_rate, in davinci_pll_clk_register()
469 info->pllout_max_rate); in davinci_pll_clk_register()
473 if (info->flags & PLL_HAS_POSTDIV) { in davinci_pll_clk_register()
474 bool fixed = info->flags & PLL_POSTDIV_FIXED_DIV; in davinci_pll_clk_register()
477 snprintf(postdiv_name, MAX_NAME_SIZE, "%s_postdiv", info->name); in davinci_pll_clk_register()
479 if (info->flags & PLL_POSTDIV_ALWAYS_ENABLED) in davinci_pll_clk_register()
494 ret = -ENOMEM; in davinci_pll_clk_register()
498 snprintf(pllen_name, MAX_NAME_SIZE, "%s_pllen", info->name); in davinci_pll_clk_register()
506 pllen->hw.init = &init; in davinci_pll_clk_register()
507 pllen->base = base; in davinci_pll_clk_register()
509 pllen_clk = clk_register(dev, &pllen->hw); in davinci_pll_clk_register()
536 * davinci_pll_auxclk_register - Register bypass clock (AUXCLK)
538 * @name: The clock name
550 * davinci_pll_sysclkbp_clk_register - Register bypass divider clock (SYSCLKBP)
552 * @name: The clock name
565 * davinci_pll_obsclk_register - Register oscillator divider clock (OBSCLK)
567 * @info: The clock info
584 return ERR_PTR(-ENOMEM); in davinci_pll_obsclk_register()
586 mux->reg = base + OCSEL; in davinci_pll_obsclk_register()
587 mux->table = info->table; in davinci_pll_obsclk_register()
588 mux->mask = info->ocsrc_mask; in davinci_pll_obsclk_register()
592 ret = -ENOMEM; in davinci_pll_obsclk_register()
596 gate->reg = base + CKEN; in davinci_pll_obsclk_register()
597 gate->bit_idx = CKEN_OBSCLK_SHIFT; in davinci_pll_obsclk_register()
601 ret = -ENOMEM; in davinci_pll_obsclk_register()
605 divider->reg = base + OSCDIV; in davinci_pll_obsclk_register()
606 divider->shift = DIV_RATIO_SHIFT; in davinci_pll_obsclk_register()
607 divider->width = DIV_RATIO_WIDTH; in davinci_pll_obsclk_register()
614 clk = clk_register_composite(dev, info->name, info->parent_names, in davinci_pll_obsclk_register()
615 info->num_parents, in davinci_pll_obsclk_register()
616 &mux->hw, &clk_mux_ops, in davinci_pll_obsclk_register()
617 &divider->hw, &clk_divider_ops, in davinci_pll_obsclk_register()
618 &gate->hw, &clk_gate_ops, 0); in davinci_pll_obsclk_register()
642 struct clk_hw *hw = __clk_get_hw(clk_get_parent(cnd->clk)); in davinci_pll_sysclk_rate_change()
649 pllcmd = readl(pll->base + PLLCMD); in davinci_pll_sysclk_rate_change()
651 writel(pllcmd, pll->base + PLLCMD); in davinci_pll_sysclk_rate_change()
656 pllstat = readl(pll->base + PLLSTAT); in davinci_pll_sysclk_rate_change()
669 * davinci_pll_sysclk_register - Register divider clocks (SYSCLKn)
671 * @info: The clock info
688 if (info->id < 4) in davinci_pll_sysclk_register()
689 reg = PLLDIV1 + 4 * (info->id - 1); in davinci_pll_sysclk_register()
691 reg = PLLDIV4 + 4 * (info->id - 4); in davinci_pll_sysclk_register()
695 return ERR_PTR(-ENOMEM); in davinci_pll_sysclk_register()
697 gate->reg = base + reg; in davinci_pll_sysclk_register()
698 gate->bit_idx = DIV_ENABLE_SHIFT; in davinci_pll_sysclk_register()
702 ret = -ENOMEM; in davinci_pll_sysclk_register()
706 divider->reg = base + reg; in davinci_pll_sysclk_register()
707 divider->shift = DIV_RATIO_SHIFT; in davinci_pll_sysclk_register()
708 divider->width = info->ratio_width; in davinci_pll_sysclk_register()
709 divider->flags = 0; in davinci_pll_sysclk_register()
711 if (info->flags & SYSCLK_FIXED_DIV) { in davinci_pll_sysclk_register()
712 divider->flags |= CLK_DIVIDER_READ_ONLY; in davinci_pll_sysclk_register()
716 /* Only the ARM clock can change the parent PLL rate */ in davinci_pll_sysclk_register()
717 if (info->flags & SYSCLK_ARM_RATE) in davinci_pll_sysclk_register()
720 if (info->flags & SYSCLK_ALWAYS_ENABLED) in davinci_pll_sysclk_register()
723 clk = clk_register_composite(dev, info->name, &info->parent_name, 1, in davinci_pll_sysclk_register()
724 NULL, NULL, &divider->hw, divider_ops, in davinci_pll_sysclk_register()
725 &gate->hw, &clk_gate_ops, flags); in davinci_pll_sysclk_register()
755 if (info->flags & PLL_HAS_CLKMODE) in of_davinci_pll_init()
762 dev_err(dev, "failed to register %s\n", info->name); in of_davinci_pll_init()
781 return -ENOMEM; in of_davinci_pll_init()
788 return -ENOMEM; in of_davinci_pll_init()
791 clk_data->clks = clks; in of_davinci_pll_init()
792 clk_data->clk_num = n_clks; in of_davinci_pll_init()
795 clks[i] = ERR_PTR(-ENOENT); in of_davinci_pll_init()
801 (*div_info)->name, PTR_ERR(clk)); in of_davinci_pll_init()
803 clks[(*div_info)->id] = clk; in of_davinci_pll_init()
813 snprintf(child_name, MAX_NAME_SIZE, "%s_auxclk", info->name); in of_davinci_pll_init()
829 clk = ERR_PTR(-EINVAL); in of_davinci_pll_init()
844 CLK_OF_DECLARE(da850_pll0, "ti,da850-pll0", of_da850_pll0_init);
849 { .compatible = "ti,da850-pll1", .data = of_da850_pll1_init },
856 { .name = "da830-pll", .driver_data = (kernel_ulong_t)da830_pll_init },
859 { .name = "da850-pll0", .driver_data = (kernel_ulong_t)da850_pll0_init },
860 { .name = "da850-pll1", .driver_data = (kernel_ulong_t)da850_pll1_init },
870 struct device *dev = &pdev->dev; in davinci_pll_probe()
876 if (!pll_init && pdev->id_entry) in davinci_pll_probe()
877 pll_init = (void *)pdev->id_entry->driver_data; in davinci_pll_probe()
881 return -EINVAL; in davinci_pll_probe()
884 cfgchip = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip"); in davinci_pll_probe()
896 .name = "davinci-pll-clk",
956 regset->regs = davinci_pll_regs; in davinci_pll_debug_init()
957 regset->nregs = ARRAY_SIZE(davinci_pll_regs); in davinci_pll_debug_init()
958 regset->base = pll->base; in davinci_pll_debug_init()