ARM64: DTS: Add rk3399-firefly uart4 device, node as /dev/ttyS1
[firefly-linux-kernel-4.4.55.git] / pm.c
1 #include <linux/clk.h>
2 #include <linux/delay.h>
3 #include <linux/err.h>
4 #include <linux/kernel.h>
5 #include <linux/init.h>
6 #include <linux/pm.h>
7 #include <linux/suspend.h>
8 #include <linux/random.h>
9 #include <linux/crc32.h>
10 #include <linux/io.h>
11 #include <linux/wakelock.h>
12 #include <asm/cacheflush.h>
13 #include <asm/tlbflush.h>
14 #include <asm/hardware/cache-l2x0.h>
15 #include <asm/hardware/gic.h>
16
17 #include <mach/pmu.h>
18 #include <mach/board.h>
19 #include <mach/system.h>
20 #include <mach/sram.h>
21 #include <mach/gpio.h>
22 #include <mach/iomux.h>
23 #include <mach/cru.h>
24 #include <mach/ddr.h>
25 #include <mach/debug_uart.h>
26 #include <plat/efuse.h>
27 #include <plat/cpu.h>
28
29 #define cru_readl(offset)       readl_relaxed(RK30_CRU_BASE + offset)
30 #define cru_writel(v, offset)   do { writel_relaxed(v, RK30_CRU_BASE + offset); dsb(); } while (0)
31
32 #define pmu_readl(offset)       readl_relaxed(RK30_PMU_BASE + offset)
33 #define pmu_writel(v,offset)    do { writel_relaxed(v, RK30_PMU_BASE + offset); dsb(); } while (0)
34
35 #define grf_readl(offset)       readl_relaxed(RK30_GRF_BASE + offset)
36 #define grf_writel(v, offset)   do { writel_relaxed(v, RK30_GRF_BASE + offset); dsb(); } while (0)
37
38 #define gate_save_soc_clk(val,_save,cons,w_msk) \
39         (_save)=cru_readl(cons);\
40         cru_writel((((~(val)|(_save))&(w_msk))|((w_msk)<<16)),cons)
41
42
43 __weak void board_gpio_suspend(void) {}
44 __weak void board_gpio_resume(void) {}
45 __weak void __sramfunc board_pmu_suspend(void) {}
46 __weak void __sramfunc board_pmu_resume(void) {}
47 __weak void __sramfunc rk30_suspend_voltage_set(unsigned int vol){}
48 __weak void __sramfunc rk30_suspend_voltage_resume(unsigned int vol){}
49
50 __weak void  rk30_pwm_suspend_voltage_set(void){}
51 __weak void  rk30_pwm_resume_voltage_set(void){}
52 __weak void board_act8846_set_suspend_vol(void){}
53 __weak void board_act8846_set_resume_vol(void){}
54
55 __weak void __sramfunc rk30_pwm_logic_suspend_voltage(void){}
56 __weak void __sramfunc rk30_pwm_logic_resume_voltage(void){}
57
58 static int rk3188plus_soc = 0;
59
60 /********************************sram_printch**************************************************/
61 static bool __sramdata pm_log;
62 extern void pm_emit_log_char(char c);
63
64 void __sramfunc sram_printch(char byte)
65 {
66 #ifdef DEBUG_UART_BASE
67         u32 clk_gate2, clk_gate4, clk_gate8;
68
69         gate_save_soc_clk(0
70                           | (1 << CLK_GATE_ACLK_PERIPH % 16)
71                           | (1 << CLK_GATE_HCLK_PERIPH % 16)
72                           | (1 << CLK_GATE_PCLK_PERIPH % 16)
73                           , clk_gate2, CRU_CLKGATES_CON(2), 0
74                           | (1 << ((CLK_GATE_ACLK_PERIPH % 16) + 16))
75                           | (1 << ((CLK_GATE_HCLK_PERIPH % 16) + 16))
76                           | (1 << ((CLK_GATE_PCLK_PERIPH % 16) + 16)));
77         gate_save_soc_clk((1 << CLK_GATE_ACLK_CPU_PERI % 16)
78                           , clk_gate4, CRU_CLKGATES_CON(4),
79                           (1 << ((CLK_GATE_ACLK_CPU_PERI % 16) + 16)));
80         gate_save_soc_clk((1 << ((CLK_GATE_PCLK_UART0 + CONFIG_RK_DEBUG_UART) % 16)),
81                           clk_gate8, CRU_CLKGATES_CON(8),
82                           (1 << (((CLK_GATE_PCLK_UART0 + CONFIG_RK_DEBUG_UART) % 16) + 16)));
83         sram_udelay(1);
84
85         writel_relaxed(byte, DEBUG_UART_BASE);
86         dsb();
87
88         /* loop check LSR[6], Transmitter Empty bit */
89         while (!(readl_relaxed(DEBUG_UART_BASE + 0x14) & 0x40))
90                 barrier();
91
92         cru_writel(0xffff0000 | clk_gate2, CRU_CLKGATES_CON(2));
93         cru_writel(0xffff0000 | clk_gate4, CRU_CLKGATES_CON(4));
94         cru_writel(0xffff0000 | clk_gate8, CRU_CLKGATES_CON(8));
95 #endif
96
97         sram_log_char(byte);
98         if (pm_log)
99                 pm_emit_log_char(byte);
100
101         if (byte == '\n')
102                 sram_printch('\r');
103 }
104 /********************************ddr test**************************************************/
105
106 #ifdef CONFIG_DDR_TEST
107 static int ddr_debug=0;
108 module_param(ddr_debug, int, 0644);
109
110 static int inline calc_crc32(u32 addr, size_t len)
111 {
112         return crc32_le(~0, (const unsigned char *)addr, len);
113 }
114
115 extern __sramdata uint32_t mem_type;
116 static void ddr_testmode(void)
117 {
118         int32_t g_crc1, g_crc2;
119         uint32_t nMHz;
120         uint32_t n = 0;
121         uint32_t min,max;
122         extern char _stext[], _etext[];
123         if (ddr_debug == 0)
124                 return;
125         
126         if (ddr_debug == 1) {
127             switch(mem_type)
128             {
129                 case 0:  //LPDDR
130                 case 1:  //DDR
131                     max = 210;
132                     min = 100;
133                     break;
134                 case 2:  //DDR2
135                 case 4:  //LPDDR2
136                     max=410;
137                     min=100;
138                     break;
139                 case 3:  //DDR3
140                 default:
141                     max=500;
142                     min=100;
143                     break;
144             }
145                 for (;;) {
146                         sram_printascii("\n change freq:");
147                         g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
148                         do
149                         {
150                             nMHz = min + random32();
151                             nMHz %= max;
152                         }while(nMHz < min);
153                         sram_printhex(nMHz);
154                         sram_printch(' ');
155                         nMHz = ddr_change_freq(nMHz);                   
156                         sram_printhex(n++);
157                         sram_printch(' ');
158                         g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
159                         if (g_crc1!=g_crc2) {
160                                 sram_printascii("fail\n");
161                         }
162                         //ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
163                         //     sram_printascii("change freq success\n");
164                 }
165         } else if(ddr_debug == 2) {
166                 for (;;) {
167                         sram_printch(' ');
168                         sram_printch('9');
169                         sram_printch('9');
170                         sram_printch('9');
171                         sram_printch(' ');
172                         g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
173                         nMHz = (random32()>>13);// 16.7s max
174                         ddr_suspend();
175                         sram_udelay(nMHz);
176                         ddr_resume();
177                         sram_printhex(nMHz);
178                         sram_printch(' ');
179                         sram_printhex(n++);
180                         g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
181                         if (g_crc1 != g_crc2) {
182                                 sram_printch(' ');
183                                 sram_printch('f');
184                                 sram_printch('a');
185                                 sram_printch('i');
186                                 sram_printch('l');
187                         }
188                         // ddr_print("check image crc32 fail!, count:%d\n", n++);
189                         //    sram_printascii("self refresh fail\n");
190                         //else
191                         //ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
192                         //    sram_printascii("self refresh success\n");
193                 }
194         } else if (ddr_debug == 3) {
195                 extern int memtester(void);
196                 memtester();
197         }
198         else
199         {
200             ddr_change_freq(ddr_debug);
201             ddr_debug=0;
202         }
203 }
204 #else
205 static void ddr_testmode(void) {}
206 #endif
207
208
209 #define DUMP_GPIO_INT_STATUS(ID) \
210 do { \
211         if (irq_gpio & (1 << ID)) \
212                 printk("wakeup gpio" #ID ": %08x\n", readl_relaxed(RK30_GPIO##ID##_BASE + GPIO_INT_STATUS)); \
213 } while (0)
214
215 static noinline void rk30_pm_dump_irq(void)
216 {
217         u32 irq_gpio = (readl_relaxed(RK30_GICD_BASE + GIC_DIST_PENDING_SET + 8) >> 22) & 0x7F;
218         printk("wakeup irq: %08x %08x %08x %08x\n",
219                 readl_relaxed(RK30_GICD_BASE + GIC_DIST_PENDING_SET + 4),
220                 readl_relaxed(RK30_GICD_BASE + GIC_DIST_PENDING_SET + 8),
221                 readl_relaxed(RK30_GICD_BASE + GIC_DIST_PENDING_SET + 12),
222                 readl_relaxed(RK30_GICD_BASE + GIC_DIST_PENDING_SET + 16));
223         DUMP_GPIO_INT_STATUS(0);
224         DUMP_GPIO_INT_STATUS(1);
225         DUMP_GPIO_INT_STATUS(2);
226         DUMP_GPIO_INT_STATUS(3);
227 #if !(defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188))
228         DUMP_GPIO_INT_STATUS(4);
229         DUMP_GPIO_INT_STATUS(6);
230 #endif
231 }
232
233 #define DUMP_GPIO_INTEN(ID) \
234 do { \
235         u32 en = readl_relaxed(RK30_GPIO##ID##_BASE + GPIO_INTEN); \
236         if (en) { \
237                 sram_printascii("GPIO" #ID "_INTEN: "); \
238                 sram_printhex(en); \
239                 sram_printch('\n'); \
240                 printk(KERN_DEBUG "GPIO%d_INTEN: %08x\n", ID, en); \
241         } \
242 } while (0)
243
244 static noinline void rk30_pm_dump_inten(void)
245 {
246         DUMP_GPIO_INTEN(0);
247         DUMP_GPIO_INTEN(1);
248         DUMP_GPIO_INTEN(2);
249         DUMP_GPIO_INTEN(3);
250 #if !(defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188))
251         DUMP_GPIO_INTEN(4);
252         DUMP_GPIO_INTEN(6);
253 #endif
254 }
255
256 static void pm_pll_wait_lock(int pll_idx)
257 {
258         u32 pll_state[4] = { 1, 0, 2, 3 };
259 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
260
261         u32 bit = 0x20u << pll_state[pll_idx];
262 #else
263         u32 bit = 0x10u << pll_state[pll_idx];
264 #endif
265         u32 delay = pll_idx == APLL_ID ? 600000U : 30000000U;
266         dsb();
267         dsb();
268         dsb();
269         dsb();
270         dsb();
271         dsb();
272         while (delay > 0) {
273                 if (grf_readl(GRF_SOC_STATUS0) & bit)
274                         break;
275                 delay--;
276         }
277         if (delay == 0) {
278                 //CRU_PRINTK_ERR("wait pll bit 0x%x time out!\n", bit); 
279                 sram_printch('p');
280                 sram_printch('l');
281                 sram_printch('l');
282                 sram_printhex(pll_idx);
283                 sram_printch('\n');
284         }
285 }
286
287 static void power_on_pll(enum rk_plls_id pll_id)
288 {
289 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
290         if (!rk3188plus_soc) {
291                 cru_writel(PLL_PWR_DN_W_MSK | PLL_PWR_ON, PLL_CONS((pll_id), 3));
292                 pm_pll_wait_lock((pll_id));
293         } else {
294                 u32 pllcon0, pllcon1, pllcon2;
295                 cru_writel(PLL_PWR_DN_W_MSK | PLL_PWR_ON, PLL_CONS((pll_id),3));
296                 pllcon0 = cru_readl(PLL_CONS((pll_id),0));
297                 pllcon1 = cru_readl(PLL_CONS((pll_id),1));
298                 pllcon2 = cru_readl(PLL_CONS((pll_id),2));
299
300                 //enter slowmode
301                 cru_writel(PLL_MODE_SLOW(pll_id), CRU_MODE_CON);
302
303                 //enter rest
304                 cru_writel(PLL_RESET_W_MSK | PLL_RESET, PLL_CONS(pll_id,3));
305                 cru_writel(pllcon0, PLL_CONS(pll_id,0));
306                 cru_writel(pllcon1, PLL_CONS(pll_id,1));
307                 cru_writel(pllcon2, PLL_CONS(pll_id,2));
308                 if (pll_id == APLL_ID)
309                         sram_udelay(5);
310                 else
311                         udelay(5);
312
313                 //return form rest
314                 cru_writel(PLL_RESET_W_MSK | PLL_RESET_RESUME, PLL_CONS(pll_id,3));
315
316                 //wating lock state
317                 if (pll_id == APLL_ID)
318                         sram_udelay(168);
319                 else
320                         udelay(168);
321                 pm_pll_wait_lock(pll_id);
322
323                 //return form slow
324                 cru_writel(PLL_MODE_NORM(pll_id), CRU_MODE_CON);
325         }
326 #else
327         u32 pllcon0, pllcon1, pllcon2;
328
329         cru_writel(PLL_PWR_DN_W_MSK | PLL_PWR_ON, PLL_CONS((pll_id),3));
330         pllcon0 = cru_readl(PLL_CONS((pll_id),0));
331         pllcon1 = cru_readl(PLL_CONS((pll_id),1));
332         pllcon2 = cru_readl(PLL_CONS((pll_id),2));
333
334         //enter slowmode
335         cru_writel(PLL_MODE_SLOW(pll_id), CRU_MODE_CON);
336
337         //enter rest
338         cru_writel(PLL_REST_W_MSK | PLL_REST, PLL_CONS(pll_id,3));
339         cru_writel(pllcon0, PLL_CONS(pll_id,0));
340         cru_writel(pllcon1, PLL_CONS(pll_id,1));
341         cru_writel(pllcon2, PLL_CONS(pll_id,2));
342         if (pll_id == APLL_ID)
343                 sram_udelay(5);
344         else
345                 udelay(5);
346
347         //return form rest
348         cru_writel(PLL_REST_W_MSK | PLL_REST_RESM, PLL_CONS(pll_id,3));
349
350         //wating lock state
351         if (pll_id == APLL_ID)
352                 sram_udelay(168);
353         else
354                 udelay(168);
355         pm_pll_wait_lock(pll_id);
356
357         //return form slow
358         cru_writel(PLL_MODE_NORM(pll_id), CRU_MODE_CON);
359 #endif
360 }
361
362 #define power_off_pll(id) \
363         cru_writel(PLL_PWR_DN_W_MSK | PLL_PWR_DN, PLL_CONS((id), 3))
364
365
366 #define DDR_SAVE_SP(save_sp)            do { save_sp = ddr_save_sp(((unsigned long)SRAM_DATA_END & (~7))); } while (0)
367 #define DDR_RESTORE_SP(save_sp)         do { ddr_save_sp(save_sp); } while (0)
368 static unsigned long save_sp;
369 static noinline void interface_ctr_reg_pread(void)
370 {
371         u32 addr;
372
373         flush_cache_all();
374         outer_flush_all();
375         local_flush_tlb_all();
376
377         for (addr = (u32)SRAM_CODE_OFFSET; addr < (u32)SRAM_CODE_END; addr += PAGE_SIZE)
378                 readl_relaxed(addr);
379         for (addr = (u32)SRAM_DATA_OFFSET; addr < (u32)SRAM_DATA_END; addr += PAGE_SIZE)
380                 readl_relaxed(addr);
381         readl_relaxed(RK30_PMU_BASE);
382         readl_relaxed(RK30_GRF_BASE);
383         readl_relaxed(RK30_DDR_PCTL_BASE);
384         readl_relaxed(RK30_DDR_PUBL_BASE);
385         readl_relaxed(RK30_I2C1_BASE+SZ_4K);
386         readl_relaxed(RK30_GPIO0_BASE);
387         readl_relaxed(RK30_GPIO3_BASE);
388 #if defined(RK30_GPIO6_BASE)
389         readl_relaxed(RK30_GPIO6_BASE);
390 #endif
391 }
392
393
394 static inline bool pm_pmu_power_domain_is_on(enum pmu_power_domain pd, u32 pmu_pwrdn_st)
395 {
396         return !(pmu_pwrdn_st & (1 << pd));
397 }
398 static void rk30_pm_set_power_domain(u32 pmu_pwrdn_st, bool state)
399 {
400 #if !(defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188))
401         if (pm_pmu_power_domain_is_on(PD_DBG, pmu_pwrdn_st))
402                 pmu_set_power_domain(PD_DBG, state);
403 #endif
404
405         if (pm_pmu_power_domain_is_on(PD_GPU, pmu_pwrdn_st)) {
406 #if defined(CONFIG_ARCH_RK3066B)
407                 u32 gate[3];
408                 gate[0] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU_MST));
409                 gate[1] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU_SLV));
410                 gate[2] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_CLK_GPU));
411                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_CLK_GPU), CLK_GATE_CLKID_CONS(CLK_GATE_CLK_GPU));
412                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_GPU_MST), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU_MST));
413                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_GPU_SLV), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU_SLV));
414                 pmu_set_power_domain(PD_GPU, state);
415                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_GPU_MST) | gate[0], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU_MST));
416                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_GPU_SLV) | gate[1], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU_SLV));
417                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_CLK_GPU) | gate[2], CLK_GATE_CLKID_CONS(CLK_GATE_CLK_GPU));
418 #elif defined(CONFIG_ARCH_RK3188)
419                 u32 gate[2];
420                 gate[0] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU_SRC));
421                 gate[1] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU));
422                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_GPU_SRC), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU_SRC));
423                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_GPU), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU));
424                 pmu_set_power_domain(PD_GPU, state);
425                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_GPU_SRC) | gate[0],
426                                 CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU_SRC));
427                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_GPU) | gate[1], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU));
428 #else
429                 u32 gate[2];
430                 gate[0] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_GPU_SRC));
431                 gate[1] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU));
432                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_GPU_SRC), CLK_GATE_CLKID_CONS(CLK_GATE_GPU_SRC));
433                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_GPU), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU));
434                 pmu_set_power_domain(PD_GPU, state);
435                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_GPU_SRC) | gate[0], CLK_GATE_CLKID_CONS(CLK_GATE_GPU_SRC));
436                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_GPU) | gate[1], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_GPU));
437 #endif
438         }
439
440         if (pm_pmu_power_domain_is_on(PD_VIDEO, pmu_pwrdn_st)) {
441                 u32 gate[3];
442                 gate[0] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VEPU));
443                 gate[1] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VDPU));
444 #if !defined(CONFIG_ARCH_RK3188)
445                 gate[2] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VCODEC));
446 #endif
447                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_VEPU), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VEPU));
448                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_VDPU), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VDPU));
449 #if !defined(CONFIG_ARCH_RK3188)
450                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_VCODEC), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VCODEC));
451 #endif
452                 pmu_set_power_domain(PD_VIDEO, state);
453                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_VEPU) | gate[0], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VEPU));
454                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_VDPU) | gate[1], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VDPU));
455 #if !defined(CONFIG_ARCH_RK3188)
456                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_VCODEC) | gate[2], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VCODEC));
457 #endif
458         }
459
460         if (pm_pmu_power_domain_is_on(PD_VIO, pmu_pwrdn_st)) {
461                 u32 gate[10];
462                 gate[0] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC0_SRC));
463                 gate[1] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC1_SRC));
464                 gate[2] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC0));
465                 gate[3] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC1));
466                 gate[4] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_CIF0));
467                 gate[5] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_CIF1));
468                 gate[6] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VIO0));
469                 gate[7] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VIO1));
470                 gate[8] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_IPP));
471                 gate[9] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_RGA));
472                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_LCDC0_SRC), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC0_SRC));
473                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_LCDC1_SRC), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC1_SRC));
474                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_LCDC0), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC0));
475                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_LCDC1), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC1));
476                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_CIF0), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_CIF0));
477                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_CIF1), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_CIF1));
478                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_VIO0), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VIO0));
479                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_VIO1), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VIO1));
480                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_IPP), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_IPP));
481                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_RGA), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_RGA));
482                 pmu_set_power_domain(PD_VIO, state);
483                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_LCDC0_SRC) | gate[0], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC0_SRC));
484                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_LCDC1_SRC) | gate[1], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC1_SRC));
485                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_LCDC0) | gate[2], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC0));
486                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_LCDC1) | gate[3], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC1));
487                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_CIF0) | gate[4], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_CIF0));
488                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_CIF1) | gate[5], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_CIF1));
489                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_VIO0) | gate[6], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VIO0));
490                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_VIO1) | gate[7], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VIO1));
491                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_IPP) | gate[8], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_IPP));
492                 cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_RGA) | gate[9], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_RGA));
493         }
494 }
495 static void __sramfunc rk_pm_soc_sram_volt_suspend(void)
496 {
497         rk30_suspend_voltage_set(1000000);
498         rk30_pwm_logic_suspend_voltage();
499 #ifdef CONFIG_ACT8846_SUPPORT_RESET
500         board_act8846_set_suspend_vol();
501 #endif
502 }       
503
504 static void __sramfunc rk_pm_soc_sram_volt_resume(void)
505 {
506
507         #ifdef CONFIG_ACT8846_SUPPORT_RESET
508                 board_act8846_set_resume_vol();
509         #endif
510
511         rk30_pwm_logic_resume_voltage();
512         rk30_suspend_voltage_resume(1100000);
513
514 }
515
516 #define CLK_GATE_W_MSK0 (0xffff)
517 #define CLK_GATE_W_MSK1 (0xffff)
518 #define CLK_GATE_W_MSK2 (0xffff)
519 #define CLK_GATE_W_MSK3 (0xff9f)
520 #define CLK_GATE_W_MSK4 (0xffff)
521 #define CLK_GATE_W_MSK5 (0xffff)
522 #define CLK_GATE_W_MSK6 (0xffff)
523 #define CLK_GATE_W_MSK7 (0xffff)
524 #define CLK_GATE_W_MSK8 (0x01ff)
525 #define CLK_GATE_W_MSK9 (0x07ff)
526 static u32 __sramdata clkgt_regs_sram[CRU_CLKGATES_CON_CNT];
527 static u32 __sramdata sram_grf_uoc0_con0_status;
528
529 static void __sramfunc rk_pm_soc_sram_clk_gating(void)
530 {
531         int i;
532
533         #if defined(CONFIG_ARCH_RK3188) && (CONFIG_RK_DEBUG_UART == 2)
534         #ifdef CONFIG_RK_USB_UART
535                 sram_grf_uoc0_con0_status = grf_readl(GRF_UOC0_CON0);
536                 grf_writel(0x03000000, GRF_UOC0_CON0);
537         #endif
538         #endif
539
540         
541         for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
542                 clkgt_regs_sram[i] = cru_readl(CRU_CLKGATES_CON(i));
543         }
544         gate_save_soc_clk(0
545                           | (1 << CLK_GATE_CORE_PERIPH)
546                           | (1 << CLK_GATE_ACLK_CPU)
547                           | (1 << CLK_GATE_HCLK_CPU)
548                           | (1 << CLK_GATE_PCLK_CPU)
549                           | (1 << CLK_GATE_ACLK_CORE)
550                           , clkgt_regs_sram[0], CRU_CLKGATES_CON(0), CLK_GATE_W_MSK0);
551         
552         gate_save_soc_clk(0, clkgt_regs_sram[1], CRU_CLKGATES_CON(1), CLK_GATE_W_MSK1);
553         
554 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
555         if(((clkgt_regs_sram[8] >> CLK_GATE_PCLK_GPIO3% 16) & 0x01) == 0x01){
556 #else
557         if(((clkgt_regs_sram[8] >> CLK_GATE_PCLK_GPIO3% 16) & 0x03) == 0x03){
558 #endif
559                 gate_save_soc_clk(0
560                                 , clkgt_regs_sram[2], CRU_CLKGATES_CON(2), CLK_GATE_W_MSK2);
561
562         }else{
563                 gate_save_soc_clk(0
564                                   | (1 << CLK_GATE_PERIPH_SRC % 16)
565                                   | (1 << CLK_GATE_PCLK_PERIPH % 16)
566                                 , clkgt_regs_sram[2], CRU_CLKGATES_CON(2), CLK_GATE_W_MSK2);
567         }
568         gate_save_soc_clk(0
569                 #if 1  //for uart befor wfi 
570                 | (1 << CLK_GATE_PCLK_PERI_AXI_MATRIX % 16)
571                 | (1 << CLK_GATE_ACLK_PERI_AXI_MATRIX % 16)
572                 | (1 << CLK_GATE_ACLK_PEI_NIU % 16)
573                 #endif  
574                 
575                 | (1 << CLK_GATE_ACLK_STRC_SYS % 16)
576                 | (1 << CLK_GATE_ACLK_INTMEM % 16)
577                 #if !defined(CONFIG_ARCH_RK3188)
578                 | (1 << CLK_GATE_HCLK_L2MEM % 16)
579                 #else
580                 | (1 << CLK_GATE_HCLK_IMEM1 % 16)
581                 | (1 << CLK_GATE_HCLK_IMEM0 % 16)
582                 #endif
583                 , clkgt_regs_sram[4], CRU_CLKGATES_CON(4), CLK_GATE_W_MSK4);
584
585         gate_save_soc_clk(0
586                   | (1 << CLK_GATE_PCLK_GRF % 16)
587                   | (1 << CLK_GATE_PCLK_PMU % 16)
588                   , clkgt_regs_sram[5], CRU_CLKGATES_CON(5), CLK_GATE_W_MSK5);
589         
590         gate_save_soc_clk(0, clkgt_regs_sram[7], CRU_CLKGATES_CON(7), CLK_GATE_W_MSK7);
591         
592         gate_save_soc_clk(0
593                           | (1 << CLK_GATE_CLK_L2C % 16)
594                           | (1 << CLK_GATE_ACLK_INTMEM0 % 16)
595                           | (1 << CLK_GATE_ACLK_INTMEM1 % 16)
596                           | (1 << CLK_GATE_ACLK_INTMEM2 % 16)
597                           | (1 << CLK_GATE_ACLK_INTMEM3 % 16)
598                           , clkgt_regs_sram[9], CRU_CLKGATES_CON(9), CLK_GATE_W_MSK9);
599
600 }
601
602 static void __sramfunc rk_pm_soc_sram_clk_ungating(void)
603 {
604         int i;
605         for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
606                 cru_writel(clkgt_regs_sram[i] | 0xffff0000, CRU_CLKGATES_CON(i));
607         }
608
609         #if defined(CONFIG_ARCH_RK3188) && (CONFIG_RK_DEBUG_UART == 2)
610         #ifdef CONFIG_RK_USB_UART
611                 grf_writel(0x03000000 | sram_grf_uoc0_con0_status, GRF_UOC0_CON0);
612         #endif
613         #endif
614 }
615
616 static u32 __sramdata sram_cru_clksel0_con, sram_cru_clksel10_con,sram_cru_mode_con;
617 static void __sramfunc rk_pm_soc_sram_sys_clk_suspend(void)
618 {
619         sram_cru_clksel0_con = cru_readl(CRU_CLKSELS_CON(0));
620 #ifdef CONFIG_CLK_SWITCH_TO_32K
621                 sram_cru_mode_con = cru_readl(CRU_MODE_CON);
622                 sram_cru_clksel10_con = cru_readl(CRU_CLKSELS_CON(10));
623                 cru_writel(PERI_ACLK_DIV_W_MSK | PERI_ACLK_DIV(4), CRU_CLKSELS_CON(10));
624                 cru_writel(CORE_CLK_DIV_W_MSK | CORE_CLK_DIV(4) | CPU_CLK_DIV_W_MSK | CPU_CLK_DIV(4), CRU_CLKSELS_CON(0));
625                 cru_writel(0
626                            | PLL_MODE_DEEP(APLL_ID)
627                            | PLL_MODE_DEEP(DPLL_ID)
628                            | PLL_MODE_DEEP(CPLL_ID)
629                            | PLL_MODE_DEEP(GPLL_ID)
630                            , CRU_MODE_CON);
631                 //board_pmu_suspend();
632 #else
633                 cru_writel(CORE_CLK_DIV_W_MSK | CORE_CLK_DIV_MSK | CPU_CLK_DIV_W_MSK | CPU_CLK_DIV_MSK, CRU_CLKSELS_CON(0));
634 #endif
635
636 }
637
638 static void __sramfunc  rk_pm_soc_sram_sys_clk_resume(void)
639 {
640
641 #ifdef CONFIG_CLK_SWITCH_TO_32K
642         cru_writel((0xffff<<16) | sram_cru_mode_con, CRU_MODE_CON);
643         cru_writel(CORE_CLK_DIV_W_MSK | CPU_CLK_DIV_W_MSK | sram_cru_clksel0_con, CRU_CLKSELS_CON(0));
644         cru_writel(PERI_ACLK_DIV_W_MSK | sram_cru_clksel10_con, CRU_CLKSELS_CON(10));
645 #else
646         cru_writel(CORE_CLK_DIV_W_MSK | CPU_CLK_DIV_W_MSK | sram_cru_clksel0_con, CRU_CLKSELS_CON(0));
647 #endif
648
649 }
650 /*********************************code is in ddr ******************************************/
651
652 static inline void rk_pm_soc_prepare(void)
653 {
654         // dump GPIO INTEN for debug
655         rk30_pm_dump_inten();
656 #if !(defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188))
657         //gpio6_b7
658         grf_writel(0xc0004000, 0x10c);
659         cru_writel(0x07000000, CRU_MISC_CON);
660 #endif
661
662 #ifdef CONFIG_DDR_TEST
663         // memory tester
664                 ddr_testmode();
665 #endif
666 }
667
668 static inline void rk_pm_soc_finsh(void)
669 {
670         rk30_pm_dump_irq();
671 }
672
673
674 static u32 pmu_pwrdn_st;
675
676 static inline void rk_pm_soc_pd_suspend(void)
677 {
678         pmu_pwrdn_st = pmu_readl(PMU_PWRDN_ST);
679         rk30_pm_set_power_domain(pmu_pwrdn_st, false);
680 }
681
682 static inline void rk_pm_soc_pd_resume(void)
683 {
684         rk30_pm_set_power_domain(pmu_pwrdn_st, true);
685 }
686
687
688 static u32 clkgt_regs_first[CRU_CLKGATES_CON_CNT];
689 static void rk_pm_soc_clk_gating_first(void)
690 {
691         int i;
692
693         for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
694                 clkgt_regs_first[i] = cru_readl(CRU_CLKGATES_CON(i));
695         }
696
697         gate_save_soc_clk(0
698                           | (1 << CLK_GATE_CORE_PERIPH)
699 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
700                           | (1 << CLK_GATE_CPU_GPLL_PATH)
701                           | (1 << CLK_GATE_ACLK_CORE)
702 #endif
703                           | (1 << CLK_GATE_DDRPHY)
704                           | (1 << CLK_GATE_ACLK_CPU)
705                           | (1 << CLK_GATE_HCLK_CPU)
706                           | (1 << CLK_GATE_PCLK_CPU)
707                           , clkgt_regs_first[0], CRU_CLKGATES_CON(0), CLK_GATE_W_MSK0);
708         gate_save_soc_clk(0
709                           | (1 << CLK_GATE_DDR_GPLL % 16)
710                           , clkgt_regs_first[1], CRU_CLKGATES_CON(1), CLK_GATE_W_MSK1);
711         gate_save_soc_clk(0
712                           | (1 << CLK_GATE_PERIPH_SRC % 16)
713                           | (1 << CLK_GATE_PCLK_PERIPH % 16)
714                           | (1 << CLK_GATE_ACLK_PERIPH % 16)
715                           , clkgt_regs_first[2], CRU_CLKGATES_CON(2),CLK_GATE_W_MSK2 );
716         gate_save_soc_clk(0, clkgt_regs_first[3], CRU_CLKGATES_CON(3),CLK_GATE_W_MSK3);
717         gate_save_soc_clk(0
718                           | (1 << CLK_GATE_HCLK_PERI_AXI_MATRIX % 16)
719                           | (1 << CLK_GATE_PCLK_PERI_AXI_MATRIX % 16)
720                           | (1 << CLK_GATE_ACLK_CPU_PERI % 16)
721                           | (1 << CLK_GATE_ACLK_PERI_AXI_MATRIX % 16)
722                           | (1 << CLK_GATE_ACLK_PEI_NIU % 16)
723                           | (1 << CLK_GATE_HCLK_PERI_AHB_ARBI % 16)
724                           | (1 << CLK_GATE_HCLK_CPUBUS % 16)
725                           | (1 << CLK_GATE_ACLK_STRC_SYS % 16)
726                           | (1 << CLK_GATE_ACLK_INTMEM % 16)
727 #if !defined(CONFIG_ARCH_RK3188)
728                           | (1 << CLK_GATE_HCLK_L2MEM % 16)
729 #else
730                           | (1 << CLK_GATE_HCLK_IMEM1 % 16)
731                           | (1 << CLK_GATE_HCLK_IMEM0 % 16)
732 #endif
733                           , clkgt_regs_first[4], CRU_CLKGATES_CON(4), CLK_GATE_W_MSK4);
734         gate_save_soc_clk(0
735                           | (1 << CLK_GATE_PCLK_GRF % 16)
736                           | (1 << CLK_GATE_PCLK_PMU % 16)
737                           | (1 << CLK_GATE_PCLK_DDRUPCTL % 16)
738                           , clkgt_regs_first[5], CRU_CLKGATES_CON(5), CLK_GATE_W_MSK5);
739         gate_save_soc_clk(0, clkgt_regs_first[6], CRU_CLKGATES_CON(6), CLK_GATE_W_MSK6);
740         gate_save_soc_clk(0
741                           | (1 << CLK_GATE_PCLK_PWM01 % 16)
742                           | (1 << CLK_GATE_PCLK_PWM23 % 16)
743                           , clkgt_regs_first[7], CRU_CLKGATES_CON(7),CLK_GATE_W_MSK7);
744         gate_save_soc_clk(0 , clkgt_regs_first[8], CRU_CLKGATES_CON(8), CLK_GATE_W_MSK8);
745         gate_save_soc_clk(0
746                           | (1 << CLK_GATE_CLK_L2C % 16)
747                           | (1 << CLK_GATE_PCLK_PUBL % 16)
748                           | (1 << CLK_GATE_ACLK_INTMEM0 % 16)
749                           | (1 << CLK_GATE_ACLK_INTMEM1 % 16)
750                           | (1 << CLK_GATE_ACLK_INTMEM2 % 16)
751                           | (1 << CLK_GATE_ACLK_INTMEM3 % 16)
752                           , clkgt_regs_first[9], CRU_CLKGATES_CON(9), CLK_GATE_W_MSK9);
753 }
754
755 static void rk_pm_soc_clk_ungating_first(void)
756 {
757         int i;
758         
759         for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
760                 cru_writel(clkgt_regs_first[i] | 0xffff0000, CRU_CLKGATES_CON(i));
761         }
762 }
763
764 static u32 clk_sel0, clk_sel1, clk_sel10;
765 static u32 cpll_con3;
766 static u32 cru_mode_con;
767 static void rk_pm_soc_pll_suspend(void)
768 {
769         cru_mode_con = cru_readl(CRU_MODE_CON);
770         
771                 //cpll
772                 if(rk_pll_flag()==0)
773                 {       
774                 cru_writel(PLL_MODE_SLOW(CPLL_ID), CRU_MODE_CON);
775                 cpll_con3 = cru_readl(PLL_CONS(CPLL_ID, 3));
776                 power_off_pll(CPLL_ID);
777                 }
778         
779                 //apll
780                 clk_sel0 = cru_readl(CRU_CLKSELS_CON(0));
781                 clk_sel1 = cru_readl(CRU_CLKSELS_CON(1));
782         
783                 cru_writel(PLL_MODE_SLOW(APLL_ID), CRU_MODE_CON);
784                 /* To make sure aclk_cpu select gpll before div effect */
785                 cru_writel(CPU_SEL_PLL_W_MSK | CPU_SEL_APLL, CRU_CLKSELS_CON(0));
786                 cru_writel(CORE_PERIPH_W_MSK | CORE_PERIPH_2
787                            | CORE_CLK_DIV_W_MSK | CORE_CLK_DIV(1)
788                            | CPU_CLK_DIV_W_MSK | CPU_CLK_DIV(1)
789                            | CORE_SEL_PLL_W_MSK | CORE_SEL_APLL
790                            , CRU_CLKSELS_CON(0));
791                 cru_writel(CORE_ACLK_W_MSK | CORE_ACLK_11
792 #if !defined(CONFIG_ARCH_RK3188)
793                            | CPU_ACLK_W_MSK | CPU_ACLK_11
794 #endif
795                            | ACLK_HCLK_W_MSK | ACLK_HCLK_11
796                            | ACLK_PCLK_W_MSK | ACLK_PCLK_11
797                            | AHB2APB_W_MSK | AHB2APB_11
798                            , CRU_CLKSELS_CON(1));
799                 power_off_pll(APLL_ID);
800         
801                 //gpll
802                 if(rk_pll_flag()==0)
803                 {
804                 cru_writel(PLL_MODE_SLOW(GPLL_ID), CRU_MODE_CON);
805                 clk_sel10 = cru_readl(CRU_CLKSELS_CON(10));
806                 cru_writel(CRU_W_MSK_SETBITS(0, PERI_ACLK_DIV_OFF, PERI_ACLK_DIV_MASK)
807                            | CRU_W_MSK_SETBITS(0, PERI_HCLK_DIV_OFF, PERI_HCLK_DIV_MASK)
808                            | CRU_W_MSK_SETBITS(0, PERI_PCLK_DIV_OFF, PERI_PCLK_DIV_MASK)
809                            , CRU_CLKSELS_CON(10));
810                 power_off_pll(GPLL_ID);
811                 }
812
813 }
814
815 static void rk_pm_soc_pll_resume(void)
816 {
817         
818         //gpll
819         if(rk_pll_flag()==0)
820         {
821         cru_writel(0xffff0000 | clk_sel10, CRU_CLKSELS_CON(10));
822         power_on_pll(GPLL_ID);
823         cru_writel((PLL_MODE_MSK(GPLL_ID) << 16) | (PLL_MODE_MSK(GPLL_ID) & cru_mode_con), CRU_MODE_CON);
824         }
825         //apll
826         cru_writel(0xffff0000 | clk_sel1, CRU_CLKSELS_CON(1));
827         /* To make sure aclk_cpu select gpll after div effect */
828         cru_writel(0xffdf0000 | clk_sel0, CRU_CLKSELS_CON(0));
829         cru_writel(0x00200000 | clk_sel0, CRU_CLKSELS_CON(0));
830         power_on_pll(APLL_ID);
831         cru_writel((PLL_MODE_MSK(APLL_ID) << 16) | (PLL_MODE_MSK(APLL_ID) & cru_mode_con), CRU_MODE_CON);
832
833         //cpll
834         if(rk_pll_flag()==0)
835         {       
836         if (((cpll_con3 & PLL_PWR_DN_MSK) == PLL_PWR_ON) &&
837                 ((PLL_MODE_NORM(CPLL_ID) & PLL_MODE_MSK(CPLL_ID)) == (cru_mode_con & PLL_MODE_MSK(CPLL_ID)))) {
838                 power_on_pll(CPLL_ID);
839         }
840         cru_writel((PLL_MODE_MSK(CPLL_ID) << 16) | (PLL_MODE_MSK(CPLL_ID) & cru_mode_con), CRU_MODE_CON);
841         }
842
843
844 }
845
846 /*********************************pm control******************************************/
847
848 enum rk_soc_pm_ctr_flags_offset {
849
850         RK_PM_CTR_NO_PD=0,
851         RK_PM_CTR_NO_CLK_GATING,
852         RK_PM_CTR_NO_PLL,
853         RK_PM_CTR_NO_VOLT,
854         RK_PM_CTR_NO_GPIO,
855         RK_PM_CTR_NO_SRAM,
856         RK_PM_CTR_NO_DDR,
857         RK_PM_CTR_NO_SYS_CLK,
858         RK_PM_CTR_NO_PMIC,
859
860         RK_PM_CTR_RET_DIRT=24,
861         RK_PM_CTR_SRAM_NO_WFI,
862         RK_PM_CTR_WAKE_UP_KEY,
863         RK_PM_CTR_ALL=31,
864 };
865
866 struct rk_soc_pm_info_st {
867         int offset;
868         char *name;
869 };
870
871 #define RK_SOC_PM_HELP_(id,NAME)\
872         {\
873         .offset= RK_PM_CTR_##id,\
874         .name= NAME,\
875         }
876
877 struct rk_soc_pm_info_st rk_soc_pm_helps[]={
878         RK_SOC_PM_HELP_(NO_PD,"pd is not power dn"),
879         RK_SOC_PM_HELP_(NO_CLK_GATING,"clk is not gating"),
880         RK_SOC_PM_HELP_(NO_PLL,"pll is not power dn"),
881         RK_SOC_PM_HELP_(NO_VOLT,"volt is not set suspend"),
882         RK_SOC_PM_HELP_(NO_GPIO,"gpio is not control "),
883         //RK_SOC_PM_HELP_(NO_SRAM,"not enter sram code"),
884         RK_SOC_PM_HELP_(NO_DDR,"ddr is not reflash"),
885         RK_SOC_PM_HELP_(NO_PMIC,"pmic is not suspend"),
886         RK_SOC_PM_HELP_(RET_DIRT,"sys return from pm_enter directly"),
887         RK_SOC_PM_HELP_(SRAM_NO_WFI,"sys is not runing wfi in sram"),
888         RK_SOC_PM_HELP_(WAKE_UP_KEY,"send a power key to wake up lcd"),
889 };
890
891 ssize_t rk_soc_pm_helps_print(char *buf)
892 {
893         char *s = buf;
894         int i;
895
896         for(i=0;i<ARRAY_SIZE(rk_soc_pm_helps);i++)
897         {
898                 s += sprintf(s, "bit(%d): %s\n", rk_soc_pm_helps[i].offset,rk_soc_pm_helps[i].name);
899         }
900
901         return (s-buf);
902 }       
903
904 // pm enter return directly
905 #define RK_SUSPEND_RET_DIRT_BITS ((1<<RK_PM_CTR_RET_DIRT))
906 // not enter rk30_suspend
907 #define RK_NO_SUSPEND_CTR_BITS ((1<<RK_PM_CTR_NO_PLL))
908 //not running wfi in sram code
909 #define RK_SUSPEND_NO_SRAM_WFI_BITS ((1<<RK_PM_CTR_SRAM_NO_WFI))
910
911
912 static u32  __sramdata rk_soc_pm_ctr_flags_sram=0;
913 static u32   rk_soc_pm_ctr_flags=0;
914
915 static int __init early_param_rk_soc_pm_ctr(char *str)
916 {
917         get_option(&str, &rk_soc_pm_ctr_flags);
918         printk("early_param_rk_soc_pm_ctr=%x\n",rk_soc_pm_ctr_flags);
919         return 0;
920 }
921
922 early_param("rk_soc_pm_ctr", early_param_rk_soc_pm_ctr);
923
924 void  rk_soc_pm_ctr_bits_set(u32 flags)
925 {       
926         rk_soc_pm_ctr_flags = flags;
927         
928 }
929 u32  rk_soc_pm_ctr_bits_get(void)
930 {       
931         return rk_soc_pm_ctr_flags;
932 }
933
934 void  rk_soc_pm_ctr_bit_set(int offset)
935 {       
936         rk_soc_pm_ctr_flags|=(1<<offset);
937 }
938 void inline rk_soc_pm_ctr_bit_clear(int offset)
939 {
940         rk_soc_pm_ctr_flags&=~(1<<offset);
941 }
942
943 u32 inline rk_soc_pm_ctr_bits_check(int bits)
944 {
945         return (rk_soc_pm_ctr_flags_sram&(bits));
946 }       
947
948 #define  RK_SOC_PM_CTR_FUN(ctr,fun) \
949         if(!(rk_soc_pm_ctr_bits_check((1<<RK_PM_CTR_##ctr))))\
950                 (fun)()
951
952 void rk_soc_pm_ctr_bits_prepare(void)
953 {
954         
955         rk_soc_pm_ctr_flags_sram=rk_soc_pm_ctr_flags;
956         if(rk_soc_pm_ctr_flags_sram&(1<<RK_PM_CTR_NO_PLL))
957         {
958                 rk_soc_pm_ctr_flags_sram|=(1<<RK_PM_CTR_NO_VOLT);
959         }
960                 
961 }       
962
963 static void __sramfunc rk30_sram_suspend(void)
964 {
965
966         sram_printch('5');
967         
968         RK_SOC_PM_CTR_FUN(NO_DDR,ddr_suspend);
969         sram_printch('6');
970         RK_SOC_PM_CTR_FUN(NO_VOLT,rk_pm_soc_sram_volt_suspend);
971         sram_printch('7');
972         RK_SOC_PM_CTR_FUN(NO_CLK_GATING,rk_pm_soc_sram_clk_gating);
973         RK_SOC_PM_CTR_FUN(NO_SYS_CLK,rk_pm_soc_sram_sys_clk_suspend);
974         RK_SOC_PM_CTR_FUN(NO_PMIC,board_pmu_suspend);
975         if(!rk_soc_pm_ctr_bits_check(RK_SUSPEND_NO_SRAM_WFI_BITS))
976         {
977                 dsb();
978                 wfi();
979         }
980
981         RK_SOC_PM_CTR_FUN(NO_PMIC,board_pmu_resume);
982         RK_SOC_PM_CTR_FUN(NO_SYS_CLK,rk_pm_soc_sram_sys_clk_resume);
983         RK_SOC_PM_CTR_FUN(NO_CLK_GATING,rk_pm_soc_sram_clk_ungating);
984         sram_printch('7');
985         RK_SOC_PM_CTR_FUN(NO_VOLT,rk_pm_soc_sram_volt_resume);
986         sram_printch('6');      
987         RK_SOC_PM_CTR_FUN(NO_DDR,ddr_resume);
988         sram_printch('5');
989         
990 }
991
992 static void noinline rk30_suspend(void)
993 {
994         DDR_SAVE_SP(save_sp);
995         rk30_sram_suspend();
996         DDR_RESTORE_SP(save_sp);
997 }
998
999 static int rk30_pm_enter(suspend_state_t state)
1000 {
1001         rk_soc_pm_ctr_bits_prepare();
1002
1003         if(rk_soc_pm_ctr_bits_check(RK_SUSPEND_RET_DIRT_BITS))
1004         {
1005                 printk("%s return directly\n",__FUNCTION__);
1006                 return 0;
1007         }
1008         
1009         rk_pm_soc_prepare();
1010         
1011         printk(KERN_DEBUG "pm: ");
1012         pm_log = true;
1013         sram_log_reset();
1014         sram_printch('0');
1015         
1016         RK_SOC_PM_CTR_FUN(NO_PD,rk_pm_soc_pd_suspend);
1017
1018         sram_printch('1');
1019         local_fiq_disable();
1020         
1021         RK_SOC_PM_CTR_FUN(NO_CLK_GATING,rk_pm_soc_clk_gating_first);
1022
1023         sram_printch('2');
1024         RK_SOC_PM_CTR_FUN(NO_PLL,rk_pm_soc_pll_suspend);
1025
1026         sram_printch('3');
1027
1028         RK_SOC_PM_CTR_FUN(NO_VOLT,rk30_pwm_suspend_voltage_set);
1029         RK_SOC_PM_CTR_FUN(NO_GPIO,board_gpio_suspend);
1030
1031
1032         interface_ctr_reg_pread();
1033
1034         sram_printch('4');
1035         pm_log = false;
1036         
1037         if(!rk_soc_pm_ctr_bits_check(RK_NO_SUSPEND_CTR_BITS))
1038                 rk30_suspend();
1039         
1040         
1041         pm_log = true;
1042         sram_printch('4');
1043
1044         RK_SOC_PM_CTR_FUN(NO_GPIO,board_gpio_resume);
1045         RK_SOC_PM_CTR_FUN(NO_VOLT,rk30_pwm_resume_voltage_set);
1046
1047         sram_printch('3');
1048         
1049         RK_SOC_PM_CTR_FUN(NO_PLL,rk_pm_soc_pll_resume);
1050
1051         sram_printch('2');
1052         
1053         RK_SOC_PM_CTR_FUN(NO_CLK_GATING,rk_pm_soc_clk_ungating_first);
1054         
1055         local_fiq_enable();
1056         sram_printch('1');
1057
1058         RK_SOC_PM_CTR_FUN(NO_PD,rk_pm_soc_pd_resume);
1059         
1060         sram_printch('0');
1061         pm_log = false;
1062         printk(KERN_CONT "\n");
1063         sram_printch('\n');
1064         rk_pm_soc_finsh();
1065         return 0;
1066 }
1067
1068 static int rk30_pm_prepare(void)
1069 {
1070         /* disable entering idle by disable_hlt() */
1071         disable_hlt();
1072         return 0;
1073 }
1074
1075 static void rk30_pm_finish(void)
1076 {
1077         enable_hlt();
1078         if(rk_soc_pm_ctr_bits_check(1<<RK_PM_CTR_WAKE_UP_KEY))
1079         {
1080                 rk28_send_wakeup_key();
1081                 printk("rk30_pm_finish rk28_send_wakeup_key\n");
1082         }
1083
1084 }
1085
1086 static struct platform_suspend_ops rk30_pm_ops = {
1087         .enter          = rk30_pm_enter,
1088         .valid          = suspend_valid_only_mem,
1089         .prepare        = rk30_pm_prepare,
1090         .finish         = rk30_pm_finish,
1091 };
1092
1093 static int __init rk30_pm_init(void)
1094 {
1095         suspend_set_ops(&rk30_pm_ops);
1096
1097 #ifdef CONFIG_EARLYSUSPEND
1098         pm_set_vt_switch(0); /* disable vt switch while suspend */
1099 #endif
1100         rk3188plus_soc = soc_is_rk3188plus();
1101         return 0;
1102 }
1103 __initcall(rk30_pm_init);