]>
Commit | Line | Data |
---|---|---|
37554d48 SL |
1 | From 37fb0a55032f46776cb2b53484a2e8c528377cc8 Mon Sep 17 00:00:00 2001 |
2 | From: Douglas Anderson <dianders@chromium.org> | |
3 | Date: Thu, 11 Apr 2019 16:21:53 -0700 | |
4 | Subject: clk: rockchip: Turn on "aclk_dmac1" for suspend on rk3288 | |
5 | ||
6 | [ Upstream commit 57a20248ef3e429dc822f0774bc4e00136c46c83 ] | |
7 | ||
8 | Experimentally it can be seen that going into deep sleep (specifically | |
9 | setting PMU_CLR_DMA and PMU_CLR_BUS in RK3288_PMU_PWRMODE_CON1) | |
10 | appears to fail unless "aclk_dmac1" is on. The failure is that the | |
11 | system never signals that it made it into suspend on the GLOBAL_PWROFF | |
12 | pin and it just hangs. | |
13 | ||
14 | NOTE that it's confirmed that it's the actual suspend that fails, not | |
15 | one of the earlier calls to read/write registers. Specifically if you | |
16 | comment out the "PMU_GLOBAL_INT_DISABLE" setting in | |
17 | rk3288_slp_mode_set() and then comment out the "cpu_do_idle()" call in | |
18 | rockchip_lpmode_enter() then you can exercise the whole suspend path | |
19 | without any crashing. | |
20 | ||
21 | This is currently not a problem with suspend upstream because there is | |
22 | no current way to exercise the deep suspend code. However, anyone | |
23 | trying to make it work will run into this issue. | |
24 | ||
25 | This was not a problem on shipping rk3288-based Chromebooks because | |
26 | those 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 | ||
29 | There are several ways to skin this problem. | |
30 | ||
31 | A) We could add "aclk_dmac1" to the list of critical clocks and that | |
32 | apperas to work, but presumably that wastes power. | |
33 | ||
34 | B) We could keep a list of "struct clk" objects to enable at suspend | |
35 | time in clk-rk3288.c and use the standard clock APIs. | |
36 | ||
37 | C) We could make the rk3288-pmu driver keep a list of clocks to enable | |
38 | at suspend time. Presumably this would require a dts and bindings | |
39 | change. | |
40 | ||
41 | D) We could just whack the clock on in the existing syscore suspend | |
42 | function where we whack a bunch of other clocks. This is particularly | |
43 | easy 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 | |
45 | than ungate it. | |
46 | ||
47 | In this case I have chosen D) because it seemed like the least work, | |
48 | but any of the other options would presumably also work fine. | |
49 | ||
50 | Signed-off-by: Douglas Anderson <dianders@chromium.org> | |
51 | Reviewed-by: Elaine Zhang <zhangqing@rock-chips.com> | |
52 | Signed-off-by: Heiko Stuebner <heiko@sntech.de> | |
53 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
54 | --- | |
55 | drivers/clk/rockchip/clk-rk3288.c | 11 +++++++++++ | |
56 | 1 file changed, 11 insertions(+) | |
57 | ||
58 | diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c | |
59 | index 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 | -- | |
88 | 2.20.1 | |
89 |