From e162786e2c7dd37ff0729e8adc5b3217d3c9817b Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Mon, 8 Oct 2012 10:08:16 -0500 Subject: [PATCH] ENGR00227426 MX6SL-Fix bugs in low power IDLE mode Need to ensure that DDR IO pads are not floated when a peripheral that needs DDR is active, for ex SDMA. Also need to keep IPMUX clock enabled even when ARM is in WFI, so set the CCGR bits accordingly. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/clock_mx6sl.c | 6 ++-- arch/arm/mach-mx6/system.c | 52 ++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index 04ea66b0c267..748bb13edcb6 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -4061,9 +4061,9 @@ int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc, 3 << MXC_CCM_CCGRx_CG11_OFFSET, MXC_CCM_CCGR1); __raw_writel(1 << MXC_CCM_CCGRx_CG12_OFFSET | 1 << MXC_CCM_CCGRx_CG11_OFFSET | - 1 << MXC_CCM_CCGRx_CG10_OFFSET | - 1 << MXC_CCM_CCGRx_CG9_OFFSET | - 1 << MXC_CCM_CCGRx_CG8_OFFSET, MXC_CCM_CCGR2); + 3 << MXC_CCM_CCGRx_CG10_OFFSET | + 3 << MXC_CCM_CCGRx_CG9_OFFSET | + 3 << MXC_CCM_CCGRx_CG8_OFFSET, MXC_CCM_CCGR2); __raw_writel(1 << MXC_CCM_CCGRx_CG14_OFFSET | 3 << MXC_CCM_CCGRx_CG13_OFFSET | 3 << MXC_CCM_CCGRx_CG12_OFFSET | diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c index 2f1516dbe7e6..533d4f5dbfab 100644 --- a/arch/arm/mach-mx6/system.c +++ b/arch/arm/mach-mx6/system.c @@ -51,6 +51,7 @@ extern unsigned int gpc_wake_irq[4]; static void __iomem *gpc_base = IO_ADDRESS(GPC_BASE_ADDR); +static struct clk *ddr_clk; volatile unsigned int num_cpu_idle; volatile unsigned int num_cpu_idle_lock = 0x0; @@ -271,7 +272,14 @@ void arch_idle_single_core(void) ca9_do_idle(); } else { if (low_bus_freq_mode || audio_bus_freq_mode) { - if (cpu_is_mx6sl() && low_bus_freq_mode) { + u32 ddr_usecount; + if (ddr_clk == NULL) + ddr_clk = clk_get(NULL , + "mmdc_ch0_axi"); + ddr_usecount = clk_get_usecount(ddr_clk); + + if (cpu_is_mx6sl() && low_bus_freq_mode + && ddr_usecount == 1) { /* In this mode PLL2 i already in bypass, * ARM is sourced from PLL1. The code in IRAM * will set ARM to be sourced from STEP_CLK @@ -290,17 +298,41 @@ void arch_idle_single_core(void) * is at 12MHz. This is valid for audio mode on * MX6SL, and all low power modes on MX6DLS. */ - /* PLL1_SW_CLK is sourced from PLL2_PFD2400MHz - * at this point. Move it to bypassed PLL1. - */ - reg = __raw_readl(MXC_CCM_CCSR); - reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL; - __raw_writel(reg, MXC_CCM_CCSR); - + if (cpu_is_mx6sl() && low_bus_freq_mode) { + /* ARM is from PLL1, need to switch to + * STEP_CLK sourced from 24MHz. + */ + /* Swtich STEP_CLK to 24MHz. */ + reg = __raw_readl(MXC_CCM_CCSR); + reg &= ~MXC_CCM_CCSR_STEP_SEL; + __raw_writel(reg, MXC_CCM_CCSR); + /* Set PLL1_SW_CLK to be from + *STEP_CLK. + */ + reg = __raw_readl(MXC_CCM_CCSR); + reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + __raw_writel(reg, MXC_CCM_CCSR); + + } else { + /* PLL1_SW_CLK is sourced from + * PLL2_PFD2_400MHz at this point. + * Move it to bypassed PLL1. + */ + reg = __raw_readl(MXC_CCM_CCSR); + reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + __raw_writel(reg, MXC_CCM_CCSR); + } ca9_do_idle(); - reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; - __raw_writel(reg, MXC_CCM_CCSR); + if (cpu_is_mx6sl() && low_bus_freq_mode) { + /* Set PLL1_SW_CLK to be from PLL1 */ + reg = __raw_readl(MXC_CCM_CCSR); + reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + __raw_writel(reg, MXC_CCM_CCSR); + } else { + reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + __raw_writel(reg, MXC_CCM_CCSR); + } } } else { /* -- 2.39.5