Lines Matching +full:pll +full:- +full:in
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * PLL clock driver for Keystone devices
6 * Murali Karicheri <m-karicheri2@ti.com>
9 #include <linux/clk-provider.h>
26 * struct clk_pll_data - pll data structure
27 * @has_pllctrl: If set to non zero, lower 6 bits of multiplier is in pllm
28 * register of pll controller, else it is in the pll_ctrl0((bit 11-6)
29 * @phy_pllm: Physical address of PLLM in pll controller. Used when
31 * @phy_pll_ctl0: Physical address of PLL ctrl0. This could be that of
32 * Main PLL or any other PLLs in the device such as ARM PLL, DDR PLL
33 * or PA PLL available on keystone2. These PLLs are controlled by
34 * this register. Main PLL is controlled by a PLL controller.
35 * @pllm: PLL register map address for multiplier bits
36 * @pllod: PLL register map address for post divider bits
37 * @pll_ctl0: PLL controller map address
64 * struct clk_pll - Main pll clock
65 * @hw: clk_hw for the pll
66 * @pll_data: PLL driver specific data
78 struct clk_pll *pll = to_clk_pll(hw); in clk_pllclk_recalc() local
79 struct clk_pll_data *pll_data = pll->pll_data; in clk_pllclk_recalc()
84 * get bits 0-5 of multiplier from pllctrl PLLM register in clk_pllclk_recalc()
87 if (pll_data->has_pllctrl) { in clk_pllclk_recalc()
88 val = readl(pll_data->pllm); in clk_pllclk_recalc()
89 mult = (val & pll_data->pllm_lower_mask); in clk_pllclk_recalc()
92 /* bit6-12 of PLLM is in Main PLL control register */ in clk_pllclk_recalc()
93 val = readl(pll_data->pll_ctl0); in clk_pllclk_recalc()
94 mult |= ((val & pll_data->pllm_upper_mask) in clk_pllclk_recalc()
95 >> pll_data->pllm_upper_shift); in clk_pllclk_recalc()
96 prediv = (val & pll_data->plld_mask); in clk_pllclk_recalc()
98 if (!pll_data->has_pllctrl) in clk_pllclk_recalc()
100 postdiv = ((val & pll_data->clkod_mask) >> in clk_pllclk_recalc()
101 pll_data->clkod_shift) + 1; in clk_pllclk_recalc()
102 else if (pll_data->pllod) { in clk_pllclk_recalc()
103 postdiv = readl(pll_data->pllod); in clk_pllclk_recalc()
104 postdiv = ((postdiv & pll_data->clkod_mask) >> in clk_pllclk_recalc()
105 pll_data->clkod_shift) + 1; in clk_pllclk_recalc()
107 postdiv = pll_data->postdiv; in clk_pllclk_recalc()
126 struct clk_pll *pll; in clk_register_pll() local
129 pll = kzalloc(sizeof(*pll), GFP_KERNEL); in clk_register_pll()
130 if (!pll) in clk_register_pll()
131 return ERR_PTR(-ENOMEM); in clk_register_pll()
139 pll->pll_data = pll_data; in clk_register_pll()
140 pll->hw.init = &init; in clk_register_pll()
142 clk = clk_register(NULL, &pll->hw); in clk_register_pll()
148 kfree(pll); in clk_register_pll()
153 * _of_pll_clk_init - PLL initialisation via DT
155 * @pllctrl: If true, lower 6 bits of multiplier is in pllm register of
156 * pll controller, else it is in the control register0(bit 11-6)
172 if (of_property_read_u32(node, "fixed-postdiv", &pll_data->postdiv)) { in _of_pll_clk_init()
173 /* assume the PLL has output divider register bits */ in _of_pll_clk_init()
174 pll_data->clkod_mask = CLKOD_MASK; in _of_pll_clk_init()
175 pll_data->clkod_shift = CLKOD_SHIFT; in _of_pll_clk_init()
178 * Check if there is an post-divider register. If not in _of_pll_clk_init()
181 i = of_property_match_string(node, "reg-names", in _of_pll_clk_init()
182 "post-divider"); in _of_pll_clk_init()
183 pll_data->pllod = of_iomap(node, i); in _of_pll_clk_init()
186 i = of_property_match_string(node, "reg-names", "control"); in _of_pll_clk_init()
187 pll_data->pll_ctl0 = of_iomap(node, i); in _of_pll_clk_init()
188 if (!pll_data->pll_ctl0) { in _of_pll_clk_init()
190 iounmap(pll_data->pllod); in _of_pll_clk_init()
194 pll_data->pllm_lower_mask = PLLM_LOW_MASK; in _of_pll_clk_init()
195 pll_data->pllm_upper_shift = PLLM_HIGH_SHIFT; in _of_pll_clk_init()
196 pll_data->plld_mask = PLLD_MASK; in _of_pll_clk_init()
197 pll_data->has_pllctrl = pllctrl; in _of_pll_clk_init()
198 if (!pll_data->has_pllctrl) { in _of_pll_clk_init()
199 pll_data->pllm_upper_mask = PLLM_HIGH_MASK; in _of_pll_clk_init()
201 pll_data->pllm_upper_mask = MAIN_PLLM_HIGH_MASK; in _of_pll_clk_init()
202 i = of_property_match_string(node, "reg-names", "multiplier"); in _of_pll_clk_init()
203 pll_data->pllm = of_iomap(node, i); in _of_pll_clk_init()
204 if (!pll_data->pllm) { in _of_pll_clk_init()
205 iounmap(pll_data->pll_ctl0); in _of_pll_clk_init()
206 iounmap(pll_data->pllod); in _of_pll_clk_init()
211 clk = clk_register_pll(NULL, node->name, parent_name, pll_data); in _of_pll_clk_init()
218 pr_err("%s: error initializing pll %pOFn\n", __func__, node); in _of_pll_clk_init()
223 * of_keystone_pll_clk_init - PLL initialisation DT wrapper
230 CLK_OF_DECLARE(keystone_pll_clock, "ti,keystone,pll-clock",
234 * of_keystone_main_pll_clk_init - Main PLL initialisation DT wrapper
241 CLK_OF_DECLARE(keystone_main_pll_clock, "ti,keystone,main-pll-clock",
245 * of_pll_div_clk_init - PLL divider setup function
254 const char *clk_name = node->name; in of_pll_div_clk_init()
256 of_property_read_string(node, "clock-output-names", &clk_name); in of_pll_div_clk_init()
270 if (of_property_read_u32(node, "bit-shift", &shift)) { in of_pll_div_clk_init()
276 if (of_property_read_u32(node, "bit-mask", &mask)) { in of_pll_div_clk_init()
277 pr_err("%s: missing 'bit-mask' property\n", __func__); in of_pll_div_clk_init()
292 CLK_OF_DECLARE(pll_divider_clock, "ti,keystone,pll-divider-clock", of_pll_div_clk_init);
295 * of_pll_mux_clk_init - PLL mux setup function
304 const char *clk_name = node->name; in of_pll_mux_clk_init()
306 of_property_read_string(node, "clock-output-names", &clk_name); in of_pll_mux_clk_init()
319 if (of_property_read_u32(node, "bit-shift", &shift)) { in of_pll_mux_clk_init()
324 if (of_property_read_u32(node, "bit-mask", &mask)) { in of_pll_mux_clk_init()
325 pr_err("%s: missing 'bit-mask' property\n", __func__); in of_pll_mux_clk_init()
339 CLK_OF_DECLARE(pll_mux_clock, "ti,keystone,pll-mux-clock", of_pll_mux_clk_init);
342 MODULE_DESCRIPTION("PLL clock driver for Keystone devices");
343 MODULE_AUTHOR("Murali Karicheri <m-karicheri2@ti.com>");