From e0b28271ea07da1df384335c35ac018e9b20b0e8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E5=AE=8B=E7=A7=80=E6=9D=B0?= Date: Tue, 14 Sep 2010 01:34:23 -0700 Subject: [PATCH] add raho pm control, add LCDC resume --- arch/arm/mach-rk2818/pm.c | 458 ++++++++++++++++++++++++++++++++++---- drivers/video/rk2818_fb.c | 3 +- 2 files changed, 419 insertions(+), 42 deletions(-) mode change 100644 => 100755 arch/arm/mach-rk2818/pm.c diff --git a/arch/arm/mach-rk2818/pm.c b/arch/arm/mach-rk2818/pm.c old mode 100644 new mode 100755 index c9f19c05e1a1..ba48fee04149 --- a/arch/arm/mach-rk2818/pm.c +++ b/arch/arm/mach-rk2818/pm.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include extern void rockchip_timer_clocksource_suspend_resume(int suspend); extern int rockchip_timer_clocksource_irq_checkandclear(void); @@ -39,10 +41,6 @@ static int rk28_usb_check_connectid_change(void) { return 0; } #define ddr_readl(offset) readl(RK2818_SDRAMC_BASE + offset) #define ddr_writel(v, offset) writel(v, RK2818_SDRAMC_BASE + offset) -#define irq_readl(offset) readl(RK2818_INTC_BASE + offset) -#define gpio0_readl(offset) readl(RK2818_GPIO0_BASE + offset) -#define gpio1_readl(offset) readl(RK2818_GPIO1_BASE + offset) - #define PLL_PD (0x01u<<22) /* CPU_APB_REG0 */ @@ -59,6 +57,17 @@ static inline u32 sdram_get_mem_type(void) return (regfile_readl(CPU_APB_REG0) & MEMTYPEMASK) >> MEMTYPESHIFT; } +#define ASM_LOOP_INSTRUCTION_NUM 4 + +/*static noinline void __tcmlocalfunc tcm_udelay(unsigned long usecs, u32 arm_freq_mhz) +{ + volatile unsigned int cycle; + + cycle = usecs * arm_freq_mhz / ASM_LOOP_INSTRUCTION_NUM; + + while (cycle--) {} +}*/ + #define CLK_GATE_SDRAM_MASK ((1 << (CLK_GATE_SDRAM_COMMON & 31)) | (1 << (CLK_GATE_SDRAM_CONTROLLER & 31))) #define CLK_GATE_MOBILESDRAM_MASK ((1 << (CLK_GATE_SDRAM_COMMON & 31)) | (1 << (CLK_GATE_MOBILE_SDRAM_CONTROLLER & 31))) @@ -154,17 +163,414 @@ void __tcmfunc sdram_exit_self_refresh(u32 ctrl_reg_62) tcm_udelay(100, 24); //DRVDelayUs(100); 延时一下比较安全,保证退出后稳定 } +#define RK2818_MOBLIE_PM_CON +#ifdef RK2818_MOBLIE_PM_CON + +#define RK2818_MOBLIE_PM_PRT_ORIGINAL_REG +//#define RK2818_MOBLIE_PM_PRT_CHANGED_REG + +#define PM_SAVE_REG_NUM 4 +struct rk2818_pm_st{ +unsigned int *pm_scu_reg; +unsigned int *pm_cpu_reg; +unsigned int *pm_gpio0_reg; +unsigned int *pm_gpio1_reg; +unsigned int *savereg; + +unsigned int *pm_scu_reg_ch; +unsigned int *pm_cpu_reg_ch; +unsigned int *pm_gpio0_reg_ch; +unsigned int *pm_gpio1_reg_ch; +unsigned int *save_ch; + +u16 scu_regbit; +u16 cpu_regbit; +u16 gpio0_regbit; +u16 gpio1_regbit; + + +}; +unsigned int __tcmdata pm_scu_reg_save[PM_SCU_REG_NUM]; +unsigned int __tcmdata pm_cpu_reg_save[PM_GENERAL_CPU_REG]; +unsigned int __tcmdata pm_gpio0_reg_save[PM_SCU_GPIO_SWPORTC_NUM]; +unsigned int __tcmdata pm_gpio1_reg_save[PM_SCU_GPIO_SWPORTC_NUM]; +unsigned int __tcmdata pm_savereg[PM_SAVE_REG_NUM]; + +unsigned int __tcmdata pm_scu_reg_ch[PM_SCU_REG_NUM]; +unsigned int __tcmdata pm_cpu_reg_ch[PM_GENERAL_CPU_REG]; +unsigned int __tcmdata pm_gpio0_reg_save_ch[PM_SCU_GPIO_SWPORTC_NUM]; +unsigned int __tcmdata pm_gpio1_reg_save_ch[PM_SCU_GPIO_SWPORTC_NUM]; +unsigned int __tcmdata savereg_ch[PM_SAVE_REG_NUM]; + + + + +struct rk2818_pm_st __tcmdata pm_save={ +.pm_scu_reg=&pm_scu_reg_save[0], +.pm_cpu_reg=&pm_cpu_reg_save[0], +.pm_gpio0_reg=&pm_gpio0_reg_save[0], +.pm_gpio1_reg=&pm_gpio1_reg_save[0], +.savereg=&pm_savereg[0], + + +.pm_scu_reg_ch=&pm_scu_reg_ch[0], +.pm_cpu_reg_ch=&pm_cpu_reg_ch[0], +.pm_gpio0_reg_ch=&pm_gpio0_reg_save_ch[0], +.pm_gpio1_reg_ch=&pm_gpio1_reg_save_ch[0], +.save_ch=&savereg_ch[0], +}; + + + +#if 0 +#define rk2818_define_value \ +unsigned int pm_scu_reg_save[PM_SCU_REG_NUM];\ +unsigned int pm_cpu_reg_save[PM_GENERAL_CPU_REG];\ +unsigned int pm_gpio0_reg_save[PM_SCU_GPIO_SWPORTC_NUM];\ +unsigned int pm_gpio1_reg_save[PM_SCU_GPIO_SWPORTC_NUM];\ +unsigned int save[4];\ +unsigned int pm_scu_reg_ch[PM_SCU_REG_NUM];\ +unsigned int pm_cpu_reg_ch[PM_GENERAL_CPU_REG];\ +struct rk2818_pm_st pm_save={&pm_scu_reg_save[0],&pm_cpu_reg_save[0],&pm_gpio0_reg_save[0],&pm_gpio1_reg_save[0],&save[0]\ +,&pm_scu_reg_ch[0],&pm_cpu_reg_ch[0]\ +};\ +struct regulator *buck1 + +#endif +static int __tcmfunc pm_set_gpio_pinstate(unsigned int gpio,unsigned int output,unsigned int level) +{ + unsigned int *rk2818_gpio_reg; + unsigned int regoff; + + if(gpio>=RK2818GPIO_TOTAL) + return -1; + + if(gpio<32) + rk2818_gpio_reg=(unsigned int *)RK2818_GPIO0_BASE; + else + { + rk2818_gpio_reg=(unsigned int *)RK2818_GPIO1_BASE; + gpio-=32; + } + + regoff=PM_GPIO_SWPORTA_DR+(gpio/8)*3; + gpio%=8; + + if(output) + { + rk2818_gpio_reg[regoff+1]|=(1<pm_scu_reg,rk2818_scu_reg,PM_SCU_REG_NUM); + rk2818_pm_save_reg(pm_save->pm_cpu_reg,rk2818_cpu_reg,PM_GENERAL_CPU_REG); + rk2818_pm_save_reg(pm_save->pm_gpio0_reg,rk2818_gpio0_reg,PM_SCU_GPIO_SWPORTC_NUM); + rk2818_pm_save_reg(pm_save->pm_gpio1_reg,rk2818_gpio1_reg,PM_SCU_GPIO_SWPORTC_NUM); + pm_save->scu_regbit=0; + pm_save->cpu_regbit=0; + pm_save->gpio0_regbit=0x6db; + pm_save->gpio1_regbit=0x6db; + //pm_save->savereg[0]=rk2818_ddr_reg[82]; + //rk2818_ddr_reg[82]=rk2818_ddr_reg[82]&(~(0xffff))&(~(0xf<<20)); + + //pm_set_gpio_pinstate(RK2818_PIN_PC2,1,0); //¿ØÖÆPMUµÄDVS½Å +} + +static void __tcmfunc rk2818_pm_resume_first(struct rk2818_pm_st *pm_save) +{ + unsigned int *rk2818_ddr_reg=(unsigned int *)RK2818_SDRAMC_BASE; + + //pm_set_gpio_pinstate(RK2818_PIN_PC2,1,1); //¿ØÖÆPMUµÄDVS½Å + + //rk2818_ddr_reg[82]=pm_save->save[0]; + +} +static void __tcmfunc rk2818_soc_scu_suspend(struct rk2818_pm_st *pm_save) +{ + + unsigned int *rk2818_scu_reg=(unsigned int *)RK2818_SCU_BASE; + int i; + + pm_save->scu_regbit|=(0x1<scu_regbit|=(0x1<scu_regbit|=(0x1<scu_regbit|=(0x1<scu_regbit|=(0x1<scu_regbit|=(0x1<scu_regbit|=(0x1<scu_regbit|=(0x1<scu_regbit|=(0x1<scu_regbit|=(0x1<scu_regbit|=(0x1<pm_scu_reg_ch,rk2818_scu_reg,PM_SCU_REG_NUM); + #endif + + +} +// output 1 is a output pin + +static void __tcmfunc rk2818_soc_general_cpu_suspend(struct rk2818_pm_st *pm_save) +{ + + unsigned int *rk2818_cpu_reg=(unsigned int *)RK2818_REGFILE_BASE; + unsigned int *rk2818_gpio0_reg=(unsigned int *)RK2818_GPIO0_BASE; + unsigned int *rk2818_gpio1_reg=(unsigned int *)RK2818_GPIO1_BASE; + + int i; + + #if 0 + pm_save->cpu_regbit|=(0x1<cpu_regbit|=(0x1<cpu_regbit|=(0x1<cpu_regbit|=(0x1<cpu_regbit|=(0x1<cpu_regbit|=(0x1<pm_cpu_reg_ch,rk2818_cpu_reg,PM_GENERAL_CPU_REG); + rk2818_pm_save_reg(pm_save->pm_gpio0_reg_ch,rk2818_gpio0_reg,PM_SCU_GPIO_SWPORTC_NUM); + rk2818_pm_save_reg(pm_save->pm_gpio1_reg_ch,rk2818_gpio1_reg,PM_SCU_GPIO_SWPORTC_NUM); +#endif + +} +static void rk2818_pm_reg_print(unsigned int *pm_save_reg,unsigned int *pm_ch_reg,int num,char *name) +{ + int i; -static void __tcmfunc rk2818_tcm_idle(void) +#ifdef RK2818_MOBLIE_PM_PRT_ORIGINAL_REG + printk("***the follow inf is %s original reg***\n",name); + for(i=0;i>i)&0x0001) + base_add[i]=pm_save_reg[i]; + } +} +void __tcmfunc rk2818_pm_soc_suspend(struct rk2818_pm_st *pm_save) +{ + rk2818_soc_scu_suspend(pm_save); + //rk2818_soc_general_cpu_suspend(pm_save); +} +void __tcmfunc rk2818_pm_soc_resume(struct rk2818_pm_st *pm_save) +{ + rk2818_soc_resume(pm_save->pm_scu_reg,RK2818_SCU_BASE,pm_save->scu_regbit,PM_SCU_REG_NUM); + //rk2818_soc_resume(pm_save->pm_cpu_reg,RK2818_REGFILE_BASE,pm_save->cpu_regbit,PM_GENERAL_CPU_REG); +} +void rk2818_pm_print(struct rk2818_pm_st *pm_save) +{ + rk2818_pm_reg_print(pm_save->pm_scu_reg,pm_save->pm_scu_reg_ch,PM_SCU_REG_NUM,"scu"); + //rk2818_pm_reg_print(pm_save->pm_cpu_reg,pm_save->pm_cpu_reg,PM_GENERAL_CPU_REG,"general_cpu"); + //rk2818_pm_reg_print(pm_save->pm_gpio0_reg,pm_save->pm_gpio0_reg,PM_SCU_GPIO_SWPORTC_NUM,"gpio0"); + //rk2818_pm_reg_print(pm_save->pm_gpio1_reg,pm_save->pm_gpio1_reg,PM_SCU_GPIO_SWPORTC_NUM,"gpio1"); +} + +#else +#define rk2818_pm_suspend_first(a) +#define rk2818_pm_resume_first(b) +#define rk2818_pm_soc_suspend(a) +#define rk2818_pm_soc_resume(a) +#define rk2818_define_value + +#endif +static int __tcmfunc rk2818_tcm_idle(void) +{ + // rk2818_define_value; + volatile u32 unit; u32 ctrl_reg_62; + + u32 scu_mode = scu_readl(SCU_MODE_CON); + u32 scu_apll = scu_readl(SCU_APLL_CON); + u32 scu_clksel0 = scu_readl(SCU_CLKSEL0_CON); + printk("enter suspend\n"); asm("b 1f; .align 5; 1:"); asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ + + + scu_writel(scu_mode & ~(3 << 2), SCU_MODE_CON); // slow + scu_writel(scu_apll | PLL_PD, SCU_APLL_CON); // powerdown + ctrl_reg_62 = sdram_enter_self_refresh(); + + tcm_udelay(1, 24); + rk2818_pm_suspend_first((struct rk2818_pm_st *)&pm_save.pm_scu_reg); + tcm_udelay(1, 24); + rk2818_pm_soc_suspend((struct rk2818_pm_st *)&pm_save.pm_scu_reg); + tcm_udelay(1, 24); asm("mcr p15, 0, r0, c7, c0, 4"); /* wait for interrupt */ + rk2818_pm_resume_first((struct rk2818_pm_st *)&pm_save.pm_scu_reg); + tcm_udelay(1, 24); + rk2818_pm_soc_resume((struct rk2818_pm_st *)&pm_save.pm_scu_reg); + tcm_udelay(1, 24); sdram_exit_self_refresh(ctrl_reg_62); + + //regulator_set_voltage(buck1,1200000,1200000); + + scu_writel(scu_apll, SCU_APLL_CON); // powerup + scu_writel(scu_clksel0 & (~3), SCU_CLKSEL0_CON); + + unit = 7200; /* 24m,0.3ms , 24*300*/ + while (unit-- > 0) { + if (regfile_readl(CPU_APB_REG0) & 0x80) + break; + } + + tcm_udelay(5 << 8, 24); + scu_writel(scu_clksel0, SCU_CLKSEL0_CON); + tcm_udelay(5, 24); + + scu_writel(scu_mode, SCU_MODE_CON); // normal + rk2818_pm_print((struct rk2818_pm_st *)&pm_save.pm_scu_reg); + return unit; } static void rk2818_idle(void) @@ -178,46 +584,21 @@ static void rk2818_idle(void) asm volatile ("mov sp, %0" :: "r" (old_sp)); } -static void dump_register(void) -{ -#ifdef CONFIG_PM_DEBUG - printk(KERN_DEBUG "SCU_APLL_CON : 0x%08x\n", scu_readl(SCU_APLL_CON)); - printk(KERN_DEBUG "SCU_DPLL_CON : 0x%08x\n", scu_readl(SCU_DPLL_CON)); - printk(KERN_DEBUG "SCU_CPLL_CON : 0x%08x\n", scu_readl(SCU_CPLL_CON)); - printk(KERN_DEBUG "SCU_MODE_CON : 0x%08x\n", scu_readl(SCU_MODE_CON)); - printk(KERN_DEBUG "SCU_PMU_CON : 0x%08x\n", scu_readl(SCU_PMU_CON)); - printk(KERN_DEBUG "SCU_CLKSEL_CON : 0x%08x 0x%08x 0x%08x\n", scu_readl(SCU_CLKSEL0_CON), scu_readl(SCU_CLKSEL1_CON), scu_readl(SCU_CLKSEL2_CON)); - printk(KERN_DEBUG "SCU_CLKGATE_CON : 0x%08x 0x%08x 0x%08x\n", scu_readl(SCU_CLKGATE0_CON), scu_readl(SCU_CLKGATE1_CON), scu_readl(SCU_CLKGATE2_CON)); - printk(KERN_DEBUG "IRQ_INTEN : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_INTEN_L), irq_readl(IRQ_REG_INTEN_H)); - printk(KERN_DEBUG "IRQ_INTMASK : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_INTMASK_L), irq_readl(IRQ_REG_INTMASK_H)); - printk(KERN_DEBUG "IRQ_INTFORCE : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_INTFORCE_L), irq_readl(IRQ_REG_INTFORCE_H)); - printk(KERN_DEBUG "IRQ_RAWSTATUS : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_RAWSTATUS_L), irq_readl(IRQ_REG_RAWSTATUS_H)); - printk(KERN_DEBUG "IRQ_STATUS : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_STATUS_L), irq_readl(IRQ_REG_STATUS_H)); - printk(KERN_DEBUG "IRQ_MASKSTATUS : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_MASKSTATUS_L), irq_readl(IRQ_REG_MASKSTATUS_H)); - printk(KERN_DEBUG "IRQ_FINALSTATUS : 0x%08x 0x%02x\n", irq_readl(IRQ_REG_FINALSTATUS_L), irq_readl(IRQ_REG_FINALSTATUS_H)); - printk(KERN_DEBUG "GPIO_INTEN : 0x%08x 0x%08x\n", gpio0_readl(GPIO_INTEN), gpio1_readl(GPIO_INTEN)); - printk(KERN_DEBUG "GPIO_INTMASK : 0x%08x 0x%08x\n", gpio0_readl(GPIO_INTMASK), gpio1_readl(GPIO_INTMASK)); - printk(KERN_DEBUG "GPIO_INTTYPE_LEVEL : 0x%08x 0x%08x\n", gpio0_readl(GPIO_INTTYPE_LEVEL), gpio1_readl(GPIO_INTTYPE_LEVEL)); - printk(KERN_DEBUG "GPIO_INT_POLARITY : 0x%08x 0x%08x\n", gpio0_readl(GPIO_INT_POLARITY), gpio1_readl(GPIO_INT_POLARITY)); - printk(KERN_DEBUG "GPIO_INT_STATUS : 0x%08x 0x%08x\n", gpio0_readl(GPIO_INT_STATUS), gpio1_readl(GPIO_INT_STATUS)); - printk(KERN_DEBUG "GPIO_INT_RAWSTATUS : 0x%08x 0x%08x\n", gpio0_readl(GPIO_INT_RAWSTATUS), gpio1_readl(GPIO_INT_RAWSTATUS)); -#endif -} - static int rk2818_pm_enter(suspend_state_t state) { int irq_val = 0; - struct clk *arm_clk = clk_get(NULL, "arm"); - unsigned long arm_rate = clk_get_rate(arm_clk); + struct regulator *buck1; + u32 scu_mode = scu_readl(SCU_MODE_CON); + u32 scu_apll = scu_readl(SCU_APLL_CON); + u32 scu_clksel0 = scu_readl(SCU_CLKSEL0_CON); printk(KERN_DEBUG "before core halt\n"); - clk_set_rate(arm_clk, 24000000); - dump_register(); + + #ifdef CONFIG_RK28_USB_WAKE rockchip_timer_clocksource_suspend_resume(1); - while (!irq_val) { rk28_usb_suspend(0); #endif @@ -226,7 +607,7 @@ static int rk2818_pm_enter(suspend_state_t state) #ifdef CONFIG_RK28_USB_WAKE rk28_usb_suspend(1); - udelay(400); + __udelay(400); irq_val = rockchip_timer_clocksource_irq_checkandclear(); irq_val |= rk28_usb_check_vbus_change(); @@ -236,9 +617,6 @@ static int rk2818_pm_enter(suspend_state_t state) rockchip_timer_clocksource_suspend_resume(0); #endif - dump_register(); - clk_set_rate(arm_clk, arm_rate); - printk(KERN_DEBUG "quit arm halt,irq_val=0x%x\n", irq_val); return 0; } diff --git a/drivers/video/rk2818_fb.c b/drivers/video/rk2818_fb.c index 9c2f008bbba6..614c5a346255 100755 --- a/drivers/video/rk2818_fb.c +++ b/drivers/video/rk2818_fb.c @@ -2070,7 +2070,6 @@ void resume(struct early_suspend *h) struct rk2818fb_inf *inf = info->inf; fbprintk(">>>>>> %s : %s\n", __FILE__, __FUNCTION__); - if(!inf) { printk("inf==0, rk2818fb_resume fail! \n"); return ; @@ -2088,7 +2087,6 @@ void resume(struct early_suspend *h) } msleep(100); } - LcdMskReg(inf, DSP_CTRL1, m_BLANK_MODE , v_BLANK_MODE(0)); LcdMskReg(inf, SYS_CONFIG, m_STANDBY, v_STANDBY(0)); LcdWrReg(inf, REG_CFG_DONE, 0x01); @@ -2100,6 +2098,7 @@ void resume(struct early_suspend *h) } msleep(100); set_lcd_pin(g_pdev, 1); + memcpy(inf->preg, &inf->regbak, 47*4); //resume reg } struct suspend_info suspend_info = { -- 2.34.1