Commit 93f89519 authored by Steven Miao's avatar Steven Miao Committed by Bob Liu

blackfin: bf60x: add power management support

Add bf60x cpu pm callbacks and change blackfin pm framework to support bf60x.
Signed-off-by: default avatarSteven Miao <realmz6@gmail.com>
Signed-off-by: default avatarBob Liu <lliubbo@gmail.com>
parent b2cfc653
This diff is collapsed.
/*
* Blackfin bf609 power management
*
* Copyright 2011 Analog Devices Inc.
*
* Licensed under the GPL-2
*/
#ifndef __PM_H__
#define __PM_H__
#include <mach/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;
# ifdef CONFIG_BFIN_COREB
void bfin_coreb_start(void);
void bfin_coreb_stop(void);
void bfin_coreb_reset(void);
# endif
#endif
#include <linux/linkage.h>
#include <asm/blackfin.h>
#include <asm/dpmc.h>
#define PM_STACK (COREA_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
.section .l1.text
ENTRY(_enter_hibernate)
/* switch stack to L1 scratch, prepare for ddr srfr */
P0.H = HI(PM_STACK);
P0.L = LO(PM_STACK);
SP = P0;
call _bf609_ddr_sr;
call _bfin_hibernate_syscontrol;
P0.H = HI(DPM0_RESTORE4);
P0.L = LO(DPM0_RESTORE4);
P1.H = _bf609_pm_data;
P1.L = _bf609_pm_data;
[P0] = P1;
P0.H = HI(DPM0_CTL);
P0.L = LO(DPM0_CTL);
R3.H = HI(0x00000010);
R3.L = LO(0x00000010);
[P0] = R3;
SSYNC;
ENDPROC(_enter_hibernate_mode)
.section .text
ENTRY(_bf609_hibernate)
bfin_cpu_reg_save;
bfin_core_mmr_save;
P0.H = _bf609_pm_data;
P0.L = _bf609_pm_data;
R1.H = 0xDEAD;
R1.L = 0xBEEF;
R2.H = .Lpm_resume_here;
R2.L = .Lpm_resume_here;
[P0++] = R1;
[P0++] = R2;
[P0++] = SP;
P1.H = _enter_hibernate;
P1.L = _enter_hibernate;
call (P1);
.Lpm_resume_here:
bfin_core_mmr_restore;
bfin_cpu_reg_restore;
[--sp] = RETI; /* Clear Global Interrupt Disable */
SP += 4;
RTS;
ENDPROC(_bf609_hibernate)
/*
* 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>
int bfin609_pm_enter(suspend_state_t state);
int bf609_pm_prepare(void);
void bf609_pm_finish(void);
void bf609_hibernate(void);
void bfin_sec_raise_irq(unsigned int sid);
void coreb_enable(void);
#endif
This diff is collapsed.
......@@ -6,7 +6,10 @@ obj-y := \
cache.o cache-c.o entry.o head.o \
interrupt.o arch_checks.o ints-priority.o
obj-$(CONFIG_PM) += pm.o dpmc_modes.o
obj-$(CONFIG_PM) += pm.o
ifneq ($(CONFIG_BF60x),y)
obj-$(CONFIG_PM) += dpmc_modes.o
endif
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o
obj-$(CONFIG_SMP) += smp.o
......
This diff is collapsed.
......@@ -19,20 +19,33 @@
#include <asm/gpio.h>
#include <asm/dma.h>
#include <asm/dpmc.h>
#include <asm/pm.h>
#ifdef CONFIG_BF60x
struct bfin_cpu_pm_fns *bfin_cpu_pm;
#endif
void bfin_pm_suspend_standby_enter(void)
{
#ifndef CONFIG_BF60x
bfin_pm_standby_setup();
#endif
#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
#ifndef CONFIG_BF60x
bfin_pm_standby_restore();
#endif
#ifndef CONFIG_BF60x
#ifdef SIC_IWR0
bfin_write_SIC_IWR0(IWR_DISABLE_ALL);
# ifdef SIC_IWR1
......@@ -52,6 +65,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)
......@@ -83,10 +98,13 @@ int bf53x_resume_l1_mem(unsigned char *memptr)
}
#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
# ifdef CONFIG_BF60x
__attribute__((l1_text))
# endif
static void flushinv_all_dcache(void)
{
u32 way, bank, subbank, set;
u32 status, addr;
register u32 way, bank, subbank, set;
register u32 status, addr;
u32 dmem_ctl = bfin_read_DMEM_CONTROL();
for (bank = 0; bank < 2; ++bank) {
......@@ -133,7 +151,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 +181,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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment