/* * linux/arch/arm/mach-omap1/pm.c * * OMAP Power Management Routines * * Original code for the SA11x0: * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> * * Modified for the PXA250 by Nicolas Pitre: * Copyright (c) 2002 Monta Vista Software, Inc. * * Modified for the OMAP1510 by David Singleton: * Copyright (c) 2002 Monta Vista Software, Inc. * * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* * Let's power down on idle, but only if we are really * idle, because once we start down the path of * going idle we continue to do idle even if we get * a clock tick interrupt . .
*/ void omap1_pm_idle(void)
{ extern __u32 arm_idlect1_mask;
__u32 use_idlect1 = arm_idlect1_mask;
/* * We should be able to remove the do_sleep variable and multiple * tests above as soon as drivers, timer and DMA code have been fixed. * Even the sleep block count should become obsolete.
*/ if ((use_idlect1 != ~0) || !enable_dyn_sleep) {
/* * Configuration of the wakeup event is board specific. For the * moment we put it into this helper function. Later it may move * to board specific files.
*/ staticvoid omap_pm_wakeup_setup(void)
{
u32 level1_wake = 0;
u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
/* * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade, * and the L2 wakeup interrupts: keypad and UART2. Note that the * drivers must still separately call omap_set_gpio_wakeup() to * wake up to a GPIO interrupt.
*/ if (cpu_is_omap15xx())
level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
OMAP_IRQ_BIT(INT_1510_IH2_IRQ); elseif (cpu_is_omap16xx())
level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
/* * Step 2: save registers * * The omap is a strange/beautiful device. The caches, memory * and register state are preserved across power saves. * We have to save and restore very little register state to * idle the omap. * * Save interrupt, MPUI, ARM and UPLD control registers.
*/
/* Stop all DSP domain clocks */
__raw_writew(0, DSP_IDLECT2);
/* * Step 5: Wakeup Event Setup
*/
omap_pm_wakeup_setup();
/* * Step 6: ARM and Traffic controller shutdown
*/
/* disable ARM watchdog */
omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
/* * Step 6b: ARM and Traffic controller shutdown * * Step 6 continues here. Prepare jump to power management * assembly code in internal SRAM. * * Since the omap_cpu_suspend routine has been copied to * SRAM, we'll do an indirect procedure call to it and pass the * contents of arm_idlect1 and arm_idlect2 so it can restore * them when it wakes up and it will return.
*/
/* * Step 6c: ARM and Traffic controller shutdown * * Jump to assembly code. The processor will stay there * until wake up.
*/
omap_sram_suspend(arg0, arg1);
/* * If we are here, processor is woken up!
*/
/* * Restore DSP clocks
*/
/* again temporarily enabling api_ck to access DSP registers */
omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
/* * omap_pm_prepare - Do preliminary suspend work. *
*/ staticint omap_pm_prepare(void)
{ /* We cannot sleep in idle until we have resumed */
cpu_idle_poll_ctrl(true); return 0;
}
/* * omap_pm_enter - Actually enter a sleep state. * @state: State we're entering. *
*/
staticint __init omap_pm_init(void)
{ int error = 0; int irq;
if (!cpu_class_is_omap1()) return -ENODEV;
pr_info("Power Management for TI OMAP.\n");
if (!IS_ENABLED(CONFIG_OMAP_32K_TIMER))
pr_info("OMAP1 PM: sleep states in idle disabled due to no 32KiHz timer\n");
if (!IS_ENABLED(CONFIG_OMAP_DM_TIMER))
pr_info("OMAP1 PM: sleep states in idle disabled due to no DMTIMER support\n");
if (IS_ENABLED(CONFIG_OMAP_32K_TIMER) &&
IS_ENABLED(CONFIG_OMAP_DM_TIMER)) { /* OMAP16xx only */
pr_info("OMAP1 PM: sleep states in idle enabled\n");
enable_dyn_sleep = 1;
}
/* * We copy the assembler sleep/wakeup routines to SRAM. * These routines need to be in SRAM as that's the only * memory the MPU can see when it wakes up.
*/ if (cpu_is_omap15xx()) {
omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
omap1510_cpu_suspend_sz);
} elseif (cpu_is_omap16xx()) {
omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend,
omap1610_cpu_suspend_sz);
}
if (omap_sram_suspend == NULL) {
printk(KERN_ERR "PM not initialized: Missing SRAM support\n"); return -ENODEV;
}
arm_pm_idle = omap1_pm_idle;
if (cpu_is_omap16xx())
irq = INT_1610_WAKE_UP_REQ; else
irq = -1;
if (irq >= 0) { if (request_irq(irq, omap_wakeup_interrupt, 0, "peripheral wakeup", NULL))
pr_err("Failed to request irq %d (peripheral wakeup)\n", irq);
}
/* Program new power ramp-up time * (0 for most boards since we don't lower voltage when in deep sleep)
*/
omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3);
/* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */
omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
/* Configure IDLECT3 */ if (cpu_is_omap16xx())
omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.