diff options
Diffstat (limited to 'arch/arm/mach-omap2/pm-debug.c')
| -rw-r--r-- | arch/arm/mach-omap2/pm-debug.c | 152 | 
1 files changed, 152 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c new file mode 100644 index 00000000000..6cc375a275b --- /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 <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); +}  |