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