Commit 8bd22949 authored by Kevin Hilman's avatar Kevin Hilman

OMAP2/3: PM: push core PM code from linux-omap

This patch is to sync the core linux-omap PM code with mainline.  This
code has evolved and been used for a while the linux-omap tree, but
the attempt here is to finally get this into mainline.

Following this will be a series of patches from the 'PM branch' of the
linux-omap tree to add full PM hardware support from the linux-omap
tree.

Much of this PM core code was written by Jouni Hogander with
significant contributions from Paul Walmsley as well as many others
from Nokia, Texas Instruments and linux-omap community.
Signed-off-by: default avatarJouni Hogander <jouni.hogander@nokia.com>
Cc: Paul Walmsley <paul@pwsan.com>
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent a330bd47
......@@ -25,8 +25,10 @@ obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
# Power Management
ifeq ($(CONFIG_PM),y)
obj-y += pm.o
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
obj-$(CONFIG_ARCH_OMAP24XX) += sleep24xx.o
obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
endif
# Clock framework
......
/*
* OMAP Power Management debug routines
*
* Copyright (C) 2005 Texas Instruments, Inc.
* Copyright (C) 2006-2008 Nokia Corporation
*
* Written by:
* Richard Woodruff <r-woodruff2@ti.com>
* Tony Lindgren
* Juha Yrjola
* Amit Kucheria <amit.kucheria@nokia.com>
* Igor Stoppa <igor.stoppa@nokia.com>
* Jouni Hogander
*
* Based on pm.c for omap2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <mach/clock.h>
#include <mach/board.h>
#include "prm.h"
#include "cm.h"
#include "pm.h"
int omap2_pm_debug;
#define DUMP_PRM_MOD_REG(mod, reg) \
regs[reg_count].name = #mod "." #reg; \
regs[reg_count++].val = prm_read_mod_reg(mod, reg)
#define DUMP_CM_MOD_REG(mod, reg) \
regs[reg_count].name = #mod "." #reg; \
regs[reg_count++].val = cm_read_mod_reg(mod, reg)
#define DUMP_PRM_REG(reg) \
regs[reg_count].name = #reg; \
regs[reg_count++].val = __raw_readl(reg)
#define DUMP_CM_REG(reg) \
regs[reg_count].name = #reg; \
regs[reg_count++].val = __raw_readl(reg)
#define DUMP_INTC_REG(reg, off) \
regs[reg_count].name = #reg; \
regs[reg_count++].val = __raw_readl(IO_ADDRESS(0x480fe000 + (off)))
void omap2_pm_dump(int mode, int resume, unsigned int us)
{
struct reg {
const char *name;
u32 val;
} regs[32];
int reg_count = 0, i;
const char *s1 = NULL, *s2 = NULL;
if (!resume) {
#if 0
/* MPU */
DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRM_IRQENABLE_MPU_OFFSET);
DUMP_CM_MOD_REG(MPU_MOD, CM_CLKSTCTRL);
DUMP_PRM_MOD_REG(MPU_MOD, PM_PWSTCTRL);
DUMP_PRM_MOD_REG(MPU_MOD, PM_PWSTST);
DUMP_PRM_MOD_REG(MPU_MOD, PM_WKDEP);
#endif
#if 0
/* INTC */
DUMP_INTC_REG(INTC_MIR0, 0x0084);
DUMP_INTC_REG(INTC_MIR1, 0x00a4);
DUMP_INTC_REG(INTC_MIR2, 0x00c4);
#endif
#if 0
DUMP_CM_MOD_REG(CORE_MOD, CM_FCLKEN1);
if (cpu_is_omap24xx()) {
DUMP_CM_MOD_REG(CORE_MOD, OMAP24XX_CM_FCLKEN2);
DUMP_PRM_MOD_REG(OMAP24XX_GR_MOD,
OMAP2_PRCM_CLKEMUL_CTRL_OFFSET);
DUMP_PRM_MOD_REG(OMAP24XX_GR_MOD,
OMAP2_PRCM_CLKSRC_CTRL_OFFSET);
}
DUMP_CM_MOD_REG(WKUP_MOD, CM_FCLKEN);
DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN1);
DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN2);
DUMP_CM_MOD_REG(WKUP_MOD, CM_ICLKEN);
DUMP_CM_MOD_REG(PLL_MOD, CM_CLKEN);
DUMP_CM_MOD_REG(PLL_MOD, CM_AUTOIDLE);
DUMP_PRM_MOD_REG(CORE_MOD, PM_PWSTST);
#endif
#if 0
/* DSP */
if (cpu_is_omap24xx()) {
DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_FCLKEN);
DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_ICLKEN);
DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_IDLEST);
DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_AUTOIDLE);
DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSEL);
DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSTCTRL);
DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, RM_RSTCTRL);
DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, RM_RSTST);
DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, PM_PWSTCTRL);
DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, PM_PWSTST);
}
#endif
} else {
DUMP_PRM_MOD_REG(CORE_MOD, PM_WKST1);
if (cpu_is_omap24xx())
DUMP_PRM_MOD_REG(CORE_MOD, OMAP24XX_PM_WKST2);
DUMP_PRM_MOD_REG(WKUP_MOD, PM_WKST);
DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
#if 1
DUMP_INTC_REG(INTC_PENDING_IRQ0, 0x0098);
DUMP_INTC_REG(INTC_PENDING_IRQ1, 0x00b8);
DUMP_INTC_REG(INTC_PENDING_IRQ2, 0x00d8);
#endif
}
switch (mode) {
case 0:
s1 = "full";
s2 = "retention";
break;
case 1:
s1 = "MPU";
s2 = "retention";
break;
case 2:
s1 = "MPU";
s2 = "idle";
break;
}
if (!resume)
#ifdef CONFIG_NO_HZ
printk(KERN_INFO
"--- Going to %s %s (next timer after %u ms)\n", s1, s2,
jiffies_to_msecs(get_next_timer_interrupt(jiffies) -
jiffies));
#else
printk(KERN_INFO "--- Going to %s %s\n", s1, s2);
#endif
else
printk(KERN_INFO "--- Woke up (slept for %u.%03u ms)\n",
us / 1000, us % 1000);
for (i = 0; i < reg_count; i++)
printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
}
/*
* linux/arch/arm/mach-omap2/pm.c
*
* OMAP2 Power Management Routines
*
* Copyright (C) 2006 Nokia Corporation
* Tony Lindgren <tony@atomide.com>
*
* Copyright (C) 2005 Texas Instruments, Inc.
* Richard Woodruff <r-woodruff2@ti.com>
*
* Based on pm.c for omap1
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/suspend.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/atomic.h>
#include <asm/mach/time.h>
#include <asm/mach/irq.h>
#include <mach/irqs.h>
#include <mach/clock.h>
#include <mach/sram.h>
#include <mach/pm.h>
static struct clk *vclk;
static void (*omap2_sram_idle)(void);
static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev);
static void (*saved_idle)(void);
extern void __init pmdomain_init(void);
extern void pmdomain_set_autoidle(void);
static unsigned int omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_SIZE];
void omap2_pm_idle(void)
{
local_irq_disable();
local_fiq_disable();
if (need_resched()) {
local_fiq_enable();
local_irq_enable();
return;
}
omap2_sram_idle();
local_fiq_enable();
local_irq_enable();
}
static int omap2_pm_prepare(void)
{
/* We cannot sleep in idle until we have resumed */
saved_idle = pm_idle;
pm_idle = NULL;
return 0;
}
static int omap2_pm_suspend(void)
{
return 0;
}
static int omap2_pm_enter(suspend_state_t state)
{
int ret = 0;
switch (state)
{
case PM_SUSPEND_STANDBY:
case PM_SUSPEND_MEM:
ret = omap2_pm_suspend();
break;
default:
ret = -EINVAL;
}
return ret;
}
static void omap2_pm_finish(void)
{
pm_idle = saved_idle;
}
static struct platform_suspend_ops omap_pm_ops = {
.prepare = omap2_pm_prepare,
.enter = omap2_pm_enter,
.finish = omap2_pm_finish,
.valid = suspend_valid_only_mem,
};
static int __init omap2_pm_init(void)
{
return 0;
}
__initcall(omap2_pm_init);
/*
* OMAP2/3 Power Management Routines
*
* Copyright (C) 2008 Nokia Corporation
* Jouni Hogander
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ARCH_ARM_MACH_OMAP2_PM_H
#define __ARCH_ARM_MACH_OMAP2_PM_H
extern int omap2_pm_init(void);
extern int omap3_pm_init(void);
#ifdef CONFIG_PM_DEBUG
extern void omap2_pm_dump(int mode, int resume, unsigned int us);
extern int omap2_pm_debug;
#else
#define omap2_pm_dump(mode, resume, us) do {} while (0);
#define omap2_pm_debug 0
#endif /* CONFIG_PM_DEBUG */
extern void omap24xx_idle_loop_suspend(void);
extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
void __iomem *sdrc_power);
extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
extern void save_secure_ram_context(u32 *addr);
extern unsigned int omap24xx_idle_loop_suspend_sz;
extern unsigned int omap34xx_suspend_sz;
extern unsigned int save_secure_ram_context_sz;
extern unsigned int omap24xx_cpu_suspend_sz;
extern unsigned int omap34xx_cpu_suspend_sz;
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -276,6 +276,8 @@
/* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */
#define OMAP3430_EN_GPIO1 (1 << 3)
#define OMAP3430_EN_GPIO1_SHIFT 3
#define OMAP3430_EN_GPT12 (1 << 1)
#define OMAP3430_EN_GPT12_SHIFT 1
#define OMAP3430_EN_GPT1 (1 << 0)
#define OMAP3430_EN_GPT1_SHIFT 0
......
......@@ -60,9 +60,12 @@ struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r)
{
struct omap_sdrc_params *sp;
if (!sdrc_init_params)
return NULL;
sp = sdrc_init_params;
while (sp->rate != r)
while (sp->rate && sp->rate != r)
sp++;
if (!sp->rate)
......
......@@ -28,7 +28,6 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <mach/io.h>
#include <mach/pm.h>
#include <mach/omap24xx.h>
......
This diff is collapsed.
......@@ -28,7 +28,6 @@
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <mach/pm.h>
#include <mach/mux.h>
#include <mach/usb.h>
......
......@@ -171,7 +171,7 @@ endchoice
config OMAP_SERIAL_WAKE
bool "Enable wake-up events for serial ports"
depends on OMAP_MUX
depends on ARCH_OMAP1 && OMAP_MUX
default y
help
Select this option if you want to have your system wake up
......
......@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/console.h>
#include <linux/serial.h>
#include <linux/tty.h>
......
......@@ -39,7 +39,6 @@
#include <mach/gpmc.h>
#include <mach/onenand.h>
#include <mach/gpio.h>
#include <mach/pm.h>
#include <mach/dma.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment