From e30de6e008192ac109c658c26d078ac4903c50c4 Mon Sep 17 00:00:00 2001
From: cym <cym@rock-chips.com>
Date: Wed, 12 Sep 2012 18:04:53 +0800
Subject: [PATCH] rk2928 ddr:add auto-self-refresh when early suspend

---
 arch/arm/mach-rk2928/Makefile   |  1 +
 arch/arm/mach-rk2928/ddr.c      |  2 ++
 arch/arm/mach-rk2928/ddr_freq.c | 50 +++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+)
 create mode 100644 arch/arm/mach-rk2928/ddr_freq.c

diff --git a/arch/arm/mach-rk2928/Makefile b/arch/arm/mach-rk2928/Makefile
index cbcfe87cf074..9c99e31323ed 100755
--- a/arch/arm/mach-rk2928/Makefile
+++ b/arch/arm/mach-rk2928/Makefile
@@ -7,6 +7,7 @@ obj-y += iomux.o
 obj-y += ../plat-rk/clock.o
 obj-y += clock_data.o
 obj-y += ddr.o
+obj-$(CONFIG_DDR_FREQ) += ddr_freq.o
 obj-$(CONFIG_CPU_FREQ) += cpufreq.o
 obj-$(CONFIG_DVFS) += dvfs.o
 obj-$(CONFIG_PM) += pm.o
diff --git a/arch/arm/mach-rk2928/ddr.c b/arch/arm/mach-rk2928/ddr.c
index 61fcfa754ab3..bfa7b27a1672 100755
--- a/arch/arm/mach-rk2928/ddr.c
+++ b/arch/arm/mach-rk2928/ddr.c
@@ -1978,6 +1978,8 @@ void ddr_set_auto_self_refresh(bool en)
 {
     //set auto self-refresh idle
     ddr_sr_idle = en ? SR_IDLE : 0;
+    ddr_move_to_Config_state();
+    ddr_move_to_Access_state();
 }
 EXPORT_SYMBOL(ddr_set_auto_self_refresh);
 
diff --git a/arch/arm/mach-rk2928/ddr_freq.c b/arch/arm/mach-rk2928/ddr_freq.c
new file mode 100644
index 000000000000..5a42d4ae58f9
--- /dev/null
+++ b/arch/arm/mach-rk2928/ddr_freq.c
@@ -0,0 +1,50 @@
+#include <mach/ddr.h>
+
+#include <linux/earlysuspend.h>
+#include <linux/delay.h>
+
+#define ddr_print(x...) printk( "DDR DEBUG: " x )
+
+struct ddr {
+	int suspend;
+	struct early_suspend early_suspend;
+	struct clk *ddr_pll;
+};
+
+static void ddr_early_suspend(struct early_suspend *h);
+static void ddr_late_resume(struct early_suspend *h);
+
+static struct ddr ddr = {
+	.early_suspend = {
+		.suspend = ddr_early_suspend,
+		.resume = ddr_late_resume,
+		.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 50,
+	},
+};
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void ddr_early_suspend(struct early_suspend *h)
+{
+    //Enable auto self refresh  0x01*32 DDR clk cycle
+    ddr_print("run in %s\n",__func__);
+    ddr_set_auto_self_refresh(true);
+    
+    return;
+}
+
+static void ddr_late_resume(struct early_suspend *h)
+{
+    //Disable auto self refresh
+    ddr_print("run in %s\n",__func__);
+    ddr_set_auto_self_refresh(false);
+
+    return;
+}
+
+static int rk30_ddr_late_init (void)
+{
+    register_early_suspend(&ddr.early_suspend);
+    return 0;
+}
+late_initcall(rk30_ddr_late_init);
+#endif
-- 
2.34.1