WSL2-Linux-Kernel/drivers/clk/sunxi-ng
Chen-Yu Tsai 02ae2bc6fe clk: sunxi-ng: Add clk notifier to gate then ungate PLL clocks
In common PLL designs, changes to the dividers take effect almost
immediately, while changes to the multipliers (implemented as
dividers in the feedback loop) take a few cycles to work into
the feedback loop for the PLL to stablize.

Sometimes when the PLL clock rate is changed, the decrease in the
divider is too much for the decrease in the multiplier to catch up.
The PLL clock rate will spike, and in some cases, might lock up
completely. This is especially the case if the divider changed is
the pre-divider, which affects the reference frequency.

This patch introduces a clk notifier callback that will gate and
then ungate a clk after a rate change, effectively resetting it,
so it continues to work, despite any possible lockups. Care must
be taken to reparent any consumers to other temporary clocks during
the rate change, and that this notifier callback must be the first
to be registered.

This is intended to fix occasional lockups with cpufreq on newer
Allwinner SoCs, such as the A33 and the H3. Previously it was
thought that reparenting the cpu clock away from the PLL while
it stabilized was enough, as this worked quite well on the A31.

On the A33, hangs have been observed after cpufreq was recently
introduced. With the H3, a more thorough test [1] showed that
reparenting alone isn't enough. The system still locks up unless
the dividers are limited to 1.

A hunch was if the PLL was stuck in some unknown state, perhaps
gating then ungating it would bring it back to normal. Tests
done by Icenowy Zheng using Ondrej's test firmware shows this
to be a valid solution.

[1] http://www.spinics.net/lists/arm-kernel/msg552501.html

