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 #define cru_readl(offset) readl_relaxed(RK2928_CRU_BASE + offset)
26 #define cru_writel(v, offset) do { writel_relaxed(v, RK2928_CRU_BASE + offset); dsb(); } while (0)
28 #define grf_readl(offset) readl_relaxed(RK2928_GRF_BASE + offset)
29 #define grf_writel(v, offset) do { writel_relaxed(v, RK2928_GRF_BASE + offset); dsb(); } while (0)
31 #define gate_save_soc_clk(val, _save, cons, w_msk) \
33 (_save) = cru_readl(cons); \
34 cru_writel(((~(val) | (_save)) & (w_msk)) | ((w_msk) << 16), cons); \
37 void __sramfunc sram_printch(char byte)
39 #ifdef DEBUG_UART_BASE
40 u32 clk_gate2, clk_gate4, clk_gate8;
43 | (1 << CLK_GATE_ACLK_PERIPH % 16)
44 | (1 << CLK_GATE_HCLK_PERIPH % 16)
45 | (1 << CLK_GATE_PCLK_PERIPH % 16)
46 , clk_gate2, CRU_CLKGATES_CON(2), 0
47 | (1 << ((CLK_GATE_ACLK_PERIPH % 16) + 16))
48 | (1 << ((CLK_GATE_HCLK_PERIPH % 16) + 16))
49 | (1 << ((CLK_GATE_PCLK_PERIPH % 16) + 16)));
50 gate_save_soc_clk((1 << CLK_GATE_ACLK_CPU_PERI % 16)
51 , clk_gate4, CRU_CLKGATES_CON(4),
52 (1 << ((CLK_GATE_ACLK_CPU_PERI % 16) + 16)));
53 gate_save_soc_clk((1 << ((CLK_GATE_PCLK_UART0 + CONFIG_RK_DEBUG_UART) % 16)),
54 clk_gate8, CRU_CLKGATES_CON(8),
55 (1 << (((CLK_GATE_PCLK_UART0 + CONFIG_RK_DEBUG_UART) % 16) + 16)));
58 writel_relaxed(byte, DEBUG_UART_BASE);
61 /* loop check LSR[6], Transmitter Empty bit */
62 while (!(readl_relaxed(DEBUG_UART_BASE + 0x14) & 0x40))
65 cru_writel(0xffff0000 | clk_gate2, CRU_CLKGATES_CON(2));
66 cru_writel(0xffff0000 | clk_gate4, CRU_CLKGATES_CON(4));
67 cru_writel(0xffff0000 | clk_gate8, CRU_CLKGATES_CON(8));
74 __weak void __sramfunc ddr_suspend(void) {}
75 __weak void __sramfunc ddr_resume(void) {}
76 __weak uint32_t __sramfunc ddr_change_freq(uint32_t nMHz) { return nMHz; }
78 #ifdef CONFIG_DDR_TEST
79 static int ddr_debug=0;
80 module_param(ddr_debug, int, 0644);
82 static int inline calc_crc32(u32 addr, size_t len)
84 return crc32_le(~0, (const unsigned char *)addr, len);
87 static void ddr_testmode(void)
89 int32_t g_crc1, g_crc2;
93 extern char _stext[], _etext[];
100 sram_printascii("\n change freq:");
101 g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
104 nMHz = min + random32();
109 nMHz = ddr_change_freq(nMHz);
112 g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
113 if (g_crc1!=g_crc2) {
114 sram_printascii("fail\n");
116 //ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
117 // sram_printascii("change freq success\n");
119 } else if(ddr_debug == 2) {
126 g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
127 nMHz = (random32()>>13);// 16.7s max
134 g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
135 if (g_crc1 != g_crc2) {
142 // ddr_print("check image crc32 fail!, count:%d\n", n++);
143 // sram_printascii("self refresh fail\n");
145 //ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
146 // sram_printascii("self refresh success\n");
148 } else if (ddr_debug == 3) {
149 extern int memtester(void);
154 ddr_change_freq(ddr_debug);
159 static void ddr_testmode(void) {}
162 static noinline void rk2928_pm_dump_irq(void)
164 u32 irq_gpio = (readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + (IRQ_GPIO0 / 32) * 4) >> (IRQ_GPIO0 % 32)) & 0xF;
165 printk("wakeup irq: %08x %08x %08x\n",
166 readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + 4),
167 readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + 8),
168 readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + 12));
170 printk("wakeup gpio0: %08x\n", readl_relaxed(RK2928_GPIO0_BASE + GPIO_INT_STATUS));
172 printk("wakeup gpio1: %08x\n", readl_relaxed(RK2928_GPIO1_BASE + GPIO_INT_STATUS));
174 printk("wakeup gpio2: %08x\n", readl_relaxed(RK2928_GPIO2_BASE + GPIO_INT_STATUS));
176 printk("wakeup gpio3: %08x\n", readl_relaxed(RK2928_GPIO3_BASE + GPIO_INT_STATUS));
179 #define DUMP_GPIO_INTEN(ID) \
181 u32 en = readl_relaxed(RK2928_GPIO##ID##_BASE + GPIO_INTEN); \
183 sram_printascii("GPIO" #ID "_INTEN: "); \
185 sram_printch('\n'); \
189 static noinline void rk2928_pm_dump_inten(void)
197 static void pm_pll_wait_lock(int pll_idx)
199 u32 pll_state[4] = {1, 0, 2, 3};
200 u32 bit = 0x10u << pll_state[pll_idx];
201 int delay = 24000000;
203 if ((cru_readl(PLL_CONS(pll_idx, 1)) & (0x1 << PLL_LOCK_SHIFT))) {
212 sram_printhex(pll_idx);
218 #define power_on_pll(id) \
219 cru_writel(PLL_PWR_DN_W_MSK|PLL_PWR_ON,PLL_CONS((id),3));\
220 pm_pll_wait_lock((id))
222 static int pm_pll_pwr_up(u8 pll_id)
224 u32 pllcon0,pllcon1,pllcon2;
226 cru_writel(PLL_MODE_SLOW(pll_id), CRU_MODE_CON);
227 cru_writel( CRU_W_MSK(PLL_PWR_DN_SHIFT, 0x01), PLL_CONS(pll_id, 1));
231 pm_pll_wait_lock(pll_id);
233 //cru_writel(PLL_MODE_NORM(pll_id), CRU_MODE_CON);
237 #define DDR_SAVE_SP(save_sp) do { save_sp = ddr_save_sp(((unsigned long)SRAM_DATA_END & (~7))); } while (0)
238 #define DDR_RESTORE_SP(save_sp) do { ddr_save_sp(save_sp); } while (0)
240 static unsigned long save_sp;
242 static noinline void interface_ctr_reg_pread(void)
248 local_flush_tlb_all();
250 for (addr = (u32)SRAM_CODE_OFFSET; addr < (u32)SRAM_DATA_END; addr += PAGE_SIZE)
252 readl_relaxed(RK2928_GRF_BASE);
253 readl_relaxed(RK2928_DDR_PCTL_BASE);
254 readl_relaxed(RK2928_DDR_PHY_BASE);
255 readl_relaxed(RK2928_GPIO0_BASE);
256 readl_relaxed(RK2928_GPIO1_BASE);
257 readl_relaxed(RK2928_GPIO2_BASE);
258 readl_relaxed(RK2928_GPIO3_BASE);
259 #if defined (CONFIG_MACH_RK2928_SDK)
260 readl_relaxed(RK2928_RKI2C1_BASE);
262 readl_relaxed(RK2928_RKI2C0_BASE);
266 __weak void board_gpio_suspend(void) {}
267 __weak void board_gpio_resume(void) {}
268 __weak void __sramfunc board_pmu_suspend(void) {}
269 __weak void __sramfunc board_pmu_resume(void) {}
270 __weak void __sramfunc rk30_suspend_voltage_set(unsigned int vol) {}
271 __weak void __sramfunc rk30_suspend_voltage_resume(unsigned int vol) {}
273 __weak void rk30_pwm_suspend_voltage_set(void) {}
274 __weak void rk30_pwm_resume_voltage_set(void) {}
276 __weak void __sramfunc rk30_pwm_logic_suspend_voltage(void) {}
277 __weak void __sramfunc rk30_pwm_logic_resume_voltage(void) {}
279 static void __sramfunc rk2928_sram_suspend(void)
282 u32 clkgt_regs[CRU_CLKGATES_CON_CNT];
289 rk30_suspend_voltage_set(1000000);
290 rk30_pwm_logic_suspend_voltage();
294 grf_uoc1_con = grf_readl(GRF_UOC1_CON4);
295 grf_writel(0x30000000,GRF_UOC1_CON4);
296 for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
297 clkgt_regs[i] = cru_readl(CRU_CLKGATES_CON(i));
300 | (1 << CLK_GATE_CORE_PERIPH)
301 | (1 << CLK_GATE_DDRPHY_SRC)
302 | (1 << CLK_GATE_ACLK_CPU)
303 | (1 << CLK_GATE_HCLK_CPU)
304 | (1 << CLK_GATE_PCLK_CPU)
305 | (1 << CLK_GATE_ACLK_CORE)
306 , clkgt_regs[0], CRU_CLKGATES_CON(0), 0xffff);
307 if (((clkgt_regs[8] >> (CLK_GATE_PCLK_GPIO0 % 16)) & 0xf) != 0xf) {
309 | (1 << CLK_GATE_PERIPH_SRC % 16)
310 | (1 << CLK_GATE_PCLK_PERIPH % 16)
311 , clkgt_regs[2], CRU_CLKGATES_CON(2), 0xffff);
313 gate_save_soc_clk(0, clkgt_regs[2], CRU_CLKGATES_CON(2), 0xffff);
316 | (1 << CLK_GATE_ACLK_STRC_SYS % 16)
317 | (1 << CLK_GATE_ACLK_INTMEM % 16)
318 , clkgt_regs[4], CRU_CLKGATES_CON(4), 0xffff);
320 | (1 << CLK_GATE_PCLK_GRF % 16)
321 | (1 << CLK_GATE_PCLK_DDRUPCTL % 16)
322 , clkgt_regs[5], CRU_CLKGATES_CON(5), 0xffff);
323 gate_save_soc_clk(0, clkgt_regs[7], CRU_CLKGATES_CON(7), 0xffff);
325 | (1 << CLK_GATE_CLK_L2C % 16)
326 , clkgt_regs[9], CRU_CLKGATES_CON(9), 0xffff);
328 // board_pmu_suspend();
329 cru_clksel0_con = cru_readl(CRU_CLKSELS_CON(0));
330 cru_writel((0x1f << 16) | 0x1f, CRU_CLKSELS_CON(0));
335 cru_writel((0x1f << 16) | cru_clksel0_con, CRU_CLKSELS_CON(0));
336 // board_pmu_resume();
338 for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
339 cru_writel(clkgt_regs[i] | 0xffff0000, CRU_CLKGATES_CON(i));
342 grf_writel(0x30000000|grf_uoc1_con,GRF_UOC1_CON4);
345 rk30_pwm_logic_resume_voltage();
346 rk30_suspend_voltage_resume(1100000);
352 static void noinline rk2928_suspend(void)
354 DDR_SAVE_SP(save_sp);
355 rk2928_sram_suspend();
356 DDR_RESTORE_SP(save_sp);
359 static int rk2928_pm_enter(suspend_state_t state)
362 u32 clkgt_regs[CRU_CLKGATES_CON_CNT];
363 u32 clk_sel0, clk_sel1, clk_sel10;
365 u32 apll_con1,cpll_con1,gpll_con1;
366 // dump GPIO INTEN for debug
367 rk2928_pm_dump_inten();
371 #ifdef CONFIG_DDR_TEST
380 for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
381 clkgt_regs[i] = cru_readl(CRU_CLKGATES_CON(i));
385 | (1 << CLK_GATE_CORE_PERIPH)
386 | (1 << CLK_GATE_CPU_GPLL)
387 | (1 << CLK_GATE_DDRPHY_SRC)
388 | (1 << CLK_GATE_ACLK_CPU)
389 | (1 << CLK_GATE_HCLK_CPU)
390 | (1 << CLK_GATE_PCLK_CPU)
391 | (1 << CLK_GATE_ACLK_CORE)
392 , clkgt_regs[0], CRU_CLKGATES_CON(0), 0xffff);
393 gate_save_soc_clk(0, clkgt_regs[1], CRU_CLKGATES_CON(1), 0xffff);
395 | (1 << CLK_GATE_PERIPH_SRC % 16)
396 | (1 << CLK_GATE_PCLK_PERIPH % 16)
397 | (1 << CLK_GATE_ACLK_PERIPH % 16)
398 , clkgt_regs[2], CRU_CLKGATES_CON(2), 0xffff);
399 gate_save_soc_clk(0, clkgt_regs[3], CRU_CLKGATES_CON(3), 0xffff);
401 | (1 << CLK_GATE_HCLK_PERI_AXI_MATRIX % 16)
402 | (1 << CLK_GATE_PCLK_PERI_AXI_MATRIX % 16)
403 | (1 << CLK_GATE_ACLK_CPU_PERI % 16)
404 | (1 << CLK_GATE_ACLK_PERI_AXI_MATRIX % 16)
405 | (1 << CLK_GATE_ACLK_STRC_SYS % 16)
406 | (1 << CLK_GATE_ACLK_INTMEM % 16)
407 , clkgt_regs[4], CRU_CLKGATES_CON(4), 0xffff);
409 | (1 << CLK_GATE_PCLK_GRF % 16)
410 | (1 << CLK_GATE_PCLK_DDRUPCTL % 16)
411 , clkgt_regs[5], CRU_CLKGATES_CON(5), 0xffff);
412 gate_save_soc_clk(0, clkgt_regs[6], CRU_CLKGATES_CON(6), 0xffff);
414 | (1 << CLK_GATE_PCLK_PWM01 % 16)
415 , clkgt_regs[7], CRU_CLKGATES_CON(7), 0xffff);
417 | (1 << CLK_GATE_PCLK_GPIO0 % 16)
418 | (1 << CLK_GATE_PCLK_GPIO1 % 16)
419 | (1 << CLK_GATE_PCLK_GPIO2 % 16)
420 | (1 << CLK_GATE_PCLK_GPIO3 % 16)
421 , clkgt_regs[8], CRU_CLKGATES_CON(8), 0xffff);
422 cru_writel( ((1 << CLK_GATE_PCLK_GPIO0 % 16)<<16), CRU_CLKGATES_CON(8));
424 | (1 << CLK_GATE_CLK_L2C % 16)
425 | (1 << CLK_GATE_HCLK_PERI_ARBI % 16)
426 | (1 << CLK_GATE_ACLK_PERI_NIU % 16)
427 , clkgt_regs[9], CRU_CLKGATES_CON(9), 0xffff);
431 cru_mode_con = cru_readl(CRU_MODE_CON);
434 clk_sel0 = cru_readl(CRU_CLKSELS_CON(0));
435 clk_sel1 = cru_readl(CRU_CLKSELS_CON(1));
436 apll_con1 = cru_readl(PLL_CONS(APLL_ID, 1));
438 cru_writel(PLL_MODE_SLOW(APLL_ID), CRU_MODE_CON);
439 cru_writel(CLK_CORE_DIV(1) | ACLK_CPU_DIV(1) | CPU_SEL_PLL(SEL_APLL), CRU_CLKSELS_CON(0));
440 cru_writel(CLK_CORE_PERI_DIV(1) | ACLK_CORE_DIV(1) | HCLK_CPU_DIV(1) | PCLK_CPU_DIV(1), CRU_CLKSELS_CON(1));
441 //cru_writel((0x01 <<(PLL_PWR_DN_SHIFT + 16))|(1<<PLL_PWR_DN_SHIFT), PLL_CONS(APLL_ID, 1));
442 cru_writel(CRU_W_MSK_SETBIT(0x01, PLL_PWR_DN_SHIFT) , PLL_CONS(APLL_ID, 1)); //power down apll
445 cpll_con1 = cru_readl(PLL_CONS(CPLL_ID, 1));
447 cru_writel(PLL_MODE_SLOW(CPLL_ID), CRU_MODE_CON);
448 cru_writel(CRU_W_MSK_SETBIT(0x01, PLL_PWR_DN_SHIFT), PLL_CONS(CPLL_ID, 1));//power down cpll
451 clk_sel10 = cru_readl(CRU_CLKSELS_CON(10));
452 gpll_con1 = cru_readl(PLL_CONS(GPLL_ID, 1));
454 cru_writel(PLL_MODE_SLOW(GPLL_ID), CRU_MODE_CON);
455 cru_writel(PERI_SET_ACLK_DIV(1)
456 | PERI_SET_A2H_RATIO(RATIO_11)
457 | PERI_SET_A2P_RATIO(RATIO_11)
458 , CRU_CLKSELS_CON(10));
459 cru_writel(CRU_W_MSK_SETBIT(0x01, PLL_PWR_DN_SHIFT), PLL_CONS(GPLL_ID, 1));//power down gpll
462 rk30_pwm_suspend_voltage_set();
464 board_gpio_suspend();
466 interface_ctr_reg_pread();
473 rk30_pwm_resume_voltage_set();
477 pm_pll_pwr_up(GPLL_ID);
478 cru_writel(0xffff0000 | clk_sel10, CRU_CLKSELS_CON(10));
479 cru_writel(clk_sel10, CRU_CLKSELS_CON(10));
480 cru_writel((PLL_MODE_MSK(GPLL_ID) << 16) | (PLL_MODE_MSK(GPLL_ID) & cru_mode_con), CRU_MODE_CON);
483 if(!(cpll_con1&(0x1<<PLL_PWR_DN_SHIFT)))
484 pm_pll_pwr_up(CPLL_ID);
485 cru_writel((PLL_MODE_MSK(CPLL_ID) << 16) | (PLL_MODE_MSK(CPLL_ID) & cru_mode_con), CRU_MODE_CON);
488 pm_pll_pwr_up(APLL_ID);
489 cru_writel(0xffff0000 | clk_sel1, CRU_CLKSELS_CON(1));
490 cru_writel(0xffff0000 | clk_sel0, CRU_CLKSELS_CON(0));
491 cru_writel((PLL_MODE_MSK(APLL_ID) << 16) | (PLL_MODE_MSK(APLL_ID) & cru_mode_con), CRU_MODE_CON);
495 for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) {
496 cru_writel(clkgt_regs[i] | 0xffff0000, CRU_CLKGATES_CON(i));
502 sram_printascii("0\n");
504 rk2928_pm_dump_irq();
509 static int rk2928_pm_prepare(void)
511 /* disable entering idle by disable_hlt() */
516 static void rk2928_pm_finish(void)
521 static struct platform_suspend_ops rk2928_pm_ops = {
522 .enter = rk2928_pm_enter,
523 .valid = suspend_valid_only_mem,
524 .prepare = rk2928_pm_prepare,
525 .finish = rk2928_pm_finish,
528 static int __init rk2928_pm_init(void)
530 suspend_set_ops(&rk2928_pm_ops);
532 #ifdef CONFIG_EARLYSUSPEND
533 pm_set_vt_switch(0); /* disable vt switch while suspend */
538 __initcall(rk2928_pm_init);