RK29:set neon powerdomain off when in suspend,set it by config menuconfig
author张晴 <zhangqing@rock-chips.com>
Fri, 7 Oct 2011 03:25:39 +0000 (20:25 -0700)
committer张晴 <zhangqing@rock-chips.com>
Fri, 7 Oct 2011 03:25:39 +0000 (20:25 -0700)
arch/arm/mach-rk29/Kconfig
arch/arm/mach-rk29/pm.c
arch/arm/vfp/vfphw.S

index a738886e2c6b140097cf40b787c541b18ab3c8a3..4179baaf48e0aec0742ea6478cb3aad8d8b2293c 100644 (file)
@@ -228,6 +228,10 @@ config RK29_GPIO_SUSPEND
        bool "Support gpio suspend"
        default n
 
+config RK29_NEON_POWERDOMAIN_SET
+       bool "Support neon powerdomain on and off"
+       default n
+
 config RK29_SPI_INSRAM
        tristate "Support spi control interface"
        depends on REGULATOR_WM831X
index ed840cfc00c71fa5a72730465a2c16105cb99246..7c0962532b6f2f04551e09e57ce76a90ce58c1ba 100755 (executable)
@@ -26,6 +26,8 @@
 #include <mach/iomux.h>
 #include <mach/pm-vol.h>
 
+#include <asm/vfp.h>
+
 #define grf_readl(offset) readl(RK29_GRF_BASE + offset)
 #define grf_writel(v, offset) do { writel(v, RK29_GRF_BASE + offset); readl(RK29_GRF_BASE + offset); } while (0)
 
@@ -342,6 +344,67 @@ static void dump_io_pull(void)
        DUMP_GPIO_PULL(5);
        DUMP_GPIO_PULL(6);
 }
+#ifdef CONFIG_RK29_NEON_POWERDOMAIN_SET
+/*******************************neon powermain***********************/
+#define pmu_read(offset)               readl(RK29_PMU_BASE + (offset))
+#define pmu_write(offset, value)       writel((value), RK29_PMU_BASE + (offset))
+#define PMU_PG_CON 0x10
+#define vfpreg(_vfp_) #_vfp_
+
+#define fmrx(_vfp_) ({                 \
+       u32 __v;                        \
+       asm("mrc p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx   %0, " #_vfp_    \
+           : "=r" (__v) : : "cc");     \
+       __v;                            \
+ })
+
+#define fmxr(_vfp_,_var_)              \
+       asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr   " #_vfp_ ", %0" \
+          : : "r" (_var_) : "cc")
+extern void vfp_save_state(void *location, u32 fpexc);
+extern void vfp_load_state(void *location, u32 fpexc);
+// extern  __sramdata u64  saveptr[33];
+u32  saveptr[2][60]={};
+void  neon_powerdomain_off(void)
+{
+       int ret,i=0;
+       int *p;
+       p=&saveptr[0][0];
+       
+        unsigned int fpexc = fmrx(FPEXC);  //get neon Logic gate
+        
+       fmxr(FPEXC, fpexc | FPEXC_EN);  //open neon Logic gate
+       for(i=0;i<36;i++){
+       vfp_save_state(p,fpexc);                        //save neon reg,32 D reg,2 control reg
+       p++;
+       }  
+       fmxr(FPEXC, fpexc & ~FPEXC_EN);    //close neon Logic gate
+       
+        ret=pmu_read(PMU_PG_CON);                   //get power domain state
+       pmu_write(PMU_PG_CON,ret|(0x1<<1));          //powerdomain off neon
+       printk("neon powerdomain is off\n");
+}
+void   neon_powerdomain_on(void)
+{
+       int ret,i=0;
+       int *p;
+       p=&saveptr[0][0];
+       
+       ret=pmu_read(PMU_PG_CON);                   //get power domain state
+       pmu_write(PMU_PG_CON,ret&~(0x1<<1));                //powerdomain on neon
+       mdelay(4);
+       
+       unsigned int fpexc = fmrx(FPEXC);              //get neon Logic gate
+       fmxr(FPEXC, fpexc | FPEXC_EN);                   //open neon Logic gate
+       for(i=0;i<36;i++){
+       vfp_load_state(p,fpexc);   //recovery neon reg, 32 D reg,2 control reg
+       p++;
+       }
+       fmxr(FPEXC, fpexc | FPEXC_EN);      //open neon Logic gate
+       printk("neon powerdomain is on\n");
+}
+#endif
+
 void pm_gpio_suspend(void);
 void pm_gpio_resume(void);
 
@@ -349,7 +412,11 @@ static int rk29_pm_enter(suspend_state_t state)
 {
        u32 apll, cpll, gpll, mode, clksel0;
        u32 clkgate[4];
-
+       
+       #ifdef CONFIG_RK29_NEON_POWERDOMAIN_SET
+       neon_powerdomain_off();
+       #endif
+       
        // memory teseter
        if (ddr_debug == 3)
                ddr_testmode();
@@ -472,6 +539,11 @@ static int rk29_pm_enter(suspend_state_t state)
        sram_printascii("0\n");
 
        dump_irq();
+
+       #ifdef CONFIG_RK29_NEON_POWERDOMAIN_SET
+       neon_powerdomain_on();
+       #endif
+       
        return 0;
 }
 
index d66cead97d28b3c5d63d9c22d4fdcb77b7d7bd8e..7b0f0dae5b1de669f32caaea7634f830cbc681ef 100644 (file)
@@ -206,6 +206,23 @@ ENTRY(vfp_save_state)
        mov     pc, lr
 ENDPROC(vfp_save_state)
 
+ENTRY(vfp_load_state)
+       @ Save the current VFP state
+       @ r0 - save location
+       @ r1 - FPEXC
+       DBGSTR1 "save VFP state %p", r0
+       VFPFLDMIA r0, r2                @ save the working registers
+       ldmia   r0, {r1,r2,r3,r12}
+       tst     r1, #FPEXC_EX           @ is there additional state to save?
+       beq     1f
+       tst     r1, #FPEXC_FP2V         @ is there an FPINST2 to read?
+       beq     1f
+1:
+       VFPFMXR FPSCR, r2
+       VFPFMXR FPEXC, r1 
+       mov     pc, lr
+ENDPROC(vfp_load_state)
+
 last_VFP_context_address:
        .word   last_VFP_context