Skip to content

Commit

Permalink
ARM: mx51: Implement code to allow mx51 to enter WFI
Browse files Browse the repository at this point in the history
Implement code for MX51 that allows the SoC to enter WFI when
arch_idle is called.

This patch is also necessary for correctly suspending the system.

Signed-off-by: Dinh Nguyen <Dinh.Nguyen@freescale.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
  • Loading branch information
Dinh Nguyen authored and Sascha Hauer committed Mar 23, 2011
1 parent b6e89b2 commit 0adf882
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 2 deletions.
2 changes: 1 addition & 1 deletion arch/arm/mach-mx5/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#

# Object file lists.
obj-y := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o
obj-y := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o system.o
obj-$(CONFIG_SOC_IMX50) += mm-mx50.o

obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o
Expand Down
84 changes: 84 additions & 0 deletions arch/arm/mach-mx5/system.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
*/

/*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <linux/platform_device.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include "crm_regs.h"

/* set cpu low power mode before WFI instruction. This function is called
* mx5 because it can be used for mx50, mx51, and mx53.*/
void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
{
u32 plat_lpc, arm_srpgcr, ccm_clpcr;
u32 empgc0, empgc1;
int stop_mode = 0;

/* always allow platform to issue a deep sleep mode request */
plat_lpc = __raw_readl(MXC_CORTEXA8_PLAT_LPC) &
~(MXC_CORTEXA8_PLAT_LPC_DSM);
ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);
arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR);
empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR);
empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR);

switch (mode) {
case WAIT_CLOCKED:
break;
case WAIT_UNCLOCKED:
ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
break;
case WAIT_UNCLOCKED_POWER_OFF:
case STOP_POWER_OFF:
plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM
| MXC_CORTEXA8_PLAT_LPC_DBG_DSM;
if (mode == WAIT_UNCLOCKED_POWER_OFF) {
ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
stop_mode = 0;
} else {
ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
stop_mode = 1;
}
arm_srpgcr |= MXC_SRPGCR_PCR;

if (tzic_enable_wake(1) != 0)
return;
break;
case STOP_POWER_ON:
ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
break;
default:
printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
return;
}

__raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC);
__raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
__raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR);

/* Enable NEON SRPG for all but MX50TO1.0. */
if (mx50_revision() != IMX_CHIP_REVISION_1_0)
__raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR);

if (stop_mode) {
empgc0 |= MXC_SRPGCR_PCR;
empgc1 |= MXC_SRPGCR_PCR;

__raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR);
__raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR);
}
}
9 changes: 9 additions & 0 deletions arch/arm/plat-mxc/include/mach/mxc.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,15 @@ struct cpu_op {
u32 cpu_rate;
};

int tzic_enable_wake(int is_idle);
enum mxc_cpu_pwr_mode {
WAIT_CLOCKED, /* wfi only */
WAIT_UNCLOCKED, /* WAIT */
WAIT_UNCLOCKED_POWER_OFF, /* WAIT + SRPG */
STOP_POWER_ON, /* just STOP */
STOP_POWER_OFF, /* STOP + SRPG */
};

extern struct cpu_op *(*get_cpu_op)(int *op);
#endif

Expand Down
6 changes: 5 additions & 1 deletion arch/arm/plat-mxc/include/mach/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <mach/hardware.h>
#include <mach/common.h>

extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);

static inline void arch_idle(void)
{
#ifdef CONFIG_ARCH_MXC91231
Expand Down Expand Up @@ -54,7 +56,9 @@ static inline void arch_idle(void)
"orr %0, %0, #0x00000004\n"
"mcr p15, 0, %0, c1, c0, 0\n"
: "=r" (reg));
} else
} else if (cpu_is_mx51())
mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
else
cpu_do_idle();
}

Expand Down

0 comments on commit 0adf882

Please sign in to comment.