| /* | 
 |  * 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); | 
 | } |