summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorNancy Chen <Nancy.Chen@freescale.com>2011-01-13 14:29:03 -0600
committerNancy Chen <Nancy.Chen@freescale.com>2011-01-13 16:18:40 -0600
commitf59dc9fcc59c02152b4c73e4dd8e131836dc84ad (patch)
tree8fa13bc66faa6e66dac9049529ed9dea5ddfb3de /arch
parent783481236fa5b8d94b2e510a35e56562558d3d63 (diff)
ENGR00137973 MX53_TO2: DVFS core caused system hang
MX53_TO2: DVFS core caused system hang. Signed-off-by: Nancy Chen <Nancy.Chen@freescale.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/plat-mxc/dvfs_core.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/arch/arm/plat-mxc/dvfs_core.c b/arch/arm/plat-mxc/dvfs_core.c
index 9bce5917115e..a1024e79d496 100644
--- a/arch/arm/plat-mxc/dvfs_core.c
+++ b/arch/arm/plat-mxc/dvfs_core.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -76,6 +76,9 @@
#define MXC_DVFSCNTR_LTBRSR_OFFSET 3
#define MXC_DVFSCNTR_DVFEN 0x00000001
+#define CCM_CDCR_SW_DVFS_EN 0x20
+#define CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER 0x4
+
extern int dvfs_core_is_active;
extern void setup_pll(void);
static struct mxc_dvfs_platform_data *dvfs_data;
@@ -163,6 +166,7 @@ static int set_cpu_freq(int wp)
int gp_volt = 0;
u32 reg;
u32 reg1;
+ u32 en_sw_dvfs = 0;
unsigned long flags;
if (cpu_wp_tbl[wp].pll_rate != cpu_wp_tbl[old_wp].pll_rate) {
@@ -237,8 +241,15 @@ static int set_cpu_freq(int wp)
/* Change arm_podf only */
/* set ARM_FREQ_SHIFT_DIVIDER */
reg = __raw_readl(ccm_base + dvfs_data->ccm_cdcr_offset);
- reg &= 0xFFFFFFFB;
- reg |= 1 << 2;
+
+ /* Check if software_dvfs_en bit set */
+ if ((reg & CCM_CDCR_SW_DVFS_EN) != 0)
+ en_sw_dvfs = CCM_CDCR_SW_DVFS_EN;
+ else
+ en_sw_dvfs = 0x0;
+
+ reg &= ~(CCM_CDCR_SW_DVFS_EN | CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER);
+ reg |= CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER;
__raw_writel(reg, ccm_base + dvfs_data->ccm_cdcr_offset);
/* Get ARM_PODF */
@@ -319,9 +330,11 @@ static int set_cpu_freq(int wp)
udelay(dvfs_data->delay_time);
}
- /* Clear the ARM_FREQ_SHIFT_DIVIDER */
+ /* Clear the ARM_FREQ_SHIFT_DIVIDER and */
+ /* set software_dvfs_en bit back to original setting*/
reg = __raw_readl(ccm_base + dvfs_data->ccm_cdcr_offset);
- reg &= 0xFFFFFFFB;
+ reg &= ~(CCM_CDCR_SW_DVFS_EN | CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER);
+ reg |= en_sw_dvfs;
__raw_writel(reg, ccm_base + dvfs_data->ccm_cdcr_offset);
}
#if defined(CONFIG_CPU_FREQ)