root/arch/arm/mach-mmp/pm-pxa910.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pxa910_set_wake
  2. pxa910_pm_enter_lowpower_mode
  3. pxa910_pm_enter
  4. pxa910_pm_prepare
  5. pxa910_pm_finish
  6. pxa910_pm_valid
  7. pxa910_pm_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * PXA910 Power Management Routines
   4  *
   5  * (C) Copyright 2009 Marvell International Ltd.
   6  * All Rights Reserved
   7  */
   8 
   9 #include <linux/kernel.h>
  10 #include <linux/errno.h>
  11 #include <linux/err.h>
  12 #include <linux/time.h>
  13 #include <linux/delay.h>
  14 #include <linux/suspend.h>
  15 #include <linux/interrupt.h>
  16 #include <linux/io.h>
  17 #include <linux/irq.h>
  18 #include <asm/mach-types.h>
  19 #include <asm/outercache.h>
  20 
  21 #include "cputype.h"
  22 #include "addr-map.h"
  23 #include "pm-pxa910.h"
  24 #include "regs-icu.h"
  25 #include "irqs.h"
  26 
  27 int pxa910_set_wake(struct irq_data *data, unsigned int on)
  28 {
  29         uint32_t awucrm = 0, apcr = 0;
  30         int irq = data->irq;
  31 
  32         /* setting wakeup sources */
  33         switch (irq) {
  34         /* wakeup line 2 */
  35         case IRQ_PXA910_AP_GPIO:
  36                 awucrm = MPMU_AWUCRM_WAKEUP(2);
  37                 apcr |= MPMU_APCR_SLPWP2;
  38                 break;
  39         /* wakeup line 3 */
  40         case IRQ_PXA910_KEYPAD:
  41                 awucrm = MPMU_AWUCRM_WAKEUP(3) | MPMU_AWUCRM_KEYPRESS;
  42                 apcr |= MPMU_APCR_SLPWP3;
  43                 break;
  44         case IRQ_PXA910_ROTARY:
  45                 awucrm = MPMU_AWUCRM_WAKEUP(3) | MPMU_AWUCRM_NEWROTARY;
  46                 apcr |= MPMU_APCR_SLPWP3;
  47                 break;
  48         case IRQ_PXA910_TRACKBALL:
  49                 awucrm = MPMU_AWUCRM_WAKEUP(3) | MPMU_AWUCRM_TRACKBALL;
  50                 apcr |= MPMU_APCR_SLPWP3;
  51                 break;
  52         /* wakeup line 4 */
  53         case IRQ_PXA910_AP1_TIMER1:
  54                 awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP1_TIMER_1;
  55                 apcr |= MPMU_APCR_SLPWP4;
  56                 break;
  57         case IRQ_PXA910_AP1_TIMER2:
  58                 awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP1_TIMER_2;
  59                 apcr |= MPMU_APCR_SLPWP4;
  60                 break;
  61         case IRQ_PXA910_AP1_TIMER3:
  62                 awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP1_TIMER_3;
  63                 apcr |= MPMU_APCR_SLPWP4;
  64                 break;
  65         case IRQ_PXA910_AP2_TIMER1:
  66                 awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP2_TIMER_1;
  67                 apcr |= MPMU_APCR_SLPWP4;
  68                 break;
  69         case IRQ_PXA910_AP2_TIMER2:
  70                 awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP2_TIMER_2;
  71                 apcr |= MPMU_APCR_SLPWP4;
  72                 break;
  73         case IRQ_PXA910_AP2_TIMER3:
  74                 awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP2_TIMER_3;
  75                 apcr |= MPMU_APCR_SLPWP4;
  76                 break;
  77         case IRQ_PXA910_RTC_ALARM:
  78                 awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_RTC_ALARM;
  79                 apcr |= MPMU_APCR_SLPWP4;
  80                 break;
  81         /* wakeup line 5 */
  82         case IRQ_PXA910_USB1:
  83         case IRQ_PXA910_USB2:
  84                 awucrm = MPMU_AWUCRM_WAKEUP(5);
  85                 apcr |= MPMU_APCR_SLPWP5;
  86                 break;
  87         /* wakeup line 6 */
  88         case IRQ_PXA910_MMC:
  89                 awucrm = MPMU_AWUCRM_WAKEUP(6)
  90                         | MPMU_AWUCRM_SDH1
  91                         | MPMU_AWUCRM_SDH2;
  92                 apcr |= MPMU_APCR_SLPWP6;
  93                 break;
  94         /* wakeup line 7 */
  95         case IRQ_PXA910_PMIC_INT:
  96                 awucrm = MPMU_AWUCRM_WAKEUP(7);
  97                 apcr |= MPMU_APCR_SLPWP7;
  98                 break;
  99         default:
 100                 if (irq >= IRQ_GPIO_START && irq < IRQ_BOARD_START) {
 101                         awucrm = MPMU_AWUCRM_WAKEUP(2);
 102                         apcr |= MPMU_APCR_SLPWP2;
 103                 } else {
 104                         /* FIXME: This should return a proper error code ! */
 105                         printk(KERN_ERR "Error: no defined wake up source irq: %d\n",
 106                                 irq);
 107                 }
 108         }
 109 
 110         if (on) {
 111                 if (awucrm) {
 112                         awucrm |= __raw_readl(MPMU_AWUCRM);
 113                         __raw_writel(awucrm, MPMU_AWUCRM);
 114                 }
 115                 if (apcr) {
 116                         apcr = ~apcr & __raw_readl(MPMU_APCR);
 117                         __raw_writel(apcr, MPMU_APCR);
 118                 }
 119         } else {
 120                 if (awucrm) {
 121                         awucrm = ~awucrm & __raw_readl(MPMU_AWUCRM);
 122                         __raw_writel(awucrm, MPMU_AWUCRM);
 123                 }
 124                 if (apcr) {
 125                         apcr |= __raw_readl(MPMU_APCR);
 126                         __raw_writel(apcr, MPMU_APCR);
 127                 }
 128         }
 129         return 0;
 130 }
 131 
 132 void pxa910_pm_enter_lowpower_mode(int state)
 133 {
 134         uint32_t idle_cfg, apcr;
 135 
 136         idle_cfg = __raw_readl(APMU_MOH_IDLE_CFG);
 137         apcr = __raw_readl(MPMU_APCR);
 138 
 139         apcr &= ~(MPMU_APCR_DDRCORSD | MPMU_APCR_APBSD | MPMU_APCR_AXISD
 140                 | MPMU_APCR_VCTCXOSD | MPMU_APCR_STBYEN);
 141         idle_cfg &= ~(APMU_MOH_IDLE_CFG_MOH_IDLE
 142                 | APMU_MOH_IDLE_CFG_MOH_PWRDWN);
 143 
 144         switch (state) {
 145         case POWER_MODE_UDR:
 146                 /* only shutdown APB in UDR */
 147                 apcr |= MPMU_APCR_STBYEN | MPMU_APCR_APBSD;
 148                 /* fall through */
 149         case POWER_MODE_SYS_SLEEP:
 150                 apcr |= MPMU_APCR_SLPEN;                /* set the SLPEN bit */
 151                 apcr |= MPMU_APCR_VCTCXOSD;             /* set VCTCXOSD */
 152                 /* fall through */
 153         case POWER_MODE_APPS_SLEEP:
 154                 apcr |= MPMU_APCR_DDRCORSD;             /* set DDRCORSD */
 155                 /* fall through */
 156         case POWER_MODE_APPS_IDLE:
 157                 apcr |= MPMU_APCR_AXISD;                /* set AXISDD bit */
 158                 /* fall through */
 159         case POWER_MODE_CORE_EXTIDLE:
 160                 idle_cfg |= APMU_MOH_IDLE_CFG_MOH_IDLE;
 161                 idle_cfg |= APMU_MOH_IDLE_CFG_MOH_PWRDWN;
 162                 idle_cfg |= APMU_MOH_IDLE_CFG_MOH_PWR_SW(3)
 163                         | APMU_MOH_IDLE_CFG_MOH_L2_PWR_SW(3);
 164                 /* fall through */
 165         case POWER_MODE_CORE_INTIDLE:
 166                 break;
 167         }
 168 
 169         /* program the memory controller hardware sleep type and auto wakeup */
 170         idle_cfg |= APMU_MOH_IDLE_CFG_MOH_DIS_MC_SW_REQ;
 171         idle_cfg |= APMU_MOH_IDLE_CFG_MOH_MC_WAKE_EN;
 172         __raw_writel(0x0, APMU_MC_HW_SLP_TYPE);         /* auto refresh */
 173 
 174         /* set DSPSD, DTCMSD, BBSD, MSASLPEN */
 175         apcr |= MPMU_APCR_DSPSD | MPMU_APCR_DTCMSD | MPMU_APCR_BBSD
 176                 | MPMU_APCR_MSASLPEN;
 177 
 178         /*always set SLEPEN bit mainly for MSA*/
 179         apcr |= MPMU_APCR_SLPEN;
 180 
 181         /* finally write the registers back */
 182         __raw_writel(idle_cfg, APMU_MOH_IDLE_CFG);
 183         __raw_writel(apcr, MPMU_APCR);
 184 
 185 }
 186 
 187 static int pxa910_pm_enter(suspend_state_t state)
 188 {
 189         unsigned int idle_cfg, reg = 0;
 190 
 191         /*pmic thread not completed,exit;otherwise system can't be waked up*/
 192         reg = __raw_readl(ICU_INT_CONF(IRQ_PXA910_PMIC_INT));
 193         if ((reg & 0x3) == 0)
 194                 return -EAGAIN;
 195 
 196         idle_cfg = __raw_readl(APMU_MOH_IDLE_CFG);
 197         idle_cfg |= APMU_MOH_IDLE_CFG_MOH_PWRDWN
 198                 | APMU_MOH_IDLE_CFG_MOH_SRAM_PWRDWN;
 199         __raw_writel(idle_cfg, APMU_MOH_IDLE_CFG);
 200 
 201         /* disable L2 */
 202         outer_disable();
 203         /* wait for l2 idle */
 204         while (!(readl(CIU_REG(0x8)) & (1 << 16)))
 205                 udelay(1);
 206 
 207         cpu_do_idle();
 208 
 209         /* enable L2 */
 210         outer_resume();
 211         /* wait for l2 idle */
 212         while (!(readl(CIU_REG(0x8)) & (1 << 16)))
 213                 udelay(1);
 214 
 215         idle_cfg = __raw_readl(APMU_MOH_IDLE_CFG);
 216         idle_cfg &= ~(APMU_MOH_IDLE_CFG_MOH_PWRDWN
 217                 | APMU_MOH_IDLE_CFG_MOH_SRAM_PWRDWN);
 218         __raw_writel(idle_cfg, APMU_MOH_IDLE_CFG);
 219 
 220         return 0;
 221 }
 222 
 223 /*
 224  * Called after processes are frozen, but before we shut down devices.
 225  */
 226 static int pxa910_pm_prepare(void)
 227 {
 228         pxa910_pm_enter_lowpower_mode(POWER_MODE_UDR);
 229         return 0;
 230 }
 231 
 232 /*
 233  * Called after devices are re-setup, but before processes are thawed.
 234  */
 235 static void pxa910_pm_finish(void)
 236 {
 237         pxa910_pm_enter_lowpower_mode(POWER_MODE_CORE_INTIDLE);
 238 }
 239 
 240 static int pxa910_pm_valid(suspend_state_t state)
 241 {
 242         return ((state == PM_SUSPEND_STANDBY) || (state == PM_SUSPEND_MEM));
 243 }
 244 
 245 static const struct platform_suspend_ops pxa910_pm_ops = {
 246         .valid          = pxa910_pm_valid,
 247         .prepare        = pxa910_pm_prepare,
 248         .enter          = pxa910_pm_enter,
 249         .finish         = pxa910_pm_finish,
 250 };
 251 
 252 static int __init pxa910_pm_init(void)
 253 {
 254         uint32_t awucrm = 0;
 255 
 256         if (!cpu_is_pxa910())
 257                 return -EIO;
 258 
 259         suspend_set_ops(&pxa910_pm_ops);
 260 
 261         /* Set the following bits for MMP3 playback with VCTXO on */
 262         __raw_writel(__raw_readl(APMU_SQU_CLK_GATE_CTRL) | (1 << 30),
 263                 APMU_SQU_CLK_GATE_CTRL);
 264         __raw_writel(__raw_readl(MPMU_FCCR) | (1 << 28), MPMU_FCCR);
 265 
 266         awucrm |= MPMU_AWUCRM_AP_ASYNC_INT | MPMU_AWUCRM_AP_FULL_IDLE;
 267         __raw_writel(awucrm, MPMU_AWUCRM);
 268 
 269         return 0;
 270 }
 271 
 272 late_initcall(pxa910_pm_init);

/* [<][>][^][v][top][bottom][index][help] */