Reported-by: Ondrej Jirman <megous@megous.com>
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Tested-by: Icenowy Zheng <icenowy@aosc.io>
Tested-by: Quentin Schulz <quentin.schulz@free-electrons.com>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
2017-04-13 11:22:02 +02:00
..
Kconfig clk: sunxi-ng: fix build failure in ccu-sun9i-a80 driver 2017-04-13 11:10:41 +02:00
Makefile clk: sunxi-ng: Add A80 Display Engine CCU 2017-01-30 08:38:30 +01:00
ccu-sun5i.c clk: sunxi-ng: Add sun5i CCU driver 2017-01-23 11:45:29 +01:00
ccu-sun5i.h clk: sunxi-ng: Add sun5i CCU driver 2017-01-23 11:45:29 +01:00
ccu-sun6i-a31.c clk: sunxi-ng: sun6i: Fix enable bit offset for hdmi-ddc module clock 2017-03-06 07:36:04 +01:00
ccu-sun6i-a31.h clk: sunxi-ng: Add A31/A31s clocks 2016-08-25 22:31:43 +02:00
ccu-sun8i-a23-a33.h clk: sunxi-ng: Add A33 CCU support 2016-09-10 11:41:19 +02:00
ccu-sun8i-a23.c clk: sunxi-ng: sun8i-a23: Set CLK_SET_RATE_PARENT for audio module clocks 2016-11-11 21:47:36 +01:00
ccu-sun8i-a33.c clk: sunxi-ng: a33: Set CLK_SET_RATE_PARENT for the GPU 2017-01-27 11:05:57 +01:00
ccu-sun8i-h3.c clk: sunxi-ng: fix PLL_CPUX adjusting on H3 2017-01-02 22:24:55 +01:00
ccu-sun8i-h3.h clk: sunxi-ng: Add H3 clocks 2016-07-08 18:05:12 -07:00
ccu-sun8i-v3s.c clk: sunxi-ng: add support for V3s CCU 2017-01-20 21:39:03 +01:00
ccu-sun8i-v3s.h clk: sunxi-ng: add support for V3s CCU 2017-01-20 21:39:03 +01:00
ccu-sun9i-a80-de.c clk: sunxi-ng: sun9i-a80: Fix wrong pointer passed to PTR_ERR() 2017-02-06 15:01:29 -08:00
ccu-sun9i-a80-de.h clk: sunxi-ng: Add A80 Display Engine CCU 2017-01-30 08:38:30 +01:00
ccu-sun9i-a80-usb.c clk: sunxi-ng: Add A80 USB CCU 2017-01-30 08:37:51 +01:00
ccu-sun9i-a80-usb.h clk: sunxi-ng: Add A80 USB CCU 2017-01-30 08:37:51 +01:00
ccu-sun9i-a80.c clk: sunxi-ng: Add A80 CCU 2017-01-30 08:37:30 +01:00
ccu-sun9i-a80.h clk: sunxi-ng: Add A80 CCU 2017-01-30 08:37:30 +01:00
ccu-sun50i-a64.c clk: sunxi-ng: Fix div/mult settings for osc12M on A64 2017-03-20 09:49:43 +01:00
ccu-sun50i-a64.h clk: sunxi-ng: Add A64 clocks 2016-11-03 09:06:18 +01:00
ccu_common.c clk: sunxi-ng: Add clk notifier to gate then ungate PLL clocks 2017-04-13 11:22:02 +02:00
ccu_common.h clk: sunxi-ng: Add clk notifier to gate then ungate PLL clocks 2017-04-13 11:22:02 +02:00
ccu_div.c clk: sunxi-ng: Call divider_round_rate if we only have a single parent 2017-01-27 11:05:34 +01:00
ccu_div.h clk: sunxi-ng: Implement factors offsets 2017-01-23 11:44:27 +01:00
ccu_frac.c clk: sunxi-ng: Rename the internal structures 2016-10-20 19:24:20 +02:00
ccu_frac.h clk: sunxi-ng: Rename the internal structures 2016-10-20 19:24:20 +02:00
ccu_gate.c clk: sunxi-ng: Add gate clock support 2016-07-08 18:04:38 -07:00
ccu_gate.h clk: sunxi-ng: Add gate clock support 2016-07-08 18:04:38 -07:00
ccu_mp.c clk: sunxi-ng: mp: Adjust parent rate for pre-dividers 2017-03-06 07:36:04 +01:00
ccu_mp.h clk: sunxi-ng: Rename the internal structures 2016-10-20 19:24:20 +02:00
ccu_mult.c clk: sunxi-ng: Implement multiplier maximum 2017-01-23 11:45:01 +01:00
ccu_mult.h clk: sunxi-ng: Implement multiplier maximum 2017-01-23 11:45:01 +01:00
ccu_mux.c clk: sunxi-ng: mux: Get closest parent rate possible with CLK_SET_RATE_PARENT 2017-01-30 08:36:03 +01:00
ccu_mux.h clk: sunxi-ng: mux: Add mux table macro 2016-09-10 11:41:18 +02:00
ccu_nk.c clk: sunxi-ng: Implement multiplier maximum 2017-01-23 11:45:01 +01:00
ccu_nk.h clk: sunxi-ng: Rename the internal structures 2016-10-20 19:24:20 +02:00
ccu_nkm.c clk: sunxi-ng: Implement multiplier maximum 2017-01-23 11:45:01 +01:00
ccu_nkm.h clk: sunxi-ng: Rename the internal structures 2016-10-20 19:24:20 +02:00
ccu_nkmp.c clk: sunxi-ng: fix recalc_rate formula of NKMP clocks 2017-03-20 10:34:05 +01:00
ccu_nkmp.h clk: sunxi-ng: Rename the internal structures 2016-10-20 19:24:20 +02:00
ccu_nm.c clk: sunxi-ng: Implement multiplier maximum 2017-01-23 11:45:01 +01:00
ccu_nm.h clk: sunxi-ng: Rename the internal structures 2016-10-20 19:24:20 +02:00
ccu_phase.c clk: sunxi-ng: Add phase clock support 2016-07-08 18:04:45 -07:00
ccu_phase.h clk: sunxi-ng: Add phase clock support 2016-07-08 18:04:45 -07:00
ccu_reset.c clk: sunxi-ng: Add common infrastructure 2016-07-08 18:04:32 -07:00
ccu_reset.h clk: sunxi-ng: Add common infrastructure 2016-07-08 18:04:32 -07:00