Merge tag 'extcon-next-for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux/fpc-iii.git] / drivers / clk / mediatek / clk-pll.c
blobf440f2cd0b6988d2fcc07f344e8d56edde4b617c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2014 MediaTek Inc.
4 * Author: James Liao <jamesjj.liao@mediatek.com>
5 */
7 #include <linux/of.h>
8 #include <linux/of_address.h>
9 #include <linux/io.h>
10 #include <linux/slab.h>
11 #include <linux/clkdev.h>
12 #include <linux/delay.h>
14 #include "clk-mtk.h"
16 #define REG_CON0 0
17 #define REG_CON1 4
19 #define CON0_BASE_EN BIT(0)
20 #define CON0_PWR_ON BIT(0)
21 #define CON0_ISO_EN BIT(1)
22 #define PCW_CHG_MASK BIT(31)
24 #define AUDPLL_TUNER_EN BIT(31)
26 #define POSTDIV_MASK 0x7
28 /* default 7 bits integer, can be overridden with pcwibits. */
29 #define INTEGER_BITS 7
32 * MediaTek PLLs are configured through their pcw value. The pcw value describes
33 * a divider in the PLL feedback loop which consists of 7 bits for the integer
34 * part and the remaining bits (if present) for the fractional part. Also they
35 * have a 3 bit power-of-two post divider.
38 struct mtk_clk_pll {
39 struct clk_hw hw;
40 void __iomem *base_addr;
41 void __iomem *pd_addr;
42 void __iomem *pwr_addr;
43 void __iomem *tuner_addr;
44 void __iomem *tuner_en_addr;
45 void __iomem *pcw_addr;
46 void __iomem *pcw_chg_addr;
47 const struct mtk_pll_data *data;
50 static inline struct mtk_clk_pll *to_mtk_clk_pll(struct clk_hw *hw)
52 return container_of(hw, struct mtk_clk_pll, hw);
55 static int mtk_pll_is_prepared(struct clk_hw *hw)
57 struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
59 return (readl(pll->base_addr + REG_CON0) & CON0_BASE_EN) != 0;
62 static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin,
63 u32 pcw, int postdiv)
65 int pcwbits = pll->data->pcwbits;
66 int pcwfbits = 0;
67 int ibits;
68 u64 vco;
69 u8 c = 0;
71 /* The fractional part of the PLL divider. */
72 ibits = pll->data->pcwibits ? pll->data->pcwibits : INTEGER_BITS;
73 if (pcwbits > ibits)
74 pcwfbits = pcwbits - ibits;
76 vco = (u64)fin * pcw;
78 if (pcwfbits && (vco & GENMASK(pcwfbits - 1, 0)))
79 c = 1;
81 vco >>= pcwfbits;
83 if (c)
84 vco++;
86 return ((unsigned long)vco + postdiv - 1) / postdiv;
89 static void __mtk_pll_tuner_enable(struct mtk_clk_pll *pll)
91 u32 r;
93 if (pll->tuner_en_addr) {
94 r = readl(pll->tuner_en_addr) | BIT(pll->data->tuner_en_bit);
95 writel(r, pll->tuner_en_addr);
96 } else if (pll->tuner_addr) {
97 r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN;
98 writel(r, pll->tuner_addr);
102 static void __mtk_pll_tuner_disable(struct mtk_clk_pll *pll)
104 u32 r;
106 if (pll->tuner_en_addr) {
107 r = readl(pll->tuner_en_addr) & ~BIT(pll->data->tuner_en_bit);
108 writel(r, pll->tuner_en_addr);
109 } else if (pll->tuner_addr) {
110 r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN;
111 writel(r, pll->tuner_addr);
115 static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
116 int postdiv)
118 u32 chg, val;
120 /* disable tuner */
121 __mtk_pll_tuner_disable(pll);
123 /* set postdiv */
124 val = readl(pll->pd_addr);
125 val &= ~(POSTDIV_MASK << pll->data->pd_shift);
126 val |= (ffs(postdiv) - 1) << pll->data->pd_shift;
128 /* postdiv and pcw need to set at the same time if on same register */
129 if (pll->pd_addr != pll->pcw_addr) {
130 writel(val, pll->pd_addr);
131 val = readl(pll->pcw_addr);
134 /* set pcw */
135 val &= ~GENMASK(pll->data->pcw_shift + pll->data->pcwbits - 1,
136 pll->data->pcw_shift);
137 val |= pcw << pll->data->pcw_shift;
138 writel(val, pll->pcw_addr);
139 chg = readl(pll->pcw_chg_addr) | PCW_CHG_MASK;
140 writel(chg, pll->pcw_chg_addr);
141 if (pll->tuner_addr)
142 writel(val + 1, pll->tuner_addr);
144 /* restore tuner_en */
145 __mtk_pll_tuner_enable(pll);
147 udelay(20);
151 * mtk_pll_calc_values - calculate good values for a given input frequency.
152 * @pll: The pll
153 * @pcw: The pcw value (output)
154 * @postdiv: The post divider (output)
155 * @freq: The desired target frequency
156 * @fin: The input frequency
159 static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
160 u32 freq, u32 fin)
162 unsigned long fmin = pll->data->fmin ? pll->data->fmin : (1000 * MHZ);
163 const struct mtk_pll_div_table *div_table = pll->data->div_table;
164 u64 _pcw;
165 int ibits;
166 u32 val;
168 if (freq > pll->data->fmax)
169 freq = pll->data->fmax;
171 if (div_table) {
172 if (freq > div_table[0].freq)
173 freq = div_table[0].freq;
175 for (val = 0; div_table[val + 1].freq != 0; val++) {
176 if (freq > div_table[val + 1].freq)
177 break;
179 *postdiv = 1 << val;
180 } else {
181 for (val = 0; val < 5; val++) {
182 *postdiv = 1 << val;
183 if ((u64)freq * *postdiv >= fmin)
184 break;
188 /* _pcw = freq * postdiv / fin * 2^pcwfbits */
189 ibits = pll->data->pcwibits ? pll->data->pcwibits : INTEGER_BITS;
190 _pcw = ((u64)freq << val) << (pll->data->pcwbits - ibits);
191 do_div(_pcw, fin);
193 *pcw = (u32)_pcw;
196 static int mtk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
197 unsigned long parent_rate)
199 struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
200 u32 pcw = 0;
201 u32 postdiv;
203 mtk_pll_calc_values(pll, &pcw, &postdiv, rate, parent_rate);
204 mtk_pll_set_rate_regs(pll, pcw, postdiv);
206 return 0;
209 static unsigned long mtk_pll_recalc_rate(struct clk_hw *hw,
210 unsigned long parent_rate)
212 struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
213 u32 postdiv;
214 u32 pcw;
216 postdiv = (readl(pll->pd_addr) >> pll->data->pd_shift) & POSTDIV_MASK;
217 postdiv = 1 << postdiv;
219 pcw = readl(pll->pcw_addr) >> pll->data->pcw_shift;
220 pcw &= GENMASK(pll->data->pcwbits - 1, 0);
222 return __mtk_pll_recalc_rate(pll, parent_rate, pcw, postdiv);
225 static long mtk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
226 unsigned long *prate)
228 struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
229 u32 pcw = 0;
230 int postdiv;
232 mtk_pll_calc_values(pll, &pcw, &postdiv, rate, *prate);
234 return __mtk_pll_recalc_rate(pll, *prate, pcw, postdiv);
237 static int mtk_pll_prepare(struct clk_hw *hw)
239 struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
240 u32 r;
242 r = readl(pll->pwr_addr) | CON0_PWR_ON;
243 writel(r, pll->pwr_addr);
244 udelay(1);
246 r = readl(pll->pwr_addr) & ~CON0_ISO_EN;
247 writel(r, pll->pwr_addr);
248 udelay(1);
250 r = readl(pll->base_addr + REG_CON0);
251 r |= pll->data->en_mask;
252 writel(r, pll->base_addr + REG_CON0);
254 __mtk_pll_tuner_enable(pll);
256 udelay(20);
258 if (pll->data->flags & HAVE_RST_BAR) {
259 r = readl(pll->base_addr + REG_CON0);
260 r |= pll->data->rst_bar_mask;
261 writel(r, pll->base_addr + REG_CON0);
264 return 0;
267 static void mtk_pll_unprepare(struct clk_hw *hw)
269 struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
270 u32 r;
272 if (pll->data->flags & HAVE_RST_BAR) {
273 r = readl(pll->base_addr + REG_CON0);
274 r &= ~pll->data->rst_bar_mask;
275 writel(r, pll->base_addr + REG_CON0);
278 __mtk_pll_tuner_disable(pll);
280 r = readl(pll->base_addr + REG_CON0);
281 r &= ~CON0_BASE_EN;
282 writel(r, pll->base_addr + REG_CON0);
284 r = readl(pll->pwr_addr) | CON0_ISO_EN;
285 writel(r, pll->pwr_addr);
287 r = readl(pll->pwr_addr) & ~CON0_PWR_ON;
288 writel(r, pll->pwr_addr);
291 static const struct clk_ops mtk_pll_ops = {
292 .is_prepared = mtk_pll_is_prepared,
293 .prepare = mtk_pll_prepare,
294 .unprepare = mtk_pll_unprepare,
295 .recalc_rate = mtk_pll_recalc_rate,
296 .round_rate = mtk_pll_round_rate,
297 .set_rate = mtk_pll_set_rate,
300 static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
301 void __iomem *base)
303 struct mtk_clk_pll *pll;
304 struct clk_init_data init = {};
305 struct clk *clk;
306 const char *parent_name = "clk26m";
308 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
309 if (!pll)
310 return ERR_PTR(-ENOMEM);
312 pll->base_addr = base + data->reg;
313 pll->pwr_addr = base + data->pwr_reg;
314 pll->pd_addr = base + data->pd_reg;
315 pll->pcw_addr = base + data->pcw_reg;
316 if (data->pcw_chg_reg)
317 pll->pcw_chg_addr = base + data->pcw_chg_reg;
318 else
319 pll->pcw_chg_addr = pll->base_addr + REG_CON1;
320 if (data->tuner_reg)
321 pll->tuner_addr = base + data->tuner_reg;
322 if (data->tuner_en_reg)
323 pll->tuner_en_addr = base + data->tuner_en_reg;
324 pll->hw.init = &init;
325 pll->data = data;
327 init.name = data->name;
328 init.flags = (data->flags & PLL_AO) ? CLK_IS_CRITICAL : 0;
329 init.ops = &mtk_pll_ops;
330 if (data->parent_name)
331 init.parent_names = &data->parent_name;
332 else
333 init.parent_names = &parent_name;
334 init.num_parents = 1;
336 clk = clk_register(NULL, &pll->hw);
338 if (IS_ERR(clk))
339 kfree(pll);
341 return clk;
344 void mtk_clk_register_plls(struct device_node *node,
345 const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
347 void __iomem *base;
348 int i;
349 struct clk *clk;
351 base = of_iomap(node, 0);
352 if (!base) {
353 pr_err("%s(): ioremap failed\n", __func__);
354 return;
357 for (i = 0; i < num_plls; i++) {
358 const struct mtk_pll_data *pll = &plls[i];
360 clk = mtk_clk_register_pll(pll, base);
362 if (IS_ERR(clk)) {
363 pr_err("Failed to register clk %s: %ld\n",
364 pll->name, PTR_ERR(clk));
365 continue;
368 clk_data->clks[pll->id] = clk;