.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright 2012 Freescale Semiconductor, Inc. |
---|
3 | 4 | * Copyright 2012 Linaro Ltd. |
---|
4 | | - * |
---|
5 | | - * The code contained herein is licensed under the GNU General Public |
---|
6 | | - * License. You may obtain a copy of the GNU General Public License |
---|
7 | | - * Version 2 or later at the following locations: |
---|
8 | | - * |
---|
9 | | - * http://www.opensource.org/licenses/gpl-license.html |
---|
10 | | - * http://www.gnu.org/copyleft/gpl.html |
---|
11 | 5 | */ |
---|
12 | 6 | |
---|
13 | 7 | #include <linux/clk-provider.h> |
---|
14 | 8 | #include <linux/delay.h> |
---|
15 | 9 | #include <linux/io.h> |
---|
| 10 | +#include <linux/iopoll.h> |
---|
16 | 11 | #include <linux/slab.h> |
---|
17 | 12 | #include <linux/jiffies.h> |
---|
18 | 13 | #include <linux/err.h> |
---|
.. | .. |
---|
20 | 15 | |
---|
21 | 16 | #define PLL_NUM_OFFSET 0x10 |
---|
22 | 17 | #define PLL_DENOM_OFFSET 0x20 |
---|
| 18 | +#define PLL_IMX7_NUM_OFFSET 0x20 |
---|
| 19 | +#define PLL_IMX7_DENOM_OFFSET 0x30 |
---|
23 | 20 | |
---|
24 | 21 | #define PLL_VF610_NUM_OFFSET 0x20 |
---|
25 | 22 | #define PLL_VF610_DENOM_OFFSET 0x30 |
---|
.. | .. |
---|
29 | 26 | #define IMX7_ENET_PLL_POWER (0x1 << 5) |
---|
30 | 27 | #define IMX7_DDR_PLL_POWER (0x1 << 20) |
---|
31 | 28 | |
---|
| 29 | +#define PLL_LOCK_TIMEOUT 10000 |
---|
| 30 | + |
---|
32 | 31 | /** |
---|
33 | 32 | * struct clk_pllv3 - IMX PLL clock version 3 |
---|
34 | | - * @clk_hw: clock source |
---|
| 33 | + * @hw: clock source |
---|
35 | 34 | * @base: base address of PLL registers |
---|
36 | 35 | * @power_bit: pll power bit mask |
---|
37 | 36 | * @powerup_set: set power_bit to power up the PLL |
---|
38 | 37 | * @div_mask: mask of divider bits |
---|
39 | 38 | * @div_shift: shift of divider bits |
---|
| 39 | + * @ref_clock: reference clock rate |
---|
| 40 | + * @num_offset: num register offset |
---|
| 41 | + * @denom_offset: denom register offset |
---|
40 | 42 | * |
---|
41 | 43 | * IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3 |
---|
42 | 44 | * is actually a multiplier, and always sits at bit 0. |
---|
.. | .. |
---|
49 | 51 | u32 div_mask; |
---|
50 | 52 | u32 div_shift; |
---|
51 | 53 | unsigned long ref_clock; |
---|
| 54 | + u32 num_offset; |
---|
| 55 | + u32 denom_offset; |
---|
52 | 56 | }; |
---|
53 | 57 | |
---|
54 | 58 | #define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw) |
---|
55 | 59 | |
---|
56 | 60 | static int clk_pllv3_wait_lock(struct clk_pllv3 *pll) |
---|
57 | 61 | { |
---|
58 | | - unsigned long timeout = jiffies + msecs_to_jiffies(10); |
---|
59 | 62 | u32 val = readl_relaxed(pll->base) & pll->power_bit; |
---|
60 | 63 | |
---|
61 | 64 | /* No need to wait for lock when pll is not powered up */ |
---|
62 | 65 | if ((pll->powerup_set && !val) || (!pll->powerup_set && val)) |
---|
63 | 66 | return 0; |
---|
64 | 67 | |
---|
65 | | - /* Wait for PLL to lock */ |
---|
66 | | - do { |
---|
67 | | - if (readl_relaxed(pll->base) & BM_PLL_LOCK) |
---|
68 | | - break; |
---|
69 | | - if (time_after(jiffies, timeout)) |
---|
70 | | - break; |
---|
71 | | - usleep_range(50, 500); |
---|
72 | | - } while (1); |
---|
73 | | - |
---|
74 | | - return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT; |
---|
| 68 | + return readl_relaxed_poll_timeout(pll->base, val, val & BM_PLL_LOCK, |
---|
| 69 | + 500, PLL_LOCK_TIMEOUT); |
---|
75 | 70 | } |
---|
76 | 71 | |
---|
77 | 72 | static int clk_pllv3_prepare(struct clk_hw *hw) |
---|
.. | .. |
---|
219 | 214 | unsigned long parent_rate) |
---|
220 | 215 | { |
---|
221 | 216 | struct clk_pllv3 *pll = to_clk_pllv3(hw); |
---|
222 | | - u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET); |
---|
223 | | - u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET); |
---|
| 217 | + u32 mfn = readl_relaxed(pll->base + pll->num_offset); |
---|
| 218 | + u32 mfd = readl_relaxed(pll->base + pll->denom_offset); |
---|
224 | 219 | u32 div = readl_relaxed(pll->base) & pll->div_mask; |
---|
225 | 220 | u64 temp64 = (u64)parent_rate; |
---|
226 | 221 | |
---|
.. | .. |
---|
289 | 284 | val &= ~pll->div_mask; |
---|
290 | 285 | val |= div; |
---|
291 | 286 | writel_relaxed(val, pll->base); |
---|
292 | | - writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET); |
---|
293 | | - writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET); |
---|
| 287 | + writel_relaxed(mfn, pll->base + pll->num_offset); |
---|
| 288 | + writel_relaxed(mfd, pll->base + pll->denom_offset); |
---|
294 | 289 | |
---|
295 | 290 | return clk_pllv3_wait_lock(pll); |
---|
296 | 291 | } |
---|
.. | .. |
---|
352 | 347 | struct clk_pllv3 *pll = to_clk_pllv3(hw); |
---|
353 | 348 | struct clk_pllv3_vf610_mf mf; |
---|
354 | 349 | |
---|
355 | | - mf.mfn = readl_relaxed(pll->base + PLL_VF610_NUM_OFFSET); |
---|
356 | | - mf.mfd = readl_relaxed(pll->base + PLL_VF610_DENOM_OFFSET); |
---|
| 350 | + mf.mfn = readl_relaxed(pll->base + pll->num_offset); |
---|
| 351 | + mf.mfd = readl_relaxed(pll->base + pll->denom_offset); |
---|
357 | 352 | mf.mfi = (readl_relaxed(pll->base) & pll->div_mask) ? 22 : 20; |
---|
358 | 353 | |
---|
359 | 354 | return clk_pllv3_vf610_mf_to_rate(parent_rate, mf); |
---|
.. | .. |
---|
382 | 377 | val |= pll->div_mask; /* set bit for mfi=22 */ |
---|
383 | 378 | writel_relaxed(val, pll->base); |
---|
384 | 379 | |
---|
385 | | - writel_relaxed(mf.mfn, pll->base + PLL_VF610_NUM_OFFSET); |
---|
386 | | - writel_relaxed(mf.mfd, pll->base + PLL_VF610_DENOM_OFFSET); |
---|
| 380 | + writel_relaxed(mf.mfn, pll->base + pll->num_offset); |
---|
| 381 | + writel_relaxed(mf.mfd, pll->base + pll->denom_offset); |
---|
387 | 382 | |
---|
388 | 383 | return clk_pllv3_wait_lock(pll); |
---|
389 | 384 | } |
---|
.. | .. |
---|
412 | 407 | .recalc_rate = clk_pllv3_enet_recalc_rate, |
---|
413 | 408 | }; |
---|
414 | 409 | |
---|
415 | | -struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, |
---|
| 410 | +struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name, |
---|
416 | 411 | const char *parent_name, void __iomem *base, |
---|
417 | 412 | u32 div_mask) |
---|
418 | 413 | { |
---|
419 | 414 | struct clk_pllv3 *pll; |
---|
420 | 415 | const struct clk_ops *ops; |
---|
421 | | - struct clk *clk; |
---|
422 | | - struct clk_init_data init = {}; |
---|
| 416 | + struct clk_hw *hw; |
---|
| 417 | + struct clk_init_data init; |
---|
| 418 | + int ret; |
---|
423 | 419 | |
---|
424 | 420 | pll = kzalloc(sizeof(*pll), GFP_KERNEL); |
---|
425 | 421 | if (!pll) |
---|
426 | 422 | return ERR_PTR(-ENOMEM); |
---|
427 | 423 | |
---|
428 | 424 | pll->power_bit = BM_PLL_POWER; |
---|
| 425 | + pll->num_offset = PLL_NUM_OFFSET; |
---|
| 426 | + pll->denom_offset = PLL_DENOM_OFFSET; |
---|
429 | 427 | |
---|
430 | 428 | switch (type) { |
---|
431 | 429 | case IMX_PLLV3_SYS: |
---|
.. | .. |
---|
433 | 431 | break; |
---|
434 | 432 | case IMX_PLLV3_SYS_VF610: |
---|
435 | 433 | ops = &clk_pllv3_vf610_ops; |
---|
| 434 | + pll->num_offset = PLL_VF610_NUM_OFFSET; |
---|
| 435 | + pll->denom_offset = PLL_VF610_DENOM_OFFSET; |
---|
436 | 436 | break; |
---|
437 | 437 | case IMX_PLLV3_USB_VF610: |
---|
438 | 438 | pll->div_shift = 1; |
---|
| 439 | + fallthrough; |
---|
439 | 440 | case IMX_PLLV3_USB: |
---|
440 | 441 | ops = &clk_pllv3_ops; |
---|
441 | 442 | pll->powerup_set = true; |
---|
442 | 443 | break; |
---|
| 444 | + case IMX_PLLV3_AV_IMX7: |
---|
| 445 | + pll->num_offset = PLL_IMX7_NUM_OFFSET; |
---|
| 446 | + pll->denom_offset = PLL_IMX7_DENOM_OFFSET; |
---|
| 447 | + fallthrough; |
---|
443 | 448 | case IMX_PLLV3_AV: |
---|
444 | 449 | ops = &clk_pllv3_av_ops; |
---|
445 | 450 | break; |
---|
.. | .. |
---|
454 | 459 | break; |
---|
455 | 460 | case IMX_PLLV3_DDR_IMX7: |
---|
456 | 461 | pll->power_bit = IMX7_DDR_PLL_POWER; |
---|
| 462 | + pll->num_offset = PLL_IMX7_NUM_OFFSET; |
---|
| 463 | + pll->denom_offset = PLL_IMX7_DENOM_OFFSET; |
---|
457 | 464 | ops = &clk_pllv3_av_ops; |
---|
458 | 465 | break; |
---|
459 | 466 | default: |
---|
.. | .. |
---|
469 | 476 | init.num_parents = 1; |
---|
470 | 477 | |
---|
471 | 478 | pll->hw.init = &init; |
---|
| 479 | + hw = &pll->hw; |
---|
472 | 480 | |
---|
473 | | - clk = clk_register(NULL, &pll->hw); |
---|
474 | | - if (IS_ERR(clk)) |
---|
| 481 | + ret = clk_hw_register(NULL, hw); |
---|
| 482 | + if (ret) { |
---|
475 | 483 | kfree(pll); |
---|
| 484 | + return ERR_PTR(ret); |
---|
| 485 | + } |
---|
476 | 486 | |
---|
477 | | - return clk; |
---|
| 487 | + return hw; |
---|
478 | 488 | } |
---|