Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pm-pxa910.c
Go to the documentation of this file.
1 /*
2  * PXA910 Power Management Routines
3  *
4  * This software program is licensed subject to the GNU General Public License
5  * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
6  *
7  * (C) Copyright 2009 Marvell International Ltd.
8  * All Rights Reserved
9  */
10 
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/err.h>
14 #include <linux/time.h>
15 #include <linux/delay.h>
16 #include <linux/suspend.h>
17 #include <linux/interrupt.h>
18 #include <linux/io.h>
19 #include <linux/irq.h>
20 #include <asm/mach-types.h>
21 #include <mach/hardware.h>
22 #include <mach/cputype.h>
23 #include <mach/addr-map.h>
24 #include <mach/pm-pxa910.h>
25 #include <mach/regs-icu.h>
26 #include <mach/irqs.h>
27 
28 int pxa910_set_wake(struct irq_data *data, unsigned int on)
29 {
30  int irq = data->irq;
31  struct irq_desc *desc = irq_to_desc(data->irq);
32  uint32_t awucrm = 0, apcr = 0;
33 
34  if (unlikely(irq >= nr_irqs)) {
35  pr_err("IRQ nubmers are out of boundary!\n");
36  return -EINVAL;
37  }
38 
39  if (on) {
40  if (desc->action)
41  desc->action->flags |= IRQF_NO_SUSPEND;
42  } else {
43  if (desc->action)
44  desc->action->flags &= ~IRQF_NO_SUSPEND;
45  }
46 
47  /* setting wakeup sources */
48  switch (irq) {
49  /* wakeup line 2 */
50  case IRQ_PXA910_AP_GPIO:
51  awucrm = MPMU_AWUCRM_WAKEUP(2);
52  apcr |= MPMU_APCR_SLPWP2;
53  break;
54  /* wakeup line 3 */
55  case IRQ_PXA910_KEYPAD:
57  apcr |= MPMU_APCR_SLPWP3;
58  break;
59  case IRQ_PXA910_ROTARY:
61  apcr |= MPMU_APCR_SLPWP3;
62  break;
65  apcr |= MPMU_APCR_SLPWP3;
66  break;
67  /* wakeup line 4 */
70  apcr |= MPMU_APCR_SLPWP4;
71  break;
74  apcr |= MPMU_APCR_SLPWP4;
75  break;
78  apcr |= MPMU_APCR_SLPWP4;
79  break;
82  apcr |= MPMU_APCR_SLPWP4;
83  break;
86  apcr |= MPMU_APCR_SLPWP4;
87  break;
90  apcr |= MPMU_APCR_SLPWP4;
91  break;
94  apcr |= MPMU_APCR_SLPWP4;
95  break;
96  /* wakeup line 5 */
97  case IRQ_PXA910_USB1:
98  case IRQ_PXA910_USB2:
99  awucrm = MPMU_AWUCRM_WAKEUP(5);
100  apcr |= MPMU_APCR_SLPWP5;
101  break;
102  /* wakeup line 6 */
103  case IRQ_PXA910_MMC:
104  awucrm = MPMU_AWUCRM_WAKEUP(6)
107  apcr |= MPMU_APCR_SLPWP6;
108  break;
109  /* wakeup line 7 */
110  case IRQ_PXA910_PMIC_INT:
111  awucrm = MPMU_AWUCRM_WAKEUP(7);
112  apcr |= MPMU_APCR_SLPWP7;
113  break;
114  default:
115  if (irq >= IRQ_GPIO_START && irq < IRQ_BOARD_START) {
116  awucrm = MPMU_AWUCRM_WAKEUP(2);
117  apcr |= MPMU_APCR_SLPWP2;
118  } else
119  printk(KERN_ERR "Error: no defined wake up source irq: %d\n",
120  irq);
121  }
122 
123  if (on) {
124  if (awucrm) {
125  awucrm |= __raw_readl(MPMU_AWUCRM);
126  __raw_writel(awucrm, MPMU_AWUCRM);
127  }
128  if (apcr) {
129  apcr = ~apcr & __raw_readl(MPMU_APCR);
130  __raw_writel(apcr, MPMU_APCR);
131  }
132  } else {
133  if (awucrm) {
134  awucrm = ~awucrm & __raw_readl(MPMU_AWUCRM);
135  __raw_writel(awucrm, MPMU_AWUCRM);
136  }
137  if (apcr) {
138  apcr |= __raw_readl(MPMU_APCR);
139  __raw_writel(apcr, MPMU_APCR);
140  }
141  }
142  return 0;
143 }
144 
146 {
147  uint32_t idle_cfg, apcr;
148 
149  idle_cfg = __raw_readl(APMU_MOH_IDLE_CFG);
150  apcr = __raw_readl(MPMU_APCR);
151 
154  idle_cfg &= ~(APMU_MOH_IDLE_CFG_MOH_IDLE
156 
157  switch (state) {
158  case POWER_MODE_UDR:
159  /* only shutdown APB in UDR */
161  /* fall through */
163  apcr |= MPMU_APCR_SLPEN; /* set the SLPEN bit */
164  apcr |= MPMU_APCR_VCTCXOSD; /* set VCTCXOSD */
165  /* fall through */
167  apcr |= MPMU_APCR_DDRCORSD; /* set DDRCORSD */
168  /* fall through */
170  apcr |= MPMU_APCR_AXISD; /* set AXISDD bit */
171  /* fall through */
173  idle_cfg |= APMU_MOH_IDLE_CFG_MOH_IDLE;
174  idle_cfg |= APMU_MOH_IDLE_CFG_MOH_PWRDWN;
175  idle_cfg |= APMU_MOH_IDLE_CFG_MOH_PWR_SW(3)
177  /* fall through */
179  break;
180  }
181 
182  /* program the memory controller hardware sleep type and auto wakeup */
185  __raw_writel(0x0, APMU_MC_HW_SLP_TYPE); /* auto refresh */
186 
187  /* set DSPSD, DTCMSD, BBSD, MSASLPEN */
190 
191  /*always set SLEPEN bit mainly for MSA*/
192  apcr |= MPMU_APCR_SLPEN;
193 
194  /* finally write the registers back */
195  __raw_writel(idle_cfg, APMU_MOH_IDLE_CFG);
196  __raw_writel(apcr, MPMU_APCR);
197 
198 }
199 
200 static int pxa910_pm_enter(suspend_state_t state)
201 {
202  unsigned int idle_cfg, reg = 0;
203 
204  /*pmic thread not completed,exit;otherwise system can't be waked up*/
206  if ((reg & 0x3) == 0)
207  return -EAGAIN;
208 
209  idle_cfg = __raw_readl(APMU_MOH_IDLE_CFG);
210  idle_cfg |= APMU_MOH_IDLE_CFG_MOH_PWRDWN
212  __raw_writel(idle_cfg, APMU_MOH_IDLE_CFG);
213 
214  /* disable L2 */
215  outer_disable();
216  /* wait for l2 idle */
217  while (!(readl(CIU_REG(0x8)) & (1 << 16)))
218  udelay(1);
219 
220  cpu_do_idle();
221 
222  /* enable L2 */
223  outer_resume();
224  /* wait for l2 idle */
225  while (!(readl(CIU_REG(0x8)) & (1 << 16)))
226  udelay(1);
227 
228  idle_cfg = __raw_readl(APMU_MOH_IDLE_CFG);
229  idle_cfg &= ~(APMU_MOH_IDLE_CFG_MOH_PWRDWN
231  __raw_writel(idle_cfg, APMU_MOH_IDLE_CFG);
232 
233  return 0;
234 }
235 
236 /*
237  * Called after processes are frozen, but before we shut down devices.
238  */
239 static int pxa910_pm_prepare(void)
240 {
242  return 0;
243 }
244 
245 /*
246  * Called after devices are re-setup, but before processes are thawed.
247  */
248 static void pxa910_pm_finish(void)
249 {
251 }
252 
253 static int pxa910_pm_valid(suspend_state_t state)
254 {
255  return ((state == PM_SUSPEND_STANDBY) || (state == PM_SUSPEND_MEM));
256 }
257 
258 static const struct platform_suspend_ops pxa910_pm_ops = {
259  .valid = pxa910_pm_valid,
260  .prepare = pxa910_pm_prepare,
261  .enter = pxa910_pm_enter,
262  .finish = pxa910_pm_finish,
263 };
264 
265 static int __init pxa910_pm_init(void)
266 {
267  uint32_t awucrm = 0;
268 
269  if (!cpu_is_pxa910())
270  return -EIO;
271 
272  suspend_set_ops(&pxa910_pm_ops);
273 
274  /* Set the following bits for MMP3 playback with VCTXO on */
278 
280  __raw_writel(awucrm, MPMU_AWUCRM);
281 
282  return 0;
283 }
284 
285 late_initcall(pxa910_pm_init);