From 8bd229492209c0c7d050e2f9a600c12f035d72f7 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 28 May 2009 10:56:16 -0700 Subject: 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: Jouni Hogander Cc: Paul Walmsley Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm-debug.c | 152 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 arch/arm/mach-omap2/pm-debug.c (limited to 'arch/arm/mach-omap2/pm-debug.c') diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c new file mode 100644 index 000000000000..6cc375a275be --- /dev/null +++ b/arch/arm/mach-omap2/pm-debug.c @@ -0,0 +1,152 @@ +/* + * OMAP Power Management debug routines + * + * Copyright (C) 2005 Texas Instruments, Inc. + * Copyright (C) 2006-2008 Nokia Corporation + * + * Written by: + * Richard Woodruff + * Tony Lindgren + * Juha Yrjola + * Amit Kucheria + * Igor Stoppa + * 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 +#include +#include +#include +#include + +#include +#include + +#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); +} -- cgit v1.2.3