commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=095436926d42d7d4da00876f4933910b0a2a6e89 branch: http://blackfin.uclinux.org/git/?p=linux-kernel;a=shortlog;h=refs/heads/trunk
add bf609 cpu pm callbacks change bfin pm framework to add bf609 cpu pm tweak pm framework to build Signed-off-by: Steven Miao <[email protected]> Signed-off-by: Bob Liu <[email protected]> --- arch/blackfin/kernel/bfin_dma.c | 11 +++ arch/blackfin/mach-bf609/Makefile | 1 + arch/blackfin/mach-bf609/include/mach/pm.h | 28 +++++++ arch/blackfin/mach-bf609/pm.c | 115 ++++++++++++++++++++++++++++ arch/blackfin/mach-common/dpmc_modes.S | 8 ++- arch/blackfin/mach-common/pm.c | 24 +++++- 6 files changed, 184 insertions(+), 3 deletions(-) diff --git a/arch/blackfin/kernel/bfin_dma.c b/arch/blackfin/kernel/bfin_dma.c index 8496762..8b27899 100644 --- a/arch/blackfin/kernel/bfin_dma.c +++ b/arch/blackfin/kernel/bfin_dma.c @@ -204,6 +204,7 @@ EXPORT_SYMBOL(free_dma); # ifndef MAX_DMA_SUSPEND_CHANNELS # define MAX_DMA_SUSPEND_CHANNELS MAX_DMA_CHANNELS # endif +# ifndef CONFIG_BF60x int blackfin_dma_suspend(void) { int i; @@ -236,6 +237,16 @@ void blackfin_dma_resume(void) bfin_write_DMAC_TC_PER(0x0111); #endif } +# else +int blackfin_dma_suspend(void) +{ + return 0; +} + +void blackfin_dma_resume(void) +{ +} +#endif #endif /** diff --git a/arch/blackfin/mach-bf609/Makefile b/arch/blackfin/mach-bf609/Makefile index 88aa185..91a66bb 100644 --- a/arch/blackfin/mach-bf609/Makefile +++ b/arch/blackfin/mach-bf609/Makefile @@ -3,3 +3,4 @@ # obj-y := dma.o clock.o +obj-$(CONFIG_PM) += pm.o diff --git a/arch/blackfin/mach-bf609/include/mach/pm.h b/arch/blackfin/mach-bf609/include/mach/pm.h new file mode 100644 index 0000000..cc37980 --- /dev/null +++ b/arch/blackfin/mach-bf609/include/mach/pm.h @@ -0,0 +1,28 @@ +/* + * Blackfin bf609 power management + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 + */ + +#ifndef __MACH_BF609_PM_H__ +#define __MACH_BF609_PM_H__ + +#include <linux/suspend.h> + +struct bfin_cpu_pm_fns { + void (*save)(unsigned long *); + void (*restore)(unsigned long *); + int (*valid)(suspend_state_t state); + void (*enter)(suspend_state_t state); + int (*prepare)(void); + void (*finish)(void); +}; + +extern struct bfin_cpu_pm_fns *bfin_cpu_pm; + +extern int bfin609_pm_enter(suspend_state_t state); +extern int bf609_pm_prepare(void); +extern void bf609_pm_finish(void); +#endif diff --git a/arch/blackfin/mach-bf609/pm.c b/arch/blackfin/mach-bf609/pm.c new file mode 100644 index 0000000..3c5d0e3 --- /dev/null +++ b/arch/blackfin/mach-bf609/pm.c @@ -0,0 +1,115 @@ +/* + * Blackfin bf609 power management + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 + */ + +#include <linux/suspend.h> +#include <linux/io.h> + +#include <asm/dpmc.h> +#include <mach/pm.h> + +void bfin_cpu_suspend(void) +{ + __asm__ __volatile__( \ + ".align 8;" \ + "idle;" \ + : : \ + ); +} + +void bfin_deepsleep(unsigned long mask) +{ + uint32_t dpm0_ctl; + + dpm0_ctl = bfin_read32(DPM0_CTL); + dpm0_ctl |= 0x00000004; + bfin_write32(DPM0_CTL, dpm0_ctl); + bfin_cpu_suspend(); + +} + +void bfin_hibernate(unsigned long mask) +{ + uint32_t dpm0_ctl; + + dpm0_ctl = bfin_read32(DPM0_CTL); + dpm0_ctl |= 0x00000010; + bfin_write32(DPM0_CTL, dpm0_ctl); + bfin_cpu_suspend(); +} + +void bf609_ddr_sr(void) +{ + uint32_t reg; + + reg = bfin_read_DDR0_CTL(); + reg |= 0x8; + bfin_write_DDR0_CTL(reg); + + while (!(bfin_read_DDR0_STAT() & 0x8)) + continue; +} + +void bf609_ddr_sr_exit(void) +{ + uint32_t reg; + uint32_t dll_ctl; + uint32_t dlldatacycle; + + reg = bfin_read_DDR0_CTL(); + reg |= 0x8; + bfin_write_DDR0_CTL(reg); + while (!(bfin_read_DDR0_STAT() & 0x4)) + continue; + while (!(bfin_read_DDR0_STAT() & 0x8)) + continue; + + reg = bfin_read_DDR0_CTL(); + reg &= ~0x8; + bfin_write_DDR0_CTL(reg); + + while ((bfin_read_DDR0_STAT() & 0x8)) + continue; + + dlldatacycle = (bfin_read_DDR0_STAT() & 0x00f00000) >> 20; + dll_ctl = bfin_read_DDR0_DLLCTL(); + dll_ctl &= 0x0ff; + bfin_write_DDR0_DLLCTL(dll_ctl | (dlldatacycle << 8)); + + while (!(bfin_read_DDR0_STAT() & 0x2000)) + continue; + +} + +void bf609_cpu_pm_enter(suspend_state_t state) +{ + bfin_deepsleep(0xffff); +} + +int bf609_cpu_pm_prepare(void) +{ + return 0; +} + +void bf609_cpu_pm_finish(void) +{ + +} + +static struct bfin_cpu_pm_fns bf609_cpu_pm = { + .enter = bf609_cpu_pm_enter, + .prepare = bf609_cpu_pm_prepare, + .finish = bf609_cpu_pm_finish, +}; + +static int __init bf609_init_pm(void) +{ + bfin_cpu_pm = &bf609_cpu_pm; + return 0; +} + +late_initcall(bf609_init_pm); diff --git a/arch/blackfin/mach-common/dpmc_modes.S b/arch/blackfin/mach-common/dpmc_modes.S index 1c534d2..b6017b3 100644 --- a/arch/blackfin/mach-common/dpmc_modes.S +++ b/arch/blackfin/mach-common/dpmc_modes.S @@ -10,7 +10,7 @@ #include <asm/dpmc.h> .section .l1.text - +#ifndef CONFIG_BF60x ENTRY(_sleep_mode) [--SP] = (R7:4, P5:3); [--SP] = RETS; @@ -49,6 +49,7 @@ ENTRY(_sleep_mode) (R7:4, P5:3) = [SP++]; RTS; ENDPROC(_sleep_mode) +#endif /* * This func never returns as it puts the part into hibernate, and @@ -58,6 +59,8 @@ ENDPROC(_sleep_mode) * * We accept just one argument -- the value to write to VR_CTL. */ + +#ifndef CONFIG_BF60x ENTRY(_hibernate_mode) /* Save/setup the regs we need early for minor pipeline optimization */ R4 = R0; @@ -79,7 +82,9 @@ ENTRY(_hibernate_mode) .Lforever: jump .Lforever; ENDPROC(_hibernate_mode) +#endif +#ifndef CONFIG_BF60x ENTRY(_sleep_deeper) [--SP] = (R7:4, P5:3); [--SP] = RETS; @@ -892,3 +897,4 @@ ENTRY(_do_hibernate) RTS; ENDPROC(_do_hibernate) +#endif diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index 3c648a0..ebe2ebd 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c @@ -20,19 +20,29 @@ #include <asm/dma.h> #include <asm/dpmc.h> +#include <mach/pm.h> + +#ifdef CONFIG_BF60x +struct bfin_cpu_pm_fns *bfin_cpu_pm; +#endif void bfin_pm_suspend_standby_enter(void) { bfin_pm_standby_setup(); -#ifdef CONFIG_PM_BFIN_SLEEP_DEEPER - sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); +#ifdef CONFIG_BF60x + bfin_cpu_pm->enter(PM_SUSPEND_STANDBY); #else +# ifdef CONFIG_PM_BFIN_SLEEP_DEEPER + sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); +# else sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); +# endif #endif bfin_pm_standby_restore(); +#ifndef CONFIG_BF60x #ifdef SIC_IWR0 bfin_write_SIC_IWR0(IWR_DISABLE_ALL); # ifdef SIC_IWR1 @@ -52,6 +62,8 @@ void bfin_pm_suspend_standby_enter(void) #else bfin_write_SIC_IWR(IWR_DISABLE_ALL); #endif + +#endif } int bf53x_suspend_l1_mem(unsigned char *memptr) @@ -133,7 +145,11 @@ int bfin_pm_suspend_mem_enter(void) return -ENOMEM; } +#ifndef CONFIG_BF60x wakeup = bfin_read_VR_CTL() & ~FREQ; +#else + +#endif wakeup |= SCKELOW; #ifdef CONFIG_PM_BFIN_WAKE_PH6 @@ -159,7 +175,11 @@ int bfin_pm_suspend_mem_enter(void) _disable_icplb(); bf53x_suspend_l1_mem(memptr); +#ifndef CONFIG_BF60x do_hibernate(wakeup | vr_wakeup); /* See you later! */ +#else + bfin_cpu_pm->enter(PM_SUSPEND_MEM); +#endif bf53x_resume_l1_mem(memptr);
_______________________________________________ Linux-kernel-commits mailing list [email protected] https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits
