xref: /linux/arch/arm/mach-omap2/pm-debug.c (revision 2277ab4a1df50e05bc732fe9488d4e902bb8399a)
1 /*
2  * OMAP Power Management debug routines
3  *
4  * Copyright (C) 2005 Texas Instruments, Inc.
5  * Copyright (C) 2006-2008 Nokia Corporation
6  *
7  * Written by:
8  * Richard Woodruff <r-woodruff2@ti.com>
9  * Tony Lindgren
10  * Juha Yrjola
11  * Amit Kucheria <amit.kucheria@nokia.com>
12  * Igor Stoppa <igor.stoppa@nokia.com>
13  * Jouni Hogander
14  *
15  * Based on pm.c for omap2
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License version 2 as
19  * published by the Free Software Foundation.
20  */
21 
22 #include <linux/kernel.h>
23 #include <linux/timer.h>
24 #include <linux/clk.h>
25 #include <linux/err.h>
26 #include <linux/io.h>
27 
28 #include <mach/clock.h>
29 #include <mach/board.h>
30 
31 #include "prm.h"
32 #include "cm.h"
33 #include "pm.h"
34 
35 int omap2_pm_debug;
36 
37 #define DUMP_PRM_MOD_REG(mod, reg)    \
38 	regs[reg_count].name = #mod "." #reg; \
39 	regs[reg_count++].val = prm_read_mod_reg(mod, reg)
40 #define DUMP_CM_MOD_REG(mod, reg)     \
41 	regs[reg_count].name = #mod "." #reg; \
42 	regs[reg_count++].val = cm_read_mod_reg(mod, reg)
43 #define DUMP_PRM_REG(reg) \
44 	regs[reg_count].name = #reg; \
45 	regs[reg_count++].val = __raw_readl(reg)
46 #define DUMP_CM_REG(reg) \
47 	regs[reg_count].name = #reg; \
48 	regs[reg_count++].val = __raw_readl(reg)
49 #define DUMP_INTC_REG(reg, off) \
50 	regs[reg_count].name = #reg; \
51 	regs[reg_count++].val = __raw_readl(IO_ADDRESS(0x480fe000 + (off)))
52 
53 void omap2_pm_dump(int mode, int resume, unsigned int us)
54 {
55 	struct reg {
56 		const char *name;
57 		u32 val;
58 	} regs[32];
59 	int reg_count = 0, i;
60 	const char *s1 = NULL, *s2 = NULL;
61 
62 	if (!resume) {
63 #if 0
64 		/* MPU */
65 		DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRM_IRQENABLE_MPU_OFFSET);
66 		DUMP_CM_MOD_REG(MPU_MOD, CM_CLKSTCTRL);
67 		DUMP_PRM_MOD_REG(MPU_MOD, PM_PWSTCTRL);
68 		DUMP_PRM_MOD_REG(MPU_MOD, PM_PWSTST);
69 		DUMP_PRM_MOD_REG(MPU_MOD, PM_WKDEP);
70 #endif
71 #if 0
72 		/* INTC */
73 		DUMP_INTC_REG(INTC_MIR0, 0x0084);
74 		DUMP_INTC_REG(INTC_MIR1, 0x00a4);
75 		DUMP_INTC_REG(INTC_MIR2, 0x00c4);
76 #endif
77 #if 0
78 		DUMP_CM_MOD_REG(CORE_MOD, CM_FCLKEN1);
79 		if (cpu_is_omap24xx()) {
80 			DUMP_CM_MOD_REG(CORE_MOD, OMAP24XX_CM_FCLKEN2);
81 			DUMP_PRM_MOD_REG(OMAP24XX_GR_MOD,
82 					OMAP2_PRCM_CLKEMUL_CTRL_OFFSET);
83 			DUMP_PRM_MOD_REG(OMAP24XX_GR_MOD,
84 					OMAP2_PRCM_CLKSRC_CTRL_OFFSET);
85 		}
86 		DUMP_CM_MOD_REG(WKUP_MOD, CM_FCLKEN);
87 		DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN1);
88 		DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN2);
89 		DUMP_CM_MOD_REG(WKUP_MOD, CM_ICLKEN);
90 		DUMP_CM_MOD_REG(PLL_MOD, CM_CLKEN);
91 		DUMP_CM_MOD_REG(PLL_MOD, CM_AUTOIDLE);
92 		DUMP_PRM_MOD_REG(CORE_MOD, PM_PWSTST);
93 #endif
94 #if 0
95 		/* DSP */
96 		if (cpu_is_omap24xx()) {
97 			DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_FCLKEN);
98 			DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_ICLKEN);
99 			DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_IDLEST);
100 			DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_AUTOIDLE);
101 			DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSEL);
102 			DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSTCTRL);
103 			DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, RM_RSTCTRL);
104 			DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, RM_RSTST);
105 			DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, PM_PWSTCTRL);
106 			DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, PM_PWSTST);
107 		}
108 #endif
109 	} else {
110 		DUMP_PRM_MOD_REG(CORE_MOD, PM_WKST1);
111 		if (cpu_is_omap24xx())
112 			DUMP_PRM_MOD_REG(CORE_MOD, OMAP24XX_PM_WKST2);
113 		DUMP_PRM_MOD_REG(WKUP_MOD, PM_WKST);
114 		DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
115 #if 1
116 		DUMP_INTC_REG(INTC_PENDING_IRQ0, 0x0098);
117 		DUMP_INTC_REG(INTC_PENDING_IRQ1, 0x00b8);
118 		DUMP_INTC_REG(INTC_PENDING_IRQ2, 0x00d8);
119 #endif
120 	}
121 
122 	switch (mode) {
123 	case 0:
124 		s1 = "full";
125 		s2 = "retention";
126 		break;
127 	case 1:
128 		s1 = "MPU";
129 		s2 = "retention";
130 		break;
131 	case 2:
132 		s1 = "MPU";
133 		s2 = "idle";
134 		break;
135 	}
136 
137 	if (!resume)
138 #ifdef CONFIG_NO_HZ
139 		printk(KERN_INFO
140 		       "--- Going to %s %s (next timer after %u ms)\n", s1, s2,
141 		       jiffies_to_msecs(get_next_timer_interrupt(jiffies) -
142 					jiffies));
143 #else
144 		printk(KERN_INFO "--- Going to %s %s\n", s1, s2);
145 #endif
146 	else
147 		printk(KERN_INFO "--- Woke up (slept for %u.%03u ms)\n",
148 			us / 1000, us % 1000);
149 
150 	for (i = 0; i < reg_count; i++)
151 		printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
152 }
153