^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * linux/arch/arm/mach-omap1/pm.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * OMAP Power Management Routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Original code for the SA11x0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Modified for the PXA250 by Nicolas Pitre:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (c) 2002 Monta Vista Software, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Modified for the OMAP1510 by David Singleton:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright (c) 2002 Monta Vista Software, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * This program is free software; you can redistribute it and/or modify it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * under the terms of the GNU General Public License as published by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Free Software Foundation; either version 2 of the License, or (at your
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * You should have received a copy of the GNU General Public License along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * with this program; if not, write to the Free Software Foundation, Inc.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * 675 Mass Ave, Cambridge, MA 02139, USA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/suspend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <asm/fncpy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <asm/system_misc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <asm/mach/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <asm/mach/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <mach/tc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <mach/mux.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <linux/omap-dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <clocksource/timer-ti-dm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <mach/irqs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include "iomap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include "clock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include "pm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include "soc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include "sram.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static unsigned short dsp_sleep_save[DSP_SLEEP_SAVE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static unsigned int mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static unsigned short enable_dyn_sleep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return sprintf(buf, "%hu\n", enable_dyn_sleep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static ssize_t idle_store(struct kobject *kobj, struct kobj_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) const char * buf, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned short value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (sscanf(buf, "%hu", &value) != 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) (value != 0 && value != 1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) (value != 0 && !IS_ENABLED(CONFIG_OMAP_32K_TIMER))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) pr_err("idle_sleep_store: Invalid value\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) enable_dyn_sleep = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static struct kobj_attribute sleep_while_idle_attr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) __ATTR(sleep_while_idle, 0644, idle_show, idle_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * Let's power down on idle, but only if we are really
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * idle, because once we start down the path of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * going idle we continue to do idle even if we get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * a clock tick interrupt . .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) void omap1_pm_idle(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) extern __u32 arm_idlect1_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) __u32 use_idlect1 = arm_idlect1_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) local_fiq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #if defined(CONFIG_OMAP_MPU_TIMER) && !defined(CONFIG_OMAP_DM_TIMER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) use_idlect1 = use_idlect1 & ~(1 << 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #ifdef CONFIG_OMAP_DM_TIMER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (omap_dma_running())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) use_idlect1 &= ~(1 << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * We should be able to remove the do_sleep variable and multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * tests above as soon as drivers, timer and DMA code have been fixed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * Even the sleep block count should become obsolete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if ((use_idlect1 != ~0) || !enable_dyn_sleep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) __u32 saved_idlect1 = omap_readl(ARM_IDLECT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (cpu_is_omap15xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) use_idlect1 &= OMAP1510_BIG_SLEEP_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) use_idlect1 &= OMAP1610_IDLECT1_SLEEP_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) omap_writel(use_idlect1, ARM_IDLECT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) omap_writel(saved_idlect1, ARM_IDLECT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) local_fiq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) omap_sram_suspend(omap_readl(ARM_IDLECT1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) omap_readl(ARM_IDLECT2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) local_fiq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * Configuration of the wakeup event is board specific. For the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * moment we put it into this helper function. Later it may move
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * to board specific files.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static void omap_pm_wakeup_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u32 level1_wake = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * and the L2 wakeup interrupts: keypad and UART2. Note that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * drivers must still separately call omap_set_gpio_wakeup() to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * wake up to a GPIO interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (cpu_is_omap7xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) level1_wake = OMAP_IRQ_BIT(INT_7XX_GPIO_BANK1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) OMAP_IRQ_BIT(INT_7XX_IH2_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) else if (cpu_is_omap15xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) else if (cpu_is_omap16xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) omap_writel(~level1_wake, OMAP_IH1_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (cpu_is_omap7xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) omap_writel(~level2_wake, OMAP_IH2_0_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) omap_writel(~(OMAP_IRQ_BIT(INT_7XX_WAKE_UP_REQ) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) OMAP_IRQ_BIT(INT_7XX_MPUIO_KEYPAD)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) OMAP_IH2_1_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) } else if (cpu_is_omap15xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) omap_writel(~level2_wake, OMAP_IH2_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) } else if (cpu_is_omap16xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) omap_writel(~level2_wake, OMAP_IH2_0_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) OMAP_IH2_1_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) omap_writel(~0x0, OMAP_IH2_2_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) omap_writel(~0x0, OMAP_IH2_3_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* New IRQ agreement, recalculate in cascade order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) omap_writel(1, OMAP_IH2_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) omap_writel(1, OMAP_IH1_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define EN_DSPCK 13 /* ARM_CKCTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define EN_APICK 6 /* ARM_IDLECT2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define DSP_EN 1 /* ARM_RSTCT1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) void omap1_pm_suspend(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) unsigned long arg0 = 0, arg1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) printk(KERN_INFO "PM: OMAP%x is trying to enter deep sleep...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) omap_rev());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) omap_serial_wake_trigger(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (!cpu_is_omap15xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * Step 1: turn off interrupts (FIXME: NOTE: already disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) local_fiq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * Step 2: save registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * The omap is a strange/beautiful device. The caches, memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * and register state are preserved across power saves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * We have to save and restore very little register state to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * idle the omap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * Save interrupt, MPUI, ARM and UPLD control registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (cpu_is_omap7xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) MPUI7XX_SAVE(OMAP_IH1_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) MPUI7XX_SAVE(OMAP_IH2_0_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) MPUI7XX_SAVE(OMAP_IH2_1_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) MPUI7XX_SAVE(MPUI_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) MPUI7XX_SAVE(MPUI_DSP_BOOT_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) MPUI7XX_SAVE(MPUI_DSP_API_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) MPUI7XX_SAVE(EMIFS_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) MPUI7XX_SAVE(EMIFF_SDRAM_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) } else if (cpu_is_omap15xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) MPUI1510_SAVE(OMAP_IH1_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) MPUI1510_SAVE(OMAP_IH2_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) MPUI1510_SAVE(MPUI_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) MPUI1510_SAVE(EMIFS_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) } else if (cpu_is_omap16xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) MPUI1610_SAVE(OMAP_IH1_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) MPUI1610_SAVE(OMAP_IH2_0_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) MPUI1610_SAVE(OMAP_IH2_1_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) MPUI1610_SAVE(OMAP_IH2_2_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) MPUI1610_SAVE(OMAP_IH2_3_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) MPUI1610_SAVE(MPUI_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) MPUI1610_SAVE(EMIFS_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ARM_SAVE(ARM_CKCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ARM_SAVE(ARM_IDLECT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ARM_SAVE(ARM_IDLECT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (!(cpu_is_omap15xx()))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ARM_SAVE(ARM_IDLECT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ARM_SAVE(ARM_EWUPCT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ARM_SAVE(ARM_RSTCT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ARM_SAVE(ARM_RSTCT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ARM_SAVE(ARM_SYSST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ULPD_SAVE(ULPD_CLOCK_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ULPD_SAVE(ULPD_STATUS_REQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* (Step 3 removed - we now allow deep sleep by default) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * Step 4: OMAP DSP Shutdown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* stop DSP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* shut down dsp_ck */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (!cpu_is_omap7xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /* temporarily enabling api_ck to access DSP registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* save DSP registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) DSP_SAVE(DSP_IDLECT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* Stop all DSP domain clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) __raw_writew(0, DSP_IDLECT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * Step 5: Wakeup Event Setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) omap_pm_wakeup_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * Step 6: ARM and Traffic controller shutdown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* disable ARM watchdog */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * Step 6b: ARM and Traffic controller shutdown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * Step 6 continues here. Prepare jump to power management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * assembly code in internal SRAM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * Since the omap_cpu_suspend routine has been copied to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * SRAM, we'll do an indirect procedure call to it and pass the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * contents of arm_idlect1 and arm_idlect2 so it can restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * them when it wakes up and it will return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * Step 6c: ARM and Traffic controller shutdown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * Jump to assembly code. The processor will stay there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * until wake up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) omap_sram_suspend(arg0, arg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * If we are here, processor is woken up!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * Restore DSP clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /* again temporarily enabling api_ck to access DSP registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* Restore DSP domain clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) DSP_RESTORE(DSP_IDLECT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (!(cpu_is_omap15xx()))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ARM_RESTORE(ARM_IDLECT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) ARM_RESTORE(ARM_CKCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ARM_RESTORE(ARM_EWUPCT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ARM_RESTORE(ARM_RSTCT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ARM_RESTORE(ARM_RSTCT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ARM_RESTORE(ARM_SYSST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ULPD_RESTORE(ULPD_CLOCK_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ULPD_RESTORE(ULPD_STATUS_REQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (cpu_is_omap7xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) MPUI7XX_RESTORE(EMIFS_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) MPUI7XX_RESTORE(EMIFF_SDRAM_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) MPUI7XX_RESTORE(OMAP_IH1_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) MPUI7XX_RESTORE(OMAP_IH2_0_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) MPUI7XX_RESTORE(OMAP_IH2_1_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) } else if (cpu_is_omap15xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) MPUI1510_RESTORE(MPUI_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) MPUI1510_RESTORE(EMIFS_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) MPUI1510_RESTORE(OMAP_IH1_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) MPUI1510_RESTORE(OMAP_IH2_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) } else if (cpu_is_omap16xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) MPUI1610_RESTORE(MPUI_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) MPUI1610_RESTORE(EMIFS_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) MPUI1610_RESTORE(OMAP_IH1_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) MPUI1610_RESTORE(OMAP_IH2_0_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) MPUI1610_RESTORE(OMAP_IH2_1_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) MPUI1610_RESTORE(OMAP_IH2_2_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) MPUI1610_RESTORE(OMAP_IH2_3_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (!cpu_is_omap15xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * Re-enable interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) local_fiq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) omap_serial_wake_trigger(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) printk(KERN_INFO "PM: OMAP%x is re-starting from deep sleep...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) omap_rev());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * Read system PM registers for debugging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static int omap_pm_debug_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ARM_SAVE(ARM_CKCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ARM_SAVE(ARM_IDLECT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ARM_SAVE(ARM_IDLECT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (!(cpu_is_omap15xx()))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ARM_SAVE(ARM_IDLECT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ARM_SAVE(ARM_EWUPCT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ARM_SAVE(ARM_RSTCT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ARM_SAVE(ARM_RSTCT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ARM_SAVE(ARM_SYSST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ULPD_SAVE(ULPD_IT_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) ULPD_SAVE(ULPD_CLOCK_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ULPD_SAVE(ULPD_SOFT_REQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ULPD_SAVE(ULPD_STATUS_REQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ULPD_SAVE(ULPD_DPLL_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ULPD_SAVE(ULPD_POWER_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (cpu_is_omap7xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) MPUI7XX_SAVE(MPUI_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) MPUI7XX_SAVE(MPUI_DSP_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) MPUI7XX_SAVE(MPUI_DSP_BOOT_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) MPUI7XX_SAVE(MPUI_DSP_API_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) MPUI7XX_SAVE(EMIFF_SDRAM_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) MPUI7XX_SAVE(EMIFS_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) } else if (cpu_is_omap15xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) MPUI1510_SAVE(MPUI_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) MPUI1510_SAVE(MPUI_DSP_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) MPUI1510_SAVE(EMIFS_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) } else if (cpu_is_omap16xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) MPUI1610_SAVE(MPUI_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) MPUI1610_SAVE(MPUI_DSP_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) MPUI1610_SAVE(EMIFS_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) "ARM_CKCTL_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) "ARM_IDLECT1_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) "ARM_IDLECT2_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) "ARM_IDLECT3_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) "ARM_EWUPCT_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) "ARM_RSTCT1_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) "ARM_RSTCT2_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) "ARM_SYSST_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) "ULPD_IT_STATUS_REG: 0x%-4x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) "ULPD_CLOCK_CTRL_REG: 0x%-4x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) "ULPD_SOFT_REQ_REG: 0x%-4x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) "ULPD_DPLL_CTRL_REG: 0x%-4x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) "ULPD_STATUS_REQ_REG: 0x%-4x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) "ULPD_POWER_CTRL_REG: 0x%-4x \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ARM_SHOW(ARM_CKCTL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ARM_SHOW(ARM_IDLECT1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ARM_SHOW(ARM_IDLECT2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ARM_SHOW(ARM_IDLECT3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ARM_SHOW(ARM_EWUPCT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ARM_SHOW(ARM_RSTCT1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ARM_SHOW(ARM_RSTCT2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ARM_SHOW(ARM_SYSST),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) ULPD_SHOW(ULPD_IT_STATUS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ULPD_SHOW(ULPD_CLOCK_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) ULPD_SHOW(ULPD_SOFT_REQ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) ULPD_SHOW(ULPD_DPLL_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ULPD_SHOW(ULPD_STATUS_REQ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ULPD_SHOW(ULPD_POWER_CTRL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (cpu_is_omap7xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) "MPUI7XX_CTRL_REG 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) "MPUI7XX_DSP_STATUS_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) "MPUI7XX_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) "MPUI7XX_DSP_API_CONFIG_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) "MPUI7XX_SDRAM_CONFIG_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) "MPUI7XX_EMIFS_CONFIG_REG: 0x%-8x \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) MPUI7XX_SHOW(MPUI_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) MPUI7XX_SHOW(MPUI_DSP_STATUS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) MPUI7XX_SHOW(MPUI_DSP_BOOT_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) MPUI7XX_SHOW(MPUI_DSP_API_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) MPUI7XX_SHOW(EMIFF_SDRAM_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) MPUI7XX_SHOW(EMIFS_CONFIG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) } else if (cpu_is_omap15xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) "MPUI1510_CTRL_REG 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) "MPUI1510_DSP_STATUS_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) "MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) "MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) "MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) MPUI1510_SHOW(MPUI_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) MPUI1510_SHOW(MPUI_DSP_STATUS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) MPUI1510_SHOW(EMIFS_CONFIG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) } else if (cpu_is_omap16xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) "MPUI1610_CTRL_REG 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) "MPUI1610_DSP_STATUS_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) "MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) "MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) "MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) MPUI1610_SHOW(MPUI_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) MPUI1610_SHOW(MPUI_DSP_STATUS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) MPUI1610_SHOW(EMIFS_CONFIG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) DEFINE_SHOW_ATTRIBUTE(omap_pm_debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) static void omap_pm_init_debugfs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct dentry *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) d = debugfs_create_dir("pm_debug", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) debugfs_create_file("omap_pm", S_IWUSR | S_IRUGO, d, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) &omap_pm_debug_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) #endif /* CONFIG_DEBUG_FS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * omap_pm_prepare - Do preliminary suspend work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static int omap_pm_prepare(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /* We cannot sleep in idle until we have resumed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) cpu_idle_poll_ctrl(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * omap_pm_enter - Actually enter a sleep state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * @state: State we're entering.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static int omap_pm_enter(suspend_state_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) switch (state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) case PM_SUSPEND_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) omap1_pm_suspend();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * omap_pm_finish - Finish up suspend sequence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * This is called after we wake back up (or if entering the sleep state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * failed).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static void omap_pm_finish(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) cpu_idle_poll_ctrl(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static irqreturn_t omap_wakeup_interrupt(int irq, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static const struct platform_suspend_ops omap_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) .prepare = omap_pm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) .enter = omap_pm_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) .finish = omap_pm_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) .valid = suspend_valid_only_mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static int __init omap_pm_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (!cpu_class_is_omap1())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) pr_info("Power Management for TI OMAP.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (!IS_ENABLED(CONFIG_OMAP_32K_TIMER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) pr_info("OMAP1 PM: sleep states in idle disabled due to no 32KiHz timer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (!IS_ENABLED(CONFIG_OMAP_DM_TIMER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) pr_info("OMAP1 PM: sleep states in idle disabled due to no DMTIMER support\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (IS_ENABLED(CONFIG_OMAP_32K_TIMER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) IS_ENABLED(CONFIG_OMAP_DM_TIMER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /* OMAP16xx only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) pr_info("OMAP1 PM: sleep states in idle enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) enable_dyn_sleep = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * We copy the assembler sleep/wakeup routines to SRAM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * These routines need to be in SRAM as that's the only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) * memory the MPU can see when it wakes up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (cpu_is_omap7xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) omap_sram_suspend = omap_sram_push(omap7xx_cpu_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) omap7xx_cpu_suspend_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) } else if (cpu_is_omap15xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) omap1510_cpu_suspend_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) } else if (cpu_is_omap16xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) omap1610_cpu_suspend_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (omap_sram_suspend == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) printk(KERN_ERR "PM not initialized: Missing SRAM support\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) arm_pm_idle = omap1_pm_idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (cpu_is_omap7xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) irq = INT_7XX_WAKE_UP_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) else if (cpu_is_omap16xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) irq = INT_1610_WAKE_UP_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (irq >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (request_irq(irq, omap_wakeup_interrupt, 0, "peripheral wakeup", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) pr_err("Failed to request irq %d (peripheral wakeup)\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* Program new power ramp-up time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * (0 for most boards since we don't lower voltage when in deep sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) /* Configure IDLECT3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (cpu_is_omap7xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) omap_writel(OMAP7XX_IDLECT3_VAL, OMAP7XX_IDLECT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) else if (cpu_is_omap16xx())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) suspend_set_ops(&omap_pm_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) omap_pm_init_debugfs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) error = sysfs_create_file(power_kobj, &sleep_while_idle_attr.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (cpu_is_omap16xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /* configure LOW_PWR pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) omap_cfg_reg(T20_1610_LOW_PWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) __initcall(omap_pm_init);