Lines Matching +full:omap +full:- +full:l138
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>
24 #include <linux/platform_data/clk-davinci-pll.h>
80 * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN
87 /* From OMAP-L138 datasheet table 6-4. Units are micro seconds */
91 * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4
97 * struct davinci_pll_clk - Main PLL clock (aka PLLOUT)
122 mult = readl(pll->base + PLLM) & pll->pllm_mask; in davinci_pll_recalc_rate()
132 struct clk_hw *parent = req->best_parent_hw; in davinci_pll_determine_rate()
133 unsigned long parent_rate = req->best_parent_rate; in davinci_pll_determine_rate()
134 unsigned long rate = req->rate; in davinci_pll_determine_rate()
139 if (rate < req->min_rate) in davinci_pll_determine_rate()
140 return -EINVAL; in davinci_pll_determine_rate()
142 rate = min(rate, req->max_rate); in davinci_pll_determine_rate()
148 if (best_rate < req->min_rate) in davinci_pll_determine_rate()
149 return -EINVAL; in davinci_pll_determine_rate()
151 if (mult < pll->pllm_min || mult > pll->pllm_max) in davinci_pll_determine_rate()
152 return -EINVAL; in davinci_pll_determine_rate()
154 req->rate = best_rate; in davinci_pll_determine_rate()
162 for (mult = pll->pllm_min; mult <= pll->pllm_max; mult++) { in davinci_pll_determine_rate()
165 if (r < req->min_rate) in davinci_pll_determine_rate()
167 if (r > rate || r > req->max_rate) in davinci_pll_determine_rate()
171 req->rate = best_rate; in davinci_pll_determine_rate()
172 req->best_parent_rate = parent_rate; in davinci_pll_determine_rate()
188 writel(mult - 1, pll->base + PLLM); in davinci_pll_set_rate()
214 mult = readl(pll->base + PLLM) & pll->pllm_mask; in dm365_pll_recalc_rate()
226 * davinci_pll_div_register - common *DIV clock implementation
232 * @flags: bitmap of CLK_* flags from clock-provider.h
250 return ERR_PTR(-ENOMEM); in davinci_pll_div_register()
252 gate->reg = reg; in davinci_pll_div_register()
253 gate->bit_idx = DIV_ENABLE_SHIFT; in davinci_pll_div_register()
257 ret = -ENOMEM; in davinci_pll_div_register()
261 divider->reg = reg; in davinci_pll_div_register()
262 divider->shift = DIV_RATIO_SHIFT; in davinci_pll_div_register()
263 divider->width = DIV_RATIO_WIDTH; in davinci_pll_div_register()
266 divider->flags |= CLK_DIVIDER_READ_ONLY; in davinci_pll_div_register()
271 NULL, NULL, ÷r->hw, divider_ops, in davinci_pll_div_register()
272 &gate->hw, &clk_gate_ops, flags); in davinci_pll_div_register()
310 struct clk_hw *hw = __clk_get_hw(cnd->clk); in davinci_pllen_rate_change()
314 ctrl = readl(pll->base + PLLCTL); in davinci_pllen_rate_change()
319 writel(ctrl, pll->base + PLLCTL); in davinci_pllen_rate_change()
325 writel(ctrl, pll->base + PLLCTL); in davinci_pllen_rate_change()
331 writel(ctrl, pll->base + PLLCTL); in davinci_pllen_rate_change()
337 writel(ctrl, pll->base + PLLCTL); in davinci_pllen_rate_change()
348 * davinci_pll_clk_register - Register a PLL clock
350 * @info: The device-specific clock info
353 * @cfgchip: CFGCHIP syscon regmap for info->unlock_reg or NULL
359 * - OSCIN is the parent clock (on secondary PLL, may come from primary PLL)
360 * - PREDIV and POSTDIV are optional (depends on the PLL controller)
361 * - PLL is the PLL output (aka PLLOUT)
362 * - PLLEN is the bypass multiplexer
386 if (info->flags & PLL_HAS_CLKMODE) { in davinci_pll_clk_register()
404 if (info->flags & PLL_HAS_PREDIV) { in davinci_pll_clk_register()
405 bool fixed = info->flags & PLL_PREDIV_FIXED_DIV; in davinci_pll_clk_register()
408 snprintf(prediv_name, MAX_NAME_SIZE, "%s_prediv", info->name); in davinci_pll_clk_register()
410 if (info->flags & PLL_PREDIV_ALWAYS_ENABLED) in davinci_pll_clk_register()
414 if (info->flags & PLL_PREDIV_FIXED8) in davinci_pll_clk_register()
429 if (info->unlock_reg) { in davinci_pll_clk_register()
434 regmap_write_bits(cfgchip, info->unlock_reg, in davinci_pll_clk_register()
435 info->unlock_mask, 0); in davinci_pll_clk_register()
440 ret = -ENOMEM; in davinci_pll_clk_register()
444 snprintf(pllout_name, MAX_NAME_SIZE, "%s_pllout", info->name); in davinci_pll_clk_register()
447 if (info->flags & PLL_PLLM_2X) in davinci_pll_clk_register()
455 if (info->flags & PLL_HAS_PREDIV) in davinci_pll_clk_register()
458 pllout->hw.init = &init; in davinci_pll_clk_register()
459 pllout->base = base; in davinci_pll_clk_register()
460 pllout->pllm_mask = info->pllm_mask; in davinci_pll_clk_register()
461 pllout->pllm_min = info->pllm_min; in davinci_pll_clk_register()
462 pllout->pllm_max = info->pllm_max; in davinci_pll_clk_register()
464 pllout_clk = clk_register(dev, &pllout->hw); in davinci_pll_clk_register()
470 clk_hw_set_rate_range(&pllout->hw, info->pllout_min_rate, in davinci_pll_clk_register()
471 info->pllout_max_rate); in davinci_pll_clk_register()
475 if (info->flags & PLL_HAS_POSTDIV) { in davinci_pll_clk_register()
476 bool fixed = info->flags & PLL_POSTDIV_FIXED_DIV; in davinci_pll_clk_register()
479 snprintf(postdiv_name, MAX_NAME_SIZE, "%s_postdiv", info->name); in davinci_pll_clk_register()
481 if (info->flags & PLL_POSTDIV_ALWAYS_ENABLED) in davinci_pll_clk_register()
496 ret = -ENOMEM; in davinci_pll_clk_register()
500 snprintf(pllen_name, MAX_NAME_SIZE, "%s_pllen", info->name); in davinci_pll_clk_register()
508 pllen->hw.init = &init; in davinci_pll_clk_register()
509 pllen->base = base; in davinci_pll_clk_register()
511 pllen_clk = clk_register(dev, &pllen->hw); in davinci_pll_clk_register()
538 * davinci_pll_auxclk_register - Register bypass clock (AUXCLK)
552 * davinci_pll_sysclkbp_clk_register - Register bypass divider clock (SYSCLKBP)
567 * davinci_pll_obsclk_register - Register oscillator divider clock (OBSCLK)
586 return ERR_PTR(-ENOMEM); in davinci_pll_obsclk_register()
588 mux->reg = base + OCSEL; in davinci_pll_obsclk_register()
589 mux->table = info->table; in davinci_pll_obsclk_register()
590 mux->mask = info->ocsrc_mask; in davinci_pll_obsclk_register()
594 ret = -ENOMEM; in davinci_pll_obsclk_register()
598 gate->reg = base + CKEN; in davinci_pll_obsclk_register()
599 gate->bit_idx = CKEN_OBSCLK_SHIFT; in davinci_pll_obsclk_register()
603 ret = -ENOMEM; in davinci_pll_obsclk_register()
607 divider->reg = base + OSCDIV; in davinci_pll_obsclk_register()
608 divider->shift = DIV_RATIO_SHIFT; in davinci_pll_obsclk_register()
609 divider->width = DIV_RATIO_WIDTH; in davinci_pll_obsclk_register()
616 clk = clk_register_composite(dev, info->name, info->parent_names, in davinci_pll_obsclk_register()
617 info->num_parents, in davinci_pll_obsclk_register()
618 &mux->hw, &clk_mux_ops, in davinci_pll_obsclk_register()
619 ÷r->hw, &clk_divider_ops, in davinci_pll_obsclk_register()
620 &gate->hw, &clk_gate_ops, 0); in davinci_pll_obsclk_register()
644 struct clk_hw *hw = __clk_get_hw(clk_get_parent(cnd->clk)); in davinci_pll_sysclk_rate_change()
651 pllcmd = readl(pll->base + PLLCMD); in davinci_pll_sysclk_rate_change()
653 writel(pllcmd, pll->base + PLLCMD); in davinci_pll_sysclk_rate_change()
658 pllstat = readl(pll->base + PLLSTAT); in davinci_pll_sysclk_rate_change()
671 * davinci_pll_sysclk_register - Register divider clocks (SYSCLKn)
690 if (info->id < 4) in davinci_pll_sysclk_register()
691 reg = PLLDIV1 + 4 * (info->id - 1); in davinci_pll_sysclk_register()
693 reg = PLLDIV4 + 4 * (info->id - 4); in davinci_pll_sysclk_register()
697 return ERR_PTR(-ENOMEM); in davinci_pll_sysclk_register()
699 gate->reg = base + reg; in davinci_pll_sysclk_register()
700 gate->bit_idx = DIV_ENABLE_SHIFT; in davinci_pll_sysclk_register()
704 ret = -ENOMEM; in davinci_pll_sysclk_register()
708 divider->reg = base + reg; in davinci_pll_sysclk_register()
709 divider->shift = DIV_RATIO_SHIFT; in davinci_pll_sysclk_register()
710 divider->width = info->ratio_width; in davinci_pll_sysclk_register()
711 divider->flags = 0; in davinci_pll_sysclk_register()
713 if (info->flags & SYSCLK_FIXED_DIV) { in davinci_pll_sysclk_register()
714 divider->flags |= CLK_DIVIDER_READ_ONLY; in davinci_pll_sysclk_register()
719 if (info->flags & SYSCLK_ARM_RATE) in davinci_pll_sysclk_register()
722 if (info->flags & SYSCLK_ALWAYS_ENABLED) in davinci_pll_sysclk_register()
725 clk = clk_register_composite(dev, info->name, &info->parent_name, 1, in davinci_pll_sysclk_register()
726 NULL, NULL, ÷r->hw, divider_ops, in davinci_pll_sysclk_register()
727 &gate->hw, &clk_gate_ops, flags); in davinci_pll_sysclk_register()
757 if (info->flags & PLL_HAS_CLKMODE) in of_davinci_pll_init()
764 dev_err(dev, "failed to register %s\n", info->name); in of_davinci_pll_init()
783 return -ENOMEM; in of_davinci_pll_init()
790 return -ENOMEM; in of_davinci_pll_init()
793 clk_data->clks = clks; in of_davinci_pll_init()
794 clk_data->clk_num = n_clks; in of_davinci_pll_init()
797 clks[i] = ERR_PTR(-ENOENT); in of_davinci_pll_init()
803 (*div_info)->name, PTR_ERR(clk)); in of_davinci_pll_init()
805 clks[(*div_info)->id] = clk; in of_davinci_pll_init()
815 snprintf(child_name, MAX_NAME_SIZE, "%s_auxclk", info->name); in of_davinci_pll_init()
831 clk = ERR_PTR(-EINVAL); in of_davinci_pll_init()
858 if (dev->of_node) in davinci_pll_get_pdata()
859 pdata->cfgchip = in davinci_pll_get_pdata()
860 syscon_regmap_lookup_by_compatible("ti,da830-cfgchip"); in davinci_pll_get_pdata()
867 CLK_OF_DECLARE(da850_pll0, "ti,da850-pll0", of_da850_pll0_init);
872 { .compatible = "ti,da850-pll1", .data = of_da850_pll1_init },
879 { .name = "da830-pll", .driver_data = (kernel_ulong_t)da830_pll_init },
882 { .name = "da850-pll0", .driver_data = (kernel_ulong_t)da850_pll0_init },
883 { .name = "da850-pll1", .driver_data = (kernel_ulong_t)da850_pll1_init },
886 { .name = "dm355-pll1", .driver_data = (kernel_ulong_t)dm355_pll1_init },
887 { .name = "dm355-pll2", .driver_data = (kernel_ulong_t)dm355_pll2_init },
890 { .name = "dm365-pll1", .driver_data = (kernel_ulong_t)dm365_pll1_init },
891 { .name = "dm365-pll2", .driver_data = (kernel_ulong_t)dm365_pll2_init },
894 { .name = "dm644x-pll1", .driver_data = (kernel_ulong_t)dm644x_pll1_init },
895 { .name = "dm644x-pll2", .driver_data = (kernel_ulong_t)dm644x_pll2_init },
898 { .name = "dm646x-pll1", .driver_data = (kernel_ulong_t)dm646x_pll1_init },
899 { .name = "dm646x-pll2", .driver_data = (kernel_ulong_t)dm646x_pll2_init },
909 struct device *dev = &pdev->dev; in davinci_pll_probe()
917 pll_init = of_id->data; in davinci_pll_probe()
918 else if (pdev->id_entry) in davinci_pll_probe()
919 pll_init = (void *)pdev->id_entry->driver_data; in davinci_pll_probe()
923 return -EINVAL; in davinci_pll_probe()
929 return -EINVAL; in davinci_pll_probe()
936 return pll_init(dev, base, pdata->cfgchip); in davinci_pll_probe()
942 .name = "davinci-pll-clk",
1002 regset->regs = davinci_pll_regs; in davinci_pll_debug_init()
1003 regset->nregs = ARRAY_SIZE(davinci_pll_regs); in davinci_pll_debug_init()
1004 regset->base = pll->base; in davinci_pll_debug_init()