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

Reply via email to