1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright 2016 Maxime Ripard
5 * Maxime Ripard <maxime.ripard@free-electrons.com>
9 #include <linux/clk-provider.h>
10 #include <linux/iopoll.h>
11 #include <linux/slab.h>
13 #include "ccu_common.h"
15 #include "ccu_reset.h"
17 static DEFINE_SPINLOCK(ccu_lock
);
19 void ccu_helper_wait_for_lock(struct ccu_common
*common
, u32 lock
)
27 if (common
->features
& CCU_FEATURE_LOCK_REG
)
28 addr
= common
->base
+ common
->lock_reg
;
30 addr
= common
->base
+ common
->reg
;
32 WARN_ON(readl_relaxed_poll_timeout(addr
, reg
, reg
& lock
, 100, 70000));
36 * This clock notifier is called when the frequency of a PLL clock is
37 * changed. In common PLL designs, changes to the dividers take effect
38 * almost immediately, while changes to the multipliers (implemented
39 * as dividers in the feedback loop) take a few cycles to work into
40 * the feedback loop for the PLL to stablize.
42 * Sometimes when the PLL clock rate is changed, the decrease in the
43 * divider is too much for the decrease in the multiplier to catch up.
44 * The PLL clock rate will spike, and in some cases, might lock up
47 * This notifier callback will gate and then ungate the clock,
48 * effectively resetting it, so it proceeds to work. Care must be
49 * taken to reparent consumers to other temporary clocks during the
50 * rate change, and that this notifier callback must be the first
53 static int ccu_pll_notifier_cb(struct notifier_block
*nb
,
54 unsigned long event
, void *data
)
56 struct ccu_pll_nb
*pll
= to_ccu_pll_nb(nb
);
59 if (event
!= POST_RATE_CHANGE
)
62 ccu_gate_helper_disable(pll
->common
, pll
->enable
);
64 ret
= ccu_gate_helper_enable(pll
->common
, pll
->enable
);
68 ccu_helper_wait_for_lock(pll
->common
, pll
->lock
);
71 return notifier_from_errno(ret
);
74 int ccu_pll_notifier_register(struct ccu_pll_nb
*pll_nb
)
76 pll_nb
->clk_nb
.notifier_call
= ccu_pll_notifier_cb
;
78 return clk_notifier_register(pll_nb
->common
->hw
.clk
,
82 int sunxi_ccu_probe(struct device_node
*node
, void __iomem
*reg
,
83 const struct sunxi_ccu_desc
*desc
)
85 struct ccu_reset
*reset
;
88 for (i
= 0; i
< desc
->num_ccu_clks
; i
++) {
89 struct ccu_common
*cclk
= desc
->ccu_clks
[i
];
95 cclk
->lock
= &ccu_lock
;
98 for (i
= 0; i
< desc
->hw_clks
->num
; i
++) {
99 struct clk_hw
*hw
= desc
->hw_clks
->hws
[i
];
104 ret
= of_clk_hw_register(node
, hw
);
106 pr_err("Couldn't register clock %d - %s\n",
107 i
, clk_hw_get_name(hw
));
112 ret
= of_clk_add_hw_provider(node
, of_clk_hw_onecell_get
,
117 reset
= kzalloc(sizeof(*reset
), GFP_KERNEL
);
120 goto err_alloc_reset
;
123 reset
->rcdev
.of_node
= node
;
124 reset
->rcdev
.ops
= &ccu_reset_ops
;
125 reset
->rcdev
.owner
= THIS_MODULE
;
126 reset
->rcdev
.nr_resets
= desc
->num_resets
;
128 reset
->lock
= &ccu_lock
;
129 reset
->reset_map
= desc
->resets
;
131 ret
= reset_controller_register(&reset
->rcdev
);
133 goto err_of_clk_unreg
;
140 of_clk_del_provider(node
);
143 struct clk_hw
*hw
= desc
->hw_clks
->hws
[i
];
147 clk_hw_unregister(hw
);