summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx5/cpu.c
diff options
context:
space:
mode:
authorRanjani Vaidyanathan <ra5478@freescale.com>2010-09-03 16:47:58 -0500
committerAlan Tull <r80115@freescale.com>2010-09-25 09:52:11 -0500
commit784cad4a077b8af802466e102d276e1b9170818d (patch)
tree90ed69b626db0f64e57929f190140ac271092c53 /arch/arm/mach-mx5/cpu.c
parent057450a8090e78f6bb0750581087602ca150f0dd (diff)
ENGR00127147: MX50: Add support for Automatic Low Power Mode on DDR
Configure the Databahn so that the DDR automatically enters Low Power Mode 4. This will allow DDR to enter into self-refresh after an idle timeout. Also added code to disable DDR_CLKGAT bits in the CCM when no bus masters are accessing the DDR and ARM is in WFI. Removed calls to change DDR frequency to 24MHz in LPAPM mode as this is causing some random lockups. DDR is left at 266MHz in LPAPM mode currently. Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
Diffstat (limited to 'arch/arm/mach-mx5/cpu.c')
-rw-r--r--arch/arm/mach-mx5/cpu.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c
index 90813cc75b14..abb33781c4c1 100644
--- a/arch/arm/mach-mx5/cpu.c
+++ b/arch/arm/mach-mx5/cpu.c
@@ -11,6 +11,7 @@
* This file contains the CPU initialization code.
*/
+#include <linux/proc_fs.h>
#include <linux/types.h>
#include <linux/err.h>
#include <linux/kernel.h>
@@ -21,6 +22,7 @@
#include <linux/clk.h>
#include <mach/common.h>
#include <mach/hardware.h>
+#include <asm/mach/map.h>
#define CORTEXA8_PLAT_AMC 0x18
#define SRPG_NEON_PUPSCR 0x284
@@ -36,6 +38,10 @@ void __iomem *arm_plat_base;
void __iomem *gpc_base;
void __iomem *ccm_base;
void __iomem *databahn_base;
+void *wait_in_iram_base;
+void (*wait_in_iram)(void *ccm_addr, void *databahn_addr);
+
+extern void mx50_wait(u32 ccm_base, u32 databahn_addr);
static int cpu_silicon_rev = -1;
@@ -234,6 +240,41 @@ static int __init post_cpu_init(void)
}
databahn_base = ioremap(MX50_DATABAHN_BASE_ADDR, SZ_16K);
+
+ if (cpu_is_mx50()) {
+ struct clk *ddr_clk = clk_get(NULL, "ddr_clk");
+ unsigned long iram_paddr;
+
+ iram_alloc(SZ_4K, &iram_paddr);
+ /* Need to remap the area here since we want the memory region
+ to be executable. */
+ wait_in_iram_base = __arm_ioremap(iram_paddr,
+ SZ_4K, MT_HIGH_VECTORS);
+ memcpy(wait_in_iram_base, mx50_wait, SZ_4K);
+ wait_in_iram = (void *)wait_in_iram_base;
+
+ clk_enable(ddr_clk);
+
+ /* Set the DDR to enter automatic self-refresh. */
+ /* Set the DDR to automatically enter lower power mode 4. */
+ reg = __raw_readl(databahn_base + DATABAHN_CTL_REG22);
+ reg &= ~LOWPOWER_AUTOENABLE_MASK;
+ reg |= 1 << 1;
+ __raw_writel(reg, databahn_base + DATABAHN_CTL_REG22);
+
+ /* set the counter for entering mode 4. */
+ reg = __raw_readl(databahn_base + DATABAHN_CTL_REG21);
+ reg &= ~LOWPOWER_EXTERNAL_CNT_MASK;
+ reg = 128 << LOWPOWER_EXTERNAL_CNT_OFFSET;
+ __raw_writel(reg, databahn_base + DATABAHN_CTL_REG21);
+
+ /* Enable low power mode 4 */
+ reg = __raw_readl(databahn_base + DATABAHN_CTL_REG20);
+ reg &= ~LOWPOWER_CONTROL_MASK;
+ reg |= 1 << 1;
+ __raw_writel(reg, databahn_base + DATABAHN_CTL_REG20);
+ clk_disable(ddr_clk);
+ }
return 0;
}