Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 313813
b: refs/heads/master
c: c7e48e1
h: refs/heads/master
i:
  313811: dd4709f
v: v3
  • Loading branch information
Sonic Zhang authored and Bob Liu committed Jul 24, 2012
1 parent 4427a00 commit 5511f6c
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 128 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a5b4d4be6ce7939d1604fae05786833fffae02f9
refs/heads/master: c7e48e1e3e926de21605f959c31689d56fb639e3
9 changes: 9 additions & 0 deletions trunk/arch/blackfin/include/asm/context.S
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,12 @@
call \func;
#endif
.endm

#if defined(CONFIG_BFIN_SCRATCH_REG_RETN)
# define EX_SCRATCH_REG RETN
#elif defined(CONFIG_BFIN_SCRATCH_REG_RETE)
# define EX_SCRATCH_REG RETE
#else
# define EX_SCRATCH_REG CYCLES
#endif

2 changes: 1 addition & 1 deletion trunk/arch/blackfin/mach-bf609/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
#

obj-y := dma.o clock.o
obj-$(CONFIG_PM) += pm.o hibernate.o
obj-$(CONFIG_PM) += pm.o dpm.o
155 changes: 155 additions & 0 deletions trunk/arch/blackfin/mach-bf609/dpm.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#include <linux/linkage.h>
#include <asm/blackfin.h>
#include <asm/dpmc.h>

#include <asm/context.S>

#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);

bfin_init_pm_bench_cycles;

[P0] = R3;

SSYNC;
ENDPROC(_enter_hibernate)

/* DPM wake up interrupt won't wake up core on bf60x if its core IMASK
* is disabled. This behavior differ from bf5xx serial processor.
*/
ENTRY(_dummy_deepsleep)
[--sp] = SYSCFG;
[--sp] = (R7:0,P5:0);
cli r0;

/* get wake up interrupt ID */
P0.l = LO(SEC_SCI_BASE + SEC_CSID);
P0.h = HI(SEC_SCI_BASE + SEC_CSID);
R0 = [P0];

/* ACK wake up interrupt in SEC */
P1.l = LO(SEC_END);
P1.h = HI(SEC_END);

[P1] = R0;
SSYNC;

/* restore EVT 11 entry */
p0.h = hi(EVT11);
p0.l = lo(EVT11);
p1.h = _evt_evt11;
p1.l = _evt_evt11;

[p0] = p1;
SSYNC;

(R7:0,P5:0) = [sp++];
SYSCFG = [sp++];
RTI;
ENDPROC(_dummy_deepsleep)

ENTRY(_enter_deepsleep)
LINK 0x0;
[--sp] = (R7:0,P5:0);

/* Change EVT 11 entry to dummy handler for wake up event */
p0.h = hi(EVT11);
p0.l = lo(EVT11);
p1.h = _dummy_deepsleep;
p1.l = _dummy_deepsleep;

[p0] = p1;

P0.H = HI(PM_STACK);
P0.L = LO(PM_STACK);

EX_SCRATCH_REG = SP;
SP = P0;

SSYNC;

/* should put ddr to self refresh mode before sleep */
call _bf609_ddr_sr;

/* Set DPM controller to deep sleep mode */
P0.H = HI(DPM0_CTL);
P0.L = LO(DPM0_CTL);
R3.H = HI(0x00000008);
R3.L = LO(0x00000008);
[P0] = R3;
CSYNC;

/* Enable evt 11 in IMASK before idle, otherwise core doesn't wake up. */
r0.l = 0x800;
r0.h = 0;
sti r0;
SSYNC;

/* Fall into deep sleep in idle*/
idle;
SSYNC;

/* Restore PLL after wake up from deep sleep */
call _bf609_resume_ccbuf;

/* turn ddr out of self refresh mode */
call _bf609_ddr_sr_exit;

SP = EX_SCRATCH_REG;

(R7:0,P5:0) = [SP++];
UNLINK;
RTS;
ENDPROC(_enter_deepsleep)

.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)

65 changes: 0 additions & 65 deletions trunk/arch/blackfin/mach-bf609/hibernate.S

This file was deleted.

6 changes: 3 additions & 3 deletions trunk/arch/blackfin/mach-bf609/include/mach/pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

#include <linux/suspend.h>

int bfin609_pm_enter(suspend_state_t state);
int bf609_pm_prepare(void);
void bf609_pm_finish(void);
extern int bfin609_pm_enter(suspend_state_t state);
extern int bf609_pm_prepare(void);
extern void bf609_pm_finish(void);

