xref: /OK3568_Linux_fs/kernel/arch/arm/mach-rockchip/rv1106_pm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3  * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
4  */
5 
6 #include <linux/init.h>
7 #include <linux/io.h>
8 #include <linux/kernel.h>
9 #include <linux/of.h>
10 #include <linux/of_address.h>
11 #include <linux/suspend.h>
12 #include <linux/mfd/syscon.h>
13 
14 #include <asm/cacheflush.h>
15 #include <asm/fiq_glue.h>
16 #include <asm/tlbflush.h>
17 #include <asm/suspend.h>
18 
19 #include "rkpm_gicv2.h"
20 #include "rkpm_helpers.h"
21 #include "rkpm_uart.h"
22 
23 #include "rv1106_pm.h"
24 
25 #define RV1106_PM_REG_REGION_MEM_SIZE		SZ_4K
26 
27 enum {
28 	RV1106_GPIO_PULL_NONE,
29 	RV1106_GPIO_PULL_UP,
30 	RV1106_GPIO_PULL_DOWN,
31 	RV1106_GPIO_PULL_UP_DOWN,
32 };
33 
34 struct rockchip_pm_data {
35 	const struct platform_suspend_ops *ops;
36 	int (*init)(struct device_node *np);
37 };
38 
39 struct rv1106_sleep_ddr_data {
40 	u32 cru_gate_con[RV1106_CRU_GATE_CON_NUM];
41 	u32 pmucru_gate_con[RV1106_PMUCRU_GATE_CON_NUM];
42 	u32 pericru_gate_con[RV1106_PERICRU_GATE_CON_NUM];
43 	u32 npucru_gate_con[RV1106_NPUCRU_GATE_CON_NUM];
44 	u32 venccru_gate_con[RV1106_VENCCRU_GATE_CON_NUM];
45 	u32 vicru_gate_con[RV1106_VICRU_GATE_CON_NUM];
46 	u32 vocru_gate_con[RV1106_VOCRU_GATE_CON_NUM];
47 
48 	u32 ddrgrf_con1, ddrgrf_con2, ddrgrf_con3, ddrc_pwrctrl, ddrc_dfilpcfg0;
49 	u32 pmucru_sel_con7;
50 	u32 pmugrf_soc_con0, pmugrf_soc_con1, pmugrf_soc_con4, pmugrf_soc_con5;
51 	u32 ioc0_1a_iomux_l, ioc1_1a_iomux_l;
52 	u32 gpio0a_iomux_l, gpio0a_iomux_h, gpio0a0_pull;
53 	u32 gpio0_ddr_l, gpio0_ddr_h;
54 	u32 pmu_wkup_int_st, gpio0_int_st;
55 };
56 
57 static struct rv1106_sleep_ddr_data ddr_data;
58 
59 static void __iomem *pmucru_base;
60 static void __iomem *cru_base;
61 static void __iomem *pericru_base;
62 static void __iomem *vicru_base;
63 static void __iomem *npucru_base;
64 static void __iomem *corecru_base;
65 static void __iomem *venccru_base;
66 static void __iomem *vocru_base;
67 
68 static void __iomem *perigrf_base;
69 static void __iomem *vencgrf_base;
70 static void __iomem *npugrf_base;
71 static void __iomem *pmugrf_base;
72 static void __iomem *ddrgrf_base;
73 static void __iomem *coregrf_base;
74 static void __iomem *vigrf_base;
75 static void __iomem *vogrf_base;
76 static void __iomem *perisgrf_base;
77 static void __iomem *visgrf_base;
78 static void __iomem *npusgrf_base;
79 static void __iomem *coresgrf_base;
80 static void __iomem *vencsgrf_base;
81 static void __iomem *vosgrf_base;
82 static void __iomem *pmusgrf_base;
83 
84 static void __iomem *pmupvtm_base;
85 static void __iomem *uartdbg_base;
86 static void __iomem *pmu_base;
87 static void __iomem *gicd_base;
88 static void __iomem *gicc_base;
89 static void __iomem *firewall_ddr_base;
90 static void __iomem *firewall_syssram_base;
91 static void __iomem *pmu_base;
92 static void __iomem *nstimer_base;
93 static void __iomem *stimer_base;
94 static void __iomem *ddrc_base;
95 static void __iomem *ioc_base[5];
96 static void __iomem *gpio_base[5];
97 static void __iomem *rv1106_bootram_base;
98 
99 #define WMSK_VAL		0xffff0000
100 
101 static struct reg_region vd_core_reg_rgns[] = {
102 	/* core_cru */
103 	{ REG_REGION(0x300, 0x310, 4, &corecru_base, WMSK_VAL)},
104 	{ REG_REGION(0x800, 0x804, 4, &corecru_base, WMSK_VAL)},
105 
106 	/* core_sgrf */
107 	{ REG_REGION(0x004, 0x014, 4, &coresgrf_base, 0)},
108 	{ REG_REGION(0x000, 0x000, 4, &coresgrf_base, 0)},
109 	{ REG_REGION(0x020, 0x030, 4, &coresgrf_base, WMSK_VAL)},
110 	{ REG_REGION(0x040, 0x040, 4, &coresgrf_base, WMSK_VAL)},
111 	{ REG_REGION(0x044, 0x044, 4, &coresgrf_base, 0)},
112 
113 	/* core grf */
114 	{ REG_REGION(0x004, 0x004, 4, &coregrf_base, WMSK_VAL)},
115 	{ REG_REGION(0x008, 0x010, 4, &coregrf_base, 0)},
116 	{ REG_REGION(0x024, 0x028, 4, &coregrf_base, 0)},
117 	{ REG_REGION(0x000, 0x000, 4, &coregrf_base, WMSK_VAL)},
118 	{ REG_REGION(0x02c, 0x02c, 4, &coregrf_base, WMSK_VAL)},
119 	{ REG_REGION(0x038, 0x03c, 4, &coregrf_base, WMSK_VAL)},
120 };
121 
122 static struct reg_region vd_log_reg_rgns[] = {
123 	/* firewall_ddr */
124 	{ REG_REGION(0x000, 0x03c, 4, &firewall_ddr_base, 0)},
125 	{ REG_REGION(0x040, 0x06c, 4, &firewall_ddr_base, 0)},
126 	{ REG_REGION(0x0f0, 0x0f0, 4, &firewall_ddr_base, 0)},
127 
128 	/* firewall_sram */
129 	{ REG_REGION(0x000, 0x01c, 4, &firewall_syssram_base, 0)},
130 	{ REG_REGION(0x040, 0x054, 4, &firewall_syssram_base, 0)},
131 	{ REG_REGION(0x0f0, 0x0f0, 4, &firewall_syssram_base, 0)},
132 
133 	/* cru */
134 	{ REG_REGION(0x000, 0x004, 4, &cru_base, WMSK_VAL)},
135 	{ REG_REGION(0x008, 0x008, 4, &cru_base, 0)},
136 	{ REG_REGION(0x00c, 0x010, 4, &cru_base, WMSK_VAL)},
137 	{ REG_REGION(0x020, 0x024, 4, &cru_base, WMSK_VAL)},
138 	{ REG_REGION(0x028, 0x028, 4, &cru_base, 0)},
139 	{ REG_REGION(0x02c, 0x030, 4, &cru_base, WMSK_VAL)},
140 	{ REG_REGION(0x060, 0x064, 4, &cru_base, WMSK_VAL)},
141 	{ REG_REGION(0x068, 0x068, 4, &cru_base, 0)},
142 	{ REG_REGION(0x06c, 0x070, 4, &cru_base, WMSK_VAL)},
143 	{ REG_REGION(0x140, 0x1bc, 4, &cru_base, 0)},
144 	/* { REG_REGION(0x280, 0x280, 4, &cru_base, WMSK_VAL)}, */
145 	{ REG_REGION(0x300, 0x310, 4, &cru_base, WMSK_VAL)},
146 	{ REG_REGION(0x314, 0x34c, 8, &cru_base, WMSK_VAL)},
147 	{ REG_REGION(0x318, 0x350, 8, &cru_base, 0)},
148 	{ REG_REGION(0x354, 0x360, 4, &cru_base, WMSK_VAL)},
149 	{ REG_REGION(0x364, 0x37c, 8, &cru_base, WMSK_VAL)},
150 	{ REG_REGION(0x368, 0x380, 8, &cru_base, 0)},
151 	{ REG_REGION(0x384, 0x384, 4, &cru_base, WMSK_VAL)},
152 	{ REG_REGION(0x800, 0x80c, 4, &cru_base, WMSK_VAL)},
153 	{ REG_REGION(0xc00, 0xc00, 4, &cru_base, 0)},
154 	{ REG_REGION(0xc10, 0xc10, 4, &cru_base, 0)},
155 	{ REG_REGION(0xc14, 0xc28, 4, &cru_base, WMSK_VAL)},
156 
157 	/* npu_cru */
158 	{ REG_REGION(0x300, 0x300, 4, &npucru_base, WMSK_VAL)},
159 	{ REG_REGION(0x800, 0x804, 4, &npucru_base, WMSK_VAL)},
160 
161 	/* npu_sgrf */
162 	{ REG_REGION(0x004, 0x014, 4, &npusgrf_base, 0)},
163 	{ REG_REGION(0x000, 0x000, 4, &npusgrf_base, 0)},
164 
165 	/* peri_cru */
166 	{ REG_REGION(0x304, 0x32c, 4, &pericru_base, WMSK_VAL)},
167 	{ REG_REGION(0x800, 0x81c, 4, &pericru_base, WMSK_VAL)},
168 
169 	/* peri_sgrf */
170 	{ REG_REGION(0x004, 0x014, 4, &perisgrf_base, 0)},
171 	{ REG_REGION(0x000, 0x000, 4, &perisgrf_base, 0)},
172 	{ REG_REGION(0x020, 0x030, 4, &perisgrf_base, WMSK_VAL)},
173 	{ REG_REGION(0x080, 0x0a4, 4, &perisgrf_base, WMSK_VAL)},
174 	{ REG_REGION(0x0b8, 0x0bc, 4, &perisgrf_base, WMSK_VAL)},
175 
176 	/* vi_cru */
177 	{ REG_REGION(0x300, 0x30c, 4, &vicru_base, WMSK_VAL)},
178 	{ REG_REGION(0x800, 0x808, 4, &vicru_base, WMSK_VAL)},
179 
180 	/* vi_sgrf */
181 	{ REG_REGION(0x004, 0x014, 4, &visgrf_base, 0)},
182 	{ REG_REGION(0x000, 0x000, 4, &visgrf_base, 0)},
183 
184 	/* vo_cru */
185 	{ REG_REGION(0x300, 0x30c, 4, &vocru_base, WMSK_VAL)},
186 	{ REG_REGION(0x800, 0x80c, 4, &vocru_base, WMSK_VAL)},
187 
188 	/* vo_sgrf */
189 	{ REG_REGION(0x004, 0x014, 4, &vosgrf_base, 0)},
190 	{ REG_REGION(0x000, 0x000, 4, &vosgrf_base, 0)},
191 	{ REG_REGION(0x018, 0x018, 4, &vosgrf_base, WMSK_VAL)},
192 
193 	/* vepu_cru */
194 	{ REG_REGION(0x300, 0x304, 4, &venccru_base, WMSK_VAL)},
195 	{ REG_REGION(0x800, 0x808, 4, &venccru_base, WMSK_VAL)},
196 
197 	/* vepu_sgrf */
198 	{ REG_REGION(0x004, 0x014, 4, &vencsgrf_base, 0)},
199 	{ REG_REGION(0x000, 0x000, 4, &vencsgrf_base, 0)},
200 
201 	/* gpio1_ioc */
202 	{ REG_REGION(0x000, 0x018, 4, &ioc_base[1], WMSK_VAL)},
203 	{ REG_REGION(0x080, 0x0b4, 4, &ioc_base[1], WMSK_VAL)},
204 	{ REG_REGION(0x180, 0x18c, 4, &ioc_base[1], WMSK_VAL)},
205 	{ REG_REGION(0x1c0, 0x1cc, 4, &ioc_base[1], WMSK_VAL)},
206 	{ REG_REGION(0x200, 0x20c, 4, &ioc_base[1], WMSK_VAL)},
207 	{ REG_REGION(0x240, 0x24c, 4, &ioc_base[1], WMSK_VAL)},
208 	{ REG_REGION(0x280, 0x28c, 4, &ioc_base[1], WMSK_VAL)},
209 	{ REG_REGION(0x2c0, 0x2cc, 4, &ioc_base[1], WMSK_VAL)},
210 	{ REG_REGION(0x2f4, 0x2f4, 4, &ioc_base[1], WMSK_VAL)},
211 
212 	/* gpio2_ioc */
213 	{ REG_REGION(0x020, 0x028, 4, &ioc_base[2], WMSK_VAL)},
214 	{ REG_REGION(0x0c0, 0x0d0, 4, &ioc_base[2], WMSK_VAL)},
215 	{ REG_REGION(0x190, 0x194, 4, &ioc_base[2], WMSK_VAL)},
216 	{ REG_REGION(0x1d0, 0x1d4, 4, &ioc_base[2], WMSK_VAL)},
217 	{ REG_REGION(0x210, 0x214, 4, &ioc_base[2], WMSK_VAL)},
218 	{ REG_REGION(0x250, 0x254, 4, &ioc_base[2], WMSK_VAL)},
219 	{ REG_REGION(0x290, 0x294, 4, &ioc_base[2], WMSK_VAL)},
220 	{ REG_REGION(0x2d0, 0x2d4, 4, &ioc_base[2], WMSK_VAL)},
221 
222 	/* gpio3_ioc */
223 	{ REG_REGION(0x040, 0x058, 4, &ioc_base[3], WMSK_VAL)},
224 	{ REG_REGION(0x100, 0x10c, 4, &ioc_base[3], WMSK_VAL)},
225 	{ REG_REGION(0x128, 0x134, 4, &ioc_base[3], WMSK_VAL)},
226 	{ REG_REGION(0x1a0, 0x1ac, 4, &ioc_base[3], WMSK_VAL)},
227 	{ REG_REGION(0x1e0, 0x1ec, 4, &ioc_base[3], WMSK_VAL)},
228 	{ REG_REGION(0x220, 0x22c, 4, &ioc_base[3], WMSK_VAL)},
229 	{ REG_REGION(0x260, 0x26c, 4, &ioc_base[3], WMSK_VAL)},
230 	{ REG_REGION(0x2a0, 0x2ac, 4, &ioc_base[3], WMSK_VAL)},
231 	{ REG_REGION(0x2e0, 0x2ec, 4, &ioc_base[3], WMSK_VAL)},
232 	{ REG_REGION(0x2f4, 0x2f4, 4, &ioc_base[3], WMSK_VAL)},
233 
234 	/* gpio1~3 */
235 	{ REG_REGION(0x000, 0x00c, 4, &gpio_base[1], WMSK_VAL)},
236 	{ REG_REGION(0x018, 0x044, 4, &gpio_base[1], WMSK_VAL)},
237 	{ REG_REGION(0x048, 0x048, 4, &gpio_base[1], 0)},
238 	{ REG_REGION(0x060, 0x064, 4, &gpio_base[1], WMSK_VAL)},
239 	{ REG_REGION(0x100, 0x108, 4, &gpio_base[1], WMSK_VAL)},
240 	{ REG_REGION(0x010, 0x014, 4, &gpio_base[1], WMSK_VAL)},
241 
242 	{ REG_REGION(0x000, 0x00c, 4, &gpio_base[2], WMSK_VAL)},
243 	{ REG_REGION(0x018, 0x044, 4, &gpio_base[2], WMSK_VAL)},
244 	{ REG_REGION(0x048, 0x048, 4, &gpio_base[2], 0)},
245 	{ REG_REGION(0x060, 0x064, 4, &gpio_base[2], WMSK_VAL)},
246 	{ REG_REGION(0x100, 0x108, 4, &gpio_base[2], WMSK_VAL)},
247 	{ REG_REGION(0x010, 0x014, 4, &gpio_base[2], WMSK_VAL)},
248 
249 	{ REG_REGION(0x000, 0x00c, 4, &gpio_base[3], WMSK_VAL)},
250 	{ REG_REGION(0x018, 0x044, 4, &gpio_base[3], WMSK_VAL)},
251 	{ REG_REGION(0x048, 0x048, 4, &gpio_base[3], 0)},
252 	{ REG_REGION(0x060, 0x064, 4, &gpio_base[3], WMSK_VAL)},
253 	{ REG_REGION(0x100, 0x108, 4, &gpio_base[3], WMSK_VAL)},
254 	{ REG_REGION(0x010, 0x014, 4, &gpio_base[3], WMSK_VAL)},
255 
256 	/* NS TIMER 6 channel */
257 	{ REG_REGION(0x00, 0x04, 4, &nstimer_base, 0)},
258 	{ REG_REGION(0x10, 0x10, 4, &nstimer_base, 0)},
259 	{ REG_REGION(0x20, 0x24, 4, &nstimer_base, 0)},
260 	{ REG_REGION(0x30, 0x30, 4, &nstimer_base, 0)},
261 	{ REG_REGION(0x40, 0x44, 4, &nstimer_base, 0)},
262 	{ REG_REGION(0x50, 0x50, 4, &nstimer_base, 0)},
263 	{ REG_REGION(0x60, 0x64, 4, &nstimer_base, 0)},
264 	{ REG_REGION(0x70, 0x70, 4, &nstimer_base, 0)},
265 	{ REG_REGION(0x80, 0x84, 4, &nstimer_base, 0)},
266 	{ REG_REGION(0x90, 0x90, 4, &nstimer_base, 0)},
267 	{ REG_REGION(0xa0, 0xa4, 4, &nstimer_base, 0)},
268 	{ REG_REGION(0xb0, 0xb0, 4, &nstimer_base, 0)},
269 
270 	/* S TIMER0 2 channel */
271 	{ REG_REGION(0x00, 0x04, 4, &stimer_base, 0)},
272 	{ REG_REGION(0x10, 0x10, 4, &stimer_base, 0)},
273 	{ REG_REGION(0x20, 0x24, 4, &stimer_base, 0)},
274 	{ REG_REGION(0x30, 0x30, 4, &stimer_base, 0)},
275 };
276 
277 #define PLL_LOCKED_TIMEOUT		600000U
278 
pm_pll_wait_lock(u32 pll_id)279 static void pm_pll_wait_lock(u32 pll_id)
280 {
281 	int delay = PLL_LOCKED_TIMEOUT;
282 
283 	if (readl_relaxed(cru_base + RV1106_CRU_PLL_CON(pll_id, 1)) & CRU_PLLCON1_PWRDOWN)
284 		return;
285 
286 	while (delay-- >= 0) {
287 		if (readl_relaxed(cru_base + RV1106_CRU_PLL_CON(pll_id, 1)) &
288 		    CRU_PLLCON1_LOCK_STATUS)
289 			break;
290 
291 		rkpm_raw_udelay(1);
292 	}
293 
294 	if (delay <= 0) {
295 		rkpm_printstr("Can't wait pll lock: ");
296 		rkpm_printhex(pll_id);
297 		rkpm_printch('\n');
298 	}
299 }
300 
301 struct plat_gicv2_dist_ctx_t gicd_ctx_save;
302 struct plat_gicv2_cpu_ctx_t gicc_ctx_save;
303 
gic400_save(void)304 static void gic400_save(void)
305 {
306 	rkpm_gicv2_cpu_save(gicd_base, gicc_base, &gicc_ctx_save);
307 	rkpm_gicv2_dist_save(gicd_base, &gicd_ctx_save);
308 }
309 
gic400_restore(void)310 static void gic400_restore(void)
311 {
312 	rkpm_gicv2_dist_restore(gicd_base, &gicd_ctx_save);
313 	rkpm_gicv2_cpu_restore(gicd_base, gicc_base, &gicc_ctx_save);
314 }
315 
uart_wrtie_byte(uint8_t byte)316 static void uart_wrtie_byte(uint8_t byte)
317 {
318 	writel_relaxed(byte, uartdbg_base + 0x0);
319 
320 	while (!(readl_relaxed(uartdbg_base + 0x14) & 0x40))
321 		;
322 }
323 
rkpm_printch(int c)324 void rkpm_printch(int c)
325 {
326 	if (c == '\n')
327 		uart_wrtie_byte('\r');
328 
329 	uart_wrtie_byte(c);
330 }
331 
332 #define RV1106_DUMP_GPIO_INTEN(id)							\
333 	do {										\
334 		rkpm_printstr("GPIO");							\
335 		rkpm_printdec(id);							\
336 		rkpm_printstr(": ");							\
337 		rkpm_printhex(readl_relaxed(gpio_base[id] + RV1106_GPIO_INT_EN_L));	\
338 		rkpm_printch(' ');							\
339 		rkpm_printhex(readl_relaxed(gpio_base[id] + RV1106_GPIO_INT_EN_H));	\
340 		rkpm_printch(' ');							\
341 		rkpm_printhex(readl_relaxed(gpio_base[id] + RV1106_GPIO_INT_MASK_L));	\
342 		rkpm_printch(' ');							\
343 		rkpm_printhex(readl_relaxed(gpio_base[id] + RV1106_GPIO_INT_MASK_H));	\
344 		rkpm_printch(' ');							\
345 		rkpm_printhex(readl_relaxed(gpio_base[id] + RV1106_GPIO_INT_STATUS));	\
346 		rkpm_printch(' ');							\
347 		rkpm_printhex(readl_relaxed(gpio_base[id] + RV1106_GPIO_INT_RAWSTATUS));\
348 		rkpm_printch('\n');							\
349 	} while (0)
350 
rv1106_dbg_pmu_wkup_src(void)351 static void rv1106_dbg_pmu_wkup_src(void)
352 {
353 	u32 pmu_int_st = ddr_data.pmu_wkup_int_st;
354 
355 	rkpm_printstr("wake up status:");
356 	rkpm_printhex(pmu_int_st);
357 	rkpm_printch('\n');
358 
359 	if (pmu_int_st)
360 		rkpm_printstr("wake up information:\n");
361 
362 	if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_GPIO_INT_EN)) {
363 		rkpm_printstr("GPIO0 interrupt wakeup:");
364 		rkpm_printhex(ddr_data.gpio0_int_st);
365 		rkpm_printch('\n');
366 	}
367 
368 	if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_SDMMC_EN))
369 		rkpm_printstr("PWM detect wakeup\n");
370 
371 	if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_SDIO_EN))
372 		rkpm_printstr("GMAC interrupt wakeup\n");
373 
374 	if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_TIMER_EN))
375 		rkpm_printstr("TIMER interrupt wakeup\n");
376 
377 	if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_USBDEV_EN))
378 		rkpm_printstr("USBDEV detect wakeup\n");
379 
380 	if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_TIMEROUT_EN))
381 		rkpm_printstr("TIMEOUT interrupt wakeup\n");
382 
383 	rkpm_printch('\n');
384 }
385 
rv1106_dbg_irq_prepare(void)386 static void rv1106_dbg_irq_prepare(void)
387 {
388 	RV1106_DUMP_GPIO_INTEN(0);
389 }
390 
rv1106_dbg_irq_finish(void)391 static void rv1106_dbg_irq_finish(void)
392 {
393 	rv1106_dbg_pmu_wkup_src();
394 }
395 
rv1106_l2_config(void)396 static inline u32 rv1106_l2_config(void)
397 {
398 	u32 l2ctlr;
399 
400 	asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (l2ctlr));
401 	return l2ctlr;
402 }
403 
rv1106_config_bootdata(void)404 static void __init rv1106_config_bootdata(void)
405 {
406 	rkpm_bootdata_cpusp = RV1106_PMUSRAM_BASE + (SZ_8K - 8);
407 	rkpm_bootdata_cpu_code = __pa_symbol(cpu_resume);
408 
409 	rkpm_bootdata_l2ctlr_f = 1;
410 	rkpm_bootdata_l2ctlr = rv1106_l2_config();
411 }
412 
clock_suspend(void)413 static void clock_suspend(void)
414 {
415 	int i;
416 
417 	for (i = 0; i < RV1106_CRU_GATE_CON_NUM; i++) {
418 		ddr_data.cru_gate_con[i] =
419 			readl_relaxed(cru_base + RV1106_CRU_GATE_CON(i));
420 		writel_relaxed(0xffff0000, cru_base + RV1106_CRU_GATE_CON(i));
421 	}
422 
423 	for (i = 0; i < RV1106_PMUCRU_GATE_CON_NUM; i++) {
424 		ddr_data.pmucru_gate_con[i] =
425 			readl_relaxed(pmucru_base + RV1106_PMUCRU_GATE_CON(i));
426 		writel_relaxed(0xffff0000, pmucru_base + RV1106_PMUCRU_GATE_CON(i));
427 	}
428 
429 	for (i = 0; i < RV1106_PERICRU_GATE_CON_NUM; i++) {
430 		ddr_data.pericru_gate_con[i] =
431 			readl_relaxed(pericru_base + RV1106_PERICRU_GATE_CON(i));
432 		writel_relaxed(0xffff0000, pericru_base + RV1106_PERICRU_GATE_CON(i));
433 	}
434 
435 	for (i = 0; i < RV1106_NPUCRU_GATE_CON_NUM; i++) {
436 		ddr_data.npucru_gate_con[i] =
437 			readl_relaxed(npucru_base + RV1106_NPUCRU_GATE_CON(i));
438 		writel_relaxed(0xffff0000, npucru_base + RV1106_NPUCRU_GATE_CON(i));
439 	}
440 
441 	for (i = 0; i < RV1106_VENCCRU_GATE_CON_NUM; i++) {
442 		ddr_data.venccru_gate_con[i] =
443 			readl_relaxed(venccru_base + RV1106_VENCCRU_GATE_CON(i));
444 		writel_relaxed(0xffff0000, venccru_base + RV1106_VENCCRU_GATE_CON(i));
445 	}
446 
447 	for (i = 0; i < RV1106_VICRU_GATE_CON_NUM; i++) {
448 		ddr_data.vicru_gate_con[i] =
449 			readl_relaxed(vicru_base + RV1106_VICRU_GATE_CON(i));
450 		writel_relaxed(0xffff0000, vicru_base + RV1106_VICRU_GATE_CON(i));
451 	}
452 
453 	for (i = 0; i < RV1106_VOCRU_GATE_CON_NUM; i++) {
454 		ddr_data.vocru_gate_con[i] =
455 			readl_relaxed(vocru_base + RV1106_VOCRU_GATE_CON(i));
456 		writel_relaxed(0xffff0000, vocru_base + RV1106_VOCRU_GATE_CON(i));
457 	}
458 }
459 
clock_resume(void)460 static void clock_resume(void)
461 {
462 	int i;
463 
464 	for (i = 0; i < RV1106_CRU_GATE_CON_NUM; i++)
465 		writel_relaxed(WITH_16BITS_WMSK(ddr_data.cru_gate_con[i]),
466 			       cru_base + RV1106_CRU_GATE_CON(i));
467 
468 	for (i = 0; i < RV1106_PMUCRU_GATE_CON_NUM; i++)
469 		writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmucru_gate_con[i]),
470 			       pmucru_base + RV1106_PMUCRU_GATE_CON(i));
471 
472 	for (i = 0; i < RV1106_PERICRU_GATE_CON_NUM; i++)
473 		writel_relaxed(WITH_16BITS_WMSK(ddr_data.pericru_gate_con[i]),
474 			       pericru_base + RV1106_PERICRU_GATE_CON(i));
475 
476 	for (i = 0; i < RV1106_NPUCRU_GATE_CON_NUM; i++)
477 		writel_relaxed(WITH_16BITS_WMSK(ddr_data.npucru_gate_con[i]),
478 			       npucru_base + RV1106_NPUCRU_GATE_CON(i));
479 
480 	for (i = 0; i < RV1106_VENCCRU_GATE_CON_NUM; i++)
481 		writel_relaxed(WITH_16BITS_WMSK(ddr_data.venccru_gate_con[i]),
482 			       venccru_base + RV1106_VENCCRU_GATE_CON(i));
483 
484 	for (i = 0; i < RV1106_VICRU_GATE_CON_NUM; i++)
485 		writel_relaxed(WITH_16BITS_WMSK(ddr_data.vicru_gate_con[i]),
486 			       vicru_base + RV1106_VICRU_GATE_CON(i));
487 
488 	for (i = 0; i < RV1106_VOCRU_GATE_CON_NUM; i++)
489 		writel_relaxed(WITH_16BITS_WMSK(ddr_data.vocru_gate_con[i]),
490 			       vocru_base + RV1106_VOCRU_GATE_CON(i));
491 }
492 
pvtm_32k_config(int flag)493 static void pvtm_32k_config(int flag)
494 {
495 	int value;
496 	int pvtm_freq_khz, pvtm_div;
497 	int sleep_clk_freq_khz;
498 
499 	ddr_data.pmucru_sel_con7 =
500 		readl_relaxed(pmucru_base + RV1106_PMUCRU_CLKSEL_CON(7));
501 
502 	if (flag) {
503 		writel_relaxed(BITS_WITH_WMASK(0x1, 0x1, 6), vigrf_base + 0x0);
504 		writel_relaxed(BITS_WITH_WMASK(0x4, 0xf, 0), ioc_base[0] + 0);
505 		writel_relaxed(BITS_WITH_WMASK(0x1, 0x1, 15),
506 			       pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
507 		writel_relaxed(BITS_WITH_WMASK(0x1, 0x3, 0),
508 			       pmucru_base + RV1106_PMUCRU_CLKSEL_CON(7));
509 	} else {
510 		writel_relaxed(BITS_WITH_WMASK(0, 0x3, 0),
511 			       pmupvtm_base + RV1106_PVTM_CON(2));
512 		writel_relaxed(RV1106_PVTM_CALC_CNT,
513 			       pmupvtm_base + RV1106_PVTM_CON(1));
514 		writel_relaxed(BITS_WITH_WMASK(0, 0x3, PVTM_START),
515 			       pmupvtm_base + RV1106_PVTM_CON(0));
516 		dsb();
517 
518 		writel_relaxed(BITS_WITH_WMASK(0, 0x7, PVTM_OSC_SEL),
519 			       pmupvtm_base + RV1106_PVTM_CON(0));
520 		writel_relaxed(BITS_WITH_WMASK(1, 0x1, PVTM_OSC_EN),
521 			       pmupvtm_base + RV1106_PVTM_CON(0));
522 		writel_relaxed(BITS_WITH_WMASK(1, 0x1, PVTM_RND_SEED_EN),
523 			       pmupvtm_base + RV1106_PVTM_CON(0));
524 		dsb();
525 
526 		writel_relaxed(BITS_WITH_WMASK(1, 0x1, PVTM_START),
527 			       pmupvtm_base + RV1106_PVTM_CON(0));
528 		dsb();
529 
530 		while (readl_relaxed(pmupvtm_base + RV1106_PVTM_STATUS(1)) < 30)
531 			;
532 
533 		dsb();
534 
535 		while (!readl_relaxed(pmupvtm_base + RV1106_PVTM_STATUS(0)) & 0x1)
536 			;
537 
538 		value = (readl_relaxed(pmupvtm_base + RV1106_PVTM_STATUS(1)));
539 		pvtm_freq_khz = (value * 24000 + RV1106_PVTM_CALC_CNT / 2) / RV1106_PVTM_CALC_CNT;
540 		pvtm_div = (pvtm_freq_khz + 16) / 32 - 1;
541 		if (pvtm_div > 0xfff)
542 			pvtm_div = 0xfff;
543 
544 		writel_relaxed(WITH_16BITS_WMSK(pvtm_div),
545 			       pmugrf_base + RV1106_PMUGRF_SOC_CON(3));
546 
547 		/* select 32k source */
548 		writel_relaxed(BITS_WITH_WMASK(0x2, 0x3, 0),
549 			       pmucru_base + RV1106_PMUCRU_CLKSEL_CON(7));
550 
551 		sleep_clk_freq_khz = pvtm_freq_khz / (pvtm_div + 1);
552 
553 		rkpm_printstr("pvtm real_freq (khz):");
554 		rkpm_printhex(sleep_clk_freq_khz);
555 		rkpm_printch('\n');
556 	}
557 }
558 
pvtm_32k_config_restore(void)559 static void pvtm_32k_config_restore(void)
560 {
561 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmucru_sel_con7),
562 		       pmucru_base + RV1106_PMUCRU_CLKSEL_CON(7));
563 }
564 
ddr_sleep_config(void)565 static void ddr_sleep_config(void)
566 {
567 	u32 val;
568 
569 	ddr_data.ddrc_pwrctrl = readl_relaxed(ddrc_base + 0x30);
570 	ddr_data.ddrgrf_con1 = readl_relaxed(ddrgrf_base + RV1106_DDRGRF_CON(1));
571 	ddr_data.ddrgrf_con2 = readl_relaxed(ddrgrf_base + RV1106_DDRGRF_CON(2));
572 	ddr_data.ddrgrf_con3 = readl_relaxed(ddrgrf_base + RV1106_DDRGRF_CON(3));
573 	ddr_data.ddrc_dfilpcfg0 = readl_relaxed(ddrc_base + 0x198);
574 	ddr_data.pmugrf_soc_con0 = readl_relaxed(pmugrf_base + RV1106_PMUGRF_SOC_CON(0));
575 
576 	val = readl_relaxed(ddrc_base + 0x30);
577 	writel_relaxed(val & ~(BIT(0) | BIT(1)), ddrc_base + 0x30);
578 
579 	/* disable ddr auto gt */
580 	writel_relaxed(BITS_WITH_WMASK(0x12, 0x1f, 0), ddrgrf_base + RV1106_DDRGRF_CON(1));
581 
582 	writel_relaxed(BITS_WITH_WMASK(0x3ff, 0x3ff, 0), ddrgrf_base + RV1106_DDRGRF_CON(2));
583 
584 	/* ddr low power request by pmu */
585 	writel_relaxed(BITS_WITH_WMASK(0x3, 0x3, 8), ddrgrf_base + RV1106_DDRGRF_CON(3));
586 
587 	while ((readl_relaxed(ddrc_base + 0x4) & 0x7) != 0x1)
588 		continue;
589 
590 	val = readl_relaxed(ddrc_base + 0x198) & ~(0xf << 12 | 0xf << 4);
591 	val |= (0xa << 12 | 0xa << 4);
592 	writel_relaxed(val, ddrc_base + 0x198);
593 
594 	val = readl_relaxed(ddrc_base + 0x198) | BIT(8) | BIT(0);
595 	writel_relaxed(val, ddrc_base + 0x198);
596 
597 	/* ddr io ret by pmu */
598 	writel_relaxed(BITS_WITH_WMASK(0x0, 0x7, 9), pmugrf_base + RV1106_PMUGRF_SOC_CON(0));
599 }
600 
ddr_sleep_config_restore(void)601 static void ddr_sleep_config_restore(void)
602 {
603 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.ddrgrf_con3),
604 		       ddrgrf_base + RV1106_DDRGRF_CON(3));
605 }
606 
pmu_sleep_config(void)607 static void pmu_sleep_config(void)
608 {
609 	u32 clk_freq_khz = 32;
610 	u32 pmu_wkup_con, pmu_pwr_con, pmu_scu_con, pmu_ddr_con;
611 	u32 pmu_bus_idle_con, pmu_cru_con[2], pmu_pll_con;
612 
613 	ddr_data.pmugrf_soc_con1 = readl_relaxed(pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
614 	ddr_data.pmugrf_soc_con4 = readl_relaxed(pmugrf_base + RV1106_PMUGRF_SOC_CON(4));
615 	ddr_data.pmugrf_soc_con5 = readl_relaxed(pmugrf_base + RV1106_PMUGRF_SOC_CON(5));
616 	ddr_data.ioc1_1a_iomux_l = readl_relaxed(ioc_base[1] + 0);
617 
618 	pmu_wkup_con =
619 		/* BIT(RV1106_PMU_WAKEUP_TIMEROUT_EN) | */
620 		/* BIT(RV1106_PMU_WAKEUP_CPU_INT_EN) | */
621 		BIT(RV1106_PMU_WAKEUP_GPIO_INT_EN) |
622 		0;
623 
624 	pmu_pwr_con =
625 		BIT(RV1106_PMU_PWRMODE_EN) |
626 		/* BIT(RV1106_PMU_BUS_BYPASS) | */
627 		/* BIT(RV1106_PMU_DDR_BYPASS) | */
628 		/* BIT(RV1106_PMU_CRU_BYPASS) | */
629 		0;
630 
631 	pmu_scu_con =
632 		BIT(RV1106_PMU_SCU_INT_MASK_ENA) |
633 		BIT(RV1106_PMU_CPU_INT_MASK_ENA) |
634 		0;
635 
636 	pmu_bus_idle_con =
637 		BIT(RV1106_PMU_IDLE_REQ_MSCH) |
638 		BIT(RV1106_PMU_IDLE_REQ_DDR) |
639 		BIT(RV1106_PMU_IDLE_REQ_NPU) |
640 		BIT(RV1106_PMU_IDLE_REQ_NPU_ACLK) |
641 		BIT(RV1106_PMU_IDLE_REQ_VI) |
642 		BIT(RV1106_PMU_IDLE_REQ_VO) |
643 		BIT(RV1106_PMU_IDLE_REQ_PERI) |
644 		BIT(RV1106_PMU_IDLE_REQ_CRU) |
645 		BIT(RV1106_PMU_IDLE_REQ_CPU) |
646 		BIT(RV1106_PMU_IDLE_REQ_VENC_COM) |
647 		BIT(RV1106_PMU_IDLE_REQ_VEPU) |
648 		0;
649 
650 	pmu_cru_con[0] =
651 		BIT(RV1106_PMU_ALIVE_32K_ENA) |
652 		BIT(RV1106_PMU_OSC_DIS_ENA) |
653 		BIT(RV1106_PMU_WAKEUP_RST_ENA) |
654 		BIT(RV1106_PMU_INPUT_CLAMP_ENA) |
655 		/* BIT(RV1106_PMU_ALIVE_OSC_ENA) | */
656 		BIT(RV1106_PMU_POWER_OFF_ENA) |
657 		0;
658 
659 	pmu_cru_con[1] =
660 		/* BIT(RV1106_PMU_VI_CLK_SRC_GATE_ENA) | */
661 		/* BIT(RV1106_PMU_VO_CLK_SRC_GATE_ENA) | */
662 		/* BIT(RV1106_PMU_VENC_CLK_SRC_GATE_ENA) | */
663 		/* BIT(RV1106_PMU_NPU_CLK_SRC_GATE_ENA) | */
664 		/* BIT(RV1106_PMU_DDR_CLK_SRC_CATE_ENA) | */
665 		/* BIT(RV1106_PMU_PERI_CLK_SRC_GATE_ENA) | */
666 		/* BIT(RV1106_PMU_CORE_CLK_SRC_GATE_ENA) | */
667 		/* BIT(RV1106_PMU_CRU_CLK_SRC_GATE_ENA) | */
668 		0;
669 
670 	pmu_ddr_con =
671 		BIT(RV1106_PMU_DDR_SREF_C_ENA) |
672 #if !RV1106_WAKEUP_TO_SYSTEM_RESET
673 		BIT(RV1106_PMU_DDRIO_RET_ENA) |
674 #endif
675 		BIT(RV1106_PMU_DDRCTL_C_AUTO_GATING_ENA) |
676 		BIT(RV1106_PMU_MSCH_AUTO_GATING_ENA) |
677 		BIT(RV1106_PMU_DDR_SREF_A_ENA) |
678 		BIT(RV1106_PMU_DDRCTL_A_AUTO_GATING_ENA) |
679 		0;
680 
681 	pmu_pll_con =
682 		BIT(RV1106_PMU_APLL_PD_ENA) |
683 		BIT(RV1106_PMU_DPLL_PD_ENA) |
684 		BIT(RV1106_PMU_CPLL_PD_ENA) |
685 		BIT(RV1106_PMU_GPLL_PD_ENA) |
686 		0;
687 
688 	/* pmic_sleep */
689 	/* gpio0_a3 activelow, gpio0_a4 active high */
690 	writel_relaxed(BITS_WITH_WMASK(0x4, 0x7, 0), pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
691 	/* select sleep func */
692 	writel_relaxed(BITS_WITH_WMASK(0x1, 0x1, 0), pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
693 	/* gpio0_a3 iomux */
694 	writel_relaxed(BITS_WITH_WMASK(0x1, 0xf, 12), ioc_base[0] + 0);
695 
696 	/* pmu_debug */
697 	writel_relaxed(0xffffff01, pmu_base + RV1106_PMU_INFO_TX_CON);
698 	writel_relaxed(BITS_WITH_WMASK(0x1, 0xf, 4), ioc_base[1] + 0);
699 
700 	/* pmu count */
701 	writel_relaxed(clk_freq_khz * 32, pmu_base + RV1106_PMU_OSC_STABLE_CNT);
702 	writel_relaxed(clk_freq_khz * 32, pmu_base + RV1106_PMU_PMIC_STABLE_CNT);
703 	writel_relaxed(clk_freq_khz * 3000, pmu_base + RV1106_PMU_WAKEUP_TIMEOUT_CNT);
704 
705 	/* Pmu's clk has switched to 24M back When pmu FSM counts
706 	 * the follow counters, so we should use 24M to calculate
707 	 * these counters.
708 	 */
709 	writel_relaxed(24000 * 2, pmu_base + RV1106_PMU_WAKEUP_RSTCLR_CNT);
710 	writel_relaxed(24000 * 5, pmu_base + RV1106_PMU_PLL_LOCK_CNT);
711 	writel_relaxed(24000 * 5, pmu_base + RV1106_PMU_PWM_SWITCH_CNT);
712 
713 	/* pmu reset hold */
714 	writel_relaxed(0xffffffff, pmugrf_base + RV1106_PMUGRF_SOC_CON(4));
715 	writel_relaxed(0xffffff47, pmugrf_base + RV1106_PMUGRF_SOC_CON(5));
716 
717 	writel_relaxed(0x00010001, pmu_base + RV1106_PMU_INT_MASK_CON);
718 	writel_relaxed(WITH_16BITS_WMSK(pmu_scu_con), pmu_base + RV1106_PMU_SCU_PWR_CON);
719 
720 	writel_relaxed(WITH_16BITS_WMSK(pmu_cru_con[0]), pmu_base + RV1106_PMU_CRU_PWR_CON0);
721 	writel_relaxed(WITH_16BITS_WMSK(pmu_cru_con[1]), pmu_base + RV1106_PMU_CRU_PWR_CON1);
722 	writel_relaxed(WITH_16BITS_WMSK(pmu_bus_idle_con), pmu_base + RV1106_PMU_BIU_IDLE_CON);
723 
724 	writel_relaxed(WITH_16BITS_WMSK(pmu_ddr_con), pmu_base + RV1106_PMU_DDR_PWR_CON);
725 	writel_relaxed(WITH_16BITS_WMSK(pmu_pll_con), pmu_base + RV1106_PMU_PLLPD_CON);
726 	writel_relaxed(pmu_wkup_con, pmu_base + RV1106_PMU_WAKEUP_INT_CON);
727 	writel_relaxed(WITH_16BITS_WMSK(pmu_pwr_con), pmu_base + RV1106_PMU_PWR_CON);
728 
729 #if RV1106_WAKEUP_TO_SYSTEM_RESET
730 	writel_relaxed(0, pmugrf_base + RV1106_PMUGRF_OS_REG(9));
731 	/* Use PMUGRF_OS_REG10 to save wakeup source */
732 	writel_relaxed(0, pmugrf_base + RV1106_PMUGRF_OS_REG(10));
733 #else
734 	writel_relaxed(PMU_SUSPEND_MAGIC, pmugrf_base + RV1106_PMUGRF_OS_REG(9));
735 #endif
736 }
737 
pmu_sleep_restore(void)738 static void pmu_sleep_restore(void)
739 {
740 	ddr_data.pmu_wkup_int_st = readl_relaxed(pmu_base + RV1106_PMU_WAKEUP_INT_ST);
741 	ddr_data.gpio0_int_st = readl_relaxed(gpio_base[0] + RV1106_GPIO_INT_STATUS);
742 
743 	writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_INFO_TX_CON);
744 	writel_relaxed(0x00010000, pmu_base + RV1106_PMU_INT_MASK_CON);
745 	writel_relaxed(0x00000000, pmu_base + RV1106_PMU_WAKEUP_INT_CON);
746 	writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_PWR_CON);
747 	writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_BIU_IDLE_CON);
748 	writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_DDR_PWR_CON);
749 	writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_SCU_PWR_CON);
750 	writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_PLLPD_CON);
751 	writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_CRU_PWR_CON0);
752 	writel_relaxed(0xffff0000, pmu_base + RV1106_PMU_CRU_PWR_CON1);
753 
754 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.ioc1_1a_iomux_l),
755 		       ioc_base[1] + 0);
756 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmugrf_soc_con1),
757 		       pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
758 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmugrf_soc_con4),
759 		       pmugrf_base + RV1106_PMUGRF_SOC_CON(4));
760 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmugrf_soc_con5),
761 		       pmugrf_base + RV1106_PMUGRF_SOC_CON(5));
762 }
763 
soc_sleep_config(void)764 static void soc_sleep_config(void)
765 {
766 	ddr_data.ioc0_1a_iomux_l = readl_relaxed(ioc_base[0] + 0);
767 
768 	rkpm_printch('a');
769 
770 	pvtm_32k_config(0);
771 	rkpm_printch('b');
772 
773 	ddr_sleep_config();
774 	rkpm_printch('c');
775 
776 	pmu_sleep_config();
777 	rkpm_printch('d');
778 }
779 
soc_sleep_restore(void)780 static void soc_sleep_restore(void)
781 {
782 	rkpm_printch('d');
783 
784 	pmu_sleep_restore();
785 	rkpm_printch('c');
786 
787 	ddr_sleep_config_restore();
788 	rkpm_printch('b');
789 
790 	pvtm_32k_config_restore();
791 	rkpm_printch('a');
792 
793 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.ioc0_1a_iomux_l),
794 		       ioc_base[0] + 0);
795 }
796 
plls_suspend(void)797 static void plls_suspend(void)
798 {
799 }
800 
plls_resume(void)801 static void plls_resume(void)
802 {
803 }
804 
gpio0_set_iomux(u32 pin_id,u32 func)805 static void gpio0_set_iomux(u32 pin_id, u32 func)
806 {
807 	u32 sft = (pin_id % 4) << 2;
808 
809 	if (pin_id < 4)
810 		writel_relaxed(BITS_WITH_WMASK(func, 0xf, sft), ioc_base[0] + 0);
811 	else
812 		writel_relaxed(BITS_WITH_WMASK(func, 0xf, sft), ioc_base[0] + 4);
813 }
814 
gpio0_set_pull(u32 pin_id,int pull)815 static void gpio0_set_pull(u32 pin_id, int pull)
816 {
817 	u32 sft = (pin_id % 8) << 1;
818 
819 	writel_relaxed(BITS_WITH_WMASK(pull, 0x3, sft), ioc_base[0] + 0x38);
820 }
821 
gpio0_set_direct(u32 pin_id,int out)822 static void gpio0_set_direct(u32 pin_id, int out)
823 {
824 	u32 sft = (pin_id % 16);
825 
826 	if (pin_id < 16)
827 		writel_relaxed(BITS_WITH_WMASK(out, 0x1, sft),
828 			       gpio_base[0] + RV1106_GPIO_SWPORT_DDR_L);
829 	else
830 		writel_relaxed(BITS_WITH_WMASK(out, 0x1, sft),
831 			       gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H);
832 }
833 
gpio_config(void)834 static void gpio_config(void)
835 {
836 	ddr_data.gpio0a_iomux_l = readl_relaxed(ioc_base[0] + 0);
837 	ddr_data.gpio0a_iomux_h = readl_relaxed(ioc_base[0] + 0x4);
838 	ddr_data.gpio0a0_pull = readl_relaxed(ioc_base[0] + 0x38);
839 	ddr_data.gpio0_ddr_l = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_L);
840 	ddr_data.gpio0_ddr_h = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H);
841 
842 	/* gpio0_a0, input, pulldown */
843 	gpio0_set_iomux(0, 0);
844 	gpio0_set_pull(0, RV1106_GPIO_PULL_DOWN);
845 	gpio0_set_direct(0, 0);
846 
847 #ifdef RV1106_GPIO0_A1_LOWPOWER
848 	/* gpio0_a1, input, pulldown */
849 	gpio0_set_iomux(1, 0);
850 	gpio0_set_pull(1, RV1106_GPIO_PULL_DOWN);
851 	gpio0_set_direct(1, 0);
852 #endif
853 	/* gpio0_a2, input, pulldown */
854 	gpio0_set_iomux(2, 0);
855 	gpio0_set_pull(2, RV1106_GPIO_PULL_DOWN);
856 	gpio0_set_direct(2, 0);
857 
858 	/* gpio0_a3, pullnone */
859 	gpio0_set_pull(3, RV1106_GPIO_PULL_NONE);
860 
861 	/* gpio0_a4, input, pulldown */
862 	gpio0_set_iomux(4, 0);
863 	gpio0_set_pull(4, RV1106_GPIO_PULL_DOWN);
864 	gpio0_set_direct(4, 0);
865 
866 	/* gpio0_a5, input, pullnone */
867 	gpio0_set_iomux(5, 0);
868 	gpio0_set_pull(5, RV1106_GPIO_PULL_NONE);
869 	gpio0_set_direct(5, 0);
870 
871 	/* gpio0_a6, input, pullnone */
872 	gpio0_set_iomux(6, 0);
873 	gpio0_set_pull(6, RV1106_GPIO_PULL_NONE);
874 	gpio0_set_direct(6, 0);
875 }
876 
gpio_restore(void)877 static void gpio_restore(void)
878 {
879 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_l), ioc_base[0] + 0);
880 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_h), ioc_base[0] + 0x4);
881 
882 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a0_pull), ioc_base[0] + 0x38);
883 
884 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0_ddr_l),
885 		       gpio_base[0] + RV1106_GPIO_SWPORT_DDR_L);
886 	writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0_ddr_h),
887 		       gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H);
888 }
889 
890 static struct uart_debug_ctx debug_port_save;
891 static u32 cru_mode;
892 
vd_log_regs_save(void)893 static void vd_log_regs_save(void)
894 {
895 	cru_mode = readl_relaxed(cru_base + 0x280);
896 
897 	rkpm_printch('a');
898 
899 	gic400_save();
900 	rkpm_printch('b');
901 
902 	rkpm_reg_rgn_save(vd_core_reg_rgns, ARRAY_SIZE(vd_core_reg_rgns));
903 	rkpm_printch('c');
904 	rkpm_reg_rgn_save(vd_log_reg_rgns, ARRAY_SIZE(vd_log_reg_rgns));
905 	rkpm_printch('d');
906 
907 	rkpm_uart_debug_save(uartdbg_base, &debug_port_save);
908 	rkpm_printch('e');
909 }
910 
vd_log_regs_restore(void)911 static void vd_log_regs_restore(void)
912 {
913 	rkpm_uart_debug_restore(uartdbg_base, &debug_port_save);
914 
915 	/* slow mode */
916 	writel_relaxed(0x003f0000, cru_base + 0x280);
917 
918 	rkpm_reg_rgn_restore(vd_core_reg_rgns, ARRAY_SIZE(vd_core_reg_rgns));
919 	rkpm_reg_rgn_restore(vd_log_reg_rgns, ARRAY_SIZE(vd_log_reg_rgns));
920 
921 	/* wait lock */
922 	pm_pll_wait_lock(RV1106_APLL_ID);
923 	pm_pll_wait_lock(RV1106_CPLL_ID);
924 	pm_pll_wait_lock(RV1106_GPLL_ID);
925 
926 	/* restore mode */
927 	writel_relaxed(WITH_16BITS_WMSK(cru_mode), cru_base + 0x280);
928 
929 	gic400_restore();
930 }
931 
rkpm_reg_rgns_init(void)932 static void rkpm_reg_rgns_init(void)
933 {
934 	rkpm_alloc_region_mem(vd_core_reg_rgns, ARRAY_SIZE(vd_core_reg_rgns));
935 	rkpm_alloc_region_mem(vd_log_reg_rgns, ARRAY_SIZE(vd_log_reg_rgns));
936 }
937 
rkpm_regs_rgn_dump(void)938 static void rkpm_regs_rgn_dump(void)
939 {
940 	return;
941 
942 	rkpm_dump_reg_rgns(vd_core_reg_rgns, ARRAY_SIZE(vd_core_reg_rgns));
943 	rkpm_dump_reg_rgns(vd_log_reg_rgns, ARRAY_SIZE(vd_log_reg_rgns));
944 }
945 
rockchip_lpmode_enter(unsigned long arg)946 static int rockchip_lpmode_enter(unsigned long arg)
947 {
948 	flush_cache_all();
949 
950 	cpu_do_idle();
951 
952 	pr_err("%s: Failed to suspend\n", __func__);
953 
954 	return 1;
955 }
956 
rv1106_suspend_enter(suspend_state_t state)957 static int rv1106_suspend_enter(suspend_state_t state)
958 {
959 	rkpm_printstr("rv1106 enter sleep\n");
960 
961 	local_fiq_disable();
962 
963 	rv1106_dbg_irq_prepare();
964 
965 	rkpm_printch('-');
966 
967 	clock_suspend();
968 	rkpm_printch('0');
969 
970 	soc_sleep_config();
971 	rkpm_printch('1');
972 
973 	plls_suspend();
974 	rkpm_printch('2');
975 
976 	gpio_config();
977 	rkpm_printch('3');
978 
979 	vd_log_regs_save();
980 	rkpm_regs_rgn_dump();
981 	rkpm_printch('4');
982 
983 	rkpm_printstr("-WFI-");
984 	cpu_suspend(0, rockchip_lpmode_enter);
985 
986 	rkpm_printch('4');
987 
988 	vd_log_regs_restore();
989 	rkpm_printch('3');
990 	rkpm_regs_rgn_dump();
991 
992 	gpio_restore();
993 	rkpm_printch('2');
994 
995 	plls_resume();
996 	rkpm_printch('1');
997 
998 	soc_sleep_restore();
999 	rkpm_printch('0');
1000 
1001 	clock_resume();
1002 	rkpm_printch('-');
1003 
1004 	fiq_glue_resume();
1005 
1006 	rv1106_dbg_irq_finish();
1007 
1008 	local_fiq_enable();
1009 	rkpm_printstr("rv1106 exit sleep\n");
1010 
1011 	return 0;
1012 }
1013 
rv1106_suspend_init(struct device_node * np)1014 static int __init rv1106_suspend_init(struct device_node *np)
1015 {
1016 	void __iomem *dev_reg_base;
1017 
1018 	dev_reg_base = ioremap(RV1106_DEV_REG_BASE, RV1106_DEV_REG_SIZE);
1019 	if (dev_reg_base)
1020 		pr_info("%s map dev_reg 0x%x -> 0x%x\n",
1021 			__func__, RV1106_DEV_REG_BASE, (u32)dev_reg_base);
1022 	else
1023 		pr_err("%s: can't map dev_reg(0x%x)\n", __func__, RV1106_DEV_REG_BASE);
1024 
1025 	gicd_base = dev_reg_base + RV1106_GIC_OFFSET + 0x1000;
1026 	gicc_base = dev_reg_base + RV1106_GIC_OFFSET + 0x2000;
1027 
1028 	firewall_ddr_base = dev_reg_base + RV1106_FW_DDR_OFFSET;
1029 	firewall_syssram_base = dev_reg_base + RV1106_FW_SRAM_OFFSET;
1030 
1031 	nstimer_base = dev_reg_base + RV1106_NSTIMER_OFFSET;
1032 	stimer_base = dev_reg_base + RV1106_STIMER_OFFSET;
1033 
1034 	pmu_base = dev_reg_base + RV1106_PMU_OFFSET;
1035 	uartdbg_base = dev_reg_base + RV1106_UART2_OFFSET;
1036 	pmupvtm_base = dev_reg_base + RV1106_PMUPVTM_OFFSET;
1037 	pmusgrf_base = dev_reg_base + RV1106_PMUSGRF_OFFSET;
1038 	ddrc_base = dev_reg_base + RV1106_DDRC_OFFSET;
1039 
1040 	perigrf_base = dev_reg_base + RV1106_PERIGRF_OFFSET;
1041 	vencgrf_base = dev_reg_base + RV1106_VENCGRF_OFFSET;
1042 	npugrf_base = dev_reg_base + RV1106_NPUGRF_OFFSET;
1043 	pmugrf_base = dev_reg_base + RV1106_PMUGRF_OFFSET;
1044 	ddrgrf_base = dev_reg_base + RV1106_DDRGRF_OFFSET;
1045 	coregrf_base = dev_reg_base + RV1106_COREGRF_OFFSET;
1046 	vigrf_base = dev_reg_base + RV1106_VIGRF_OFFSET;
1047 	vogrf_base = dev_reg_base + RV1106_VOGRF_OFFSET;
1048 
1049 	perisgrf_base = dev_reg_base + RV1106_PERISGRF_OFFSET;
1050 	visgrf_base = dev_reg_base + RV1106_VIGRF_OFFSET;
1051 	npusgrf_base = dev_reg_base + RV1106_NPUSGRF_OFFSET;
1052 	coresgrf_base = dev_reg_base + RV1106_CORESGRF_OFFSET;
1053 	vencsgrf_base = dev_reg_base + RV1106_VENCSGRF_OFFSET;
1054 	vosgrf_base = dev_reg_base + RV1106_VOSGRF_OFFSET;
1055 	pmusgrf_base = dev_reg_base + RV1106_PMUSGRF_OFFSET;
1056 
1057 	pmucru_base = dev_reg_base + RV1106_PMUCRU_OFFSET;
1058 	cru_base = dev_reg_base + RV1106_CRU_OFFSET;
1059 	pericru_base = dev_reg_base + RV1106_PERICRU_OFFSET;
1060 	vicru_base = dev_reg_base + RV1106_VICRU_OFFSET;
1061 	npucru_base = dev_reg_base + RV1106_NPUCRU_OFFSET;
1062 	corecru_base = dev_reg_base + RV1106_CORECRU_OFFSET;
1063 	venccru_base = dev_reg_base + RV1106_VENCCRU_OFFSET;
1064 	vocru_base = dev_reg_base + RV1106_VOCRU_OFFSET;
1065 
1066 	ioc_base[0] = dev_reg_base + RV1106_GPIO0IOC_OFFSET;
1067 	ioc_base[1] = dev_reg_base + RV1106_GPIO1IOC_OFFSET;
1068 	ioc_base[2] = dev_reg_base + RV1106_GPIO2IOC_OFFSET;
1069 	ioc_base[3] = dev_reg_base + RV1106_GPIO3IOC_OFFSET;
1070 	ioc_base[4] = dev_reg_base + RV1106_GPIO4IOC_OFFSET;
1071 
1072 	gpio_base[0] = dev_reg_base + RV1106_GPIO0_OFFSET;
1073 	gpio_base[1] = dev_reg_base + RV1106_GPIO1_OFFSET;
1074 	gpio_base[2] = dev_reg_base + RV1106_GPIO2_OFFSET;
1075 	gpio_base[3] = dev_reg_base + RV1106_GPIO3_OFFSET;
1076 	gpio_base[4] = dev_reg_base + RV1106_GPIO4_OFFSET;
1077 
1078 	rv1106_bootram_base = dev_reg_base + RV1106_PMUSRAM_OFFSET;
1079 
1080 	rv1106_config_bootdata();
1081 
1082 	/* copy resume code and data to bootsram */
1083 	memcpy(rv1106_bootram_base, rockchip_slp_cpu_resume,
1084 	       rv1106_bootram_sz + 0x50);
1085 
1086 	/* remap */
1087 #if RV1106_WAKEUP_TO_SYSTEM_RESET
1088 	writel_relaxed(BITS_WITH_WMASK(1, 0x1, 10), pmusgrf_base + RV1106_PMUSGRF_SOC_CON(1));
1089 #else
1090 	writel_relaxed(BITS_WITH_WMASK(0, 0x1, 10), pmusgrf_base + RV1106_PMUSGRF_SOC_CON(1));
1091 #endif
1092 	/* biu auto con */
1093 	writel_relaxed(0x07ff07ff, pmu_base + RV1106_PMU_BIU_AUTO_CON);
1094 
1095 	rkpm_region_mem_init(RV1106_PM_REG_REGION_MEM_SIZE);
1096 	rkpm_reg_rgns_init();
1097 
1098 	return 0;
1099 }
1100 
1101 static const struct platform_suspend_ops rv1106_suspend_ops = {
1102 	.enter   = rv1106_suspend_enter,
1103 	.valid   = suspend_valid_only_mem,
1104 };
1105 
1106 static const struct rockchip_pm_data rv1106_pm_data __initconst = {
1107 	.ops = &rv1106_suspend_ops,
1108 	.init = rv1106_suspend_init,
1109 };
1110 
1111 /****************************************************************************/
1112 static const struct of_device_id rockchip_pmu_of_device_ids[] __initconst = {
1113 	{
1114 		.compatible = "rockchip,rv1106-pmu",
1115 		.data = &rv1106_pm_data,
1116 	},
1117 	{ /* sentinel */ },
1118 };
1119 
rockchip_suspend_init(void)1120 void __init rockchip_suspend_init(void)
1121 {
1122 	const struct rockchip_pm_data *pm_data;
1123 	const struct of_device_id *match;
1124 	struct device_node *np;
1125 	int ret;
1126 
1127 	np = of_find_matching_node_and_match(NULL, rockchip_pmu_of_device_ids,
1128 					     &match);
1129 	if (!match) {
1130 		pr_err("Failed to find PMU node\n");
1131 		return;
1132 	}
1133 	pm_data = (struct rockchip_pm_data *)match->data;
1134 
1135 	if (pm_data->init) {
1136 		ret = pm_data->init(np);
1137 
1138 		if (ret) {
1139 			pr_err("%s: matches init error %d\n", __func__, ret);
1140 			return;
1141 		}
1142 	}
1143 
1144 	suspend_set_ops(pm_data->ops);
1145 }
1146