Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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);