From: 张晴 Date: Fri, 7 Oct 2011 03:25:39 +0000 (-0700) Subject: RK29:set neon powerdomain off when in suspend,set it by config menuconfig X-Git-Tag: firefly_0821_release~9766^2~39^2~5 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=79f2077c99746a705c2789ae5b0dc1dad6cab8e6;p=firefly-linux-kernel-4.4.55.git RK29:set neon powerdomain off when in suspend,set it by config menuconfig --- diff --git a/arch/arm/mach-rk29/Kconfig b/arch/arm/mach-rk29/Kconfig index a738886e2c6b..4179baaf48e0 100644 --- a/arch/arm/mach-rk29/Kconfig +++ b/arch/arm/mach-rk29/Kconfig @@ -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 diff --git a/arch/arm/mach-rk29/pm.c b/arch/arm/mach-rk29/pm.c index ed840cfc00c7..7c0962532b6f 100755 --- a/arch/arm/mach-rk29/pm.c +++ b/arch/arm/mach-rk29/pm.c @@ -26,6 +26,8 @@ #include #include +#include + #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; } diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index d66cead97d28..7b0f0dae5b1d 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -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