2 #include <linux/delay.h>
4 #include <linux/kernel.h>
5 #include <linux/init.h>
7 #include <linux/suspend.h>
8 #include <linux/random.h>
9 #include <linux/crc32.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>
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>
25 #include <mach/debug_uart.h>
26 #include <plat/efuse.h>
28 #include <linux/regulator/machine.h>
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)
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)
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)
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)
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){}
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){}
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)
65 static int rk3188plus_soc = 0;
67 /********************************sram_printch**************************************************/
68 static bool __sramdata pm_log;
69 extern void pm_emit_log_char(char c);
71 void __sramfunc sram_printch(char byte)
73 #ifdef DEBUG_UART_BASE
74 u32 clk_gate2, clk_gate4, clk_gate8;
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)));
92 writel_relaxed(byte, DEBUG_UART_BASE);
95 /* loop check LSR[6], Transmitter Empty bit */
96 while (!(readl_relaxed(DEBUG_UART_BASE + 0x14) & 0x40))
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));
106 pm_emit_log_char(byte);
111 /********************************ddr test**************************************************/
113 #ifdef CONFIG_DDR_TEST
114 static int ddr_debug=0;
115 module_param(ddr_debug, int, 0644);
117 static int inline calc_crc32(u32 addr, size_t len)
119 return crc32_le(~0, (const unsigned char *)addr, len);
122 extern __sramdata uint32_t mem_type;
123 static void ddr_testmode(void)
125 int32_t g_crc1, g_crc2;
129 extern char _stext[], _etext[];
133 if (ddr_debug == 1) {
153 sram_printascii("\n change freq:");
154 g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
157 nMHz = min + random32();
162 nMHz = ddr_change_freq(nMHz);
165 g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
166 if (g_crc1!=g_crc2) {
167 sram_printascii("fail\n");
169 //ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
170 // sram_printascii("change freq success\n");
172 } else if(ddr_debug == 2) {
179 g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
180 nMHz = (random32()>>13);// 16.7s max
187 g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
188 if (g_crc1 != g_crc2) {
195 // ddr_print("check image crc32 fail!, count:%d\n", n++);
196 // sram_printascii("self refresh fail\n");
198 //ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
199 // sram_printascii("self refresh success\n");
201 } else if (ddr_debug == 3) {
202 extern int memtester(void);
207 ddr_change_freq(ddr_debug);
212 static void ddr_testmode(void) {}
216 #define DUMP_GPIO_INT_STATUS(ID) \
218 if (irq_gpio & (1 << ID)) \
219 printk("wakeup gpio" #ID ": %08x\n", readl_relaxed(RK30_GPIO##ID##_BASE + GPIO_INT_STATUS)); \
222 static noinline void rk30_pm_dump_irq(void)
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);
240 #define DUMP_GPIO_INTEN(ID) \
242 u32 en = readl_relaxed(RK30_GPIO##ID##_BASE + GPIO_INTEN); \
244 sram_printascii("GPIO" #ID "_INTEN: "); \
246 sram_printch('\n'); \
247 printk(KERN_DEBUG "GPIO%d_INTEN: %08x\n", ID, en); \
251 static noinline void rk30_pm_dump_inten(void)
257 #if !(defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188))
263 static void pm_pll_wait_lock(int pll_idx)
265 u32 pll_state[4] = { 1, 0, 2, 3 };
266 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
268 u32 bit = 0x20u << pll_state[pll_idx];
270 u32 bit = 0x10u << pll_state[pll_idx];
272 u32 delay = pll_idx == APLL_ID ? 600000U : 30000000U;
280 if (grf_readl(GRF_SOC_STATUS0) & bit)
285 //CRU_PRINTK_ERR("wait pll bit 0x%x time out!\n", bit);
289 sram_printhex(pll_idx);
294 static void power_on_pll(enum rk_plls_id pll_id)
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));
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));
308 cru_writel(PLL_MODE_SLOW(pll_id), CRU_MODE_CON);
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)
321 cru_writel(PLL_RESET_W_MSK | PLL_RESET_RESUME, PLL_CONS(pll_id,3));
324 if (pll_id == APLL_ID)
328 pm_pll_wait_lock(pll_id);
331 cru_writel(PLL_MODE_NORM(pll_id), CRU_MODE_CON);
334 u32 pllcon0, pllcon1, pllcon2;
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));
342 cru_writel(PLL_MODE_SLOW(pll_id), CRU_MODE_CON);
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)
355 cru_writel(PLL_REST_W_MSK | PLL_REST_RESM, PLL_CONS(pll_id,3));
358 if (pll_id == APLL_ID)
362 pm_pll_wait_lock(pll_id);
365 cru_writel(PLL_MODE_NORM(pll_id), CRU_MODE_CON);
369 #define power_off_pll(id) \
370 cru_writel(PLL_PWR_DN_W_MSK | PLL_PWR_DN, PLL_CONS((id), 3))
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)
382 local_flush_tlb_all();
384 for (addr = (u32)SRAM_CODE_OFFSET; addr < (u32)SRAM_CODE_END; addr += PAGE_SIZE)
386 for (addr = (u32)SRAM_DATA_OFFSET; addr < (u32)SRAM_DATA_END; addr += PAGE_SIZE)
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);
401 static inline bool pm_pmu_power_domain_is_on(enum pmu_power_domain pd, u32 pmu_pwrdn_st)
403 return !(pmu_pwrdn_st & (1 << pd));
405 static void rk30_pm_set_power_domain(u32 pmu_pwrdn_st, bool state)
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);
412 if (pm_pmu_power_domain_is_on(PD_GPU, pmu_pwrdn_st)) {
413 #if defined(CONFIG_ARCH_RK3066B)
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)
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));
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));
447 if (pm_pmu_power_domain_is_on(PD_VIDEO, pmu_pwrdn_st)) {
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));
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));
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));
467 if (pm_pmu_power_domain_is_on(PD_VIO, pmu_pwrdn_st)) {
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));
502 static void __sramfunc rk_pm_soc_sram_volt_suspend(void)
504 rk30_suspend_voltage_set(1000000);
505 rk30_pwm_logic_suspend_voltage();
506 #ifdef CONFIG_ACT8846_SUPPORT_RESET
507 board_act8846_set_suspend_vol();
511 static void __sramfunc rk_pm_soc_sram_volt_resume(void)
514 #ifdef CONFIG_ACT8846_SUPPORT_RESET
515 board_act8846_set_resume_vol();
518 rk30_pwm_logic_resume_voltage();
519 rk30_suspend_voltage_resume(1100000);
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;
536 static void __sramfunc rk_pm_soc_sram_clk_gating(void)
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);
548 for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
549 clkgt_regs_sram[i] = cru_readl(CRU_CLKGATES_CON(i));
551 #ifndef CONFIG_PHONE_INCALL_IS_SUSPEND
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);
561 if(rk30_phonecall_lowerpower() == 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);
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)
577 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
578 | (1 << CLK_GATE_I2S0_SRC)
579 | (1 << CLK_GATE_I2S0_FRAC)
581 |(1<<CLK_GATE_I2S0_FRAC)
583 |(1<<CLK_GATE_I2S1_FRAC)
585 |(1<<CLK_GATE_I2S2_FRAC)
587 , clkgt_regs_sram[0], CRU_CLKGATES_CON(0), CLK_GATE_W_MSK0);
591 gate_save_soc_clk(0, clkgt_regs_sram[1], CRU_CLKGATES_CON(1), CLK_GATE_W_MSK1);
593 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
594 if(((clkgt_regs_sram[8] >> CLK_GATE_PCLK_GPIO3% 16) & 0x01) == 0x01){
596 if(((clkgt_regs_sram[8] >> CLK_GATE_PCLK_GPIO3% 16) & 0x03) == 0x03){
599 , clkgt_regs_sram[2], CRU_CLKGATES_CON(2), CLK_GATE_W_MSK2);
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);
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)
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)
619 | (1 << CLK_GATE_HCLK_IMEM1 % 16)
620 | (1 << CLK_GATE_HCLK_IMEM0 % 16)
622 , clkgt_regs_sram[4], CRU_CLKGATES_CON(4), CLK_GATE_W_MSK4);
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);
631 if(rk30_phonecall_lowerpower() == 0){
632 gate_save_soc_clk(0, clkgt_regs_sram[7], CRU_CLKGATES_CON(7), CLK_GATE_W_MSK7);
635 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
636 | (1 << CLK_GATE_HCLK_I2S0_2CH % 16)
638 | (1 <<CLK_GATE_HCLK_I2S0_2CH)
639 | (1 <<CLK_GATE_HCLK_I2S1_2CH)
640 | (1 <<CLK_GATE_HCLK_I2S_8CH)
642 , clkgt_regs_sram[7], CRU_CLKGATES_CON(7),CLK_GATE_W_MSK7);
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);
655 static void __sramfunc rk_pm_soc_sram_clk_ungating(void)
658 for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
659 cru_writel(clkgt_regs_sram[i] | 0xffff0000, CRU_CLKGATES_CON(i));
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);
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)
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));
679 | PLL_MODE_DEEP(APLL_ID)
680 | PLL_MODE_DEEP(DPLL_ID)
681 | PLL_MODE_DEEP(CPLL_ID)
682 | PLL_MODE_DEEP(GPLL_ID)
684 //board_pmu_suspend();
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));
691 static void __sramfunc rk_pm_soc_sram_sys_clk_resume(void)
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));
699 cru_writel(CORE_CLK_DIV_W_MSK | CPU_CLK_DIV_W_MSK | sram_cru_clksel0_con, CRU_CLKSELS_CON(0));
703 /*********************************code is in ddr ******************************************/
705 static inline void rk_pm_soc_prepare(void)
707 // dump GPIO INTEN for debug
708 rk30_pm_dump_inten();
709 #if !(defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188))
711 grf_writel(0xc0004000, 0x10c);
712 cru_writel(0x07000000, CRU_MISC_CON);
715 #ifdef CONFIG_DDR_TEST
721 static inline void rk_pm_soc_finsh(void)
727 static u32 pmu_pwrdn_st;
729 static inline void rk_pm_soc_pd_suspend(void)
731 pmu_pwrdn_st = pmu_readl(PMU_PWRDN_ST);
732 rk30_pm_set_power_domain(pmu_pwrdn_st, false);
735 static inline void rk_pm_soc_pd_resume(void)
737 rk30_pm_set_power_domain(pmu_pwrdn_st, true);
741 static u32 clkgt_regs_first[CRU_CLKGATES_CON_CNT];
742 static void rk_pm_soc_clk_gating_first(void)
746 for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
747 clkgt_regs_first[i] = cru_readl(CRU_CLKGATES_CON(i));
749 #ifndef CONFIG_PHONE_INCALL_IS_SUSPEND
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)
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);
763 if(rk30_phonecall_lowerpower() == 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)
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);
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)
782 | (1 << CLK_GATE_DDRPHY)
783 | (1 << CLK_GATE_ACLK_CPU)
784 | (1 << CLK_GATE_HCLK_CPU)
785 | (1 << CLK_GATE_PCLK_CPU)
787 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
788 | (1 << CLK_GATE_I2S0_SRC)
789 | (1 << CLK_GATE_I2S0_FRAC)
791 |(1<<CLK_GATE_I2S0_FRAC)
793 |(1<<CLK_GATE_I2S1_FRAC)
795 |(1<<CLK_GATE_I2S2_FRAC)
797 , clkgt_regs_first[0], CRU_CLKGATES_CON(0), CLK_GATE_W_MSK0);
802 | (1 << CLK_GATE_DDR_GPLL % 16)
803 , clkgt_regs_first[1], CRU_CLKGATES_CON(1), CLK_GATE_W_MSK1);
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);
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)
823 | (1 << CLK_GATE_HCLK_IMEM1 % 16)
824 | (1 << CLK_GATE_HCLK_IMEM0 % 16)
826 , clkgt_regs_first[4], CRU_CLKGATES_CON(4), CLK_GATE_W_MSK4);
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
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);
839 if(rk30_phonecall_lowerpower() == 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);
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)
851 | (1 <<CLK_GATE_HCLK_I2S0_2CH% 16)
852 | (1 <<CLK_GATE_HCLK_I2S1_2CH% 16)
853 | (1 <<CLK_GATE_HCLK_I2S_8CH% 16)
855 , clkgt_regs_first[7], CRU_CLKGATES_CON(7),CLK_GATE_W_MSK7);
858 gate_save_soc_clk(0 , clkgt_regs_first[8], CRU_CLKGATES_CON(8), CLK_GATE_W_MSK8);
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);
869 static void rk_pm_soc_clk_ungating_first(void)
873 for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
874 cru_writel(clkgt_regs_first[i] | 0xffff0000, CRU_CLKGATES_CON(i));
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)
883 cru_mode_con = cru_readl(CRU_MODE_CON);
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);
894 clk_sel0 = cru_readl(CRU_CLKSELS_CON(0));
895 clk_sel1 = cru_readl(CRU_CLKSELS_CON(1));
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
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);
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);
930 static void rk_pm_soc_pll_resume(void)
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);
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);
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);
955 cru_writel((PLL_MODE_MSK(CPLL_ID) << 16) | (PLL_MODE_MSK(CPLL_ID) & cru_mode_con), CRU_MODE_CON);
961 /*********************************pm control******************************************/
963 enum rk_soc_pm_ctr_flags_offset {
966 RK_PM_CTR_NO_CLK_GATING,
972 RK_PM_CTR_NO_SYS_CLK,
975 RK_PM_CTR_RET_DIRT=24,
976 RK_PM_CTR_SRAM_NO_WFI,
977 RK_PM_CTR_WAKE_UP_KEY,
981 struct rk_soc_pm_info_st {
986 #define RK_SOC_PM_HELP_(id,NAME)\
988 .offset= RK_PM_CTR_##id,\
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"),
1006 ssize_t rk_soc_pm_helps_sprintf(char *buf)
1011 for(i=0;i<ARRAY_SIZE(rk_soc_pm_helps);i++)
1013 s += sprintf(s, "bit(%d): %s\n", rk_soc_pm_helps[i].offset,rk_soc_pm_helps[i].name);
1019 void rk_soc_pm_helps_printk(void)
1022 printk("**************rk_suspend_ctr_bits bits help***********:\n");
1023 for(i=0;i<ARRAY_SIZE(rk_soc_pm_helps);i++)
1025 printk("bit(%d): %s\n", rk_soc_pm_helps[i].offset,rk_soc_pm_helps[i].name);
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))
1038 static u32 __sramdata rk_soc_pm_ctr_flags_sram=0;
1039 static u32 rk_soc_pm_ctr_flags=0;
1041 static int arm_suspend_volt = 0;
1042 static int logic_suspend_volt = 0;
1044 static int __init early_param_rk_soc_pm_ctr(char *str)
1046 get_option(&str, &rk_soc_pm_ctr_flags);
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)
1052 rk_soc_pm_helps_printk();
1054 printk("********rk_suspend_ctr_bits information end*********\n");
1058 early_param("rk_suspend_ctr_bits", early_param_rk_soc_pm_ctr);
1061 void rk_soc_pm_ctr_bits_set(u32 flags)
1063 rk_soc_pm_ctr_flags = flags;
1066 u32 rk_soc_pm_ctr_bits_get(void)
1068 return rk_soc_pm_ctr_flags;
1071 void rk_soc_pm_ctr_bit_set(int offset)
1073 rk_soc_pm_ctr_flags|=(1<<offset);
1075 void inline rk_soc_pm_ctr_bit_clear(int offset)
1077 rk_soc_pm_ctr_flags&=~(1<<offset);
1080 u32 inline rk_soc_pm_ctr_bits_check(int bits)
1082 return (rk_soc_pm_ctr_flags_sram&(bits));
1085 #define RK_SOC_PM_CTR_FUN(ctr,fun) \
1086 if(!(rk_soc_pm_ctr_bits_check((1<<RK_PM_CTR_##ctr))))\
1089 void rk_soc_pm_ctr_bits_prepare(void)
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))
1095 rk_soc_pm_ctr_flags_sram|=(1<<RK_PM_CTR_NO_VOLT);
1101 static int __init set_arm_suspend_volt(char *str)
1103 get_option(&str, &arm_suspend_volt);
1104 printk("rk_suspend_arm_volt=%dmV\n", arm_suspend_volt);
1107 early_param("rk_suspend_arm_volt", set_arm_suspend_volt);
1109 static int __init set_logic_suspend_volt(char *str)
1111 get_option(&str, &logic_suspend_volt);
1112 printk("rk_suspend_logic_volt=%dmV\n", logic_suspend_volt);
1115 early_param("rk_suspend_logic_volt", set_logic_suspend_volt);
1119 static int __init pm_suspend_volt_seting(void)
1121 struct regulator *regulator;
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__);
1130 regulator_set_suspend_voltage(regulator, arm_suspend_volt);
1131 regulator_put(regulator);
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__);
1140 regulator_set_suspend_voltage(regulator, logic_suspend_volt);
1141 regulator_put(regulator);
1146 device_initcall_sync(pm_suspend_volt_seting);
1149 /*********************************pm main function******************************************/
1151 static void __sramfunc rk30_sram_suspend(void)
1156 RK_SOC_PM_CTR_FUN(NO_DDR,ddr_suspend);
1158 RK_SOC_PM_CTR_FUN(NO_VOLT,rk_pm_soc_sram_volt_suspend);
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))
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);
1173 RK_SOC_PM_CTR_FUN(NO_VOLT,rk_pm_soc_sram_volt_resume);
1175 RK_SOC_PM_CTR_FUN(NO_DDR,ddr_resume);
1180 static void noinline rk30_suspend(void)
1182 DDR_SAVE_SP(save_sp);
1183 rk30_sram_suspend();
1184 DDR_RESTORE_SP(save_sp);
1187 static int rk30_pm_enter(suspend_state_t state)
1189 rk_soc_pm_ctr_bits_prepare();
1191 if(rk_soc_pm_ctr_bits_check(RK_SUSPEND_RET_DIRT_BITS))
1193 printk("%s return directly\n",__FUNCTION__);
1197 rk_pm_soc_prepare();
1199 printk(KERN_DEBUG "pm: ");
1204 RK_SOC_PM_CTR_FUN(NO_PD,rk_pm_soc_pd_suspend);
1207 local_fiq_disable();
1209 RK_SOC_PM_CTR_FUN(NO_CLK_GATING,rk_pm_soc_clk_gating_first);
1212 RK_SOC_PM_CTR_FUN(NO_PLL,rk_pm_soc_pll_suspend);
1216 RK_SOC_PM_CTR_FUN(NO_VOLT,rk30_pwm_suspend_voltage_set);
1217 RK_SOC_PM_CTR_FUN(NO_GPIO,board_gpio_suspend);
1220 interface_ctr_reg_pread();
1225 if(!rk_soc_pm_ctr_bits_check(RK_NO_SUSPEND_CTR_BITS))
1232 RK_SOC_PM_CTR_FUN(NO_GPIO,board_gpio_resume);
1233 RK_SOC_PM_CTR_FUN(NO_VOLT,rk30_pwm_resume_voltage_set);
1237 RK_SOC_PM_CTR_FUN(NO_PLL,rk_pm_soc_pll_resume);
1241 RK_SOC_PM_CTR_FUN(NO_CLK_GATING,rk_pm_soc_clk_ungating_first);
1246 RK_SOC_PM_CTR_FUN(NO_PD,rk_pm_soc_pd_resume);
1250 printk(KERN_CONT "\n");
1256 static int rk30_pm_prepare(void)
1258 /* disable entering idle by disable_hlt() */
1263 static void rk30_pm_finish(void)
1266 #ifdef CONFIG_KEYS_RK29
1267 if(rk_soc_pm_ctr_bits_check(1<<RK_PM_CTR_WAKE_UP_KEY))
1269 rk28_send_wakeup_key();
1270 printk("rk30_pm_finish rk28_send_wakeup_key\n");
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,
1282 static int __init rk30_pm_init(void)
1284 suspend_set_ops(&rk30_pm_ops);
1285 #ifdef CONFIG_EARLYSUSPEND
1286 pm_set_vt_switch(0); /* disable vt switch while suspend */
1288 rk3188plus_soc = soc_is_rk3188plus();
1291 __initcall(rk30_pm_init);