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