arm64: dts: rk3368: add iep device node
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / pm.c
1 /*
2  * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
3  * Author: Tony Xie <tony.xie@rock-chips.com>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  */
15
16 #include <linux/init.h>
17 #include <linux/io.h>
18 #include <linux/kernel.h>
19 #include <linux/of.h>
20 #include <linux/of_address.h>
21 #include <linux/regmap.h>
22 #include <linux/suspend.h>
23 #include <linux/mfd/syscon.h>
24 #include <linux/regulator/machine.h>
25 #include <linux/moduleparam.h>
26
27 #include <asm/cacheflush.h>
28 #include <asm/tlbflush.h>
29 #include <asm/suspend.h>
30
31 #include "pm.h"
32 #include "embedded/rk3288_resume.h"
33
34 /* These enum are option of low power mode */
35 enum {
36         ROCKCHIP_ARM_OFF_LOGIC_NORMAL = 0,
37         ROCKCHIP_ARM_OFF_LOGIC_DEEP = 1,
38 };
39
40 struct rockchip_pm_data {
41         const struct platform_suspend_ops *ops;
42         int (*init)(struct device_node *np);
43 };
44
45 static bool deep_sleep = true;
46 module_param(deep_sleep, bool, S_IRUGO | S_IWUSR);
47 MODULE_PARM_DESC(deep_sleep, "Go into deep sleep");
48
49 static void __iomem *rk3288_bootram_base;
50 static phys_addr_t rk3288_bootram_phy;
51
52 static struct regmap *pmu_regmap;
53 static struct regmap *sgrf_regmap;
54 static struct regmap *grf_regmap;
55
56 static u32 rk3288_pmu_pwr_mode_con;
57 static u32 rk3288_sgrf_soc_con0;
58 static u32 rk3288_sgrf_cpu_con0;
59
60 static inline u32 rk3288_l2_config(void)
61 {
62         u32 l2ctlr;
63
64         asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (l2ctlr));
65         return l2ctlr;
66 }
67
68 static void __init rk3288_init_pmu_sram(void)
69 {
70         extern char _binary_arch_arm_mach_rockchip_embedded_rk3288_resume_bin_start;
71         extern char _binary_arch_arm_mach_rockchip_embedded_rk3288_resume_bin_end;
72         u32 size = &_binary_arch_arm_mach_rockchip_embedded_rk3288_resume_bin_end -
73                    &_binary_arch_arm_mach_rockchip_embedded_rk3288_resume_bin_start;
74         struct rk3288_resume_params *params;
75
76         /* move resume code and data to PMU sram */
77         memcpy(rk3288_bootram_base,
78                &_binary_arch_arm_mach_rockchip_embedded_rk3288_resume_bin_start,
79                size);
80
81         /* setup the params that we know at boot time */
82         params = (struct rk3288_resume_params *)rk3288_bootram_base;
83
84         params->cpu_resume = (void *)virt_to_phys(cpu_resume);
85
86         params->l2ctlr_f = 1;
87         params->l2ctlr = rk3288_l2_config();
88
89         rk3288_ddr_suspend_init(&params->ddr_save_data);
90 }
91
92 #define GRF_UOC0_CON0                   0x320
93 #define GRF_UOC1_CON0                   0x334
94 #define GRF_UOC2_CON0                   0x348
95 #define GRF_SIDDQ                       BIT(13)
96
97 static bool rk3288_slp_disable_osc(void)
98 {
99         static const u32 reg_offset[] = { GRF_UOC0_CON0, GRF_UOC1_CON0,
100                                           GRF_UOC2_CON0 };
101         u32 reg, i;
102
103         /*
104          * if any usb phy is still on(GRF_SIDDQ==0), that means we need the
105          * function of usb wakeup, so do not switch to 32khz, since the usb phy
106          * clk does not connect to 32khz osc
107          */
108         for (i = 0; i < ARRAY_SIZE(reg_offset); i++) {
109                 regmap_read(grf_regmap, reg_offset[i], &reg);
110                 if (!(reg & GRF_SIDDQ))
111                         return false;
112         }
113
114         return true;
115 }
116
117 static void rk3288_slp_mode_set(int level)
118 {
119         struct rk3288_resume_params *params =
120                 (struct rk3288_resume_params *)rk3288_bootram_base;
121
122         u32 mode_set, mode_set1;
123         bool osc_disable = rk3288_slp_disable_osc();
124
125         regmap_read(sgrf_regmap, RK3288_SGRF_CPU_CON0, &rk3288_sgrf_cpu_con0);
126         regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0);
127
128         regmap_read(pmu_regmap, RK3288_PMU_PWRMODE_CON,
129                     &rk3288_pmu_pwr_mode_con);
130
131         /*
132          * SGRF_FAST_BOOT_EN - system to boot from FAST_BOOT_ADDR
133          * PCLK_WDT_GATE - disable WDT during suspend.
134          */
135         regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
136                      SGRF_PCLK_WDT_GATE | SGRF_FAST_BOOT_EN
137                      | SGRF_PCLK_WDT_GATE_WRITE | SGRF_FAST_BOOT_EN_WRITE);
138
139         /*
140          * The dapswjdp can not auto reset before resume, that cause it may
141          * access some illegal address during resume. Let's disable it before
142          * suspend, and the MASKROM will enable it back.
143          */
144         regmap_write(sgrf_regmap, RK3288_SGRF_CPU_CON0, SGRF_DAPDEVICEEN_WRITE);
145
146         /* booting address of resuming system is from this register value */
147         regmap_write(sgrf_regmap, RK3288_SGRF_FAST_BOOT_ADDR,
148                      (u32)params->resume_loc);
149
150         mode_set = BIT(PMU_GLOBAL_INT_DISABLE) | BIT(PMU_L2FLUSH_EN) |
151                    BIT(PMU_SREF0_ENTER_EN) | BIT(PMU_SREF1_ENTER_EN) |
152                    BIT(PMU_DDR0_GATING_EN) | BIT(PMU_DDR1_GATING_EN) |
153                    BIT(PMU_PWR_MODE_EN) | BIT(PMU_CHIP_PD_EN) |
154                    BIT(PMU_SCU_EN);
155
156         mode_set1 = BIT(PMU_CLR_CORE) | BIT(PMU_CLR_CPUP);
157
158         if (level == ROCKCHIP_ARM_OFF_LOGIC_DEEP) {
159                 /* arm off, logic deep sleep */
160                 mode_set |= BIT(PMU_BUS_PD_EN) |  BIT(PMU_PMU_USE_LF) |
161                             BIT(PMU_DDR1IO_RET_EN) | BIT(PMU_DDR0IO_RET_EN) |
162                             BIT(PMU_ALIVE_USE_LF) | BIT(PMU_PLL_PD_EN);
163
164                 mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) |
165                              BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA);
166
167                 regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
168                      PMU_ARMINT_WAKEUP_EN);
169
170                 /*
171                  * In deep suspend we use PMU_PMU_USE_LF to let the rk3288
172                  * switch its main clock supply to the alternative 32kHz
173                  * source. Therefore set 30ms on a 32kHz clock for pmic
174                  * stabilization. Similar 30ms on 24MHz for the other
175                  * mode below.
176                  */
177                 regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 32 * 30);
178
179                 /* only wait for stabilization, if we turned the osc off */
180                 regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT,
181                                          osc_disable ? 32 * 30 : 0);
182
183                 if (osc_disable)
184                         mode_set |= BIT(PMU_OSC_24M_DIS);
185
186                 params->ddr_resume_f = true;
187
188                 /* TODO: check error from ddr_suspend() and pass back */
189                 rk3288_ddr_suspend(&params->ddr_save_data);
190         } else {
191                 /*
192                  * arm off, logic normal
193                  * if pmu_clk_core_src_gate_en is not set,
194                  * wakeup will be error
195                  */
196                 mode_set |= BIT(PMU_CLK_CORE_SRC_GATE_EN);
197
198                 regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
199                              PMU_ARMINT_WAKEUP_EN | PMU_GPIOINT_WAKEUP_EN);
200
201                 /* 30ms on a 24MHz clock for pmic stabilization */
202                 regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 24000 * 30);
203
204                 /* oscillator is still running, so no need to wait */
205                 regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT, 0);
206
207                 params->ddr_resume_f = false;
208         }
209
210         regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON, mode_set);
211         regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON1, mode_set1);
212 }
213
214 static void rk3288_slp_mode_set_resume(int level)
215 {
216         regmap_write(sgrf_regmap, RK3288_SGRF_CPU_CON0,
217                      rk3288_sgrf_cpu_con0 | SGRF_DAPDEVICEEN_WRITE);
218
219         regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON,
220                      rk3288_pmu_pwr_mode_con);
221
222         regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
223                      rk3288_sgrf_soc_con0 | SGRF_PCLK_WDT_GATE_WRITE
224                      | SGRF_FAST_BOOT_EN_WRITE);
225
226         if (level == ROCKCHIP_ARM_OFF_LOGIC_DEEP)
227                 rk3288_ddr_resume();
228 }
229
230 static int rockchip_lpmode_enter(unsigned long arg)
231 {
232         flush_cache_all();
233
234         cpu_do_idle();
235
236         pr_err("%s: Failed to suspend\n", __func__);
237
238         return 1;
239 }
240
241 static int rk3288_suspend_enter(suspend_state_t state)
242 {
243         int level = deep_sleep ?
244                 ROCKCHIP_ARM_OFF_LOGIC_DEEP :
245                 ROCKCHIP_ARM_OFF_LOGIC_NORMAL;
246
247         local_fiq_disable();
248
249         rk3288_slp_mode_set(level);
250
251         cpu_suspend(0, rockchip_lpmode_enter);
252
253         rk3288_slp_mode_set_resume(level);
254
255         local_fiq_enable();
256
257         return 0;
258 }
259
260 static int rk3288_suspend_prepare(void)
261 {
262         return regulator_suspend_prepare(PM_SUSPEND_MEM);
263 }
264
265 static void rk3288_suspend_finish(void)
266 {
267         if (regulator_suspend_finish())
268                 pr_err("%s: Suspend finish failed\n", __func__);
269 }
270
271 static int __init rk3288_suspend_init(struct device_node *np)
272 {
273         struct device_node *sram_np;
274         struct resource res;
275         int ret;
276
277         pmu_regmap = syscon_node_to_regmap(np);
278         if (IS_ERR(pmu_regmap)) {
279                 pr_err("%s: could not find pmu regmap\n", __func__);
280                 return PTR_ERR(pmu_regmap);
281         }
282
283         sgrf_regmap = syscon_regmap_lookup_by_compatible(
284                                 "rockchip,rk3288-sgrf");
285         if (IS_ERR(sgrf_regmap)) {
286                 pr_err("%s: could not find sgrf regmap\n", __func__);
287                 return PTR_ERR(sgrf_regmap);
288         }
289
290         grf_regmap = syscon_regmap_lookup_by_compatible(
291                                 "rockchip,rk3288-grf");
292         if (IS_ERR(grf_regmap)) {
293                 pr_err("%s: could not find grf regmap\n", __func__);
294                 return PTR_ERR(grf_regmap);
295         }
296
297         sram_np = of_find_compatible_node(NULL, NULL,
298                                           "rockchip,rk3288-pmu-sram");
299         if (!sram_np) {
300                 pr_err("%s: could not find bootram dt node\n", __func__);
301                 return -ENODEV;
302         }
303
304         rk3288_bootram_base = of_iomap(sram_np, 0);
305         if (!rk3288_bootram_base) {
306                 pr_err("%s: could not map bootram base\n", __func__);
307                 return -ENOMEM;
308         }
309
310         ret = of_address_to_resource(sram_np, 0, &res);
311         if (ret) {
312                 pr_err("%s: could not get bootram phy addr\n", __func__);
313                 return ret;
314         }
315         rk3288_bootram_phy = res.start;
316
317         of_node_put(sram_np);
318
319         rk3288_init_pmu_sram();
320
321         return 0;
322 }
323
324 static const struct platform_suspend_ops rk3288_suspend_ops = {
325         .enter   = rk3288_suspend_enter,
326         .valid   = suspend_valid_only_mem,
327         .prepare = rk3288_suspend_prepare,
328         .finish  = rk3288_suspend_finish,
329 };
330
331 static const struct rockchip_pm_data rk3288_pm_data __initconst = {
332         .ops = &rk3288_suspend_ops,
333         .init = rk3288_suspend_init,
334 };
335
336 static const struct of_device_id rockchip_pmu_of_device_ids[] __initconst = {
337         {
338                 .compatible = "rockchip,rk3288-pmu",
339                 .data = &rk3288_pm_data,
340         },
341         { /* sentinel */ },
342 };
343
344 void __init rockchip_suspend_init(void)
345 {
346         const struct rockchip_pm_data *pm_data;
347         const struct of_device_id *match;
348         struct device_node *np;
349         int ret;
350
351         np = of_find_matching_node_and_match(NULL, rockchip_pmu_of_device_ids,
352                                              &match);
353         if (!match) {
354                 pr_err("Failed to find PMU node\n");
355                 return;
356         }
357         pm_data = (struct rockchip_pm_data *) match->data;
358
359         if (pm_data->init) {
360                 ret = pm_data->init(np);
361
362                 if (ret) {
363                         pr_err("%s: matches init error %d\n", __func__, ret);
364                         return;
365                 }
366         }
367
368         suspend_set_ops(pm_data->ops);
369 }