Merge branch 'misc' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6
[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 "crm_regs.h"
17
18 /* set cpu low power mode before WFI instruction. This function is called
19   * mx5 because it can be used for mx50, mx51, and mx53.*/
20 void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
21 {
22         u32 plat_lpc, arm_srpgcr, ccm_clpcr;
23         u32 empgc0, empgc1;
24         int stop_mode = 0;
25
26         /* always allow platform to issue a deep sleep mode request */
27         plat_lpc = __raw_readl(MXC_CORTEXA8_PLAT_LPC) &
28             ~(MXC_CORTEXA8_PLAT_LPC_DSM);
29         ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);
30         arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR);
31         empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR);
32         empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR);
33
34         switch (mode) {
35         case WAIT_CLOCKED:
36                 break;
37         case WAIT_UNCLOCKED:
38                 ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
39                 break;
40         case WAIT_UNCLOCKED_POWER_OFF:
41         case STOP_POWER_OFF:
42                 plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM
43                             | MXC_CORTEXA8_PLAT_LPC_DBG_DSM;
44                 if (mode == WAIT_UNCLOCKED_POWER_OFF) {
45                         ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
46                         ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
47                         ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
48                         stop_mode = 0;
49                 } else {
50                         ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
51                         ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
52                         ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
53                         ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
54                         stop_mode = 1;
55                 }
56                 arm_srpgcr |= MXC_SRPGCR_PCR;
57
58                 if (tzic_enable_wake(1) != 0)
59                         return;
60                 break;
61         case STOP_POWER_ON:
62                 ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
63                 break;
64         default:
65                 printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
66                 return;
67         }
68
69         __raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC);
70         __raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
71         __raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR);
72
73         /* Enable NEON SRPG for all but MX50TO1.0. */
74         if (mx50_revision() != IMX_CHIP_REVISION_1_0)
75                 __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR);
76
77         if (stop_mode) {
78                 empgc0 |= MXC_SRPGCR_PCR;
79                 empgc1 |= MXC_SRPGCR_PCR;
80
81                 __raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR);
82                 __raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR);
83         }
84 }