From 8db81b142f60f518c2d2548600e9b753317bd033 Mon Sep 17 00:00:00 2001 From: xxx Date: Fri, 28 Mar 2014 15:58:51 +0800 Subject: [PATCH] rk3288 sleep support --- arch/arm/boot/dts/rk3188.dtsi | 1 - arch/arm/boot/dts/rk3288-clocks.dtsi | 6 +- arch/arm/boot/dts/rk3288.dtsi | 20 +- arch/arm/boot/dts/rk808.dtsi | 2 +- arch/arm/mach-rockchip/pm-rk3188.c | 6 +- arch/arm/mach-rockchip/pm-rk3288.c | 845 ++++++++++++++++++++------- arch/arm/mach-rockchip/rk3288.c | 88 +-- 7 files changed, 691 insertions(+), 277 deletions(-) mode change 100644 => 100755 arch/arm/boot/dts/rk808.dtsi mode change 100644 => 100755 arch/arm/mach-rockchip/pm-rk3188.c mode change 100644 => 100755 arch/arm/mach-rockchip/pm-rk3288.c diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index 5191fadbebae..3a04341acee7 100755 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -510,7 +510,6 @@ |RKPM_CTR_GTCLKS |RKPM_CTR_PLLS |RKPM_CTR_SYSCLK_DIV - |RKPM_CTR_NORIDLE_MD ) >; rockchip,pmic-gpios=< diff --git a/arch/arm/boot/dts/rk3288-clocks.dtsi b/arch/arm/boot/dts/rk3288-clocks.dtsi index 3750fabd1381..76c8214d52f9 100755 --- a/arch/arm/boot/dts/rk3288-clocks.dtsi +++ b/arch/arm/boot/dts/rk3288-clocks.dtsi @@ -2158,7 +2158,7 @@ "reserved", "reserved", /*"g_clk_ddrphy0", "g_clk_ddrphy1",*/ "clk_jtag", "reserved"; /*"testclk_gate_en";*/ - rockchip,suspend-clkgating-setting=<0x7000 0xf000>; + rockchip,suspend-clkgating-setting=<0xf000 0xf000>; #clock-cells = <1>; }; @@ -2190,7 +2190,7 @@ "g_hdmi_hdcp_clk", "g_ps2c_clk", "usbphy_480m", "g_mipidsi_24m"; - rockchip,suspend-clkgating-setting=<0x0000 0x0000>; + rockchip,suspend-clkgating-setting=<0x0100 0x0100>; #clock-cells = <1>; }; @@ -2355,7 +2355,7 @@ "g_aclk_dmac1", "g_aclk_strc_sys", "g_p_ddrupctl0", "g_pclk_publ0"; - rockchip,suspend-clkgating-setting=<0xe0f0 0xe0f0>; + rockchip,suspend-clkgating-setting=<0xe2f0 0xe2f0>; #clock-cells = <1>; }; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index efb1df6f3292..91eaa01ee753 100755 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -1050,15 +1050,17 @@ }; rockchip_suspend { - rockchip,ctrbits = < - (0 - //|RKPM_CTR_PWR_DMNS - //|RKPM_CTR_GTCLKS - //|RKPM_CTR_PLLS - //|RKPM_CTR_SYSCLK_DIV - //|RKPM_CTR_NORIDLE_MD - ) - >; + rockchip,ctrbits = < + (0 + |RKPM_CTR_PWR_DMNS + |RKPM_CTR_GTCLKS + |RKPM_CTR_PLLS + //|RKPM_CTR_SYSCLK_DIV + //|RKPM_CTR_IDLEAUTO_MD + //|RKPM_CTR_ARMDP_LPMD + |RKPM_CTR_ARMOFF_LPMD + ) + >; rockchip,pmic-gpios=< RKPM_PINGPIO_BITS_OUTPUT(GPIO0_A0,RKPM_GPIO_OUT_L) RKPM_PINGPIO_BITS_INTPUT(GPIO0_A1,RKPM_GPIO_PULL_UP) diff --git a/arch/arm/boot/dts/rk808.dtsi b/arch/arm/boot/dts/rk808.dtsi old mode 100644 new mode 100755 index 10829ad669c3..2983ac7001ab --- a/arch/arm/boot/dts/rk808.dtsi +++ b/arch/arm/boot/dts/rk808.dtsi @@ -15,7 +15,7 @@ regulator-initial-state = <3>; regulator-state-mem { regulator-state-mode = <0x2>; - regulator-state-enabled; + regulator-state-disabled;//disabled regulator-state-uv = <900000>; }; }; diff --git a/arch/arm/mach-rockchip/pm-rk3188.c b/arch/arm/mach-rockchip/pm-rk3188.c old mode 100644 new mode 100755 index e35f296f5726..e65a6c6ce857 --- a/arch/arm/mach-rockchip/pm-rk3188.c +++ b/arch/arm/mach-rockchip/pm-rk3188.c @@ -315,7 +315,7 @@ static u32 clk_sel0, clk_sel1, clk_sel10; static u32 cpll_con3; static u32 cru_mode_con; -void plls_suspend(void) +static void plls_suspend(void) { cru_mode_con = cru_readl(RK3188_CRU_MODE_CON); cru_writel(RK3188_PLL_MODE_SLOW(RK3188_CPLL_ID), RK3188_CRU_MODE_CON); @@ -357,7 +357,7 @@ void plls_suspend(void) } -void plls_resume(void) +static void plls_resume(void) { //gpll @@ -451,7 +451,7 @@ void PIE_FUNC(sysclk_resume)(u32 sel_clk) } -void clks_gating_suspend_init(void) +static void clks_gating_suspend_init(void) { // get clk gating info p_rkpm_clkgt_last_set= kern_to_pie(rockchip_pie_chunk, &DATA(rkpm_clkgt_last_set[0])); diff --git a/arch/arm/mach-rockchip/pm-rk3288.c b/arch/arm/mach-rockchip/pm-rk3288.c old mode 100644 new mode 100755 index 6ff9839d8f3f..3d911f022ca2 --- a/arch/arm/mach-rockchip/pm-rk3288.c +++ b/arch/arm/mach-rockchip/pm-rk3288.c @@ -19,19 +19,16 @@ #include #include #include "pm.h" +#include #define CPU 3288 //#include "sram.h" #include "pm-pie.c" - /*************************cru define********************************************/ #define RK3288_CRU_UNGATING_OPS(id) cru_writel(CRU_W_MSK_SETBITS(0,id%16,0x1),RK3288_CRU_GATEID_CONS(id)) #define RK3288_CRU_GATING_OPS(id) cru_writel(CRU_W_MSK_SETBITS(1,id%16,0x1),RK3288_CRU_GATEID_CONS(id)) - - - /*******************************gpio define **********************************************/ /* GPIO control registers */ @@ -49,23 +46,7 @@ #define GPIO_LS_SYNC 0x60 /***********************************sleep func*********************************************/ -#define SEELP_SRAM_SAVE_SIZE (0x100) - -static char slp_sram_code_save[SEELP_SRAM_SAVE_SIZE]; -#define RK_SLEEP_DDR_CODE_OFF (512) - -#define RK_SLEEP_DDR_DATA_OFF (512+2048) - -// index data off in SLP_DATA_SAVE_BASE -// it may be include in *.s ,so con't use enum type define -#define SLP_DDR_NEED_RES (0) //ddr ctrl is need to resume -#define SLP_DPLL_NEED_RES (1) //ddr pll is need to resume -#define SLP_DDR_CODE_PHY (2) //ddr resume code phy -#define SLP_DDR_DATA_PHY (3) //ddr resume data phy -#define SLP_SLEEP_RES_CON_CNT (PM_BOOT_DATA_SIZE/4) // all index - -#if 1 // sys resume data in boot ram #define SLP_DATA_SAVE_PHY (RK3288_BOOTRAM_PHYS+PM_BOOT_CODE_OFFSET+PM_BOOT_CODE_SIZE) #define SLP_DATA_SAVE_BASE (RK_BOOTRAM_VIRT+PM_BOOT_CODE_OFFSET+PM_BOOT_CODE_SIZE) @@ -73,24 +54,20 @@ static char slp_sram_code_save[SEELP_SRAM_SAVE_SIZE]; // ddr resume data in boot ram #define SLP_DDR_DATA_SAVE_PHY (RK3288_BOOTRAM_PHYS + PM_BOOT_DDR_CODE_OFFSET) #define SLP_DDR_DATA_SAVE_BASE (RK_BOOTRAM_VIRT+PM_BOOT_DDR_CODE_OFFSET) -#endif -#define PM_BOOT_CODE_OFFSET (0x0) -#define PM_BOOT_CODE_SIZE (64*4) -#define PM_BOOT_DATA_SIZE (10*4) #define PM_BOOT_DDR_CODE_OFFSET (((PM_BOOT_CODE_OFFSET+PM_BOOT_CODE_SIZE+PM_BOOT_DATA_SIZE)/4+2)*4) -#define PM_BOOT_CODE_SP (RK3288_BOOTRAM_PHYS+(RK3288_BOOTRAM_SIZE-1)&~0x7) +#define PM_BOOT_CODE_SP (RK3288_BOOTRAM_PHYS+((RK3288_BOOTRAM_SIZE-1)&~0x7)) #define BOOT_RAM_SIZE (4*1024) #define INT_RAM_SIZE (64*1024) -static char boot_ram_data[BOOT_RAM_SIZE]; +static char boot_ram_data[BOOT_RAM_SIZE+4*10]; static char int_ram_data[INT_RAM_SIZE]; // the value is used to control cpu resume flow -static u32 sleep_resume_data[SLP_SLEEP_RES_CON_CNT]; +static u32 sleep_resume_data[SLPDATA_SLEEP_RES_CON_CNT]; static char *resume_data_base=(char *)(SLP_DATA_SAVE_BASE); static char *resume_data_phy= (char *)(SLP_DATA_SAVE_PHY); @@ -105,10 +82,6 @@ static void sram_code_reset(char *data, char *save, char* sram_base,char* sram_p flush_icache_range((unsigned long)addr_d, (unsigned long)addr_d + _size); outer_clean_range((phys_addr_t) sram_phy, _size); } -void rk_slp_cpu_resume(void) -{ - -} /** ddr code and data @@ -118,8 +91,8 @@ ddr code and data ---code---- ---data---- */ - static void sram_data_for_sleep(char *boot_save, char *int_save) - { +static void sram_data_for_sleep(char *boot_save, char *int_save) +{ char *addr_base,*addr_phy,*data_src,*data_dst; u32 sr_size,data_size; @@ -135,7 +108,7 @@ ddr code and data // move resume code and date to boot sram // move sys code data_dst=(char *)RK_BOOTRAM_VIRT+PM_BOOT_CODE_OFFSET; - data_src=(char *)rk_slp_cpu_resume; + data_src=(char *)rkpm_slp_cpu_resume; data_size=PM_BOOT_CODE_SIZE; memcpy((char *)data_dst,(char *)data_src, data_size); @@ -164,7 +137,7 @@ ddr code and data /*************************ddr code cpy end*************************************/ #endif flush_icache_range((unsigned long)addr_base, (unsigned long)addr_base + sr_size); - outer_clean_range((phys_addr_t) addr_phy, sr_size); + outer_clean_range((phys_addr_t) addr_phy, (phys_addr_t)(addr_phy)+sr_size); #if 0 /*************************int mem bak*************************************/ // int mem @@ -180,61 +153,319 @@ ddr code and data #endif } - static void sram_data_resume(char *boot_save, char *int_save) - { - - char *addr_base,*addr_phy; - u32 sr_size; +static void sram_data_resume(char *boot_save, char *int_save) +{ - addr_base=(char *)RK_BOOTRAM_VIRT; - addr_phy=(char *)RK3288_BOOTRAM_PHYS; - sr_size=RK3288_BOOTRAM_SIZE; - - // save boot sram - if(boot_save) - memcpy(addr_base,boot_save, sr_size); - - flush_icache_range((unsigned long)addr_base, (unsigned long)addr_base + sr_size); - outer_clean_range((phys_addr_t) addr_phy, sr_size); + char *addr_base,*addr_phy; + u32 sr_size; + + addr_base=(char *)RK_BOOTRAM_VIRT; + addr_phy=(char *)RK3288_BOOTRAM_PHYS; + sr_size=RK3288_BOOTRAM_SIZE; + // save boot sram + if(boot_save) + memcpy(addr_base,boot_save, sr_size); + + flush_icache_range((unsigned long)addr_base, (unsigned long)addr_base + sr_size); + outer_clean_range((phys_addr_t) addr_phy, (phys_addr_t)addr_phy+sr_size); + + #if 0 + // int mem + addr_base=(char *)RK319X_IMEM_BASE; + addr_phy=(char *)RK319X_IMEM_PHYS; + sr_size=RK319X_IMEM_SIZE; + + if(int_save) + memcpy(addr_base, int_save,sr_size); + + flush_icache_range((unsigned long)addr_base, (unsigned long)addr_base + sr_size); + outer_clean_range((phys_addr_t) addr_phy, sr_size); + #endif +} + +/**************************************gic save and resume**************************/ +#define RK_GICD_BASE (RK_GIC_VIRT) +#define RK_GICC_BASE (RK_GIC_VIRT+RK3288_GIC_DIST_SIZE) + +#define PM_IRQN_START 32 +#define PM_IRQN_END 107//107 +static void pm_gic_enable(u32 irqs) +{ + + int irqstart=0; + u32 bit_off; + void __iomem *reg_off; + unsigned int gic_irqs; + gic_irqs = PM_IRQN_END; + irqstart=PM_IRQN_START;//PM_IRQN_START; + + reg_off=(irqs/32)*4+GIC_DIST_ENABLE_SET+RK_GICD_BASE; + bit_off=irqs%32; + writel_relaxed(readl_relaxed(reg_off)|(1< 1020) + gic_irqs = 1020; + //printk("gic_irqs=%d\n",gic_irqs); + //gic_irqs = PM_IRQN_END; + irqstart=PM_IRQN_START;//PM_IRQN_START; + + i = 0; + //level + for (j = irqstart; j < gic_irqs; j += 16) + context[i++]=readl_relaxed(RK_GICD_BASE + GIC_DIST_CONFIG + (j * 4) / 16); + gic_reg_dump("gic level",j,RK_GICD_BASE + GIC_DIST_CONFIG); + + /* + * Set all global interrupts to this CPU only. + */ + for(j = 0; j < gic_irqs; j += 4) + context[i++]=readl_relaxed(RK_GICD_BASE + GIC_DIST_TARGET + (j * 4) / 4); + + gic_reg_dump("gic trig",j,RK_GICD_BASE + GIC_DIST_TARGET); + + //pri + for (j = 0; j < gic_irqs; j += 4) + context[i++]=readl_relaxed(RK_GICD_BASE+ GIC_DIST_PRI + (j * 4) / 4); + gic_reg_dump("gic pri",j,RK_GICD_BASE + GIC_DIST_PRI); + + + + + //secure + for (j = 0; j < gic_irqs; j += 32) + context[i++]=readl_relaxed(RK_GICD_BASE + 0x80 + (j * 4) / 32); + gic_reg_dump("gic secure",j,RK_GICD_BASE + 0x80); + + for (j = irqstart; j < gic_irqs; j += 32) + context[i++]=readl_relaxed(RK_GICD_BASE + GIC_DIST_PENDING_SET + (j * 4) / 32); + + gic_reg_dump("gic PENDING",j,RK_GICD_BASE + GIC_DIST_PENDING_SET); + + + #if 0 - // int mem - addr_base=(char *)RK319X_IMEM_BASE; - addr_phy=(char *)RK319X_IMEM_PHYS; - sr_size=RK319X_IMEM_SIZE; - - if(int_save) - memcpy(addr_base, int_save,sr_size); + //disable + for (j = 0; j < gic_irqs; j += 32) + context[i++]=readl_relaxed(RK_GICD_BASE + GIC_DIST_ENABLE_CLEAR + (j * 4) / 32); + + gic_reg_dump("gic dis",j,RK_GICD_BASE + GIC_DIST_ENABLE_CLEAR); + #endif + //enable + for (j = 0; j < gic_irqs; j += 32) + context[i++]=readl_relaxed(RK_GICD_BASE + GIC_DIST_ENABLE_SET + (j * 4) / 32); + + //sram_printhex(j); + gic_reg_dump("gic en",j,RK_GICD_BASE + GIC_DIST_ENABLE_SET); + + + + gic_reg_dump("gicc",0x1c,RK_GICC_BASE); + gic_reg_dump("giccfc",0,RK_GICC_BASE+0xfc); + + context[i++]=readl_relaxed(RK_GICC_BASE + GIC_CPU_PRIMASK); + context[i++]=readl_relaxed(RK_GICC_BASE + GIC_CPU_CTRL); + context[i++]=readl_relaxed(RK_GICD_BASE + GIC_DIST_CTRL); + + + #if 0 + context[i++]=readl_relaxed(RK_GICC_BASE + GIC_CPU_BINPOINT); + context[i++]=readl_relaxed(RK_GICC_BASE + GIC_CPU_PRIMASK); + context[i++]=readl_relaxed(RK_GICC_BASE + GIC_DIST_SOFTINT); + context[i++]=readl_relaxed(RK_GICC_BASE + GIC_CPU_CTRL); + context[i++]=readl_relaxed(RK_GICD_BASE + GIC_DIST_CTRL); + #endif + #if 0 //rk319x is not need + for (j = irqstart; j < gic_irqs; j += 32) + { + writel_relaxed(0xffffffff, RK_GICD_BASE + GIC_DIST_ENABLE_CLEAR + j * 4 / 32); + dsb(); + + } + #endif + +} + +static void rkpm_gic_dist_resume(u32 *context) +{ + + int i = 0,j,irqstart=0; + unsigned int gic_irqs; + + gic_irqs = readl_relaxed(RK_GICD_BASE + GIC_DIST_CTR) & 0x1f; + gic_irqs = (gic_irqs + 1) * 32; + if (gic_irqs > 1020) + gic_irqs = 1020; + + + //gic_irqs = PM_IRQN_END; + irqstart=PM_IRQN_START;//PM_IRQN_START; + + writel_relaxed(0,RK_GICC_BASE + GIC_CPU_CTRL); + dsb(); + writel_relaxed(0,RK_GICD_BASE + GIC_DIST_CTRL); + dsb(); + for (j = irqstart; j < gic_irqs; j += 32) + { + writel_relaxed(0xffffffff, RK_GICD_BASE + GIC_DIST_ENABLE_CLEAR + j * 4 / 32); + dsb(); + } + + + i = 0; + + //trig + for (j = irqstart; j < gic_irqs; j += 16) + { + writel_relaxed(context[i++],RK_GICD_BASE + GIC_DIST_CONFIG + j * 4 / 16); + dsb(); + } + gic_reg_dump("gic level",j,RK_GICD_BASE + GIC_DIST_CONFIG); + + /* + * Set all global interrupts to this CPU only. + */ + for (j = 0; j < gic_irqs; j += 4) + { + writel_relaxed(context[i++],RK_GICD_BASE + GIC_DIST_TARGET + (j * 4) / 4); + dsb(); + } + gic_reg_dump("gic target",j,RK_GICD_BASE + GIC_DIST_TARGET); + + //pri + for (j = 0; j < gic_irqs; j += 4) + { + writel_relaxed(context[i++],RK_GICD_BASE+ GIC_DIST_PRI + (j * 4) / 4); + + dsb(); + } + gic_reg_dump("gic pri",j,RK_GICD_BASE + GIC_DIST_PRI); + + + //secu + for (j = 0; j < gic_irqs; j += 32) + { + writel_relaxed(context[i++],RK_GICD_BASE + 0x80 + (j * 4 )/ 32); + #if 0 + sram_printhex((j * 4 )/ 32); + + sram_printch('_'); + sram_printhex(temp); + + sram_printch('_'); + sram_printhex(readl_relaxed(RK_GICD_BASE + 0x80 + (j * 4 )/ 32)); + sram_printch('\n'); +#endif + + dsb(); + } + + gic_reg_dump("gic secu",j,RK_GICD_BASE + 0x80); + + + //pending + for (j = irqstart; j < gic_irqs; j += 32) + { + //writel_relaxed(context[i++],RK_GICD_BASE + GIC_DIST_PENDING_SET + j * 4 / 32); + i++; + dsb(); + } + gic_reg_dump("gic pending",j,RK_GICD_BASE + GIC_DIST_PENDING_SET); + + + //disable +#if 0 + for (j = 0; j < gic_irqs; j += 32) + { + writel_relaxed(context[i++],RK_GICD_BASE + GIC_DIST_ENABLE_CLEAR + j * 4 / 32); + + dsb(); + } + gic_reg_dump("gic disable",j,RK_GICD_BASE + GIC_DIST_ENABLE_CLEAR); + +#else + //for (j = 0; j < gic_irqs; j += 32) + // writel_relaxed(0xffffffff,RK_GICD_BASE + GIC_DIST_ENABLE_CLEAR + j * 4 / 32); +#endif + + + //enable + for (j = 0; j < gic_irqs; j += 32) + { + writel_relaxed(context[i++],RK_GICD_BASE + GIC_DIST_ENABLE_SET + (j * 4) / 32); + + dsb(); + } + // sram_printhex(j); + gic_reg_dump("gic enable",j,RK_GICD_BASE + GIC_DIST_ENABLE_SET); + + writel_relaxed(context[i++],RK_GICC_BASE + GIC_CPU_PRIMASK); + + writel_relaxed(context[i++],RK_GICC_BASE + GIC_CPU_CTRL); + + writel_relaxed(context[i++],RK_GICD_BASE + GIC_DIST_CTRL); + + gic_reg_dump("gicc",0x1c,RK_GICC_BASE); + gic_reg_dump("giccfc",0,RK_GICC_BASE+0xfc); + +} + + - flush_icache_range((unsigned long)addr_base, (unsigned long)addr_base + sr_size); - outer_clean_range((phys_addr_t) addr_phy, sr_size); - #endif - } /**************************************regs save and resume**************************/ - void slp_regs_save(u32 *data,void __iomem * base,u32 st_offset,u32 end_offset) - { - u32 i; +void slp_regs_save(u32 *data,void __iomem * base,u32 st_offset,u32 end_offset) +{ + u32 i; u32 cnt=(end_offset-st_offset)/4+1; - for(i=0;iLP_ARM_LOG_NOR) - { - local_flush_tlb_all(); - flush_cache_all(); - outer_flush_all(); - outer_disable(); - cpu_proc_fin(); - //outer_inv_all();// ??? - // l2x0_inv_all_pm(); //rk319x is not need - flush_cache_all(); - } + //rkpm_ddr_printch('g'); + rkpm_gic_dist_resume(&slp_gic_save[0]); + + fiq_glue_resume(); + #if 0 + rkpm_ddr_printascii("l2-"); + rkpm_ddr_printhex(rkpm_l2_config()); + rkpm_ddr_printascii("\n"); + #endif - rkpm_ddr_printch('w'); - dsb(); - wfi(); - dsb(); - - rkpm_ddr_printch('w'); - + } + rkpm_slp_mode_set_resume(); + sram_data_resume(boot_ram_data,int_ram_data); } - /*******************************common code for rkxxx*********************************/ - static void inline uart_printch(char byte) { u32 reg_save[2]; @@ -713,33 +1047,62 @@ void PIE_FUNC(sram_printch)(char byte) uart_printch(byte); } +static void pll_udelay(u32 udelay); + static void ddr_printch(char byte) { uart_printch(byte); + pll_udelay(2); } /*******************************gpio func*******************************************/ +//#define RK3288_PMU_GPIO0_A_IOMUX 0x0084 +//#define RK3288_PMU_GPIO0_B_IOMUX 0x0088 +//#define RK3288_PMU_GPIO0_C_IOMUX 0x008c +//#define RK3288_PMU_GPIO0_D_IOMUX 0x0090 + //pin=0x0a21 gpio0a2,port=0,bank=a,b_gpio=2,fun=1 static inline void pin_set_fun(u8 port,u8 bank,u8 b_gpio,u8 fun) { u8 off_set; bank-=0xa; - off_set=port*(4*4)+bank*4; + + if(port==0) + { + if(bank>2) + return; + + off_set=RK3288_PMU_GPIO0_A_IOMUX+bank*4; + pmu_writel(RKPM_VAL_SETBITS(pmu_readl(off_set),fun,b_gpio*2,0x3),off_set); + } + else + { - if(off_set2) + return 0; + off_set=RK3288_PMU_GPIO0_A_IOMUX+bank*4; + return (pmu_readl(off_set)>>(b_gpio*2))&0x3; + } + else + { - if(off_set>(b_gpio*2))&0x3; + off_set=port*(4*4)+bank*4; + //form RK3288_GRF_GPIO1D_IOMUX + return (reg_readl(RK_GRF_VIRT+0+off_set)>>(b_gpio*2))&0x3; + } } static inline void pin_set_pull(u8 port,u8 bank,u8 b_gpio,u8 pull) @@ -1128,11 +1491,6 @@ static void rkpm_gpio_resume(void) } } - - - - - static void gpio_get_dts_info(struct device_node *parent) { int i; @@ -1286,8 +1644,8 @@ enum rk_plls_id { static void pm_pll_wait_lock(u32 pll_idx) { u32 delay = 600000U; - u32 mode; - mode=cru_readl(RK3288_CRU_MODE_CON); + // u32 mode; + // mode=cru_readl(RK3288_CRU_MODE_CON); dsb(); dsb(); dsb(); @@ -1295,7 +1653,7 @@ static void pm_pll_wait_lock(u32 pll_idx) dsb(); dsb(); while (delay > 0) { - if (cru_readl(RK3288_PLL_CONS(pll_idx,1))&(0x1<<31)) + if ((cru_readl(RK3288_PLL_CONS(pll_idx,1))&(0x1<<31))) break; delay--; } @@ -1304,10 +1662,10 @@ static void pm_pll_wait_lock(u32 pll_idx) rkpm_ddr_printhex(pll_idx); rkpm_ddr_printch('\n'); } - cru_writel(mode|(RK3288_PLL_MODE_MSK(pll_idx)<<16), RK3288_CRU_MODE_CON); + //cru_writel(mode|(RK3288_PLL_MODE_MSK(pll_idx)<<16), RK3288_CRU_MODE_CON); } -void pll_udelay(u32 udelay) +static void pll_udelay(u32 udelay) { u32 mode; mode=cru_readl(RK3288_CRU_MODE_CON); @@ -1319,12 +1677,20 @@ void pll_udelay(u32 udelay) cru_writel(mode|(RK3288_PLL_MODE_MSK(APLL_ID)<<16), RK3288_CRU_MODE_CON); } +static u32 plls_con0_save[END_PLL_ID]; +static u32 plls_con1_save[END_PLL_ID]; +static u32 plls_con2_save[END_PLL_ID]; static u32 plls_con3_save[END_PLL_ID]; + static u32 cru_mode_con; static inline void plls_suspend(u32 pll_id) { + plls_con0_save[pll_id]=cru_readl(RK3288_PLL_CONS((pll_id), 0)); + plls_con1_save[pll_id]=cru_readl(RK3288_PLL_CONS((pll_id), 1)); + plls_con2_save[pll_id]=cru_readl(RK3288_PLL_CONS((pll_id), 2)); plls_con3_save[pll_id]=cru_readl(RK3288_PLL_CONS((pll_id), 3)); + cru_writel(RK3288_PLL_PWR_DN, RK3288_PLL_CONS((pll_id), 3)); } @@ -1332,25 +1698,22 @@ static inline void plls_resume(u32 pll_id) { u32 pllcon0, pllcon1, pllcon2; - // rkpm_ddr_printascii("ddr"); - // rkpm_ddr_printhex(pll_id); - - if(!(plls_con3_save[pll_id]&&RK3288_PLL_PWR_DN_MSK)) - return ; - //rkpm_ddr_printascii("res\n"); + if((plls_con3_save[pll_id]&RK3288_PLL_PWR_DN_MSK)) + return ; + //enter slowmode cru_writel(RK3288_PLL_MODE_SLOW(pll_id), RK3288_CRU_MODE_CON); cru_writel(RK3288_PLL_PWR_ON, RK3288_PLL_CONS((pll_id),3)); cru_writel(RK3288_PLL_NO_BYPASS, RK3288_PLL_CONS((pll_id),3)); - pllcon0 = cru_readl(RK3288_PLL_CONS((pll_id),0)); - pllcon1 = cru_readl(RK3288_PLL_CONS((pll_id),1)); - pllcon2 = cru_readl(RK3288_PLL_CONS((pll_id),2)); + pllcon0 =plls_con0_save[pll_id];// cru_readl(RK3288_PLL_CONS((pll_id),0)); + pllcon1 = plls_con1_save[pll_id];//cru_readl(RK3288_PLL_CONS((pll_id),1)); + pllcon2 = plls_con2_save[pll_id];//cru_readl(RK3288_PLL_CONS((pll_id),2)); //enter rest cru_writel(RK3288_PLL_RESET, RK3288_PLL_CONS(pll_id,3)); - cru_writel(pllcon0, RK3288_PLL_CONS(pll_id,0)); + cru_writel(pllcon0|CRU_W_MSK(0,0xf)|CRU_W_MSK(8,0x3f), RK3288_PLL_CONS(pll_id,0)); cru_writel(pllcon1, RK3288_PLL_CONS(pll_id,1)); cru_writel(pllcon2, RK3288_PLL_CONS(pll_id,2)); @@ -1365,21 +1728,23 @@ static inline void plls_resume(u32 pll_id) pm_pll_wait_lock(pll_id); cru_writel(plls_con3_save[pll_id]|(RK3288_PLL_BYPASS_MSK<<16),RK3288_PLL_CONS(pll_id,3)); + } -static u32 clk_sel0,clk_sel1, clk_sel10,clk_sel26,clk_sel36, clk_sel37; +static u32 clk_sel0,clk_sel1, clk_sel10,clk_sel26,clk_sel33,clk_sel36, clk_sel37; static void pm_plls_suspend(void) { - //rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_PLL_CONS((0), 0),RK3288_PLL_CONS((4), 3)); - //rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_CRU_MODE_CON,RK3288_CRU_MODE_CON); - //rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_CRU_CLKSELS_CON(0),RK3288_CRU_CLKSELS_CON(42)); + // rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_PLL_CONS((0), 0),RK3288_PLL_CONS((4), 3)); + // rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_CRU_MODE_CON,RK3288_CRU_MODE_CON); + // rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_CRU_CLKSELS_CON(0),RK3288_CRU_CLKSELS_CON(42)); clk_sel0=cru_readl(RK3288_CRU_CLKSELS_CON(0)); - clk_sel1=cru_readl(RK3288_CRU_CLKSELS_CON(1)); + clk_sel1=cru_readl(RK3288_CRU_CLKSELS_CON(1)); clk_sel10=cru_readl(RK3288_CRU_CLKSELS_CON(10)); - clk_sel26=cru_readl(RK3288_CRU_CLKSELS_CON(26)); + clk_sel26=cru_readl(RK3288_CRU_CLKSELS_CON(26)); + clk_sel33=cru_readl(RK3288_CRU_CLKSELS_CON(33)); clk_sel36=cru_readl(RK3288_CRU_CLKSELS_CON(36)); clk_sel37=cru_readl(RK3288_CRU_CLKSELS_CON(37)); @@ -1388,49 +1753,67 @@ static void pm_plls_suspend(void) cru_writel(RK3288_PLL_MODE_SLOW(NPLL_ID), RK3288_CRU_MODE_CON); plls_suspend(NPLL_ID); - - + // cpll cru_writel(RK3288_PLL_MODE_SLOW(CPLL_ID), RK3288_CRU_MODE_CON); + // gpll cru_writel(RK3288_PLL_MODE_SLOW(GPLL_ID), RK3288_CRU_MODE_CON); // set 1,pdbus pll is gpll - cru_writel(CRU_W_MSK_SETBITS(1,15,0x1), RK3288_CRU_CLKSELS_CON(1)); - - // pd_bus clk ,aclk ,hclk ,pclk, pd bus pll sel - cru_writel(CRU_W_MSK_SETBITS(1,0,0x7)|CRU_W_MSK_SETBITS(1,3,0x1f)|CRU_W_MSK_SETBITS(1,8,0x3)|CRU_W_MSK_SETBITS(1,12,0x3) + cru_writel(CRU_W_MSK_SETBITS(1,15,0x1), RK3288_CRU_CLKSELS_CON(1)); // 0 cpll 1gpll + + // pd_bus clk + cru_writel(0 + |CRU_W_MSK_SETBITS(0,0,0x7) // 1 aclk + |CRU_W_MSK_SETBITS(0,3,0x1f) // 1 aclk src + |CRU_W_MSK_SETBITS(0,8,0x3) // 1 hclk 0~1 1 2 4 + |CRU_W_MSK_SETBITS(0,12,0x7) // 3 pclk , RK3288_CRU_CLKSELS_CON(1)); + //crypto for pd_bus cru_writel(CRU_W_MSK_SETBITS(3,6,0x3), RK3288_CRU_CLKSELS_CON(26)); // peri aclk hclk pclk - cru_writel(CRU_W_MSK_SETBITS(1,0,0x1f)|CRU_W_MSK_SETBITS(1,8,0x3) - |CRU_W_MSK_SETBITS(2,12,0x7), RK3288_CRU_CLKSELS_CON(10)); + cru_writel(0 + |CRU_W_MSK_SETBITS(0,0,0x1f) // 1 aclk + |CRU_W_MSK_SETBITS(0,8,0x3) // 2 hclk 0 1:1,1 2:1 ,2 4:1 + |CRU_W_MSK_SETBITS(0,12,0x3)// 2 0~3 1 2 4 8 div + , RK3288_CRU_CLKSELS_CON(10)); - plls_suspend(CPLL_ID); plls_suspend(GPLL_ID); //apll cru_writel(RK3288_PLL_MODE_SLOW(APLL_ID), RK3288_CRU_MODE_CON); // core_m0 core_mp a12_core - cru_writel(CRU_W_MSK_SETBITS(1,0,0xf)|CRU_W_MSK_SETBITS(3,4,0xf) - |CRU_W_MSK_SETBITS(0,8,0x1f), RK3288_CRU_CLKSELS_CON(0)); + cru_writel(0 + |CRU_W_MSK_SETBITS(0,0,0xf) // 1 axi_mo + |CRU_W_MSK_SETBITS(0,4,0xf) // 3 axi mp + |CRU_W_MSK_SETBITS(0,8,0x1f) // 0 a12 core div + , RK3288_CRU_CLKSELS_CON(0)); // core0 core1 core2 core3 - cru_writel(CRU_W_MSK_SETBITS(0,0,0x7)|CRU_W_MSK_SETBITS(0,4,0x7) - |CRU_W_MSK_SETBITS(0,8,0x7)|CRU_W_MSK_SETBITS(0,12,0x7) + cru_writel(0 + |CRU_W_MSK_SETBITS(0,0,0x7) //core 0 div + |CRU_W_MSK_SETBITS(0,4,0x7) // core 1 + |CRU_W_MSK_SETBITS(0,8,0x7) // core2 + |CRU_W_MSK_SETBITS(0,12,0x7)//core3 , RK3288_CRU_CLKSELS_CON(36)); // l2ram atclk pclk - cru_writel((CRU_W_MSK_SETBITS(3,0,0x7)|CRU_W_MSK_SETBITS(0xf,4,0x1f) - |CRU_W_MSK_SETBITS(0xf,9,0x1f)), RK3288_CRU_CLKSELS_CON(37)); + cru_writel(0 + |CRU_W_MSK_SETBITS(3,0,0x7) // l2ram + |CRU_W_MSK_SETBITS(0xf,4,0x1f) // atclk + |CRU_W_MSK_SETBITS(0xf,9,0x1f) // pclk dbg + , RK3288_CRU_CLKSELS_CON(37)); plls_suspend(APLL_ID); } static void pm_plls_resume(void) { - plls_resume(APLL_ID); + + plls_resume(APLL_ID); + // core_m0 core_mp a12_core cru_writel(clk_sel0|(CRU_W_MSK(0,0xf)|CRU_W_MSK(4,0xf)|CRU_W_MSK(8,0xf)),RK3288_CRU_CLKSELS_CON(0)); // core0 core1 core2 core3 @@ -1438,31 +1821,39 @@ static void pm_plls_resume(void) , RK3288_CRU_CLKSELS_CON(36)); // l2ram atclk pclk cru_writel(clk_sel37|(CRU_W_MSK(0,0x7)|CRU_W_MSK(4,0x1f)|CRU_W_MSK(9,0x1f)) , RK3288_CRU_CLKSELS_CON(37)); + cru_writel(cru_mode_con|(RK3288_PLL_MODE_MSK(APLL_ID)<<16), RK3288_CRU_MODE_CON); + plls_resume(GPLL_ID); - plls_resume(CPLL_ID); + plls_resume(CPLL_ID); + // peri aclk hclk pclk - cru_writel(clk_sel10|(CRU_W_MSK(0,0x1f)|CRU_W_MSK(8,0x3)|CRU_W_MSK(12,0x7)) + cru_writel(clk_sel10|(CRU_W_MSK(0,0x1f)|CRU_W_MSK(8,0x3)|CRU_W_MSK(12,0x3)) , RK3288_CRU_CLKSELS_CON(10)); - // pd_bus aclk hclk pclk - cru_writel(clk_sel1|(CRU_W_MSK(0,0x7)|CRU_W_MSK(3,0x1f)|CRU_W_MSK(8,0x3)|CRU_W_MSK(12,0x3)) + //pd bus gpll sel + cru_writel(clk_sel1|CRU_W_MSK(15,0x1), RK3288_CRU_CLKSELS_CON(1)); + // pd_bus clk + cru_writel(clk_sel1|(CRU_W_MSK(0,0x7)|CRU_W_MSK(3,0x1f)|CRU_W_MSK(8,0x3)|CRU_W_MSK(12,0x7)) , RK3288_CRU_CLKSELS_CON(1)); + // crypto cru_writel(clk_sel26|CRU_W_MSK(6,0x3), RK3288_CRU_CLKSELS_CON(26)); - - cru_writel(clk_sel1|CRU_W_MSK(15,0x1), RK3288_CRU_CLKSELS_CON(1)); - - cru_writel(cru_mode_con|(RK3288_PLL_MODE_MSK(GPLL_ID)<<16), RK3288_CRU_MODE_CON); + + + // pmu alive + cru_writel(clk_sel33|CRU_W_MSK(0,0x1f)|CRU_W_MSK(8,0x1f), RK3288_CRU_CLKSELS_CON(33)); + + cru_writel(cru_mode_con|(RK3288_PLL_MODE_MSK(GPLL_ID)<<16), RK3288_CRU_MODE_CON); cru_writel(cru_mode_con|(RK3288_PLL_MODE_MSK(CPLL_ID)<<16), RK3288_CRU_MODE_CON); - + plls_resume(NPLL_ID); cru_writel(cru_mode_con|(RK3288_PLL_MODE_MSK(NPLL_ID)<<16), RK3288_CRU_MODE_CON); - //rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_PLL_CONS((0), 0),RK3288_PLL_CONS((4), 3)); - // rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_CRU_MODE_CON,RK3288_CRU_MODE_CON); - //rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_CRU_CLKSELS_CON(0),RK3288_CRU_CLKSELS_CON(42)); - + // rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_PLL_CONS((0), 0),RK3288_PLL_CONS((4), 3)); + // rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_CRU_MODE_CON,RK3288_CRU_MODE_CON); + // rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_CRU_CLKSELS_CON(0),RK3288_CRU_CLKSELS_CON(42)); + } static __sramdata u32 sysclk_clksel0_con,sysclk_clksel1_con,sysclk_clksel10_con,sysclk_mode_con; @@ -1625,6 +2016,16 @@ static void interface_ctr_reg_pread(void) //readl_relaxed(RK30_I2C1_BASE+SZ_4K); //readl_relaxed(RK_GPIO_VIRT(3)); } +void PIE_FUNC(ddr_leakage_tst)(void) +{ + cru_writel(RK3288_PLL_MODE_SLOW(DPLL_ID), RK3288_CRU_MODE_CON); + rkpm_sram_printch('\n'); + rkpm_sram_printch('t'); + rkpm_sram_printch('e'); + rkpm_sram_printch('s'); + rkpm_sram_printch('t'); + while(1); +} static void __init rk3288_suspend_init(void) { @@ -1653,10 +2054,12 @@ static void __init rk3288_suspend_init(void) clks_gating_suspend_init(); rkpm_set_ops_plls(pm_plls_suspend,pm_plls_resume); - + + //rkpm_set_sram_ops_ddr(fn_to_pie(rockchip_pie_chunk, &FUNC(ddr_leakage_tst)),NULL); rkpm_set_ops_prepare_finish(rkpm_prepare,rkpm_finish); //rkpm_set_ops_regs_pread(interface_ctr_reg_pread); + rkpm_set_ops_regs_sleep(pm_sleep_func_save,rkpm_slp_mode_set,pm_sleep_func_rusume_first,pm_sleep_func_rusume_last); if(rockchip_pie_chunk) rkpm_set_sram_ops_printch(fn_to_pie(rockchip_pie_chunk, &FUNC(sram_printch))); diff --git a/arch/arm/mach-rockchip/rk3288.c b/arch/arm/mach-rockchip/rk3288.c index 8f8b8f764f0c..9e0bec94191f 100755 --- a/arch/arm/mach-rockchip/rk3288.c +++ b/arch/arm/mach-rockchip/rk3288.c @@ -80,7 +80,7 @@ static struct map_desc rk3288_io_desc[] __initdata = { RK_DEVICE(RK_GPIO_VIRT(8), RK3288_GPIO8_PHYS, RK3288_GPIO_SIZE), RK_DEVICE(RK_DEBUG_UART_VIRT, RK3288_UART_DBG_PHYS, RK3288_UART_SIZE), RK_DEVICE(RK_GIC_VIRT, RK3288_GIC_DIST_PHYS, RK3288_GIC_DIST_SIZE), - RK_DEVICE(RK_GIC_VIRT + RK3288_GIC_DIST_SIZE, RK3288_GIC_DIST_PHYS + RK3288_GIC_DIST_SIZE, RK3288_GIC_CPU_SIZE), + RK_DEVICE(RK_GIC_VIRT + RK3288_GIC_DIST_SIZE, RK3288_GIC_CPU_PHYS, RK3288_GIC_CPU_SIZE), RK_DEVICE(RK_BOOTRAM_VIRT, RK3288_BOOTRAM_PHYS, RK3288_BOOTRAM_SIZE), RK_DEVICE(RK3288_IMEM_VIRT, RK3288_IMEM_PHYS, SZ_4K), }; @@ -416,7 +416,6 @@ EXPORT_PIE_SYMBOL(DATA(sram_stack)); static int __init rk3288_pie_init(void) { int err; - if (!cpu_is_rk3288()) return 0; @@ -434,7 +433,8 @@ static int __init rk3288_pie_init(void) rockchip_sram_virt = kern_to_pie(rockchip_pie_chunk, &__pie_common_start[0]); rockchip_sram_stack = kern_to_pie(rockchip_pie_chunk, (char *) DATA(sram_stack) + sizeof(DATA(sram_stack))); - return 0; + + return 0; } arch_initcall(rk3288_pie_init); #ifdef CONFIG_PM @@ -493,53 +493,63 @@ int rk3288_sys_set_power_domain(enum pmu_power_domain pd, bool on) static u32 rk_pmu_pwrdn_st; static inline void rk_pm_soc_pd_suspend(void) { - rk_pmu_pwrdn_st = pmu_readl(RK3288_PMU_PWR_STATE); - - if(!(rk_pmu_pwrdn_st&BIT(pmu_pd_map[IDLE_REQ_GPU]))) - rk3288_sys_set_power_domain(IDLE_REQ_GPU, false); - - if(!(rk_pmu_pwrdn_st&BIT(pmu_pd_map[IDLE_REQ_HEVC]))) - rk3288_sys_set_power_domain(IDLE_REQ_HEVC, false); - - if(!(rk_pmu_pwrdn_st&BIT(pmu_pd_map[IDLE_REQ_VIO]))) - rk3288_sys_set_power_domain(IDLE_REQ_VIO, false); - - if(!(rk_pmu_pwrdn_st&BIT(pmu_pd_map[IDLE_REQ_VIDEO]))) - rk3288_sys_set_power_domain(IDLE_REQ_VIDEO, false); - - rkpm_ddr_printascii("pd state:"); - rkpm_ddr_printhex(pmu_readl(RK3288_PMU_PWR_STATE)); - rkpm_ddr_printascii("\n"); - + rk_pmu_pwrdn_st = pmu_readl(RK3288_PMU_PWRDN_ST); + + if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_GPU]))) + rk3288_sys_set_power_domain(PD_GPU, false); + + if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_HEVC]))) + rk3288_sys_set_power_domain(PD_HEVC, false); + + if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_VIO]))) + rk3288_sys_set_power_domain(PD_VIO, false); + + if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_VIDEO]))) + rk3288_sys_set_power_domain(PD_VIDEO, false); +#if 0 + rkpm_ddr_printascii("pd state:"); + rkpm_ddr_printhex(rk_pmu_pwrdn_st); + rkpm_ddr_printhex(pmu_readl(RK3288_PMU_PWRDN_ST)); + rkpm_ddr_printascii("\n"); + #endif } static inline void rk_pm_soc_pd_resume(void) { - if(!(rk_pmu_pwrdn_st&BIT(pmu_pd_map[IDLE_REQ_GPU]))) - rk3288_sys_set_power_domain(IDLE_REQ_GPU, false); - - if(!(rk_pmu_pwrdn_st&BIT(pmu_pd_map[IDLE_REQ_HEVC]))) - rk3288_sys_set_power_domain(IDLE_REQ_HEVC, false); - - if(!(rk_pmu_pwrdn_st&BIT(pmu_pd_map[IDLE_REQ_VIO]))) - rk3288_sys_set_power_domain(IDLE_REQ_VIO, false); - - if(!(rk_pmu_pwrdn_st&BIT(pmu_pd_map[IDLE_REQ_VIDEO]))) - rk3288_sys_set_power_domain(IDLE_REQ_VIDEO, false); + if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_GPU]))) + rk3288_sys_set_power_domain(PD_GPU, true); + + if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_HEVC]))) + rk3288_sys_set_power_domain(PD_HEVC, true); + + if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_VIO]))) + rk3288_sys_set_power_domain(PD_VIO, true); + + if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_VIDEO]))) + rk3288_sys_set_power_domain(PD_VIDEO, true); +#if 0 rkpm_ddr_printascii("pd state:"); - rkpm_ddr_printhex(pmu_readl(RK3288_PMU_PWR_STATE)); + rkpm_ddr_printhex(pmu_readl(RK3288_PMU_PWRDN_ST)); rkpm_ddr_printascii("\n"); +#endif } -//extern bool console_suspend_enabled; -static void __init rk3288_init_suspend(void) + +extern bool console_suspend_enabled; + +static void rk3288_init_suspend(void) { - //return; printk("%s\n",__FUNCTION__); rockchip_suspend_init(); //rkpm_pie_init(); rk3288_suspend_init(); - // rkpm_set_ops_pwr_dmns(rk_pm_soc_pd_suspend,rk_pm_soc_pd_resume); - //console_suspend_enabled=0; - //pm_suspend(PM_SUSPEND_MEM); + rkpm_set_ops_pwr_dmns(rk_pm_soc_pd_suspend,rk_pm_soc_pd_resume); + #if 0 + console_suspend_enabled=0; + do{ + pm_suspend(PM_SUSPEND_MEM); + } + while(1); + #endif } + #endif -- 2.34.1