Merge branch 'for-linus' of git://git.selinuxproject.org/~jmorris/linux-security
[pandora-kernel.git] / arch / arm / mach-mx5 / system.c
1 /*
2  * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3  */
4
5 /*
6  * The code contained herein is licensed under the GNU General Public
7  * License. You may obtain a copy of the GNU General Public License
8  * Version 2 or later at the following locations:
9  *
10  * http://www.opensource.org/licenses/gpl-license.html
11  * http://www.gnu.org/copyleft/gpl.html
12  */
13 #include <linux/platform_device.h>
14 #include <linux/io.h>
15 #include <mach/hardware.h>
16 #include <mach/common.h>
17 #include "crm_regs.h"
18
19 /* set cpu low power mode before WFI instruction. This function is called
20   * mx5 because it can be used for mx50, mx51, and mx53.*/
21 void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
22 {
23         u32 plat_lpc, arm_srpgcr, ccm_clpcr;
24         u32 empgc0, empgc1;
25         int stop_mode = 0;
26
27         /* always allow platform to issue a deep sleep mode request */
28         plat_lpc = __raw_readl(MXC_CORTEXA8_PLAT_LPC) &
29             ~(MXC_CORTEXA8_PLAT_LPC_DSM);
30         ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);
31         arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR);
32         empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR);
33         empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR);
34
35         switch (mode) {
36         case WAIT_CLOCKED:
37                 break;
38         case WAIT_UNCLOCKED:
39                 ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
40                 break;
41         case WAIT_UNCLOCKED_POWER_OFF:
42         case STOP_POWER_OFF:
43                 plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM
44                             | MXC_CORTEXA8_PLAT_LPC_DBG_DSM;
45                 if (mode == WAIT_UNCLOCKED_POWER_OFF) {
46                         ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
47                         ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
48                         ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
49                         stop_mode = 0;
50                 } else {
51                         ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
52                         ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
53                         ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
54                         ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
55                         stop_mode = 1;
56                 }
57                 arm_srpgcr |= MXC_SRPGCR_PCR;
58
59                 if (tzic_enable_wake(1) != 0)
60                         return;
61                 break;
62         case STOP_POWER_ON:
63                 ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
64                 break;
65         default:
66                 printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
67                 return;
68         }
69
70         __raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC);
71         __raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
72         __raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR);
73
74         /* Enable NEON SRPG for all but MX50TO1.0. */
75         if (mx50_revision() != IMX_CHIP_REVISION_1_0)
76                 __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR);
77
78         if (stop_mode) {
79                 empgc0 |= MXC_SRPGCR_PCR;
80                 empgc1 |= MXC_SRPGCR_PCR;
81
82                 __raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR);
83                 __raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR);
84         }
85 }