4 #include <linux/delay.h>
6 #include <linux/kernel.h>
7 #include <linux/init.h>
9 #include <linux/suspend.h>
10 #include <linux/random.h>
11 #include <linux/crc32.h>
13 #include <linux/wakelock.h>
14 #include <asm/tlbflush.h>
15 #include <asm/hardware/gic.h>
17 #include <mach/rk29_iomap.h>
20 #include <mach/board.h>
21 #include <mach/system.h>
22 #include <mach/sram.h>
23 #include <mach/gpio.h>
25 #include <mach/memtester.h>
26 #include <mach/iomux.h>
27 #include <mach/pm-vol.h>
31 #define grf_readl(offset) readl(RK29_GRF_BASE + offset)
32 #define grf_writel(v, offset) do { writel(v, RK29_GRF_BASE + offset); readl(RK29_GRF_BASE + offset); } while (0)
34 static unsigned long save_sp;
36 static inline void delay_500ns(void)
41 static inline void delay_300us(void)
43 LOOP(300 * LOOPS_PER_USEC);
47 void/* inline*/ __sramfunc sram_printch(char byte)
52 local_irq_save(flags);
53 gate1 = cru_readl(CRU_CLKGATE1_CON);
54 gate2 = cru_readl(CRU_CLKGATE2_CON);
55 cru_writel(gate1 & ~((1 << CLK_GATE_PCLK_PEIRPH % 32) | (1 << CLK_GATE_ACLK_PEIRPH % 32) | (1 << CLK_GATE_ACLK_CPU_PERI % 32)), CRU_CLKGATE1_CON);
56 cru_writel(gate2 & ~(1 << CLK_GATE_UART1 % 32), CRU_CLKGATE2_CON);
59 writel(byte, RK29_UART1_BASE);
61 /* loop check LSR[6], Transmitter Empty bit */
62 while (!(readl(RK29_UART1_BASE + 0x14) & 0x40))
65 cru_writel(gate2, CRU_CLKGATE2_CON);
66 cru_writel(gate1, CRU_CLKGATE1_CON);
67 local_irq_restore(flags);
72 void print(const char *s)
77 void __sramfunc print_Hex(unsigned int hex)
83 unsigned char c = (hex & 0xF0000000) >> 28;
84 sram_printch(c < 0xa ? c + '0' : c - 0xa + 'a');
89 void __sramfunc print_Dec (uint32_t n)
96 sram_printch((char)(n + '0'));
99 void print_Dec_3(uint32_t value)
116 static void inline sram_printch(char byte) {}
117 static void inline sram_printascii(const char *s) {}
118 static void inline printhex(unsigned int hex) {}
121 /*volatile __sramdata */int ddr_debug;
122 module_param(ddr_debug, int, 0644);
124 static int inline calc_crc32(u32 addr, size_t len)
126 return crc32_le(~0,(const unsigned char *)addr,len);
128 void __sramfunc ddr_testmode(void)
130 int32_t g_crc1,g_crc2;
133 extern char _stext[], _etext[];
138 sram_printascii("change freq\n");
139 g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
140 nMHz = 333 + random32();
144 nMHz = ddr_change_freq(nMHz);
149 g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
152 sram_printascii("fail\n");
154 //ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
155 // sram_printascii("change freq success\n");
158 else if(ddr_debug == 2)
167 g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
168 nMHz = (random32()>>13);// 16.7s max
175 g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext));
184 // ddr_print("check image crc32 fail!, count:%d\n", n++);
185 // sram_printascii("self refresh fail\n");
187 //ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++);
188 // sram_printascii("self refresh success\n");
191 else if(ddr_debug == 3)
197 void __sramfunc ddr_testmode(void)
201 void __sramfunc pm_clk_switch_32k(void);
203 void __sramfunc pm_wfi(void)
207 clksel0 = cru_readl(CRU_CLKSEL0_CON);
208 /* set arm clk 24MHz/32 = 750KHz */
209 cru_writel(clksel0 | 0x1F, CRU_CLKSEL0_CON);
217 cru_writel(clksel0, CRU_CLKSEL0_CON);
223 static void __sramfunc rk29_sram_suspend(void)
234 vol=rk29_suspend_voltage_set(1000000);
235 #ifdef CONFIG_RK29_CLK_SWITCH_TO_32K
240 rk29_suspend_voltage_resume(vol);
247 static void noinline rk29_suspend(void)
249 DDR_SAVE_SP(save_sp);
251 DDR_RESTORE_SP(save_sp);
254 static void dump_irq(void)
256 u32 irq_gpio = (readl(RK29_GICPERI_BASE + GIC_DIST_PENDING_SET + 8) >> 23) & 0x7F;
257 printk("wakeup irq: %08x %08x %01x\n",
258 readl(RK29_GICPERI_BASE + GIC_DIST_PENDING_SET + 4),
259 readl(RK29_GICPERI_BASE + GIC_DIST_PENDING_SET + 8),
260 readl(RK29_GICPERI_BASE + GIC_DIST_PENDING_SET + 12) & 0xf);
262 printk("wakeup gpio0: %08x\n", readl(RK29_GPIO0_BASE + GPIO_INT_STATUS));
264 printk("wakeup gpio1: %08x\n", readl(RK29_GPIO1_BASE + GPIO_INT_STATUS));
266 printk("wakeup gpio2: %08x\n", readl(RK29_GPIO2_BASE + GPIO_INT_STATUS));
268 printk("wakeup gpio3: %08x\n", readl(RK29_GPIO3_BASE + GPIO_INT_STATUS));
270 printk("wakeup gpio4: %08x\n", readl(RK29_GPIO4_BASE + GPIO_INT_STATUS));
272 printk("wakeup gpio5: %08x\n", readl(RK29_GPIO5_BASE + GPIO_INT_STATUS));
274 printk("wakeup gpio6: %08x\n", readl(RK29_GPIO6_BASE + GPIO_INT_STATUS));
277 #define DUMP_GPIO_INTEN(ID) \
279 u32 en = readl(RK29_GPIO##ID##_BASE + GPIO_INTEN); \
281 sram_printascii("GPIO" #ID "_INTEN: "); \
283 sram_printch('\n'); \
287 static void dump_inten(void)
300 #define DUMP_GPIO_PULL(ID) \
302 u32 state = readl(RK29_GRF_BASE + GRF_GPIO0_PULL + (ID<<2)); \
303 sram_printascii("GPIO" #ID "_PULL: "); \
304 sram_printhex(state); \
305 sram_printch('\n'); \
308 static void dump_io_pull(void)
318 #ifdef CONFIG_RK29_NEON_POWERDOMAIN_SET
319 /*******************************neon powermain***********************/
320 #define pmu_read(offset) readl(RK29_PMU_BASE + (offset))
321 #define pmu_write(offset, value) writel((value), RK29_PMU_BASE + (offset))
322 #define PMU_PG_CON 0x10
323 #define vfpreg(_vfp_) #_vfp_
325 #define fmrx(_vfp_) ({ \
327 asm("mrc p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_ \
328 : "=r" (__v) : : "cc"); \
332 #define fmxr(_vfp_,_var_) \
333 asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \
334 : : "r" (_var_) : "cc")
335 extern void vfp_save_state(void *location, u32 fpexc);
336 extern void vfp_load_state(void *location, u32 fpexc);
337 // extern __sramdata u64 saveptr[33];
338 static u32 saveptr[2][60]={};
339 static void neon_powerdomain_off(void)
347 fpexc= fmrx(FPEXC); //get neon Logic gate
349 fmxr(FPEXC, fpexc | FPEXC_EN); //open neon Logic gate
351 vfp_save_state(p,fpexc); //save neon reg,32 D reg,2 control reg
354 fmxr(FPEXC, fpexc & ~FPEXC_EN); //close neon Logic gate
356 ret=pmu_read(PMU_PG_CON); //get power domain state
357 pmu_write(PMU_PG_CON,ret|(0x1<<1)); //powerdomain off neon
358 printk("neon powerdomain is off\n");
360 static void neon_powerdomain_on(void)
367 ret=pmu_read(PMU_PG_CON); //get power domain state
368 pmu_write(PMU_PG_CON,ret&~(0x1<<1)); //powerdomain on neon
371 fpexc = fmrx(FPEXC); //get neon Logic gate
372 fmxr(FPEXC, fpexc | FPEXC_EN); //open neon Logic gate
374 vfp_load_state(p,fpexc); //recovery neon reg, 32 D reg,2 control reg
377 fmxr(FPEXC, fpexc | FPEXC_EN); //open neon Logic gate
378 printk("neon powerdomain is on\n");
381 /*******************************neon powermain***********************/
383 void pm_gpio_suspend(void);
384 void pm_gpio_resume(void);
386 static int rk29_pm_enter(suspend_state_t state)
388 u32 apll, cpll, gpll, mode, clksel0;
391 #ifdef CONFIG_RK29_NEON_POWERDOMAIN_SET
392 neon_powerdomain_off();
399 // dump GPIO INTEN for debug
401 // dump GPIO PULL state for debug
402 //if you want to display the information, please enable the code.
409 #if defined(CONFIG_RK29_SPI_INSRAM) || defined(CONFIG_RK29_PWM_INSRAM)
410 interface_ctr_reg_pread();
412 #if defined(CONFIG_RK29_I2C_INSRAM)
413 i2c_interface_ctr_reg_pread();
417 clkgate[0] = cru_readl(CRU_CLKGATE0_CON);
418 clkgate[1] = cru_readl(CRU_CLKGATE1_CON);
419 clkgate[2] = cru_readl(CRU_CLKGATE2_CON);
420 clkgate[3] = cru_clkgate3_con_mirror;
421 cru_writel(~((1 << CLK_GATE_CORE)
422 | (1 << CLK_GATE_ACLK_CPU)
423 | (1 << CLK_GATE_ACLK_CPU2)
424 | (1 << CLK_GATE_PCLK_CPU)
425 | (1 << CLK_GATE_GIC)
426 | (1 << CLK_GATE_INTMEM)
427 | (1 << CLK_GATE_DDR_PHY)
428 | (1 << CLK_GATE_DDR_REG)
429 | (1 << CLK_GATE_DDR_CPU)
430 | (1 << CLK_GATE_GPIO0)
431 | (1 << CLK_GATE_RTC)
432 | (1 << CLK_GATE_GRF)
433 #ifdef CONFIG_RK29_JTAG
434 | (1 << CLK_GATE_PCLK_CORE)
435 | (1 << CLK_GATE_ATCLK_CORE)
436 | (1 << CLK_GATE_ATCLK_CPU)
437 | (1 << CLK_GATE_DEBUG)
438 | (1 << CLK_GATE_TPIU)
440 ) | clkgate[0], CRU_CLKGATE0_CON);
442 #ifdef CONFIG_PHONE_INCALL_IS_SUSPEND
443 #if defined(CONFIG_SND_RK29_SOC_I2S_8CH)
444 cru_writel(clkgate[0]&(~(1<<CLK_GATE_I2S0)),CRU_CLKGATE0_CON);
445 #elif defined(CONFIG_SND_RK29_SOC_I2S_2CH)
446 cru_writel(clkgate[0]&(~(1<<CLK_GATE_I2S1)),CRU_CLKGATE0_CON);
450 cru_writel(~0, CRU_CLKGATE1_CON);
451 cru_writel(~((1 << CLK_GATE_GPIO1 % 32)
452 | (1 << CLK_GATE_GPIO2 % 32)
453 | (1 << CLK_GATE_GPIO3 % 32)
454 | (1 << CLK_GATE_GPIO4 % 32)
455 | (1 << CLK_GATE_GPIO5 % 32)
456 | (1 << CLK_GATE_GPIO6 % 32)
457 | (1 << CLK_GATE_PWM % 32)
458 #ifdef CONFIG_RK29_JTAG
459 | (1 << CLK_GATE_JTAG % 32)
461 ) | clkgate[2], CRU_CLKGATE2_CON);
462 cru_writel(~0, CRU_CLKGATE3_CON);
465 mode = cru_readl(CRU_MODE_CON);
466 clksel0 = cru_readl(CRU_CLKSEL0_CON);
468 /* suspend arm pll */
469 apll = cru_readl(CRU_APLL_CON);
470 cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CPU_MODE_MASK) | CRU_CPU_MODE_SLOW, CRU_MODE_CON);
471 cru_writel(apll | PLL_BYPASS, CRU_APLL_CON);
472 cru_writel(apll | PLL_PD | PLL_BYPASS, CRU_APLL_CON);
474 /* set core = aclk_cpu = hclk_cpu = pclk_cpu = 24MHz */
475 cru_writel(clksel0 & 0xFFFFF000, CRU_CLKSEL0_CON);
478 /* suspend codec pll */
479 cpll = cru_readl(CRU_CPLL_CON);
480 cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CODEC_MODE_MASK) | CRU_CODEC_MODE_SLOW, CRU_MODE_CON);
481 cru_writel(cpll | PLL_BYPASS, CRU_CPLL_CON);
482 cru_writel(cpll | PLL_PD | PLL_BYPASS, CRU_CPLL_CON);
486 /* suspend general pll */
487 gpll = cru_readl(CRU_GPLL_CON);
488 cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_GENERAL_MODE_MASK) | CRU_GENERAL_MODE_SLOW, CRU_MODE_CON);
489 cru_writel(gpll | PLL_BYPASS, CRU_GPLL_CON);
490 cru_writel(gpll | PLL_PD | PLL_BYPASS, CRU_GPLL_CON);
492 /* set aclk_periph = hclk_periph = pclk_periph = 24MHz */
493 cru_writel(clksel0 & ~0x7FC000, CRU_CLKSEL0_CON);
501 /* resume general pll */
502 cru_writel(gpll, CRU_GPLL_CON);
504 /* restore aclk_periph/hclk_periph/pclk_periph */
505 cru_writel(cru_readl(CRU_CLKSEL0_CON) | (clksel0 & 0x7FC000), CRU_CLKSEL0_CON);
506 cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_GENERAL_MODE_MASK) | (mode & CRU_GENERAL_MODE_MASK), CRU_MODE_CON);
509 /* resume codec pll */
510 cru_writel(cpll, CRU_CPLL_CON);
512 cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CODEC_MODE_MASK) | (mode & CRU_CODEC_MODE_MASK), CRU_MODE_CON);
516 cru_writel(apll, CRU_APLL_CON);
518 /* restore core/aclk_cpu/hclk_cpu/pclk_cpu */
519 cru_writel(cru_readl(CRU_CLKSEL0_CON) | (clksel0 & 0xFFF), CRU_CLKSEL0_CON);
520 cru_writel((cru_readl(CRU_MODE_CON) & ~CRU_CPU_MODE_MASK) | (mode & CRU_CPU_MODE_MASK), CRU_MODE_CON);
524 cru_writel(clkgate[0], CRU_CLKGATE0_CON);
525 cru_writel(clkgate[1], CRU_CLKGATE1_CON);
526 cru_writel(clkgate[2], CRU_CLKGATE2_CON);
527 cru_writel(clkgate[3], CRU_CLKGATE3_CON);
528 sram_printascii("0\n");
532 #ifdef CONFIG_RK29_NEON_POWERDOMAIN_SET
533 neon_powerdomain_on();
539 static int rk29_pm_prepare(void)
541 /* disable entering rk29_idle() by disable_hlt() */
546 static void rk29_pm_finish(void)
551 static struct platform_suspend_ops rk29_pm_ops = {
552 .enter = rk29_pm_enter,
553 .valid = suspend_valid_only_mem,
554 .prepare = rk29_pm_prepare,
555 .finish = rk29_pm_finish,
558 static void rk29_idle(void)
560 if (!need_resched()) {
562 #ifdef CONFIG_HAS_WAKELOCK
563 allow_sleep = !has_wake_lock(WAKE_LOCK_IDLE);
566 u32 mode_con = cru_readl(CRU_MODE_CON);
567 cru_writel((mode_con & ~CRU_CPU_MODE_MASK) | CRU_CPU_MODE_SLOW, CRU_MODE_CON);
569 cru_writel(mode_con, CRU_MODE_CON);
577 static int __init rk29_pm_init(void)
579 suspend_set_ops(&rk29_pm_ops);
581 /* set idle function */
585 #ifdef CONFIG_EARLYSUSPEND
586 pm_set_vt_switch(0); /* disable vt switch while suspend */
591 __initcall(rk29_pm_init);