void bf609_hibernate(void);
void bfin_sec_raise_irq(unsigned int sid);
Expand Down
80 changes: 29 additions & 51 deletions trunk/arch/blackfin/mach-bf609/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <asm/pm.h>
#include <mach/pm.h>
#include <asm/blackfin.h>
#include <asm/mem_init.h>

/***********************************************************/
/* */
Expand Down Expand Up @@ -132,60 +133,30 @@ void bfin_cpu_suspend(void)
}

__attribute__((l1_text))
void bfin_deepsleep(unsigned long mask)
void bf609_ddr_sr(void)
{
uint32_t dpm0_ctl;

bfin_write32(DPM0_WAKE_EN, 0x10);
bfin_write32(DPM0_WAKE_POL, 0x10);
dpm0_ctl = 0x00000008;
bfin_write32(DPM0_CTL, dpm0_ctl);
SSYNC();
__asm__ __volatile__( \
".align 8;" \
"idle;" \
: : \
);
#ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH
__asm__ __volatile__(
"R0 = 0;"
"CYCLES = R0;"
"CYCLES2 = R0;"
"R0 = SYSCFG;"
"BITSET(R0, 1);"
"SYSCFG = R0;"
: : : "R0"
);
#endif

dmc_enter_self_refresh();
}

__attribute__((l1_text))
void bf609_ddr_sr(void)
void bf609_ddr_sr_exit(void)
{
uint32_t reg;

reg = bfin_read_DMC0_CTL();
reg |= 0x8;
bfin_write_DMC0_CTL(reg);
dmc_exit_self_refresh();

while (!(bfin_read_DMC0_STAT() & 0x8))
/* After wake up from deep sleep and exit DDR from self refress mode,
* should wait till CGU PLL is locked.
*/
while (bfin_read32(CGU0_STAT) & CLKSALGN)
continue;
}

__attribute__((l1_text))
void bf609_ddr_sr_exit(void)
void bf609_resume_ccbuf(void)
{
uint32_t reg;
while (!(bfin_read_DMC0_STAT() & 0x1))
continue;
bfin_write32(DPM0_CCBF_EN, 3);
bfin_write32(DPM0_CTL, 2);

reg = bfin_read_DMC0_CTL();
reg &= ~0x8;
bfin_write_DMC0_CTL(reg);

while ((bfin_read_DMC0_STAT() & 0x8))
continue;
while ((bfin_read32(DPM0_STAT) & 0xf) != 1);
}

__attribute__((l1_text))
Expand All @@ -208,15 +179,24 @@ void bfin_hibernate_syscontrol(void)
#else
# define SIC_SYSIRQ(irq) ((irq) - IVG15)
#endif
asmlinkage void enter_deepsleep(void);

__attribute__((l1_text))
void bfin_deepsleep(unsigned long mask)
{
bfin_write32(DPM0_WAKE_EN, 0x10);
bfin_write32(DPM0_WAKE_POL, 0x10);
SSYNC();
enter_deepsleep();
}

void bfin_hibernate(unsigned long mask)
{
bfin_write32(DPM0_WAKE_EN, 0x10);
bfin_write32(DPM0_WAKE_POL, 0x10);
bfin_write32(DPM0_PGCNTR, 0x0000FFFF);
bfin_write32(DPM0_HIB_DIS, 0xFFFF);

printk(KERN_DEBUG "hibernate: restore %x pgcnt %x\n", bfin_read32(DPM0_RESTORE0), bfin_read32(DPM0_PGCNTR));

bf609_hibernate();
}

Expand Down Expand Up @@ -294,6 +274,7 @@ void bf609_cpu_pm_enter(suspend_state_t state)
else {
bfin_hibernate(wakeup);
}

}

int bf609_cpu_pm_prepare(void)
Expand All @@ -320,21 +301,18 @@ static irqreturn_t test_isr(int irq, void *dev_id)

static irqreturn_t dpm0_isr(int irq, void *dev_id)
{
uint32_t wake_stat;

wake_stat = bfin_read32(DPM0_WAKE_STAT);
printk(KERN_DEBUG "enter %s wake stat %08x\n", __func__, wake_stat);

bfin_write32(DPM0_WAKE_STAT, wake_stat);
bfin_write32(DPM0_WAKE_STAT, bfin_read32(DPM0_WAKE_STAT));
bfin_write32(CGU0_STAT, bfin_read32(CGU0_STAT));
return IRQ_HANDLED;
}
#endif

static int __init bf609_init_pm(void)
{
int irq;
int error;

#if CONFIG_PM_BFIN_WAKE_PE12
#ifdef CONFIG_PM_BFIN_WAKE_PE12
irq = gpio_to_irq(GPIO_PE12);
if (irq < 0) {
error = irq;
Expand Down
Loading

0 comments on commit 5511f6c

Please sign in to comment.