]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.51/clk-rockchip-turn-on-aclk_dmac1-for-suspend-on-rk328.patch
Linux 4.19.51
[thirdparty/kernel/stable-queue.git] / releases / 4.19.51 / clk-rockchip-turn-on-aclk_dmac1-for-suspend-on-rk328.patch
CommitLineData
37554d48
SL
1From 37fb0a55032f46776cb2b53484a2e8c528377cc8 Mon Sep 17 00:00:00 2001
2From: Douglas Anderson <dianders@chromium.org>
3Date: Thu, 11 Apr 2019 16:21:53 -0700
4Subject: clk: rockchip: Turn on "aclk_dmac1" for suspend on rk3288
5
6[ Upstream commit 57a20248ef3e429dc822f0774bc4e00136c46c83 ]
7
8Experimentally it can be seen that going into deep sleep (specifically
9setting PMU_CLR_DMA and PMU_CLR_BUS in RK3288_PMU_PWRMODE_CON1)
10appears to fail unless "aclk_dmac1" is on. The failure is that the
11system never signals that it made it into suspend on the GLOBAL_PWROFF
12pin and it just hangs.
13
14NOTE that it's confirmed that it's the actual suspend that fails, not
15one of the earlier calls to read/write registers. Specifically if you
16comment out the "PMU_GLOBAL_INT_DISABLE" setting in
17rk3288_slp_mode_set() and then comment out the "cpu_do_idle()" call in
18rockchip_lpmode_enter() then you can exercise the whole suspend path
19without any crashing.
20
21This is currently not a problem with suspend upstream because there is
22no current way to exercise the deep suspend code. However, anyone
23trying to make it work will run into this issue.
24
25This was not a problem on shipping rk3288-based Chromebooks because
26those devices all ran on an old kernel based on 3.14. On that kernel
27"aclk_dmac1" appears to be left on all the time.
28
29There are several ways to skin this problem.
30
31A) We could add "aclk_dmac1" to the list of critical clocks and that
32apperas to work, but presumably that wastes power.
33
34B) We could keep a list of "struct clk" objects to enable at suspend
35time in clk-rk3288.c and use the standard clock APIs.
36
37C) We could make the rk3288-pmu driver keep a list of clocks to enable
38at suspend time. Presumably this would require a dts and bindings
39change.
40
41D) We could just whack the clock on in the existing syscore suspend
42function where we whack a bunch of other clocks. This is particularly
43easy because we know for sure that the clock's only parent
44("aclk_cpu") is a critical clock so we don't need to do anything more
45than ungate it.
46
47In this case I have chosen D) because it seemed like the least work,
48but any of the other options would presumably also work fine.
49
50Signed-off-by: Douglas Anderson <dianders@chromium.org>
51Reviewed-by: Elaine Zhang <zhangqing@rock-chips.com>
52Signed-off-by: Heiko Stuebner <heiko@sntech.de>
53Signed-off-by: Sasha Levin <sashal@kernel.org>
54---
55 drivers/clk/rockchip/clk-rk3288.c | 11 +++++++++++
56 1 file changed, 11 insertions(+)
57
58diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
59index 64191694ff6e..9cfdbea493bb 100644
60--- a/drivers/clk/rockchip/clk-rk3288.c
61+++ b/drivers/clk/rockchip/clk-rk3288.c
62@@ -835,6 +835,9 @@ static const int rk3288_saved_cru_reg_ids[] = {
63 RK3288_CLKSEL_CON(10),
64 RK3288_CLKSEL_CON(33),
65 RK3288_CLKSEL_CON(37),
66+
67+ /* We turn aclk_dmac1 on for suspend; this will restore it */
68+ RK3288_CLKGATE_CON(10),
69 };
70
71 static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)];
72@@ -850,6 +853,14 @@ static int rk3288_clk_suspend(void)
73 readl_relaxed(rk3288_cru_base + reg_id);
74 }
75
76+ /*
77+ * Going into deep sleep (specifically setting PMU_CLR_DMA in
78+ * RK3288_PMU_PWRMODE_CON1) appears to fail unless
79+ * "aclk_dmac1" is on.
80+ */
81+ writel_relaxed(1 << (12 + 16),
82+ rk3288_cru_base + RK3288_CLKGATE_CON(10));
83+
84 /*
85 * Switch PLLs other than DPLL (for SDRAM) to slow mode to
86 * avoid crashes on resume. The Mask ROM on the system will
87--
882.20.1
89