ARM: rockchip: rk3228: implement function rk3228_restart
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / pm-rk3188.c
1
2 #include <linux/kernel.h>
3 #include <linux/init.h>
4 #include <asm/cacheflush.h>
5 #include <asm/tlbflush.h>
6 #include <asm/hardware/cache-l2x0.h>
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
9
10 #include <linux/pm.h>
11 #include <linux/suspend.h>
12 #include <linux/of.h>
13 #include <asm/io.h>
14 #include <linux/of.h>
15 #include <linux/of_address.h>
16
17 #include <linux/rockchip/cpu.h>
18 #include <linux/rockchip/cru.h>
19 #include <linux/rockchip/grf.h>
20 #include <linux/rockchip/iomap.h>
21 #include "pm.h"
22
23 #define CPU 3188
24 //#include "sram.h"
25 #include "pm-pie.c"
26
27 #define RK3188_CLK_GATING_OPS(ID) cru_writel((0x1<<((ID%16)+16))|(0x1<<(ID%16)),RK3188_CRU_GATEID_CONS(ID))
28 #define RK3188_CLK_UNGATING_OPS(ID) cru_writel(0x1<<((ID%16)+16),RK3188_CRU_GATEID_CONS(ID))
29
30 /*************************cru define********************************************/
31 /*******************CRU BITS*******************************/
32 #define CRU_W_MSK(bits_shift, msk)      ((msk) << ((bits_shift) + 16))
33 #define CRU_SET_BITS(val, bits_shift, msk)      (((val)&(msk)) << (bits_shift))
34 #define CRU_W_MSK_SETBITS(val, bits_shift,msk) \
35         (CRU_W_MSK(bits_shift, msk) | CRU_SET_BITS(val, bits_shift, msk))
36         
37 #define RK3188_CRU_GET_REG_BITS_VAL(reg,bits_shift, msk)  (((reg) >> (bits_shift))&(msk))
38 #define RK3188_CRU_W_MSK(bits_shift, msk)       ((msk) << ((bits_shift) + 16))
39 #define RK3188_CRU_SET_BITS(val,bits_shift, msk)        (((val)&(msk)) << (bits_shift))
40     
41 #define RK3188_CRU_W_MSK_SETBITS(val,bits_shift,msk) \
42         (RK3188_CRU_W_MSK(bits_shift, msk)|RK3188_CRU_SET_BITS(val,bits_shift, msk))
43     
44     
45 /*******************RK3188_PLL CON3 BITS***************************/
46
47 #define RK3188_PLL_PWR_DN_MSK           (1 << 1)
48 #define RK3188_PLL_PWR_DN_W_MSK (RK3188_PLL_PWR_DN_MSK << 16)
49 #define RK3188_PLL_PWR_DN               (1 << 1)
50 #define RK3188_PLL_PWR_ON               (0 << 1)
51     
52
53
54 /*******************CLKSEL0 BITS***************************/
55 //RK3188_CORE_preiph div
56 #define RK3188_CORE_PERIPH_W_MSK        (3 << 22)
57 #define RK3188_CORE_PERIPH_MSK          (3 << 6)
58 #define RK3188_CORE_PERIPH_2            (0 << 6)
59 #define RK3188_CORE_PERIPH_4            (1 << 6)
60 #define RK3188_CORE_PERIPH_8            (2 << 6)
61 #define RK3188_CORE_PERIPH_16           (3 << 6)
62
63 //clk_RK3188_CORE
64 #define RK3188_CORE_SEL_PLL_MSK (1 << 8)
65 #define RK3188_CORE_SEL_PLL_W_MSK       (1 << 24)
66 #define RK3188_CORE_SEL_APLL            (0 << 8)
67 #define RK3188_CORE_SEL_GPLL            (1 << 8)
68
69 #define RK3188_CORE_CLK_DIV_W_MSK       (0x1F << 25)
70 #define RK3188_CORE_CLK_DIV_MSK (0x1F << 9)
71 #define RK3188_CORE_CLK_DIV(i)          ((((i) - 1) & 0x1F) << 9)
72 #define RK3188_CORE_CLK_MAX_DIV 32
73
74 #define RK3188_CPU_SEL_PLL_MSK          (1 << 5)
75 #define RK3188_CPU_SEL_PLL_W_MSK        (1 << 21)
76 #define RK3188_CPU_SEL_APLL             (0 << 5)
77 #define RK3188_CPU_SEL_GPLL             (1 << 5)
78
79 #define RK3188_CPU_CLK_DIV_W_MSK        (0x1F << 16)
80 #define RK3188_CPU_CLK_DIV_MSK          (0x1F)
81 #define RK3188_CPU_CLK_DIV(i)           (((i) - 1) & 0x1F)
82
83 /*******************CLKSEL1 BITS***************************/
84 //aclk div
85 #define RK3188_GET_CORE_ACLK_VAL(reg) ((reg)>=4 ?8:((reg)+1))
86
87 #define RK3188_CORE_ACLK_W_MSK          (7 << 19)
88 #define RK3188_CORE_ACLK_MSK            (7 << 3)
89 #define RK3188_CORE_ACLK_11             (0 << 3)
90 #define RK3188_CORE_ACLK_21             (1 << 3)
91 #define RK3188_CORE_ACLK_31             (2 << 3)
92 #define RK3188_CORE_ACLK_41             (3 << 3)
93 #define RK3188_CORE_ACLK_81             (4 << 3)
94 //hclk div
95 #define RK3188_ACLK_HCLK_W_MSK          (3 << 24)
96 #define RK3188_ACLK_HCLK_MSK            (3 << 8)
97 #define RK3188_ACLK_HCLK_11             (0 << 8)
98 #define RK3188_ACLK_HCLK_21             (1 << 8)
99 #define RK3188_ACLK_HCLK_41             (2 << 8)
100 // pclk div
101 #define RK3188_ACLK_PCLK_W_MSK          (3 << 28)
102 #define RK3188_ACLK_PCLK_MSK            (3 << 12)
103 #define RK3188_ACLK_PCLK_11             (0 << 12)
104 #define RK3188_ACLK_PCLK_21             (1 << 12)
105 #define RK3188_ACLK_PCLK_41             (2 << 12)
106 #define RK3188_ACLK_PCLK_81             (3 << 12)
107 // ahb2apb div
108 #define RK3188_AHB2APB_W_MSK            (3 << 30)
109 #define RK3188_AHB2APB_MSK              (3 << 14)
110 #define RK3188_AHB2APB_11               (0 << 14)
111 #define RK3188_AHB2APB_21               (1 << 14)
112 #define RK3188_AHB2APB_41               (2 << 14)
113
114 /*******************clksel10***************************/
115
116 #define RK3188_PERI_ACLK_DIV_MASK 0x1f
117 #define RK3188_PERI_ACLK_DIV_W_MSK      (RK3188_PERI_ACLK_DIV_MASK << 16)
118 #define RK3188_PERI_ACLK_DIV(i) (((i) - 1) & RK3188_PERI_ACLK_DIV_MASK)
119 #define RK3188_PERI_ACLK_DIV_OFF 0
120
121 #define RK3188_PERI_HCLK_DIV_MASK 0x3
122 #define RK3188_PERI_HCLK_DIV_OFF 8
123
124 #define RK3188_PERI_PCLK_DIV_MASK 0x3
125 #define RK3188_PERI_PCLK_DIV_OFF 12
126
127
128
129 /*************************gate id**************************************/
130 #define RK3188_CLK_GATEID(i)    (16 * (i))
131
132
133 enum cru_clk_gate {
134         /* SCU CLK GATE 0 CON */
135         RK3188_CLKGATE_CORE_PERIPH = RK3188_CLK_GATEID(0),
136
137         RK3188_CLKGATE_TIMER0 = RK3188_CLK_GATEID(1),
138         RK3188_CLKGATE_UART0_SRC=RK3188_CLK_GATEID(1)+8,
139         RK3188_CLKGATE_UART0_FRAC_SRC,
140
141         RK3188_CLKGATE_PCLK_UART0 = RK3188_CLK_GATEID(8),
142         
143
144         RK3188_CLKGATE_CLK_CORE_DBG = RK3188_CLK_GATEID(9),
145
146         RK3188_CLKGATE_MAX= RK3188_CLK_GATEID(10),
147 };
148 /*******************************gpio define **********************************************/
149 #define GPIO_INTEN                      0x30
150 #define GPIO_INTMASK            0x34
151 #define GPIO_INTTYPE_LEVEL      0x38
152 #define GPIO_INT_POLARITY       0x3c
153 #define GPIO_INT_STATUS         0x40
154
155 /*******************************common code  for rkxxx*********************************/
156
157 static void  inline uart_printch(char byte)
158 {
159         u32 reg_save[2];
160         u32 u_clk_id=(RK3188_CLKGATE_UART0_SRC+CONFIG_RK_DEBUG_UART);
161         u32 u_pclk_id=(RK3188_CLKGATE_PCLK_UART0+CONFIG_RK_DEBUG_UART);
162         
163         reg_save[0]=cru_readl(RK3188_CRU_GATEID_CONS(u_clk_id));
164         reg_save[1]=cru_readl(RK3188_CRU_GATEID_CONS(u_pclk_id));
165         RK3188_CLK_UNGATING_OPS(u_clk_id);
166         RK3188_CLK_UNGATING_OPS(u_pclk_id);
167         
168         rkpm_udelay(1);
169         
170 write_uart:
171         writel_relaxed(byte, RK_DEBUG_UART_VIRT);
172         dsb();
173
174         /* loop check LSR[6], Transmitter Empty bit */
175         while (!(readl_relaxed(RK_DEBUG_UART_VIRT + 0x14) & 0x40))
176                 barrier();
177     
178         if (byte == '\n') {
179                 byte = '\r';
180                 goto write_uart;
181         }
182
183          cru_writel(reg_save[0]|0x1<<((u_pclk_id%16)+16),RK3188_CRU_GATEID_CONS(u_clk_id));         
184          cru_writel(reg_save[1]|0x1<<((u_pclk_id%16)+16),RK3188_CRU_GATEID_CONS(u_pclk_id));
185 }
186
187 void PIE_FUNC(sram_printch)(char byte)
188 {
189         uart_printch(byte);
190 }
191
192 static void  ddr_printch(char byte)
193 {
194         uart_printch(byte);
195 }
196 /*******************************clk gating config*******************************************/
197 #define CLK_MSK_GATING(msk, con) cru_writel((msk << 16) | 0xffff, con)
198 #define CLK_MSK_UNGATING(msk, con) cru_writel(((~msk) << 16) | 0xffff, con)
199
200
201 static u32 clk_ungt_msk[RK3188_CRU_CLKGATES_CON_CNT];// first clk gating setting
202 static u32 clk_ungt_save[RK3188_CRU_CLKGATES_CON_CNT]; //first clk gating value saveing
203
204
205 u32 DEFINE_PIE_DATA(rkpm_clkgt_last_set[RK3188_CRU_CLKGATES_CON_CNT]);
206 static u32 *p_rkpm_clkgt_last_set;
207
208 u32 DEFINE_PIE_DATA(rkpm_clkgt_last_save[RK3188_CRU_CLKGATES_CON_CNT]);
209 static u32 *p_rkpm_clkgt_last_save;
210
211 void PIE_FUNC(gtclks_sram_suspend)(void)
212 {
213     int i;
214    // u32 u_clk_id=(RK3188_CLKGATE_UART0_SRC+CONFIG_RK_DEBUG_UART);
215    // u32 u_pclk_id=(RK3188_CLKGATE_PCLK_UART0+CONFIG_RK_DEBUG_UART);
216
217     for(i=0;i<RK3188_CRU_CLKGATES_CON_CNT;i++)
218     {
219         DATA(rkpm_clkgt_last_save[i])=cru_readl(RK3188_CRU_CLKGATES_CON(i));     
220         CLK_MSK_UNGATING( DATA(rkpm_clkgt_last_set[i]), RK3188_CRU_CLKGATES_CON(i));      
221         #if 0
222         rkpm_sram_printch('\n');   
223         rkpm_sram_printhex(DATA(rkpm_clkgt_last_save[i]));
224         rkpm_sram_printch('-');   
225         rkpm_sram_printhex(DATA(rkpm_clkgt_last_set[i]));
226         rkpm_sram_printch('-');   
227         rkpm_sram_printhex(cru_readl(RK3188_CRU_CLKGATES_CON(i)));
228         if(i==(RK3188_CRU_CLKGATES_CON_CNT-1))         
229         rkpm_sram_printch('\n');   
230         #endif
231     }
232     
233         //RK3188_CLK_UNGATING_OPS(u_clk_id);
234         //RK3188_CLK_UNGATING_OPS(u_pclk_id);
235  
236 }
237
238 void PIE_FUNC(gtclks_sram_resume)(void)
239 {
240     int i;
241     for(i=0;i<RK3188_CRU_CLKGATES_CON_CNT;i++)
242     {
243         cru_writel(DATA(rkpm_clkgt_last_save[i])|0xffff0000, RK3188_CRU_CLKGATES_CON(i));
244     }
245 }
246
247 static void gtclks_suspend(void)
248 {
249     int i;
250     
251     for(i=0;i<RK3188_CRU_CLKGATES_CON_CNT;i++)
252     {
253     
254         clk_ungt_save[i]=cru_readl(RK3188_CRU_CLKGATES_CON(i));    
255         //if(i!=4||i!=0)
256         CLK_MSK_UNGATING(clk_ungt_msk[i],RK3188_CRU_CLKGATES_CON(i));
257        #if 0
258         rkpm_ddr_printch('\n');   
259         rkpm_ddr_printhex(clk_ungt_save[i]);
260         rkpm_ddr_printch('-');   
261         rkpm_ddr_printhex(clk_ungt_msk[i]);
262         rkpm_ddr_printch('-');   
263         rkpm_ddr_printhex(cru_readl(RK3188_CRU_CLKGATES_CON(i))) ;  
264         if(i==(RK3188_CRU_CLKGATES_CON_CNT-1))            
265             rkpm_ddr_printch('\n');   
266         #endif
267     }
268
269 }
270
271 static void gtclks_resume(void)
272 {
273     int i;
274      for(i=0;i<RK3188_CRU_CLKGATES_CON_CNT;i++)
275     {
276        cru_writel(clk_ungt_save[i]|0xffff0000,RK3188_CRU_CLKGATES_CON(i));
277     }
278     
279 }
280
281 /********************************pll power down***************************************/
282
283 #define power_off_pll(id) \
284         cru_writel(RK3188_PLL_PWR_DN_W_MSK | RK3188_PLL_PWR_DN, RK3188_PLL_CONS((id), 3))
285 #if 0
286
287 static void pm_pll_wait_lock(u32 pll_idx)
288 {
289         u32 pll_state[4] = { 1, 0, 2, 3 };
290         u32 bit = 0x20u << pll_state[pll_idx];
291         u32 delay = pll_idx == RK3188_APLL_ID ? 600000U : 30000000U;
292         dsb();
293         dsb();
294         dsb();
295         dsb();
296         dsb();
297         dsb();
298         while (delay > 0) {
299                 if (grf_readl(RK3188_GRF_SOC_STATUS0) & bit)
300                         break;
301                 delay--;
302         }
303         if (delay == 0) {
304                 //CRU_PRINTK_ERR("wait pll bit 0x%x time out!\n", bit); 
305                 rkpm_ddr_printch('p');
306                 rkpm_ddr_printch('l');
307                 rkpm_ddr_printch('l');
308                 rkpm_ddr_printhex(pll_idx);
309                 rkpm_ddr_printch('\n');
310         }
311 }       
312 static void power_on_pll(u32 pll_id)
313 {
314         cru_writel(RK3188_PLL_PWR_DN_W_MSK | RK3188_PLL_PWR_ON, RK3188_PLL_CONS((pll_id), 3));
315         pm_pll_wait_lock((pll_id));
316 }
317 #endif
318 static u32 clk_sel0, clk_sel1, clk_sel10;
319 static u32 cpll_con3;
320 static u32 cru_mode_con;
321
322 static void plls_suspend(void)
323 {
324     cru_mode_con = cru_readl(RK3188_CRU_MODE_CON);
325     cru_writel(RK3188_PLL_MODE_SLOW(RK3188_CPLL_ID), RK3188_CRU_MODE_CON);
326
327     cpll_con3 = cru_readl(RK3188_PLL_CONS(RK3188_CPLL_ID, 3));
328    //power_off_pll(RK3188_CPLL_ID);
329        
330
331        //apll
332        clk_sel0 = cru_readl(RK3188_CRU_CLKSELS_CON(0));
333        clk_sel1 = cru_readl(RK3188_CRU_CLKSELS_CON(1));
334
335        cru_writel(RK3188_PLL_MODE_SLOW(RK3188_APLL_ID), RK3188_CRU_MODE_CON);
336        
337        /* To make sure aclk_cpu select apll before div effect */
338        cru_writel(RK3188_CPU_SEL_PLL_W_MSK | RK3188_CPU_SEL_APLL
339                           | RK3188_CORE_SEL_PLL_W_MSK | RK3188_CORE_SEL_APLL
340                           , RK3188_CRU_CLKSELS_CON(0));
341        cru_writel(RK3188_CORE_PERIPH_W_MSK | RK3188_CORE_PERIPH_2
342               | RK3188_CORE_CLK_DIV_W_MSK | RK3188_CORE_CLK_DIV(1)
343               | RK3188_CPU_CLK_DIV_W_MSK | RK3188_CPU_CLK_DIV(1)
344               , RK3188_CRU_CLKSELS_CON(0));
345        cru_writel(RK3188_CORE_ACLK_W_MSK | RK3188_CORE_ACLK_11
346               | RK3188_ACLK_HCLK_W_MSK | RK3188_ACLK_HCLK_11
347               | RK3188_ACLK_PCLK_W_MSK | RK3188_ACLK_PCLK_11
348               | RK3188_AHB2APB_W_MSK | RK3188_AHB2APB_11
349               , RK3188_CRU_CLKSELS_CON(1));
350        //power_off_pll(RK3188_APLL_ID);
351     cru_writel(RK3188_PLL_MODE_SLOW(RK3188_GPLL_ID), RK3188_CRU_MODE_CON);
352
353        
354     clk_sel10 = cru_readl(RK3188_CRU_CLKSELS_CON(10));
355     cru_writel(RK3188_CRU_W_MSK_SETBITS(0, RK3188_PERI_ACLK_DIV_OFF, RK3188_PERI_ACLK_DIV_MASK)
356     | RK3188_CRU_W_MSK_SETBITS(0,RK3188_PERI_HCLK_DIV_OFF, RK3188_PERI_HCLK_DIV_MASK)
357     | RK3188_CRU_W_MSK_SETBITS(0, RK3188_PERI_PCLK_DIV_OFF, RK3188_PERI_PCLK_DIV_MASK)
358     , RK3188_CRU_CLKSELS_CON(10));
359     
360   //power_off_pll(RK3188_GPLL_ID);
361
362 }
363
364 static void plls_resume(void)
365 {
366     //gpll
367        
368         cru_writel(0xffff0000 | clk_sel10, RK3188_CRU_CLKSELS_CON(10));
369     
370       // power_on_pll(RK3188_GPLL_ID);
371         cru_writel((RK3188_PLL_MODE_MSK(RK3188_GPLL_ID) << 16) 
372                         | (RK3188_PLL_MODE_MSK(RK3188_GPLL_ID) & cru_mode_con)
373                         ,  RK3188_CRU_MODE_CON);
374
375         //apll
376         cru_writel(0xffff0000 | clk_sel1, RK3188_CRU_CLKSELS_CON(1));
377         /* To make sure aclk_cpu select gpll after div effect */
378         cru_writel((0xffff0000 & ~RK3188_CPU_SEL_PLL_W_MSK & ~RK3188_CORE_SEL_PLL_W_MSK) 
379                          | clk_sel0
380                          , RK3188_CRU_CLKSELS_CON(0));
381         
382         cru_writel(RK3188_CPU_SEL_PLL_W_MSK 
383                         | RK3188_CORE_SEL_PLL_W_MSK 
384                         | clk_sel0
385                         , RK3188_CRU_CLKSELS_CON(0));
386         
387      //   power_on_pll(RK3188_APLL_ID);
388         cru_writel((RK3188_PLL_MODE_MSK(RK3188_APLL_ID) << 16)
389                         | (RK3188_PLL_MODE_MSK(RK3188_APLL_ID) & cru_mode_con)
390                         , RK3188_CRU_MODE_CON);
391
392     
393         // it was power off ,don't need to power up
394         if (((cpll_con3 & RK3188_PLL_PWR_DN_MSK) == RK3188_PLL_PWR_ON) 
395             &&((RK3188_PLL_MODE_NORM(RK3188_CPLL_ID) & RK3188_PLL_MODE_MSK(RK3188_CPLL_ID)) 
396             == (cru_mode_con & RK3188_PLL_MODE_MSK(RK3188_CPLL_ID)))) {
397        //     power_on_pll(RK3188_CPLL_ID);
398         }
399         cru_writel((RK3188_PLL_MODE_MSK(RK3188_CPLL_ID) << 16) 
400                         | (RK3188_PLL_MODE_MSK(RK3188_CPLL_ID) & cru_mode_con)
401                         , RK3188_CRU_MODE_CON);
402 }
403
404 u32  DEFINE_PIE_DATA(sysclk_cru_clksel0_con);
405 u32  DEFINE_PIE_DATA(sysclk_cru_clksel10_con);
406 u32  DEFINE_PIE_DATA(sysclk_cru_mode_con);
407
408 void PIE_FUNC(sysclk_suspend)(u32 sel_clk)
409 {
410       DATA(sysclk_cru_clksel0_con) = cru_readl(RK3188_CRU_CLKSELS_CON(0));
411       if(sel_clk&(RKPM_CTR_SYSCLK_32K))
412         {
413             DATA(sysclk_cru_mode_con) = cru_readl(RK3188_CRU_MODE_CON);
414             DATA(sysclk_cru_clksel10_con) = cru_readl(RK3188_CRU_CLKSELS_CON(10));
415             
416             cru_writel(RK3188_PERI_ACLK_DIV_W_MSK | RK3188_PERI_ACLK_DIV(4), RK3188_CRU_CLKSELS_CON(10));
417             cru_writel(RK3188_CORE_CLK_DIV_W_MSK | RK3188_CORE_CLK_DIV(4) 
418                             | RK3188_CPU_CLK_DIV_W_MSK | RK3188_CPU_CLK_DIV(4)
419                             , RK3188_CRU_CLKSELS_CON(0));
420             
421             cru_writel(0
422                             | RK3188_PLL_MODE_DEEP(RK3188_APLL_ID)
423                             //| RK3188_PLL_MODE_DEEP(RK3188_DPLL_ID)
424                             | RK3188_PLL_MODE_DEEP(RK3188_CPLL_ID)
425                             | RK3188_PLL_MODE_DEEP(RK3188_GPLL_ID)
426                             , RK3188_CRU_MODE_CON);
427             rkpm_sram_printch('8');
428         }
429         else if(sel_clk&(RKPM_CTR_SYSCLK_DIV))
430         {
431             //set core_clk_div and cpu_clk_div to the largest
432             cru_writel(RK3188_CORE_CLK_DIV_W_MSK | RK3188_CORE_CLK_DIV_MSK
433                         | RK3188_CPU_CLK_DIV_W_MSK | RK3188_CPU_CLK_DIV_MSK, RK3188_CRU_CLKSELS_CON(0));
434         }
435 }
436
437 void PIE_FUNC(sysclk_resume)(u32 sel_clk)
438 {
439
440     if(sel_clk&(RKPM_CTR_SYSCLK_32K))
441     {
442         cru_writel((0xffff<<16) | DATA(sysclk_cru_mode_con), RK3188_CRU_MODE_CON);
443         cru_writel(RK3188_CORE_CLK_DIV_W_MSK | RK3188_CPU_CLK_DIV_W_MSK
444                         | DATA(sysclk_cru_clksel0_con), RK3188_CRU_CLKSELS_CON(0));
445         cru_writel(RK3188_PERI_ACLK_DIV_W_MSK | DATA(sysclk_cru_clksel10_con),
446                         RK3188_CRU_CLKSELS_CON(10));
447         
448         rkpm_sram_printch('8');
449     }
450     else if(sel_clk&(RKPM_CTR_SYSCLK_DIV))
451     {
452         cru_writel(RK3188_CORE_CLK_DIV_W_MSK | RK3188_CPU_CLK_DIV_W_MSK
453                         | DATA(sysclk_cru_clksel0_con), RK3188_CRU_CLKSELS_CON(0));
454     }
455
456 }
457
458 static void clks_gating_suspend_init(void)
459 {
460     // get clk gating info
461     p_rkpm_clkgt_last_set= kern_to_pie(rockchip_pie_chunk, &DATA(rkpm_clkgt_last_set[0]));
462     p_rkpm_clkgt_last_save= kern_to_pie(rockchip_pie_chunk, &DATA(rkpm_clkgt_last_save[0]));
463     
464     if(clk_suspend_clkgt_info_get(clk_ungt_msk,p_rkpm_clkgt_last_set, RK3188_CRU_CLKGATES_CON_CNT) 
465         ==RK3188_CRU_CLKGATES_CON(0))
466     {
467         rkpm_set_ops_gtclks(gtclks_suspend,gtclks_resume);
468         rkpm_set_sram_ops_gtclks(fn_to_pie(rockchip_pie_chunk, &FUNC(gtclks_sram_suspend)), 
469                         fn_to_pie(rockchip_pie_chunk, &FUNC(gtclks_sram_resume)));
470         
471         PM_LOG("%s:clkgt info ok\n",__FUNCTION__);
472
473     }
474     rkpm_set_sram_ops_sysclk(fn_to_pie(rockchip_pie_chunk, &FUNC(sysclk_suspend))
475                                                 ,fn_to_pie(rockchip_pie_chunk, &FUNC(sysclk_resume))); 
476 }
477
478 /***************************prepare and finish reg_pread***********************************/
479
480 static noinline void rk30_pm_dump_irq(void)
481 {
482 #if 0
483         u32 irq_gpio = (readl_relaxed(RK30_GICD_BASE + GIC_DIST_PENDING_SET + 8) >> 22) & 0x7F;
484         printk("wakeup irq: %08x %08x %08x %08x\n",
485                 readl_relaxed(RK30_GICD_BASE + GIC_DIST_PENDING_SET + 4),
486                 readl_relaxed(RK30_GICD_BASE + GIC_DIST_PENDING_SET + 8),
487                 readl_relaxed(RK30_GICD_BASE + GIC_DIST_PENDING_SET + 12),
488                 readl_relaxed(RK30_GICD_BASE + GIC_DIST_PENDING_SET + 16));
489         DUMP_GPIO_INT_STATUS(0);
490         DUMP_GPIO_INT_STATUS(1);
491         DUMP_GPIO_INT_STATUS(2);
492         DUMP_GPIO_INT_STATUS(3);
493     #if GPIO_BANKS > 4
494         DUMP_GPIO_INT_STATUS(4);
495     #endif
496     #if GPIO_BANKS > 5
497         DUMP_GPIO_INT_STATUS(6);
498     #endif
499     #endif
500 }
501
502
503 #define DUMP_GPIO_INTEN(ID) \
504 do { \
505         u32 en = readl_relaxed(RK_GPIO_VIRT(ID) + GPIO_INTEN); \
506         if (en) { \
507                 rkpm_ddr_printascii("GPIO" #ID "_INTEN: "); \
508                 rkpm_ddr_printhex(en); \
509                 rkpm_ddr_printch('\n'); \
510                 printk(KERN_DEBUG "GPIO%d_INTEN: %08x\n", ID, en); \
511         } \
512 } while (0)
513 static noinline void rk30_pm_dump_inten(void)
514 {
515         DUMP_GPIO_INTEN(0);
516         DUMP_GPIO_INTEN(1);
517         DUMP_GPIO_INTEN(2);
518         DUMP_GPIO_INTEN(3);
519 }
520
521
522 static  void rkpm_prepare(void)
523 {   
524     #if 1
525         u32 temp =reg_readl(RK_GPIO_VIRT(0)+0x30);
526
527        // rkpm_ddr_printhex(temp);
528         reg_writel(temp|0x1<<4,RK_GPIO_VIRT(0)+0x30);
529         temp =reg_readl(RK_GPIO_VIRT(0)+0x30);
530        // rkpm_ddr_printhex(temp);
531 #endif
532         
533         // dump GPIO INTEN for debug
534         rk30_pm_dump_inten();
535         #ifdef CONFIG_DDR_TEST
536         // memory tester
537         //ddr_testmode();
538         #endif
539 }
540
541 static void rkpm_finish(void)
542 {
543         rk30_pm_dump_irq();
544 }
545
546
547 static  void interface_ctr_reg_pread(void)
548 {
549         //u32 addr;
550         flush_cache_all();
551         outer_flush_all();
552         local_flush_tlb_all();
553         #if 0  // do it in ddr suspend 
554         for (addr = (u32)SRAM_CODE_OFFSET; addr < (u32)(SRAM_CODE_OFFSET+rockchip_sram_size); addr += PAGE_SIZE)
555                 readl_relaxed(addr);
556         #endif
557         readl_relaxed(RK_PMU_VIRT);
558         readl_relaxed(RK_GRF_VIRT);
559         readl_relaxed(RK_DDR_VIRT);
560         readl_relaxed(RK_GPIO_VIRT(0));     
561         //readl_relaxed(RK30_I2C1_BASE+SZ_4K);
562         //readl_relaxed(RK_GPIO_VIRT(3));
563 }
564
565 static u32 gpios_data[2];
566
567 static void __init  rk3188_suspend_init(void)
568 {
569     struct device_node *parent;
570     u32 pm_ctrbits;
571
572     PM_LOG("%s enter\n",__FUNCTION__);
573
574     parent = of_find_node_by_name(NULL, "rockchip_suspend");    
575
576     if (IS_ERR_OR_NULL(parent)) {
577                 PM_ERR("%s dev node err\n", __func__);
578                 return;
579         }
580
581
582     if(of_property_read_u32_array(parent,"rockchip,ctrbits",&pm_ctrbits,1))
583     {
584             PM_ERR("%s:get pm ctr error\n",__FUNCTION__);
585             return ;
586     }
587     PM_LOG("%s: pm_ctrbits =%x\n",__FUNCTION__,pm_ctrbits);
588
589     if(of_property_read_u32_array(parent,"rockchip,pmic-gpios",gpios_data,ARRAY_SIZE(gpios_data)))
590     {
591             PM_ERR("%s:get pm ctr error\n",__FUNCTION__);
592             return ;
593     }
594     rkpm_set_ctrbits(pm_ctrbits);
595     clks_gating_suspend_init();
596     rkpm_set_ops_plls(plls_suspend,plls_resume);
597     rkpm_set_ops_prepare_finish(rkpm_prepare,rkpm_finish);
598     rkpm_set_ops_regs_pread(interface_ctr_reg_pread); 
599     
600     //rkpm_set_sram_ops_ddr(fn_to_pie(rockchip_pie_chunk, &FUNC(ddr_suspend))
601                                    //     ,fn_to_pie(rockchip_pie_chunk, &FUNC(ddr_resume)));
602                                    
603     rkpm_set_sram_ops_printch(fn_to_pie(rockchip_pie_chunk, &FUNC(sram_printch)));
604     rkpm_set_ops_printch(ddr_printch);  
605     
606 }
607