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