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